From b3d853a0d15be2b3ce35fcfd2ad5f558e1e9dd2b Mon Sep 17 00:00:00 2001 From: Ming Rui Zhang Date: Fri, 9 Jul 2021 15:41:47 -0400 Subject: [PATCH] messagewebview: QML invition page implementation Gitlab: #469 Change-Id: I661185530ee3703527fd85a7022b42a3bcb7f579 --- images/icons/block_black-24dp.svg | 11 + images/icons/check-24px.svg | 1 - images/icons/check_black-24dp.svg | 47 ++++ images/icons/ic_block_24px.svg | 13 -- qml.qrc | 2 + resources.qrc | 5 +- src/commoncomponents/GeneralWebEngineView.qml | 78 +++++++ .../emojipicker/EmojiPicker.qml | 50 +---- src/constant/JamiStrings.qml | 6 + src/constant/JamiTheme.qml | 13 +- .../ConversationSmartListContextMenu.qml | 2 +- src/mainview/components/InvitationView.qml | 201 ++++++++++++++++++ src/mainview/components/MessageWebView.qml | 173 +++++++-------- .../components/MessageWebViewFooter.qml | 9 +- src/messagesadapter.cpp | 39 ++-- src/messagesadapter.h | 15 +- 16 files changed, 470 insertions(+), 195 deletions(-) create mode 100644 images/icons/block_black-24dp.svg delete mode 100644 images/icons/check-24px.svg create mode 100644 images/icons/check_black-24dp.svg delete mode 100644 images/icons/ic_block_24px.svg create mode 100644 src/commoncomponents/GeneralWebEngineView.qml create mode 100644 src/mainview/components/InvitationView.qml diff --git a/images/icons/block_black-24dp.svg b/images/icons/block_black-24dp.svg new file mode 100644 index 00000000..c24b8807 --- /dev/null +++ b/images/icons/block_black-24dp.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/images/icons/check-24px.svg b/images/icons/check-24px.svg deleted file mode 100644 index 522695ef..00000000 --- a/images/icons/check-24px.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/icons/check_black-24dp.svg b/images/icons/check_black-24dp.svg new file mode 100644 index 00000000..ca099655 --- /dev/null +++ b/images/icons/check_black-24dp.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/icons/ic_block_24px.svg b/images/icons/ic_block_24px.svg deleted file mode 100644 index 991f6d45..00000000 --- a/images/icons/ic_block_24px.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - BLOCK - - - - - - - - - - \ No newline at end of file diff --git a/qml.qrc b/qml.qrc index d6c7e7dd..c33ffabb 100644 --- a/qml.qrc +++ b/qml.qrc @@ -156,5 +156,7 @@ src/mainview/components/FilesToSendContainer.qml src/commoncomponents/Avatar.qml src/mainview/components/ConversationAvatar.qml + src/mainview/components/InvitationView.qml + src/commoncomponents/GeneralWebEngineView.qml diff --git a/resources.qrc b/resources.qrc index d54f4bfe..383d412e 100644 --- a/resources.qrc +++ b/resources.qrc @@ -22,6 +22,7 @@ images/icons/backup-24px.svg images/icons/check_box_outline_blank-24px.svg images/icons/check_box-24px.svg + images/icons/check_black-24dp.svg images/icons/devices-24px.svg images/icons/ic_arrow_back_24px.svg images/icons/ic_arrow_back_white_24dp.svg @@ -32,13 +33,12 @@ images/icons/ic_arrow_forward_white_48dp_2x.png images/icons/ic_arrow_tab_next_black_9dp_2x.png images/icons/ic_arrow_tab_previous_black_9dp_2x.png - images/icons/ic_block_24px.svg + images/icons/block_black-24dp.svg images/icons/ic_hangup_participant-24px.svg images/icons/delete_forever-24px.svg images/icons/phone_forwarded-24px.svg images/icons/ic_chat_black_24dp_2x.png images/icons/ic_chat_white_24dp.png - images/icons/ic_check_white_18dp_2x.png images/icons/ic_clear_24px.svg images/icons/ic_content_copy.svg images/icons/ic_done_white_24dp.png @@ -102,7 +102,6 @@ images/icons/qr_code-24px.svg images/icons/content_copy-24px.svg images/icons/videocam_off-24px.svg - images/icons/check-24px.svg images/icons/mic_off-24px.svg images/icons/mic-24px.svg images/icons/group_add-24px.svg diff --git a/src/commoncomponents/GeneralWebEngineView.qml b/src/commoncomponents/GeneralWebEngineView.qml new file mode 100644 index 00000000..8390c371 --- /dev/null +++ b/src/commoncomponents/GeneralWebEngineView.qml @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Mingrui Zhang + * + * 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 . + */ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtWebEngine 1.10 +import QtWebChannel 1.14 + +import net.jami.Adapters 1.0 +import net.jami.Constants 1.0 + +WebEngineView { + id: root + + property string onCompletedLoadHtml: "" + property string onCompletedUrl: "qrc" + onCompletedLoadHtml + + backgroundColor: "transparent" + + settings.javascriptEnabled: true + settings.javascriptCanOpenWindows: false + settings.javascriptCanAccessClipboard: true + settings.javascriptCanPaste: true + settings.fullScreenSupportEnabled: true + settings.allowRunningInsecureContent: true + settings.localContentCanAccessRemoteUrls: true + settings.localContentCanAccessFileUrls: true + settings.errorPageEnabled: false + settings.pluginsEnabled: false + settings.screenCaptureEnabled: false + settings.linksIncludedInFocusChain: false + settings.localStorageEnabled: true + + // Provide WebChannel by registering jsBridgeObject. + webChannel: WebChannel { + id: webViewChannel + } + + onNavigationRequested: { + if (request.navigationType === WebEngineView.LinkClickedNavigation) { + MessagesAdapter.openUrl(request.url) + request.action = WebEngineView.IgnoreRequest + } + } + + onContextMenuRequested: { + var needContextMenu = request.selectedText.length || request.isContentEditable + if (!needContextMenu) + request.accepted = true + } + + Component.onCompleted: { + profile.cachePath = UtilsAdapter.getCachePath() + profile.persistentStoragePath = UtilsAdapter.getCachePath() + profile.persistentCookiesPolicy = WebEngineProfile.NoPersistentCookies + profile.httpCacheType = WebEngineProfile.NoCache + profile.httpUserAgent = JamiStrings.httpUserAgentName + + root.loadHtml(UtilsAdapter.qStringFromFile(onCompletedLoadHtml), + onCompletedLoadHtml) + root.url = onCompletedUrl + } +} diff --git a/src/commoncomponents/emojipicker/EmojiPicker.qml b/src/commoncomponents/emojipicker/EmojiPicker.qml index 6e71b255..ca54c2b2 100644 --- a/src/commoncomponents/emojipicker/EmojiPicker.qml +++ b/src/commoncomponents/emojipicker/EmojiPicker.qml @@ -67,28 +67,20 @@ Rectangle { } } - WebEngineView { + GeneralWebEngineView { id: emojiPickerWebView anchors.fill: root - backgroundColor: JamiTheme.transparentColor + webChannel.registeredObjects: [jsBridgeObject] - settings.javascriptEnabled: true - settings.javascriptCanOpenWindows: false - settings.javascriptCanAccessClipboard: true - settings.javascriptCanPaste: true - settings.fullScreenSupportEnabled: true - settings.allowRunningInsecureContent: true - settings.localContentCanAccessRemoteUrls: false - settings.localContentCanAccessFileUrls: false - settings.errorPageEnabled: false - settings.pluginsEnabled: false - settings.screenCaptureEnabled: false - settings.linksIncludedInFocusChain: false - settings.localStorageEnabled: true + onCompletedLoadHtml: ":/src/commoncomponents/emojipicker/emojiPickerLoader.html" - webChannel: emojiPickerWebViewChannel + onActiveFocusChanged: { + if (visible) { + closeEmojiPicker() + } + } onLoadingChanged: { if (loadRequest.status == WebEngineView.LoadSucceededStatus) { @@ -104,31 +96,5 @@ Rectangle { "init_emoji_picker(" + JamiTheme.darkTheme + ");") } } - - onActiveFocusChanged: { - if (visible) { - closeEmojiPicker() - } - } - - Component.onCompleted: { - profile.cachePath = UtilsAdapter.getCachePath() - profile.persistentStoragePath = UtilsAdapter.getCachePath() - profile.persistentCookiesPolicy = WebEngineProfile.NoPersistentCookies - profile.httpCacheType = WebEngineProfile.NoCache - profile.httpUserAgent = JamiStrings.httpUserAgentName - - emojiPickerWebView.loadHtml( - UtilsAdapter.qStringFromFile( - ":/src/commoncomponents/emojipicker/emojiPickerLoader.html"), - ":/src/commoncomponents/emojipicker/emojiPickerLoader.html") - emojiPickerWebView.url = "qrc:/src/commoncomponents/emojipicker/emojiPickerLoader.html" - } - } - - // Provide WebChannel by registering jsBridgeObject. - WebChannel { - id: emojiPickerWebViewChannel - registeredObjects: [jsBridgeObject] } } diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml index d9356ba1..b6223327 100644 --- a/src/constant/JamiStrings.qml +++ b/src/constant/JamiStrings.qml @@ -495,4 +495,10 @@ Item { property string send: qsTr("Send") property string remove: qsTr("Remove") property string writeTo: qsTr("Write to %1") + + // Invitation View + property string invitationViewSentRequest: qsTr("%1 has sent you a request for a conversation.") + property string invitationViewJoinConversation: qsTr("Hello,\nWould you like to join the conversation?") + property string invitationViewAcceptedConversation: qsTr("You have accepted\nthe conversation request") + property string invitationViewWaitingForSync: qsTr("Waiting until %1\nconnects to synchronize the conversation.") } diff --git a/src/constant/JamiTheme.qml b/src/constant/JamiTheme.qml index 687946aa..ae77e712 100644 --- a/src/constant/JamiTheme.qml +++ b/src/constant/JamiTheme.qml @@ -135,6 +135,10 @@ Item { // ParticipantCallInStatusView property color participantCallInStatusTextColor: whiteColor + // InvitationView + property color blockOrange: rgba256(232, 92, 36, 100) + property color blockOrangeTransparency: rgba256(232, 92, 36, 56) + // Chatview property color jamiLightBlue: darkTheme ? "#003b4e" : Qt.rgba(59, 193, 211, 0.3) property color jamiDarkBlue: darkTheme ? "#28b1ed" : "#003b4e" @@ -276,9 +280,16 @@ Item { property real filesToSendDelegateButtonSize: 16 property real filesToSendDelegateFontPointSize: textFontSize + 2 + // InvitationView + property real invitationViewAvatarSize: 112 + property real invitationViewButtonRadius: 25 + property real invitationViewButtonSize: 48 + property real invitationViewButtonIconSize: 24 + property real invitationViewButtonsSpacing: 30 + // Main application spec property real mainViewMinWidth: 300 - property real mainViewMinHeight: 400 + property real mainViewMinHeight: 500 property real wizardViewMinWidth: 500 property real wizardViewMinHeight: 600 diff --git a/src/mainview/components/ConversationSmartListContextMenu.qml b/src/mainview/components/ConversationSmartListContextMenu.qml index f129e98f..1c78e0ba 100644 --- a/src/mainview/components/ConversationSmartListContextMenu.qml +++ b/src/mainview/components/ConversationSmartListContextMenu.qml @@ -135,7 +135,7 @@ ContextMenuAutoLoader { canTrigger: !hasCall && contactType !== Profile.Type.SIP itemName: JamiStrings.blockContact - iconSource: "qrc:/images/icons/ic_block_24px.svg" + iconSource: "qrc:/images/icons/block_black-24dp.svg" addMenuSeparatorAfter: contactType !== Profile.Type.SIP onClicked: { MessagesAdapter.blockConversation(responsibleConvUid) diff --git a/src/mainview/components/InvitationView.qml b/src/mainview/components/InvitationView.qml new file mode 100644 index 00000000..e928cc62 --- /dev/null +++ b/src/mainview/components/InvitationView.qml @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Mingrui Zhang + * + * 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 . + */ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.14 +import QtGraphicalEffects 1.14 + +import net.jami.Adapters 1.0 +import net.jami.Constants 1.0 +import net.jami.Models 1.0 + +import "../../commoncomponents" + +Rectangle { + id: root + + property string invitationViewImageId + property string invitationViewContactTitle + property bool invitationViewNeedSyncing: false + + property real marginSize: 20 + property real textMarginSize: 50 + + color: JamiTheme.primaryBackgroundColor + + Text { + id: invitationViewSentRequestText + + anchors.top: root.top + anchors.topMargin: visible ? marginSize : 0 + anchors.horizontalCenter: root.horizontalCenter + + width: infoColumnLayout.width - textMarginSize + height: visible ? contentHeight : 0 + + visible: !invitationViewNeedSyncing + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.pointSize: JamiTheme.textFontSize + color: JamiTheme.textColor + wrapMode: Text.Wrap + + text: JamiStrings.invitationViewSentRequest.arg(invitationViewContactTitle) + } + + ColumnLayout { + id: infoColumnLayout + + anchors.centerIn: root + + width: root.width + + Avatar { + id: avatarImage + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: invitationViewSentRequestText.visible ? marginSize : 0 + Layout.preferredHeight: JamiTheme.invitationViewAvatarSize + Layout.preferredWidth: JamiTheme.invitationViewAvatarSize + + showPresenceIndicator: false + mode: Avatar.Mode.Contact + imageId: invitationViewImageId + } + + Text { + id: invitationViewMiddlePhraseText + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: marginSize + Layout.preferredWidth: infoColumnLayout.width - textMarginSize + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.weight: Font.DemiBold + font.pointSize: JamiTheme.textFontSize + 3 + color: JamiTheme.textColor + wrapMode: Text.Wrap + + text: root.invitationViewNeedSyncing ? + JamiStrings.invitationViewAcceptedConversation : + JamiStrings.invitationViewJoinConversation + } + + Text { + id: invitationViewWaitingForSyncText + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: marginSize + Layout.preferredWidth: infoColumnLayout.width - textMarginSize + Layout.preferredHeight: visible ? contentHeight : 0 + + visible: invitationViewNeedSyncing + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.pointSize: JamiTheme.textFontSize + color: JamiTheme.textColor + wrapMode: Text.Wrap + + text: JamiStrings.invitationViewWaitingForSync.arg(invitationViewContactTitle) + } + + RowLayout { + id: buttonGroupRowLayout + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: marginSize + + spacing: JamiTheme.invitationViewButtonsSpacing + + visible: !invitationViewNeedSyncing + + PushButton { + id: blockButton + + Layout.alignment: Qt.AlignHCenter + Layout.preferredHeight: JamiTheme.invitationViewButtonSize + Layout.preferredWidth: JamiTheme.invitationViewButtonSize + + preferredSize: JamiTheme.invitationViewButtonIconSize + radius: JamiTheme.invitationViewButtonRadius + + toolTipText: JamiStrings.blockContact + + source: "qrc:/images/icons/block_black-24dp.svg" + imageColor: JamiTheme.primaryBackgroundColor + + normalColor: JamiTheme.blockOrangeTransparency + pressedColor: JamiTheme.blockOrange + hoveredColor: JamiTheme.blockOrange + + onClicked: MessagesAdapter.blockConversation() + } + + PushButton { + id: refuseButton + + Layout.alignment: Qt.AlignHCenter + Layout.preferredHeight: JamiTheme.invitationViewButtonSize + Layout.preferredWidth: JamiTheme.invitationViewButtonSize + + preferredSize: JamiTheme.invitationViewButtonSize + radius: JamiTheme.invitationViewButtonRadius + + toolTipText: JamiStrings.declineContactRequest + + source: "qrc:/images/icons/cross_black_24dp.svg" + imageColor: JamiTheme.primaryBackgroundColor + + normalColor: JamiTheme.refuseRedTransparent + pressedColor: JamiTheme.refuseRed + hoveredColor: JamiTheme.refuseRed + + onClicked: MessagesAdapter.refuseInvitation() + } + + PushButton { + id: acceptButton + + Layout.alignment: Qt.AlignHCenter + Layout.preferredHeight: JamiTheme.invitationViewButtonSize + Layout.preferredWidth: JamiTheme.invitationViewButtonSize + + preferredSize: JamiTheme.invitationViewButtonIconSize + radius: JamiTheme.invitationViewButtonRadius + + toolTipText: JamiStrings.acceptContactRequest + + source: "qrc:/images/icons/check_black-24dp.svg" + imageColor: JamiTheme.primaryBackgroundColor + + normalColor: JamiTheme.acceptGreenTransparency + pressedColor: JamiTheme.acceptGreen + hoveredColor: JamiTheme.acceptGreen + + onClicked: MessagesAdapter.acceptInvitation() + } + } + } +} diff --git a/src/mainview/components/MessageWebView.qml b/src/mainview/components/MessageWebView.qml index 3de94078..4068f16b 100644 --- a/src/mainview/components/MessageWebView.qml +++ b/src/mainview/components/MessageWebView.qml @@ -32,9 +32,15 @@ import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation Rectangle { id: root + enum Mode { + Chat = 0, + Invitation + } + property string headerUserAliasLabelText: "" property string headerUserUserNameLabelText: "" property bool jsLoaded: false + property var mode: MessageWebView.Mode.Chat signal needToHideConversationInCall signal messagesCleared @@ -105,6 +111,24 @@ Rectangle { } } + Connections { + target: MessagesAdapter + + function onChangeInvitationViewRequest(show, isSwarm, needsSyncing, + contactTitle, contactUri) { + if (show) + root.mode = MessageWebView.Mode.Invitation + else { + root.mode = MessageWebView.Mode.Chat + return + } + + invitationView.invitationViewImageId = contactUri + invitationView.invitationViewContactTitle = contactTitle + invitationView.invitationViewNeedSyncing = needsSyncing + } + } + QtObject { id: jsBridgeObject @@ -137,18 +161,6 @@ Rectangle { MessagesAdapter.refuseFile(arg) } - function acceptInvitation() { - MessagesAdapter.acceptInvitation() - } - - function refuseInvitation() { - MessagesAdapter.refuseInvitation() - } - - function blockConversation() { - MessagesAdapter.blockConversation() - } - function emitMessagesCleared() { root.messagesCleared() } @@ -170,12 +182,6 @@ Rectangle { } } - // Provide WebChannel by registering jsBridgeObject. - WebChannel { - id: messageWebViewChannel - registeredObjects: [jsBridgeObject] - } - ColumnLayout { anchors.fill: root @@ -215,8 +221,8 @@ Rectangle { } } - WebEngineView { - id: messageWebView + StackLayout { + id: messageWebViewStack Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true @@ -224,89 +230,66 @@ Rectangle { Layout.topMargin: JamiTheme.messageWebViewHairLineSize Layout.bottomMargin: JamiTheme.messageWebViewHairLineSize - backgroundColor: "transparent" + currentIndex: root.mode - settings.javascriptEnabled: true - settings.javascriptCanOpenWindows: true - settings.javascriptCanAccessClipboard: true - settings.javascriptCanPaste: true - settings.fullScreenSupportEnabled: true - settings.allowRunningInsecureContent: true - settings.localContentCanAccessRemoteUrls: true - settings.localContentCanAccessFileUrls: true - settings.errorPageEnabled: false - settings.pluginsEnabled: false - settings.screenCaptureEnabled: false - settings.linksIncludedInFocusChain: false - settings.localStorageEnabled: true + GeneralWebEngineView { + id: messageWebView - webChannel: messageWebViewChannel + Layout.fillWidth: true + Layout.fillHeight: true - DropArea { - anchors.fill: parent - onDropped: messageWebViewFooter.setFilePathsToSend(drop.urls) - } + onCompletedLoadHtml: ":/chatview.html" - onNavigationRequested: { - if (request.navigationType === WebEngineView.LinkClickedNavigation) { - MessagesAdapter.openUrl(request.url) - request.action = WebEngineView.IgnoreRequest + webChannel.registeredObjects: [jsBridgeObject] + + DropArea { + anchors.fill: parent + onDropped: messageWebViewFooter.setFilePathsToSend(drop.urls) + } + + onLoadingChanged: { + if (loadRequest.status == WebEngineView.LoadSucceededStatus) { + messageWebView.runJavaScript(UtilsAdapter.getStyleSheet( + "chatcss", + UtilsAdapter.qStringFromFile( + ":/chatview.css"))) + messageWebView.runJavaScript(UtilsAdapter.getStyleSheet( + "chatwin", + UtilsAdapter.qStringFromFile( + ":/chatview-qt.css"))) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/linkify.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/linkify-html.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/linkify-string.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/qwebchannel.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/jed.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/emoji.js")) + messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( + ":/previewInfo.js")) + messageWebView.runJavaScript( + UtilsAdapter.qStringFromFile(":/chatview.js"), + function() { + messageWebView.runJavaScript("init_i18n();") + MessagesAdapter.setDisplayLinks() + updateChatviewTheme() + messageWebView.runJavaScript("displayNavbar(false);") + messageWebView.runJavaScript("hideMessageBar(true);") + jsLoaded = true + }) + } } } - onLoadingChanged: { - if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - messageWebView.runJavaScript(UtilsAdapter.getStyleSheet( - "chatcss", - UtilsAdapter.qStringFromFile( - ":/chatview.css"))) - messageWebView.runJavaScript(UtilsAdapter.getStyleSheet( - "chatwin", - UtilsAdapter.qStringFromFile( - ":/chatview-qt.css"))) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/linkify.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/linkify-html.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/linkify-string.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/qwebchannel.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/jed.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/emoji.js")) - messageWebView.runJavaScript(UtilsAdapter.qStringFromFile( - ":/previewInfo.js")) - messageWebView.runJavaScript( - UtilsAdapter.qStringFromFile(":/chatview.js"), - function() { - messageWebView.runJavaScript("init_i18n();") - MessagesAdapter.setDisplayLinks() - updateChatviewTheme() - messageWebView.runJavaScript("displayNavbar(false);") - messageWebView.runJavaScript("hideMessageBar(true);") - jsLoaded = true - }) - } - } + InvitationView { + id: invitationView - onContextMenuRequested: { - var needContextMenu = request.selectedText.length || request.isContentEditable - if (!needContextMenu) - request.accepted = true - } - - Component.onCompleted: { - profile.cachePath = UtilsAdapter.getCachePath() - profile.persistentStoragePath = UtilsAdapter.getCachePath() - profile.persistentCookiesPolicy = WebEngineProfile.NoPersistentCookies - profile.httpCacheType = WebEngineProfile.NoCache - profile.httpUserAgent = JamiStrings.httpUserAgentName - - messageWebView.loadHtml(UtilsAdapter.qStringFromFile( - ":/chatview.html"), ":/chatview.html") - messageWebView.url = "qrc:/chatview.html" + Layout.fillWidth: true + Layout.fillHeight: true } } diff --git a/src/mainview/components/MessageWebViewFooter.qml b/src/mainview/components/MessageWebViewFooter.qml index 66ca473b..f945de94 100644 --- a/src/mainview/components/MessageWebViewFooter.qml +++ b/src/mainview/components/MessageWebViewFooter.qml @@ -78,10 +78,11 @@ Rectangle { messageBar.textAreaObj.pasteText() } - function onChangeMessageWebViewFooterVisibilityRequest(visible) { - messageBar.visible = visible - dataTransferSendContainer.visible = visible - root.visible = visible + function onChangeInvitationViewRequest(show, isSwarm) { + var footerVisibility = show ? !isSwarm : !show + messageBar.visible = footerVisibility + dataTransferSendContainer.visible = footerVisibility + root.visible = footerVisibility } } diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp index 1e12851d..622cf487 100644 --- a/src/messagesadapter.cpp +++ b/src/messagesadapter.cpp @@ -85,11 +85,11 @@ MessagesAdapter::setupChatView(const QString& convUid) setMessagesVisibility(false); setIsSwarm(convInfo.isSwarm()); - setInvitation(convInfo.isRequest or convInfo.needsSyncing, - convModel->title(convInfo.uid), - contactURI, - !convInfo.isSwarm(), - convInfo.needsSyncing); + changeInvitationViewRequest(convInfo.isRequest or convInfo.needsSyncing, + !convInfo.isSwarm(), + convInfo.needsSyncing, + convModel->title(convInfo.uid), + contactURI); Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared())); clearChatView(); @@ -384,11 +384,11 @@ MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info& !(convInfo.isSwarm() && (convInfo.isRequest || convInfo.needsSyncing)))); - setInvitation(convInfo.isRequest or convInfo.needsSyncing, - title, - contactUri, - convInfo.isSwarm(), - convInfo.needsSyncing); + changeInvitationViewRequest(convInfo.isRequest or convInfo.needsSyncing, + convInfo.isSwarm(), + convInfo.needsSyncing, + title, + contactUri); if (convInfo.isSwarm()) return; auto& contact = accInfo->contactModel->getContact(contactUri); @@ -439,21 +439,6 @@ MessagesAdapter::setMessagesVisibility(bool visible) QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s)); } -void -MessagesAdapter::setInvitation( - bool show, const QString& contactUri, const QString& contactId, bool isSwarm, bool needsSyncing) -{ - Q_EMIT changeMessageWebViewFooterVisibilityRequest(show ? !isSwarm : !show); - - QString s = show ? QString::fromLatin1("showInvitation(\"%1\", \"%2\", %3, %4)") - .arg(contactUri) - .arg(contactId) - .arg(isSwarm) - .arg(needsSyncing) - : QString::fromLatin1("showInvitation()"); - QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s)); -} - void MessagesAdapter::setIsSwarm(bool isSwarm) { @@ -618,7 +603,7 @@ MessagesAdapter::refuseInvitation(const QString& convUid) { const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid; lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, false); - setInvitation(false); + changeInvitationViewRequest(false); } void @@ -626,7 +611,7 @@ MessagesAdapter::blockConversation(const QString& convUid) { const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid; lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, true); - setInvitation(false); + changeInvitationViewRequest(false); } void diff --git a/src/messagesadapter.h b/src/messagesadapter.h index bdf45443..c97d284c 100644 --- a/src/messagesadapter.h +++ b/src/messagesadapter.h @@ -48,11 +48,11 @@ protected: const QString& convUid, bool banContact = false); Q_INVOKABLE void clearConversationHistory(const QString& accountId, const QString& convUid); - - // JS Q_INVOKABLE. Q_INVOKABLE void acceptInvitation(const QString& convId = {}); Q_INVOKABLE void refuseInvitation(const QString& convUid = ""); Q_INVOKABLE void blockConversation(const QString& convUid = ""); + + // JS Q_INVOKABLE. Q_INVOKABLE void setDisplayLinks(); Q_INVOKABLE void sendMessage(const QString& message); Q_INVOKABLE void sendFile(const QString& message); @@ -69,11 +69,6 @@ protected: // Run corrsponding js functions, c++ to qml. void setMessagesVisibility(bool visible); - void setInvitation(bool show, - const QString& contactUri = {}, - const QString& contactId = {}, - bool isSwarm = false, - bool needsSyncing = false); void setIsSwarm(bool isSwarm); void clearChatView(); void printHistory(ConversationModel& conversationModel, MessagesList interactions); @@ -98,7 +93,11 @@ Q_SIGNALS: void newMessageBarPlaceholderText(QString placeholderText); void newFilePasted(QString filePath); void newTextPasted(); - void changeMessageWebViewFooterVisibilityRequest(bool visible); + void changeInvitationViewRequest(bool show, + bool isSwarm = false, + bool needsSyncing = false, + QString contactTitle = {}, + QString contactUri = {}); private Q_SLOTS: void slotMessagesCleared();