diff --git a/qortal-ui-plugins/package.json b/qortal-ui-plugins/package.json
index b117f3f3..31a7523d 100644
--- a/qortal-ui-plugins/package.json
+++ b/qortal-ui-plugins/package.json
@@ -20,10 +20,26 @@
"@lit-labs/motion": "^1.0.3",
"@material/mwc-list": "0.27.0",
"@material/mwc-select": "0.27.0",
+ "@tiptap/core": "^2.0.0-beta.209",
+ "@tiptap/extension-image": "^2.0.0-beta.209",
+ "@tiptap/extension-placeholder": "^2.0.0-beta.209",
+ "@tiptap/extension-underline": "^2.0.0-beta.209",
+ "@tiptap/html": "^2.0.0-beta.209",
+ "@tiptap/starter-kit": "^2.0.0-beta.209",
"asmcrypto.js": "2.3.2",
"compressorjs": "^1.1.1",
"emoji-picker-js": "https://github.com/Qortal/emoji-picker-js",
"localforage": "^1.10.0",
+ "prosemirror-commands": "^1.5.0",
+ "prosemirror-dropcursor": "^1.6.1",
+ "prosemirror-gapcursor": "^1.3.1",
+ "prosemirror-history": "^1.3.0",
+ "prosemirror-keymap": "^1.2.0",
+ "prosemirror-model": "^1.18.3",
+ "prosemirror-schema-list": "^1.2.2",
+ "prosemirror-state": "^1.4.2",
+ "prosemirror-transform": "^1.7.0",
+ "prosemirror-view": "^1.29.1",
"short-unique-id": "^4.4.4"
},
"devDependencies": {
@@ -47,8 +63,6 @@
"@polymer/paper-slider": "3.0.1",
"@polymer/paper-spinner": "3.0.2",
"@polymer/paper-tooltip": "3.0.1",
- "@vaadin/horizontal-layout": "23.3.2",
- "@vaadin/tabs": "23.3.2",
"@rollup/plugin-alias": "4.0.2",
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-commonjs": "24.0.0",
@@ -58,7 +72,9 @@
"@vaadin/avatar": "23.3.2",
"@vaadin/button": "23.3.2",
"@vaadin/grid": "23.3.2",
+ "@vaadin/horizontal-layout": "23.3.2",
"@vaadin/icons": "23.3.2",
+ "@vaadin/tabs": "23.3.2",
"@vaadin/tooltip": "23.3.2",
"epml": "0.3.3",
"file-saver": "2.0.5",
diff --git a/qortal-ui-plugins/plugins/core/components/ChatPage.js b/qortal-ui-plugins/plugins/core/components/ChatPage.js
index 39fb2a50..e117b082 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatPage.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatPage.js
@@ -4,6 +4,12 @@ import {animate} from '@lit-labs/motion';
import { Epml } from '../../../epml.js';
import { use, get, translate, registerTranslateConfig } from 'lit-translate';
import { chatStyles } from './ChatScroller-css.js'
+import { generateHTML } from '@tiptap/core'
+import StarterKit from '@tiptap/starter-kit'
+import Underline from '@tiptap/extension-underline';
+import Placeholder from '@tiptap/extension-placeholder'
+import {unsafeHTML} from 'lit/directives/unsafe-html.js';
+import { Editor, Extension } from '@tiptap/core'
// import localForage from "localforage";
registerTranslateConfig({
@@ -72,8 +78,6 @@ class ChatPage extends LitElement {
iframeHeight: { type: Number },
imageFile: { type: Object },
isUploadingImage: { type: Boolean },
- chatEditor: { type: Object },
- chatEditorNewChat: { type: Object },
userLanguage: { type: String },
lastMessageRefVisible: { type: Boolean },
isLoadingOldMessages: { type: Boolean },
@@ -91,7 +95,9 @@ class ChatPage extends LitElement {
userFoundModalOpen: { type: Boolean },
webWorker: { type: Object },
webWorkerImage: { type: Object },
- myTrimmedMeassage: { type: String }
+ myTrimmedMeassage: { type: String },
+ editor: {type: Object},
+ currentEditor: {type: String}
}
}
@@ -299,6 +305,7 @@ class ChatPage extends LitElement {
justify-content: center;
min-height: 60px;
max-height: 100%;
+ overflow: hidden;
}
.chat-text-area .typing-area {
@@ -348,6 +355,10 @@ class ChatPage extends LitElement {
gap: 5px;
width: 100%;
}
+ .repliedTo-message p {
+ margin: 0px;
+ padding: 0px;
+ }
.reply-icon {
width: 20px;
@@ -858,6 +869,7 @@ class ChatPage extends LitElement {
}
this.webWorker = null;
this.webWorkerImage = null;
+ this.currentEditor = '_chatEditorDOM'
}
_toggle(value) {
@@ -922,7 +934,11 @@ class ChatPage extends LitElement {
${this.repliedToMessageObj.senderName ? this.repliedToMessageObj.senderName : this.repliedToMessageObj.sender}
-
${this.repliedToMessageObj.message}
+ ${unsafeHTML(generateHTML(this.repliedToMessageObj.message, [
+ StarterKit,
+ Underline
+ // other extensions …
+ ]))}
${translate("chatpage.cchange25")}
-
${this.editedMessageObj.message}
+ ${unsafeHTML(generateHTML(this.editedMessageObj.message, [
+ StarterKit,
+ Underline
+ // other extensions …
+ ]))}
this.setChatEditor(editor)}
- .chatEditor=${this.chatEditor}
.imageFile=${this.imageFile}
.insertImage=${this.insertImage}
.editedMessageObj=${this.editedMessageObj}
?isLoading=${this.isLoading}
?isLoadingMessages=${this.isLoadingMessages}
- ?isEditMessageOpen=${this.isEditMessageOpen}>
+ ?isEditMessageOpen=${this.isEditMessageOpen}
+ .editor=${this.editor}
+ .updatePlaceholder=${(editor, value)=> this.updatePlaceholder(editor, value)}
+ id="_chatEditorDOM"
+ >
@@ -985,10 +1007,9 @@ class ChatPage extends LitElement {
`: ''}
{
- this.chatEditorNewChat.resetValue();
this.removeImage();
}}
- style=${(this.imageFile && !this.isUploadingImage) ? "display: block" : "display: none"}>
+ style=${(this.imageFile && !this.isUploadingImage) ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100"}>
${this.imageFile && html`
@@ -1000,20 +1021,20 @@ class ChatPage extends LitElement {
?hasGlobalEvents=${false}
placeholder=${this.chatEditorPlaceholder}
._sendMessage=${this._sendMessage}
- .setChatEditor=${(editor)=> this.setChatEditorNewChat(editor)}
- .chatEditor=${this.chatEditorNewChat}
.imageFile=${this.imageFile}
.insertImage=${this.insertImage}
.editedMessageObj=${this.editedMessageObj}
?isLoading=${this.isLoading}
?isLoadingMessages=${this.isLoadingMessages}
id="chatTextCaption"
+ .editor=${this.editorImage}
+ .updatePlaceholder=${(editor, value)=> this.updatePlaceholder(editor, value)}
>
`}
@@ -501,7 +516,8 @@ class MessageTemplate extends LitElement {
id="messageContent"
class="message"
style=${(image && replacedMessage !== "") &&"margin-top: 15px;"}>
- ${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
+
+ ${unsafeHTML(messageVersion2)}
@@ -783,7 +796,6 @@ class ChatMenu extends LitElement {
return
}
this.setEditedMessageObj(this.originalMessage);
- this.focusChatEditor();
}}>
diff --git a/qortal-ui-plugins/plugins/core/components/ChatTextEditor copy.js b/qortal-ui-plugins/plugins/core/components/ChatTextEditor copy.js
new file mode 100644
index 00000000..dfc572bc
--- /dev/null
+++ b/qortal-ui-plugins/plugins/core/components/ChatTextEditor copy.js
@@ -0,0 +1,828 @@
+import { LitElement, html, css } from "lit";
+import { get } from 'lit-translate';
+import { escape, unescape } from 'html-escaper';
+import { EmojiPicker } from 'emoji-picker-js';
+import { inputKeyCodes } from '../../utils/keyCodes.js';
+import { Epml } from '../../../epml.js';
+
+const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
+class ChatTextEditor extends LitElement {
+ static get properties() {
+ return {
+ isLoading: { type: Boolean },
+ isLoadingMessages: { type: Boolean },
+ _sendMessage: { attribute: false },
+ placeholder: { type: String },
+ imageFile: { type: Object },
+ insertImage: { attribute: false },
+ iframeHeight: { type: Number },
+ editedMessageObj: { type: Object },
+ chatEditor: { type: Object },
+ setChatEditor: { attribute: false },
+ iframeId: { type: String },
+ hasGlobalEvents: { type: Boolean },
+ chatMessageSize: { type: Number },
+ isEditMessageOpen: { type: Boolean },
+ theme: {
+ type: String,
+ reflect: true
+ }
+ }
+ }
+
+ static get styles() {
+ return css`
+ :host {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ height: auto;
+ overflow-y: hidden;
+ width: 100%;
+ }
+ .chatbar-container {
+ width: 100%;
+ display: flex;
+ height: auto;
+ overflow: hidden;
+ }
+
+ .chatbar-caption {
+ border-bottom: 2px solid var(--mdc-theme-primary);
+ }
+
+ .emoji-button {
+ width: 45px;
+ height: 40px;
+ padding-top: 4px;
+ border: none;
+ outline: none;
+ background: transparent;
+ cursor: pointer;
+ max-height: 40px;
+ color: var(--black);
+ }
+
+ .message-size-container {
+ display: flex;
+ justify-content: flex-end;
+ width: 100%;
+ }
+
+ .message-size {
+ font-family: Roboto, sans-serif;
+ font-size: 12px;
+ color: black;
+ }
+
+ .paperclip-icon {
+ color: var(--paperclip-icon);
+ width: 25px;
+ }
+
+ .paperclip-icon:hover {
+ cursor: pointer;
+ }
+
+ .send-icon {
+ width: 30px;
+ margin-left: 5px;
+ transition: all 0.1s ease-in-out;
+ cursor: pointer;
+ }
+
+ .send-icon:hover {
+ filter: brightness(1.1);
+ }
+
+ .file-picker-container {
+ position: relative;
+ height: 25px;
+ width: 25px;
+ }
+
+ .file-picker-input-container {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ z-index: 10;
+ opacity: 0;
+ overflow: hidden;
+ }
+
+ input[type=file]::-webkit-file-upload-button {
+ cursor: pointer;
+ }
+
+ .chatbar-container textarea {
+ display: none;
+ }
+
+ .chatbar-container .chat-editor {
+ display: flex;
+ max-height: -webkit-fill-available;
+ width: 100%;
+ border-color: transparent;
+ margin: 0;
+ padding: 0;
+ border: none;
+ }
+
+ .checkmark-icon {
+ width: 30px;
+ color: var(--mdc-theme-primary);
+ margin-bottom: 6px;
+ }
+
+ .checkmark-icon:hover {
+ cursor: pointer;
+ }
+ `
+ }
+
+ constructor() {
+ super()
+ this.isLoadingMessages = true
+ this.isLoading = false
+ this.getMessageSize = this.getMessageSize.bind(this)
+ this.calculateIFrameHeight = this.calculateIFrameHeight.bind(this)
+ this.resetIFrameHeight = this.resetIFrameHeight.bind(this)
+ this.addGlobalEventListener = this.addGlobalEventListener.bind(this)
+ this.sendMessageFunc = this.sendMessageFunc.bind(this)
+ this.removeGlobalEventListener = this.removeGlobalEventListener.bind(this)
+ this.initialChat = this.initialChat.bind(this)
+ this.iframeHeight = 42
+ this.chatMessageSize = 0
+ this.userName = window.parent.reduxStore.getState().app.accountInfo.names[0]
+ this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
+ }
+
+ render() {
+ let scrollHeightBool = false;
+ try {
+ if (this.chatMessageInput && this.chatMessageInput.contentDocument.body.scrollHeight > 60 && this.shadowRoot.querySelector(".chat-editor").contentDocument.body.querySelector("#chatbarId").innerHTML.trim() !== "") {
+ scrollHeightBool = true;
+ }
+ } catch (error) {
+ scrollHeightBool = false;
+ }
+ return html`
+
+
{
+ this.preventUserSendingImage(e)
+ }}>
+
+
+
+ {
+ this.insertImage(e.target.files[0]);
+ const filePickerInput = this.shadowRoot.getElementById('file-picker')
+ if(filePickerInput){
+ filePickerInput.value = ""
+ }
+ }
+ }"
+ id="file-picker"
+ class="file-picker-input" type="file" name="myImage" accept="image/*" />
+
+
+
+
+
+ ${this.editedMessageObj ? (
+ html`
+
+ ${this.isLoading === false ? html`
+
{
+ this.sendMessageFunc();
+ }}
+ >
+
+ ` :
+ html`
+
+ `}
+
+ `
+ ) :
+ html`
+
+ ${this.isLoading === false ? html`
+
![send-icon](/img/qchat-send-message-icon.svg)
{
+ this.sendMessageFunc();
+ }}
+ />
+ ` :
+ html`
+
+ `}
+
+ `
+ }
+
+ ${this.chatMessageSize >= 750 ?
+ html`
+
+
+ ${`Your message size is of ${this.chatMessageSize} bytes out of a maximum of 1000`}
+
+
+ ` :
+ html``}
+
+ `
+ }
+
+ preventUserSendingImage(e) {
+ if (!this.userName) {
+ e.preventDefault();
+ parentEpml.request('showSnackBar', get("chatpage.cchange27"));
+ };
+ }
+
+ initialChat(e) {
+ if (!this.chatEditor?.contentDiv.matches(':focus')) {
+ // WARNING: Deprecated methods from KeyBoard Event
+ if (e.code === "Space" || e.keyCode === 32 || e.which === 32) {
+ this.chatEditor.insertText(' ');
+ } else if (inputKeyCodes.includes(e.keyCode)) {
+ this.chatEditor.insertText(e.key);
+ return this.chatEditor.focus();
+ } else {
+ return this.chatEditor.focus();
+ }
+ }
+ }
+
+ addGlobalEventListener(){
+ document.addEventListener('keydown', this.initialChat);
+ }
+
+ removeGlobalEventListener(){
+ document.removeEventListener('keydown', this.initialChat);
+ }
+
+ async firstUpdated() {
+ if (this.hasGlobalEvents) {
+ this.addGlobalEventListener();
+ }
+
+ window.addEventListener('storage', () => {
+ const checkTheme = localStorage.getItem('qortalTheme');
+ const chatbar = this.shadowRoot.getElementById(this.iframeId).contentWindow.document.getElementById('chatbarId');
+ if (checkTheme === 'dark') {
+ this.theme = 'dark';
+ chatbar.style.cssText = "color:#ffffff;"
+ } else {
+ this.theme = 'light';
+ chatbar.style.cssText = "color:#080808;"
+ }
+ })
+
+ this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button');
+ this.mirrorChatInput = this.shadowRoot.getElementById('messageBox');
+ this.chatMessageInput = this.shadowRoot.getElementById(this.iframeId);
+
+ this.emojiPicker = new EmojiPicker({
+ style: "twemoji",
+ twemojiBaseUrl: '/emoji/',
+ showPreview: false,
+ showVariants: false,
+ showAnimation: false,
+ position: 'top-start',
+ boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px',
+ zIndex: 100
+
+ });
+
+ this.emojiPicker.on('emoji', selection => {
+ const emojiHtmlString = `
`;
+ this.chatEditor.insertEmoji(emojiHtmlString);
+ });
+
+
+ this.emojiPickerHandler.addEventListener('click', () => this.emojiPicker.togglePicker(this.emojiPickerHandler));
+
+ await this.updateComplete;
+ this.initChatEditor();
+ }
+
+ async updated(changedProperties) {
+ if (changedProperties && changedProperties.has('editedMessageObj')) {
+ if (this.editedMessageObj) {
+ this.chatEditor.insertText(this.editedMessageObj.message);
+ this.getMessageSize(this.editedMessageObj.message);
+ } else {
+ this.chatEditor.insertText("");
+ this.chatMessageSize = 0;
+ }
+ }
+ if (changedProperties && changedProperties.has('placeholder')) {
+ const captionEditor = this.shadowRoot.getElementById(this.iframeId).contentWindow.document.getElementById('chatbarId');
+ captionEditor.setAttribute('data-placeholder', this.placeholder);
+ }
+
+ if (changedProperties && changedProperties.has("imageFile")) {
+ this.chatMessageInput = "newChat";
+ }
+ }
+
+ shouldUpdate(changedProperties) {
+ // Only update element if prop1 changed.
+ if(changedProperties.has('setChatEditor') && changedProperties.size === 1) return false
+ return true
+ }
+
+ sendMessageFunc(props) {
+ if (this.chatMessageSize > 1000 ) {
+ parentEpml.request('showSnackBar', get("chatpage.cchange29"));
+ return;
+ };
+ this.chatMessageSize = 0;
+ this.chatEditor.updateMirror();
+ this._sendMessage(props);
+ }
+
+ getMessageSize(message){
+ try {
+ const messageText = message;
+ // Format and Sanitize Message
+ const sanitizedMessage = messageText.replace(/ /gi, ' ').replace(/
/gi, '\n');
+ const trimmedMessage = sanitizedMessage.trim();
+ let messageObject = {};
+
+ if (this.repliedToMessageObj) {
+ let chatReference = this.repliedToMessageObj.reference;
+ if (this.repliedToMessageObj.chatReference) {
+ chatReference = this.repliedToMessageObj.chatReference;
+ }
+ messageObject = {
+ messageText: trimmedMessage,
+ images: [''],
+ repliedTo: chatReference,
+ version: 1
+ }
+ } else if (this.editedMessageObj) {
+ let message = "";
+ try {
+ const parsedMessageObj = JSON.parse(this.editedMessageObj.decodedMessage);
+ message = parsedMessageObj;
+ } catch (error) {
+ message = this.messageObj.decodedMessage
+ }
+ messageObject = {
+ ...message,
+ messageText: trimmedMessage,
+ }
+ } else if(this.imageFile && this.iframeId === 'newChat') {
+ messageObject = {
+ messageText: trimmedMessage,
+ images: [{
+ service: "QCHAT_IMAGE",
+ name: '123456789123456789123456789',
+ identifier: '123456'
+ }],
+ repliedTo: '',
+ version: 1
+ };
+ } else {
+ messageObject = {
+ messageText: trimmedMessage,
+ images: [''],
+ repliedTo: '',
+ version: 1
+ };
+ }
+
+ const stringified = JSON.stringify(messageObject);
+ const size = new Blob([stringified]).size;
+ this.chatMessageSize = size;
+ } catch (error) {
+ console.error(error)
+ }
+
+ }
+
+ calculateIFrameHeight(height) {
+ setTimeout(()=> {
+ const editorTest = this.shadowRoot.getElementById(this.iframeId).contentWindow.document.getElementById('chatbarId').scrollHeight;
+ this.iframeHeight = editorTest + 20;
+ }, 50)
+ }
+ resetIFrameHeight(height) {
+ this.iframeHeight = 42;
+ }
+ initChatEditor() {
+ const ChatEditor = function (editorConfig) {
+ const ChatEditor = function () {
+ const editor = this;
+ editor.init();
+ };
+
+ ChatEditor.prototype.getValue = function () {
+ const editor = this;
+
+ if (editor.contentDiv) {
+ return editor.contentDiv.innerHTML;
+ }
+ };
+
+ ChatEditor.prototype.setValue = function (value) {
+ const editor = this;
+
+ if (value) {
+ editor.contentDiv.innerHTML = value;
+ editor.updateMirror();
+ }
+
+ editor.focus();
+ };
+
+ ChatEditor.prototype.resetValue = function () {
+ const editor = this;
+ editor.contentDiv.innerHTML = '';
+ editor.updateMirror();
+ editor.focus();
+ editorConfig.resetIFrameHeight()
+ };
+
+ ChatEditor.prototype.styles = function () {
+ const editor = this;
+
+ editor.styles = document.createElement('style');
+ editor.styles.setAttribute('type', 'text/css');
+ editor.styles.innerText = `
+ html {
+ cursor: text;
+ }
+
+ .chatbar-body {
+ display: flex;
+ align-items: center;
+ }
+
+ .chatbar-body::-webkit-scrollbar-track {
+ background-color: whitesmoke;
+ border-radius: 7px;
+ }
+
+ .chatbar-body::-webkit-scrollbar {
+ width: 6px;
+ border-radius: 7px;
+ background-color: whitesmoke;
+ }
+
+ .chatbar-body::-webkit-scrollbar-thumb {
+ background-color: rgb(180, 176, 176);
+ border-radius: 7px;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .chatbar-body::-webkit-scrollbar-thumb:hover {
+ background-color: rgb(148, 146, 146);
+ cursor: pointer;
+ }
+
+ div {
+ font-size: 1rem;
+ line-height: 1.38rem;
+ font-weight: 400;
+ font-family: "Open Sans", helvetica, sans-serif;
+ padding-right: 3px;
+ text-align: left;
+ white-space: break-spaces;
+ word-break: break-word;
+ outline: none;
+ min-height: 20px;
+ width: 100%;
+ }
+
+ div[contentEditable=true]:empty:before {
+ content: attr(data-placeholder);
+ display: block;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ user-select: none;
+ white-space: nowrap;
+ opacity: 0.7;
+ }
+
+ div[contentEditable=false]{
+ background: rgba(0,0,0,0.1);
+ width: 100%;
+ }
+
+ img.emoji {
+ width: 1.7em;
+ height: 1.5em;
+ margin-bottom: -2px;
+ vertical-align: bottom;
+ }
+ `;
+ editor.content.head.appendChild(editor.styles);
+ };
+
+ ChatEditor.prototype.enable = function () {
+ const editor = this;
+
+ editor.contentDiv.setAttribute('contenteditable', 'true');
+ editor.focus();
+ };
+
+ ChatEditor.prototype.getMirrorElement = function (){
+ return editor.mirror
+ }
+
+ ChatEditor.prototype.disable = function () {
+ const editor = this;
+
+ editor.contentDiv.setAttribute('contenteditable', 'false');
+ };
+
+ ChatEditor.prototype.state = function () {
+ const editor = this;
+
+ return editor.contentDiv.getAttribute('contenteditable');
+ };
+
+ ChatEditor.prototype.focus = function () {
+ const editor = this;
+
+ editor.contentDiv.focus();
+ };
+
+ ChatEditor.prototype.clearSelection = function () {
+ const editor = this;
+
+ let selection = editor.content.getSelection().toString();
+ if (!/^\s*$/.test(selection)) editor.content.getSelection().removeAllRanges();
+ };
+
+ ChatEditor.prototype.insertEmoji = function (emojiImg) {
+ const editor = this;
+
+ const doInsert = () => {
+
+ if (editor.content.queryCommandSupported("InsertHTML")) {
+ editor.content.execCommand("insertHTML", false, emojiImg);
+ editor.updateMirror();
+ }
+ };
+
+ editor.focus();
+ return doInsert();
+ };
+
+ ChatEditor.prototype.insertText = function (text) {
+ const editor = this;
+
+ const parsedText = editorConfig.emojiPicker.parse(text);
+ const doPaste = () => {
+
+ if (editor.content.queryCommandSupported("InsertHTML")) {
+ editor.content.execCommand("insertHTML", false, parsedText);
+ editor.updateMirror();
+ }
+ };
+
+ editor.focus();
+ return doPaste();
+ };
+
+ ChatEditor.prototype.updateMirror = function () {
+ const editor = this;
+
+ const chatInputValue = editor.getValue();
+ const filteredValue = chatInputValue.replace(//g, '');
+
+ let unescapedValue = editorConfig.unescape(filteredValue);
+ editor.mirror.value = unescapedValue;
+ };
+
+ ChatEditor.prototype.listenChanges = function () {
+
+ const editor = this;
+
+ const events = ['drop', 'contextmenu', 'mouseup', 'click', 'touchend', 'keydown', 'blur', 'paste']
+
+ for (let i = 0; i < events.length; i++) {
+ const event = events[i]
+ editor.content.body.addEventListener(event, async function (e) {
+
+ if (e.type === 'click') {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ if (e.type === 'paste') {
+ e.preventDefault();
+ const item_list = await navigator.clipboard.read();
+ let image_type; // we will feed this later
+ const item = item_list.find( item => // choose the one item holding our image
+ item.types.some( type => {
+ if (type.startsWith( 'image/')) {
+ image_type = type;
+ return true;
+ }
+ })
+ );
+ if(item){
+ const blob = item && await item.getType( image_type );
+ var file = new File([blob], "name", {
+ type: image_type
+ });
+
+ editorConfig.insertImage(file)
+ } else {
+ navigator.clipboard.readText()
+ .then(clipboardText => {
+ let escapedText = editorConfig.escape(clipboardText);
+ editor.insertText(escapedText);
+ })
+ .then(() => {
+ editorConfig.getMessageSize(editorConfig.editableElement.contentDocument.body.querySelector("#chatbarId").innerHTML);
+ })
+ .catch(err => {
+ // Fallback if everything fails...
+ let textData = (e.originalEvent || e).clipboardData.getData('text/plain');
+ editor.insertText(textData);
+ })
+ }
+
+
+ return false;
+ }
+
+ if (e.type === 'contextmenu') {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+
+ if (e.type === 'keydown') {
+ await new Promise((res, rej) => {
+ setTimeout(() => {
+ editorConfig.calculateIFrameHeight(editorConfig.editableElement.contentDocument.body.scrollHeight);
+ editorConfig.getMessageSize(editorConfig.editableElement.contentDocument.body.querySelector("#chatbarId").innerHTML);
+ }, 0);
+ res();
+ })
+
+ // Handle Enter
+ if (e.keyCode === 13 && !e.shiftKey) {
+
+
+ if (editor.state() === 'false') return false;
+ if (editorConfig.iframeId === 'newChat') {
+ editorConfig.sendFunc(
+ {
+ type: 'image',
+ imageFile: editorConfig.imageFile,
+ }
+ );
+ } else {
+ editorConfig.sendFunc();
+ }
+
+ e.preventDefault();
+ return false;
+ }
+
+ // Handle Commands with CTR or CMD
+ if (e.ctrlKey || e.metaKey) {
+ switch (e.keyCode) {
+ case 66:
+ case 98: e.preventDefault();
+ return false;
+ case 73:
+ case 105: e.preventDefault();
+ return false;
+ case 85:
+ case 117: e.preventDefault();
+ return false;
+ }
+
+ return false;
+ }
+ }
+
+ if (e.type === 'blur') {
+ editor.clearSelection();
+ }
+
+ if (e.type === 'drop') {
+ e.preventDefault();
+
+ let droppedText = e.dataTransfer.getData('text/plain')
+ let escapedText = editorConfig.escape(droppedText)
+
+ editor.insertText(escapedText);
+ return false;
+ }
+
+ editor.updateMirror();
+ });
+ }
+
+ editor.content.addEventListener('click', function (event) {
+ event.preventDefault();
+ editor.focus();
+ });
+ };
+
+ ChatEditor.prototype.remove = function () {
+ const editor = this;
+ var old_element = editor.content.body;
+ var new_element = old_element.cloneNode(true);
+ editor.content.body.parentNode.replaceChild(new_element, old_element);
+ while (editor.content.body.firstChild) {
+ editor.content.body.removeChild(editor.content.body.lastChild);
+ }
+
+ };
+
+ ChatEditor.prototype.init = function () {
+ const editor = this;
+
+ editor.frame = editorConfig.editableElement;
+ editor.mirror = editorConfig.mirrorElement;
+
+ editor.content = (editor.frame.contentDocument || editor.frame.document);
+ editor.content.body.classList.add("chatbar-body");
+
+ let elemDiv = document.createElement('div');
+ elemDiv.setAttribute('contenteditable', 'true');
+ elemDiv.setAttribute('spellcheck', 'false');
+ elemDiv.setAttribute('data-placeholder', editorConfig.placeholder);
+ elemDiv.style.cssText = `width:100%; ${editorConfig.theme === "dark" ? "color:#ffffff;" : "color: #080808"}`;
+ elemDiv.id = 'chatbarId';
+ editor.content.body.appendChild(elemDiv);
+ editor.contentDiv = editor.frame.contentDocument.body.firstChild;
+ editor.styles();
+ editor.listenChanges();
+
+ };
+
+
+ function doInit() {
+ return new ChatEditor();
+ }
+ return doInit();
+ };
+
+ const editorConfig = {
+ getMessageSize: this.getMessageSize,
+ calculateIFrameHeight: this.calculateIFrameHeight,
+ mirrorElement: this.mirrorChatInput,
+ editableElement: this.chatMessageInput,
+ sendFunc: this.sendMessageFunc,
+ emojiPicker: this.emojiPicker,
+ escape: escape,
+ unescape: unescape,
+ placeholder: this.placeholder,
+ imageFile: this.imageFile,
+ requestUpdate: this.requestUpdate,
+ insertImage: this.insertImage,
+ chatMessageSize: this.chatMessageSize,
+ addGlobalEventListener: this.addGlobalEventListener,
+ removeGlobalEventListener: this.removeGlobalEventListener,
+ iframeId: this.iframeId,
+ theme: this.theme,
+ resetIFrameHeight: this.resetIFrameHeight
+ };
+ const newChat = new ChatEditor(editorConfig);
+ this.setChatEditor(newChat);
+ }
+}
+
+window.customElements.define("chat-text-editor", ChatTextEditor)
diff --git a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
index dfc572bc..6ce77fbc 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
@@ -4,6 +4,10 @@ import { escape, unescape } from 'html-escaper';
import { EmojiPicker } from 'emoji-picker-js';
import { inputKeyCodes } from '../../utils/keyCodes.js';
import { Epml } from '../../../epml.js';
+import { Editor } from '@tiptap/core'
+import StarterKit from '@tiptap/starter-kit'
+import Underline from '@tiptap/extension-underline';
+import Image from '@tiptap/extension-image'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
class ChatTextEditor extends LitElement {
@@ -17,12 +21,12 @@ class ChatTextEditor extends LitElement {
insertImage: { attribute: false },
iframeHeight: { type: Number },
editedMessageObj: { type: Object },
- chatEditor: { type: Object },
setChatEditor: { attribute: false },
iframeId: { type: String },
hasGlobalEvents: { type: Boolean },
chatMessageSize: { type: Number },
isEditMessageOpen: { type: Boolean },
+ editor: {type: Object},
theme: {
type: String,
reflect: true
@@ -39,8 +43,8 @@ class ChatTextEditor extends LitElement {
justify-content: center;
align-items: center;
height: auto;
- overflow-y: hidden;
width: 100%;
+ overflow-y: hidden;
}
.chatbar-container {
width: 100%;
@@ -63,6 +67,7 @@ class ChatTextEditor extends LitElement {
cursor: pointer;
max-height: 40px;
color: var(--black);
+ margin-bottom: 5px;
}
.message-size-container {
@@ -101,6 +106,7 @@ class ChatTextEditor extends LitElement {
position: relative;
height: 25px;
width: 25px;
+ margin-bottom: 10px;
}
.file-picker-input-container {
@@ -141,6 +147,129 @@ class ChatTextEditor extends LitElement {
.checkmark-icon:hover {
cursor: pointer;
}
+
+ .element {
+ width: 100%;
+ max-height: 100%;
+ overflow: auto;
+ color: var(--black);
+ padding: 0px 10px;
+ }
+ .element::-webkit-scrollbar-track {
+ background-color: whitesmoke;
+ border-radius: 7px;
+ }
+
+ .element::-webkit-scrollbar {
+ width: 6px;
+ border-radius: 7px;
+ background-color: whitesmoke;
+ }
+
+ .element::-webkit-scrollbar-thumb {
+ background-color: rgb(180, 176, 176);
+ border-radius: 7px;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .element::-webkit-scrollbar-thumb:hover {
+ background-color: rgb(148, 146, 146);
+ cursor: pointer;
+ }
+ .ProseMirror:focus {
+ outline: none;
+ }
+
+ .is-active {
+ background-color: var(--white)
+ }
+
+ .ProseMirror > * + * {
+ margin-top: 0.75em;
+ outline: none;
+ }
+
+ .ProseMirror ul,
+ ol {
+ padding: 0 1rem;
+ }
+
+ .ProseMirror h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ line-height: 1.1;
+ }
+
+ .ProseMirror code {
+ background-color: rgba(#616161, 0.1);
+ color: #616161;
+ }
+
+ .ProseMirror pre {
+ background: #0D0D0D;
+ color: #FFF;
+ font-family: 'JetBrainsMono', monospace;
+ padding: 0.75rem 1rem;
+ border-radius: 0.5rem;
+ }
+ .ProseMirror pre code {
+ color: inherit;
+ padding: 0;
+ background: none;
+ font-size: 0.8rem;
+ }
+
+
+ .ProseMirror img {
+ width: 1.7em;
+ height: 1.5em;
+ margin: 0px;
+
+ }
+
+ .ProseMirror blockquote {
+ padding-left: 1rem;
+ border-left: 2px solid rgba(#0D0D0D, 0.1);
+ }
+
+ .ProseMirror hr {
+ border: none;
+ border-top: 2px solid rgba(#0D0D0D, 0.1);
+ margin: 2rem 0;
+ }
+ .chatbar-button-single {
+ background: var(--white);
+ outline: none;
+ border: none;
+ color: var(--black);
+ padding: 4px 8px;
+ border-radius: 5px;
+ cursor: pointer;
+ margin-right: 2px;
+ filter: brightness(100%);
+ transition: all 0.2s;
+ }
+ .chatbar-button-single:hover {
+ filter: brightness(120%);
+ }
+ .chatbar-buttons {
+ visibility: hidden;
+ transition: all .2s;
+ }
+ .chatbar-container:hover .chatbar-buttons {
+ visibility: visible;
+ }
+ .ProseMirror p.is-editor-empty:first-child::before {
+ color: #adb5bd;
+ content: attr(data-placeholder);
+ float: left;
+ height: 0;
+ pointer-events: none;
+}
+
`
}
@@ -159,21 +288,68 @@ class ChatTextEditor extends LitElement {
this.chatMessageSize = 0
this.userName = window.parent.reduxStore.getState().app.accountInfo.names[0]
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
+ this.editor = null
}
render() {
+ console.log('this.editor', this.editor)
let scrollHeightBool = false;
try {
- if (this.chatMessageInput && this.chatMessageInput.contentDocument.body.scrollHeight > 60 && this.shadowRoot.querySelector(".chat-editor").contentDocument.body.querySelector("#chatbarId").innerHTML.trim() !== "") {
+ console.log('this.chatMessageInput', this.chatMessageInput)
+ if (this.chatMessageInput && this.chatMessageInput.scrollHeight > 60) {
scrollHeightBool = true;
}
} catch (error) {
scrollHeightBool = false;
}
return html`
+
+ style="align-items: flex-end; position: relative">
+
+
+
+
+
+
-
+
+
${this.editedMessageObj ? (
html`
-
+
${this.isLoading === false ? html`
@@ -271,17 +446,17 @@ class ChatTextEditor extends LitElement {
}
initialChat(e) {
- if (!this.chatEditor?.contentDiv.matches(':focus')) {
- // WARNING: Deprecated methods from KeyBoard Event
- if (e.code === "Space" || e.keyCode === 32 || e.which === 32) {
- this.chatEditor.insertText(' ');
- } else if (inputKeyCodes.includes(e.keyCode)) {
- this.chatEditor.insertText(e.key);
- return this.chatEditor.focus();
- } else {
- return this.chatEditor.focus();
- }
- }
+ // if (!this.chatEditor?.contentDiv.matches(':focus')) {
+ // // WARNING: Deprecated methods from KeyBoard Event
+ // if (e.code === "Space" || e.keyCode === 32 || e.which === 32) {
+ // this.chatEditor.insertText(' ');
+ // } else if (inputKeyCodes.includes(e.keyCode)) {
+ // this.chatEditor.insertText(e.key);
+ // return this.chatEditor.focus();
+ // } else {
+ // return this.chatEditor.focus();
+ // }
+ // }
}
addGlobalEventListener(){
@@ -294,24 +469,38 @@ class ChatTextEditor extends LitElement {
async firstUpdated() {
if (this.hasGlobalEvents) {
- this.addGlobalEventListener();
+ // this.addGlobalEventListener();
}
-
+ Image.configure({
+ inline: true,
+ })
+ // this.editor = new Editor({
+ // element: this.shadowRoot.querySelector('.element'),
+ // extensions: [
+ // StarterKit,
+ // Underline,
+ // Image
+ // ],
+ // content: 'Hello World!
',
+ // })
+
window.addEventListener('storage', () => {
const checkTheme = localStorage.getItem('qortalTheme');
- const chatbar = this.shadowRoot.getElementById(this.iframeId).contentWindow.document.getElementById('chatbarId');
+ const chatbar = this.shadowRoot.querySelector('.element')
if (checkTheme === 'dark') {
this.theme = 'dark';
chatbar.style.cssText = "color:#ffffff;"
+
} else {
this.theme = 'light';
chatbar.style.cssText = "color:#080808;"
+
}
})
this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button');
this.mirrorChatInput = this.shadowRoot.getElementById('messageBox');
- this.chatMessageInput = this.shadowRoot.getElementById(this.iframeId);
+ this.chatMessageInput = this.shadowRoot.querySelector('.element')
this.emojiPicker = new EmojiPicker({
style: "twemoji",
@@ -327,29 +516,32 @@ class ChatTextEditor extends LitElement {
this.emojiPicker.on('emoji', selection => {
const emojiHtmlString = `
`;
- this.chatEditor.insertEmoji(emojiHtmlString);
+ console.log('hello insert 6', selection)
+ this.editor.commands.insertContent(selection.emoji, {
+ parseOptions: {
+ preserveWhitespace: false
+ }
+ })
});
this.emojiPickerHandler.addEventListener('click', () => this.emojiPicker.togglePicker(this.emojiPickerHandler));
await this.updateComplete;
- this.initChatEditor();
+ // this.initChatEditor();
}
async updated(changedProperties) {
if (changedProperties && changedProperties.has('editedMessageObj')) {
if (this.editedMessageObj) {
- this.chatEditor.insertText(this.editedMessageObj.message);
+ this.editor.commands.setContent(this.editedMessageObj.message)
this.getMessageSize(this.editedMessageObj.message);
} else {
- this.chatEditor.insertText("");
this.chatMessageSize = 0;
}
}
if (changedProperties && changedProperties.has('placeholder')) {
- const captionEditor = this.shadowRoot.getElementById(this.iframeId).contentWindow.document.getElementById('chatbarId');
- captionEditor.setAttribute('data-placeholder', this.placeholder);
+ this.updatePlaceholder(this.editor, this.placeholder )
}
if (changedProperties && changedProperties.has("imageFile")) {
@@ -364,13 +556,12 @@ class ChatTextEditor extends LitElement {
}
sendMessageFunc(props) {
- if (this.chatMessageSize > 1000 ) {
- parentEpml.request('showSnackBar', get("chatpage.cchange29"));
- return;
- };
- this.chatMessageSize = 0;
- this.chatEditor.updateMirror();
- this._sendMessage(props);
+ // if (this.chatMessageSize > 1000 ) {
+ // parentEpml.request('showSnackBar', get("chatpage.cchange29"));
+ // return;
+ // };
+ // this.chatMessageSize = 0;
+ this._sendMessage(props, this.editor.getJSON());
}
getMessageSize(message){
@@ -442,387 +633,7 @@ class ChatTextEditor extends LitElement {
resetIFrameHeight(height) {
this.iframeHeight = 42;
}
- initChatEditor() {
- const ChatEditor = function (editorConfig) {
- const ChatEditor = function () {
- const editor = this;
- editor.init();
- };
-
- ChatEditor.prototype.getValue = function () {
- const editor = this;
-
- if (editor.contentDiv) {
- return editor.contentDiv.innerHTML;
- }
- };
-
- ChatEditor.prototype.setValue = function (value) {
- const editor = this;
-
- if (value) {
- editor.contentDiv.innerHTML = value;
- editor.updateMirror();
- }
-
- editor.focus();
- };
-
- ChatEditor.prototype.resetValue = function () {
- const editor = this;
- editor.contentDiv.innerHTML = '';
- editor.updateMirror();
- editor.focus();
- editorConfig.resetIFrameHeight()
- };
-
- ChatEditor.prototype.styles = function () {
- const editor = this;
-
- editor.styles = document.createElement('style');
- editor.styles.setAttribute('type', 'text/css');
- editor.styles.innerText = `
- html {
- cursor: text;
- }
-
- .chatbar-body {
- display: flex;
- align-items: center;
- }
-
- .chatbar-body::-webkit-scrollbar-track {
- background-color: whitesmoke;
- border-radius: 7px;
- }
-
- .chatbar-body::-webkit-scrollbar {
- width: 6px;
- border-radius: 7px;
- background-color: whitesmoke;
- }
-
- .chatbar-body::-webkit-scrollbar-thumb {
- background-color: rgb(180, 176, 176);
- border-radius: 7px;
- transition: all 0.3s ease-in-out;
- }
-
- .chatbar-body::-webkit-scrollbar-thumb:hover {
- background-color: rgb(148, 146, 146);
- cursor: pointer;
- }
-
- div {
- font-size: 1rem;
- line-height: 1.38rem;
- font-weight: 400;
- font-family: "Open Sans", helvetica, sans-serif;
- padding-right: 3px;
- text-align: left;
- white-space: break-spaces;
- word-break: break-word;
- outline: none;
- min-height: 20px;
- width: 100%;
- }
-
- div[contentEditable=true]:empty:before {
- content: attr(data-placeholder);
- display: block;
- text-overflow: ellipsis;
- overflow: hidden;
- user-select: none;
- white-space: nowrap;
- opacity: 0.7;
- }
-
- div[contentEditable=false]{
- background: rgba(0,0,0,0.1);
- width: 100%;
- }
-
- img.emoji {
- width: 1.7em;
- height: 1.5em;
- margin-bottom: -2px;
- vertical-align: bottom;
- }
- `;
- editor.content.head.appendChild(editor.styles);
- };
-
- ChatEditor.prototype.enable = function () {
- const editor = this;
-
- editor.contentDiv.setAttribute('contenteditable', 'true');
- editor.focus();
- };
-
- ChatEditor.prototype.getMirrorElement = function (){
- return editor.mirror
- }
-
- ChatEditor.prototype.disable = function () {
- const editor = this;
-
- editor.contentDiv.setAttribute('contenteditable', 'false');
- };
-
- ChatEditor.prototype.state = function () {
- const editor = this;
-
- return editor.contentDiv.getAttribute('contenteditable');
- };
-
- ChatEditor.prototype.focus = function () {
- const editor = this;
-
- editor.contentDiv.focus();
- };
-
- ChatEditor.prototype.clearSelection = function () {
- const editor = this;
-
- let selection = editor.content.getSelection().toString();
- if (!/^\s*$/.test(selection)) editor.content.getSelection().removeAllRanges();
- };
-
- ChatEditor.prototype.insertEmoji = function (emojiImg) {
- const editor = this;
-
- const doInsert = () => {
-
- if (editor.content.queryCommandSupported("InsertHTML")) {
- editor.content.execCommand("insertHTML", false, emojiImg);
- editor.updateMirror();
- }
- };
-
- editor.focus();
- return doInsert();
- };
-
- ChatEditor.prototype.insertText = function (text) {
- const editor = this;
-
- const parsedText = editorConfig.emojiPicker.parse(text);
- const doPaste = () => {
-
- if (editor.content.queryCommandSupported("InsertHTML")) {
- editor.content.execCommand("insertHTML", false, parsedText);
- editor.updateMirror();
- }
- };
-
- editor.focus();
- return doPaste();
- };
-
- ChatEditor.prototype.updateMirror = function () {
- const editor = this;
-
- const chatInputValue = editor.getValue();
- const filteredValue = chatInputValue.replace(//g, '');
-
- let unescapedValue = editorConfig.unescape(filteredValue);
- editor.mirror.value = unescapedValue;
- };
-
- ChatEditor.prototype.listenChanges = function () {
-
- const editor = this;
-
- const events = ['drop', 'contextmenu', 'mouseup', 'click', 'touchend', 'keydown', 'blur', 'paste']
-
- for (let i = 0; i < events.length; i++) {
- const event = events[i]
- editor.content.body.addEventListener(event, async function (e) {
-
- if (e.type === 'click') {
- e.preventDefault();
- e.stopPropagation();
- }
-
- if (e.type === 'paste') {
- e.preventDefault();
- const item_list = await navigator.clipboard.read();
- let image_type; // we will feed this later
- const item = item_list.find( item => // choose the one item holding our image
- item.types.some( type => {
- if (type.startsWith( 'image/')) {
- image_type = type;
- return true;
- }
- })
- );
- if(item){
- const blob = item && await item.getType( image_type );
- var file = new File([blob], "name", {
- type: image_type
- });
-
- editorConfig.insertImage(file)
- } else {
- navigator.clipboard.readText()
- .then(clipboardText => {
- let escapedText = editorConfig.escape(clipboardText);
- editor.insertText(escapedText);
- })
- .then(() => {
- editorConfig.getMessageSize(editorConfig.editableElement.contentDocument.body.querySelector("#chatbarId").innerHTML);
- })
- .catch(err => {
- // Fallback if everything fails...
- let textData = (e.originalEvent || e).clipboardData.getData('text/plain');
- editor.insertText(textData);
- })
- }
-
-
- return false;
- }
-
- if (e.type === 'contextmenu') {
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
-
- if (e.type === 'keydown') {
- await new Promise((res, rej) => {
- setTimeout(() => {
- editorConfig.calculateIFrameHeight(editorConfig.editableElement.contentDocument.body.scrollHeight);
- editorConfig.getMessageSize(editorConfig.editableElement.contentDocument.body.querySelector("#chatbarId").innerHTML);
- }, 0);
- res();
- })
-
- // Handle Enter
- if (e.keyCode === 13 && !e.shiftKey) {
-
-
- if (editor.state() === 'false') return false;
- if (editorConfig.iframeId === 'newChat') {
- editorConfig.sendFunc(
- {
- type: 'image',
- imageFile: editorConfig.imageFile,
- }
- );
- } else {
- editorConfig.sendFunc();
- }
-
- e.preventDefault();
- return false;
- }
-
- // Handle Commands with CTR or CMD
- if (e.ctrlKey || e.metaKey) {
- switch (e.keyCode) {
- case 66:
- case 98: e.preventDefault();
- return false;
- case 73:
- case 105: e.preventDefault();
- return false;
- case 85:
- case 117: e.preventDefault();
- return false;
- }
-
- return false;
- }
- }
-
- if (e.type === 'blur') {
- editor.clearSelection();
- }
-
- if (e.type === 'drop') {
- e.preventDefault();
-
- let droppedText = e.dataTransfer.getData('text/plain')
- let escapedText = editorConfig.escape(droppedText)
-
- editor.insertText(escapedText);
- return false;
- }
-
- editor.updateMirror();
- });
- }
-
- editor.content.addEventListener('click', function (event) {
- event.preventDefault();
- editor.focus();
- });
- };
-
- ChatEditor.prototype.remove = function () {
- const editor = this;
- var old_element = editor.content.body;
- var new_element = old_element.cloneNode(true);
- editor.content.body.parentNode.replaceChild(new_element, old_element);
- while (editor.content.body.firstChild) {
- editor.content.body.removeChild(editor.content.body.lastChild);
- }
-
- };
-
- ChatEditor.prototype.init = function () {
- const editor = this;
-
- editor.frame = editorConfig.editableElement;
- editor.mirror = editorConfig.mirrorElement;
-
- editor.content = (editor.frame.contentDocument || editor.frame.document);
- editor.content.body.classList.add("chatbar-body");
-
- let elemDiv = document.createElement('div');
- elemDiv.setAttribute('contenteditable', 'true');
- elemDiv.setAttribute('spellcheck', 'false');
- elemDiv.setAttribute('data-placeholder', editorConfig.placeholder);
- elemDiv.style.cssText = `width:100%; ${editorConfig.theme === "dark" ? "color:#ffffff;" : "color: #080808"}`;
- elemDiv.id = 'chatbarId';
- editor.content.body.appendChild(elemDiv);
- editor.contentDiv = editor.frame.contentDocument.body.firstChild;
- editor.styles();
- editor.listenChanges();
-
- };
-
-
- function doInit() {
- return new ChatEditor();
- }
- return doInit();
- };
-
- const editorConfig = {
- getMessageSize: this.getMessageSize,
- calculateIFrameHeight: this.calculateIFrameHeight,
- mirrorElement: this.mirrorChatInput,
- editableElement: this.chatMessageInput,
- sendFunc: this.sendMessageFunc,
- emojiPicker: this.emojiPicker,
- escape: escape,
- unescape: unescape,
- placeholder: this.placeholder,
- imageFile: this.imageFile,
- requestUpdate: this.requestUpdate,
- insertImage: this.insertImage,
- chatMessageSize: this.chatMessageSize,
- addGlobalEventListener: this.addGlobalEventListener,
- removeGlobalEventListener: this.removeGlobalEventListener,
- iframeId: this.iframeId,
- theme: this.theme,
- resetIFrameHeight: this.resetIFrameHeight
- };
- const newChat = new ChatEditor(editorConfig);
- this.setChatEditor(newChat);
- }
+
}
window.customElements.define("chat-text-editor", ChatTextEditor)
diff --git a/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
index 18cec93b..86e43929 100644
--- a/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
+++ b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
@@ -22,6 +22,10 @@ import '@material/mwc-dialog'
import '@material/mwc-icon'
import '@material/mwc-snackbar'
import '@vaadin/grid'
+import StarterKit from '@tiptap/starter-kit'
+import Underline from '@tiptap/extension-underline';
+import Placeholder from '@tiptap/extension-placeholder'
+import { Editor, Extension } from '@tiptap/core'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@@ -47,7 +51,8 @@ class Chat extends LitElement {
openPrivateMessage: { type: Boolean },
userFound: { type: Array},
userFoundModalOpen: { type: Boolean },
- userSelected: { type: Object }
+ userSelected: { type: Object },
+ editor: {type: Object}
}
}
@@ -94,6 +99,66 @@ class Chat extends LitElement {
this.activeChatHeadUrl = url
}
+ resetChatEditor(){
+
+ this.editor.commands.setContent('')
+
+ }
+ async getUpdateCompleteTextEditor() {
+ await super.getUpdateComplete();
+ const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor'));
+ await Promise.all(marginElements.map(el => el.updateComplete));
+ const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal'));
+ await Promise.all(marginElements2.map(el => el.updateComplete));
+ return true;
+ }
+
+ async connectedCallback() {
+ super.connectedCallback();
+ await this.getUpdateCompleteTextEditor();
+
+ const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage')
+ console.log({elementChatId})
+ this.editor = new Editor({
+ element: elementChatId,
+ extensions: [
+ StarterKit,
+ Underline,
+ Placeholder.configure({
+ placeholder: 'Write something …',
+ }),
+ Extension.create({
+ addKeyboardShortcuts:()=> {
+ return {
+ 'Enter': ()=> {
+ const chatTextEditor = this.shadowRoot.getElementById('messageBox')
+ chatTextEditor.sendMessageFunc({
+ })
+ return true
+ }
+ }
+ }})
+ ]
+ })
+
+ }
+
+ disconnectedCallback() {
+ super.disconnectedCallback();
+ this.editor.destroy()
+
+ }
+
+ updatePlaceholder(editor, text){
+ editor.extensionManager.extensions.forEach((extension) => {
+ if (extension.name === "placeholder") {
+
+ extension.options["placeholder"] = text
+ editor.commands.focus('end')
+ }
+ })
+ }
+
render() {
return html`
@@ -127,13 +192,13 @@ class Chat extends LitElement {
{
- this.chatEditor.resetValue();
+ this.resetChatEditor();
this.openPrivateMessage = false;
this.shadowRoot.getElementById('sendTo').value = "";
this.userFoundModalOpen = false;
this.userFound = [];
} }
- style=${this.openPrivateMessage ? "display: block" : "display: none"}>
+ style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}>