Q-Chat fixes and additions

- Added copy paste with line breaks to message field
- Added upload file ( max file size 125 MB )
- Added auto detect if image is GIF and display it so ( max file size 3 MB )
- Added auto detect if file is attachment or file
- Added download splash if download larger files
- Fixed regex for qortal// links
- Fixed rporsemirror whitespace error
- Fixed upload attachment like pdf ( max file size 10 MB )
- Fixed delete image, gif, attachment, file
This commit is contained in:
AlphaX-Projects 2024-05-25 12:05:45 +02:00
parent 4276f54933
commit 96230a60f5
5 changed files with 1373 additions and 123 deletions

BIN
img/file-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,9 @@ import './ChatImage'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-dialog' import '@material/mwc-dialog'
import '@material/mwc-icon' import '@material/mwc-icon'
import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/iron-icons/iron-icons.js'
import '@vaadin/icon' import '@vaadin/icon'
import '@vaadin/icons' import '@vaadin/icons'
import '@vaadin/tooltip' import '@vaadin/tooltip'
@ -96,6 +99,7 @@ function processText(input) {
parts.forEach((part) => { parts.forEach((part) => {
if (part.startsWith('qortal://')) { if (part.startsWith('qortal://')) {
const link = document.createElement('span') const link = document.createElement('span')
// Store the URL in a data attribute // Store the URL in a data attribute
link.setAttribute('data-url', part) link.setAttribute('data-url', part)
link.textContent = part link.textContent = part
@ -107,7 +111,9 @@ function processText(input) {
e.preventDefault() e.preventDefault()
try { try {
const res = await extractComponents(part) const res = await extractComponents(part)
if (!res) return if (!res) return
if (res.type && res.groupid && res.action === 'join') { if (res.type && res.groupid && res.action === 'join') {
window.parent.reduxStore.dispatch( window.parent.reduxStore.dispatch(
window.parent.reduxAction.setNewTab({ window.parent.reduxAction.setNewTab({
@ -130,7 +136,7 @@ function processText(input) {
window.parent.reduxStore.dispatch( window.parent.reduxStore.dispatch(
window.parent.reduxAction.setSideEffectAction({ window.parent.reduxAction.setSideEffectAction({
type: 'openJoinGroupModal', type: 'openJoinGroupModal',
data: +res.groupid data: res.groupid
}) })
) )
return return
@ -987,7 +993,9 @@ class MessageTemplate extends LitElement {
openDialogImage: { type: Boolean }, openDialogImage: { type: Boolean },
openDialogGif: { type: Boolean }, openDialogGif: { type: Boolean },
openDeleteImage: { type: Boolean }, openDeleteImage: { type: Boolean },
openDeleteGif: { type: Boolean },
openDeleteAttachment: { type: Boolean }, openDeleteAttachment: { type: Boolean },
openDeleteFile: { type: Boolean },
isImageLoaded: { type: Boolean }, isImageLoaded: { type: Boolean },
isGifLoaded: { type: Boolean }, isGifLoaded: { type: Boolean },
isFirstMessage: { type: Boolean }, isFirstMessage: { type: Boolean },
@ -1032,6 +1040,10 @@ class MessageTemplate extends LitElement {
this.isLastMessageInGroup = false this.isLastMessageInGroup = false
this.viewImage = false this.viewImage = false
this.isInProgress = false this.isInProgress = false
this.openDeleteImage = false
this.openDeleteGif = false
this.openDeleteAttachment = false
this.openDeleteFile = false
} }
render() { render() {
@ -1044,36 +1056,50 @@ class MessageTemplate extends LitElement {
let repliedToData = null let repliedToData = null
let image = null let image = null
let gif = null let gif = null
let attachment = null
let file = null
let isImageDeleted = false let isImageDeleted = false
let isGifDeleted = false
let isAttachmentDeleted = false let isAttachmentDeleted = false
let isFileDeleted = false
let version = 0 let version = 0
let isForwarded = false let isForwarded = false
let isEdited = false let isEdited = false
let attachment = null
try { try {
const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage) const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage)
if (+parsedMessageObj.version > 1 && parsedMessageObj.messageText) { if (+parsedMessageObj.version > 1 && parsedMessageObj.messageText) {
messageVersion2 = generateHTML(parsedMessageObj.messageText, [StarterKit, Underline, Highlight]) messageVersion2 = generateHTML(parsedMessageObj.messageText, [StarterKit, Underline, Highlight])
messageVersion2WithLink = processText(messageVersion2) messageVersion2WithLink = processText(messageVersion2)
} }
message = parsedMessageObj.messageText message = parsedMessageObj.messageText
repliedToData = this.messageObj.repliedToData repliedToData = this.messageObj.repliedToData
isImageDeleted = parsedMessageObj.isImageDeleted isImageDeleted = parsedMessageObj.isImageDeleted
isGifDeleted = parsedMessageObj.isGifDeleted
isAttachmentDeleted = parsedMessageObj.isAttachmentDeleted isAttachmentDeleted = parsedMessageObj.isAttachmentDeleted
isFileDeleted = parsedMessageObj.isFileDeleted
// reactions = parsedMessageObj.reactions || [] // reactions = parsedMessageObj.reactions || []
version = parsedMessageObj.version version = parsedMessageObj.version
isForwarded = parsedMessageObj.type === 'forward' isForwarded = parsedMessageObj.type === 'forward'
isEdited = parsedMessageObj.isEdited && true isEdited = parsedMessageObj.isEdited && true
if (parsedMessageObj.attachments && Array.isArray(parsedMessageObj.attachments) && parsedMessageObj.attachments.length > 0) {
attachment = parsedMessageObj.attachments[0]
}
if (parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0) { if (parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0) {
image = parsedMessageObj.images[0] image = parsedMessageObj.images[0]
} }
if (parsedMessageObj.gifs && Array.isArray(parsedMessageObj.gifs) && parsedMessageObj.gifs.length > 0) { if (parsedMessageObj.gifs && Array.isArray(parsedMessageObj.gifs) && parsedMessageObj.gifs.length > 0) {
gif = parsedMessageObj.gifs[0] gif = parsedMessageObj.gifs[0]
} }
if (parsedMessageObj.attachments && Array.isArray(parsedMessageObj.attachments) && parsedMessageObj.attachments.length > 0) {
attachment = parsedMessageObj.attachments[0]
}
if (parsedMessageObj.files && Array.isArray(parsedMessageObj.files) && parsedMessageObj.files.length > 0) {
file = parsedMessageObj.files[0]
}
} catch (error) { } catch (error) {
message = this.messageObj.decodedMessage message = this.messageObj.decodedMessage
} }
@ -1141,7 +1167,7 @@ class MessageTemplate extends LitElement {
if (gif) { if (gif) {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
gifUrl = `${nodeUrl}/arbitrary/${gif.service}/${gif.name}/${gif.identifier}?filepath=${gif.filePath}` gifUrl = `${nodeUrl}/arbitrary/${gif.service}/${gif.name}/${gif.identifier}?async=true`
if (this.viewImage || this.myAddress === this.messageObj.sender) { if (this.viewImage || this.myAddress === this.messageObj.sender) {
gifHTML = createGif(gifUrl) gifHTML = createGif(gifUrl)
gifHTMLDialog = createGif(gifUrl) gifHTMLDialog = createGif(gifUrl)
@ -1280,7 +1306,7 @@ class MessageTemplate extends LitElement {
class=${[`image-container`, !this.isImageLoaded ? 'defaultSize' : '',].join(' ')} class=${[`image-container`, !this.isImageLoaded ? 'defaultSize' : '',].join(' ')}
style=${this.isFirstMessage && 'margin-top: 10px;'} style=${this.isFirstMessage && 'margin-top: 10px;'}
> >
<div style="display:flex;width:100%;height:100%;justify-content:center;align-items:center;cursor:pointer;color:var(--black);"> <div style="display: flex; width: 100%; height: 100%; justify-content: center; align-items: center; cursor: pointer; color: var(--black);">
${translate('chatpage.cchange40')} ${translate('chatpage.cchange40')}
</div> </div>
</div> </div>
@ -1293,7 +1319,12 @@ class MessageTemplate extends LitElement {
${imageHTML} ${imageHTML}
${this.myAddress === this.messageObj.sender ? ${this.myAddress === this.messageObj.sender ?
html` html`
<vaadin-icon @click=${() => {this.openDeleteImage = true;}} class="image-delete-icon" icon="vaadin:close" slot="icon"></vaadin-icon> <vaadin-icon
@click=${() => this.openDeleteImageDialog()}
icon="vaadin:close"
slot="icon"
class="image-delete-icon"
></vaadin-icon>
` `
: '' : ''
} }
@ -1301,35 +1332,62 @@ class MessageTemplate extends LitElement {
` `
: image && isImageDeleted ? : image && isImageDeleted ?
html` html`
<p class="image-deleted-msg">${translate('chatpage.cchange80')}</p> <div class="attachment-container">
<div class="attachment-info">
<p style=${'font-style: italic;'} class="attachment-name">
${translate('chatpage.cchange80')}
</p>
</div>
</div>
` `
: html`` : html``
} }
${gif && !this.viewImage && this.myAddress !== this.messageObj.sender ? ${gif && !isGifDeleted && !this.viewImage && this.myAddress !== this.messageObj.sender ?
html` html`
<div <div
@click=${() => {this.viewImage = true;}} @click=${() => {this.viewImage = true;}}
class=${[`image-container`, !this.isImageLoaded ? 'defaultSize' : '', ].join(' ')} class=${[`image-container`, !this.isGifoaded ? 'defaultSize' : '', ].join(' ')}
style=${this.isFirstMessage && 'margin-top: 10px;'} style=${this.isFirstMessage && 'margin-top: 10px;'}
> >
<div style="display:flex;width:100%;height:100%;justify-content:center;align-items:center;cursor:pointer;color:var(--black);"> <div style="display: flex; width: 100%; height: 100%; justify-content: center; align-items: center; cursor: pointer; color: var(--black);">
${translate('gifs.gchange25')} ${translate('gifs.gchange25')}
</div> </div>
</div> </div>
` `
: html`` : html``
} }
${gif && (this.viewImage || this.myAddress === this.messageObj.sender) ? ${gif && !isGifDeleted && (this.viewImage || this.myAddress === this.messageObj.sender) ?
html` html`
<div class=${[`image-container`, !this.isGifLoaded ? 'defaultSize' : '',].join(' ')} style=${this.isFirstMessage && 'margin-top: 10px;'}> <div class=${[`image-container`, !this.isGifLoaded ? 'defaultSize' : '',].join(' ')} style=${this.isFirstMessage && 'margin-top: 10px;'}>
${gifHTML} ${gifHTML}
${this.myAddress === this.messageObj.sender ?
html`
<vaadin-icon
@click=${() => this.openDeleteGifDialog()}
icon="vaadin:close"
slot="icon"
class="image-delete-icon"
></vaadin-icon>
`
: ''
}
</div> </div>
` `
: gif && isGifDeleted ?
html`
<div class="attachment-container">
<div class="attachment-info">
<p style=${'font-style: italic;'} class="attachment-name">
${translate('chatpage.cchange107')}
</p>
</div>
</div>
`
: html`` : html``
} }
${attachment && !isAttachmentDeleted ? ${attachment && !isAttachmentDeleted ?
html` html`
<div @click=${async () => await this.downloadAttachment(attachment)} class="attachment-container"> <div class="attachment-container">
<div class="attachment-icon-container"> <div class="attachment-icon-container">
<img src="/img/attachment-icon.png" alt="attachment-icon" class="attachment-icon" /> <img src="/img/attachment-icon.png" alt="attachment-icon" class="attachment-icon" />
</div> </div>
@ -1341,11 +1399,16 @@ class MessageTemplate extends LitElement {
${roundToNearestDecimal(attachment.attachmentSize)} mb ${roundToNearestDecimal(attachment.attachmentSize)} mb
</p> </p>
</div> </div>
<vaadin-icon icon="vaadin:download-alt" slot="icon" class="download-icon"></vaadin-icon> <vaadin-icon
@click=${async () => await this.downloadAttachment(attachment)}
icon="vaadin:download-alt"
slot="icon"
class="download-icon"
></vaadin-icon>
${this.myAddress === this.messageObj.sender ? ${this.myAddress === this.messageObj.sender ?
html` html`
<vaadin-icon <vaadin-icon
@click=${(e) => {e.stopPropagation(); this.openDeleteAttachment = true;}} @click=${() => this.openDeleteAttachmentDialog()}
class="image-delete-icon" class="image-delete-icon"
icon="vaadin:close" icon="vaadin:close"
slot="icon" slot="icon"
@ -1368,6 +1431,51 @@ class MessageTemplate extends LitElement {
` `
: html`` : html``
} }
${file && !isFileDeleted ?
html`
<div class="file-container">
<div class="file-icon-container">
<img src="/img/file-icon.png" alt="file-icon" class="file-icon" />
</div>
<div class="attachment-info">
<p class="attachment-name">
${file && file.appFileName}
</p>
<p class="attachment-size">
${roundToNearestDecimal(file.appFileSize)} mb
</p>
</div>
<vaadin-icon
@click=${async () => await this.downloadFile(file)}
icon="vaadin:download-alt"
slot="icon"
class="download-icon"
></vaadin-icon>
${this.myAddress === this.messageObj.sender ?
html`
<vaadin-icon
@click=${() => this.openDeleteFileDialog()}
class="image-delete-icon"
icon="vaadin:close"
slot="icon"
></vaadin-icon>
`
: html``
}
</div>
`
: file && isFileDeleted ?
html`
<div class="attachment-container">
<div class="attachment-info">
<p style=${'font-style: italic;'} class="attachment-name">
${translate('chatpage.cchange102')}
</p>
</div>
</div>
`
: html``
}
<div id="messageContent" class="message" style=${image && replacedMessage !== '' && 'margin-top: 15px;'}> <div id="messageContent" class="message" style=${image && replacedMessage !== '' && 'margin-top: 15px;'}>
${+version > 1 ? messageVersion2WithLink ? ${+version > 1 ? messageVersion2WithLink ?
html` html`
@ -1511,7 +1619,6 @@ class MessageTemplate extends LitElement {
</mwc-button> </mwc-button>
</mwc-dialog> </mwc-dialog>
<mwc-dialog id="showDialogPublicKey" ?open=${this.openDialogGif} @closed=${() => {this.openDialogGif = false;}}> <mwc-dialog id="showDialogPublicKey" ?open=${this.openDialogGif} @closed=${() => {this.openDialogGif = false;}}>
MessageTemplate
<div class="dialog-header"></div> <div class="dialog-header"></div>
<div class="dialog-container imageContainer"> <div class="dialog-container imageContainer">
${gifHTMLDialog} ${gifHTMLDialog}
@ -1519,34 +1626,88 @@ class MessageTemplate extends LitElement {
<mwc-button slot="primaryAction" dialogAction="cancel" class="red" @click=${() => {this.openDialogGif = false;}}> <mwc-button slot="primaryAction" dialogAction="cancel" class="red" @click=${() => {this.openDialogGif = false;}}>
${translate('general.close')} ${translate('general.close')}
</mwc-button> </mwc-button>
MessageTemplate
</mwc-dialog> </mwc-dialog>
<mwc-dialog hideActions ?open=${this.openDeleteImage} @closed=${() => {this.openDeleteImage = false;}}> <mwc-dialog hideActions id="deleteImageDialog" scrimClickAction="" escapeKeyAction="">
<div class="delete-image-msg"> <div class="delete-image-msg">
<p>${translate('chatpage.cchange78')}</p> <p>${translate('chatpage.cchange78')}</p>
</div> </div>
<div class="modal-button-row" @click=${() => (this.openDeleteImage = false)}> <div class="modal-button-row">
<button class="modal-button-red"> <button class="modal-button-red" @click=${() => this.closeDeleteImageDialog()}>
Cancel ${translate('login.lp4')}
</button> </button>
<button class="modal-button" @click=${() => this.sendMessage({type: 'delete', name: image.name, identifier: image.identifier, editedMessageObj: this.messageObj,})}> <button class="modal-button" @click=${() => {
Yes this.sendMessage({type: 'delete', name: image.name, identifier: image.identifier, editedMessageObj: this.messageObj});
this.closeDeleteImageDialog();
}}>
${translate('general.yes')}
</button> </button>
</div> </div>
</mwc-dialog> </mwc-dialog>
<mwc-dialog hideActions ?open=${this.openDeleteAttachment} @closed=${() => {this.openDeleteAttachment = false;}}> <mwc-dialog hideActions id="deleteGifDialog" scrimClickAction="" escapeKeyAction="">
<div class="delete-image-msg">
<p>${translate('chatpage.cchange106')}</p>
</div>
<div class="modal-button-row">
<button class="modal-button-red" @click=${() => this.closeDeleteGifDialog()}>
${translate('login.lp4')}
</button>
<button class="modal-button" @click=${() => {
this.sendMessage({type: 'deleteGif', gif: gif, name: gif.name, identifier: gif.identifier, editedMessageObj: this.messageObj});
this.closeDeleteGifDialog();
}}>
${translate('general.yes')}
</button>
</div>
</mwc-dialog>
<mwc-dialog hideActions id="deleteAttachmentDialog" scrimClickAction="" escapeKeyAction="">
<div class="delete-image-msg"> <div class="delete-image-msg">
<p>${translate('chatpage.cchange79')}</p> <p>${translate('chatpage.cchange79')}</p>
</div> </div>
<div class="modal-button-row" @click=${() => (this.openDeleteAttachment = false)}> <div class="modal-button-row">
<button class="modal-button-red"> <button class="modal-button-red" @click=${() => this.closeDeleteAttachmentDialog()}>
Cancel ${translate('login.lp4')}
</button> </button>
<button class="modal-button" @click=${() => {this.sendMessage({type: 'deleteAttachment', attachment: attachment, name: attachment.name, identifier: attachment.identifier, editedMessageObj: this.messageObj,});}}> <button class="modal-button" @click=${() => {
Yes this.sendMessage({type: 'deleteAttachment', attachment: attachment, name: attachment.name, identifier: attachment.identifier, editedMessageObj: this.messageObj});
this.closeDeleteAttachmentDialog();
}}>
${translate('general.yes')}
</button> </button>
</div> </div>
</mwc-dialog> </mwc-dialog>
<mwc-dialog hideActions id="deleteFileDialog" scrimClickAction="" escapeKeyAction="">
<div class="delete-image-msg">
<p>${translate('chatpage.cchange101')}</p>
</div>
<div class="modal-button-row">
<button class="modal-button-red" @click=${() => this.closeDeleteFileDialog()}>
${translate('login.lp4')}
</button>
<button class="modal-button" @click=${() => {
this.sendMessage({type: 'deleteFile', file: file, name: file.name, identifier: file.identifier, editedMessageObj: this.messageObj});
this.closeDeleteFileDialog();
}}>
${translate('general.yes')}
</button>
</div>
</mwc-dialog>
<paper-dialog id="downloadProgressDialog" class="progress" modal>
<span class="close-download"><paper-icon-button icon="icons:close" @click="${() => this.closeDownloadProgressDialog()}" title="${translate("general.close")}"></paper-icon-button></span>
<div class="lds-roller">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<h2>${translate('appspage.schange41')}</h2>
</paper-dialog>
<paper-dialog id="closeProgressDialog" class="close-progress" modal>
${translate('chatpage.cchange108')}
</paper-dialog>
` `
} }
@ -1574,6 +1735,14 @@ class MessageTemplate extends LitElement {
}, 60000) }, 60000)
} }
async closeDownloadProgressDialog() {
const closeDelay = ms => new Promise(res => setTimeout(res, ms))
this.shadowRoot.getElementById('downloadProgressDialog').close()
this.shadowRoot.getElementById('closeProgressDialog').open()
await closeDelay(3000)
this.shadowRoot.getElementById('closeProgressDialog').close()
}
// Open & Close Private Message Chat Modal // Open & Close Private Message Chat Modal
showPrivateMessageModal() { showPrivateMessageModal() {
this.openDialogPrivateMessage = true this.openDialogPrivateMessage = true
@ -1600,17 +1769,82 @@ class MessageTemplate extends LitElement {
} }
} }
async downloadAttachment(attachment) { openDeleteImageDialog() {
this.openDeleteImage = true
this.shadowRoot.querySelector('#deleteImageDialog').show()
}
closeDeleteImageDialog() {
this.shadowRoot.querySelector('#deleteImageDialog').close()
this.openDeleteImage = false
}
openDeleteGifDialog() {
this.openDeleteGif = true
this.shadowRoot.querySelector('#deleteGifDialog').show()
}
closeDeleteGifDialog() {
this.shadowRoot.querySelector('#deleteGifDialog').close()
this.openDeleteGif = false
}
openDeleteAttachmentDialog() {
this.openDeleteAttachment = true
this.shadowRoot.querySelector('#deleteAttachmentDialog').show()
}
closeDeleteAttachmentDialog() {
this.shadowRoot.querySelector('#deleteAttachmentDialog').close()
this.openDeleteAttachment = false
}
openDeleteFileDialog() {
this.openDeleteFile = true
this.shadowRoot.querySelector('#deleteFileDialog').show()
}
closeDeleteFileDialog() {
this.shadowRoot.querySelector('#deleteFileDialog').close()
this.openDeleteFile = false
}
downloadAttachment(attachment) {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
this.shadowRoot.getElementById('downloadProgressDialog').open()
try { try {
axios.get( axios.get(
`${nodeUrl}/arbitrary/QCHAT_ATTACHMENT/${attachment.name}/${attachment.identifier}`, `${nodeUrl}/arbitrary/ATTACHMENT/${attachment.name}/${attachment.identifier}`,
{ responseType: 'blob' } { responseType: 'blob' }
).then((response) => { ).then((response) => {
this.shadowRoot.getElementById('downloadProgressDialog').close()
let filename = attachment.attachmentName let filename = attachment.attachmentName
let blob = new Blob([response.data], { type: 'application/octet-stream' }) let blob = new Blob([response.data], { type: 'application/octet-stream' })
this.shadowRoot.getElementById('downloadProgressDialog').close()
this.saveFileToDisk(blob, filename)
})
} catch (error) {
console.error(error)
}
}
downloadFile(file) {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
this.shadowRoot.getElementById('downloadProgressDialog').open()
try {
axios.get(
`${nodeUrl}/arbitrary/FILE/${file.name}/${file.identifier}`,
{ responseType: 'blob' }
).then((response) => {
this.shadowRoot.getElementById('downloadProgressDialog').close()
let filename = file.appFileName
let blob = new Blob([response.data], { type: 'application/octet-stream' })
this.saveFileToDisk(blob, filename) this.saveFileToDisk(blob, filename)
}) })
} catch (error) { } catch (error) {
@ -1630,7 +1864,8 @@ class MessageTemplate extends LitElement {
await writable.write(contents) await writable.write(contents)
await writable.close() await writable.close()
} }
writeFile(fileHandle, blob).then(() => console.log('FILE SAVED'))
await writeFile(fileHandle, blob).then(() => console.log('FILE SAVED'))
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }

View File

@ -135,14 +135,18 @@ class ChatTextEditor extends LitElement {
this.insertFile(e.target.files[0]) this.insertFile(e.target.files[0])
const filePickerInput = this.shadowRoot.getElementById('file-picker') const filePickerInput = this.shadowRoot.getElementById('file-picker')
if (filePickerInput) { if (filePickerInput) {
filePickerInput.value = "" filePickerInput.value = ''
} }
}}" }}"
id="file-picker" id="file-picker"
class="file-picker-input" class="file-picker-input"
type="file" type="file"
name="myImage" name="myImage"
accept="image/*, .doc, .docx, .pdf, .zip, .pdf, .txt, .odt, .ods, .xls, .xlsx, .ppt, .pptx" accept="
image/*, .doc, .docx, .zip, .pdf, .txt, .odt, .ods, .html,
.xls, .xlsx, .ppt, .pptx, .jar, .gzip, .exe, .deb, .rar, .log,
.sh, .dmg, .pkg, .7z, .gz, .psd, .mp4, .rpm, .snap, .AppImage
"
> >
</div> </div>
</div> </div>
@ -295,7 +299,7 @@ class ChatTextEditor extends LitElement {
} }
sendMessageFunc(props) { sendMessageFunc(props) {
if (this.editor.isEmpty && (this.iframeId !== 'newChat' && this.iframeId !== 'newAttachmentChat')) return if (this.editor.isEmpty && (this.iframeId !== 'newChat' && this.iframeId !== 'newGifChat' && this.iframeId !== 'newAttachmentChat' && this.iframeId !== 'newFileChat')) return
this.getMessageSize(this.editor.getJSON()) this.getMessageSize(this.editor.getJSON())
@ -351,18 +355,42 @@ class ChatTextEditor extends LitElement {
repliedTo: '', repliedTo: '',
version: 3 version: 3
} }
} else if (this.gifFile && this.iframeId === 'newGifChat') {
messageObject = {
messageText: trimmedMessage,
images: [{
service: "IMAGE",
name: '123456789123456789123456789',
identifier: '123456'
}],
repliedTo: '',
version: 3
}
} else if (this.attachment && this.iframeId === 'newAttachmentChat') { } else if (this.attachment && this.iframeId === 'newAttachmentChat') {
messageObject = { messageObject = {
messageText: trimmedMessage, messageText: trimmedMessage,
attachments: [{ attachments: [{
service: "QCHAT_ATTACHMENT", service: "ATTACHMENT",
name: '123456789123456789123456789', name: '123456789123456789123456789',
identifier: '123456', identifier: '123456',
attachmentName: "123456789123456789123456789", attachmentName: "123456789123456789123456789",
attachmentSize: "123456" attachmentSize: "123456"
}], }],
repliedTo: '', repliedTo: '',
version: 2 version: 3
}
} else if (this.appFile && this.iframeId === 'newFileChat') {
messageObject = {
messageText: trimmedMessage,
files: [{
service: "FILE",
name: '123456789123456789123456789',
identifier: '123456',
appFileName: "123456789123456789123456789",
appFileSize: "123456"
}],
repliedTo: '',
version: 3
} }
} else { } else {
messageObject = { messageObject = {

View File

@ -426,7 +426,6 @@ export const chatpageStyles = css`
width: 800px; width: 800px;
} }
.close-icon { .close-icon {
color: #676b71; color: #676b71;
width: 18px; width: 18px;
@ -1152,6 +1151,22 @@ export const chatpageStyles = css`
width: 70%; width: 70%;
} }
.file-icon-container {
display: flex;
align-items: center;
justify-content: center;
height: 128px;
width: 128px;
border-radius: 50%;
border: none;
background-color: transparent;
}
.file-icon {
height: 128px;
width: 128px;
}
.attachment-name { .attachment-name {
font-family: Work Sans, sans-serif; font-family: Work Sans, sans-serif;
font-size: 20px; font-size: 20px;
@ -1440,6 +1455,7 @@ export const chatStyles = css`
--mdc-theme-secondary: var(--mdc-theme-primary); --mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-dialog-max-width: 85vw; --mdc-dialog-max-width: 85vw;
--mdc-dialog-max-height: 95vh; --mdc-dialog-max-height: 95vh;
} }
* :focus-visible { * :focus-visible {
@ -1567,7 +1583,6 @@ export const chatStyles = css`
min-width: 150px; min-width: 150px;
} }
.message-myBg { .message-myBg {
background-color: var(--chat-bubble-myBg) !important; background-color: var(--chat-bubble-myBg) !important;
} }
@ -2107,10 +2122,8 @@ export const chatStyles = css`
justify-content: space-evenly; justify-content: space-evenly;
padding: 5px 0 10px 0; padding: 5px 0 10px 0;
gap: 20px; gap: 20px;
cursor: pointer;
} }
.attachment-icon-container { .attachment-icon-container {
display: flex; display: flex;
align-items: center; align-items: center;
@ -2126,6 +2139,30 @@ export const chatStyles = css`
width: 70%; width: 70%;
} }
.file-container {
display: flex;
align-items: center;
justify-content: space-evenly;
padding: 5px 0 10px 0;
gap: 20px;
}
.file-icon-container {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
width: 50px;
border-radius: 50%;
border: none;
background-color: transparent;
}
.file-icon {
height: 50px;
width: 50px;
}
.attachment-info { .attachment-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -2158,6 +2195,7 @@ export const chatStyles = css`
color: var(--chat-bubble-msg-color); color: var(--chat-bubble-msg-color);
width: 19px; width: 19px;
background-color: transparent; background-color: transparent;
cursor: pointer;
} }
.download-icon:hover::before { .download-icon:hover::before {
@ -2247,6 +2285,155 @@ export const chatStyles = css`
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
paper-dialog.progress {
width: auto;
max-width: 50vw;
height: auto;
max-height: 30vh;
background-color: var(--white);
color: var(--black);
border: 1px solid var(--black);
border-radius: 15px;
text-align: center;
padding: 15px;
line-height: 1.6;
overflow: hidden;
}
paper-dialog.close-progress {
min-width: 550px;
max-width: 550px;
height: auto;
background-color: var(--white);
color: var(--black);
border: 1px solid var(--black);
border-radius: 15px;
text-align: center;
padding: 15px;
font-size: 17px;
font-weight: 500;
line-height: 20px;
overflow: hidden;
}
.lds-roller {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-roller div {
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.lds-roller div:after {
content: " ";
display: block;
position: absolute;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--black);
margin: -4px 0 0 -4px;
}
.lds-roller div:nth-child(1) {
animation-delay: -0.036s;
}
.lds-roller div:nth-child(1):after {
top: 63px;
left: 63px;
}
.lds-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.lds-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.lds-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.lds-roller div:nth-child(3):after {
top: 71px;
left: 48px;
}
.lds-roller div:nth-child(4) {
animation-delay: -0.144s;
}
.lds-roller div:nth-child(4):after {
top: 72px;
left: 40px;
}
.lds-roller div:nth-child(5) {
animation-delay: -0.18s;
}
.lds-roller div:nth-child(5):after {
top: 71px;
left: 32px;
}
.lds-roller div:nth-child(6) {
animation-delay: -0.216s;
}
.lds-roller div:nth-child(6):after {
top: 68px;
left: 24px;
}
.lds-roller div:nth-child(7) {
animation-delay: -0.252s;
}
.lds-roller div:nth-child(7):after {
top: 63px;
left: 17px;
}
.lds-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.lds-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes lds-roller {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.close-download {
color: var(--black);
font-size: 14px;
font-weight: bold;
position: absolute;
top: -15px;
right: -15px;
}
.close-download:hover {
color: #df3636;
}
` `
export const toolTipStyles = css` export const toolTipStyles = css`
@ -3631,6 +3818,12 @@ export const chatTextEditorStyles = css`
cursor: pointer; cursor: pointer;
} }
.ProseMirror {
word-wrap: break-word;
white-space: pre-wrap;
white-space: break-spaces;
}
.ProseMirror:focus { .ProseMirror:focus {
outline: none; outline: none;
} }