2020-08-03 13:27:42 -04:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020 by Savoir-faire Linux
|
|
|
|
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
2020-09-04 14:51:39 -04:00
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
import QtQuick 2.14
|
|
|
|
import QtQuick.Controls 2.14
|
|
|
|
import QtQuick.Layouts 1.14
|
|
|
|
import QtWebEngine 1.10
|
|
|
|
import QtWebChannel 1.14
|
|
|
|
import net.jami.Models 1.0
|
2020-09-04 14:51:39 -04:00
|
|
|
import net.jami.Adapters 1.0
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
import "../../commoncomponents"
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
id: messageWebViewRect
|
|
|
|
|
2020-07-30 13:38:57 +02:00
|
|
|
property int messageWebViewHeaderPreferredHeight: 64
|
2020-08-03 13:27:42 -04:00
|
|
|
property string headerUserAliasLabelText: ""
|
|
|
|
property string headerUserUserNameLabelText: ""
|
2020-10-06 14:19:28 -04:00
|
|
|
property bool jsLoaded: false
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
signal needToHideConversationInCall
|
|
|
|
|
|
|
|
signal sendMessageContentSaved(string arg)
|
|
|
|
signal messagesCleared
|
|
|
|
signal messagesLoaded
|
|
|
|
|
2020-09-29 11:47:57 -04:00
|
|
|
function focusMessageWebView() {
|
|
|
|
messageWebView.forceActiveFocus()
|
|
|
|
}
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
function webViewRunJavaScript(arg) {
|
|
|
|
messageWebView.runJavaScript(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSendContactRequestButtonVisible(visible) {
|
|
|
|
messageWebViewHeader.sendContactRequestButtonVisible = visible
|
|
|
|
}
|
|
|
|
|
|
|
|
function setMessagingHeaderButtonsVisible(visible) {
|
|
|
|
messageWebViewHeader.toggleMessagingHeaderButtonsVisible(visible)
|
|
|
|
}
|
|
|
|
|
|
|
|
function resetMessagingHeaderBackButtonSource(reset) {
|
|
|
|
messageWebViewHeader.resetBackToWelcomeViewButtonSource(reset)
|
|
|
|
}
|
|
|
|
|
|
|
|
JamiFileDialog {
|
|
|
|
id: jamiFileDialog
|
|
|
|
|
|
|
|
mode: JamiFileDialog.Mode.OpenFiles
|
|
|
|
|
|
|
|
onAccepted: {
|
|
|
|
var filePaths = jamiFileDialog.files
|
|
|
|
for (var index = 0; index < filePaths.length; ++index) {
|
2020-09-04 14:51:39 -04:00
|
|
|
var path = UtilsAdapter.getAbsPath(filePaths[index])
|
2020-08-03 13:27:42 -04:00
|
|
|
MessagesAdapter.setNewMessagesContent(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MessageWebViewHeader {
|
|
|
|
|
|
|
|
DropArea{
|
|
|
|
anchors.fill: parent
|
|
|
|
onDropped: {
|
2020-09-04 14:51:39 -04:00
|
|
|
var path = UtilsAdapter.getAbsPath(drop.text.toString())
|
2020-08-03 13:27:42 -04:00
|
|
|
MessagesAdapter.setNewMessagesContent(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
id: messageWebViewHeader
|
|
|
|
|
|
|
|
anchors.top: messageWebViewRect.top
|
|
|
|
anchors.left: messageWebViewRect.left
|
|
|
|
|
|
|
|
width: messageWebViewRect.width
|
|
|
|
height: messageWebViewHeaderPreferredHeight
|
|
|
|
|
|
|
|
userAliasLabelText: headerUserAliasLabelText
|
|
|
|
userUserNameLabelText: headerUserUserNameLabelText
|
|
|
|
|
2020-09-21 11:50:29 +02:00
|
|
|
onBackClicked: {
|
2020-08-03 13:27:42 -04:00
|
|
|
MessagesAdapter.updateDraft()
|
2020-09-21 11:50:29 +02:00
|
|
|
mainViewWindow.showWelcomeView()
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
onNeedToHideConversationInCall: {
|
|
|
|
messageWebViewRect.needToHideConversationInCall()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: jsBridgeObject
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
// ID, under which this object will be known at chatview.js side.
|
2020-08-03 13:27:42 -04:00
|
|
|
WebChannel.id: "jsbridge"
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
// Functions that are exposed, return code can be derived from js side
|
|
|
|
// by setting callback function.
|
2020-08-03 13:27:42 -04:00
|
|
|
function deleteInteraction(arg) {
|
|
|
|
MessagesAdapter.deleteInteraction(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function retryInteraction(arg) {
|
|
|
|
MessagesAdapter.retryInteraction(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function openFile(arg) {
|
|
|
|
MessagesAdapter.openFile(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function acceptFile(arg) {
|
|
|
|
MessagesAdapter.acceptFile(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function refuseFile(arg) {
|
|
|
|
MessagesAdapter.refuseFile(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendMessage(arg) {
|
|
|
|
MessagesAdapter.sendMessage(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendImage(arg) {
|
|
|
|
MessagesAdapter.sendImage(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendFile(arg) {
|
|
|
|
MessagesAdapter.sendFile(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function selectFile() {
|
|
|
|
jamiFileDialog.open()
|
|
|
|
}
|
|
|
|
|
|
|
|
function acceptInvitation() {
|
|
|
|
MessagesAdapter.acceptInvitation()
|
2020-09-14 16:15:28 +02:00
|
|
|
messageWebViewHeader.sendContactRequestButtonVisible = false
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function refuseInvitation() {
|
|
|
|
MessagesAdapter.refuseInvitation()
|
2020-09-14 16:15:28 +02:00
|
|
|
messageWebViewHeader.sendContactRequestButtonVisible = false
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function blockConversation() {
|
|
|
|
MessagesAdapter.blockConversation()
|
2020-09-14 16:15:28 +02:00
|
|
|
messageWebViewHeader.sendContactRequestButtonVisible = false
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function emitMessagesCleared() {
|
|
|
|
messageWebViewRect.messagesCleared()
|
|
|
|
}
|
|
|
|
|
|
|
|
function emitMessagesLoaded() {
|
|
|
|
messageWebViewRect.messagesLoaded()
|
|
|
|
}
|
|
|
|
|
|
|
|
function emitPasteKeyDetected() {
|
|
|
|
MessagesAdapter.pasteKeyDetected()
|
|
|
|
}
|
|
|
|
|
|
|
|
function openAudioRecorder(spikePosX, spikePosY) {
|
|
|
|
recordBox.openRecorder(spikePosX, spikePosY, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
function openVideoRecorder(spikePosX, spikePosY) {
|
|
|
|
recordBox.openRecorder(spikePosX, spikePosY, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveSendMessageContent(arg) {
|
|
|
|
messageWebViewRect.sendMessageContentSaved(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function onComposing(isComposing) {
|
|
|
|
MessagesAdapter.onComposing(isComposing)
|
|
|
|
}
|
2020-10-07 10:28:17 -04:00
|
|
|
|
|
|
|
function parseI18nData() {
|
|
|
|
return {
|
|
|
|
["backButtonTitle"] : JamiStrings.backButtonTitle,
|
|
|
|
["placeCallButtonTitle"] : JamiStrings.placeCallButtonTitle,
|
|
|
|
["placeAudioCallButtonTitle"] : JamiStrings.placeAudioCallButtonTitle,
|
|
|
|
["addToConversationsButtonTitle"] : JamiStrings.addToConversationsButtonTitle,
|
|
|
|
["unbanButtonTitle"] : JamiStrings.unbanButtonTitle,
|
|
|
|
["sendButtonTitle"] : JamiStrings.sendButtonTitle,
|
|
|
|
["optionsButtonTitle"] : JamiStrings.optionsButtonTitle,
|
|
|
|
["backToBottomBtnInnerHTML"] : JamiStrings.backToBottomBtnInnerHTML,
|
|
|
|
["sendFileButtonTitle"] : JamiStrings.sendFileButtonTitle,
|
|
|
|
["videoRecordButtonTitle"] : JamiStrings.videoRecordButtonTitle,
|
|
|
|
["audioRecordButtonTitle"] : JamiStrings.audioRecordButtonTitle,
|
|
|
|
["acceptButtonTitle"] : JamiStrings.acceptButtonTitle,
|
|
|
|
["refuseButtonTitle"] : JamiStrings.refuseButtonTitle,
|
|
|
|
["blockButtonTitle"] : JamiStrings.blockButtonTitle,
|
|
|
|
["messageBarInputPlaceholder"] : JamiStrings.messageBarInputPlaceholder,
|
|
|
|
["placeHolderTemporaryContact"] : JamiStrings.placeHolderTemporaryContact,
|
|
|
|
["isNotInYourContacts"] : JamiStrings.isNotInYourContacts,
|
|
|
|
["automaticallyAcceptInvitation"] : JamiStrings.automaticallyAcceptInvitation,
|
|
|
|
["daysAgo"] : JamiStrings.daysAgo,
|
2020-10-09 10:31:22 -04:00
|
|
|
["oneDayAgo"] : JamiStrings.oneDayAgo,
|
2020-10-07 10:28:17 -04:00
|
|
|
["hoursAgo"] : JamiStrings.hoursAgo,
|
2020-10-09 10:31:22 -04:00
|
|
|
["oneHourAgo"] : JamiStrings.oneHourAgo,
|
2020-10-07 10:28:17 -04:00
|
|
|
["minutesAgo"] : JamiStrings.minutesAgo,
|
|
|
|
["justNow"] : JamiStrings.justNow,
|
|
|
|
["failureString"] : JamiStrings.failureString,
|
|
|
|
["acceptString"] : JamiStrings.acceptString,
|
|
|
|
["refuseString"] : JamiStrings.refuseString,
|
|
|
|
["deleteString"] : JamiStrings.deleteString,
|
|
|
|
["retryString"] : JamiStrings.retryString
|
|
|
|
}
|
|
|
|
}
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
WebEngineView {
|
|
|
|
id: messageWebView
|
|
|
|
|
|
|
|
anchors.top: messageWebViewHeader.bottom
|
|
|
|
anchors.topMargin: 1
|
|
|
|
anchors.left: messageWebViewRect.left
|
|
|
|
|
|
|
|
width: messageWebViewRect.width
|
|
|
|
height: messageWebViewRect.height - messageWebViewHeaderPreferredHeight
|
|
|
|
|
|
|
|
settings.javascriptEnabled: true
|
|
|
|
settings.javascriptCanOpenWindows: 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: false
|
|
|
|
|
|
|
|
webChannel: messageWebViewChannel
|
|
|
|
profile: messageWebViewProfile
|
|
|
|
|
|
|
|
DropArea{
|
|
|
|
anchors.fill: parent
|
|
|
|
onDropped: {
|
2020-09-04 14:51:39 -04:00
|
|
|
var path = UtilsAdapter.getAbsPath(drop.text.toString())
|
2020-08-03 13:27:42 -04:00
|
|
|
MessagesAdapter.setNewMessagesContent(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-29 13:45:07 -04:00
|
|
|
onNavigationRequested: {
|
|
|
|
if(request.navigationType === WebEngineView.LinkClickedNavigation) {
|
|
|
|
MessagesAdapter.openUrl(request.url)
|
|
|
|
request.action = WebEngineView.IgnoreRequest
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
onLoadingChanged: {
|
|
|
|
if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.getStyleSheet(
|
2020-08-03 13:27:42 -04:00
|
|
|
"chatcss",
|
2020-09-04 14:51:39 -04:00
|
|
|
UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/chatview.css")))
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.getStyleSheet(
|
2020-08-03 13:27:42 -04:00
|
|
|
"chatwin",
|
2020-09-04 14:51:39 -04:00
|
|
|
UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/chatview-windows.css")))
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/linkify.js"))
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/linkify-html.js"))
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/linkify-string.js"))
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/qwebchannel.js"))
|
2020-10-07 10:28:17 -04:00
|
|
|
messageWebView.runJavaScript(
|
|
|
|
UtilsAdapter.qStringFromFile(":/chatview.js"),
|
|
|
|
function() {
|
|
|
|
messageWebView.runJavaScript("init_i18n();")
|
|
|
|
messageWebView.runJavaScript("displayNavbar(false);")
|
|
|
|
jsLoaded = true
|
|
|
|
})
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
}
|
2020-09-22 11:28:20 -04:00
|
|
|
|
|
|
|
onContextMenuRequested: {
|
|
|
|
var needContextMenu = request.selectedText.length || request.isContentEditable
|
|
|
|
if (!needContextMenu)
|
|
|
|
request.accepted = true
|
|
|
|
}
|
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
Component.onCompleted: {
|
2020-09-04 14:51:39 -04:00
|
|
|
messageWebView.loadHtml(UtilsAdapter.qStringFromFile(
|
2020-08-03 13:27:42 -04:00
|
|
|
":/chatview.html"), ":/chatview.html")
|
|
|
|
messageWebView.url = "qrc:/chatview.html"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
// Provide WebEngineProfile.
|
2020-08-03 13:27:42 -04:00
|
|
|
WebEngineProfile {
|
|
|
|
id: messageWebViewProfile
|
|
|
|
|
2020-09-04 14:51:39 -04:00
|
|
|
cachePath: UtilsAdapter.getCachePath()
|
|
|
|
persistentStoragePath: UtilsAdapter.getCachePath()
|
2020-08-03 13:27:42 -04:00
|
|
|
persistentCookiesPolicy: WebEngineProfile.NoPersistentCookies
|
|
|
|
httpCacheType: WebEngineProfile.NoCache
|
|
|
|
httpUserAgent: "jami-windows"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
// Provide WebChannel by registering jsBridgeObject.
|
2020-08-03 13:27:42 -04:00
|
|
|
WebChannel {
|
|
|
|
id: messageWebViewChannel
|
|
|
|
registeredObjects: [jsBridgeObject]
|
|
|
|
}
|
|
|
|
}
|