// This file is part of Friendiqa // https://git.friendi.ca/lubuwest/Friendiqa // Copyright (C) 2020 Marco R. // // 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. // // In addition, as a special exception, the copyright holders give // permission to link the code of portions of this program with the // OpenSSL library under certain conditions as described in each // individual source file, and distribute linked combinations including // the two. // // You must obey the GNU General Public License in all respects for all // of the code used other than OpenSSL. If you modify file(s) with this // exception, you may extend this exception to your version of the // file(s), but you are not obligated to do so. If you do not wish to do // so, delete this exception statement from your version. If you delete // this exception statement from all source files in the program, then // also delete it here. // // 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 . // message.qml // message with buttons import QtQuick 6.3 import QtQuick.Controls 6.3 import QtQuick.Window 2.0; import QtQuick.Dialogs 6.3; //import Qt.labs.platform 6.3 as Platform import io.qt.examples.texteditor 1.0; import "qrc:/js/helper.js" as Helperjs import "qrc:/js/smiley.js" as Smileyjs import "qrc:/js/news.js" as Newsjs import "qrc:/qml/genericqml" import "qrc:/qml/newsqml" Window{ color: osSettings.backgroundColor width: parent.width height: 2/3*parent.height id: messageSend title: (reply_to_user!="")?qsTr("Answer to")+" @"+reply_to_user:qsTr("New message") property bool wideScreen : width>height property string parentId: "" property string reply_to_user:"" property string windowstate:"" property alias bodyMessage: bodyField.text property var media_ids:[] property var contacts: [] property var groups: [] property var contact_allow:login.hasOwnProperty("permissions")?login.permissions[0]:[] property var contact_deny:login.hasOwnProperty("permissions")?login.permissions[1]:[] property var group_allow:login.hasOwnProperty("permissions")?login.permissions[2]:[] property var group_deny:login.hasOwnProperty("permissions")?login.permissions[3]:[] function sendUrls(urls){ attachImage(urls); messageSend.state="active"; } function sendtext(text){ if(text){ if (text.subject=="undefined"){text.subject=""} if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){ text.plaintext=""} bodyField.text=text.subject+"\n"+text.plaintext; messageSend.state="active"; } } function attachImage(url){ if(url!=""){ imageUploadDialog.visible=true; imageUploadDialog.attachImage(url) } } function statusUpdate(title,status,in_reply_to_status_id) { try{newsBusy.running=true;conversationBusy.running=true}catch(e){} xhr.setAccount(login); xhr.setApi("/api/statuses/update"); xhr.setParam("source", "Friendiqa"); xhr.setParam("status", status); if (parentId!="") {xhr.setParam("in_reply_to_status_id", in_reply_to_status_id)}; if (title!=="") {xhr.setParam("title", title)}; // if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; // if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; // if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; // if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; if (media_ids.length>0) { xhr.setParam("media_ids", media_ids.join()); } xhr.post(); Newsjs.storeHashtags(login,db,status,root); media_ids=[] messageSend.close() } function dmUpdate(title,text,replyto,screen_name) { newsBusy.running=true; xhr.setAccount(login); xhr.setApi("/api/direct_messages/new"); xhr.setParam("text", text); xhr.setParam("screen_name", screen_name); if (parentId!="") {xhr.setParam("replyto", replyto)}; xhr.post(); messageSend.close() } function contactmenu(letter){ Newsjs.listFriends(login,db,function(contacts){ contactModel.clear(); for (var i=0;i1){ contact.screen_name=contact.screen_name+"+"+contacts.cid } if (windowstate=='directmessage'){ receiverLabel.text=contact.screen_name; reply_to_user=contact.screen_name } else { bodyField.remove(bodyField.getText(0,bodyField.cursorPosition).lastIndexOf(bodyField.contactprefix,bodyField.cursorPosition),bodyField.cursorPosition); bodyField.insert(bodyField.cursorPosition, bodyField.contactprefix+contact.screen_name+" "); bodyField.cursorPosition=bodyField.cursorPosition+contact.screen_name.length+1 } contactSelector.visible=false } delegate: ContactComponent { } } ListModel{id:contactModel} ListView{ id: tagSelector visible: false z:3 x:2*root.fontFactor*osSettings.bigFontSize width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize height: messageSend.height/2 model:tagModel clip: true spacing: 0 function processTagSelection(hashtag){ bodyField.insert(bodyField.cursorPosition, hashtag+" "); bodyField.cursorPosition=bodyField.cursorPosition+hashtag.length+1 tagSelector.visible=false } delegate: MButton {text:tag;onClicked: tagSelector.processTagSelection(tag)} } ListModel{id:tagModel} Row{ id:formatRow visible: wideScreen spacing: mm height: 3.5*root.fontFactor*osSettings.bigFontSize x: 0.5*mm MButton { id: boldButton //text: "\uf032" // icon-bold text: qsTr("Bold") display: AbstractButton.IconOnly icon.name: "format-text-bold" icon.source: "qrc:/assets/icons/bold.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Bold") focusPolicy: Qt.NoFocus onClicked: { document.bold = !document.bold; bodyField.forceActiveFocus() } } MButton { id: italicButton //text: "\uf033" // icon-italic text: qsTr("Format") display: AbstractButton.IconOnly icon.name: "format-text-italic" icon.source: "qrc:/assets/icons/italic.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Italic") focusPolicy: Qt.NoFocus onClicked: {document.italic = !document.italic;bodyField.forceActiveFocus()} } MButton { id: liststyleButton //text: "\uf03a" // icon-align-justify text: qsTr("Format") display: AbstractButton.IconOnly icon.name: "format-list-unordered" icon.source: "qrc:/assets/icons/list.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Create list") onClicked: {document.liststyle = !document.liststyle;bodyField.forceActiveFocus()} } MButton { id: codeblockButton //text: "\uf121" // icon-code text: qsTr("Format") display: AbstractButton.IconOnly icon.name: "format-text-code" icon.source: "qrc:/assets/icons/code.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Format as code") onClicked: {document.codeblock = !document.codeblock;bodyField.forceActiveFocus()} } MButton { id: plainButton text: bodyField.textFormat==TextEdit.PlainText?qsTr("Rendered"):qsTr("MD") // icon-code ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Show Markdown code") onClicked: { if(bodyField.textFormat==TextEdit.PlainText){ bodyField.textFormat=TextEdit.MarkdownText;} else {bodyField.textFormat=TextEdit.PlainText} bodyField.forceActiveFocus() } } MButton { id: menuButton //text: "\uf044" text: qsTr("Format") display: AbstractButton.IconOnly icon.name: "view-more-symbolic"//"overflow-menu" icon.source: "qrc:/assets/icons/ellipsis-v.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Edit") onClicked: { contextMenu.open()} } } //PermissionDialog{id:permissionDialog;x:mm;visible: false} SmileyDialog{id:smileyDialog;x:mm;visible: false} MessageImageUploadDialog{id:imageUploadDialog;visible: false} Row{ id:buttonRow visible: true spacing: mm height: 3.5*root.fontFactor*osSettings.bigFontSize x: 0.5*mm // MButton{id:permButton //Permissions not working in Friendica 02/2022 // visible: !conversation && (newsSwipeview.stacktype!=="DirectMessages") // height: 2*root.fontFactor*osSettings.bigFontSize // width: 2*root.fontFactor*osSettings.bigFontSize // text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" // onClicked: { if (permissionDialog.visible==false){permissionDialog.visible=true} else{permissionDialog.visible=false}} // } MButton{ id:smileyButton text: qsTr("emojies") display: AbstractButton.IconOnly icon.name: "smiley" icon.source: "qrc:/assets/icons/smile-o.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Insert smiley") onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} } MButton{ id:hastagButton text: "#" // display: AbstractButton.IconOnly // icon.name: "tag-symbolic" // icon.source: "qrc:/assets/icons/hashtag.svg" // icon.width: root.fontFactor*osSettings.bigFontSize // icon.height: root.fontFactor*osSettings.bigFontSize ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Insert previous hashtag") onClicked: {if (tagSelector.visible==false){hashtagmenu()} else{tagSelector.visible=false}} } MButton{ id:imagesButton visible:(newsSwipeview.stacktype!="DirectMessages") //text: "\uf03e" text: qsTr("Image") display: AbstractButton.IconOnly icon.name: "viewimage" icon.source: "qrc:/assets/icons/picture-o.svg" ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Insert images") onClicked: { if (imageUploadDialog.visible==false){ imageUploadDialog.visible=true; imageUploadDialog.attach() } else{imageUploadDialog.visible=false}} } MButton { id: cancelButton ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Cancel message") text: qsTr("Close") display: AbstractButton.IconOnly icon.name: "dialog-close" icon.source: "qrc:/assets/icons/times-circle.svg" onClicked: {messageSend.close()} } MButton { id: formatButton visible: !wideScreen ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Format message") text: qsTr("Format") display: AbstractButton.IconOnly icon.name: "format-text-italic" icon.source: "qrc:/assets/icons/font.svg" onClicked: {formatRow.visible?formatRow.visible=false:formatRow.visible=true} } MButton { id: sendButton ToolTip.delay: 800 ToolTip.visible: pressed || hovered ToolTip.text: qsTr("Send message") text: qsTr("Send") display: AbstractButton.IconOnly icon.name: "document-send" icon.source: "qrc:/assets/icons/paper-plane-o.svg" onClicked: { var title=titleField.text.replace("\"","\'"); var body=bodyField.getFormattedText(0,bodyField.length); var dmbody=bodyField.getText(0,bodyField.length); if (windowstate=="directmessage"){ if (reply_to_user!=""){dmUpdate(title,dmbody,parentId,reply_to_user)} else{Helperjs.showMessage(qsTr("Error"),qsTr("No receiver supplied!"),root)} }else { body=body.replace(/\*\*/g,"__") statusUpdate(title,body,parentId) } } } } } } Component.onCompleted:{ if(parentId!="" &&reply_to_user!=""){ receiverLabel.text=reply_to_user; } // root.replySignal.connect(setParent); // root.directmessageSignal.connect(directmessagePrepare); root.uploadSignal.connect(sendUrls); root.sendtextSignal.connect(sendtext); bodyField.forceActiveFocus() } StateGroup{ state: windowstate states: [ State { name: "active" PropertyChanges { target: messageColumn; height: implicitHeight } PropertyChanges { target: titleField; visible: true } }, State { name: "directmessage" PropertyChanges { target: messageColumn; height: implicitHeight } PropertyChanges { target: formatRow; visible: false } PropertyChanges { target: titleField; visible: false } PropertyChanges { target: receiverLabel; visible: true; } PropertyChanges { target: imagesButton; visible: false } PropertyChanges { target: formatButton; visible: false } }, State { name: "reply" PropertyChanges { target: messageColumn; height: implicitHeight } PropertyChanges { target: titleField; visible: false } PropertyChanges { target: bodyField; placeholderText:"";focus:true } } ] } }