mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-04-21 21:52:03 +02:00
build: add option to build without Qt WebEngine
This patch allows building the project without Qt WebEngine, by disabling (for the time being) the features that depend on it: the emoji picker, link previews, and media file previews in the chatview. Co-authored-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> Co-authored-by: Amin Bandali <amin.bandali@savoirfairelinux.com> Change-Id: I74751b0cc6f22c61a6fd7281ca3207e0fdbb2212
This commit is contained in:
parent
d6d1f90315
commit
3f88ceda93
17 changed files with 353 additions and 150 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -23,7 +23,7 @@ build-local/
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
*qmlcache.qrc
|
*qmlcache.qrc
|
||||||
|
qml_without_webengine.qrc
|
||||||
.deploy.stamp
|
.deploy.stamp
|
||||||
|
|
||||||
# auto-gen files
|
# auto-gen files
|
||||||
|
|
|
@ -42,12 +42,22 @@ set(QT_MODULES
|
||||||
Concurrent
|
Concurrent
|
||||||
Core
|
Core
|
||||||
Core5Compat
|
Core5Compat
|
||||||
WebEngineCore
|
|
||||||
WebEngineQuick
|
|
||||||
WebChannel
|
|
||||||
WebEngineWidgets
|
|
||||||
Multimedia
|
Multimedia
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT DEFINED WITH_WEBENGINE)
|
||||||
|
set(WITH_WEBENGINE true)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WITH_WEBENGINE)
|
||||||
|
list(APPEND QT_MODULES
|
||||||
|
WebEngineCore
|
||||||
|
WebEngineQuick
|
||||||
|
WebChannel
|
||||||
|
WebEngineWidgets
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 COMPONENTS ${QT_MODULES} REQUIRED)
|
find_package(Qt6 COMPONENTS ${QT_MODULES} REQUIRED)
|
||||||
foreach(MODULE ${QT_MODULES})
|
foreach(MODULE ${QT_MODULES})
|
||||||
list(APPEND QT_LIBS "Qt::${MODULE}")
|
list(APPEND QT_LIBS "Qt::${MODULE}")
|
||||||
|
@ -57,8 +67,23 @@ set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
|
||||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS})
|
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS})
|
||||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
|
||||||
|
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
|
||||||
|
include(FindPython3)
|
||||||
|
find_package (Python3 COMPONENTS Interpreter)
|
||||||
|
set(PYTHON_EXEC ${Python3_EXECUTABLE})
|
||||||
|
else()
|
||||||
|
include(FindPythonInterp)
|
||||||
|
set(PYTHON_EXEC ${PYTHON_EXECUTABLE})
|
||||||
|
endif()
|
||||||
|
|
||||||
set(QML_RESOURCES ${PROJECT_SOURCE_DIR}/resources.qrc)
|
set(QML_RESOURCES ${PROJECT_SOURCE_DIR}/resources.qrc)
|
||||||
set(QML_RESOURCES_QML ${PROJECT_SOURCE_DIR}/qml.qrc)
|
if(WITH_WEBENGINE)
|
||||||
|
set(QML_RESOURCES_QML ${PROJECT_SOURCE_DIR}/qml.qrc)
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND ${PYTHON_EXEC} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-qrc-without-webengine.py
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
set(QML_RESOURCES_QML ${PROJECT_SOURCE_DIR}/qml_without_webengine.qrc)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
@ -78,14 +103,6 @@ file(GLOB_RECURSE
|
||||||
RES_FILES CONFIGURE_DEPENDS
|
RES_FILES CONFIGURE_DEPENDS
|
||||||
${PROJECT_SOURCE_DIR}/resources/*
|
${PROJECT_SOURCE_DIR}/resources/*
|
||||||
)
|
)
|
||||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
|
|
||||||
include(FindPython3)
|
|
||||||
find_package (Python3 COMPONENTS Interpreter)
|
|
||||||
set(PYTHON_EXEC ${Python3_EXECUTABLE})
|
|
||||||
else()
|
|
||||||
include(FindPythonInterp)
|
|
||||||
set(PYTHON_EXEC ${PYTHON_EXECUTABLE})
|
|
||||||
endif()
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${PYTHON_EXEC} ${PROJECT_SOURCE_DIR}/gen-resources.py
|
COMMAND ${PYTHON_EXEC} ${PROJECT_SOURCE_DIR}/gen-resources.py
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
|
@ -137,7 +154,6 @@ set(COMMON_SOURCES
|
||||||
${SRC_DIR}/currentconversation.cpp
|
${SRC_DIR}/currentconversation.cpp
|
||||||
${SRC_DIR}/currentaccount.cpp
|
${SRC_DIR}/currentaccount.cpp
|
||||||
${SRC_DIR}/videodevices.cpp
|
${SRC_DIR}/videodevices.cpp
|
||||||
${SRC_DIR}/previewengine.cpp
|
|
||||||
${SRC_DIR}/videoprovider.cpp
|
${SRC_DIR}/videoprovider.cpp
|
||||||
${SRC_DIR}/callparticipantsmodel.cpp
|
${SRC_DIR}/callparticipantsmodel.cpp
|
||||||
)
|
)
|
||||||
|
@ -194,11 +210,19 @@ set(COMMON_HEADERS
|
||||||
${SRC_DIR}/currentconversation.h
|
${SRC_DIR}/currentconversation.h
|
||||||
${SRC_DIR}/currentaccount.h
|
${SRC_DIR}/currentaccount.h
|
||||||
${SRC_DIR}/videodevices.h
|
${SRC_DIR}/videodevices.h
|
||||||
${SRC_DIR}/previewengine.h
|
|
||||||
${SRC_DIR}/videoprovider.h
|
${SRC_DIR}/videoprovider.h
|
||||||
${SRC_DIR}/callparticipantsmodel.h
|
${SRC_DIR}/callparticipantsmodel.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WITH_WEBENGINE)
|
||||||
|
list(APPEND COMMON_SOURCES
|
||||||
|
${SRC_DIR}/previewengine.cpp)
|
||||||
|
add_definitions(-DWITH_WEBENGINE)
|
||||||
|
else()
|
||||||
|
list(APPEND COMMON_SOURCES
|
||||||
|
${SRC_DIR}/nowebengine/previewengine.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
# For libavutil/avframe.
|
# For libavutil/avframe.
|
||||||
set(LIBJAMI_CONTRIB_DIR "${PROJECT_SOURCE_DIR}/../daemon/contrib")
|
set(LIBJAMI_CONTRIB_DIR "${PROJECT_SOURCE_DIR}/../daemon/contrib")
|
||||||
find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h
|
find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h
|
||||||
|
|
1
qml.qrc
1
qml.qrc
|
@ -30,6 +30,7 @@
|
||||||
<file>src/commoncomponents/PresenceIndicator.qml</file>
|
<file>src/commoncomponents/PresenceIndicator.qml</file>
|
||||||
<file>src/commoncomponents/DaemonReconnectPopup.qml</file>
|
<file>src/commoncomponents/DaemonReconnectPopup.qml</file>
|
||||||
<file>src/commoncomponents/SpinningAnimation.qml</file>
|
<file>src/commoncomponents/SpinningAnimation.qml</file>
|
||||||
|
<file>src/commoncomponents/MediaPreviewBase.qml</file>
|
||||||
<file>src/settingsview/SettingsView.qml</file>
|
<file>src/settingsview/SettingsView.qml</file>
|
||||||
<file>src/settingsview/components/ChatviewSettings.qml</file>
|
<file>src/settingsview/components/ChatviewSettings.qml</file>
|
||||||
<file>src/settingsview/components/FileTransferSettings.qml</file>
|
<file>src/settingsview/components/FileTransferSettings.qml</file>
|
||||||
|
|
31
scripts/gen-qrc-without-webengine.py
Executable file
31
scripts/gen-qrc-without-webengine.py
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
#
|
||||||
|
# Author: Kateryna Kostiuk <kateryna.kostiuk@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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
with open('qml_without_webengine.qrc', 'w') as outfile:
|
||||||
|
with open('qml.qrc', 'r') as infile:
|
||||||
|
line = infile.readline()
|
||||||
|
while line:
|
||||||
|
if 'EmojiPicker.qml' in line:
|
||||||
|
outfile.write('\t<file>src/nowebengine/EmojiPicker.qml</file>\n')
|
||||||
|
elif 'MediaPreviewBase.qml' in line:
|
||||||
|
outfile.write('\t<file>src/nowebengine/MediaPreviewBase.qml</file>\n')
|
||||||
|
else:
|
||||||
|
outfile.write(line)
|
||||||
|
line = infile.readline()
|
|
@ -22,7 +22,6 @@ import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import QtWebEngine
|
|
||||||
|
|
||||||
import net.jami.Models 1.1
|
import net.jami.Models 1.1
|
||||||
import net.jami.Constants 1.1
|
import net.jami.Constants 1.1
|
||||||
|
@ -41,7 +40,7 @@ Loader {
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
if (Status === Interaction.Status.TRANSFER_FINISHED) {
|
if (Status === Interaction.Status.TRANSFER_FINISHED) {
|
||||||
mediaInfo = MessagesAdapter.getMediaInfo(Body)
|
mediaInfo = MessagesAdapter.getMediaInfo(Body)
|
||||||
if (Object.keys(mediaInfo).length !== 0)
|
if (Object.keys(mediaInfo).length !== 0 && WITH_WEBENGINE)
|
||||||
return localMediaMsgComp
|
return localMediaMsgComp
|
||||||
}
|
}
|
||||||
return dataTransferMsgComp
|
return dataTransferMsgComp
|
||||||
|
@ -264,48 +263,10 @@ Loader {
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
id: avComp
|
id: avComp
|
||||||
WebEngineView {
|
Loader {
|
||||||
id: wev
|
Component.onCompleted: {
|
||||||
anchors.right: isOutgoing ? parent.right : undefined
|
var qml = WITH_WEBENGINE ? "qrc:/src/commoncomponents/MediaPreviewBase.qml" : "qrc:/src/nowebengine/MediaPreviewBase.qml"
|
||||||
readonly property real minSize: 192
|
setSource( qml, { isVideo: mediaInfo.isVideo, html:mediaInfo.html } )
|
||||||
readonly property real maxSize: 256
|
|
||||||
readonly property real aspectRatio: 1 / .75
|
|
||||||
readonly property real adjustedWidth: Math.min(maxSize,
|
|
||||||
Math.max(minSize,
|
|
||||||
innerContent.width - senderMargin))
|
|
||||||
width: isFullScreen ? parent.width : adjustedWidth
|
|
||||||
height: mediaInfo.isVideo ?
|
|
||||||
isFullScreen ?
|
|
||||||
parent.height :
|
|
||||||
Math.ceil(adjustedWidth / aspectRatio) :
|
|
||||||
54
|
|
||||||
onContextMenuRequested: function(request) {
|
|
||||||
request.accepted = true
|
|
||||||
}
|
|
||||||
settings.fullScreenSupportEnabled: mediaInfo.isVideo
|
|
||||||
settings.javascriptCanOpenWindows: false
|
|
||||||
Component.onCompleted: loadHtml(mediaInfo.html, 'file://')
|
|
||||||
layer.enabled: !isFullScreen
|
|
||||||
layer.effect: OpacityMask {
|
|
||||||
maskSource: MessageBubble {
|
|
||||||
out: isOutgoing
|
|
||||||
type: seq
|
|
||||||
width: wev.width
|
|
||||||
height: wev.height
|
|
||||||
radius: msgRadius
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFullScreenRequested: function(request) {
|
|
||||||
if (request.toggleOn) {
|
|
||||||
layoutManager.pushFullScreenItem(
|
|
||||||
this,
|
|
||||||
localMediaCompLoader,
|
|
||||||
null,
|
|
||||||
function() { wev.fullScreenCancelled() })
|
|
||||||
} else if (!request.toggleOn) {
|
|
||||||
layoutManager.removeFullScreenItem(this)
|
|
||||||
}
|
|
||||||
request.accept()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
74
src/commoncomponents/MediaPreviewBase.qml
Normal file
74
src/commoncomponents/MediaPreviewBase.qml
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
|
||||||
|
* Author: Andreas Traczyk <andreas.traczyk@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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import QtWebEngine
|
||||||
|
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
|
||||||
|
WebEngineView {
|
||||||
|
id: wev
|
||||||
|
property bool isVideo
|
||||||
|
property string html
|
||||||
|
readonly property real minSize: 192
|
||||||
|
readonly property real maxSize: 256
|
||||||
|
readonly property real aspectRatio: 1 / .75
|
||||||
|
readonly property real adjustedWidth: Math.min(maxSize,
|
||||||
|
Math.max(minSize,
|
||||||
|
innerContent.width - senderMargin))
|
||||||
|
anchors.right: isOutgoing ? parent.right : undefined
|
||||||
|
width: isFullScreen ? parent.width : adjustedWidth
|
||||||
|
height: isVideo ?
|
||||||
|
isFullScreen ?
|
||||||
|
parent.height :
|
||||||
|
Math.ceil(adjustedWidth / aspectRatio) :
|
||||||
|
54
|
||||||
|
onContextMenuRequested: function(request) {
|
||||||
|
request.accepted = true
|
||||||
|
}
|
||||||
|
settings.fullScreenSupportEnabled: isVideo
|
||||||
|
settings.javascriptCanOpenWindows: false
|
||||||
|
Component.onCompleted: loadHtml(html, 'file://')
|
||||||
|
layer.enabled: !isFullScreen
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: MessageBubble {
|
||||||
|
out: isOutgoing
|
||||||
|
type: seq
|
||||||
|
width: wev.width
|
||||||
|
height: wev.height
|
||||||
|
radius: msgRadius
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onFullScreenRequested: function(request) {
|
||||||
|
if (request.toggleOn) {
|
||||||
|
layoutManager.pushFullScreenItem(
|
||||||
|
this,
|
||||||
|
localMediaCompLoader,
|
||||||
|
null,
|
||||||
|
function() { wev.fullScreenCancelled() })
|
||||||
|
} else if (!request.toggleOn) {
|
||||||
|
layoutManager.removeFullScreenItem(this)
|
||||||
|
}
|
||||||
|
request.accept()
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,8 +24,11 @@
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QtQuick>
|
||||||
|
#ifdef WITH_WEBENGINE
|
||||||
#include <QtWebEngineCore>
|
#include <QtWebEngineCore>
|
||||||
#include <QtWebEngineQuick>
|
#include <QtWebEngineQuick>
|
||||||
|
#endif
|
||||||
#if defined(HAS_VULKAN) && !defined(Q_OS_LINUX)
|
#if defined(HAS_VULKAN) && !defined(Q_OS_LINUX)
|
||||||
#include <QVulkanInstance>
|
#include <QVulkanInstance>
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,9 +59,11 @@ parseInputArgument(int& argc, char* argv[], QList<char*> argsToParse)
|
||||||
return newArgv;
|
return newArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_WEBENGINE
|
||||||
// Qt WebEngine Chromium Flags
|
// Qt WebEngine Chromium Flags
|
||||||
static char disableWebSecurity[] {"--disable-web-security"};
|
static char disableWebSecurity[] {"--disable-web-security"};
|
||||||
static char singleProcess[] {"--single-process"};
|
static char singleProcess[] {"--single-process"};
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
main(int argc, char* argv[])
|
||||||
|
@ -88,8 +93,10 @@ main(int argc, char* argv[])
|
||||||
*/
|
*/
|
||||||
unsetenv("QT_STYLE_OVERRIDE");
|
unsetenv("QT_STYLE_OVERRIDE");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_WEBENGINE
|
||||||
qtWebEngineChromiumFlags << disableWebSecurity;
|
qtWebEngineChromiumFlags << disableWebSecurity;
|
||||||
qtWebEngineChromiumFlags << singleProcess;
|
qtWebEngineChromiumFlags << singleProcess;
|
||||||
|
#endif
|
||||||
|
|
||||||
QApplication::setApplicationName("Jami");
|
QApplication::setApplicationName("Jami");
|
||||||
QApplication::setOrganizationDomain("jami.net");
|
QApplication::setOrganizationDomain("jami.net");
|
||||||
|
|
|
@ -193,6 +193,11 @@ MainApplication::init()
|
||||||
auto startMinimizedSetting = settingsManager_->getValue(Settings::Key::StartMinimized).toBool();
|
auto startMinimizedSetting = settingsManager_->getValue(Settings::Key::StartMinimized).toBool();
|
||||||
// The presence of start URI should override the startMinimized setting for this instance.
|
// The presence of start URI should override the startMinimized setting for this instance.
|
||||||
set_startMinimized(startMinimizedSetting && runOptions_[Option::StartUri].isNull());
|
set_startMinimized(startMinimizedSetting && runOptions_[Option::StartUri].isNull());
|
||||||
|
#ifdef WITH_WEBENGINE
|
||||||
|
engine_.get()->rootContext()->setContextProperty("WITH_WEBENGINE", QVariant(true));
|
||||||
|
#else
|
||||||
|
engine_.get()->rootContext()->setContextProperty("WITH_WEBENGINE", QVariant(false));
|
||||||
|
#endif
|
||||||
|
|
||||||
initQmlLayer();
|
initQmlLayer();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import net.jami.Constants 1.1
|
||||||
import net.jami.Adapters 1.1
|
import net.jami.Adapters 1.1
|
||||||
|
|
||||||
import "../../commoncomponents"
|
import "../../commoncomponents"
|
||||||
import "../../commoncomponents/emojipicker"
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
@ -90,10 +89,19 @@ Rectangle {
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiPicker {
|
Loader {
|
||||||
id: emojiPicker
|
id: empjiLoader
|
||||||
|
source: WITH_WEBENGINE ? "qrc:/src/commoncomponents/emojipicker/EmojiPicker.qml" : "qrc:/src/nowebengine/EmojiPicker.qml"
|
||||||
|
|
||||||
onEmojiIsPicked: messageBar.textAreaObj.insertText(content)
|
function openEmojiPicker() {
|
||||||
|
item.openEmojiPicker()
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: empjiLoader.item
|
||||||
|
function onEmojiIsPicked(content) {
|
||||||
|
messageBar.textAreaObj.insertText(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JamiFileDialog {
|
JamiFileDialog {
|
||||||
|
@ -126,20 +134,20 @@ Rectangle {
|
||||||
onEmojiButtonClicked: {
|
onEmojiButtonClicked: {
|
||||||
JamiQmlUtils.updateMessageBarButtonsPoints()
|
JamiQmlUtils.updateMessageBarButtonsPoints()
|
||||||
|
|
||||||
emojiPicker.parent = JamiQmlUtils.mainViewRectObj
|
empjiLoader.parent = JamiQmlUtils.mainViewRectObj
|
||||||
|
|
||||||
emojiPicker.x = Qt.binding(function() {
|
empjiLoader.x = Qt.binding(function() {
|
||||||
var buttonX = JamiQmlUtils.emojiPickerButtonInMainViewPoint.x +
|
var buttonX = JamiQmlUtils.emojiPickerButtonInMainViewPoint.x +
|
||||||
JamiQmlUtils.emojiPickerButtonObj.width
|
JamiQmlUtils.emojiPickerButtonObj.width
|
||||||
return buttonX - emojiPicker.width
|
return buttonX - empjiLoader.width
|
||||||
})
|
})
|
||||||
emojiPicker.y = Qt.binding(function() {
|
empjiLoader.y = Qt.binding(function() {
|
||||||
var buttonY = JamiQmlUtils.audioRecordMessageButtonInMainViewPoint.y
|
var buttonY = JamiQmlUtils.audioRecordMessageButtonInMainViewPoint.y
|
||||||
return buttonY - emojiPicker.height - messageBar.marginSize
|
return buttonY - empjiLoader.height - messageBar.marginSize
|
||||||
- JamiTheme.chatViewHairLineSize
|
- JamiTheme.chatViewHairLineSize
|
||||||
})
|
})
|
||||||
|
|
||||||
emojiPicker.openEmojiPicker()
|
empjiLoader.openEmojiPicker()
|
||||||
}
|
}
|
||||||
onSendFileButtonClicked: jamiFileDialog.open()
|
onSendFileButtonClicked: jamiFileDialog.open()
|
||||||
onSendMessageButtonClicked: {
|
onSendMessageButtonClicked: {
|
||||||
|
|
|
@ -157,6 +157,7 @@ ColumnLayout {
|
||||||
|
|
||||||
PushButton {
|
PushButton {
|
||||||
id: emojiButton
|
id: emojiButton
|
||||||
|
visible: WITH_WEBENGINE
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.rightMargin: sendMessageButton.visible ? 0 : marginSize
|
Layout.rightMargin: sendMessageButton.visible ? 0 : marginSize
|
||||||
|
|
|
@ -61,10 +61,7 @@ MessagesAdapter::MessagesAdapter(AppSettingsManager* settingsManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(previewEngine_, &PreviewEngine::infoReady, this, &MessagesAdapter::onPreviewInfoReady);
|
connect(previewEngine_, &PreviewEngine::infoReady, this, &MessagesAdapter::onPreviewInfoReady);
|
||||||
connect(previewEngine_,
|
connect(previewEngine_, &PreviewEngine::linkified, this, &MessagesAdapter::onMessageLinkified);
|
||||||
&PreviewEngine::linkifyReady,
|
|
||||||
this,
|
|
||||||
&MessagesAdapter::onMessageLinkified);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
27
src/nowebengine/EmojiPicker.qml
Normal file
27
src/nowebengine/EmojiPicker.qml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
* Author: Kateryna Kostiuk <kateryna.kostiuk@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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
signal emojiIsPicked(string content)
|
||||||
|
function openEmojiPicker() {}
|
||||||
|
function closeEmojiPicker() {}
|
||||||
|
}
|
26
src/nowebengine/MediaPreviewBase.qml
Normal file
26
src/nowebengine/MediaPreviewBase.qml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
* Author: Kateryna Kostiuk <kateryna.kostiuk@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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property bool isVideo
|
||||||
|
property string html
|
||||||
|
}
|
44
src/nowebengine/previewengine.cpp
Normal file
44
src/nowebengine/previewengine.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
* Author: Kateryna Kostiuk <kateryna.kostiuk@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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "previewengine.h"
|
||||||
|
|
||||||
|
struct PreviewEngine::Impl : public QObject
|
||||||
|
{
|
||||||
|
Impl(PreviewEngine&)
|
||||||
|
: QObject(nullptr)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
PreviewEngine::PreviewEngine(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, pimpl_(std::make_unique<Impl>(*this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PreviewEngine::~PreviewEngine() {}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreviewEngine::parseMessage(const QString&, const QString&, bool)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreviewEngine::log(const QString&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
#include "moc_previewengine.cpp"
|
||||||
|
#include "previewengine.moc"
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
|
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
|
||||||
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
||||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||||
|
@ -23,65 +23,78 @@
|
||||||
#include <QWebEngineProfile>
|
#include <QWebEngineProfile>
|
||||||
#include <QWebEngineSettings>
|
#include <QWebEngineSettings>
|
||||||
|
|
||||||
PreviewEngine::PreviewEngine(QObject* parent)
|
#include <QtWebChannel>
|
||||||
: QWebEnginePage(parent)
|
#include <QWebEnginePage>
|
||||||
, pimpl_(new PreviewEnginePrivate(this))
|
|
||||||
|
struct PreviewEngine::Impl : public QWebEnginePage
|
||||||
{
|
{
|
||||||
QWebEngineProfile* profile = QWebEngineProfile::defaultProfile();
|
public:
|
||||||
|
PreviewEngine& parent_;
|
||||||
|
QWebChannel* channel_;
|
||||||
|
|
||||||
QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
|
Impl(PreviewEngine& parent)
|
||||||
dataDir.cdUp();
|
: QWebEnginePage((QObject*) nullptr)
|
||||||
auto cachePath = dataDir.absolutePath() + "/jami";
|
, parent_(parent)
|
||||||
profile->setCachePath(cachePath);
|
{
|
||||||
profile->setPersistentStoragePath(cachePath);
|
QWebEngineProfile* profile = QWebEngineProfile::defaultProfile();
|
||||||
profile->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
|
|
||||||
profile->setHttpCacheType(QWebEngineProfile::NoCache);
|
|
||||||
|
|
||||||
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
|
QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
|
||||||
settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, false);
|
dataDir.cdUp();
|
||||||
settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
|
auto cachePath = dataDir.absolutePath() + "/jami";
|
||||||
settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false);
|
profile->setCachePath(cachePath);
|
||||||
settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, false);
|
profile->setPersistentStoragePath(cachePath);
|
||||||
settings()->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, false);
|
profile->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
|
||||||
settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
|
profile->setHttpCacheType(QWebEngineProfile::NoCache);
|
||||||
settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, true);
|
|
||||||
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
|
|
||||||
settings()->setAttribute(QWebEngineSettings::XSSAuditingEnabled, false);
|
|
||||||
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
|
|
||||||
|
|
||||||
channel_ = new QWebChannel(this);
|
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
|
||||||
channel_->registerObject(QStringLiteral("jsbridge"), pimpl_);
|
settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, true);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::XSSAuditingEnabled, false);
|
||||||
|
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
|
||||||
|
|
||||||
setWebChannel(channel_);
|
channel_ = new QWebChannel(this);
|
||||||
runJavaScript(Utils::QByteArrayFromFile(":/linkify.js"), QWebEngineScript::MainWorld);
|
channel_->registerObject(QStringLiteral("jsbridge"), &parent_);
|
||||||
runJavaScript(Utils::QByteArrayFromFile(":/linkify-string.js"), QWebEngineScript::MainWorld);
|
|
||||||
runJavaScript(Utils::QByteArrayFromFile(":/qwebchannel.js"), QWebEngineScript::MainWorld);
|
setWebChannel(channel_);
|
||||||
runJavaScript(Utils::QByteArrayFromFile(":/previewInfo.js"), QWebEngineScript::MainWorld);
|
runJavaScript(Utils::QByteArrayFromFile(":/linkify.js"), QWebEngineScript::MainWorld);
|
||||||
runJavaScript(Utils::QByteArrayFromFile(":/misc/previewInterop.js"),
|
runJavaScript(Utils::QByteArrayFromFile(":/linkify-string.js"), QWebEngineScript::MainWorld);
|
||||||
QWebEngineScript::MainWorld);
|
runJavaScript(Utils::QByteArrayFromFile(":/qwebchannel.js"), QWebEngineScript::MainWorld);
|
||||||
}
|
runJavaScript(Utils::QByteArrayFromFile(":/previewInfo.js"), QWebEngineScript::MainWorld);
|
||||||
|
runJavaScript(Utils::QByteArrayFromFile(":/misc/previewInterop.js"),
|
||||||
|
QWebEngineScript::MainWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseMessage(const QString& messageId, const QString& msg, bool showPreview)
|
||||||
|
{
|
||||||
|
runJavaScript(QString("parseMessage(`%1`, `%2`, %3)")
|
||||||
|
.arg(messageId, msg, showPreview ? "true" : "false"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PreviewEngine::PreviewEngine(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, pimpl_(std::make_unique<Impl>(*this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PreviewEngine::~PreviewEngine() {}
|
||||||
|
|
||||||
void
|
void
|
||||||
PreviewEngine::parseMessage(const QString& messageId, const QString& msg, bool showPreview)
|
PreviewEngine::parseMessage(const QString& messageId, const QString& msg, bool showPreview)
|
||||||
{
|
{
|
||||||
runJavaScript(
|
pimpl_->parseMessage(messageId, msg, showPreview);
|
||||||
QString("parseMessage(`%1`, `%2`, %3)").arg(messageId, msg, showPreview ? "true" : "false"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PreviewEnginePrivate::log(const QString& str)
|
PreviewEngine::log(const QString& str)
|
||||||
{
|
{
|
||||||
qDebug() << str;
|
qDebug() << str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
#include "moc_previewengine.cpp"
|
||||||
PreviewEnginePrivate::infoReady(const QString& messageId, const QVariantMap& info)
|
#include "previewengine.moc"
|
||||||
{
|
|
||||||
Q_EMIT parent_->infoReady(messageId, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PreviewEnginePrivate::linkifyReady(const QString& messageId, const QString& linkified)
|
|
||||||
{
|
|
||||||
Q_EMIT parent_->linkifyReady(messageId, linkified);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
|
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
|
||||||
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
||||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||||
|
@ -20,42 +20,25 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include <QtWebChannel>
|
class PreviewEngine : public QObject
|
||||||
#include <QWebEnginePage>
|
|
||||||
|
|
||||||
class PreviewEngine;
|
|
||||||
|
|
||||||
class PreviewEnginePrivate : public QObject
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(PreviewEngine)
|
||||||
public:
|
public:
|
||||||
explicit PreviewEnginePrivate(PreviewEngine* parent)
|
PreviewEngine(QObject* parent = nullptr);
|
||||||
: parent_(parent)
|
~PreviewEngine();
|
||||||
{}
|
|
||||||
|
|
||||||
Q_INVOKABLE void infoReady(const QString& messageId, const QVariantMap& info);
|
|
||||||
Q_INVOKABLE void linkifyReady(const QString& messageId, const QString& linkified);
|
|
||||||
Q_INVOKABLE void log(const QString& str);
|
|
||||||
|
|
||||||
private:
|
|
||||||
PreviewEngine* parent_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PreviewEngine : public QWebEnginePage
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PreviewEngine(QObject* parent = nullptr);
|
|
||||||
~PreviewEngine() = default;
|
|
||||||
|
|
||||||
void parseMessage(const QString& messageId, const QString& msg, bool showPreview);
|
void parseMessage(const QString& messageId, const QString& msg, bool showPreview);
|
||||||
|
|
||||||
|
Q_INVOKABLE void log(const QString& str);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void infoReady(const QString& messageId, const QVariantMap& info);
|
Q_INVOKABLE void infoReady(const QString& messageId, const QVariantMap& info);
|
||||||
void linkifyReady(const QString& messageId, const QString& linkified);
|
Q_INVOKABLE void linkified(const QString& messageId, const QString& linkified);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWebChannel* channel_;
|
struct Impl;
|
||||||
PreviewEnginePrivate* pimpl_;
|
std::unique_ptr<Impl> pimpl_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,6 +62,7 @@ ColumnLayout {
|
||||||
|
|
||||||
ToggleSwitch {
|
ToggleSwitch {
|
||||||
id: displayImagesCheckbox
|
id: displayImagesCheckbox
|
||||||
|
visible: WITH_WEBENGINE
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||||
|
|
Loading…
Add table
Reference in a new issue