From 9e1d8e3e56c634f9a3e7b7fe983e24cba9c608ed Mon Sep 17 00:00:00 2001 From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> Date: Thu, 11 Apr 2024 16:58:35 -0400 Subject: [PATCH] messagebar: move js into js file, simplify markdown editing This will make the code easier to read/debug and get us closer to adhering to the coding guidelines regarding QML file length. Gitlab: #1639 Change-Id: I6d6e9604c4a54e9fe354c0d24ef66b41ebbbff2a --- src/app/js/.clang-format | 2 + src/app/js/markdownedition.js | 279 +++++++++++++++++ src/app/mainview/components/MessageBar.qml | 341 +++------------------ 3 files changed, 329 insertions(+), 293 deletions(-) create mode 100644 src/app/js/.clang-format create mode 100644 src/app/js/markdownedition.js diff --git a/src/app/js/.clang-format b/src/app/js/.clang-format new file mode 100644 index 000000000..95a074734 --- /dev/null +++ b/src/app/js/.clang-format @@ -0,0 +1,2 @@ +Language: JavaScript +BasedOnStyle: Google diff --git a/src/app/js/markdownedition.js b/src/app/js/markdownedition.js new file mode 100644 index 000000000..08964bf92 --- /dev/null +++ b/src/app/js/markdownedition.js @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2020-2024 Savoir-faire Linux Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +// This file contains the functions that allow the user to format the text in +// the message bar by adding bold, italic, underline, strikethrough, ordered +// list, and unordered list styles. + +function isStyle(ta, text, char1, char2) { + const start = ta.selectionStart; + const end = ta.selectionEnd; + + if (char1 === '**') { + return isStarStyle(ta, text, 'bold'); + } + if (char1 === '*') { + return isStarStyle(ta, text, 'italic'); + } + const selectedText = text.substring(start - char1.length, end + char2.length); + return (selectedText.startsWith(char1) && selectedText.endsWith(char2)); +} + +function isStarStyle(ta, text, type) { + const selectionStart = ta.selectionStart; + const selectionEnd = ta.selectionEnd; + + let start = selectionStart; + while (start > 0 && text[start - 1] === '*') { + start--; + } + let end = selectionEnd; + while (end < text.length && text[end] === '*') { + end++; + } + const starCount = Math.min(selectionStart - start, end - selectionEnd); + if (type === 'italic') { + return starCount === 1 || starCount === 3; + } + return starCount === 2 || starCount === 3; +} + +function addStyle(ta, text, char1, char2) { + const start = ta.selectionStart; + const end = ta.selectionEnd; + + // Get the selected text with markdown effect + var selectedText = text.substring(start - char1.length, end + char2.length); + + // If the selected text is already formatted with the given characters, remove + // them + if (isStyle(ta, text, char1, char2)) { + selectedText = text.substring(start, end); + ta.text = text.substring(0, start - char1.length) + selectedText + + text.substring(end + char2.length); + ta.selectText(start - char1.length, end - char1.length); + return; + } + + // Otherwise, add the formatting characters to the selected text + ta.text = text.substring(0, start) + char1 + text.substring(start, end) + + char2 + text.substring(end); + ta.selectText(start + char1.length, end + char1.length); +} + +function isPrefixSyle(ta, message, delimiter, isOrderedList) { + const selectionStart = ta.selectionStart; + const selectionEnd = ta.selectionEnd; + + // Represents all the selected lines + var multilineSelection; + var newPrefix; + var newSuffix; + var newStartPos; + var newEndPos; + function nextIndexOf(text, char1, startPos) { + return text.indexOf(char1, startPos + 1); + } + + // Get the previous index of the multilineSelection text + if (message[selectionStart] === '\n') + newStartPos = message.lastIndexOf('\n', selectionStart - 1); + else + newStartPos = message.lastIndexOf('\n', selectionStart); + + // Get the next index of the multilineSelection text + if (message[selectionEnd] === '\n' || message[selectionEnd] === undefined) + newEndPos = selectionEnd; + else + newEndPos = nextIndexOf(message, '\n', selectionEnd); + + // If the text is empty + if (newStartPos === -1) newStartPos = 0; + newPrefix = message.slice(0, newStartPos); + multilineSelection = message.slice(newStartPos, newEndPos); + newSuffix = message.slice(newEndPos); + var isFirstLineSelected = + !multilineSelection.startsWith('\n') || newPrefix === ''; + var getDelimiter_counter = 1; + function getDelimiter() { + return `${getDelimiter_counter++}. `; + } + function getHasCurrentMarkdown() { + const linesQuantity = (multilineSelection.match(/\n/g) || []).length; + const newLinesWithDelimitersQuantity = + (multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) || + []).length; + if (newLinesWithDelimitersQuantity === linesQuantity && + !isFirstLineSelected) + return true; + return linesQuantity === newLinesWithDelimitersQuantity && + multilineSelection.startsWith(delimiter); + } + function getHasCurrentMarkdownBullet() { + const linesQuantity = (multilineSelection.match(/\n/g) || []).length; + const newLinesWithDelimitersQuantity = + (multilineSelection.match(/\n\d+\. /g) || []).length; + if (newLinesWithDelimitersQuantity === linesQuantity && + !isFirstLineSelected) + return true; + return linesQuantity === newLinesWithDelimitersQuantity && + (/^\d\. /).test(multilineSelection); + } + var newValue; + var newStart; + var newEnd; + var count; + var startPos; + var multilineSelectionLength; + if (!isOrderedList) { + return getHasCurrentMarkdown(); + } else { + return getHasCurrentMarkdownBullet(); + } +} + +function addPrefixStyle(ta, message, delimiter, isOrderedList) { + const selectionStart = ta.selectionStart; + const selectionEnd = ta.selectionEnd; + + // Represents all the selected lines + var multilineSelection; + var newPrefix; + var newSuffix; + var newStartPos; + var newEndPos; + function nextIndexOf(text, char1, startPos) { + return text.indexOf(char1, startPos + 1); + } + + // Get the previous index of the multilineSelection text + if (message[selectionStart] === '\n') + newStartPos = message.lastIndexOf('\n', selectionStart - 1); + else + newStartPos = message.lastIndexOf('\n', selectionStart); + + // Get the next index of the multilineSelection text + if (message[selectionEnd] === '\n' || message[selectionEnd] === undefined) + newEndPos = selectionEnd; + else + newEndPos = nextIndexOf(message, '\n', selectionEnd); + + // If the text is empty + if (newStartPos === -1) newStartPos = 0; + newPrefix = message.slice(0, newStartPos); + multilineSelection = message.slice(newStartPos, newEndPos); + newSuffix = message.slice(newEndPos); + var isFirstLineSelected = + !multilineSelection.startsWith('\n') || newPrefix === ''; + var getDelimiter_counter = 1; + function getDelimiter() { + return `${getDelimiter_counter++}. `; + } + function getHasCurrentMarkdown() { + const linesQuantity = (multilineSelection.match(/\n/g) || []).length; + const newLinesWithDelimitersQuantity = + (multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) || + []).length; + if (newLinesWithDelimitersQuantity === linesQuantity && + !isFirstLineSelected) + return true; + return linesQuantity === newLinesWithDelimitersQuantity && + multilineSelection.startsWith(delimiter); + } + function getHasCurrentMarkdownBullet() { + const linesQuantity = (multilineSelection.match(/\n/g) || []).length; + const newLinesWithDelimitersQuantity = + (multilineSelection.match(/\n\d+\. /g) || []).length; + if (newLinesWithDelimitersQuantity === linesQuantity && + !isFirstLineSelected) + return true; + return linesQuantity === newLinesWithDelimitersQuantity && + (/^\d\. /).test(multilineSelection); + } + var newValue; + var newStart; + var newEnd; + var count; + var startPos; + var multilineSelectionLength; + if (!isOrderedList) { + if (getHasCurrentMarkdown()) { + // Clear first line from delimiter + if (isFirstLineSelected) + multilineSelection = multilineSelection.slice(delimiter.length); + newValue = newPrefix + + multilineSelection.replace(new RegExp(`\n${delimiter}`, 'g'), '\n') + + newSuffix; + count = 0; + if (isFirstLineSelected) count++; + count += (multilineSelection.match(/\n/g) || []).length; + newStart = Math.max(selectionStart - delimiter.length, 0); + newEnd = Math.max(selectionEnd - (delimiter.length * count), 0); + } else { + newValue = newPrefix + + multilineSelection.replace(/\n/g, `\n${delimiter}`) + newSuffix; + count = 0; + if (isFirstLineSelected) { + newValue = delimiter + newValue; + count++; + } + count += (multilineSelection.match(new RegExp('\\n', 'g')) || []).length; + newStart = selectionStart + delimiter.length; + newEnd = selectionEnd + (delimiter.length * count); + } + } else if (getHasCurrentMarkdownBullet()) { + if (message[selectionStart] === '\n') + startPos = message.lastIndexOf('\n', selectionStart - 1) + 1; + else + startPos = message.lastIndexOf('\n', selectionStart) + 1; + newStart = startPos; + multilineSelection = multilineSelection.replace(/^\d+\.\s/gm, ''); + newValue = newPrefix + multilineSelection + newSuffix; + multilineSelectionLength = multilineSelection.length; + + // If the first line is not selected, we need to remove the first "\n" of + // multilineSelection + if (newStart) multilineSelectionLength = multilineSelection.length - 1; + newEnd = Math.max(newStart + multilineSelectionLength, 0); + } else { + if (message[selectionStart] === '\n') + startPos = message.lastIndexOf('\n', selectionStart - 1) + 1; + else + startPos = message.lastIndexOf('\n', selectionStart) + 1; + newStart = startPos; + + // If no text is selected + if (selectionStart === selectionEnd) newStart = newStart + 3; + if (isFirstLineSelected) + multilineSelection = getDelimiter() + multilineSelection; + const selectionArr = Array.from(multilineSelection); + for (var i = 0; i < selectionArr.length; i++) { + if (selectionArr[i] === '\n') selectionArr[i] = `\n${getDelimiter()}`; + } + multilineSelection = selectionArr.join(''); + newValue = newPrefix + multilineSelection + newSuffix; + multilineSelectionLength = multilineSelection.length; + + // If the first line is not selected, we meed to remove the first "\n" of + // multilineSelection + if (startPos) multilineSelectionLength = multilineSelection.length - 1; + newEnd = Math.max(startPos + multilineSelectionLength, 0); + } + + ta.text = newValue; + ta.selectText(newStart, newEnd); +} diff --git a/src/app/mainview/components/MessageBar.qml b/src/app/mainview/components/MessageBar.qml index 7cfb59e18..a728ce50f 100644 --- a/src/app/mainview/components/MessageBar.qml +++ b/src/app/mainview/components/MessageBar.qml @@ -25,6 +25,8 @@ import net.jami.Enums 1.1 import net.jami.Constants 1.1 import "../../commoncomponents" +import "qrc:/js/markdownedition.js" as MDE + RowLayout { id: root @@ -358,231 +360,6 @@ RowLayout { id: listViewTypo height: JamiTheme.chatViewFooterButtonSize - function isStyle(text, start, end, char1, char2, regex) { - if (char1 === "**") { - return isStarStyle(text, start, end, "bold"); - } - if (char1 === "*") { - return isStarStyle(text, start, end, "italic"); - } - var selectedText = text.substring(start - char1.length, end + char2.length); - return (selectedText.startsWith(char1) && selectedText.endsWith(char2)); - } - - function isStarStyle(text, selectionStart, selectionEnd, type) { - let start = selectionStart; - while (start > 0 && text[start - 1] === "*") { - start--; - } - let end = selectionEnd; - while (end < text.length && text[end] === "*") { - end++; - } - const starCount = Math.min(selectionStart - start, end - selectionEnd); - if (type === "italic") { - return starCount === 1 || starCount === 3; - } - return starCount === 2 || starCount === 3; - } - - function addStyle(text, start, end, char1, char2, regex) { - // get the selected text with markdown effect - var selectedText = text.substring(start - char1.length, end + char2.length); - if (isStyle(text, start, end, char1, char2, regex)) { - // If the selected text is already formatted with the given characters, remove them - selectedText = text.substring(start, end); - root.text = text.substring(0, start - char1.length) + selectedText + text.substring(end + char2.length); - messageBarTextArea.selectText(start - char1.length, end - char1.length); - } else { - // Otherwise, add the formatting characters to the selected text - root.text = text.substring(0, start) + char1 + text.substring(start, end) + char2 + text.substring(end); - messageBarTextArea.selectText(start + char1.length, end + char1.length); - } - } - - function isPrefixSyle(message, selectionStart, selectionEnd, delimiter, isOrderedList) { - //represents all the selected lines - var multilineSelection; - var newPrefix; - var newSuffix; - var newStartPos; - var newEndPos; - function nextIndexOf(text, char1, startPos) { - return text.indexOf(char1, startPos + 1); - } - - //get the previous index of the multilineSelection text - if (message[selectionStart] === "\n") - newStartPos = message.lastIndexOf('\n', selectionStart - 1); - else - newStartPos = message.lastIndexOf('\n', selectionStart); - - //get the next index of the multilineSelection text - if (message[selectionEnd] === "\n" || message[selectionEnd] === undefined) - newEndPos = selectionEnd; - else - newEndPos = nextIndexOf(message, "\n", selectionEnd); - - //if the text is empty - if (newStartPos === -1) - newStartPos = 0; - newPrefix = message.slice(0, newStartPos); - multilineSelection = message.slice(newStartPos, newEndPos); - newSuffix = message.slice(newEndPos); - var isFirstLineSelected = !multilineSelection.startsWith('\n') || newPrefix === ""; - var getDelimiter_counter = 1; - function getDelimiter() { - return `${getDelimiter_counter++}. `; - } - function getHasCurrentMarkdown() { - const linesQuantity = (multilineSelection.match(/\n/g) || []).length; - const newLinesWithDelimitersQuantity = (multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) || []).length; - if (newLinesWithDelimitersQuantity === linesQuantity && !isFirstLineSelected) - return true; - return linesQuantity === newLinesWithDelimitersQuantity && multilineSelection.startsWith(delimiter); - } - function getHasCurrentMarkdownBullet() { - const linesQuantity = (multilineSelection.match(/\n/g) || []).length; - const newLinesWithDelimitersQuantity = (multilineSelection.match(/\n\d+\. /g) || []).length; - if (newLinesWithDelimitersQuantity === linesQuantity && !isFirstLineSelected) - return true; - return linesQuantity === newLinesWithDelimitersQuantity && (/^\d\. /).test(multilineSelection); - } - var newValue; - var newStart; - var newEnd; - var count; - var startPos; - var multilineSelectionLength; - if (!isOrderedList) { - return getHasCurrentMarkdown(); - } else { - return getHasCurrentMarkdownBullet(); - } - } - - function addPrefixStyle(message, selectionStart, selectionEnd, delimiter, isOrderedList) { - //represents all the selected lines - var multilineSelection; - var newPrefix; - var newSuffix; - var newStartPos; - var newEndPos; - function nextIndexOf(text, char1, startPos) { - return text.indexOf(char1, startPos + 1); - } - - //get the previous index of the multilineSelection text - if (message[selectionStart] === "\n") - newStartPos = message.lastIndexOf('\n', selectionStart - 1); - else - newStartPos = message.lastIndexOf('\n', selectionStart); - - //get the next index of the multilineSelection text - if (message[selectionEnd] === "\n" || message[selectionEnd] === undefined) - newEndPos = selectionEnd; - else - newEndPos = nextIndexOf(message, "\n", selectionEnd); - - //if the text is empty - if (newStartPos === -1) - newStartPos = 0; - newPrefix = message.slice(0, newStartPos); - multilineSelection = message.slice(newStartPos, newEndPos); - newSuffix = message.slice(newEndPos); - var isFirstLineSelected = !multilineSelection.startsWith('\n') || newPrefix === ""; - var getDelimiter_counter = 1; - function getDelimiter() { - return `${getDelimiter_counter++}. `; - } - function getHasCurrentMarkdown() { - const linesQuantity = (multilineSelection.match(/\n/g) || []).length; - const newLinesWithDelimitersQuantity = (multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) || []).length; - if (newLinesWithDelimitersQuantity === linesQuantity && !isFirstLineSelected) - return true; - return linesQuantity === newLinesWithDelimitersQuantity && multilineSelection.startsWith(delimiter); - } - function getHasCurrentMarkdownBullet() { - const linesQuantity = (multilineSelection.match(/\n/g) || []).length; - const newLinesWithDelimitersQuantity = (multilineSelection.match(/\n\d+\. /g) || []).length; - if (newLinesWithDelimitersQuantity === linesQuantity && !isFirstLineSelected) - return true; - return linesQuantity === newLinesWithDelimitersQuantity && (/^\d\. /).test(multilineSelection); - } - var newValue; - var newStart; - var newEnd; - var count; - var startPos; - var multilineSelectionLength; - if (!isOrderedList) { - if (getHasCurrentMarkdown()) { - - // clear first line from delimiter - if (isFirstLineSelected) - multilineSelection = multilineSelection.slice(delimiter.length); - newValue = newPrefix + multilineSelection.replace(new RegExp(`\n${delimiter}`, 'g'), '\n') + newSuffix; - count = 0; - if (isFirstLineSelected) - count++; - count += (multilineSelection.match(/\n/g) || []).length; - newStart = Math.max(selectionStart - delimiter.length, 0); - newEnd = Math.max(selectionEnd - (delimiter.length * count), 0); - } else { - newValue = newPrefix + multilineSelection.replace(/\n/g, `\n${delimiter}`) + newSuffix; - count = 0; - if (isFirstLineSelected) { - newValue = delimiter + newValue; - count++; - } - count += (multilineSelection.match(new RegExp('\\n', 'g')) || []).length; - newStart = selectionStart + delimiter.length; - newEnd = selectionEnd + (delimiter.length * count); - } - } else if (getHasCurrentMarkdownBullet()) { - if (message[selectionStart] === "\n") - startPos = message.lastIndexOf('\n', selectionStart - 1) + 1; - else - startPos = message.lastIndexOf('\n', selectionStart) + 1; - newStart = startPos; - multilineSelection = multilineSelection.replace(/^\d+\.\s/gm, ''); - newValue = newPrefix + multilineSelection + newSuffix; - multilineSelectionLength = multilineSelection.length; - - //if the first line is not selected, we need to remove the first "\n" of multilineSelection - if (newStart) - multilineSelectionLength = multilineSelection.length - 1; - newEnd = Math.max(newStart + multilineSelectionLength, 0); - } else { - if (message[selectionStart] === "\n") - startPos = message.lastIndexOf('\n', selectionStart - 1) + 1; - else - startPos = message.lastIndexOf('\n', selectionStart) + 1; - newStart = startPos; - - // if no text is selected - if (selectionStart === selectionEnd) - newStart = newStart + 3; - if (isFirstLineSelected) - multilineSelection = getDelimiter() + multilineSelection; - const selectionArr = Array.from(multilineSelection); - for (var i = 0; i < selectionArr.length; i++) { - if (selectionArr[i] === '\n') - selectionArr[i] = `\n${getDelimiter()}`; - } - multilineSelection = selectionArr.join(''); - newValue = newPrefix + multilineSelection + newSuffix; - multilineSelectionLength = multilineSelection.length; - - //if the first line is not selected, we meed to remove the first "\n" of multilineSelection - if (startPos) - multilineSelectionLength = multilineSelection.length - 1; - newEnd = Math.max(startPos + multilineSelectionLength, 0); - } - root.text = newValue; - messageBarTextArea.selectText(newStart, newEnd); - } - ListView { id: listViewTypoFirst @@ -600,70 +377,56 @@ RowLayout { height: JamiTheme.chatViewFooterButtonSize orientation: ListView.Horizontal interactive: false - leftMargin: 5 - rightMargin: 5 spacing: 5 property list<Action> menuTypoActionsFirst: [ Action { id: boldAction - property var iconSrc: JamiResources.bold_black_24dp_svg - property var shortcutText: JamiStrings.bold + property string iconSrc: JamiResources.bold_black_24dp_svg + property string shortcutText: JamiStrings.bold property string shortcutKey: "Ctrl+B" - property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/) - onTriggered: function clickAction() { - listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/); - } + property bool isStyle: MDE.isStyle(messageBarTextArea, root.text, "**", "**") + onTriggered: MDE.addStyle(messageBarTextArea, root.text, "**", "**") }, Action { id: italicAction - property var iconSrc: JamiResources.italic_black_24dp_svg - property var shortcutText: JamiStrings.italic + property string iconSrc: JamiResources.italic_black_24dp_svg + property string shortcutText: JamiStrings.italic property string shortcutKey: "Ctrl+I" - property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/) - onTriggered: function clickAction() { - listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/); - } + property bool isStyle: MDE.isStyle(messageBarTextArea, root.text, "*", "*") + onTriggered: MDE.addStyle(messageBarTextArea, root.text, "*", "*") }, Action { id: strikethroughAction - property var iconSrc: JamiResources.s_barre_black_24dp_svg - property var shortcutText: JamiStrings.strikethrough + property string iconSrc: JamiResources.s_barre_black_24dp_svg + property string shortcutText: JamiStrings.strikethrough property string shortcutKey: "Shift+Alt+X" - property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/) - onTriggered: function clickAction() { - listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/); - } + property bool isStyle: MDE.isStyle(messageBarTextArea, root.text, "~~", "~~") + onTriggered: MDE.addStyle(messageBarTextArea, root.text, "~~", "~~") }, Action { id: titleAction - property var iconSrc: JamiResources.title_black_24dp_svg - property var shortcutText: JamiStrings.heading + property string iconSrc: JamiResources.title_black_24dp_svg + property string shortcutText: JamiStrings.heading property string shortcutKey: "Ctrl+Alt+H" - property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "### ", false) - onTriggered: function clickAction() { - listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "### ", false); - } + property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, root.text, "### ", false) + onTriggered: MDE.addPrefixStyle(messageBarTextArea, root.text, "### ", false) }, Action { id: linkAction - property var iconSrc: JamiResources.link_web_black_24dp_svg - property var shortcutText: JamiStrings.link + property string iconSrc: JamiResources.link_web_black_24dp_svg + property string shortcutText: JamiStrings.link property string shortcutKey: "Ctrl+Alt+K" - property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/) - onTriggered: function clickAction() { - listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/); - } + property bool isStyle: MDE.isStyle(messageBarTextArea, root.text, "[", "](url)") + onTriggered: MDE.addStyle(messageBarTextArea, root.text, "[", "](url)") }, Action { id: codeAction - property var iconSrc: JamiResources.code_black_24dp_svg - property var shortcutText: JamiStrings.code + property string iconSrc: JamiResources.code_black_24dp_svg + property string shortcutText: JamiStrings.code property string shortcutKey: "Ctrl+Alt+C" - property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/) - onTriggered: function clickAction() { - listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/); - } + property bool isStyle: MDE.isStyle(messageBarTextArea, root.text, "```", "```") + onTriggered: MDE.addStyle(messageBarTextArea, root.text, "```", "```") } ] @@ -795,8 +558,6 @@ RowLayout { height: JamiTheme.chatViewFooterButtonSize orientation: ListView.Horizontal interactive: false - leftMargin: 10 - rightMargin: 10 spacing: 10 Rectangle { @@ -808,33 +569,27 @@ RowLayout { property list<Action> menuTypoActionsSecond: [ Action { id: quoteAction - property var iconSrc: JamiResources.quote_black_24dp_svg - property var shortcutText: JamiStrings.quote + property string iconSrc: JamiResources.quote_black_24dp_svg + property string shortcutText: JamiStrings.quote property string shortcutKey: "Shift+Alt+9" - property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "> ", false) - onTriggered: function clickAction() { - listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "> ", false); - } + property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, root.text, "> ", false) + onTriggered: MDE.addPrefixStyle(messageBarTextArea, root.text, "> ", false) }, Action { id: unorderedListAction - property var iconSrc: JamiResources.bullet_point_black_24dp_svg - property var shortcutText: JamiStrings.unorderedList + property string iconSrc: JamiResources.bullet_point_black_24dp_svg + property string shortcutText: JamiStrings.unorderedList property string shortcutKey: "Shift+Alt+8" - property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "- ", false) - onTriggered: function clickAction() { - listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "- ", false); - } + property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, root.text, "- ", false) + onTriggered: MDE.addPrefixStyle(messageBarTextArea, root.text, "- ", false) }, Action { id: orderedListAction - property var iconSrc: JamiResources.bullet_number_black_24dp_svg - property var shortcutText: JamiStrings.orderedList + property string iconSrc: JamiResources.bullet_number_black_24dp_svg + property string shortcutText: JamiStrings.orderedList property string shortcutKey: "Shift+Alt+7" - property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true) - onTriggered: function clickAction() { - listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true); - } + property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, root.text, "", true) + onTriggered: MDE.addPrefixStyle(messageBarTextArea, root.text, "", true) } ] @@ -945,8 +700,8 @@ RowLayout { property list<Action> menuActions: [ Action { id: sendFile - property var iconSrc: JamiResources.link_black_24dp_svg - property var toolTip: JamiStrings.sendFile + property string iconSrc: JamiResources.link_black_24dp_svg + property string toolTip: JamiStrings.sendFile property bool show: true property bool needWebEngine: false property bool needVideoDevice: false @@ -958,8 +713,8 @@ RowLayout { }, Action { id: addEmoji - property var iconSrc: JamiResources.emoji_black_24dp_svg - property var toolTip: JamiStrings.addEmoji + property string iconSrc: JamiResources.emoji_black_24dp_svg + property string toolTip: JamiStrings.addEmoji property bool show: true property bool needWebEngine: true property bool needVideoDevice: false @@ -1047,8 +802,8 @@ RowLayout { property list<Action> menuMoreButton: [ Action { id: leaveAudioMessage - property var iconSrc: JamiResources.message_audio_black_24dp_svg - property var toolTip: JamiStrings.leaveAudioMessage + property string iconSrc: JamiResources.message_audio_black_24dp_svg + property string toolTip: JamiStrings.leaveAudioMessage property bool show: false property bool needWebEngine: false property bool needVideoDevice: false @@ -1059,8 +814,8 @@ RowLayout { }, Action { id: leaveVideoMessage - property var iconSrc: JamiResources.message_video_black_24dp_svg - property var toolTip: JamiStrings.leaveVideoMessage + property string iconSrc: JamiResources.message_video_black_24dp_svg + property string toolTip: JamiStrings.leaveVideoMessage property bool show: false property bool needWebEngine: false property bool needVideoDevice: true @@ -1071,8 +826,8 @@ RowLayout { }, Action { id: shareLocation - property var iconSrc: JamiResources.localisation_sharing_send_pin_svg - property var toolTip: JamiStrings.shareLocation + property string iconSrc: JamiResources.localisation_sharing_send_pin_svg + property string toolTip: JamiStrings.shareLocation property bool show: false property bool needWebEngine: true property bool needVideoDevice: false -- GitLab