Compare commits

...

67 Commits

Author SHA1 Message Date
ec60458dbe misc: fix sidepanel and donation date
Change-Id: I98294ccfb1ae68b45260f3e66bdce3e179ee55a9
2023-10-26 15:57:11 -04:00
8a9aea2f28 Patch menu: position of the popup
Change-Id: I9a07dccc7bb4a17c0ce3046906f922d5ace35f8a
2023-10-26 11:15:47 -04:00
ae86464658 Chat setting view: add darktheme color
GitLab: #1369

Change-Id: I863d13dc924e3e0d12dd92f9fb2b8d48bad051f4
2023-10-25 13:10:44 -04:00
5f0163df05 Menu: add some details on menu
GitLab: #1388
Change-Id: Ia38dbd15b176afcaf7c03b6612695ee5b6e89723
2023-10-25 11:34:53 -04:00
493addcbd8 Menu: refactor menu
GitLab: #1388

Change-Id: Ia168dce60ffdafa1ab4d08905c46f47f98625916
2023-10-24 15:20:03 -04:00
f144b27db8 misc: bump daemon
Change-Id: I3d6a777d5b482f0810144780c333a292ce0e3f5c
2023-10-24 14:52:38 -04:00
861c42e3d5 fix: don't remove the daemon cache dir
Change-Id: Icde3c4f5dbb54c2ae93712434f5d08def4e3c3bb
2023-10-24 13:20:29 -04:00
873c4c72b9 i18n: automatic bump
Change-Id: Id0905136d6091270819b9ae8b37d3e9be5d9c1dc
2023-10-23 16:47:01 -04:00
3e012c32d5 Welcome view: set default title to false and resize logo
GitLab: #1334

Change-Id: I71930584b3f5e0925ba8f5f42fff669ff9237dd1
2023-10-23 14:41:23 -04:00
6bff3c54f1 TroubleshootingSetting: Connection monitoring
Change-Id: Idf922df701cdf2efc2d167362dca021897d8e2e5
2023-10-23 13:39:13 -04:00
e55eaa5d8e packaging: add fedora 39, ubuntu 23.10
Change-Id: I2da6a821b25c3a5ae26ba8f59f3dc8b6656751b5
2023-10-20 09:16:08 -04:00
1a17735d55 misc: bump daemon
Change-Id: I20cbebf0bea67385b08fa879884ce2a7f8634d52
2023-10-19 15:52:03 -04:00
4e5f153230 Message button: set circled false
Change-Id: I58aee3397e46025a79321e2a54211f72d299077e
2023-10-19 15:23:12 -04:00
15351a5aae splitview: hide handles when in single-pane mode
Prevents breaking the UI.

Gitlab: #1370
Change-Id: I6bad222c2a05dc66402bc8f86e17f9a6d4d99c99
2023-10-18 13:01:58 -04:00
e89aa95673 Donation: show the tipbox only after the 1st November 2023
Change-Id: If2bb725a0be137a55a29cd7592726c4f2c718c8a
2023-10-17 14:29:49 -04:00
3609dae584 pushbutton: circled default to true
Change-Id: I85967917eae6d69f534aebeaae998454a9a6a4c0
2023-10-17 15:01:45 -03:00
8b21b0fda9 Share popup: fix font size
Change-Id: Ied676c0bcea675735274362ecc35de504c4c7fa9
2023-10-17 10:02:33 -04:00
811a93cc27 Chat settings: refactor chat settings
GitLab: #1369
Change-Id: I1bd9dfab7526a9cd0d84205817ab4eae951dba90
2023-10-17 08:31:05 -04:00
baeb90bced i18n: automatic bump
Change-Id: I5f6e1f01940f43a6e4d8ffd8c497a848ed981971
2023-10-16 16:42:38 -04:00
439fea530d PushButton: Remove transparent color who break the animation
PopUp: Add shadow on the SharePopup

Change-Id: I3829fb651116e2ce8da05e71ecb61a67356748c7
2023-10-16 12:57:16 -04:00
55415d6062 Donation campaign: add toggleswitch setting
GitLab: #1334
Change-Id: Ic0e2a4b08db7228e4a4bdab665f53adfa581e16c
2023-10-13 09:23:36 -04:00
9d3b5cd0c5 Donation campaign: add donate tipbox
GitLab: #1334
Change-Id: Ie32b6278fb28381524936baabf09ee3cbba04eb6
2023-10-11 11:25:05 -04:00
4e549d123e misc: use the cache dir instead of the data dir as the cache dir
Gitlab: #1378
Change-Id: I0249a87fba240eb65165fc79bdbc0ffb55f00af8
2023-10-11 09:51:54 -04:00
77193b26d9 eleutheria: update welcome page for release
GitLab: #1334
Change-Id: Ibe19091076f3b041517f32684a248700c0fce7ff
2023-10-10 15:13:02 -04:00
afb514ee02 i18n: automatic bump
Change-Id: I2a892bc8ee46e169865397d771d3e9d233468911
2023-10-09 16:43:02 -04:00
f1ccd5d05d downloader: use native separators when building target file path
Also reverts waiting on the msiexec process + error checking.

Change-Id: Icfd8c349087d1b9f84c95d855b68b7ef2e45b3ab
2023-10-05 19:12:07 -04:00
6a0963d37b misc: bump daemon
Change-Id: Ia78ee9a1946d79b68b0761642b37f90a77182a68
2023-10-05 17:13:29 -04:00
6fc30b51d6 windows: updates: make UI represent underlying update states
This commit fixes several issues:
- the update confirmation dialog getting stuck in the open state
- secondary attempts to download an update possibly causing a crash
- poor error information presented in the case of missing content
- unhandled errors during MSI package installation

Gitlab: #1367
Change-Id: Ia8855b8268ab13b8e1cbbb15de75d41f593f947a
2023-10-03 17:49:04 -04:00
2719f303d9 misc: bump daemon
Change-Id: I8a3fe51e2d868f25c482b1a57bea82bc976a457a
2023-10-03 16:30:22 -04:00
100756b02d viewmanager: allow creating more than 1 instance of a view
Previously, managed views were always stored in a dictionary using non-unique keys. This commit adds a method to the ViewManager component allowing for automatic unique key generation if the base key (QML component path) is the same. This is used for dialogs because we need to possibly open nested modal dialogs.

Gitlab: #1367
Change-Id: I94e0ef0e0ae79689445be0409dd902dc74554e43
2023-10-03 15:38:39 -04:00
b963a0bdf2 Avoid infinite loops in MainApplication::cleanup
Change-Id: I910ab554c463a3d91c48c297c6c1ed48202283f9
2023-10-03 15:18:47 -04:00
d765fc9297 PluginStoreEndPoint: add possibility to change the plugin store end point
Gitlab: #1341
Change-Id: Ib4516c6cf2361a4976230a6b056a4c072932a92b
2023-10-03 13:55:05 -04:00
f8f1301fa0 i18n: automatic bump
Change-Id: I35a6a56c9e7ddd8f83ef0a388ed7b7ec6d6f72d7
2023-10-02 16:42:38 -04:00
b9d24298f7 Donation campaign: add banner in smartlist
GitLab: #1334
Change-Id: I53b23eabab47389b9bea50f54afac28d41741b0b
2023-09-29 20:04:04 -04:00
6b9ce14ca9 messagerbar: add continue editing tooltip
Change-Id: Ifa69df02610e0d104b6a0bf338ded3128e2be9b7
GitLab: #1359
2023-09-29 05:06:41 -04:00
f88b8584af deploy-packages: add alma
Change-Id: I5ff774d6e2eceb3ce99d16eae34249ee451f9199
2023-09-29 02:18:36 -04:00
ad35d108f2 link-device: apply new design and add QR code
GitLab: #1253
Change-Id: Ib47a081e4e5d714e98fb397732ff9232b62afc36
2023-09-28 16:59:20 -04:00
63c3d0bf2e Build: build without dbus if enable_libwrap is not specified
Change-Id: I8819b193b83f7ee051d78d30990db40e3f295354
2023-09-28 11:37:54 -04:00
6f8f96edfd Correct some bug MessageBar
Change-Id: I198763539ba1b093ef9dfbc6f429ba15dcf93285
2023-09-26 17:03:27 -04:00
1bd7d75d29 Fingerprint : prevent overflow when zooming
GitLab: #1347
Change-Id: I2b1862b1df7b2bcc7c173a04b50c006d861241d2
2023-09-26 12:01:03 -04:00
ad29993e17 AboutJami button : text scale with text size
GitLab: #1348
Change-Id: I442b4ca074113ca4460757780b1bcc0b1675a35e
2023-09-26 11:15:10 -04:00
70ce0c091e i18n: automatic bump
Change-Id: I9b9ac457d4c71a343af793ad15bd6ce8c2ed4089
2023-09-25 16:43:03 -04:00
ea5b2d6589 misc: bump daemon
Change-Id: I9d10579e5bb231f4b457a0fd9f3c36c8bc491dbc
2023-09-22 15:04:16 -04:00
eaababc817 callactionbar: fix submenus layouts
Change-Id: I1d100b48db6ad95bf5e09642e9c12aad8ccf110a
2023-09-21 08:45:09 -04:00
aa96b723bc misc: bump daemon
Change-Id: I8ec5348b0a37c06e81ad3fc46c11822556391694
2023-09-20 21:16:46 -04:00
1616261bef misc: update plugin-store after plugin uninstall
Change-Id: Ibbb428e17f362f3645a530ad55fbd87d6719f98d
2023-09-20 14:58:32 -04:00
926ab72334 markdown: fix keyboard shortcuts
Change-Id: Ic02ab2df7a4a3870dbbe2f0e23160f13281ba2ac
GitLab: #1321
2023-09-20 14:54:54 -04:00
a6d16ba1f8 misc: pass HideSelf to true by default
Change-Id: I507ec00f9d94ae9cec5f63ca948bca1f9cdd82b3
2023-09-20 13:13:23 -04:00
b0c205159e misc: bump daemon
Change-Id: I424250b351a0947fe37c4baebfc27405ff48dad8
2023-09-20 09:20:59 -04:00
0c440660c4 i18n: automatic bump
Change-Id: I65efe898569dff45b9e6341db6e6b9332e60d890
2023-09-19 11:40:04 -04:00
c8cc61520d misc: update version name to Eleutheria
Change-Id: I6679ffec816636d6bb8bfded88b86f23c11f3b03
2023-09-19 11:01:13 -04:00
ab25276e27 Dialog popup: BaseModalDialog redone, every popup based on it checked
GitLab: #1326
Change-Id: Ia72a9f4d2daa60261054e050ab89de18a139ecd2
2023-09-19 10:33:20 -04:00
7b41c6faff UserProfile: display name must be readOnly
Change-Id: I3cd106af5ad7a141d884b948448e25053ab0832b
GitLab: #1349
2023-09-18 14:35:54 -04:00
7a84518f2c misc: cleanup, remove cacheAvatars
Now there is only one client, this doesn't need to be configured

Change-Id: Iba1265fbdb8ab18bfb44fc7c2c70ebfe6000ee2c
GitLab: #1305
2023-09-18 10:25:12 -04:00
1a12cb3b8c misc: replace Swarm Created message in 1:1
Change-Id: I71388da217d4912a4f89c36e8a539cdc65f40097
GitLab: #1342
2023-09-18 10:23:13 -04:00
75a154f4fe plugins: fix background of installed plugin
Change-Id: I0b890270dc10ddb3d77d10f07252d5da7266ba7f
2023-09-18 10:10:25 -04:00
b95abbc891 misc: fix shortcut for tile screenshot
Change-Id: Ic2e18dc9aef3e01d7d8f1f935b90fe73b527127b
GitLab: #1344
2023-09-15 12:34:57 -04:00
bc51b74692 misc: add search tooltip
Change-Id: I55e29557eca3b32c714a313cd18aff66a870fd0f
GitLab: #1343
2023-09-15 12:33:03 -04:00
899ff6120c misc: move GenericErrorsRow in MainApplicationWindow
Change-Id: I09fea85e9fa603481bd2cfe81b15a4d94dcc3ebd
Gitlab: #1135
2023-09-15 12:29:27 -04:00
b77012baae misc: bump daemon
Change-Id: Ibf34d81f97f5d601e7357096279e07833a940a33
2023-09-14 13:35:43 -04:00
bc34abc8f4 misc: add tooltip for show preview button
Change-Id: I8b292bdb157c0fed6f873263dc97c4f7f2fa1f02
GitLab: #1337
2023-09-14 13:35:02 -04:00
69b59ad2dd misc: bump daemon
Change-Id: Ie3c7b8665c87e0b7e1b051816f72ec223e559c92
2023-09-14 10:44:33 -04:00
1f2401bc7e PluginDescription: handle language to send request to the plugin store
Change-Id: Id96578cf238246ebe69a6f9b77b0ed1d1f465f38
2023-09-14 10:44:19 -04:00
06b0f1d39c plugins: use pluginId for getIconUrl
Change-Id: I560429fa6604a595c945ffca73fed3c43b152e40
2023-09-14 10:18:01 -04:00
d5b36e7a6d Icon local Path: change identifier plugin name to plugin id
Change-Id: I5091b6f4d5a8d42c73b574d4f889d5795b7ec0db
2023-09-13 15:22:25 -04:00
4e2ae6cde0 misc: bump daemon
Change-Id: I5b014d9c1bf5541fef6dc0af0eda57357c149e9c
2023-09-13 15:28:34 -03:00
0895a9f183 TextEditor: patch height binding after tap big message
Change-Id: I91111ff3b4d54dda85e649e62eef91ad9b935bb8
2023-09-13 11:06:22 -04:00
239 changed files with 60762 additions and 41009 deletions

View File

@ -244,7 +244,8 @@ set(COMMON_SOURCES
${APP_SRC_DIR}/messageparser.cpp
${APP_SRC_DIR}/previewengine.cpp
${APP_SRC_DIR}/imagedownloader.cpp
${APP_SRC_DIR}/pluginversionmanager.cpp)
${APP_SRC_DIR}/pluginversionmanager.cpp
${APP_SRC_DIR}/connectioninfolistmodel.cpp)
set(COMMON_HEADERS
${APP_SRC_DIR}/avatarimageprovider.h
@ -310,8 +311,8 @@ set(COMMON_HEADERS
${APP_SRC_DIR}/messageparser.h
${APP_SRC_DIR}/htmlparser.h
${APP_SRC_DIR}/imagedownloader.h
${APP_SRC_DIR}/pluginversionmanager.h)
${APP_SRC_DIR}/pluginversionmanager.h
${APP_SRC_DIR}/connectioninfolistmodel.h)
# For libavutil/avframe.
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")

2
daemon

Submodule daemon updated: 459e58a6d2...24f8c52acf

View File

@ -49,7 +49,7 @@ QT_MAJOR := 6
QT_MINOR := 4
QT_PATCH := 3
QT_TARBALL_CHECKSUM := 29a7eebdbba0ea57978dea6083709c93593a60f0f3133a3de08b9571ee8eaab4
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-2
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-3
DEBIAN_QT_DSC_FILENAME := libqt-jami_$(DEBIAN_QT_VERSION).dsc
QT_JAMI_PREFIX := /usr/lib/libqt-jami
@ -167,8 +167,10 @@ DISTRIBUTIONS := \
ubuntu_20.04 \
ubuntu_22.04 \
ubuntu_23.04 \
ubuntu_23.10 \
fedora_37 \
fedora_38 \
fedora_39 \
opensuse-leap_15.4 \
snap

View File

@ -0,0 +1,105 @@
FROM fedora:39
RUN dnf clean all
RUN dnf update -y
RUN dnf install -y dnf-command\(builddep\) rpmdevtools && \
dnf install -y mock
RUN dnf groupinstall -y "X Software Development"
RUN dnf install -y \
git \
rpm-build \
tar \
make \
autoconf \
automake \
nasm \
speexdsp-devel \
pulseaudio-libs-devel \
libcanberra-devel \
libcurl-devel \
libtool \
mesa-libgbm-devel \
mesa-dri-drivers \
dbus-devel \
expat-devel \
pcre-devel \
yaml-cpp-devel \
libXext-devel \
libXfixes-devel \
yasm \
speex-devel \
gsm-devel \
chrpath \
check \
astyle \
uuid-c++-devel \
gettext-devel \
gcc-c++ \
which \
alsa-lib-devel \
systemd-devel \
libuuid-devel \
uuid-devel \
gnutls-devel \
nettle-devel \
opus-devel \
patch \
jsoncpp-devel \
libnatpmp-devel \
webkitgtk4-devel \
cryptopp-devel \
libva-devel \
libvdpau-devel \
msgpack-devel \
NetworkManager-libnm-devel \
openssl-devel \
clutter-devel \
clutter-gtk-devel \
libappindicator-gtk3-devel \
libnotify-devel \
libupnp-devel \
qrencode-devel \
libargon2-devel \
libsndfile-devel \
libdrm \
gperf \
bison \
clang \
clang-devel \
llvm-devel \
nodejs \
flex \
gstreamer1 gstreamer1-devel \
gstreamer1-plugins-base-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
nss-devel \
libxcb* \
libxkb* \
libX11-devel \
vulkan-devel \
libXrender-devel \
xcb-util-* \
xz \
xkeyboard-config \
libnotify \
wget \
libstdc++-static \
sqlite-devel \
perl-generators \
perl-English \
libxshmfence-devel \
ninja-build \
clang \
cmake \
fmt-devel \
python3-html5lib \
cups-devel \
python-six
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
CMD ["/opt/build-package-rpm.sh"]

View File

@ -0,0 +1,22 @@
FROM ubuntu:23.10
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get clean
RUN apt-get update && \
apt-get install -y -o Acquire::Retries=10 \
devscripts \
equivs \
python-is-python3 \
wget
ADD extras/packaging/gnu-linux/scripts/prebuild-package-debian.sh /opt/prebuild-package-debian.sh
COPY extras/packaging/gnu-linux/rules/debian-qt/control /tmp/builddeps/debian/control
RUN /opt/prebuild-package-debian.sh qt-deps
COPY extras/packaging/gnu-linux/rules/debian/control /tmp/builddeps/debian/control
RUN /opt/prebuild-package-debian.sh jami-deps
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
CMD ["/opt/build-package-debian.sh"]

View File

@ -0,0 +1,81 @@
From ecae5d93b0a89e2b8c16a2227b2d176f58579d04 Mon Sep 17 00:00:00 2001
From: Rémi Denis-Courmont <remi@remlab.net>
Date: Sun, 16 Jul 2023 18:18:02 +0300
Subject: [PATCH] Fix ffmpeg assembly with newer binutil
avcodec/x86/mathops: clip constants used with shift instructions within inline assembly
Fixes assembling with binutil as >= 2.41
FFmpeg commit effadce6c756247ea8bae32dc13bb3e6f464f0eb.
Deals with: "Error: operand type mismatch for `shr'"
Fixes: QTBUG-116649
Change-Id: I094e8c23fed4a61fba3f1e3a9c73c016d129d830
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/495990
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 29354c7c7def7bdc66bcd25d401677fd9421f657)
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/509219
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
index 6298f5e..ca7e2df 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
+++ b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
@@ -35,12 +35,20 @@
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
{
int rt, dummy;
+ if (__builtin_constant_p(shift))
__asm__ (
"imull %3 \n\t"
"shrdl %4, %%edx, %%eax \n\t"
:"=a"(rt), "=d"(dummy)
- :"a"(a), "rm"(b), "ci"((uint8_t)shift)
+ :"a"(a), "rm"(b), "i"(shift & 0x1F)
);
+ else
+ __asm__ (
+ "imull %3 \n\t"
+ "shrdl %4, %%edx, %%eax \n\t"
+ :"=a"(rt), "=d"(dummy)
+ :"a"(a), "rm"(b), "c"((uint8_t)shift)
+ );
return rt;
}
@@ -113,19 +121,31 @@
// avoid +32 for shift optimization (gcc should do that ...)
#define NEG_SSR32 NEG_SSR32
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
+ if (__builtin_constant_p(s))
__asm__ ("sarl %1, %0\n\t"
: "+r" (a)
- : "ic" ((uint8_t)(-s))
+ : "i" (-s & 0x1F)
);
+ else
+ __asm__ ("sarl %1, %0\n\t"
+ : "+r" (a)
+ : "c" ((uint8_t)(-s))
+ );
return a;
}
#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
+ if (__builtin_constant_p(s))
__asm__ ("shrl %1, %0\n\t"
: "+r" (a)
- : "ic" ((uint8_t)(-s))
+ : "i" (-s & 0x1F)
);
+ else
+ __asm__ ("shrl %1, %0\n\t"
+ : "+r" (a)
+ : "c" ((uint8_t)(-s))
+ );
return a;
}

View File

@ -0,0 +1,16 @@
qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
index 3488120..120e47a 100644
--- a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
+++ b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
}
catch (const DeadlyImportError& e)
{
- if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
+ if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
}
throw;

View File

@ -0,0 +1,433 @@
qtbase/src/corelib/debug_script.py | 2 +-
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py | 2 +-
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py | 2 +-
qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py | 2 +-
.../3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py | 2 +-
qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py | 2 +-
qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py | 2 +-
31 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/qtbase/src/corelib/debug_script.py b/qtbase/src/corelib/debug_script.py
index f6207c6104..663c8e0ac1 100644
--- a/qtbase/src/corelib/debug_script.py
+++ b/qtbase/src/corelib/debug_script.py
@@ -3,7 +3,7 @@
import os
import sys
-import imp
+import importlib
from distutils.version import LooseVersion
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
index 681039d34b..a1fe56fa05 100644
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
@@ -16,7 +16,7 @@ import subprocess
import sys
import tempfile
import time
-import imp
+import importlib
# from TestCasePackagerConfig import *
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
index 92d4e6139b..7a18e12ced 100644
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
@@ -7,7 +7,7 @@ import unittest
import os
import yaml
-import imp
+import importlib
# add parent dir to search path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
index c7412927c8..ad2caff318 100755
--- a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
+++ b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
@@ -5,7 +5,7 @@
import os
import sys
-import imp
+import importlib
import tempfile
import unittest
import PRESUBMIT
diff --git a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
index 5daee773ba..2d6b124162 100755
--- a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
+++ b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
@@ -9,7 +9,7 @@
"""
from __future__ import print_function
import abc
-import imp
+import importlib
import optparse
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
index bf626f5479..3fae129aaa 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
@@ -3,7 +3,7 @@
# found in the LICENSE file.
import errno
-import imp
+import importlib
import os.path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
index ff5753a291..04fc34f742 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import shutil
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
index 32c884a8c0..e761faa54c 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
index 95a916db08..4331e2fbfa 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
index 62798631db..28e9dbf705 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
index cba249b0f3..5a4051827a 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
index 4a2fefc712..11a9879cb7 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
index cc17ae0253..bcc944f06b 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
index bd72830e54..f2fdc9ae28 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
index 1feb303a48..8428de61bb 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
@@ -6,7 +6,7 @@
angle_presubmit_utils_unittest.py: Top-level unittest script for ANGLE presubmit checks.
"""
-import imp
+import importlib
import os
import unittest
from angle_presubmit_utils import *
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
index ed4f38c67b..cac734cefa 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
@@ -7,7 +7,7 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
-import imp
+import importlib
import inspect
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
index 0244c9787e..f535afe99c 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
@@ -32,7 +32,7 @@ if PY3:
memoryview_type = memoryview
struct_bool_decl = "?"
else:
- import imp
+ import importlib
string_types = (unicode,)
if PY26 or PY27:
binary_types = (str,bytearray)
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
index 8430390eea..29212205bc 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
@@ -732,7 +732,7 @@ class Environment(object):
)
py_compile = False
else:
- import imp
+ import importlib
import marshal
py_header = imp.get_magic() + u"\xff\xff\xff\xff".encode("iso-8859-15")
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
index 06bb8d99f5..05089dc982 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
@@ -115,7 +115,7 @@ if py3k:
return module
else:
- import imp
+ import importlib
def load_module(module_id, path):
fp = open(path, "rb")
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
index a7dc683365..68b6804c78 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for call_trees module."""
-import imp
+import importlib
from tensorflow.python.autograph.converters import call_trees
from tensorflow.python.autograph.converters import functions
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
index 81a7fde808..1370f900fd 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for converter module."""
-import imp
+import importlib
from tensorflow.python.autograph.core import converter
from tensorflow.python.autograph.core import converter_testing
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
index b93cbb627b..452ec71f5b 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
@@ -15,7 +15,7 @@
"""Base class for tests in this module."""
import contextlib
-import imp
+import importlib
import inspect
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
index 9a62d7c0d2..7ec4fa6dca 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
@@ -19,7 +19,7 @@ import collections
import contextlib
import functools
import gc
-import imp
+import importlib
import inspect
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
index 852af3efe7..6456c50446 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for conversion module."""
-import imp
+import importlib
import sys
import types
import weakref
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
index a50a64534a..ba0f31afa2 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
@@ -17,7 +17,7 @@
import abc
import collections
import functools
-import imp
+import importlib
import textwrap
import six
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
index 29f38d853a..7ca88fa371 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for templates module."""
-import imp
+import importlib
from absl.testing import parameterized
import gast
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
index e46460574b..a40fea6568 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
@@ -14,7 +14,7 @@
# =============================================================================
"""Tests for create_python_api."""
-import imp
+import importlib
import sys
from tensorflow.python.platform import test
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
index 73d1742714..ea77dd7647 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
@@ -1,5 +1,5 @@
import importlib
-import imp
+import importlib
from .browsers import product_list
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
index 6a744472b5..9175cb5d34 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
@@ -1,6 +1,6 @@
import copy
import functools
-import imp
+import importlib
import io
import os
from collections import OrderedDict, defaultdict
diff --git a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
index 6912b6f3c0..7d851f7f76 100755
--- a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
+++ b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
@@ -16,7 +16,7 @@
from __future__ import print_function
-import imp
+import importlib
import optparse
import os
import pipes
diff --git a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
index 1c2aba80af..55260d697e 100644
--- a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
+++ b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
@@ -10,7 +10,7 @@ from __future__ import print_function
import os
import re
-import imp
+import importlib
from _monkeyYaml import load as yamlLoad

View File

@ -1,2 +1,5 @@
0001-fix-gcc13.patch
0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
0003-fix-mathops.patch
0004-fix-binary-tokenizer.patch
0005-importlib.patch

View File

@ -101,6 +101,8 @@ if [ -f /etc/os-release ]; then
ENDTAG="ubuntu_22.04"
elif [ "${UBUNTU_CODENAME}" = "lunar" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.04" ]; then
ENDTAG="ubuntu_23.04"
elif [ "${UBUNTU_CODENAME}" = "mantic" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.10" ]; then
ENDTAG="ubuntu_23.10"
elif [ "${ID}" = "debian" ] && \
[ "$(command -v lsb_release)" ] && \
[ "$(lsb_release -rs)" = "testing" ]; then

View File

@ -28,6 +28,9 @@ URL: https://jami.net/
Source: jami-libqt-%{version}.tar.xz
Patch0: 0001-fix-gcc13.patch
Patch1: 0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
Patch2: 0003-fix-mathops.patch
Patch3: 0004-fix-binary-tokenizer.patch
Patch4: 0005-importlib.patch
%global gst 0.10
%if 0%{?fedora} || 0%{?rhel} > 7
@ -42,6 +45,7 @@ BuildRequires: bison
BuildRequires: gperf
BuildRequires: flex
BuildRequires: vulkan-devel
BuildRequires: python-six
%if %{defined suse_version}
BuildRequires: ffmpeg-devel
BuildRequires: ffmpeg
@ -64,6 +68,9 @@ This package contains Qt libraries for Jami.
%setup -n qt-everywhere-src-%{version}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
echo "Building Qt using %{job_count} parallel jobs"

View File

@ -0,0 +1,81 @@
From ecae5d93b0a89e2b8c16a2227b2d176f58579d04 Mon Sep 17 00:00:00 2001
From: Rémi Denis-Courmont <remi@remlab.net>
Date: Sun, 16 Jul 2023 18:18:02 +0300
Subject: [PATCH] Fix ffmpeg assembly with newer binutil
avcodec/x86/mathops: clip constants used with shift instructions within inline assembly
Fixes assembling with binutil as >= 2.41
FFmpeg commit effadce6c756247ea8bae32dc13bb3e6f464f0eb.
Deals with: "Error: operand type mismatch for `shr'"
Fixes: QTBUG-116649
Change-Id: I094e8c23fed4a61fba3f1e3a9c73c016d129d830
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/495990
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 29354c7c7def7bdc66bcd25d401677fd9421f657)
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/509219
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
index 6298f5e..ca7e2df 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
+++ b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
@@ -35,12 +35,20 @@
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
{
int rt, dummy;
+ if (__builtin_constant_p(shift))
__asm__ (
"imull %3 \n\t"
"shrdl %4, %%edx, %%eax \n\t"
:"=a"(rt), "=d"(dummy)
- :"a"(a), "rm"(b), "ci"((uint8_t)shift)
+ :"a"(a), "rm"(b), "i"(shift & 0x1F)
);
+ else
+ __asm__ (
+ "imull %3 \n\t"
+ "shrdl %4, %%edx, %%eax \n\t"
+ :"=a"(rt), "=d"(dummy)
+ :"a"(a), "rm"(b), "c"((uint8_t)shift)
+ );
return rt;
}
@@ -113,19 +121,31 @@
// avoid +32 for shift optimization (gcc should do that ...)
#define NEG_SSR32 NEG_SSR32
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
+ if (__builtin_constant_p(s))
__asm__ ("sarl %1, %0\n\t"
: "+r" (a)
- : "ic" ((uint8_t)(-s))
+ : "i" (-s & 0x1F)
);
+ else
+ __asm__ ("sarl %1, %0\n\t"
+ : "+r" (a)
+ : "c" ((uint8_t)(-s))
+ );
return a;
}
#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
+ if (__builtin_constant_p(s))
__asm__ ("shrl %1, %0\n\t"
: "+r" (a)
- : "ic" ((uint8_t)(-s))
+ : "i" (-s & 0x1F)
);
+ else
+ __asm__ ("shrl %1, %0\n\t"
+ : "+r" (a)
+ : "c" ((uint8_t)(-s))
+ );
return a;
}

View File

@ -0,0 +1,16 @@
qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
index 3488120..120e47a 100644
--- a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
+++ b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
}
catch (const DeadlyImportError& e)
{
- if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
+ if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
}
throw;

View File

@ -0,0 +1,433 @@
qtbase/src/corelib/debug_script.py | 2 +-
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py | 2 +-
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py | 2 +-
qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py | 2 +-
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py | 2 +-
.../3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py | 2 +-
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py | 2 +-
qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py | 2 +-
qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py | 2 +-
31 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/qtbase/src/corelib/debug_script.py b/qtbase/src/corelib/debug_script.py
index f6207c6104..663c8e0ac1 100644
--- a/qtbase/src/corelib/debug_script.py
+++ b/qtbase/src/corelib/debug_script.py
@@ -3,7 +3,7 @@
import os
import sys
-import imp
+import importlib
from distutils.version import LooseVersion
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
index 681039d34b..a1fe56fa05 100644
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
@@ -16,7 +16,7 @@ import subprocess
import sys
import tempfile
import time
-import imp
+import importlib
# from TestCasePackagerConfig import *
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
index 92d4e6139b..7a18e12ced 100644
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
@@ -7,7 +7,7 @@ import unittest
import os
import yaml
-import imp
+import importlib
# add parent dir to search path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
index c7412927c8..ad2caff318 100755
--- a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
+++ b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
@@ -5,7 +5,7 @@
import os
import sys
-import imp
+import importlib
import tempfile
import unittest
import PRESUBMIT
diff --git a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
index 5daee773ba..2d6b124162 100755
--- a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
+++ b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
@@ -9,7 +9,7 @@
"""
from __future__ import print_function
import abc
-import imp
+import importlib
import optparse
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
index bf626f5479..3fae129aaa 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
@@ -3,7 +3,7 @@
# found in the LICENSE file.
import errno
-import imp
+import importlib
import os.path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
index ff5753a291..04fc34f742 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import shutil
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
index 32c884a8c0..e761faa54c 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
index 95a916db08..4331e2fbfa 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
index 62798631db..28e9dbf705 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
index cba249b0f3..5a4051827a 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
index 4a2fefc712..11a9879cb7 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
index cc17ae0253..bcc944f06b 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
index bd72830e54..f2fdc9ae28 100644
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import imp
+import importlib
import os.path
import sys
import unittest
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
index 1feb303a48..8428de61bb 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
@@ -6,7 +6,7 @@
angle_presubmit_utils_unittest.py: Top-level unittest script for ANGLE presubmit checks.
"""
-import imp
+import importlib
import os
import unittest
from angle_presubmit_utils import *
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
index ed4f38c67b..cac734cefa 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
@@ -7,7 +7,7 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
-import imp
+import importlib
import inspect
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
index 0244c9787e..f535afe99c 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
@@ -32,7 +32,7 @@ if PY3:
memoryview_type = memoryview
struct_bool_decl = "?"
else:
- import imp
+ import importlib
string_types = (unicode,)
if PY26 or PY27:
binary_types = (str,bytearray)
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
index 8430390eea..29212205bc 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
@@ -732,7 +732,7 @@ class Environment(object):
)
py_compile = False
else:
- import imp
+ import importlib
import marshal
py_header = imp.get_magic() + u"\xff\xff\xff\xff".encode("iso-8859-15")
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
index 06bb8d99f5..05089dc982 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
@@ -115,7 +115,7 @@ if py3k:
return module
else:
- import imp
+ import importlib
def load_module(module_id, path):
fp = open(path, "rb")
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
index a7dc683365..68b6804c78 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for call_trees module."""
-import imp
+import importlib
from tensorflow.python.autograph.converters import call_trees
from tensorflow.python.autograph.converters import functions
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
index 81a7fde808..1370f900fd 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for converter module."""
-import imp
+import importlib
from tensorflow.python.autograph.core import converter
from tensorflow.python.autograph.core import converter_testing
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
index b93cbb627b..452ec71f5b 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
@@ -15,7 +15,7 @@
"""Base class for tests in this module."""
import contextlib
-import imp
+import importlib
import inspect
import sys
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
index 9a62d7c0d2..7ec4fa6dca 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
@@ -19,7 +19,7 @@ import collections
import contextlib
import functools
import gc
-import imp
+import importlib
import inspect
import os
import re
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
index 852af3efe7..6456c50446 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for conversion module."""
-import imp
+import importlib
import sys
import types
import weakref
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
index a50a64534a..ba0f31afa2 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
@@ -17,7 +17,7 @@
import abc
import collections
import functools
-import imp
+import importlib
import textwrap
import six
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
index 29f38d853a..7ca88fa371 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
@@ -14,7 +14,7 @@
# ==============================================================================
"""Tests for templates module."""
-import imp
+import importlib
from absl.testing import parameterized
import gast
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
index e46460574b..a40fea6568 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
@@ -14,7 +14,7 @@
# =============================================================================
"""Tests for create_python_api."""
-import imp
+import importlib
import sys
from tensorflow.python.platform import test
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
index 73d1742714..ea77dd7647 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
@@ -1,5 +1,5 @@
import importlib
-import imp
+import importlib
from .browsers import product_list
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
index 6a744472b5..9175cb5d34 100644
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
@@ -1,6 +1,6 @@
import copy
import functools
-import imp
+import importlib
import io
import os
from collections import OrderedDict, defaultdict
diff --git a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
index 6912b6f3c0..7d851f7f76 100755
--- a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
+++ b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
@@ -16,7 +16,7 @@
from __future__ import print_function
-import imp
+import importlib
import optparse
import os
import pipes
diff --git a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
index 1c2aba80af..55260d697e 100644
--- a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
+++ b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
@@ -10,7 +10,7 @@ from __future__ import print_function
import os
import re
-import imp
+import importlib
from _monkeyYaml import load as yamlLoad

View File

@ -46,7 +46,7 @@ CMAKE_PREFIX_PATH="${QT_JAMI_PREFIX}/lib/cmake:${CMAKE_PREFIX_PATH}"
QT_MAJOR=6
QT_MINOR=4
QT_PATCH=3
QT_RELEASE_PATCH=2
QT_RELEASE_PATCH=3
QT_MAJOR_MINOR=${QT_MAJOR}.${QT_MINOR}
QT_MAJOR_MINOR_PATCH=${QT_MAJOR}.${QT_MINOR}.${QT_PATCH}
@ -105,18 +105,14 @@ if [ ! -f "${RPM_PATH}" ]; then
# Cache the built Qt RPM package.
if [[ "${DISTRIBUTION:0:4}" == "rhel" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.el8.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_33" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc33.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_34" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc34.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_35" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc35.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_36" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc36.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_37" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc37.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_38" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc38.x86_64.rpm "${RPM_PATH}"
elif [[ "${DISTRIBUTION}" == "fedora_39" ]]; then
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc39.x86_64.rpm "${RPM_PATH}"
else
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-*.rpm "${RPM_PATH}"
fi

View File

@ -272,7 +272,7 @@ function package()
{
if [[ $DISTRIBUTION =~ debian|ubuntu|raspbian|guix-deb-pack ]]; then
package_deb
elif [[ $DISTRIBUTION =~ fedora|rhel|opensuse|guix-rpm-pack ]]; then
elif [[ $DISTRIBUTION =~ alma|fedora|rhel|opensuse|guix-rpm-pack ]]; then
package_rpm
elif [[ $DISTRIBUTION =~ snap ]]; then
package_snap

View File

@ -125,6 +125,8 @@ else
if [[ "$OSTYPE" != "darwin"* ]]; then
CONFIGURE_FLAGS+=" --disable-shared"
fi
else
CONFIGURE_FLAGS+="--without-dbus"
fi
BUILD_TYPE="Release"

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path id="noun-connection-5025318" d="M18,6.3c1.2,0,2.2-1,2.2-2.1C20.1,3,19.2,2,18,2c-1.2,0-2.2,1-2.2,2.1c0,0.5,0.2,1.1,0.6,1.5
l-3.3,3.8c-0.8-0.6-2-0.5-2.7,0.2L7.3,7.1c0.5-0.8,0.2-1.9-0.6-2.4C5.9,4.2,4.8,4.5,4.3,5.3C3.8,6.1,4,7.2,4.9,7.7
C5.6,8.1,6.4,8,7,7.5l3.1,2.5c-0.5,0.8-0.4,1.9,0.3,2.6l-2.9,2.9c-1.1-0.7-2.5-0.4-3.2,0.7c-0.7,1.1-0.4,2.5,0.7,3.2
c1.1,0.7,2.5,0.4,3.2-0.7c0.6-0.9,0.5-2.1-0.3-2.9l2.9-2.9c0.3,0.2,0.7,0.3,1.2,0.3c0,0,0.1,0,0.1,0l0.8,4.8
c-1.1,0.3-1.7,1.4-1.4,2.5c0.3,1.1,1.4,1.7,2.5,1.4c1.1-0.3,1.7-1.4,1.4-2.5c-0.3-0.9-1-1.4-1.9-1.4c0,0-0.1,0-0.1,0l-0.8-4.8
c0.4-0.1,0.7-0.3,0.9-0.6l3.6,2.7c-0.4,0.8-0.2,1.8,0.6,2.2c0.8,0.4,1.8,0.2,2.2-0.6c0.4-0.8,0.2-1.8-0.6-2.2
c-0.6-0.4-1.4-0.3-1.9,0.2l-3.6-2.7c0.2-0.3,0.3-0.7,0.3-1.1c0-0.5-0.2-1.1-0.6-1.5l3.3-3.8C17.1,6.2,17.5,6.3,18,6.3L18,6.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<g id="noun-waiting-3611673" transform="translate(-13.64 -30.48)">
<path id="Path_278" d="M25.9,34.5c0.5,0,0.8-0.4,0.8-0.8c0-0.5-0.4-0.8-0.8-0.8c-0.5,0-0.8,0.4-0.8,0.8c0,0.2,0.1,0.4,0.2,0.6
C25.4,34.4,25.6,34.5,25.9,34.5z"/>
<path id="Path_279" d="M32.7,36.9c0.4-0.4,0.4-1.1,0-1.5c-0.4-0.4-1.1-0.4-1.5,0c-0.4,0.4-0.4,1.1,0,1.5c0.2,0.2,0.5,0.3,0.8,0.3
C32.2,37.2,32.5,37.1,32.7,36.9z"/>
<path id="Path_280" d="M34.5,41c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.7,0,1.2-0.5,1.2-1.2c0-0.3-0.1-0.6-0.3-0.8
C35.1,41.1,34.8,41,34.5,41z"/>
<path id="Path_281" d="M31.9,47c-0.7,0-1.3,0.6-1.3,1.3c0,0.7,0.6,1.3,1.3,1.3c0.7,0,1.3-0.6,1.3-1.3c0-0.3-0.1-0.7-0.4-0.9
C32.6,47.1,32.3,47,31.9,47z"/>
<path id="Path_282" d="M25.9,49.4c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.8,0,1.4-0.6,1.4-1.4c0-0.4-0.1-0.7-0.4-1
C26.6,49.5,26.2,49.4,25.9,49.4z"/>
<path id="Path_283" d="M18.7,47.2L18.7,47.2c-0.6,0.6-0.6,1.6,0,2.2c0.6,0.6,1.6,0.6,2.2,0c0.6-0.6,0.6-1.6,0-2.2
c-0.3-0.3-0.7-0.5-1.1-0.5C19.4,46.7,19,46.9,18.7,47.2z"/>
<path id="Path_284" d="M18.9,42.2c0-0.9-0.7-1.7-1.6-1.7s-1.7,0.7-1.7,1.6c0,0.9,0.7,1.7,1.6,1.7c0.4,0,0.9-0.2,1.2-0.5
C18.8,43,18.9,42.6,18.9,42.2z"/>
<path id="Path_285" d="M21.1,34.9c-0.7-0.3-1.5-0.1-1.9,0.6c-0.3,0.7-0.1,1.5,0.6,1.9c0.7,0.3,1.5,0.1,1.9-0.6
c0.1-0.2,0.2-0.5,0.1-0.7C21.8,35.5,21.5,35.1,21.1,34.9z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="43" height="52.655" viewBox="0 0 43 52.655">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_268" data-name="Rectangle 268" width="38" height="24" transform="translate(-0.407 0.083)" fill="#fff" stroke="#707070" stroke-width="1"/>
</clipPath>
</defs>
<g id="Icon_Donate" transform="translate(-22 -189.345)">
<rect id="Rectangle_267" data-name="Rectangle 267" width="43" height="10" rx="5" transform="translate(22 232)" fill="#9eb3c3"/>
<path id="Path_459" data-name="Path 459" d="M9.674,17.083,8.562,16.07C4.609,12.486,2,10.122,2,7.221A4.18,4.18,0,0,1,6.221,3,4.6,4.6,0,0,1,9.674,4.6,4.6,4.6,0,0,1,13.128,3a4.18,4.18,0,0,1,4.221,4.221c0,2.9-2.609,5.265-6.562,8.856Z" transform="translate(22.407 199.828)" fill="#ff0045" opacity="0.3"/>
<path id="Path_460" data-name="Path 460" d="M6.953,12.088l-.718-.654C3.684,9.122,2,7.6,2,5.724A2.7,2.7,0,0,1,4.724,3,2.966,2.966,0,0,1,6.953,4.035,2.966,2.966,0,0,1,9.182,3a2.7,2.7,0,0,1,2.724,2.724c0,1.872-1.684,3.4-4.235,5.716Z" transform="translate(45.571 186.345)" fill="#ff0045" opacity="0.16"/>
<g id="Mask_Group_38" data-name="Mask Group 38" transform="translate(24.407 213.918)" clip-path="url(#clip-path)">
<path id="Path_270" data-name="Path 270" d="M12.649,22.542l-1.544-1.406C5.621,16.163,2,12.883,2,8.857A5.8,5.8,0,0,1,7.857,3a6.377,6.377,0,0,1,4.792,2.226A6.377,6.377,0,0,1,17.442,3,5.8,5.8,0,0,1,23.3,8.857c0,4.025-3.621,7.306-9.105,12.289Z" transform="translate(5.992 5.54)" fill="#ff0045"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21.5" height="20.112" viewBox="0 0 21.5 20.112">
<g id="favorite_black_24dp" transform="translate(-1.25 -2.25)">
<path id="Path_270" data-name="Path 270" d="M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5A5.447,5.447,0,0,1,7.5,3,5.988,5.988,0,0,1,12,5.09,5.988,5.988,0,0,1,16.5,3,5.447,5.447,0,0,1,22,8.5c0,3.78-3.4,6.86-8.55,11.54Z" fill="none" stroke="#03b9e9" stroke-width="1.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 KiB

View File

@ -65,6 +65,15 @@ ApplicationWindow {
}
}
header: Loader {
active: true
sourceComponent: GenericErrorsRow {
id: genericError
text: CurrentAccount.enabled ? JamiStrings.noNetworkConnectivity : JamiStrings.disabledAccount
height: visible? JamiTheme.chatViewHeaderPreferredHeight : 0
}
}
Rectangle {
id: focusOverlay
objectName: "focusOverlay"
@ -259,7 +268,7 @@ ApplicationWindow {
}
function presentUpdateInfoDialog(infoText) {
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
return viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": infoText,
"buttonTitles": [JamiStrings.optionOk],
@ -268,6 +277,36 @@ ApplicationWindow {
});
}
function presentUpdateConfirmInstallDialog(switchToBeta=false) {
return viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": switchToBeta ? JamiStrings.confirmBeta : JamiStrings.updateFound,
"buttonTitles": [JamiStrings.optionUpgrade, JamiStrings.optionLater],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": [function () {
AppVersionManager.applyUpdates(switchToBeta);
}]
});
}
function translateErrorToString(error) {
switch (error) {
case NetworkManager.DISCONNECTED:
return JamiStrings.networkDisconnected;
case NetworkManager.CONTENT_NOT_FOUND:
return JamiStrings.contentNotFoundError;
case NetworkManager.ACCESS_DENIED:
return JamiStrings.accessError;
case NetworkManager.SSL_ERROR:
return JamiStrings.updateSSLError;
case NetworkManager.CANCELED:
return JamiStrings.updateDownloadCanceled;
case NetworkManager.NETWORK_ERROR:
default:
return JamiStrings.updateNetworkError;
}
}
Connections {
target: AppVersionManager
@ -279,41 +318,22 @@ ApplicationWindow {
function onUpdateCheckReplyReceived(ok, found) {
if (!ok) {
// Show an error dialog describing that we could not successfully check for an update.
presentUpdateInfoDialog(JamiStrings.updateCheckError);
return;
}
if (!found) {
// Show a dialog describing that no update was found.
presentUpdateInfoDialog(JamiStrings.updateNotFound);
} else {
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": JamiStrings.updateFound,
"buttonTitles": [JamiStrings.optionUpgrade, JamiStrings.optionLater],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": [function () {
AppVersionManager.applyUpdates();
}]
});
// Show a dialog describing that an update were found, and offering to install it.
presentUpdateConfirmInstallDialog()
}
}
function onUpdateErrorOccurred(error) {
presentUpdateInfoDialog((function () {
switch (error) {
case NetworkManager.ACCESS_DENIED:
return JamiStrings.genericError;
case NetworkManager.DISCONNECTED:
return JamiStrings.networkDisconnected;
case NetworkManager.NETWORK_ERROR:
return JamiStrings.updateNetworkError;
case NetworkManager.SSL_ERROR:
return JamiStrings.updateSSLError;
case NetworkManager.CANCELED:
return JamiStrings.updateDownloadCanceled;
default:
return {};
}
})());
function onNetworkErrorOccurred(error) {
var errorStr = translateErrorToString(error);
presentUpdateInfoDialog(errorStr);
}
}

View File

@ -74,7 +74,7 @@ QtObject {
// Create, present, and return a dialog object.
function presentDialog(parent, path, props = {}) {
// Open the dialog once the object is created
return viewManager.createView(path, parent, function (obj) {
return viewManager.createUniqueView(path, parent, function (obj) {
const doneCb = function () {
viewManager.destroyView(path);
};

View File

@ -36,36 +36,70 @@ QtObject {
}
}
// Create a view from a path only if it doesn't already exist. This is used
// by the view coordinator to create views that are not self-destructing
// (main views) and only exist once per instance of the app.
function createView(path, parent = null, cb = null, props = {}) {
if (views.hasOwnProperty(path)) {
// an instance of <path> already exists
const component = Qt.createComponent(Qt.resolvedUrl(path));
return createViewFromComponent(component, path, parent, cb, props);
}
// Create a new view. Useful when we want to create multiple views that are
// self-destructing (dialogs).
function createUniqueView(path, parent = null, cb = null, props = {}) {
const component = Qt.createComponent(Qt.resolvedUrl(path));
return createViewFromComponent(component, getViewName(path), parent, cb,
props);
}
// Create a new view from a component. If a view with the same path already
// exists, it is returned instead.
function createViewFromComponent(component, viewName, parent = null,
cb = null, props = {}) {
if (views.hasOwnProperty(viewName)) {
// an instance of the view already exists
if (cb !== null) {
cb(views[path])
cb(views[viewName])
}
return views[path]
return views[viewName]
}
const component = Qt.createComponent(Qt.resolvedUrl(path))
if (component.status === Component.Ready) {
const obj = component.createObject(parent, props)
if (obj === null) {
print("error creating object")
console.error("error creating object")
return null
}
views[path] = obj
views[viewName] = obj
// Set the view name to the object name if it has one.
const viewName = obj.objectName.toString() !== '' ? obj.objectName : path.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "")
viewPaths[viewName] = path
const friendlyName = obj.objectName.toString() !== '' ?
obj.objectName :
viewName.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "")
viewPaths[friendlyName] = viewName
if (cb !== null) {
cb(obj)
}
return views[path]
return views[viewName]
}
print("error creating component", path)
console.error("error creating component", component.url)
console.error(component.errorString())
Qt.exit(1)
return null
}
// Finds a unique view name for a given path by appending a number to the
// base name. For example, if a view named "MyView" already exists, the next
// view will be named "MyView_1".
function getViewName(path) {
const baseName = path.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "")
let viewName = baseName
let suffix = 1
while (views.hasOwnProperty(viewName)) {
viewName = `${baseName}_${suffix}`
suffix++
}
return viewName
}
function destroyView(path) {
// The view may already have been destroyed.
if (!views.hasOwnProperty(path)) {

View File

@ -46,7 +46,7 @@ extern const QString defaultDownloadPath;
X(AppTheme, "System") \
X(BaseZoom, 1.0) \
X(ParticipantsSide, false) \
X(HideSelf, false) \
X(HideSelf, true) \
X(HideSpectators, false) \
X(AutoUpdate, true) \
X(PluginAutoUpdate, false) \
@ -57,12 +57,16 @@ extern const QString defaultDownloadPath;
X(WindowState, QWindow::AutomaticVisibility) \
X(EnableExperimentalSwarm, false) \
X(LANG, "SYSTEM") \
X(PluginStoreEndpoint, "https://plugins.jami.net") \
X(PositionShareDuration, 15) \
X(PositionShareLimit, true) \
X(FlipSelf, true) \
X(ShowMardownOption, false) \
X(ChatViewEnterIsNewLine, false) \
X(ShowSendOption, false)
X(ShowSendOption, false) \
X(DonationVisibleDate, "2023-11-01 05:00") \
X(IsDonationVisible, true) \
X(DonationEndDate, "2024-01-01 00:00")
/*
* A class to expose settings keys in both c++ and QML.

View File

@ -44,7 +44,6 @@ struct AppVersionManager::Impl : public QObject
, parent_(parent)
, lrcInstance_(instance)
, baseUrlString_(url.isEmpty() ? downloadUrl : url)
, tempPath_(QDir::tempPath())
, updateTimer_(new QTimer(this))
{
connect(updateTimer_, &QTimer::timeout, this, [this] {
@ -62,11 +61,11 @@ struct AppVersionManager::Impl : public QObject
connect(&parent_,
&NetworkManager::errorOccurred,
&parent_,
&AppVersionManager::updateErrorOccurred);
&AppVersionManager::networkErrorOccurred);
cleanUpdateFiles();
QUrl versionUrl {isBeta ? QUrl::fromUserInput(baseUrlString_ + betaVersionSubUrl)
: QUrl::fromUserInput(baseUrlString_ + versionSubUrl)};
const QUrl versionUrl {isBeta ? QUrl::fromUserInput(baseUrlString_ + betaVersionSubUrl)
: QUrl::fromUserInput(baseUrlString_ + versionSubUrl)};
parent_.sendGetRequest(versionUrl, [this, quiet](const QByteArray& latestVersionString) {
if (latestVersionString.isEmpty()) {
qWarning() << "Error checking version";
@ -76,14 +75,15 @@ struct AppVersionManager::Impl : public QObject
}
auto currentVersion = QString(VERSION_STRING).toULongLong();
auto latestVersion = latestVersionString.toULongLong();
qDebug() << "latest: " << latestVersion << " current: " << currentVersion;
if (latestVersion > currentVersion) {
qDebug() << "New version found";
const QString channelStr = isBeta ? "beta" : "stable";
const auto newVersionFound = latestVersion > currentVersion;
qInfo().noquote() << "--------- Version info ------------"
<< QString("\n - Current: %1 (%2)").arg(currentVersion).arg(channelStr);
if (newVersionFound) {
qDebug() << " - Latest: " << latestVersion;
Q_EMIT parent_.updateCheckReplyReceived(true, true);
} else {
qDebug() << "No new version found";
if (!quiet)
Q_EMIT parent_.updateCheckReplyReceived(true, false);
} else if (!quiet) {
Q_EMIT parent_.updateCheckReplyReceived(true, false);
}
});
};
@ -94,20 +94,21 @@ struct AppVersionManager::Impl : public QObject
connect(&parent_,
&NetworkManager::errorOccurred,
&parent_,
&AppVersionManager::updateErrorOccurred);
&AppVersionManager::networkErrorOccurred);
const QUrl downloadUrl {(beta || isBeta)
? QUrl::fromUserInput(baseUrlString_ + betaMsiSubUrl)
: QUrl::fromUserInput(baseUrlString_ + msiSubUrl)};
int uuid = parent_.downloadFile(
const auto lastDownloadReplyId = parent_.replyId_;
parent_.replyId_ = parent_.downloadFile(
downloadUrl,
*(parent_.replyId_),
[this, downloadUrl](bool success, const QString& errorMessage) {
lastDownloadReplyId,
[downloadUrl](bool success, const QString& errorMessage) {
Q_UNUSED(success)
Q_UNUSED(errorMessage)
const QProcess process;
auto basePath = tempPath_ + QDir::separator();
QProcess process;
auto basePath = QDir::tempPath() + QDir::separator();
auto msiPath = QDir::toNativeSeparators(basePath + downloadUrl.fileName());
auto logPath = QDir::toNativeSeparators(basePath + "jami_x64_install.log");
process.startDetached("msiexec",
@ -116,13 +117,12 @@ struct AppVersionManager::Impl : public QObject
<< "WIXNONUILAUNCH=1"
<< "/L*V" << logPath);
},
tempPath_);
parent_.replyId_.reset(&uuid);
QDir::tempPath());
};
void cancelUpdate()
{
parent_.cancelDownload(*(parent_.replyId_));
parent_.cancelDownload(parent_.replyId_);
};
void setAutoUpdateCheck(bool state)
@ -138,7 +138,7 @@ struct AppVersionManager::Impl : public QObject
void cleanUpdateFiles()
{
// Delete all logs and msi in the temporary directory before launching.
QString dir = QDir::tempPath();
const QString dir = QDir::tempPath();
QDir log_dir(dir, {"jami*.log"});
for (const QString& filename : log_dir.entryList()) {
log_dir.remove(filename);
@ -157,7 +157,6 @@ struct AppVersionManager::Impl : public QObject
LRCInstance* lrcInstance_ {nullptr};
QString baseUrlString_;
QString tempPath_;
QTimer* updateTimer_;
};
@ -166,13 +165,13 @@ AppVersionManager::AppVersionManager(const QString& url,
LRCInstance* instance,
QObject* parent)
: NetworkManager(cm, parent)
, replyId_(new int(0))
, replyId_(0)
, pimpl_(std::make_unique<Impl>(url, instance, *this))
{}
AppVersionManager::~AppVersionManager()
{
cancelDownload(*replyId_);
cancelDownload(replyId_);
}
void

View File

@ -47,10 +47,10 @@ Q_SIGNALS:
void appCloseRequested();
void updateCheckReplyReceived(bool ok, bool found = false);
void updateDownloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
void updateErrorOccurred(const NetworkManager::GetError& error);
void networkErrorOccurred(const NetworkManager::GetError& error);
private:
QScopedPointer<int> replyId_;
int replyId_;
struct Impl;
friend struct Impl;
std::unique_ptr<Impl> pimpl_;

View File

@ -20,6 +20,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import net.jami.Constants 1.1
import "../mainview/components"
Popup {
id: root
@ -28,65 +29,80 @@ Popup {
property bool autoClose: true
property alias backgroundColor: container.color
property alias title: titleText.text
property var popupContentLoader: containerSubContentLoader
property var popupcontainerSubContentLoader: containerSubContentLoader
property bool topLayoutVisible: true
property alias popupContentLoadStatus: containerSubContentLoader.status
property alias popupContent: containerSubContentLoader.sourceComponent
property int popupContentPreferredHeight: 0
property int popupContentPreferredWidth: 0
property int popupContentMargins: 0
property int popupContentMargins: JamiTheme.preferredMarginSize
parent: Overlay.overlay
// center in parent
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2)
anchors.centerIn: parent
modal: true
padding: popupContentMargins
padding: 0
// A popup is invisible until opened.
visible: false
focus: true
closePolicy: autoClose ? (Popup.CloseOnEscape | Popup.CloseOnPressOutside) : Popup.NoAutoClose
Rectangle {
contentItem: Control {
id: container
anchors.fill: parent
property color color: JamiTheme.secondaryBackgroundColor
padding: popupContentMargins
anchors.margins: popupContentMargins
anchors.centerIn: parent
ColumnLayout {
anchors.fill: parent
background: Rectangle {
id: bgRect
radius: JamiTheme.modalPopupRadius
color: container.color
layer.enabled: true
layer.effect: DropShadow {
horizontalOffset: 3.0
verticalOffset: 3.0
radius: bgRect.radius * 4
color: JamiTheme.shadowColor
source: bgRect
transparentBorder: true
samples: radius + 1
}
}
spacing: 0
contentItem: ColumnLayout {
id: contentLayout
Text {
id: titleText
RowLayout {
Layout.preferredWidth: parent.width
Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: topLayoutVisible
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.margins: text.length === 0 ? 0 : 10
Label {
id: titleText
Layout.preferredHeight: text.length === 0 ? 0 : contentHeight
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
font.pointSize: JamiTheme.menuFontSize
color: JamiTheme.textColor
font.pointSize: JamiTheme.menuFontSize
color: JamiTheme.textColor
visible: text.length > 0
}
JamiPushButton {
id: closeButton
Layout.alignment: Qt.AlignRight
imageColor: "grey"
normalColor: "transparent"
source: JamiResources.round_close_24dp_svg
onClicked: close()
}
}
Loader {
id: containerSubContentLoader
Layout.topMargin: popupContentMargins
Layout.bottomMargin: popupContentMargins
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: popupContentPreferredWidth === 0
Layout.fillHeight: popupContentPreferredHeight === 0
Layout.preferredHeight: popupContentPreferredHeight
Layout.preferredWidth: popupContentPreferredWidth
}
}
radius: JamiTheme.modalPopupRadius
color: JamiTheme.secondaryBackgroundColor
}
background: Rectangle {
@ -103,19 +119,6 @@ Popup {
}
}
DropShadow {
z: -1
width: root.width
height: root.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: container.radius * 4
color: JamiTheme.shadowColor
source: container
transparentBorder: true
samples: radius + 1
}
enter: Transition {
NumberAnimation {
properties: "opacity"

View File

@ -27,9 +27,6 @@ BaseModalDialog {
signal accepted
width: Math.min(appWindow.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogWidth)
height: Math.min(appWindow.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogHeight)
property string confirmLabel: ""
property string textLabel: ""
@ -40,7 +37,7 @@ BaseModalDialog {
id: labelAction
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: column.width - JamiTheme.preferredMarginSize * 2
Layout.maximumWidth: root.width - JamiTheme.preferredMarginSize * 4
color: JamiTheme.textColor
text: root.textLabel
@ -55,8 +52,8 @@ BaseModalDialog {
RowLayout {
spacing: 16
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
Layout.topMargin: JamiTheme.preferredMarginSize
MaterialButton {
id: primaryBtn

View File

@ -68,7 +68,8 @@ BaseModalDialog {
id: daemonReconnectPopupTextLabel
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
Layout.topMargin: preferredMargin
Layout.maximumWidth: root.parent.width - 4 * JamiTheme.preferredMarginSize
wrapMode: Text.Wrap
text: connectionFailed ? JamiStrings.reconnectionFailed : JamiStrings.reconnectDaemon
font.pointSize: JamiTheme.textFontSize + 2

View File

@ -33,17 +33,15 @@ BaseModalDialog {
title: JamiStrings.deleteAccount
width: Math.min(appWindow.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogWidth)
height: Math.min(appWindow.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogHeight)
popupContent: ColumnLayout {
id: deleteAccountContentColumnLayout
anchors.centerIn: parent
Label {
id: labelDeletion
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: deleteAccountContentColumnLayout.width - JamiTheme.preferredMarginSize * 2
Layout.maximumWidth: root.width - 4*JamiTheme.preferredMarginSize
color: JamiTheme.textColor
text: JamiStrings.confirmDeleteQuestion
@ -51,8 +49,6 @@ BaseModalDialog {
font.pointSize: JamiTheme.textFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
@ -60,7 +56,6 @@ BaseModalDialog {
id: labelBestId
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: deleteAccountContentColumnLayout.width - JamiTheme.preferredMarginSize * 2
color: JamiTheme.textColor
text: bestName
@ -68,9 +63,6 @@ BaseModalDialog {
font.pointSize: JamiTheme.textFontSize
font.kerning: true
font.bold: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
@ -78,7 +70,7 @@ BaseModalDialog {
id: labelAccountHash
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: deleteAccountContentColumnLayout.width - JamiTheme.preferredMarginSize * 2
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
color: JamiTheme.textColor
text: accountId
@ -87,7 +79,6 @@ BaseModalDialog {
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
@ -97,7 +88,7 @@ BaseModalDialog {
visible: !isSIP
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: deleteAccountContentColumnLayout.width - JamiTheme.preferredMarginSize * 2
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
text: JamiStrings.deleteAccountInfos
@ -120,6 +111,7 @@ BaseModalDialog {
id: btnDelete
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: JamiTheme.preferredMarginSize
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
@ -164,6 +156,7 @@ BaseModalDialog {
id: btnCancel
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: JamiTheme.preferredMarginSize
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin

View File

@ -25,19 +25,13 @@ import net.jami.Constants 1.1
BaseModalDialog {
id: root
width: 488
height: 256
width: JamiTheme.secondaryDialogDimension
property var previousBodies: undefined
popupContent: Item {
id: rect
width: root.width
JamiListView {
anchors.fill: parent
anchors.margins: JamiTheme.preferredMarginSize
popupContent: JamiListView {
width: root.width - 4 * JamiTheme.preferredMarginSize
height: Math.min(count * 50, 150)
model: root.previousBodies
@ -79,17 +73,4 @@ BaseModalDialog {
}
}
}
PushButton {
id: btnCancel
imageColor: "grey"
normalColor: "transparent"
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 10
anchors.rightMargin: 10
source: JamiResources.round_close_24dp_svg
onClicked: close()
}
}
}

View File

@ -24,6 +24,7 @@ import net.jami.Constants 1.1
Item {
id: jamiId
property bool slimDisplay: true
property color backgroundColor: JamiTheme.welcomeBlockColor
property color contentColor: JamiTheme.tintedBlue
@ -104,6 +105,8 @@ Item {
visible: usernameTextEdit.readOnly
Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: JamiTheme.pushButtonMargins
Layout.maximumWidth: leftRect.width - 50
elide: Text.ElideRight
color: jamiId.contentColor
font.pixelSize : text.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
property string registeredName: CurrentAccount.registeredName

View File

@ -68,6 +68,7 @@ SplitView {
}
handle: Rectangle {
visible: !isSinglePane
implicitWidth: JamiTheme.splitViewHandlePreferredWidth
implicitHeight: root.height
color: JamiTheme.primaryBackgroundColor

View File

@ -35,8 +35,10 @@ ContextMenuAutoLoader {
GeneralMenuItem {
id: copy
canTrigger: lineEditObj.selectedText.length
canTrigger: true
isActif: lineEditObj.selectedText.length
itemName: JamiStrings.copy
hasIcon: false
onClicked: {
lineEditObj.copy();
}
@ -44,9 +46,10 @@ ContextMenuAutoLoader {
GeneralMenuItem {
id: cut
canTrigger: lineEditObj.selectedText.length && !selectOnly
canTrigger: true
isActif: lineEditObj.selectedText.length && !selectOnly
itemName: JamiStrings.cut
hasIcon: false
onClicked: {
lineEditObj.cut();
}
@ -56,6 +59,7 @@ ContextMenuAutoLoader {
canTrigger: !selectOnly
itemName: JamiStrings.paste
hasIcon: false
onClicked: {
if (customizePaste)
root.contextMenuRequirePaste();
@ -76,10 +80,6 @@ ContextMenuAutoLoader {
lineEditObj.select(selectionStart, selectionEnd);
}
contextMenuItemPreferredHeight: JamiTheme.lineEditContextMenuItemsHeight
contextMenuItemPreferredWidth: JamiTheme.lineEditContextMenuItemsWidth
contextMenuSeparatorPreferredHeight: JamiTheme.lineEditContextMenuSeparatorsHeight
Connections {
target: root.item
enabled: root.status === Loader.Ready

View File

@ -1,309 +0,0 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Author: Nicolas Vengeon <nicolas.vengeon@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 Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
Popup {
id: root
width: emojiColumn.width + JamiTheme.emojiMargins
height: emojiColumn.height + JamiTheme.emojiMargins
padding: 0
background.visible: false
required property var emojiReactions
property var emojiReplied: emojiReactions.ownEmojis
required property string msgId
required property string msgBody
required property bool isOutgoing
required property int type
required property string transferName
required property Item msgBubble
required property ListView listView
property string transferId: msgId
property string location: msgBody
property bool closeWithoutAnimation: false
property var emojiPicker
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
function xPositionProvider(width) {
// Use the width at function scope to retrigger property evaluation.
const listViewWidth = listView.width
if (isOutgoing) {
const leftMargin = msgBubble.mapToItem(listView, 0, 0).x
return width > leftMargin ? -leftMargin : -width
} else {
const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width)
return width > rightMargin ? msgBubble.width - width : msgBubble.width
}
}
function yPositionProvider(height) {
const topOffset = msgBubble.mapToItem(listView, 0, 0).y
if (topOffset < 0) return -topOffset
const bottomOffset = topOffset + height - listView.height
if (bottomOffset > 0) return -bottomOffset
return 0
}
x: xPositionProvider(width)
y: yPositionProvider(height)
signal addMoreEmoji
onAddMoreEmoji: {
JamiQmlUtils.updateMessageBarButtonsPoints()
openEmojiPicker()
}
function openEmojiPicker() {
var component = WITH_WEBENGINE ?
Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") :
Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
emojiPicker = component.createObject(root.parent, { listView: listView })
emojiPicker.emojiIsPicked.connect(function(content) {
if (emojiReplied.includes(content)) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId)
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId)
}
})
if (emojiPicker !== null) {
root.opacity = 0
emojiPicker.closed.connect(() => close())
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth)
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight)
emojiPicker.open()
} else {
console.log("Error creating emojiPicker from message options popup");
}
}
// Close the picker when listView vertical properties change.
property real listViewHeight: listView.height
onListViewHeightChanged: close()
property bool isScrolling: listView.verticalScrollBar.active
onIsScrollingChanged: close()
onOpened: root.closeWithoutAnimation = false
onClosed: if (emojiPicker) emojiPicker.closeEmojiPicker()
function getModel() {
const defaultModel = ["👍", "👎", "😂"]
const reactedEmojis = Array.isArray(emojiReplied) ? emojiReplied.slice(0, defaultModel.length) : []
const uniqueEmojis = Array.from(new Set(reactedEmojis))
const missingEmojis = defaultModel.filter(emoji => !uniqueEmojis.includes(emoji))
return uniqueEmojis.concat(missingEmojis)
}
Rectangle {
id: bubble
color: JamiTheme.chatviewBgColor
anchors.fill: parent
radius: JamiTheme.modalPopupRadius
ColumnLayout {
id: emojiColumn
anchors.centerIn: parent
RowLayout {
id: emojiRow
Layout.alignment: Qt.AlignCenter
Repeater {
model: root.getModel()
delegate: Button {
id: emojiButton
height: 50
width: 50
text: modelData
font.pointSize: JamiTheme.emojiBubbleSize
Text {
visible: emojiButton.hovered
anchors.centerIn: parent
text: modelData
font.pointSize: JamiTheme.emojiBubbleSizeBig
z: 1
}
background: Rectangle {
anchors.fill: parent
opacity: emojiReplied ? (emojiReplied.includes(modelData) ? 1 : 0) : 0
color: JamiTheme.emojiReactPushButtonColor
radius: 10
}
onClicked: {
if (emojiReplied.includes(modelData))
MessagesAdapter.removeEmojiReaction(CurrentConversation.id,text,msgId)
else
MessagesAdapter.addEmojiReaction(CurrentConversation.id,text,msgId)
close()
}
}
}
PushButton {
toolTipText: JamiStrings.moreEmojis
source: JamiResources.add_reaction_svg
normalColor: JamiTheme.emojiReactBubbleBgColor
imageColor: JamiTheme.emojiReactPushButtonColor
visible: WITH_WEBENGINE
onClicked: {
root.closeWithoutAnimation = true
root.addMoreEmoji()
//close()
}
}
}
Rectangle {
Layout.margins: 5
color: JamiTheme.timestampColor
Layout.fillWidth: true
Layout.preferredHeight: 1
radius: width * 0.5
opacity: 0.6
}
MessageOptionButton {
textButton: JamiStrings.copy
iconSource: JamiResources.copy_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
UtilsAdapter.setClipboardText(msgBody)
close()
}
}
MessageOptionButton {
visible: type === Interaction.Type.DATA_TRANSFER
textButton: JamiStrings.saveFile
iconSource: JamiResources.save_file_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
close()
}
}
MessageOptionButton {
visible: type === Interaction.Type.DATA_TRANSFER
textButton: JamiStrings.openLocation
iconSource: JamiResources.round_folder_24dp_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.openDirectory(root.location)
close()
}
}
MessageOptionButton {
visible: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
textButton: JamiStrings.removeLocally
iconSource: JamiResources.trash_black_24dp_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.removeFile(msgId, root.location)
close()
}
}
MessageOptionButton {
id: buttonEdit
visible: root.isOutgoing && type === Interaction.Type.TEXT
textButton: JamiStrings.editMessage
iconSource: JamiResources.edit_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.replyToId = ""
MessagesAdapter.editId = root.msgId
close()
}
}
MessageOptionButton {
visible: root.isOutgoing && type === Interaction.Type.TEXT
textButton: JamiStrings.deleteMessage
iconSource: JamiResources.delete_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId)
close()
}
}
}
}
Overlay.modal: Rectangle {
color: JamiTheme.transparentColor
// Color animation for overlay when pop up is shown.
ColorAnimation on color {
to: JamiTheme.popupOverlayColor
duration: 500
}
}
DropShadow {
z: -1
width: bubble.width
height: bubble.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: bubble.radius * 4
color: JamiTheme.shadowColor
source: bubble
transparentBorder: true
samples: radius + 1
}
enter: Transition {
NumberAnimation {
properties: "opacity"; from: 0.0; to: 1.0
duration: JamiTheme.shortFadeDuration
}
}
exit: Transition {
NumberAnimation {
properties: "opacity"; from: 1.0; to: 0.0
duration: root.closeWithoutAnimation ? 0 : JamiTheme.shortFadeDuration
}
}
}

View File

@ -35,9 +35,6 @@ BaseModalDialog {
signal done(bool success, int purpose)
width: Math.min(appWindow.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogWidth)
height: Math.min(appWindow.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogHeight)
title: {
switch (purpose) {
case PasswordDialog.ExportAccount:
@ -75,7 +72,7 @@ BaseModalDialog {
popupContent: ColumnLayout {
id: popupContentColumnLayout
spacing: 0
spacing: 16
function validatePassword() {
switch (purpose) {
@ -128,6 +125,8 @@ BaseModalDialog {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.ExportAccount
placeholderText: JamiStrings.enterCurrentPassword
@ -141,6 +140,8 @@ BaseModalDialog {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.SetPassword
@ -155,6 +156,8 @@ BaseModalDialog {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.SetPassword
@ -163,49 +166,24 @@ BaseModalDialog {
onDynamicTextChanged: popupContentColumnLayout.validatePassword()
}
RowLayout {
spacing: 16
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
MaterialButton {
id: btnConfirm
MaterialButton {
id: btnConfirm
Layout.alignment: Qt.AlignHCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
Layout.alignment: Qt.AlignHCenter
color: enabled ? JamiTheme.buttonTintedBlack : JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
autoAccelerator: true
enabled: purpose === PasswordDialog.SetPassword
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
text: (purpose === PasswordDialog.ExportAccount) ? JamiStrings.exportAccount : JamiStrings.change
color: enabled ? JamiTheme.buttonTintedBlack : JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
autoAccelerator: true
enabled: purpose === PasswordDialog.SetPassword
text: (purpose === PasswordDialog.ExportAccount) ? JamiStrings.exportAccount : JamiStrings.change
onClicked: {
btnConfirm.enabled = false;
timerToOperate.restart();
}
}
MaterialButton {
id: btnCancel
Layout.alignment: Qt.AlignHCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
autoAccelerator: true
text: JamiStrings.optionCancel
onClicked: close()
onClicked: {
btnConfirm.enabled = false;
timerToOperate.restart();
}
}
}

View File

@ -32,15 +32,12 @@ import "../mainview/components"
BaseModalDialog {
id: root
height: 157
x: - width / 2
y: - height / 5
property string imageId
property bool newItem
property real buttonSize: JamiTheme.smartListAvatarSize
property real imageSize: 25
signal focusOnPreviousItem
signal focusOnNextItem
@ -60,9 +57,15 @@ BaseModalDialog {
importButton.forceActiveFocus()
}
width: JamiTheme.preferredDialogWidth
title: JamiStrings.chooseAvatarPicture
RecordBox {
id: recordBox
anchors.centerIn: parent
isPhoto: true
visible: false
@ -77,223 +80,176 @@ BaseModalDialog {
}
}
popupContent: Item {
popupContent: RowLayout {
id: buttonsRowLayout
Component.onCompleted: {
root.width = Qt.binding(() => clearButton.visible ? 283 : 210)
}
Rectangle {
id: container
anchors.fill: parent
radius: JamiTheme.photoPopupRadius
color: JamiTheme.inviteHoverColor
spacing: 10
PushButton {
id: btnCancel
imageColor: "grey"
id: takePhotoButton
objectName: "takePhotoButton"
Layout.alignment: Qt.AlignHCenter
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 10
anchors.rightMargin: 10
source: JamiResources.round_close_24dp_svg
onClicked: { close();}
}
imageColor: JamiTheme.buttonTintedBlue
toolTipText: JamiStrings.takePhoto
source: JamiResources.baseline_camera_alt_24dp_svg
hoveredColor: JamiTheme.smartListHoveredColor
ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.margins: JamiTheme.preferredMarginSize
Text {
id: informativeLabel
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Layout.topMargin: 26
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: JamiStrings.chooseAvatarPicture
color: JamiTheme.primaryForegroundColor
font.pixelSize: JamiTheme.popupPhotoTextSize
elide: Text.ElideRight
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Up) {
root.focusOnPreviousItem()
keyEvent.accepted = true
}
}
RowLayout {
id: buttonsRowLayout
Layout.preferredHeight: childrenRect.height
Layout.alignment: Qt.AlignCenter
spacing: 10
KeyNavigation.tab: {
if (clearButton.visible)
return clearButton
return importButton
}
KeyNavigation.down: KeyNavigation.tab
PushButton {
id: takePhotoButton
onClicked: {
recordBox.parent = buttonsRowLayout
objectName: "takePhotoButton"
recordBox.x = Qt.binding(function() {
var buttonCenterX = buttonsRowLayout.width / 2
return buttonCenterX - recordBox.width / 2
})
recordBox.y = Qt.binding(function() {
return - recordBox.height / 2
})
startBooth()
}
}
Layout.alignment: Qt.AlignHCenter
PushButton {
id: importButton
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
imageColor: JamiTheme.buttonTintedBlue
toolTipText: JamiStrings.takePhoto
source: JamiResources.baseline_camera_alt_24dp_svg
hoveredColor: JamiTheme.smartListHoveredColor
objectName: "photoboothViewImportButton"
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Up) {
root.focusOnPreviousItem()
keyEvent.accepted = true
}
}
Layout.alignment: Qt.AlignHCenter
visible: parent.visible
KeyNavigation.tab: {
if (clearButton.visible)
return clearButton
return importButton
}
KeyNavigation.down: KeyNavigation.tab
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
source: JamiResources.round_folder_24dp_svg
toolTipText: JamiStrings.importFromFile
imageColor: JamiTheme.buttonTintedBlue
hoveredColor: JamiTheme.smartListHoveredColor
onClicked: {
recordBox.parent = buttonsRowLayout
recordBox.x = Qt.binding(function() {
var buttonCenterX = buttonsRowLayout.width / 2
return buttonCenterX - recordBox.width / 2
})
recordBox.y = Qt.binding(function() {
return - recordBox.height / 2
})
startBooth()
}
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Down ||
keyEvent.key === Qt.Key_Tab) {
clearButton.forceActiveFocus()
keyEvent.accepted = true
}
}
PushButton {
id: importButton
KeyNavigation.up: takePhotoButton
objectName: "photoboothViewImportButton"
Layout.alignment: Qt.AlignHCenter
visible: parent.visible
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
source: JamiResources.round_folder_24dp_svg
toolTipText: JamiStrings.importFromFile
imageColor: JamiTheme.buttonTintedBlue
hoveredColor: JamiTheme.smartListHoveredColor
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Down ||
keyEvent.key === Qt.Key_Tab) {
clearButton.forceActiveFocus()
keyEvent.accepted = true
}
onClicked: {
stopBooth()
var dlg = viewCoordinator.presentDialog(
appWindow,
"commoncomponents/JamiFileDialog.qml",
{
title: JamiStrings.chooseAvatarImage,
fileMode: JamiFileDialog.OpenFile,
folder: StandardPaths.writableLocation(
StandardPaths.PicturesLocation),
nameFilters: [JamiStrings.imageFiles,
JamiStrings.allFiles]
})
dlg.fileAccepted.connect(function(file) {
var filePath = UtilsAdapter.getAbsPath(file)
if (!root.newItem) {
AccountAdapter.setCurrentAccountAvatarFile(filePath)
} else {
UtilsAdapter.setTempCreationImageFromFile(filePath, root.imageId)
}
root.close()
})
}
}
KeyNavigation.up: takePhotoButton
PushButton {
id: clearButton
onClicked: {
stopBooth()
var dlg = viewCoordinator.presentDialog(
appWindow,
"commoncomponents/JamiFileDialog.qml",
{
title: JamiStrings.chooseAvatarImage,
fileMode: JamiFileDialog.OpenFile,
folder: StandardPaths.writableLocation(
StandardPaths.PicturesLocation),
nameFilters: [JamiStrings.imageFiles,
JamiStrings.allFiles]
})
dlg.fileAccepted.connect(function(file) {
var filePath = UtilsAdapter.getAbsPath(file)
if (!root.newItem) {
AccountAdapter.setCurrentAccountAvatarFile(filePath)
} else {
UtilsAdapter.setTempCreationImageFromFile(filePath, root.imageId)
}
root.close()
})
}
objectName: "photoboothViewClearButton"
Layout.alignment: Qt.AlignHCenter
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
source: JamiResources.ic_hangup_participant_24dp_svg
toolTipText: JamiStrings.clearAvatar
imageColor: JamiTheme.buttonTintedBlue
hoveredColor: JamiTheme.smartListHoveredColor
visible: {
if (!newItem && LRCInstance.currentAccountAvatarSet)
return true
if (newItem && UtilsAdapter.tempCreationImage(imageId).length !== 0)
return true
return false
}
KeyNavigation.up: importButton
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
importButton.forceActiveFocus()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Down ||
keyEvent.key === Qt.Key_Tab) {
btnCancel.forceActiveFocus()
keyEvent.accepted = true
}
}
PushButton {
id: clearButton
objectName: "photoboothViewClearButton"
Layout.alignment: Qt.AlignHCenter
height: buttonSize
width: buttonSize
imageContainerWidth: imageSize
imageContainerHeight: imageSize
radius: height / 2
border.color: JamiTheme.buttonTintedBlue
normalColor: "transparent"
source: JamiResources.ic_hangup_participant_24dp_svg
toolTipText: JamiStrings.clearAvatar
imageColor: JamiTheme.buttonTintedBlue
hoveredColor: JamiTheme.smartListHoveredColor
visible: {
if (!newItem && LRCInstance.currentAccountAvatarSet)
return true
if (newItem && UtilsAdapter.tempCreationImage(imageId).length !== 0)
return true
return false
}
KeyNavigation.up: importButton
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter ||
keyEvent.key === Qt.Key_Return) {
clicked()
importButton.forceActiveFocus()
keyEvent.accepted = true
} else if (keyEvent.key === Qt.Key_Down ||
keyEvent.key === Qt.Key_Tab) {
btnCancel.forceActiveFocus()
keyEvent.accepted = true
}
}
onClicked: {
if (!root.newItem)
AccountAdapter.setCurrentAccountAvatarBase64()
else
UtilsAdapter.setTempCreationImageFromString("", imageId)
visible = false
stopBooth()
root.close()
}
}
onClicked: {
if (!root.newItem)
AccountAdapter.setCurrentAccountAvatarBase64()
else
UtilsAdapter.setTempCreationImageFromString("", imageId)
visible = false
stopBooth()
root.close()
}
}
}
}
}

View File

@ -53,6 +53,7 @@ AbstractButton {
property alias toolTipText: toolTip.text
property alias hasShortcut: toolTip.hasShortcut
property alias shortcutKey: toolTip.shortcutKey
property int buttonTextFontSize: 12
// State colors
property string pressedColor: JamiTheme.pressedButtonColor
@ -143,7 +144,7 @@ AbstractButton {
color: JamiTheme.primaryForegroundColor
font.kerning: true
font.pixelSize: 12
font.pixelSize: buttonTextFontSize
elide: Qt.ElideRight
}

View File

@ -37,6 +37,7 @@ ContextMenuAutoLoader {
canTrigger: root.transferId !== ""
itemName: JamiStrings.saveFile
iconSource: JamiResources.save_file_svg
onClicked: MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
},
GeneralMenuItem {
@ -44,6 +45,7 @@ ContextMenuAutoLoader {
canTrigger: root.transferId !== ""
itemName: JamiStrings.openLocation
iconSource: JamiResources.round_folder_24dp_svg
onClicked: {
MessagesAdapter.openDirectory(root.location);
}
@ -52,6 +54,7 @@ ContextMenuAutoLoader {
id: reply
itemName: JamiStrings.reply
iconSource: JamiResources.reply_svg
onClicked: {
MessagesAdapter.editId = "";
MessagesAdapter.replyToId = root.msgId;
@ -62,6 +65,7 @@ ContextMenuAutoLoader {
canTrigger: transferId === "" && isOutgoing
itemName: JamiStrings.edit
iconSource: JamiResources.edit_svg
onClicked: {
MessagesAdapter.replyToId = "";
MessagesAdapter.editId = root.msgId;
@ -73,6 +77,7 @@ ContextMenuAutoLoader {
canTrigger: transferId === "" && isOutgoing
itemName: JamiStrings.optionDelete
iconSource: JamiResources.delete_svg
onClicked: {
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId);
}

View File

@ -277,8 +277,8 @@ Control {
anchors.rightMargin: isOutgoing ? 10 : 0
anchors.leftMargin: !isOutgoing ? 10 : 0
imageColor: JamiTheme.emojiReactPushButtonColor
normalColor: JamiTheme.transparentColor
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
toolTipText: JamiStrings.moreOptions
anchors.verticalCenter: parent.verticalCenter
anchors.right: isOutgoing ? optionButtonItem.right : undefined
@ -287,9 +287,10 @@ Control {
source: JamiResources.more_vert_24dp_svg
width: optionButtonItem.width / 2
height: optionButtonItem.height
circled: false
onClicked: {
var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml");
var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
var obj = component.createObject(bubble, {
"emojiReactions": emojiReactions,
"isOutgoing": isOutgoing,
@ -307,13 +308,15 @@ Control {
PushButton {
id: reply
imageColor: JamiTheme.emojiReactPushButtonColor
normalColor: JamiTheme.transparentColor
circled: false
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
toolTipText: JamiStrings.reply
source: JamiResources.reply_svg
width: optionButtonItem.width / 2
height: optionButtonItem.height
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 5
anchors.right: isOutgoing ? more.left : undefined
anchors.left: !isOutgoing ? more.right : undefined
visible: CurrentAccount.type !== Profile.Type.SIP && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || bgHandler.hovered)

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2020-2023 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/>.
*/
import QtQuick
import net.jami.Constants 1.1
import "contextmenu"
BaseContextMenu {
id: root
property var modelList
signal audioRecordMessageButtonClicked
signal videoRecordMessageButtonClicked
signal showMapClicked
property list<GeneralMenuItem> menuItems: [
GeneralMenuItem {
id: audioMessage
canTrigger: true
iconSource: JamiResources.message_audio_black_24dp_svg
itemName: JamiStrings.leaveAudioMessage
onClicked: {
root.audioRecordMessageButtonClicked();
}
},
GeneralMenuItem {
id: videoMessage
canTrigger: true
iconSource: JamiResources.message_video_black_24dp_svg
itemName: JamiStrings.leaveVideoMessage
onClicked: {
root.videoRecordMessageButtonClicked();
}
},
GeneralMenuItem {
id: shareLocation
canTrigger: true
iconSource: JamiResources.localisation_sharing_send_pin_svg
itemName: JamiStrings.shareLocation
onClicked: {
root.showMapClicked();
}
}
]
Component.onCompleted: {
root.loadMenuItems(menuItems);
}
}

View File

@ -1,134 +0,0 @@
/*
* Copyright (C) 2023 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/>.
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.platform
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../mainview/components"
Popup {
id: root
padding: 0
property list<Action> menuMoreButton
height: childrenRect.height
width: childrenRect.width
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
Rectangle {
id: rect
color: JamiTheme.primaryBackgroundColor
border.color: JamiTheme.chatViewFooterRectangleBorderColor
border.width: 2
radius: 5
height: listViewMoreButton.childrenRect.height + 16
width: listViewMoreButton.childrenRect.width + 16
ListView {
id: listViewMoreButton
anchors.centerIn: parent
orientation: ListView.Vertical
spacing: 0
width: contentItem.childrenRect.width
height: contentHeight
model: menuMoreButton
Rectangle {
z: -1
anchors.fill: parent
color: "transparent"
}
onCountChanged: {
for (var i = 0; i < count; i++) {
var item = listViewMoreButton.itemAtIndex(i);
item.width = listViewMoreButton.width;
}
}
delegate: ItemDelegate {
id: control
text: modelData.toolTip
contentItem: RowLayout {
Rectangle {
id: image
width: 26
height: 26
radius: 5
color: JamiTheme.transparentColor
ResponsiveImage {
anchors.fill: parent
source: modelData.iconSrc
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
}
}
Text {
Layout.alignment: Qt.AlignLeft
text: control.text
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : "#7f7f7f"
}
}
background: Rectangle {
color: control.hovered ? JamiTheme.showMoreButtonOpenColor : JamiTheme.transparentColor
}
action: modelData
onClicked: {
root.close();
}
}
}
}
background: Rectangle {
anchors.fill: parent
color: JamiTheme.transparentColor
radius: 5
z: -1
}
enter: Transition {
NumberAnimation {
properties: "opacity"
from: 0.0
to: 1.0
duration: JamiTheme.shortFadeDuration
}
}
exit: Transition {
NumberAnimation {
properties: "opacity"
from: 1.0
to: 0.0
duration: JamiTheme.shortFadeDuration
}
}
}

View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2020-2023 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/>.
*/
import QtQuick
import net.jami.Constants 1.1
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import "contextmenu"
BaseContextMenu {
id: root
required property var emojiReactions
property var emojiReplied: emojiReactions.ownEmojis
required property string msgId
required property string msgBody
required property bool isOutgoing
required property int type
required property string transferName
required property Item msgBubble
required property ListView listView
property string location: msgBody
property bool closeWithoutAnimation: false
property var emojiPicker
function xPositionProvider(width) {
// Use the width at function scope to retrigger property evaluation.
const listViewWidth = listView.width;
if (isOutgoing) {
const leftMargin = msgBubble.mapToItem(listView, 0, 0).x;
return width > leftMargin ? -leftMargin - 35 : -width - 35;
} else {
const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width);
return width > rightMargin ? msgBubble.width - width + 35 : msgBubble.width + 35;
}
}
function yPositionProvider(height) {
const topOffset = msgBubble.mapToItem(listView, 0, 0).y;
if (topOffset < 0)
return -topOffset;
const bottomOffset = topOffset + height - listView.height;
if (bottomOffset > 0)
return -bottomOffset;
return 0;
}
x: xPositionProvider(width)
y: yPositionProvider(height)
signal addMoreEmoji
onAddMoreEmoji: {
JamiQmlUtils.updateMessageBarButtonsPoints();
openEmojiPicker();
}
function openEmojiPicker() {
var component = WITH_WEBENGINE ? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") : Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml");
emojiPicker = component.createObject(root.parent, {
"listView": listView
});
emojiPicker.emojiIsPicked.connect(function (content) {
if (emojiReplied.includes(content)) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId);
}
});
if (emojiPicker !== null) {
root.opacity = 0;
emojiPicker.closed.connect(() => close());
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth);
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight);
emojiPicker.open();
} else {
console.log("Error creating emojiPicker from message options popup");
}
}
// Close the picker when listView vertical properties change.
property real listViewHeight: listView.height
onListViewHeightChanged: close()
property bool isScrolling: listView.verticalScrollBar.active
onIsScrollingChanged: close()
onOpened: root.closeWithoutAnimation = false
onClosed: if (emojiPicker)
emojiPicker.closeEmojiPicker()
function getModel() {
const defaultModel = ["👍", "👎", "😂"];
const reactedEmojis = Array.isArray(emojiReplied) ? emojiReplied.slice(0, defaultModel.length) : [];
const uniqueEmojis = Array.from(new Set(reactedEmojis));
const missingEmojis = defaultModel.filter(emoji => !uniqueEmojis.includes(emoji));
return uniqueEmojis.concat(missingEmojis);
}
property list<MenuItem> menuItems: [
GeneralMenuItemList {
id: audioMessage
modelList: getModel()
canTrigger: true
iconSource: JamiResources.add_reaction_svg
itemName: JamiStrings.copy
addMenuSeparatorAfter: true
messageId: msgId
},
GeneralMenuItem {
id: saveFile
canTrigger: type === Interaction.Type.DATA_TRANSFER
iconSource: JamiResources.save_file_svg
itemName: JamiStrings.saveFile
onClicked: {
MessagesAdapter.copyToDownloads(root.msgId, root.transferName);
}
},
GeneralMenuItem {
id: openLocation
canTrigger: type === Interaction.Type.DATA_TRANSFER
iconSource: JamiResources.round_folder_24dp_svg
itemName: JamiStrings.openLocation
onClicked: {
MessagesAdapter.openDirectory(root.location);
}
},
GeneralMenuItem {
id: removeLocally
canTrigger: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
iconSource: JamiResources.trash_black_24dp_svg
itemName: JamiStrings.removeLocally
onClicked: {
MessagesAdapter.removeFile(msgId, root.location);
;
}
},
GeneralMenuItem {
id: editMessage
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
iconSource: JamiResources.edit_svg
itemName: JamiStrings.editMessage
onClicked: {
MessagesAdapter.replyToId = "";
MessagesAdapter.editId = root.msgId;
}
},
GeneralMenuItem {
id: deleteMessage
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
iconSource: JamiResources.delete_svg
itemName: JamiStrings.deleteMessage
onClicked: {
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId);
}
},
GeneralMenuItem {
id: copyMessage
canTrigger: true
iconSource: JamiResources.copy_svg
itemName: JamiStrings.copy
onClicked: {
UtilsAdapter.setClipboardText(msgBody);
}
}
]
Component.onCompleted: {
root.loadMenuItems(menuItems);
}
}

View File

@ -44,9 +44,6 @@ BaseModalDialog {
open();
}
width: Math.max(JamiTheme.preferredDialogWidth, buttonTitles.length * (JamiTheme.preferredFieldWidth / 2 + JamiTheme.preferredMarginSize))
height: JamiTheme.preferredDialogHeight / 2 - JamiTheme.preferredMarginSize
popupContent: ColumnLayout {
Label {
id: infoTextLabel
@ -72,12 +69,10 @@ BaseModalDialog {
data: innerContentData
}
RowLayout {
spacing: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: contentHeight
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: JamiTheme.preferredMarginSize

View File

@ -43,11 +43,9 @@ Menu {
function loadMenuItems(menuItems) {
root.addItem(menuTopBorder);
// use the maximum text width as the preferred width for menu
for (var j = 0; j < menuItems.length; ++j) {
var currentItemWidth = menuItems[j].itemPreferredWidth;
if (currentItemWidth !== JamiTheme.menuItemsPreferredWidth && currentItemWidth > menuPreferredWidth)
if (currentItemWidth !== JamiTheme.menuItemsPreferredWidth && currentItemWidth > menuPreferredWidth && menuItems[j].canTrigger)
menuPreferredWidth = currentItemWidth;
}
for (var i = 0; i < menuItems.length; ++i) {
@ -55,17 +53,28 @@ Menu {
menuItems[i].parentMenu = root;
root.addItem(menuItems[i]);
if (menuPreferredWidth)
menuItems[i].itemPreferredWidth = menuPreferredWidth;
menuItems[i].itemRealWidth = menuPreferredWidth;
if (menuItemsPreferredHeight)
menuItems[i].itemPreferredHeight = menuItemsPreferredHeight;
}
if (menuItems[i].addMenuSeparatorAfter) {
// If the QML file to be loaded is a local file,
// you could omit the finishCreation() function
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
generalMenuSeparatorList.push(menuSeparatorComponentObj);
root.addItem(menuSeparatorComponentObj);
if (i !== menuItems.length - 1) {
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
generalMenuSeparatorList.push(menuSeparatorComponentObj);
root.addItem(menuSeparatorComponentObj);
}
if (menuItems[i].addMenuSeparatorAfter) {
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
var menuSeparatorComponentObj = menuSeparatorComponent.createObject(root, {
"separatorColor": "#DEDEDE",
"separatorPreferredHeight": 0
});
generalMenuSeparatorList.push(menuSeparatorComponentObj);
root.addItem(menuSeparatorComponentObj);
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
generalMenuSeparatorList.push(menuSeparatorComponentObj);
root.addItem(menuSeparatorComponentObj);
}
}
}
root.addItem(menuBottomBorder);
@ -81,24 +90,23 @@ Menu {
Overlay.modal: Rectangle {
color: "transparent"
}
font.pointSize: JamiTheme.menuFontSize
background: Rectangle {
id: container
implicitWidth: menuPreferredWidth ? menuPreferredWidth : JamiTheme.menuItemsPreferredWidth
border.width: JamiTheme.menuItemsCommonBorderWidth
border.color: JamiTheme.tabbarBorderColor
color: JamiTheme.backgroundColor
color: JamiTheme.primaryBackgroundColor
radius: 5
layer.enabled: true
layer.effect: DropShadow {
z: -1
horizontalOffset: 3.0
horizontalOffset: 0.0
verticalOffset: 3.0
radius: 16.0
color: JamiTheme.shadowColor
radius: 6
color: "#29000000"
transparentBorder: true
samples: radius + 1
}

View File

@ -30,6 +30,8 @@ Loader {
active: false
visible: false
function openMenu() {
root.active = true;
root.sourceComponent = menuComponent;

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* 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
@ -32,34 +31,41 @@ MenuItem {
property alias iconSource: contextMenuItemImage.source
property string iconColor: ""
property bool canTrigger: true
property bool hasIcon: true
property bool addMenuSeparatorAfter: false
property bool autoTextSizeAdjustment: true
property bool dangerous: false
property BaseContextMenu parentMenu
property bool isActif: true
property int itemPreferredWidth: JamiTheme.menuItemsPreferredWidth
property int itemPreferredWidth: hasIcon ? 50 + contextMenuItemText.contentWidth + contextMenuItemImage.width : 35 + contextMenuItemText.contentWidth
property int itemRealWidth: itemPreferredWidth
property int itemPreferredHeight: JamiTheme.menuItemsPreferredHeight
property int leftBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int rightBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int itemImageLeftMargin: 24
property int itemTextMargin: 20
property int itemImageLeftMargin: 10
property int itemTextMargin: 10
signal clicked
property bool itemHovered: menuItemContentRect.hovered
contentItem: AbstractButton {
width: itemRealWidth
contentItem: PushButton {
id: menuItemContentRect
background: Rectangle {
id: background
enabled: isActif
hoverEnabled: isActif
anchors.fill: parent
anchors.leftMargin: 1
anchors.rightMargin: 1
hoveredColor: JamiTheme.hoverColor
normalColor: JamiTheme.primaryBackgroundColor
circled: false
radius: 5
color: menuItemContentRect.hovered ? JamiTheme.hoverColor : JamiTheme.backgroundColor
}
//duration: 1000
anchors.leftMargin: 6
anchors.rightMargin: 6
anchors.fill: parent
@ -76,41 +82,25 @@ MenuItem {
visible: status === Image.Ready
color: iconColor !== "" ? iconColor : JamiTheme.textColor
opacity: 0.7
color: menuItemContentRect.hovered ? JamiTheme.textColor : JamiTheme.chatViewFooterImgColor
}
Text {
id: contextMenuItemText
Item {
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin / 2
Layout.rightMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin / 2
Layout.leftMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin
Layout.rightMargin: contextMenuItemImage.status === Image.Ready ? itemImageLeftMargin : itemTextMargin
Layout.preferredHeight: itemPreferredHeight
Layout.fillWidth: true
text: itemName
color: dangerous ? JamiTheme.redColor : JamiTheme.textColor
font.pointSize: JamiTheme.textFontSize
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
TextMetrics {
id: contextMenuItemTextMetrics
font: contextMenuItemText.font
text: contextMenuItemText.text
onBoundingRectChanged: {
var sizeToCompare = itemPreferredWidth - (contextMenuItemImage.source.toString().length > 0 ? itemTextMargin + itemImageLeftMargin + contextMenuItemImage.width : itemTextMargin / 2);
if (autoTextSizeAdjustment && boundingRect.width > sizeToCompare) {
if (boundingRect.width > JamiTheme.contextMenuItemTextMaxWidth) {
itemPreferredWidth += JamiTheme.contextMenuItemTextMaxWidth - JamiTheme.contextMenuItemTextPreferredWidth + itemTextMargin;
contextMenuItemText.elide = Text.ElideRight;
} else
itemPreferredWidth += boundingRect.width + itemTextMargin - sizeToCompare;
}
}
Text {
id: contextMenuItemText
height: parent.height
text: itemName
color: dangerous ? JamiTheme.redColor : isActif ? JamiTheme.textColor : JamiTheme.chatViewFooterImgColor
font.pointSize: JamiTheme.textFontSize
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
}
}
@ -130,7 +120,9 @@ MenuItem {
anchors.leftMargin: leftBorderWidth
anchors.rightMargin: rightBorderWidth
implicitWidth: itemPreferredWidth
color: JamiTheme.primaryBackgroundColor
implicitWidth: itemRealWidth
implicitHeight: itemPreferredHeight
border.width: 0
@ -141,7 +133,7 @@ MenuItem {
rBorderwidth: rightBorderWidth
tBorderwidth: 0
bBorderwidth: 0
borderColor: JamiTheme.tabbarBorderColor
borderColor: JamiTheme.primaryBackgroundColor
}
}
}

View File

@ -0,0 +1,216 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* 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/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Constants 1.1
import "../"
import net.jami.Adapters 1.1
// General menu item.
// Can control top, bottom, left, right border width.
// Use onClicked slot to simulate item click event.
// Can have image icon at the left of the text.
MenuItem {
id: menuItem
property var modelList: undefined
property string itemName: ""
property var iconSource: undefined
property string iconColor: ""
property bool canTrigger: true
property bool hasIcon: true
property bool addMenuSeparatorAfter: false
property bool autoTextSizeAdjustment: true
property bool dangerous: false
property BaseContextMenu parentMenu
property string messageId
signal addMoreEmoji
property int itemPreferredWidth: 207
property int itemRealWidth: itemPreferredWidth
property int itemPreferredHeight: JamiTheme.menuItemsPreferredHeight
property int leftBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int rightBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int itemImageLeftMargin: 18
signal clicked
width: itemRealWidth
contentItem: Item {
id: menuItemContentRect
anchors.fill: parent
RowLayout {
spacing: 0
anchors.fill: menuItemContentRect
Rectangle {
id: contextMenuItemImage
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin
height: 36
width: 36
color: emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[0]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage.color = emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[0])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[0], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[0], msgId);
}
close();
}
}
}
Rectangle {
id: contextMenuItemImage2
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
height: 36
width: 36
color: emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[1]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage2.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage2.color = emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[1])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[1], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[1], msgId);
}
close();
}
}
}
Rectangle {
id: contextMenuItemImage3
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
height: 36
width: 36
color: emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[2]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage3.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage3.color = emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[2])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[2], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[2], msgId);
}
close();
}
}
}
PushButton {
id: contextMenuItemImage4
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
Layout.rightMargin: itemImageLeftMargin
height: 36
width: 36
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
radius: 5
source: iconSource
onClicked: {
root.addMoreEmoji();
}
}
}
}
highlighted: true
background: Rectangle {
id: contextMenuBackgroundRect
anchors.fill: parent
anchors.leftMargin: leftBorderWidth
anchors.rightMargin: rightBorderWidth
color: JamiTheme.primaryBackgroundColor
implicitWidth: itemRealWidth
implicitHeight: itemPreferredHeight
border.width: 0
CustomBorder {
commonBorder: false
lBorderwidth: leftBorderWidth
rBorderwidth: rightBorderWidth
tBorderwidth: 0
bBorderwidth: 0
borderColor: JamiTheme.primaryBackgroundColor
}
}
}

View File

@ -23,19 +23,24 @@ MenuSeparator {
id: menuSeparator
property int separatorPreferredWidth: JamiTheme.menuItemsPreferredWidth
property int separatorPreferredHeight: 1
property string separatorColor: JamiTheme.tabbarBorderColor
property int separatorPreferredHeight: 5
property string separatorColor: JamiTheme.primaryBackgroundColor
padding: 0
topPadding: 1
bottomPadding: 1
contentItem: Rectangle {
implicitWidth: separatorPreferredWidth
implicitHeight: separatorPreferredHeight
color: separatorColor
radius: 5
}
background: Rectangle {
color: JamiTheme.backgroundColor
width: parent.width - 10
anchors.horizontalCenter: parent.horizontalCenter
color: separatorColor
radius: 5
}
}

View File

@ -0,0 +1,228 @@
/*
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
#include "connectioninfolistmodel.h"
ConnectionInfoListModel::ConnectionInfoListModel(LRCInstance* instance, QObject* parent)
: AbstractListModelBase(parent)
{
lrcInstance_ = instance;
connect(lrcInstance_,
&LRCInstance::currentAccountIdChanged,
this,
&ConnectionInfoListModel::resetData);
}
int
ConnectionInfoListModel::rowCount(const QModelIndex& parent) const
{
return peerIds_.size();
}
QVariant
ConnectionInfoListModel::data(const QModelIndex& index, int role) const
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
qWarning() << "ConnectionInfoListModel::data: accountId or peerID is empty";
return {};
}
const auto peerId = peerIds_[index.row()];
const auto peerData = peerData_[peerId];
switch (role) {
case ConnectionInfoList::ChannelsMap: {
QVariantMap channelsMapMap;
int i = 0;
for (const auto& device : peerData.keys()) {
QString channelsId = peerData[device]["id"].toString();
QVariantMap channelsMap;
const auto channelInfoList = lrcInstance_->getChannelList(accountId, channelsId);
for (const auto& channelInfo : channelInfoList) {
channelsMap.insert(channelInfo["id"], channelInfo["name"]);
}
channelsMapMap.insert(QString::number(i++), channelsMap);
}
return QVariant(channelsMapMap);
}
case ConnectionInfoList::ConnectionDatas: {
QString peerString;
peerString += "Peer:" + peerId;
for (const auto& device : peerData.keys()) {
peerString += "{";
peerString += "Device:" + device + ",";
peerString += "Status:" + peerData[device]["status"].toString() + ",";
peerString += "Channels:" + peerData[device]["channels"].toString() + ",";
peerString += "Remote Address" + peerData[device]["remoteAddress"].toString();
peerString += "}";
}
return peerString;
}
case ConnectionInfoList::PeerId:
return peerId;
case ConnectionInfoList::RemoteAddress: {
QVariantMap remoteAddressMap;
int i = 0;
for (const auto& device : peerData.keys()) {
remoteAddressMap.insert(QString::number(i++), peerData[device]["remoteAddress"]);
}
return QVariant(remoteAddressMap);
}
case ConnectionInfoList::DeviceId: {
QVariantMap deviceMap;
int i = 0;
for (const auto& device : peerData.keys()) {
deviceMap.insert(QString::number(i++), device);
}
return QVariant(deviceMap);
}
case ConnectionInfoList::Status: {
QVariantMap statusMap;
int i = 0;
for (const auto& device : peerData.keys()) {
statusMap.insert(QString::number(i++), peerData[device]["status"]);
}
return QVariantMap(statusMap);
}
case ConnectionInfoList::Channels: {
QVariantMap channelsMap;
int i = 0;
for (const auto& device : peerData.keys()) {
channelsMap.insert(QString::number(i++), peerData[device]["channels"]);
}
return QVariant(channelsMap);
}
case ConnectionInfoList::Count:
return peerData.size();
}
return {};
}
QHash<int, QByteArray>
ConnectionInfoListModel::roleNames() const
{
using namespace ConnectionInfoList;
QHash<int, QByteArray> roles;
#define X(role) roles[role] = #role;
CONNECTONINFO_ROLES
#undef X
return roles;
}
void
ConnectionInfoListModel::update()
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
return;
}
aggregateData();
}
template<typename T>
std::tuple<QVector<T>, QVector<T>>
getSetDiff(QVector<T> u, QVector<T> v)
{
using namespace std;
QVector<T> a, r;
set_difference(v.begin(), v.end(), u.begin(), u.end(), inserter(a, a.begin()));
set_difference(u.begin(), u.end(), v.begin(), v.end(), inserter(r, r.begin()));
return {a, r};
}
void
ConnectionInfoListModel::aggregateData()
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
return;
}
connectionInfoList_ = lrcInstance_->getConnectionList(accountId);
peerData_ = {};
QSet<QString> newPeerIds;
for (const auto& connectionInfo : connectionInfoList_) {
if (!connectionInfo["peer"].isEmpty()) {
newPeerIds.insert(connectionInfo["peer"]);
}
const auto channelInfoList = lrcInstance_->getChannelList(accountId, connectionInfo["id"]);
peerData_[connectionInfo["peer"]][connectionInfo["device"]] = {};
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["status"]
= connectionInfo["status"];
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["channels"] = channelInfoList
.size();
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["id"] = connectionInfo["id"];
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["remoteAddress"]
= connectionInfo["remoteAddress"];
}
QVector<QString> oldVector;
for (const auto& peerId : peerIds_) {
oldVector << peerId;
}
QVector<QString> newVector;
for (const auto& peerId : newPeerIds) {
newVector << peerId;
}
std::sort(oldVector.begin(), oldVector.end());
std::sort(newVector.begin(), newVector.end());
QVector<QString> removed, added;
std::tie(added, removed) = getSetDiff(oldVector, newVector);
Q_FOREACH (const auto& key, added) {
auto index = std::distance(newVector.begin(),
std::find(newVector.begin(), newVector.end(), key));
beginInsertRows(QModelIndex(), index, index);
peerIds_.insert(index, key);
endInsertRows();
}
Q_FOREACH (const auto& key, removed) {
auto index = std::distance(oldVector.begin(),
std::find(oldVector.begin(), oldVector.end(), key));
beginRemoveRows(QModelIndex(), index, index);
if (peerIds_.size() > index) {
peerIds_.remove(index);
} else {
qWarning() << "ConnectionInfoListModel::aggregateData: index out of range";
qWarning() << "index: " << index;
qWarning() << "key: " << key;
}
endRemoveRows();
}
// HACK: loop through all the peerIds_ and update the data for each one.
// This is not efficient, but it works.
Q_FOREACH (const auto& peerId, peerIds_) {
auto index = std::distance(peerIds_.begin(),
std::find(peerIds_.begin(), peerIds_.end(), peerId));
Q_EMIT dataChanged(this->index(index), this->index(index));
}
}
void
ConnectionInfoListModel::resetData()
{
beginResetModel();
peerIds_.clear();
peerData_.clear();
endResetModel();
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "abstractlistmodelbase.h"
#define CONNECTONINFO_ROLES \
X(ConnectionDatas) \
X(ChannelsMap) \
X(PeerName) \
X(PeerId) \
X(DeviceId) \
X(Status) \
X(Channels) \
X(RemoteAddress) \
X(Count) // this is the number of connections (convenience)
namespace ConnectionInfoList {
Q_NAMESPACE
enum Role {
DummyRole = Qt::UserRole + 1,
#define X(role) role,
CONNECTONINFO_ROLES
#undef X
};
Q_ENUM_NS(Role)
} // namespace ConnectionInfoList
class ConnectionInfoListModel : public AbstractListModelBase
{
public:
explicit ConnectionInfoListModel(LRCInstance* instance, QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void update();
private:
using Role = ConnectionInfoList::Role;
VectorMapStringString connectionInfoList_;
QVector<QString> peerIds_;
QMap<QString, QMap<QString, QMap<QString, QVariant>>> peerData_;
void aggregateData();
void resetData();
};

View File

@ -20,6 +20,7 @@
pragma Singleton
import QtQuick
import net.jami.Adapters 1.1
import net.jami.Enums 1.1
Item {
property string qmlFilePrefix: "file:/"
@ -69,4 +70,13 @@ Item {
function clamp(val, min, max) {
return Math.min(Math.max(val, min), max);
}
function isDonationBannerVisible() {
// The banner is visible if the current date is after the date set in the settings and before the end date
// And if the donation toggle is checked
var isDonationVisible = UtilsAdapter.getAppValue(Settings.Key.IsDonationVisible);
var endDonationDate = new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonationEndDate)));
var donationVisibleDate = new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonationVisibleDate)));
return new Date() < endDonationDate && new Date() > donationVisibleDate && isDonationVisible && false;
}
}

View File

@ -47,7 +47,7 @@ Item {
// AboutPopUp
property string version: qsTr("Version") + (AppVersionManager.isCurrentVersionBeta() ? " (Beta)" : "")
property string declarationYear: "© 2015-2023"
property string slogan: "Világfa"
property string slogan: "Eleutheria"
property string declaration: qsTr("Jami is a free universal communication software that respects the freedom and privacy of its users.")
// AccountComboBox
@ -436,7 +436,7 @@ Item {
// LinkedDevices
property string tipLinkNewDevice: qsTr("Link a new device to this account")
property string linkNewDevice: qsTr("Exporting account…")
property string linkDevice: qsTr("Exporting account…")
property string removeDevice: qsTr("Remove Device")
property string sureToRemoveDevice: qsTr("Are you sure you wish to remove this device?")
property string yourPinIs: qsTr("Your PIN is:")
@ -513,6 +513,8 @@ Item {
property string updateDownloading: "Downloading"
property string confirmBeta: qsTr("This will uninstall your current Release version and you can always download the latest Release version on our website")
property string networkDisconnected: qsTr("Network disconnected")
property string accessError: qsTr("Content access error")
property string contentNotFoundError: qsTr("Content not found")
property string genericError: qsTr("Something went wrong")
//Troubleshoot Settings
@ -575,13 +577,20 @@ Item {
// LinkDevicesDialog
property string pinTimerInfos: qsTr("The PIN and the account password should be entered in your device within 10 minutes.")
property string close: qsTr("Close")
property string enterAccountPassword: qsTr("Enter account's password")
property string enterAccountPassword: qsTr("Enter account password")
property string enterPasswordPinCode: qsTr("This account is password encrypted, enter the password to generate a PIN code.")
property string addDevice: qsTr("Add Device")
property string pinExpired: qsTr("PIN expired")
property string onAnotherDevice: qsTr("On another device")
property string onAnotherDeviceInstruction: qsTr("Install and launch Jami, select \"Import from another device\" and scan the QR code.")
property string linkNewDevice: qsTr("Link new device")
property string linkingInstructions: qsTr("In Jami, scan QR code or manually enter the PIN.")
property string pinValidity: qsTr("The PIN code is valid for: ")
// PasswordDialog
property string enterPassword: qsTr("Enter the password")
property string enterPassword: qsTr("Enter password")
property string enterCurrentPassword: qsTr("Enter current password")
property string confirmRemoval: qsTr("Enter this account's password to confirm the removal of this device")
property string confirmRemoval: qsTr("Enter account password to confirm the removal of this device")
property string enterNewPassword: qsTr("Enter new password")
property string confirmNewPassword: qsTr("Confirm new password")
property string change: qsTr("Change")
@ -723,6 +732,8 @@ Item {
property string showMore: qsTr("Show more")
property string showLess: qsTr("Show less")
property string showPreview: qsTr("Show preview")
property string continueEditing: qsTr("Continue editing")
property string bold: qsTr("Bold")
property string italic: qsTr("Italic")
property string strikethrough: qsTr("Strikethrough")
@ -826,4 +837,30 @@ Item {
// Appearence
property string theme: qsTr("Theme")
property string zoomLevel: qsTr("Text zoom level")
//Donation campaign
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/donate/\">Donate</a> to expand it.")
property string donation: qsTr("Donate")
property string donationText: qsTr("If you enjoy using Jami and believe in our mission, would you make a donation?")
property string notNow: qsTr("Not now")
property string enableDonation: qsTr("Enable donation campaign")
//Chat setting page
property string enter: qsTr("Enter")
property string shiftEnter: qsTr("Shift+Enter")
property string textFormattingDescription: qsTr("Enter or Shift+Enter to insert a new line")
property string textFormatting: qsTr("Text formatting")
//Connection monitoring
property string connected: qsTr("Connected")
property string connectingTLS: qsTr("Connecting TLS")
property string connectingICE: qsTr("Connecting ICE")
property string connecting: qsTr("Connecting")
property string waiting: qsTr("Waiting")
property string contact: qsTr("Contact")
property string connection: qsTr("Connection")
property string channels: qsTr("Channels")
property string copyAllData: qsTr("Copy all data")
property string remote: qsTr("Remote: ")
property string view: qsTr("View")
}

View File

@ -76,7 +76,7 @@ Item {
property color greyBorderColor: "#333"
property color selectionBlue: darkTheme ? "#0061a5" : "#109ede"
property color hoverColor: darkTheme ? "#4d4d4d" : "#c7c7c7"
property color hoverColor: darkTheme ? "#4d4d4d" : "#DEDEDE"
property color pressColor: darkTheme ? "#777" : "#c0c0c0"
property color selectedColor: darkTheme ? "#0e81c5" : "#e0e0e0"
property color smartListHoveredColor: darkTheme ? "#4d4d4d" : "#dedede"
@ -367,9 +367,9 @@ Item {
property int avatarReadReceiptSize: 18
property int menuItemsPreferredWidth: 220
property int menuItemsPreferredHeight: 48
property int menuItemsPreferredHeight: 36
property int menuItemsCommonBorderWidth: 1
property int menuBorderPreferredHeight: 8
property int menuBorderPreferredHeight: 5
property real maximumWidthSettingsView: 516
property real settingsHeaderpreferredHeight: 64
@ -492,6 +492,7 @@ Item {
// MessageBar
property int messageBarMarginSize: 10
property int messageBarMinimumWidth: 438
// InvitationView
property real invitationViewAvatarSize: 112
@ -532,6 +533,7 @@ Item {
// WizardView Welcome Page
property real welcomeLabelPointSize: 30
property var welcomeLogo: darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
property real welcomeLogoWidth: 100
property real welcomeLogoHeight: 100
property real wizardButtonWidth: 400
@ -541,9 +543,9 @@ Item {
property real welcomeRectTopMargin: 90
property real welcomePageSpacing: 13
property real welcomeGridWidth: 3 * JamiTheme.tipBoxWidth + 2 * JamiTheme.welcomePageSpacing
property real welcomeHalfGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 2
property real welcomeThirdGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 3
property real welcomeShortGridWidth: 2 * JamiTheme.tipBoxWidth + JamiTheme.welcomePageSpacing
readonly property string welcomeBg: darkTheme ? JamiResources.bg_darkmode_id_jami_png : JamiResources.bg_lightmode_id_jami_png
readonly property string welcomeBg: darkTheme ? JamiResources.background_don_dark_jpg : JamiResources.background_don_white_jpg
property color welcomeBlockColor: darkTheme ? "#4D000000" : "#4DFFFFFF"
// WizardView Advanced Account Settings
@ -643,6 +645,9 @@ Item {
property int settingsMenuHeaderButtonHeight: 50
property int settingsListViewsSpacing: 10
// Link Device
property color pinBackgroundColor: "#D6E4EF"
// MaterialRadioButton
property int radioImageSize: 30
property color radioBackgroundColor: darkTheme ? "#303030" : "#F0EFEF"
@ -654,7 +659,22 @@ Item {
property color darkThemeCheckedColor: "#03B9E9"
property color darkThemeBorderColor: "#03B9E9"
// Donation campaign
property color donationButtonTextColor: "#005699"
property color donationBackgroundColor: "#D5E4EF"
property string donationUrl: "https://jami.net/donate/"
//Connection monitoring
property color connectionMonitoringTableColor1: "#f0efef"
property color connectionMonitoringTableColor2: "#f6f5f5"
property color connectionMonitoringHeaderColor: "#d1d1d1"
function setTheme(dark) {
darkTheme = dark;
}
//Chat setting page
property color chatSettingButtonBackgroundColor: darkTheme ? "#303030" : "#F0EFEF"
property color chatSettingButtonBorderColor: darkTheme ? "#03B9E9" : "#005699"
property color chatSettingButtonTextColor: textColor
}

View File

@ -21,10 +21,16 @@
#include "contactadapter.h"
#include "lrcinstance.h"
#include "qmlregister.h"
ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
: QmlAdapterBase(instance, parent)
, connectionInfoListModel_(new ConnectionInfoListModel(lrcInstance_, this))
{
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS,
connectionInfoListModel_.get(),
"ConnectionInfoListModel");
selectableProxyModel_.reset(new SelectableProxyModel(this));
if (lrcInstance_) {
connectSignals();
@ -246,6 +252,12 @@ ContactAdapter::removeContact(const QString& peerUri, bool banContact)
accInfo.contactModel->removeContact(peerUri, banContact);
}
void
ContactAdapter::updateConnectionInfo()
{
connectionInfoListModel_->update();
}
void
ContactAdapter::connectSignals()
{

View File

@ -21,6 +21,7 @@
#include "qmladapterbase.h"
#include "smartlistmodel.h"
#include "conversationlistmodel.h"
#include "connectioninfolistmodel.h"
#include <QObject>
#include <QSortFilterProxyModel>
@ -90,6 +91,7 @@ public:
Q_INVOKABLE void setSearchFilter(const QString& filter);
Q_INVOKABLE void contactSelected(int index);
Q_INVOKABLE void removeContact(const QString& peerUri, bool banContact);
Q_INVOKABLE void updateConnectionInfo();
void connectSignals();
@ -104,6 +106,7 @@ private:
SmartListModel::Type listModeltype_;
QScopedPointer<SmartListModel> smartListModel_;
QScopedPointer<SelectableProxyModel> selectableProxyModel_;
QScopedPointer<ConnectionInfoListModel> connectionInfoListModel_;
QStringList defaultModerators_;

View File

@ -458,3 +458,15 @@ LRCInstance::set_selectedConvUid(QString selectedConvUid)
Q_EMIT selectedConvUidChanged();
}
}
VectorMapStringString
LRCInstance::getConnectionList(const QString& accountId, const QString& uid)
{
return Lrc::getConnectionList(accountId, uid);
}
VectorMapStringString
LRCInstance::getChannelList(const QString& accountId, const QString& uid)
{
return Lrc::getChannelList(accountId, uid);
}

View File

@ -135,6 +135,10 @@ public:
return debugMode_;
}
VectorMapStringString getConnectionList(const QString& accountId, const QString& uid = {});
VectorMapStringString getChannelList(const QString& accountId, const QString& uid = {});
Q_SIGNALS:
void accountListChanged();
void selectedConvUidChanged();

View File

@ -105,7 +105,7 @@ ScreenInfo::onPhysicalDotsPerInchChanged()
}
MainApplication::MainApplication(int& argc, char** argv)
: QApplication(argc, argv)
: QApplication(argc, argv), isCleanupped(false)
{
const char* qtVersion = qVersion();
qInfo() << "Using Qt runtime version:" << qtVersion;
@ -231,7 +231,6 @@ MainApplication::initLrc(const QString& downloadUrl,
bool debugMode,
bool muteDaemon)
{
lrc::api::Lrc::cacheAvatars.store(false);
/*
* Init mainwindow and finish splash when mainwindow shows up.
*/
@ -402,7 +401,12 @@ MainApplication::initSystray()
void
MainApplication::cleanup()
{
QApplication::exit(0);
// In Qt 6.5, QApplication::exit(0) will signal aboutToQuit, and aboutToQuit is connected to cleanup
// TODO: delete cleanup.
if (!isCleanupped) {
isCleanupped = true;
QApplication::exit(0);
}
}
#ifdef Q_OS_MACOS

View File

@ -121,4 +121,6 @@ private:
QScopedPointer<ImageDownloader> imageDownloader_;
ScreenInfo screenInfo_;
bool isCleanupped;
};

View File

@ -26,191 +26,169 @@ import "../../commoncomponents"
BaseModalDialog {
id: root
width: Math.min(parent.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.secondaryDialogDimension)
height: Math.min(parent.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.secondaryDialogDimension)
popupContentMargins: 14
PushButton {
id: btnClose
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: JamiTheme.preferredMarginSize
anchors.rightMargin: JamiTheme.preferredMarginSize
imageColor: "grey"
normalColor: JamiTheme.transparentColor
source: JamiResources.round_close_24dp_svg
onClicked: {
close();
}
}
margins: JamiTheme.preferredMarginSize
popupContent: JamiFlickable {
id: aboutPopUpScrollView
id: aboutPopUpScrollView
width: aboutPopUpContentRectColumnLayout.implicitWidth
height: JamiTheme.preferredDialogHeight
width: root.width
contentHeight: aboutPopUpContentRectColumnLayout.implicitHeight
contentHeight: aboutPopUpContentRectColumnLayout.implicitHeight
ColumnLayout {
id: aboutPopUpContentRectColumnLayout
ColumnLayout {
id: aboutPopUpContentRectColumnLayout
anchors.centerIn: parent
width: root.width
ResponsiveImage {
id: aboutPopUPJamiLogoImage
ResponsiveImage {
id: aboutPopUPJamiLogoImage
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: JamiTheme.aboutLogoPreferredWidth
Layout.preferredHeight: JamiTheme.aboutLogoPreferredHeight
Layout.alignment: Qt.AlignCenter
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.preferredWidth: JamiTheme.aboutLogoPreferredWidth
Layout.preferredHeight: JamiTheme.aboutLogoPreferredHeight
source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
}
TextEdit {
id: jamiSlogansText
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: aboutPopUpScrollView.width
Layout.topMargin: 26
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.bigFontSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: textMetricsjamiSlogansText.text
selectByMouse: true
readOnly: true
color: JamiTheme.tintedBlue
TextMetrics {
id: textMetricsjamiSlogansText
font: jamiSlogansText.font
text: JamiStrings.slogan
}
}
TextEdit {
id: jamiVersionText
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: aboutPopUpScrollView.width
font.pixelSize: JamiTheme.tinyCreditsTextSize
padding: 0
text: JamiStrings.version + ": " + UtilsAdapter.getVersionStr()
selectByMouse: true
readOnly: true
color: JamiTheme.textColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
TextEdit {
id: jamiDeclarationText
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: aboutPopUpScrollView.width - JamiTheme.preferredMarginSize * 2
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.creditsTextSize
color: JamiTheme.textColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// TextMetrics does not work for multi-line.
text: JamiStrings.declaration
selectByMouse: true
readOnly: true
}
TextEdit {
id: jamiDeclarationHyperText
Layout.alignment: Qt.AlignCenter
// Strangely, hoveredLink works badly when width grows too large
Layout.preferredWidth: 50
Layout.topMargin: 15
color: JamiTheme.textColor
font.pixelSize: JamiTheme.creditsTextSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: textMetricsjamiDeclarationHyperText.text
textFormat: TextEdit.RichText
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
TextMetrics {
id: textMetricsjamiDeclarationHyperText
font: jamiDeclarationHyperText.font
text: '<a href="https://jami.net" style="color: ' + JamiTheme.blueLinkColor + '">jami.net</a>'
source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
}
MouseArea {
anchors.fill: parent
TextEdit {
id: jamiSlogansText
// We don't want to eat clicks on the Text.
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 26
TextEdit {
id: jamiNoneWarrantyHyperText
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.bigFontSize
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: Math.min(390, root.width)
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.tinyCreditsTextSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignTop
color: JamiTheme.textColor
text: textMetricsjamiSlogansText.text
selectByMouse: true
readOnly: true
color: JamiTheme.tintedBlue
text: textMetricsjamiNoneWarrantyHyperText.text
textFormat: TextEdit.RichText
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
TextMetrics {
id: textMetricsjamiNoneWarrantyHyperText
font: jamiDeclarationHyperText.font
text: JamiStrings.declarationYear + " " + '<a href="https://savoirfairelinux.com" style="color: ' + JamiTheme.blueLinkColor + '">Savoir-faire Linux Inc.</a><br>' + 'This program comes with absolutely no warranty. See the <a href="http://www.gnu.org/licenses/gpl-3.0.html" style="color: ' + JamiTheme.blueLinkColor + '">GNU General Public License</a>, version 3 or later for details.'
TextMetrics {
id: textMetricsjamiSlogansText
font: jamiSlogansText.font
text: JamiStrings.slogan
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
TextEdit {
id: jamiVersionText
ProjectCreditsScrollView {
id: projectCreditsScrollView
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: aboutPopUpScrollView.width - JamiTheme.preferredMarginSize * 2
Layout.preferredHeight: 100
Layout.topMargin: 25
Layout.margins: JamiTheme.preferredMarginSize
}
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
font.pixelSize: JamiTheme.tinyCreditsTextSize
padding: 0
text: JamiStrings.version + ": " + UtilsAdapter.getVersionStr()
selectByMouse: true
readOnly: true
color: JamiTheme.textColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
TextEdit {
id: jamiDeclarationText
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.creditsTextSize
color: JamiTheme.textColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// TextMetrics does not work for multi-line.
text: JamiStrings.declaration
selectByMouse: true
readOnly: true
}
TextEdit {
id: jamiDeclarationHyperText
Layout.alignment: Qt.AlignCenter
// Strangely, hoveredLink works badly when width grows too large
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 15
color: JamiTheme.textColor
font.pixelSize: JamiTheme.creditsTextSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: textMetricsjamiDeclarationHyperText.text
textFormat: TextEdit.RichText
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
TextMetrics {
id: textMetricsjamiDeclarationHyperText
font: jamiDeclarationHyperText.font
text: '<a href="https://jami.net" style="color: ' + JamiTheme.blueLinkColor + '">jami.net</a>'
}
MouseArea {
anchors.fill: parent
// We don't want to eat clicks on the Text.
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
TextEdit {
id: jamiNoneWarrantyHyperText
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.tinyCreditsTextSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignTop
color: JamiTheme.textColor
text: textMetricsjamiNoneWarrantyHyperText.text
textFormat: TextEdit.RichText
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
TextMetrics {
id: textMetricsjamiNoneWarrantyHyperText
font: jamiDeclarationHyperText.font
text: JamiStrings.declarationYear + " " + '<a href="https://savoirfairelinux.com" style="color: ' + JamiTheme.blueLinkColor + '">Savoir-faire Linux Inc.</a><br>' + 'This program comes with absolutely no warranty. See the <a href="http://www.gnu.org/licenses/gpl-3.0.html" style="color: ' + JamiTheme.blueLinkColor + '">GNU General Public License</a>, version 3 or later for details.'
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
ProjectCreditsScrollView {
id: projectCreditsScrollView
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.preferredHeight: 100
Layout.topMargin: 25
Layout.margins: JamiTheme.preferredMarginSize
}
}
}
}

View File

@ -203,61 +203,70 @@ ItemDelegate {
anchors.fill: parent
color: menuItem.down ? "#c4aaaaaa" : menuItem.hovered ? "#c4777777" : "transparent"
}
contentItem: ColumnLayout {
// After update to qt 6.4.3 the layout was broken, adding a Rectangle
// as top level in the contentIntem is a workaround which removal can be
// tested with newer qt versions
contentItem: Rectangle {
anchors.fill: parent
spacing: 0
RowLayout {
Layout.fillWidth: true
Layout.rightMargin: 15
Layout.leftMargin: 20
Layout.fillHeight: true
Layout.alignment: {
if (menuAction.popupMode !== CallActionBar.ActionPopupMode.LayoutOption || TopMargin && BottomMargin) {
return Qt.AlignLeft | Qt.AlignVCenter;
}
if (TopMargin) {
Layout.bottomMargin = 4;
return Qt.AlignBottom;
}
Layout.topMargin = 4;
return Qt.AlignTop;
}
color: "transparent"
ColumnLayout {
anchors.fill: parent
spacing: 0
spacing: 6
ResponsiveImage {
source: menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement || menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? IconSource : (menuItem.ListView.isCurrentItem ? JamiResources.check_box_24dp_svg : JamiResources.check_box_outline_blank_24dp_svg)
color: "white"
width: 20
height: 20
}
Text {
id: delegateText
RowLayout {
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement || menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? Name : DeviceName
elide: Text.ElideRight
font.pointSize: JamiTheme.participantFontSize
color: "white"
Layout.fillHeight: true
Layout.rightMargin: 15
Layout.leftMargin: 20
Layout.alignment: {
if (menuAction.popupMode !== CallActionBar.ActionPopupMode.LayoutOption || TopMargin && BottomMargin) {
return Qt.AlignLeft | Qt.AlignVCenter;
}
if (TopMargin) {
Layout.bottomMargin = 4;
return Qt.AlignBottom;
}
Layout.topMargin = 4;
return Qt.AlignTop;
}
spacing: 6
ResponsiveImage {
source: menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement || menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? IconSource : (menuItem.ListView.isCurrentItem ? JamiResources.check_box_24dp_svg : JamiResources.check_box_outline_blank_24dp_svg)
color: "white"
width: 20
height: 20
}
Text {
id: delegateText
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement || menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? Name : DeviceName
elide: Text.ElideRight
font.pointSize: JamiTheme.participantFontSize
color: "white"
}
ResponsiveImage {
source: JamiResources.check_black_24dp_svg
color: "white"
width: 20
height: 20
visible: menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? ActiveSetting : false
}
}
ResponsiveImage {
source: JamiResources.check_black_24dp_svg
color: "white"
width: 20
height: 20
visible: menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? ActiveSetting : false
Rectangle {
id: buttonDiv
visible: menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? SectionEnd : false
Layout.fillWidth: true
height: 1
opacity: 0.2
border.width: 0
color: JamiTheme.separationLine
Layout.alignment: Qt.AlignBottom
}
}
Rectangle {
id: buttonDiv
visible: menuAction.popupMode === CallActionBar.ActionPopupMode.LayoutOption ? SectionEnd : false
Layout.fillWidth: true
height: 1
opacity: 0.2
border.width: 0
color: JamiTheme.separationLine
Layout.alignment: Qt.AlignBottom
}
}
}

View File

@ -106,13 +106,18 @@ Popup {
height: Top || Bottom ? 10 : 45
background: Rectangle {
radius: 5
visible: !Top && !Bottom
anchors.fill: parent
anchors.leftMargin: 5
anchors.rightMargin: 5
color: menuItem.down ? "#c4aaaaaa" : menuItem.hovered ? "#c4777777" : "transparent"
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 5
anchors.rightMargin: 5
visible: !Top && !Bottom
ResponsiveImage {
Layout.leftMargin: JamiTheme.preferredMarginSize

View File

@ -169,12 +169,6 @@ Rectangle {
}
}
GenericErrorsRow {
id: genericError
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.chatViewHeaderPreferredHeight
}
ConversationErrorsRow {
id: errorRect
Layout.fillWidth: true

View File

@ -79,6 +79,8 @@ Rectangle {
var editedMessageBody = MessagesAdapter.dataForInteraction(MessagesAdapter.editId, MessageList.Body);
messageBar.textAreaObj.insertText(editedMessageBody);
messageBar.textAreaObj.forceActiveFocus();
} else {
messageBar.textAreaObj.clearText();
}
}
@ -115,7 +117,6 @@ Rectangle {
EditContainer {
id: editContainer
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: footerColumnLayout.width
Layout.maximumWidth: JamiTheme.chatViewMaximumWidth
@ -129,7 +130,7 @@ Rectangle {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: footerColumnLayout.width
Layout.leftMargin: marginSize
Layout.leftMargin: 0
Layout.rightMargin: marginSize
Layout.bottomMargin: marginSize
Layout.preferredHeight: height

View File

@ -86,8 +86,7 @@ Rectangle {
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 8
preferredSize: 24
//preferredSize: 24
mirror: UtilsAdapter.isRTL
source: JamiResources.back_24dp_svg
@ -155,12 +154,12 @@ Rectangle {
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.preferredHeight: 30
Layout.preferredWidth: 40 + (isOpen? JamiTheme.searchbarSize : 0)
Layout.preferredWidth: 40 + (isOpen ? JamiTheme.searchbarSize : 0)
colorSearchBar: JamiTheme.backgroundColor
hoverButtonRadius: JamiTheme.chatViewHeaderButtonRadius
Behavior on Layout.preferredWidth {
Behavior on Layout.preferredWidth {
NumberAnimation {
duration: 150
}
@ -168,7 +167,7 @@ Rectangle {
visible: root.swarmDetailsVisibility
onSearchBarTextChanged: function(text){
onSearchBarTextChanged: function (text) {
MessagesAdapter.searchbarPrompt = text;
}

View File

@ -28,11 +28,6 @@ BaseModalDialog {
property int type: ContactList.CONFERENCE
width: Math.min(appWindow.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogWidth)
height: Math.min(appWindow.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.preferredDialogHeight)
padding: 0
title: {
switch (type) {
case ContactList.CONFERENCE:
@ -48,6 +43,8 @@ BaseModalDialog {
popupContent: ColumnLayout {
id: contactPickerPopupRectColumnLayout
anchors.centerIn: parent
width: 400
Searchbar {
id: contactPickerContactSearchBar
@ -81,8 +78,4 @@ BaseModalDialog {
}
}
}
onAboutToShow: {
contactPickerListView.model = ContactAdapter.getContactSelectableModel(type);
}
}

View File

@ -104,7 +104,6 @@ ContextMenuAutoLoader {
canTrigger: hasCall
itemName: JamiStrings.endCall
iconSource: JamiResources.ic_call_end_white_24dp_svg
addMenuSeparatorAfter: contactType !== Profile.Type.SIP && (contactType === Profile.Type.PENDING || !hasCall)
onClicked: CallAdapter.hangUpACall(responsibleAccountId, responsibleConvUid)
},
GeneralMenuItem {
@ -129,7 +128,6 @@ ContextMenuAutoLoader {
canTrigger: !hasCall && contactType !== Profile.Type.SIP && !root.isBanned && isCoreDialog && root.idText !== CurrentAccount.uri
itemName: JamiStrings.blockContact
iconSource: JamiResources.block_black_24dp_svg
addMenuSeparatorAfter: canTrigger
onClicked: {
var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", {
"title": JamiStrings.confirmAction,
@ -147,7 +145,6 @@ ContextMenuAutoLoader {
canTrigger: root.isBanned
itemName: JamiStrings.reinstateContact
iconSource: JamiResources.round_remove_circle_24dp_svg
addMenuSeparatorAfter: canTrigger
onClicked: MessagesAdapter.unbanConversation(responsibleConvUid)
},
GeneralMenuItem {

View File

@ -27,44 +27,26 @@ import "../../commoncomponents"
BaseModalDialog {
id: root
width: 488
height: 320
width: JamiTheme.secondaryDialogDimension
popupContent: Rectangle {
id: rect
title: JamiStrings.defaultCallHost
color: JamiTheme.transparentColor
width: root.width
PushButton {
id: btnCancel
imageColor: "grey"
normalColor: "transparent"
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 10
anchors.rightMargin: 10
source: JamiResources.round_close_24dp_svg
onClicked: {
close();
}
}
ColumnLayout {
popupContent: ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.centerIn: parent
anchors.margins: JamiTheme.preferredMarginSize
spacing: JamiTheme.preferredMarginSize
Label {
id: informativeLabel
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Layout.topMargin: 26
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
wrapMode: Text.Wrap
text: JamiStrings.chooseHoster
color: JamiTheme.primaryForegroundColor
}
@ -97,7 +79,7 @@ BaseModalDialog {
property bool isCurrent: DeviceName
implicitWidth: devicesListView.width
width: devicesListView.width
width: root.width - 4*JamiTheme.preferredMarginSize
height: 70
highlighted: ListView.isCurrentItem
@ -136,7 +118,6 @@ BaseModalDialog {
ColumnLayout {
id: deviceInfoColumnLayout
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: JamiTheme.preferredMarginSize
@ -144,7 +125,6 @@ BaseModalDialog {
id: labelDeviceName
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.fillWidth: true
elide: Text.ElideRight
color: JamiTheme.textColor
@ -155,7 +135,7 @@ BaseModalDialog {
id: labelDeviceId
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.fillWidth: true
Layout.preferredWidth: root.width - 200
elide: Text.ElideRight
color: JamiTheme.textColor
@ -175,9 +155,10 @@ BaseModalDialog {
}
}
RowLayout {
ColumnLayout {
id: buttonLayout
spacing: JamiTheme.preferredMarginSize
Layout.preferredWidth: parent.width
Layout.preferredWidth: root.width - 240
MaterialButton {
id: chooseBtn
@ -192,8 +173,8 @@ BaseModalDialog {
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
primary: true
preferredWidth: chooseBtnTextSize.width + 2 * JamiTheme.buttontextWizzardPadding
enabled: devicesListView.currentItem
text: JamiStrings.chooseThisDevice
@ -220,7 +201,6 @@ BaseModalDialog {
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
primary: true
preferredWidth: rmDeviceBtnTextSize.width + 2 * JamiTheme.buttontextWizzardPadding
enabled: devicesListView.currentItem
text: JamiStrings.removeCurrentDevice
@ -235,4 +215,4 @@ BaseModalDialog {
}
}
}
}

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import net.jami.Enums 1.1
import net.jami.Models 1.1
import "../../commoncomponents"
import "../../settingsview/components"
Rectangle {
id: donation
property bool donationVisible: JamiQmlUtils.isDonationBannerVisible()
width: parent.width - 30
height: donationTextRect.height + 45 > donationIcon.height + 20 ? donationTextRect.height + 45 : donationIcon.height + 20
radius: 5
color: JamiTheme.donationBackgroundColor
GridLayout {
id: donationLayout
anchors.fill: parent
columns: 3
rows: 2
rowSpacing: 0
columnSpacing: 10
Rectangle {
id: donationIcon
Layout.row: 0
Layout.column: 0
Layout.rowSpan: 2
Layout.preferredHeight: 70
Layout.preferredWidth: 45
Layout.leftMargin: 10
Layout.topMargin: 10
Layout.bottomMargin: 15
color: JamiTheme.transparentColor
Image {
id: donationImage
height: parent.height
width: 50
anchors.centerIn: parent
source: JamiResources.icon_donate_svg
}
}
Rectangle {
id: donationTextRect
Layout.topMargin: 10
Layout.row: 0
Layout.column: 1
Layout.columnSpan: 2
Layout.preferredHeight: donationText.height
Layout.preferredWidth: parent.width - 74
Layout.bottomMargin: 5
color: JamiTheme.transparentColor
Text {
id: donationText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: parent.width
height: contentHeight
text: JamiStrings.donationText
wrapMode: Text.WordWrap
font.pointSize: JamiTheme.textFontSize
}
}
Rectangle {
id: notNowRect
Layout.row: 1
Layout.column: 1
Layout.preferredHeight: 30
Layout.preferredWidth: (parent.width - 55) / 2
color: JamiTheme.transparentColor
Text {
id: notNowText
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
// When the user clicks on "Not now", we set the donation date to 7 days from now (1 for the test)
UtilsAdapter.setAppValue(Settings.Key.DonationVisibleDate, new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
donation.donationVisible = Qt.binding(() => JamiQmlUtils.isDonationBannerVisible());
}
}
text: JamiStrings.notNow
color: JamiTheme.donationButtonTextColor
anchors.top: parent.top
anchors.left: parent.left
font.pointSize: JamiTheme.textFontSize
}
}
Rectangle {
id: donateRect
Layout.row: 1
Layout.column: 2
Layout.preferredHeight: 30
Layout.preferredWidth: (parent.width - 50) / 2
color: JamiTheme.transparentColor
Text {
id: donateText
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
Qt.openUrlExternally(JamiTheme.donationUrl);
}
}
text: JamiStrings.donation
font.pointSize: JamiTheme.textFontSize
color: JamiTheme.donationButtonTextColor
anchors.top: parent.top
anchors.left: parent.left
}
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2023 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/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
Item {
id: root
focus: true
width: parent.width
height: backupLayout.height
property real iconSize: 26
property real margin: 5
property real preferredWidth: 170
property real maxHeight: 250
property color textColor: JamiTheme.textColor
property color iconColor: JamiTheme.tintedBlue
ColumnLayout {
id: backupLayout
anchors.top: parent.top
width: parent.width
RowLayout {
id: rowlayout
Layout.leftMargin: 15
Layout.alignment: Qt.AlignLeft
ResponsiveImage {
id: icon
visible: !opened
Layout.alignment: Qt.AlignLeft
Layout.topMargin: root.margin
Layout.preferredWidth: root.iconSize
Layout.preferredHeight: root.iconSize
containerHeight: Layout.preferredHeight
containerWidth: Layout.preferredWidth
color: JamiTheme.tintedBlue
source: JamiResources.favorite_black_24dp_svg
}
Text {
id: title
text: JamiStrings.donation
color: root.textColor
font.weight: Font.Medium
Layout.topMargin: root.margin
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: root.margin
Layout.preferredWidth: root.preferredWidth - 2 * root.margin - root.iconSize
font.pixelSize: JamiTheme.tipBoxTitleFontSize
horizontalAlignment: Text.AlignLeft
elide: Qt.ElideRight
}
}
Text {
id: content
Layout.preferredWidth: root.preferredWidth
focus: true
Layout.leftMargin: 20
Layout.topMargin: 8
Layout.bottomMargin: 8
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: true
wrapMode: Text.WordWrap
font.weight: Font.Normal
text: JamiStrings.donationTipBoxText
color: root.textColor
horizontalAlignment: Text.AlignLeft
linkColor: JamiTheme.buttonTintedBlue
onLinkActivated: {
Qt.openUrlExternally(JamiTheme.donationUrl);
}
}
}
}

View File

@ -31,7 +31,11 @@ Rectangle {
property alias text: errorLabel.text
color: JamiTheme.filterBadgeColor
visible: CurrentAccount.status === Account.Status.UNREGISTERED
visible: CurrentAccount.id !== ""
&& CurrentAccount.status !== Account.Status.REGISTERED
&& CurrentAccount.status !== Account.Status.READY
&& CurrentAccount.status !== Account.Status.TRYING
&& CurrentAccount.status !== Account.Status.INITIALIZING
RowLayout {
anchors.fill: parent
@ -41,7 +45,6 @@ Rectangle {
id: errorLabel
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
text: CurrentAccount.enabled ? JamiStrings.noNetworkConnectivity : JamiStrings.disabledAccount
color: JamiTheme.filterBadgeTextColor
font.pixelSize: JamiTheme.headerFontSize
elide: Text.ElideRight

View File

@ -26,45 +26,21 @@ import "../../commoncomponents"
BaseModalDialog {
id: root
width: 488
height: 256
property bool isAdmin: {
var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, CurrentAccount.uri);
return role === Member.Role.ADMIN;
}
popupContent: Rectangle {
id: rect
color: JamiTheme.transparentColor
width: root.width
PushButton {
id: btnCancel
imageColor: "grey"
normalColor: "transparent"
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 10
anchors.rightMargin: 10
source: JamiResources.round_close_24dp_svg
onClicked: {
close();
}
}
ColumnLayout {
popupContent: ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.margins: JamiTheme.preferredMarginSize
spacing: JamiTheme.preferredMarginSize
Label {
id: informativeLabel
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Layout.topMargin: 26
Layout.maximumWidth: root.parent.width - 4*JamiTheme.preferredMarginSize
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@ -77,7 +53,7 @@ BaseModalDialog {
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 26
Layout.margins: JamiTheme.preferredMarginSize
text: isAdmin ? JamiStrings.becomeHostOneCall : JamiStrings.hostThisCall
onClicked: {
@ -90,6 +66,7 @@ BaseModalDialog {
id: becomeDefaultHostBtn
Layout.alignment: Qt.AlignCenter
Layout.margins: JamiTheme.preferredMarginSize
text: JamiStrings.becomeDefaultHost
toolTipText: JamiStrings.becomeDefaultHost
@ -105,4 +82,4 @@ BaseModalDialog {
}
}
}
}
//}

View File

@ -170,7 +170,7 @@ Window {
description: qsTr("Stop camera")
}
ListElement {
shortcut: "Ctrl"
shortcut: "Ctrl + Mouse middle click"
description: qsTr("Take tile screenshot")
}
},

View File

@ -54,12 +54,14 @@ RowLayout {
height: showTypo || multiLine ? messageBarTextArea.height + 25 + 3 * marginSize + 1 : textAreaObj.height + marginSize + 1
Rectangle {
Layout.preferredHeight: parent.height
Layout.preferredWidth: childrenRect.width
visible: !CurrentConversation.isSip
color: JamiTheme.transparentColor
ComboBox {
id: showMoreButton
focus: true
width: JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
anchors.bottom: parent.bottom
@ -95,6 +97,7 @@ RowLayout {
}
onHoveredChanged: {
console.log("Hovered changed");
if (!sharePopup.opened) {
showMoreButton.indicator.color = hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor;
showMoreButton.background.color = hovered ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor;
@ -103,18 +106,24 @@ RowLayout {
}
onPressedChanged: {
console.log("Pressed changed");
if (sharePopup.enabled)
sharePopup.close();
}
popup: SharePopup {
popup: ShareMenu {
id: sharePopup
y: -180
x: -20
menuMoreButton: listViewMoreButton.menuMoreButton
onClosed: messageBar.textAreaObj.forceActiveFocus()
onAudioRecordMessageButtonClicked: {
root.audioRecordMessageButtonClicked();
}
onVideoRecordMessageButtonClicked: {
root.videoRecordMessageButtonClicked();
}
onShowMapClicked: {
root.showMapClicked();
}
modelList: listViewMoreButton.menuMoreButton
y: -140
}
}
}
@ -132,8 +141,6 @@ RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.rightMargin: marginSize
Layout.leftMargin: marginSize
radius: 5
color: JamiTheme.transparentColor
@ -142,12 +149,10 @@ RowLayout {
onWidthChanged: {
height = Qt.binding(() => root.height);
if (width < 468) {
if (width < JamiTheme.messageBarMinimumWidth) {
showTypoSecond = false;
} else {
if (width >= 468) {
showTypoSecond = true;
}
showTypoSecond = true;
}
}
@ -190,8 +195,12 @@ RowLayout {
onSendMessagesRequired: {
sendMessageButtonClicked();
}
onTextChanged: MessagesAdapter.userIsComposing(text ? true : false)
onTextChanged: {
MessagesAdapter.userIsComposing(text ? true : false);
if (!text) {
messageBarTextArea.heightBinding();
}
}
property var markdownShortCut: {
"Bold": function () {
if (!showPreview) {
@ -215,32 +224,32 @@ RowLayout {
},
"Link": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(0).action.triggered();
listViewTypoFirst.itemAtIndex(4).action.triggered();
}
},
"Code": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(1).action.triggered();
listViewTypoFirst.itemAtIndex(5).action.triggered();
}
},
"Quote": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(2).action.triggered();
listViewTypoSecond.itemAtIndex(0).action.triggered();
}
},
"Unordered list": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(3).action.triggered();
listViewTypoSecond.itemAtIndex(1).action.triggered();
}
},
"Ordered list": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(4).action.triggered();
listViewTypoSecond.itemAtIndex(2).action.triggered();
}
},
"Enter is new line": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(5).action.triggered();
listViewTypoSecond.itemAtIndex(3).action.triggered();
}
}
}
@ -304,6 +313,8 @@ RowLayout {
context: Qt.ApplicationShortcut
onActivated: {
showTypo = !showTypo;
messageBarTextArea.isShowTypo = showTypo;
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
}
}
@ -667,11 +678,11 @@ RowLayout {
normalColor: {
if (showPreview) {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
} else if (modelData.isStyle) {
return JamiTheme.hoveredButtonColor;
} else {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
}
}
imageColor: {
@ -694,7 +705,7 @@ RowLayout {
Rectangle {
height: JamiTheme.chatViewFooterButtonSize
color: JamiTheme.transparentColor
color: JamiTheme.primaryBackgroundColor
visible: showTypo && showTypoSecond
width: 2
@ -709,7 +720,7 @@ RowLayout {
Rectangle {
z: -1
radius: 0
color: JamiTheme.transparentColor
color: JamiTheme.primaryBackgroundColor
width: JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
@ -758,7 +769,7 @@ RowLayout {
id: markdownPopup
y: 1.5 * parent.height
x: -parent.width * 2
width: 155
width: 105
height: JamiTheme.chatViewFooterButtonSize
menuTypoActionsSecond: listViewTypoSecond.menuTypoActionsSecond
@ -814,20 +825,6 @@ RowLayout {
onTriggered: function clickAction() {
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true);
}
},
Action {
id: shiftEnterActiom
property var iconSrc: JamiResources.shift_enter_black_24dp_svg
property var shortcutText: chatViewEnterIsNewLine ? JamiStrings.enterNewLine : JamiStrings.shiftEnterNewLine
property var imageColor: chatViewEnterIsNewLine ? JamiTheme.chatViewFooterImgHoverColor : "#7f7f7f"
property var normalColor: chatViewEnterIsNewLine ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor
property var hasShortcut: false
property var shortcutKey: null
property bool isStyle: false
onTriggered: function clickAction() {
root.chatViewEnterIsNewLine = !root.chatViewEnterIsNewLine;
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, chatViewEnterIsNewLine);
}
}
]
@ -851,13 +848,13 @@ RowLayout {
normalColor: {
if (showPreview) {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
} else if (modelData.normalColor != null) {
return modelData.normalColor;
} else if (modelData.isStyle) {
return JamiTheme.hoveredButtonColor;
} else {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
}
}
imageColor: {
@ -896,24 +893,18 @@ RowLayout {
toolTipText: showTypo ? JamiStrings.hideFormatting : JamiStrings.showFormatting
source: JamiResources.text_edit_black_24dp_svg
normalColor: showPreview ? JamiTheme.transparentColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor)
normalColor: showPreview ? JamiTheme.primaryBackgroundColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor)
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered || showTypo ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
onClicked: {
showTypo = !showTypo;
messageBarTextArea.isShowTypo = showTypo;
if (messageBar.width < messageBarLayoutMaximumWidth + sendMessageButton.width + 2 * JamiTheme.preferredMarginSize)
showTypoSecond = false;
if (!showDefault)
showDefault = true;
if (showTypo) {
root.chatViewEnterIsNewLine = true;
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, true);
} else {
root.chatViewEnterIsNewLine = false;
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, false);
}
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
UtilsAdapter.setAppValue(Settings.Key.ShowSendOption, !showDefault);
}
@ -1018,7 +1009,7 @@ RowLayout {
toolTipText: modelData.toolTip
source: modelData.iconSrc
normalColor: JamiTheme.transparentColor
normalColor: JamiTheme.primaryBackgroundColor
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
@ -1157,10 +1148,11 @@ RowLayout {
imageContainerHeight: 25
radius: 5
source: JamiResources.preview_black_24dp_svg
normalColor: showPreview ? hoveredColor : JamiTheme.transparentColor
normalColor: showPreview ? hoveredColor : JamiTheme.primaryBackgroundColor
imageColor: (hovered || showPreview) ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
toolTipText: showPreview ? JamiStrings.continueEditing : JamiStrings.showPreview
onClicked: {
showPreview = !showPreview;

View File

@ -41,6 +41,7 @@ JamiFlickable {
property alias selectionStart: textArea.selectionStart
property alias selectionEnd: textArea.selectionEnd
property bool showPreview: false
property bool isShowTypo: UtilsAdapter.getAppValue(Settings.Key.ShowMardownOption)
ScrollBar.vertical.visible: textArea.text
ScrollBar.horizontal.visible: textArea.text
@ -48,7 +49,7 @@ JamiFlickable {
signal sendMessagesRequired
function heightBinding() {
textArea.height = Qt.binding(() => textArea.paintedHeight);
textArea.height = Qt.binding(() => textArea.lineCount === 1 ? 35 : textArea.paintedHeight);
}
function selectText(start, end) {
@ -60,7 +61,11 @@ JamiFlickable {
}
function clearText() {
var multiLine = textArea.lineCount !== 1;
textArea.clear();
if (multiLine) {
heightBinding();
}
}
function pasteText() {
@ -153,7 +158,7 @@ JamiFlickable {
persistentSelection: true
height: this.paintedHeight
height: textArea.lineCount === 1 ? 35 : textArea.paintedHeight
verticalAlignment: TextEdit.AlignVCenter
@ -202,7 +207,13 @@ JamiFlickable {
const isEnterNewLine = UtilsAdapter.getAppValue(Settings.Key.ChatViewEnterIsNewLine);
const isShiftPressed = (keyEvent.modifiers & Qt.ShiftModifier);
const isCtrlPressed = (keyEvent.modifiers & Qt.ControlModifier);
if (!isEnterNewLine && !isShiftPressed || isCtrlPressed) {
if (!root.isShowTypo && !isShiftPressed) {
root.sendMessagesRequired();
keyEvent.accepted = true;
} else if (isCtrlPressed) {
root.sendMessagesRequired();
keyEvent.accepted = true;
} else if (!isEnterNewLine && !isShiftPressed) {
root.sendMessagesRequired();
keyEvent.accepted = true;
}

View File

@ -75,7 +75,8 @@ Rectangle {
radius: hoverButtonRadius
hoveredColor: JamiTheme.hoveredButtonColor
source: JamiResources.ic_baseline_search_24dp_svg
normalColor: "transparent"
toolTipText: JamiStrings.search
normalColor: JamiTheme.primaryBackgroundColor
imageColor: {
if (reductionEnabled) {
if (hovered) {

View File

@ -16,21 +16,19 @@
* 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 net.jami.Adapters 1.1
import net.jami.Constants 1.1
import net.jami.Enums 1.1
import net.jami.Models 1.1
import "../../commoncomponents"
import "../../settingsview/components"
SidePanelBase {
id: root
objectName: "SidePanel"
color: JamiTheme.backgroundColor
@ -39,7 +37,7 @@ SidePanelBase {
target: LRCInstance
function onCurrentAccountIdChanged() {
clearContactSearchBar()
clearContactSearchBar();
}
}
@ -47,8 +45,8 @@ SidePanelBase {
target: ConversationsAdapter
function onConversationReady() {
selectTab(SidePanelTabBar.Conversations)
clearContactSearchBar()
selectTab(SidePanelTabBar.Conversations);
clearContactSearchBar();
}
}
@ -56,46 +54,46 @@ SidePanelBase {
target: ConversationsAdapter
function onShowSearchStatus(status) {
searchStatusText.text = status
searchStatusText.text = status;
}
function onTextFilterChanged(text) {
// In the swarm details, "Go to conversation" can
// change the search bar. Be sure to be synced
contactSearchBar.textContent = text
contactSearchBar.textContent = text;
}
}
function toggleCreateSwarmView() {
if (!inNewSwarm) {
viewCoordinator.present("NewSwarmPage")
const newSwarmPage = viewCoordinator.getView("NewSwarmPage")
viewCoordinator.present("NewSwarmPage");
const newSwarmPage = viewCoordinator.getView("NewSwarmPage");
newSwarmPage.removeMember.connect((convId, member) => {
removeMember(convId, member)
})
removeMember(convId, member);
});
newSwarmPage.createSwarmClicked.connect((title, description, avatar) => {
var uris = []
for (var idx in newSwarmPage.members) {
var uri = newSwarmPage.members[idx].uri
if (uris.indexOf(uri) === -1) {
uris.push(uri)
var uris = [];
for (var idx in newSwarmPage.members) {
var uri = newSwarmPage.members[idx].uri;
if (uris.indexOf(uri) === -1) {
uris.push(uri);
}
}
}
let convuid = ConversationsAdapter.createSwarm(title, description, avatar, uris)
viewCoordinator.dismiss("NewSwarmPage")
LRCInstance.selectConversation(convuid)
})
let convuid = ConversationsAdapter.createSwarm(title, description, avatar, uris);
viewCoordinator.dismiss("NewSwarmPage");
LRCInstance.selectConversation(convuid);
});
} else {
viewCoordinator.dismiss("NewSwarmPage")
viewCoordinator.dismiss("NewSwarmPage");
}
}
function clearContactSearchBar() {
contactSearchBar.clearText()
contactSearchBar.clearText();
}
function selectTab(tabIndex) {
sidePanelTabBar.selectTab(tabIndex)
sidePanelTabBar.selectTab(tabIndex);
}
property bool inNewSwarm: viewCoordinator.currentViewName === "NewSwarmPage"
@ -104,65 +102,64 @@ SidePanelBase {
property var highlightedMembers: []
onHighlightedMembersChanged: {
if (inNewSwarm) {
const newSwarmPage = viewCoordinator.getView("NewSwarmPage")
newSwarmPage.members = highlightedMembers
const newSwarmPage = viewCoordinator.getView("NewSwarmPage");
newSwarmPage.members = highlightedMembers;
}
}
function refreshHighlighted(convId, highlightedStatus) {
var newH = root.highlighted
var newHm = root.highlightedMembers
var newH = root.highlighted;
var newHm = root.highlightedMembers;
if (highlightedStatus) {
var item = ConversationsAdapter.getConvInfoMap(convId)
var added = false
var item = ConversationsAdapter.getConvInfoMap(convId);
var added = false;
for (var idx in item.uris) {
var uri = item.uris[idx]
if (!Array.from(newHm).find(r => r.uri === uri) &&
uri !== CurrentAccount.uri) {
newHm.push({"uri": uri, "convId": convId})
added = true
var uri = item.uris[idx];
if (!Array.from(newHm).find(r => r.uri === uri) && uri !== CurrentAccount.uri) {
newHm.push({
"uri": uri,
"convId": convId
});
added = true;
}
}
if (!added)
return false
return false;
} else {
newH = Array.from(newH).filter(r => r !== convId)
newHm = Array.from(newHm).filter(r => r.convId !== convId)
newH = Array.from(newH).filter(r => r !== convId);
newHm = Array.from(newHm).filter(r => r.convId !== convId);
}
newH.push(convId)
root.highlighted = newH
root.highlightedMembers = newHm
ConversationsAdapter.ignoreFiltering(root.highlighted)
return true
newH.push(convId);
root.highlighted = newH;
root.highlightedMembers = newHm;
ConversationsAdapter.ignoreFiltering(root.highlighted);
return true;
}
function clearHighlighted() {
root.highlighted = []
root.highlightedMembers = []
root.highlighted = [];
root.highlightedMembers = [];
}
function removeMember(convId, member) {
var refreshHighlighted = true
var newHm = []
var refreshHighlighted = true;
var newHm = [];
for (var hm in root.highlightedMembers) {
var m = root.highlightedMembers[hm]
var m = root.highlightedMembers[hm];
if (m.convId === convId && m.uri === member) {
continue;
} else if (m.convId === convId) {
refreshHighlighted = false
refreshHighlighted = false;
}
newHm.push(m)
newHm.push(m);
}
root.highlightedMembers = newHm
root.highlightedMembers = newHm;
if (refreshHighlighted) {
// Remove highlighted status if necessary
for (var d in swarmCurrentConversationList.contentItem.children) {
var delegate = swarmCurrentConversationList.contentItem.children[d]
var delegate = swarmCurrentConversationList.contentItem.children[d];
if (delegate.convId === convId)
delegate.highlighted = false
delegate.highlighted = false;
}
}
}
@ -176,11 +173,16 @@ SidePanelBase {
color: JamiTheme.backgroundColor
}
header: AccountComboBox {}
header: AccountComboBox {
}
Item {
anchors.fill: parent
onVisibleChanged: {
donation.donationVisible = Qt.binding(() => JamiQmlUtils.isDonationBannerVisible());
}
RowLayout {
id: titleBar
@ -240,7 +242,7 @@ SidePanelBase {
sequence: "Ctrl+F"
context: Qt.ApplicationShortcut
onActivated: {
contactSearchBar.forceActiveFocus()
contactSearchBar.forceActiveFocus();
}
}
@ -250,20 +252,18 @@ SidePanelBase {
Layout.fillHeight: true
Layout.fillWidth: true
onSearchBarTextChanged: function(text){
onSearchBarTextChanged: function (text) {
// not calling positionViewAtBeginning will cause
// sort animation visual bugs
conversationListView.positionViewAtBeginning()
ConversationsAdapter.ignoreFiltering(root.highlighted)
ConversationsAdapter.setFilter(text)
conversationListView.positionViewAtBeginning();
ConversationsAdapter.ignoreFiltering(root.highlighted);
ConversationsAdapter.setFilter(text);
}
onReturnPressedWhileSearching: {
var listView = searchResultsListView.count ?
searchResultsListView :
conversationListView
var listView = searchResultsListView.count ? searchResultsListView : conversationListView;
if (listView.count)
listView.model.select(0)
listView.model.select(0);
}
}
@ -291,8 +291,7 @@ SidePanelBase {
SidePanelTabBar {
id: sidePanelTabBar
visible: ConversationsAdapter.pendingRequestCount &&
!contactSearchBar.textContent && smartListLayout.visible
visible: ConversationsAdapter.pendingRequestCount && !contactSearchBar.textContent && smartListLayout.visible
anchors.top: startBar.bottom
anchors.topMargin: visible ? 10 : 0
width: page.width
@ -311,7 +310,6 @@ SidePanelBase {
height: visible ? 42 : 0
color: JamiTheme.backgroundColor
Text {
id: searchStatusText
@ -326,13 +324,22 @@ SidePanelBase {
}
}
DonationBanner {
id: donation
anchors.horizontalCenter: parent.horizontalCenter
anchors.leftMargin: 15
anchors.rightMargin: 15
anchors.top: sidePanelTabBar.bottom
anchors.topMargin: 10
visible: donation.donationVisible
}
ColumnLayout {
id: smartListLayout
width: parent.width
anchors.top: searchStatusRect.bottom
anchors.topMargin: (sidePanelTabBar.visible ||
searchStatusRect.visible) ? 0 : 12
anchors.top: donation.donationVisible ? donation.bottom : searchStatusRect.bottom
anchors.topMargin: (sidePanelTabBar.visible || searchStatusRect.visible) ? 0 : 12
anchors.bottom: parent.bottom
spacing: 4
@ -350,14 +357,14 @@ SidePanelBase {
Layout.fillWidth: true
Layout.preferredHeight: visible ? contentHeight : 0
Layout.maximumHeight: {
var otherContentHeight = conversationListView.contentHeight + 16
var otherContentHeight = conversationListView.contentHeight + 16;
if (conversationListView.visible)
if (otherContentHeight < parent.height / 2)
return parent.height - otherContentHeight
return parent.height - otherContentHeight;
else
return parent.height / 2
return parent.height / 2;
else
return parent.height
return parent.height;
}
model: SearchResultsListModel
@ -385,9 +392,8 @@ SidePanelBase {
visible: inNewSwarm
width: parent.width
anchors.top: searchStatusRect.bottom
anchors.topMargin: (sidePanelTabBar.visible ||
searchStatusRect.visible) ? 0 : 12
anchors.top: donation.donationVisible ? donation.bottom : sidePanelTabBar.bottom
anchors.topMargin: (sidePanelTabBar.visible || searchStatusRect.visible) ? 0 : 12
anchors.bottom: parent.bottom
spacing: 4
@ -404,8 +410,8 @@ SidePanelBase {
onVisibleChanged: {
if (!swarmCurrentConversationList.visible) {
highlighted = false
root.clearHighlighted()
highlighted = false;
root.clearHighlighted();
}
}
@ -414,26 +420,26 @@ SidePanelBase {
// destroyed from the memory. So, re-add the highlighted
// status if necessary
if (Array.from(root.highlighted).find(r => r === UID)) {
highlighted = true
highlighted = true;
}
}
onHighlightedChanged: function onHighlightedChanged() {
if (highlighted && Array.from(root.highlighted).find(r => r === UID)) {
// Due to scrolling destruction/reconstruction
return
return;
}
var currentHighlighted = root.highlighted
var currentHighlighted = root.highlighted;
if (!root.refreshHighlighted(UID, highlighted)) {
highlighted = false
return
highlighted = false;
return;
}
if (highlighted) {
root.highlighted.push(UID)
root.highlighted.push(UID);
} else {
root.highlighted = Array.from(root.highlighted).filter(r => r !== UID)
root.highlighted = Array.from(root.highlighted).filter(r => r !== UID);
}
root.clearContactSearchBar()
root.clearContactSearchBar();
}
}
currentIndex: model.currentFilteredRow
@ -448,7 +454,9 @@ SidePanelBase {
interval: 750
running: isSharingPosition || isReceivingPosition
repeat: true
onTriggered: {showIconArrow = !showIconArrow}
onTriggered: {
showIconArrow = !showIconArrow;
}
}
}
}

View File

@ -37,7 +37,6 @@ FocusScope {
property color textColor: JamiTheme.textColor
property color iconColor: JamiTheme.tintedBlue
property string customizeTip: "CustomizeTipBox {}"
property string backupTip: "BackupTipBox {" + " onIgnore: {" + " root.ignoreClicked()" + " }" + "}"
@ -56,7 +55,6 @@ FocusScope {
focus: true
activeFocusOnTab: true
Rectangle {
id: rect
anchors.fill: parent
@ -73,6 +71,18 @@ FocusScope {
width: parent.width
anchors.topMargin: 10
Loader {
id: loader_donationTip
active: type === "donation"
focus: true
sourceComponent: DonationTipBox {
maxHeight: root.maximumHeight
textColor: root.textColor
iconColor: root.iconColor
}
width: parent.width
}
Loader {
id: loader_backupTip
active: type === "backup"
@ -95,7 +105,6 @@ FocusScope {
}
width: parent.width
focus: true
}
Loader {
id: loader_infoTip
@ -106,7 +115,6 @@ FocusScope {
iconColor: root.iconColor
}
width: parent.width
}
}
}
@ -119,6 +127,7 @@ FocusScope {
TapHandler {
target: rect
enabled: type !== "donation"
onTapped: {
return opened ? focus = false : root.forceActiveFocus();
}

View File

@ -24,9 +24,6 @@ import "../../commoncomponents"
BaseModalDialog {
id: root
width: Math.min(appWindow.width - 2 * JamiTheme.preferredMarginSize, JamiTheme.secondaryDialogDimension)
height: Math.min(appWindow.height - 2 * JamiTheme.preferredMarginSize, JamiTheme.secondaryDialogDimension)
property string convId
property string aliasText
property string registeredNameText
@ -34,19 +31,11 @@ BaseModalDialog {
property int preferredImgSize: 80
popupContent: Rectangle {
id: userProfileContentRect
color: JamiTheme.backgroundColor
radius: JamiTheme.modalPopupRadius
anchors.fill: parent
GridLayout {
popupContent: GridLayout {
id: userProfileDialogLayout
anchors.centerIn: parent
anchors.fill: parent
anchors.margins: JamiTheme.preferredMarginSize
width: JamiTheme.secondaryDialogDimension
columns: 2
rows: 6
@ -77,6 +66,7 @@ BaseModalDialog {
visible: aliasText ? (aliasText === idText ? false : true) : false
selectByMouse: true
readOnly: true
wrapMode: Text.NoWrap
text: textMetricsContactAliasText.elidedText
@ -88,7 +78,7 @@ BaseModalDialog {
id: textMetricsContactAliasText
font: contactAlias.font
text: aliasText
elideWidth: userProfileContentRect.width - 200
elideWidth: root.width - 200
elide: Qt.ElideMiddle
}
}
@ -141,12 +131,13 @@ BaseModalDialog {
id: textMetricsContactDisplayNameText
font: contactDisplayName.font
text: registeredNameText
elideWidth: userProfileContentRect.width - 200
elideWidth: root.width - 200
elide: Qt.ElideMiddle
}
}
Text {
id: identifierText
Layout.alignment: Qt.AlignRight
font.pointSize: JamiTheme.textFontSize
text: JamiStrings.identifier
@ -157,8 +148,8 @@ BaseModalDialog {
id: contactId
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: userProfileContentRect.width - 200
Layout.preferredWidth: root.width - 250
Layout.rightMargin: JamiTheme.preferredMarginSize
font.pointSize: JamiTheme.textFontSize
font.kerning: true
color: JamiTheme.textColor
@ -166,7 +157,7 @@ BaseModalDialog {
readOnly: true
selectByMouse: true
wrapMode: TextEdit.WrapAnywhere
wrapMode: Text.Wrap
text: idText
horizontalAlignment: Text.AlignLeft
@ -193,25 +184,6 @@ BaseModalDialog {
source: convId !== "" ? "image://qrImage/contact_" + convId : "image://qrImage/contact_" + idText
}
MaterialButton {
id: btnClose
Layout.columnSpan: 2
Layout.alignment: Qt.AlignHCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
text: JamiStrings.close
onClicked: close()
}
}
}
}

View File

@ -31,7 +31,7 @@ Item {
property color textColor: JamiTheme.textColor
property color idColor: JamiTheme.welcomeBlockColor
property color contentIdColor: JamiTheme.tintedBlue
property bool hasTitle: true
property bool hasTitle: false
property bool hasDescription: true
property string title: JamiStrings.welcomeToJami
@ -39,8 +39,6 @@ Item {
property real contentWidth: welcomeInfo.width - 2 * JamiTheme.mainViewMargin
function getHeight() {
return bgRect.height;
}
@ -70,7 +68,6 @@ Item {
Loader {
id: loader_identifierDescription
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: contentWidth
Layout.preferredHeight: item ? item.contentHeight : 0
Layout.bottomMargin: loader_bottomIdentifier.item ? JamiTheme.mainViewMargin - 10 : 0
sourceComponent: {
@ -93,7 +90,6 @@ Item {
sourceComponent: JamiIdentifier {
backgroundColor: welcomeInfo.idColor
contentColor: contentIdColor
}
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: active ? item.getHeight() : 0
@ -133,7 +129,7 @@ Item {
width: welcomeInfo.contentWidth
height: contentHeight
font.pixelSize: JamiTheme.headerFontSize
font.pixelSize: JamiTheme.tipBoxContentFontSize
wrapMode: Text.WordWrap

View File

@ -36,18 +36,18 @@ Item {
width: getWidth()
function getWidth() {
return JamiTheme.welcomeHalfGridWidth;
return JamiTheme.welcomeThirdGridWidth;
}
function getHeight() {
return 120;
return 80;
}
CachedImage {
id: cachedImgLogo
objectName: "cachedImgLogo"
downloadUrl: logoUrl
defaultImage: JamiResources.jami_logo_icon_svg
defaultImage: JamiTheme.welcomeLogo
visible: welcomeLogo.visible
height: parent.height * logoSize
width: parent.width * logoSize

View File

@ -49,7 +49,7 @@ ListSelectionView {
property bool hasCustomUi: false
property bool hasTitle: true
property bool hasTitle: false
property bool hasDescription: true
property bool hasCustomTitle: false
@ -95,7 +95,7 @@ ListSelectionView {
function updateUiFlags() {
hasCustomUi = Object.keys(uiCustomization).length > 0;
hasTitle = hasCustomUi ? uiCustomization.title !== "" : true;
hasTitle = hasCustomUi ? uiCustomization.title !== "" : false;
hasDescription = hasCustomUi ? uiCustomization.description !== "" : true;
title = hasCustomUi && uiCustomization.title !== undefined ? uiCustomization.title : JamiStrings.welcomeToJami;
description = hasCustomUi && uiCustomization.description !== undefined ? uiCustomization.description : JamiStrings.hereIsIdentifier;
@ -261,16 +261,14 @@ ListSelectionView {
TextMetrics {
id: textSize
font.weight: Font.Bold
font.pixelSize: 20
font.capitalization: Font.AllUppercase
text: aboutJami.text
}
tertiary: true
anchors.horizontalCenter: parent.horizontalCenter
preferredWidth: textSize.width
preferredWidth: text.width
text: JamiStrings.aboutJami
fontSize: 12
onClicked: viewCoordinator.presentDialog(appWindow, "mainview/components/AboutPopUp.qml")
}

View File

@ -18,26 +18,26 @@
import QtQuick
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import QtQuick.Layouts
import "../../commoncomponents"
BaseModalDialog {
id: root
//Content height + margin.
property int size: JamiTheme.qrCodeImageSize + 30
width: size
height: size
topLayoutVisible: false
backgroundColor: JamiTheme.whiteColor
popupContentPreferredHeight: JamiTheme.qrCodeImageSize
popupContentPreferredWidth: JamiTheme.qrCodeImageSize
popupContent: Image {
id: userQrImage
id: userQrImage
property int size: JamiTheme.qrCodeImageSize
width: size
height: size
anchors.centerIn: parent
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrImage/account_" + CurrentAccount.id
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrImage/account_" + CurrentAccount.id
}
}

View File

@ -25,6 +25,28 @@
#include <QtNetwork>
#include <QScopedPointer>
namespace {
NetworkManager::GetError
translateErrorCode(QNetworkReply::NetworkError error)
{
// From qnetworkreply.h:
// network layer errors (1-99): / proxy errors (101-199):
// content errors (201-299): ContentAccessDenied = 201,
// protocol errors / Server side errors (401-499)
static auto inRange = [](int value, int min, int max) -> bool {
return (value >= min && value <= max);
};
if (inRange(error, 1, 199))
return NetworkManager::NETWORK_ERROR;
if (inRange(error, 201, 201))
return NetworkManager::ACCESS_DENIED;
if (inRange(error, 202, 299))
return NetworkManager::CONTENT_NOT_FOUND;
return NetworkManager::NETWORK_ERROR;
}
} // namespace
NetworkManager::NetworkManager(ConnectivityMonitor* cm, QObject* parent)
: QObject(parent)
, manager_(new QNetworkAccessManager(this))
@ -45,7 +67,7 @@ NetworkManager::NetworkManager(ConnectivityMonitor* cm, QObject* parent)
});
#endif
connect(connectivityMonitor_, &ConnectivityMonitor::connectivityChanged, this, [this] {
auto connected = connectivityMonitor_->isOnline();
const auto connected = connectivityMonitor_->isOnline();
if (connected && !lastConnectionState_) {
manager_->deleteLater();
manager_ = new QNetworkAccessManager(this);
@ -59,7 +81,28 @@ void
NetworkManager::sendGetRequest(const QUrl& url,
std::function<void(const QByteArray&)>&& onDoneCallback)
{
auto* const reply = manager_->get(QNetworkRequest(url));
const QNetworkRequest request = QNetworkRequest(url);
sendGetRequest(request, std::move(onDoneCallback));
}
void
NetworkManager::sendGetRequest(const QUrl& url,
const QMap<QString, QByteArray>& header,
std::function<void(const QByteArray&)>&& onDoneCallback)
{
QNetworkRequest request = QNetworkRequest(url);
for (auto it = header.begin(); it != header.end(); ++it) {
request.setRawHeader(QByteArray(it.key().toStdString().c_str(), it.key().size()),
it.value());
}
sendGetRequest(request, std::move(onDoneCallback));
}
void
NetworkManager::sendGetRequest(const QNetworkRequest& request,
std::function<void(const QByteArray&)>&& onDoneCallback)
{
auto* const reply = manager_->get(request);
QObject::connect(reply, &QNetworkReply::finished, this, [reply, onDoneCallback, this]() {
if (reply->error() == QNetworkReply::NoError) {
onDoneCallback(reply->readAll());
@ -77,9 +120,8 @@ NetworkManager::downloadFile(const QUrl& url,
const QString& filePath,
const QString& extension)
{
// If there is already a download in progress, return.
if ((downloadReplies_.value(replyId) != NULL || !(replyId == 0))
&& downloadReplies_[replyId]->isRunning()) {
// Don't replace the download if there is already a download in progress for this id.
if (downloadReplies_.contains(replyId) && downloadReplies_.value(replyId)->isRunning()) {
qWarning() << Q_FUNC_INFO << "Download already in progress";
return replyId;
}
@ -100,6 +142,7 @@ NetworkManager::downloadFile(const QUrl& url,
}
// set the id for the request
// NOLINTNEXTLINE(misc-const-correctness)
std::uniform_int_distribution<int> dist(1, std::numeric_limits<int>::max());
auto uuid = dist(rng_);
@ -112,7 +155,7 @@ NetworkManager::downloadFile(const QUrl& url,
const QFileInfo fileInfo(url.path());
const QString fileName = fileInfo.fileName();
auto& file = files_[uuid];
file = new QFile(filePath + fileName + extension);
file = new QFile(filePath + QDir::separator() + fileName + extension);
if (!file->open(QIODevice::WriteOnly)) {
Q_EMIT errorOccurred(GetError::ACCESS_DENIED);
files_.remove(uuid);
@ -146,7 +189,7 @@ NetworkManager::downloadFile(const QUrl& url,
resetDownload(uuid);
qWarning() << Q_FUNC_INFO
<< QMetaEnum::fromType<QNetworkReply::NetworkError>().valueToKey(error);
Q_EMIT errorOccurred(GetError::NETWORK_ERROR);
Q_EMIT errorOccurred(translateErrorCode(error));
});
connect(reply, &QNetworkReply::finished, this, [this, uuid, onDoneCallback, reply, file]() {

View File

@ -23,6 +23,7 @@
#include <QMap>
#include <QString>
#include <QNetworkReply>
#include <random>
class QNetworkAccessManager;
@ -35,16 +36,27 @@ public:
explicit NetworkManager(ConnectivityMonitor* cm, QObject* parent = nullptr);
virtual ~NetworkManager() = default;
enum GetError { DISCONNECTED, NETWORK_ERROR, ACCESS_DENIED, SSL_ERROR, CANCELED };
enum GetError {
DISCONNECTED,
CONTENT_NOT_FOUND,
ACCESS_DENIED,
SSL_ERROR,
CANCELED,
NETWORK_ERROR,
};
Q_ENUM(GetError)
void sendGetRequest(const QUrl& url, std::function<void(const QByteArray&)>&& onDoneCallback);
void sendGetRequest(const QUrl& url,
const QMap<QString, QByteArray>& header,
std::function<void(const QByteArray&)>&& onDoneCallback);
void sendGetRequest(const QNetworkRequest& request,
std::function<void(const QByteArray&)>&& onDoneCallback);
int downloadFile(const QUrl& url,
int replyId,
std::function<void(bool, const QString&)>&& onDoneCallback,
const QString& filePath,
const QString& extension = "");
const QString& extension = {});
void resetDownload(int replyId);
void cancelDownload(int replyId);
Q_SIGNALS:

View File

@ -23,24 +23,27 @@
#include "pluginstorelistmodel.h"
#include "networkmanager.h"
#include "lrcinstance.h"
#include "appsettingsmanager.h"
#include "utilsadapter.h"
#include "qmlregister.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QtNetwork>
#include <QJsonObject>
#include <QDir>
#include <QString>
PluginAdapter::PluginAdapter(LRCInstance* instance, QObject* parent, QString baseUrl)
PluginAdapter::PluginAdapter(LRCInstance* instance,
AppSettingsManager* settingsManager,
QObject* parent,
QString baseUrl)
: QmlAdapterBase(instance, parent)
, pluginStoreListModel_(new PluginStoreListModel(instance, this))
, pluginVersionManager_(new PluginVersionManager(instance, baseUrl, this))
, pluginVersionManager_(new PluginVersionManager(instance, this))
, pluginListModel_(new PluginListModel(instance, this))
, lrcInstance_(instance)
, tempPath_(QDir::tempPath())
, baseUrl_(baseUrl)
, settingsManager_(settingsManager)
{
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, pluginStoreListModel_, "PluginStoreListModel");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, pluginListModel_, "PluginListModel")
@ -89,9 +92,13 @@ PluginAdapter::getPluginsFromStore()
[this](NetworkManager::GetError error, const QString& msg) {
Q_EMIT storeNotAvailable();
});
QMap<QString, QByteArray> header;
const auto& language = settingsManager_->getLanguage();
header["Accept-Language"] = QByteArray(language.toStdString().c_str(), language.size());
pluginVersionManager_
->sendGetRequest(QUrl(baseUrl_
->sendGetRequest(QUrl(baseUrl()
+ "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"]),
header,
[this, errorHandler](const QByteArray& data) {
auto result = QJsonDocument::fromJson(data).array();
auto pluginsInstalled = lrcInstance_->pluginModel().getPluginsId();
@ -113,9 +120,13 @@ PluginAdapter::getPluginsFromStore()
void
PluginAdapter::getPluginDetails(const QString& pluginId)
{
QMap<QString, QByteArray> header;
const auto& language = settingsManager_->getLanguage();
header["Accept-Language"] = QByteArray(language.toStdString().c_str(), language.size());
pluginVersionManager_
->sendGetRequest(QUrl(baseUrl_ + "/details/" + pluginId
->sendGetRequest(QUrl(baseUrl() + "/details/" + pluginId
+ "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"]),
header,
[this](const QByteArray& data) {
auto result = QJsonDocument::fromJson(data).object();
// my response is a json object and I want to convert
@ -200,19 +211,19 @@ PluginAdapter::checkVersionStatus(const QString& pluginId)
QString
PluginAdapter::baseUrl() const
{
return baseUrl_;
return settingsManager_->getValue("PluginStoreEndpoint").toString();
}
QString
PluginAdapter::getIconUrl(const QString& pluginId) const
{
return baseUrl_ + "/icons/" + pluginId
return baseUrl() + "/icons/" + pluginId
+ "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"];
}
QString
PluginAdapter::getBackgroundImageUrl(const QString& pluginId) const
{
return baseUrl_ + "/backgrounds/" + pluginId
return baseUrl() + "/backgrounds/" + pluginId
+ "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"];
}

View File

@ -22,6 +22,7 @@
#include "pluginlistmodel.h"
#include "pluginhandlerlistmodel.h"
#include "pluginlistpreferencemodel.h"
#include "appsettingsmanager.h"
#include "pluginversionmanager.h"
#include "pluginstorelistmodel.h"
#include "preferenceitemlistmodel.h"
@ -32,6 +33,7 @@
class PluginVersionManager;
class PluginStoreListModel;
class AppSettingsManager;
class PluginAdapter final : public QmlAdapterBase
{
@ -41,6 +43,7 @@ class PluginAdapter final : public QmlAdapterBase
public:
explicit PluginAdapter(LRCInstance* instance,
AppSettingsManager* settingsManager,
QObject* parent = nullptr,
QString baseUrl = "https://plugins.jami.net");
~PluginAdapter() = default;
@ -76,7 +79,7 @@ private:
std::unique_ptr<PluginHandlerListModel> pluginHandlerListModel_;
LRCInstance* lrcInstance_;
AppSettingsManager* settingsManager_;
std::mutex mtx_;
QString tempPath_;
QString baseUrl_;
};

View File

@ -71,7 +71,7 @@ PluginListModel::data(const QModelIndex& index, int role) const
case Role::PluginIcon:
return QVariant(details.iconPath);
case Role::PluginImage:
return QVariant(details.imagePath);
return QVariant(details.backgroundPath);
case Role::IsLoaded:
return QVariant(details.loaded);
case Role::PluginAuthor:
@ -80,6 +80,8 @@ PluginListModel::data(const QModelIndex& index, int role) const
return QVariant(pluginStatus_.value(installedPlugins_.at(index.row())));
case Role::NewPluginAvailable:
return QVariant(newVersionAvailable_.value(installedPlugins_.at(index.row())));
case Role::Id:
return QVariant(details.id);
}
return QVariant();
}
@ -98,6 +100,7 @@ PluginListModel::roleNames() const
roles[Status] = "Status";
roles[PluginDescription] = "PluginDescription";
roles[NewPluginAvailable] = "NewPluginAvailable";
roles[Id] = "Id";
return roles;
}

View File

@ -38,7 +38,8 @@ public:
PluginIcon,
NewPluginAvailable,
IsLoaded,
Status
Status,
Id
};
Q_ENUM(Role)

View File

@ -79,7 +79,6 @@ void
PluginStoreListModel::reset()
{
beginResetModel();
plugins_.clear();
endResetModel();
}
@ -88,8 +87,8 @@ PluginStoreListModel::addPlugin(const QVariantMap& plugin)
{
beginInsertRows(QModelIndex(), plugins_.size(), plugins_.size());
plugins_.append(plugin);
endInsertRows();
sort();
endInsertRows();
}
void
@ -97,8 +96,8 @@ PluginStoreListModel::setPlugins(const QList<QVariantMap>& plugins)
{
beginResetModel();
plugins_ = filterPlugins(plugins);
endResetModel();
sort();
endResetModel();
}
void
@ -109,12 +108,12 @@ PluginStoreListModel::removePlugin(const QString& pluginId)
if (plugin["id"].toString() == pluginId) {
beginRemoveRows(QModelIndex(), index, index);
plugins_.removeAt(index);
sort();
endRemoveRows();
return;
}
index++;
}
sort();
}
void
@ -129,7 +128,6 @@ PluginStoreListModel::updatePlugin(const QVariantMap& plugin)
}
index++;
}
sort();
}
QColor
@ -210,7 +208,7 @@ PluginStoreListModel::rowFromPluginId(const QString& pluginId) const
const auto it = std::find_if(plugins_.begin(),
plugins_.end(),
[&pluginId](const QVariantMap& p) {
return p["name"].toString() == pluginId;
return p["id"].toString() == pluginId;
});
if (it != plugins_.end()) {
return std::distance(plugins_.begin(), it);
@ -221,11 +219,9 @@ PluginStoreListModel::rowFromPluginId(const QString& pluginId) const
void
PluginStoreListModel::sort()
{
beginResetModel();
std::sort(plugins_.begin(), plugins_.end(), [](const QVariantMap& a, const QVariantMap& b) {
return a["timestamp"].toString() < b["timestamp"].toString();
});
endResetModel();
}
QList<QVariantMap>

View File

@ -33,9 +33,8 @@ public:
Impl(LRCInstance* instance, PluginVersionManager& parent)
: QObject(nullptr)
, parent_(parent)
, appSettingsManager_(new AppSettingsManager(this))
, settingsManager_(new AppSettingsManager(this))
, lrcInstance_(instance)
, tempPath_(QDir::tempPath())
, updateTimer_(new QTimer(this))
{
connect(updateTimer_, &QTimer::timeout, this, [this] { checkForUpdates(); });
@ -78,12 +77,12 @@ public:
bool isAutoUpdaterEnabled()
{
return appSettingsManager_->getValue(Settings::Key::PluginAutoUpdate).toBool();
return settingsManager_->getValue(Settings::Key::PluginAutoUpdate).toBool();
}
void setAutoUpdate(bool state)
{
appSettingsManager_->setValue(Settings::Key::PluginAutoUpdate, state);
settingsManager_->setValue(Settings::Key::PluginAutoUpdate, state);
}
void checkVersionStatus(const QString& pluginId)
@ -103,13 +102,14 @@ public:
return;
}
parent_.sendGetRequest(QUrl(parent_.baseUrl + "/versions/" + plugin.id + "?arch="
parent_.sendGetRequest(QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString()
+ "/versions/" + plugin.id + "?arch="
+ lrcInstance_->pluginModel().getPlatformInfo()["os"]),
[this, plugin](const QByteArray& data) {
// `data` represents the version in this case.
if (plugin.version < data) {
if (isAutoUpdaterEnabled()) {
installRemotePlugin(plugin.name);
installRemotePlugin(plugin.id);
return;
}
}
@ -121,7 +121,7 @@ public:
void installRemotePlugin(const QString& pluginId)
{
parent_.downloadFile(
QUrl(parent_.baseUrl + "/download/"
QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString() + "/download/"
+ lrcInstance_->pluginModel().getPlatformInfo()["os"] + "/" + pluginId),
pluginId,
0,
@ -132,9 +132,9 @@ public:
return;
}
QThreadPool::globalInstance()->start([this, pluginId] {
auto res = lrcInstance_->pluginModel().installPlugin(QDir(tempPath_).filePath(
pluginId + ".jpl"),
true);
auto res = lrcInstance_->pluginModel()
.installPlugin(QDir(QDir::tempPath()).filePath(pluginId + ".jpl"),
true);
if (res) {
parent_.versionStatusChanged(pluginId, PluginStatus::Role::INSTALLED);
} else {
@ -143,7 +143,7 @@ public:
});
parent_.versionStatusChanged(pluginId, PluginStatus::Role::INSTALLING);
},
tempPath_ + '/');
QDir::tempPath());
Q_EMIT parent_.versionStatusChanged(pluginId, PluginStatus::Role::DOWNLOADING);
}
@ -158,15 +158,13 @@ public:
};
PluginVersionManager& parent_;
AppSettingsManager* appSettingsManager_ {nullptr};
AppSettingsManager* settingsManager_ {nullptr};
LRCInstance* lrcInstance_ {nullptr};
QString tempPath_;
QTimer* updateTimer_;
};
PluginVersionManager::PluginVersionManager(LRCInstance* instance, QString& baseUrl, QObject* parent)
PluginVersionManager::PluginVersionManager(LRCInstance* instance, QObject* parent)
: NetworkManager(&instance->connectivityMonitor(), parent)
, baseUrl(baseUrl)
, pimpl_(std::make_unique<Impl>(instance, *this))
{}

View File

@ -46,9 +46,7 @@ class PluginVersionManager final : public NetworkManager
{
Q_OBJECT
public:
explicit PluginVersionManager(LRCInstance* instance,
QString& baseUrl,
QObject* parent = nullptr);
explicit PluginVersionManager(LRCInstance* instance, QObject* parent = nullptr);
~PluginVersionManager();
Q_INVOKABLE bool isAutoUpdaterEnabled();

View File

@ -123,7 +123,7 @@ registerTypes(QQmlEngine* engine,
auto contactAdapter = new ContactAdapter(lrcInstance, parent);
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
auto pluginAdapter = new PluginAdapter(lrcInstance, settingsManager, parent);
auto currentCall = new CurrentCall(lrcInstance, parent);
auto currentConversation = new CurrentConversation(lrcInstance, parent);
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);

View File

@ -33,7 +33,7 @@ public:
instance)
{}
enum class QrType { Account, Contact };
enum class QrType { Account, Contact, Raw };
/*
* Id should be string like account_0 (account index),
@ -64,6 +64,8 @@ public:
} catch (...) {
}
return {QrType::Contact, {}};
} else if (list.contains("raw") && list.size() > 1) {
return {QrType::Raw, list[1]};
}
return {QrType::Account, {}};
}
@ -73,26 +75,24 @@ public:
Q_UNUSED(size);
QString uri;
auto indexPair = getIndexFromID(id);
auto [type, identifier] = getIndexFromID(id);
if (indexPair.first == QrType::Contact) {
uri = indexPair.second;
} else {
if (indexPair.second.isEmpty())
if (type == QrType::Account) {
if (identifier.isEmpty())
return QImage();
auto accountId = indexPair.second;
try {
auto& accountInfo = lrcInstance_->getAccountInfo(accountId);
auto& accountInfo = lrcInstance_->getAccountInfo(identifier);
uri = accountInfo.profileInfo.uri;
} catch (const std::out_of_range&) {
qWarning() << "Couldn't get account info for id:" << accountId;
qWarning() << "Couldn't get account info for id:" << identifier;
return QImage();
}
}
} else
uri = identifier;
if (!requestedSize.isEmpty())
return Utils::setupQRCode(uri, 0).scaled(requestedSize, Qt::KeepAspectRatio);
return Utils::getQRCodeImage(uri, 0).scaled(requestedSize, Qt::KeepAspectRatio);
else
return Utils::setupQRCode(uri, 0);
return Utils::getQRCodeImage(uri, 0);
}
};

View File

@ -70,10 +70,10 @@ SidePanelBase {
"title": JamiStrings.appearance
}, {
"id": 7,
"title": JamiStrings.locationSharingLabel
"title": JamiStrings.chatSettingsTitle
}, {
"id": 8,
"title": JamiStrings.fileTransfer
"title": JamiStrings.locationSharingLabel
}, {
"id": 9,
"title": JamiStrings.callRecording

View File

@ -42,8 +42,8 @@ ListSelectionView {
"AdvancedSettingsPage": Qt.resolvedUrl("components/AdvancedSettingsPage.qml"),
"SystemSettingsPage": Qt.resolvedUrl("components/SystemSettingsPage.qml"),
"AppearanceSettingsPage": Qt.resolvedUrl("components/AppearanceSettingsPage.qml"),
"Chat": Qt.resolvedUrl("components/ChatSettingsPage.qml"),
"LocationSharingSettingsPage": Qt.resolvedUrl("components/LocationSharingSettingsPage.qml"),
"FileTransferSettingsPage": Qt.resolvedUrl("components/FileTransferSettingsPage.qml"),
"CallRecordingSettingsPage": Qt.resolvedUrl("components/CallRecordingSettingsPage.qml"),
"TroubleshootSettingsPage": Qt.resolvedUrl("components/TroubleshootSettingsPage.qml"),
"UpdateSettingsPage": Qt.resolvedUrl("components/UpdateSettingsPage.qml"),
@ -119,10 +119,10 @@ ListSelectionView {
replace(currentItem, viewNode.resources["AppearanceSettingsPage"], StackView.Immediate);
break;
case 7:
replace(currentItem, viewNode.resources["LocationSharingSettingsPage"], StackView.Immediate);
replace(currentItem, viewNode.resources["Chat"], StackView.Immediate);
break;
case 8:
replace(currentItem, viewNode.resources["FileTransferSettingsPage"], StackView.Immediate);
replace(currentItem, viewNode.resources["LocationSharingSettingsPage"], StackView.Immediate);
break;
case 9:
replace(currentItem, viewNode.resources["CallRecordingSettingsPage"], StackView.Immediate);

Some files were not shown because too many files have changed in this diff Show More