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:
parent
4276f54933
commit
96230a60f5
BIN
img/file-icon.png
Normal file
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
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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 = {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user