Compare commits

...

86 Commits

Author SHA1 Message Date
c689997456 misc: bump daemon
Change-Id: I031ed502a8181309a04886b9abb482cdc3b0beb0
2023-11-23 14:55:29 -05:00
8fc1ba342c donations: update start date key
Change-Id: Ie35b2854da7165ee95018165b325698dcf0378ca
2023-11-23 14:20:32 -05:00
6b313e193d misc: update projectcredits.html
Change-Id: I529321c4ee0877b1ab158122fa183e733edf238a
2023-11-23 10:46:39 -05:00
167550abc3 misc: get donation date from settings manager
Change-Id: I4c39625b95efa1ad272ffa503e1f29228928adeb
2023-11-23 09:30:13 -05:00
7736b5c34c add sponsor button on gitHub repo
GitLab: https://git.jami.net/savoirfairelinux/jami-client-android/-/issues/1459
Change-Id: I32f11d8ccbeec0e051210394891ced63ae684ad4
2023-11-23 08:52:36 -05:00
1dd0ad71e9 PasswordDialog: new design
GitLab: #1417
Change-Id: Ic543f6b4332af15bbaea3c7b97a8642ff9dd387c
2023-11-22 17:14:25 -05:00
db4e0d3767 Revert "app Store: disable donations"
This reverts commit a433974340.

Change-Id: I1a3b663a3f6813ed0481bf4a118330cf5d974424
2023-11-22 11:51:36 -05:00
b1e129b0e2 AboutPopup: new design
GitLab: #1417
Change-Id: Ibbdaa074ac6e6a7c778ef4710f334e23d04dd121
2023-11-22 10:31:59 -05:00
3818885095 NoUserNamePopup: new design
GitLab: #1417
Change-Id: I6abc313f78ca37b9cce76137f85c4a9656b98feb
2023-11-21 14:46:07 -05:00
6cbda2cea1 LinkDeviceDialog: new design
GitLab: #1417
Change-Id: I8039355efcac28bf6ccc39dea1c785ef7f86b9f4
2023-11-21 14:45:11 -05:00
2656769a59 UserProfile popup: new design
GitLab: #1417
Change-Id: I1801f0e92e43679548ceb5be84041cba96ed7519
2023-11-21 14:37:47 -05:00
86c1bf8373 CallInformationOverlay: new design
GitLab: #1417
Change-Id: I11267d130f83421f23656f65925996caded6c10b
2023-11-21 14:35:59 -05:00
f7bf2899f7 BaseModalDialog: scrollbar added when popups are too big
GitLab: #1417
Change-Id: I7b41398656269e474cbce90ace2ba1c89c5048df
2023-11-21 11:53:37 -05:00
dc7c366afa donation: update campaign dates
Change-Id: Idc8b568234270f897936e60453e22a66d6d8624d
2023-11-28 10:58:42 -05:00
b7c3f3b553 CreateAccountPage: new design
GitLab: #1417

Change-Id: I15db389e699ae030c3657746b68f0c5ab2af31a6
2023-11-21 08:33:24 -05:00
a6b7ef76f8 DeleteAccountDialog: new design
GitLab: #1417
Change-Id: I4f701c130722f4c25ea4d13525ab111368139f98
2023-11-21 08:27:44 -05:00
17d6d56af4 i18n: automatic bump
Change-Id: I222865d7344c4d996833c6bff4d354364b627440
2023-11-20 16:42:40 -05:00
b5443e6484 misc: bump daemon submodule
Change-Id: Ifc98e6e9551a0d62194de1dddf27cc79d0cff645
2023-11-17 14:59:19 -05:00
3d0db97a17 TextField: new design
GitLab: #1417
Change-Id: I89c97d02250b9b283f85a006b13c97e4bb54ee32
2023-11-17 14:58:17 -05:00
23413a8f45 BaseModalDialog: redesign popups and add standard buttons
GitLab: #1417
Change-Id: I8693ff36d313c730b6d8fa2ea7586d1a71d582d7
2023-11-17 14:43:16 -05:00
7f414f652e callmodel: remove old TODO
This was causing some weird conference states for swarm-call

https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/916

Change-Id: I87ada927f223bc325eb0f62307c6dda51b330330
2023-11-17 09:42:39 -05:00
c6833d69fb conversationmodel: do not add calls to wrong conversations
newCall already handle everything

Change-Id: I6c9f5b1e50960b3d45e4fde198f0fc67ecfad020
GitLab: #1432
2023-11-17 09:42:39 -05:00
238547506f qrencode: windows: bump submodule version
Use version with latest vcxproj.

Change-Id: I61cb0168e684566f47cf32e993371a25539d4c8a
2023-11-16 16:37:25 -05:00
cb68ee560c PluginEnabled: remove all unnecessary method to enabled plugin on client
Gitlab: #1382

Change-Id: I5fdef9bfcb5b400c3eefa776ec441b63b0847cca
2023-11-16 07:19:19 -05:00
517f87826d misc: don't use 2 AppSettingsManager objects
Injects the primary instance into PluginVersionManager instead.

Change-Id: I3269f048a805a069d30f3ab1bec5c4be755a35cb
2023-11-15 12:02:31 -05:00
0725683727 main: prevents use-after-frees on app exit
Forces the QML exposed objects to be destroyed prior to top-level mainapplication objects like the AppSettingsManager.

Change-Id: I4183ee20890c7faae39e37bd9f7060ff50ae0db8
2023-11-15 12:02:27 -05:00
52f95ac8ed ptt: use 1 instance only and register as a QML singleton
- Prevents resetting the app-scope context property which prevents the Windows global listener callback from working.
- Removes unused QScopedPointers

Change-Id: I836d803d5a1f4093e241330c1e5dd478c743ed54
2023-11-15 12:02:20 -05:00
8d41ab6eb9 misc: bump daemon
Change-Id: Ie82dd09bde90df6d3df684198a5f561cba167347
2023-11-15 11:23:03 -05:00
b4b1cda9e6 screensharing: remove unsupported options for wayland
https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/13

Change-Id: I177104e8b2faabd356293fb704372918d7e5969a
2023-11-15 09:06:59 -05:00
e46a123609 build: windows: remove qrencode-win32 patching
Changes to a more maintained repo source.

Change-Id: Ie9903761ad8cb740b79552f59dc851976c1ef9da
2023-11-14 14:44:30 -05:00
8e33a6125f build: windows: only init the required client submodules
Change-Id: Ia4ad3e76962fac38c8f482fb7892b259a968ce5f
2023-11-14 14:44:30 -05:00
3e17a9b247 cmake: windows: add the jami-core to the project
Change-Id: Ieeeb8bbf3d032fb9595b6f76a49ab8027dad7d99
2023-11-14 14:44:30 -05:00
38e5d0967a JamiIdentifier: change icons
GitLab: #1417
Change-Id: I30e32098a53941cdb393a472764c47a333a87449
2023-11-14 08:20:44 -05:00
5ed836f34e i18n: automatic bump
Change-Id: I98012490ec3b46fc0ac358e51887f03e149f7594
2023-11-13 16:42:36 -05:00
7b55954245 misc: bump daemon
Change-Id: I3e9183624309384906a39531ea3e543716e5cfa5
2023-11-10 14:24:34 -05:00
8c75ac8a1f UpdateManager: fix to be able to update if needed
Gitlab: #1426

Change-Id: Ib6bda9d03fad23fe896ad76bda3d6fd52a1e2dbb
2023-11-10 13:20:50 -05:00
92546c7358 misc: bump daemon
Change-Id: Ie504f7953fefb62278d498c3b97e11f777a06754
2023-11-09 15:33:46 -05:00
855b023349 TextEdit: disable persistent mode and made right clickable the text
Change-Id: If8f92dfdba20005fe8430bfbe880167061301b95
2023-11-08 11:15:38 -05:00
a0f0dd132a cmake: update options (submodule on by default, option for libwrap)
Change-Id: I1b1d30da4c89af12f811075185095830a3a39157
2023-11-07 13:58:36 -05:00
428756e568 contactmodel: do not emit contactAdded for already added contact
Change-Id: I226c804181e88b47d5d361d84caaf0db23e09e6c
2023-11-07 13:20:04 -05:00
04a8dfa468 callmodel: fix mute video
Change-Id: Ic0c05b9099bc21b8ee936cbe3aef641534d55f77
2023-11-07 11:31:21 -05:00
cbef11a9ca sip: remove non necessary settings
Change-Id: Ic0ab68601b3cb801898c427494bbc996027fd6da
GitLab: #1394
GitLab: #1395
2023-11-07 08:41:17 -05:00
122628239c WelcomePage: align keyboard and about button
Change-Id: I4e391e7bb37ebcbe797bf808a10973df6484d465
GitLab: #1400
2023-11-07 08:40:48 -05:00
8922387217 ParticipantOverlayButton: avoid bugguy and custom tooltip
Change-Id: Ic92e0931227b8b0f0c9b297036367def7133eb06
GitLab: #1403
2023-11-07 08:40:32 -05:00
be85034d78 build: support enabling ASAN for daemon + contrib + client
Change-Id: Ie014285e46feb82577125b68677b19d94005789f
2023-11-07 08:40:09 -05:00
885f05ba12 welcomepage: fix color and size for about button
Change-Id: Ia8eaaca2ab3eace4dcf9cd4a06d59ef343c44da3
GitLab: #1401
2023-11-07 08:39:32 -05:00
60cfc8938f sip: update call settings visibility
Change-Id: Ib0c32198ead5d540bae201039d20dbf3b45e9f23
GitLab: #1407
2023-11-06 11:51:49 -05:00
31c5cead63 misc: use jami-core
Change-Id: I081b2575d78352e091c60c9ac80d8c8c5512e9b0
2023-11-03 15:41:03 -04:00
1c576a7a3a DocumentPreview: fix reference error
Change-Id: Ib01469a53fbb9da5eef7ec7389ecd5123ab14625
GitLab: #1402
2023-11-03 10:24:42 -04:00
92be4fa7dc build: windows: optionally use pywinmake
Change-Id: Ib0b41428f00945c9bcab2f7d68355c2128c0e68f
2023-11-02 15:06:32 -04:00
6360e52eb5 Connection monitoring: ajust dark theme color
Change-Id: I1225f1039859946ef2154820d45a6f9682b6ced1
2023-11-01 14:40:51 -04:00
d38858c1f3 filesharing: consider audio in the proposed list
When adding/removing a file sharing we must add/remove
not only the video but also the audio media attributes
to the media change proposal.

GitLab: https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/485
Change-Id: Ifa6be8d500a43b1c2494501a4d6a6a6f009fdb62
2023-11-01 13:52:51 -04:00
088c367485 filesharing: integrate mediaplayer API
GitLab: https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/485
Change-Id: I148f19eb76a526a5ab38c5f4a83f45ea66e348e4
2023-11-01 13:52:46 -04:00
fc7109950b swarm-call: do not create 1:1 conversation for incoming calls in swarm
There was no way to differentiate a 1:1 incoming call and a call
from a swarm, because username couldn't be checked. Now, create
conversation only if it's a 1:1 call

Change-Id: I0094967914b4888d083b9adc1d2b11de467d6f48
2023-11-01 13:52:37 -04:00
5776ab7c7d build: add a script option to clean libjami contribs
Change-Id: I6d3cdfb30e148c0e74fcd1b69b2f1d317425d691
2023-10-31 15:44:51 -04:00
d4d34ad4fc Patch menu: standardize with design
Positionning the menu, change reply icon, close menu when click a second time on the button, and add animation for all menu's buttons

Change-Id: I8567a74ba53de214305cbcf432541803d921f60e
2023-10-31 07:37:39 -04:00
86d55fa985 i18n: automatic bump
Change-Id: If3dbab4b02784722ee2b7785bcf14be58d0fd615
2023-10-30 16:42:38 -04:00
303acbda64 packaging: add python-six to opensuse leap 15.4 (qtwebengine)
Change-Id: Ica84f3169cfe95be9097dce50e311d1e09f65723
2023-10-30 14:23:01 -04:00
a433974340 app Store: disable donations
Change-Id: I359cf1cd538a87f12f0e931b8b2948cf1c721cce
2023-10-30 09:45:44 -04:00
7a759dab7a Push-To-Talk : add global and local ptt
It works with a Pimpl which the right pttlistener.cpp depending
on the platform you are on (macOs, windows or X11). It is a
global PTT which listen to key events during calls. If the
global PTT is not supported, a local PTT is set.

https://git.jami.net/savoirfairelinux/jami-project/-/issues/1402

Change-Id: I8399800966c737bb8e8a656ecbb6af7ac7cdde8c
2023-10-30 09:31:26 -04:00
d2e87150b4 misc: fix build on fedora 39
Change-Id: I0b64db0a418e9992dcafa053c762e153a65515b8
2023-10-30 08:40:46 -04:00
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
291 changed files with 108354 additions and 75330 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
custom: ['https://jami.net/whydonate/']
lfx_crowdfunding: jami-a-gnu-package

2
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "3rdparty/qrencode-win32"]
path = 3rdparty/qrencode-win32
url = https://github.com/BlueDragon747/qrencode-win32.git
url = https://github.com/blizzard4591/qrencode-win32.git
ignore = dirty
[submodule "3rdparty/libqrencode"]
url = https://github.com/fukuchi/libqrencode.git

View File

@ -29,12 +29,40 @@ else()
project(jami)
endif()
option(WITH_DAEMON_SUBMODULE "Build with daemon submodule" OFF)
option(WITH_DAEMON_SUBMODULE "Build with daemon submodule" ON)
option(JAMICORE_AS_SUBDIR "Build Jami-core as a subdir dependency" OFF)
option(ENABLE_TESTS "Build with tests" OFF)
option(WITH_WEBENGINE "Build with WebEngine" ON)
if(WITH_WEBENGINE)
add_definitions(-DWITH_WEBENGINE)
endif()
option(ENABLE_LIBWRAP "Enable libwrap (single process mode)" ON)
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
OR ENABLE_LIBWRAP
# because mocks use the same interface present in qtwrapper/
OR ENABLE_TEST)
set(ENABLE_LIBWRAP true)
endif()
option(ENABLE_ASAN "Enable address sanitization" OFF)
if(ENABLE_ASAN AND NOT MSVC)
message(STATUS "Address sanitization enabled for client")
# Add AddressSanitizer flags for both compiler and linker
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()
# jami-core
if(NOT WITH_DAEMON_SUBMODULE)
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/../daemon)
else()
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/daemon)
endif()
# For now only MSVC is supported for building Jami-core within the
# client cmake.
if(JAMICORE_AS_SUBDIR)
add_subdirectory(${DAEMON_DIR})
endif()
# init some variables for includes, libs, etc.
set(CLIENT_INCLUDE_DIRS, "")
@ -43,21 +71,16 @@ set(CLIENT_LIBS, "")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb")
if(NOT MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb")
endif()
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Main project directories:
# jami-daemon
if(NOT WITH_DAEMON_SUBMODULE)
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/../daemon)
else()
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/daemon)
endif()
# src
set(LIBCLIENT_SRC_DIR ${PROJECT_SOURCE_DIR}/src/libclient)
set(APP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/app)
@ -89,16 +112,6 @@ else()
message(FATAL_ERROR "Qt 6.4 or higher is required. Found ${QT_VERSION}")
endif()
if(MSVC)
set(DEFAULT_BUILD_TYPE "Debug")
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
STRING "Choose the type of build." FORCE)
endif()
set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE}")
endif()
# libjamiclient
add_subdirectory(${LIBCLIENT_SRC_DIR})
@ -244,6 +257,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}/connectioninfolistmodel.cpp
${APP_SRC_DIR}/pluginversionmanager.cpp)
set(COMMON_HEADERS
@ -310,8 +325,9 @@ 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
${APP_SRC_DIR}/pttlistener.h)
# For libavutil/avframe.
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")
@ -347,10 +363,6 @@ if(MSVC)
# preprocessor defines
add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG)
# dependencies
set(QRENCODE_DIR
${PROJECT_SOURCE_DIR}/3rdparty/qrencode-win32/qrencode-win32)
# compiler options
add_compile_options(
/wd4068 /wd4099 /wd4189 /wd4267 /wd4577 /wd4467 /wd4715 /wd4828)
@ -368,12 +380,13 @@ if(MSVC)
"/NODEFAULTLIB:LIBCMT")
# client deps
set(QRENCODE_LIB
${QRENCODE_DIR}/vc8/qrcodelib/x64/Release-Lib/qrcodelib.lib)
set(QRENCODE_DIR ${PROJECT_SOURCE_DIR}/3rdparty/qrencode-win32/qrencode-win32)
file(GLOB_RECURSE QRENCODE_LIB ${QRENCODE_DIR}/qrcodelib.lib)
file(GLOB_RECURSE QRENCODE_INCLUDE ${QRENCODE_DIR}/qrencode.h)
get_filename_component(QRENCODE_INCLUDE_DIR ${QRENCODE_INCLUDE} DIRECTORY)
# daemon
set(JAMID_SRC_PATH ${DAEMON_DIR}/contrib/msvc/include)
set(JAMID_LIB ${DAEMON_DIR}/build/x64/ReleaseLib_win32/bin/libjami.lib)
set(GNUTLS_LIB ${DAEMON_DIR}/contrib/msvc/lib/x64/libgnutls.lib)
# Beta config
@ -389,7 +402,7 @@ if(MSVC)
include_directories(
${JAMID_SRC_PATH}
${LIBCLIENT_SRC_DIR}
${QRENCODE_DIR})
${QRENCODE_INCLUDE_DIR})
elseif (NOT APPLE)
list(APPEND COMMON_SOURCES
${APP_SRC_DIR}/xrectsel.c
@ -493,6 +506,29 @@ else()
OPTIONAL_COMPONENTS LinguistTools)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
if (DEFINED ENV{XDG_SESSION_TYPE})
if ($ENV{XDG_SESSION_TYPE} STREQUAL "x11")
set(PTT_PLATFORM "x11")
list(APPEND COMMON_HEADER ${APP_SRC_DIR}/platform/X11/xcbkeyboard.H)
# TODO: add Wayland support
endif ()
endif ()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(PTT_PLATFORM "windows")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(PTT_PLATFORM "macos")
endif ()
if (NOT ${PTT_PLATFORM} STREQUAL "")
message(STATUS "Platform: ${PTT_PLATFORM}")
add_definitions(-DHAVE_GLOBAL_PTT)
list(APPEND COMMON_SOURCES ${APP_SRC_DIR}/platform/${PTT_PLATFORM}/pttlistener.cpp)
else ()
message(WARNING "Global push-to-talk not supported.")
list(APPEND COMMON_SOURCES ${APP_SRC_DIR}/platform/local/pttlistener.cpp)
endif ()
# common includes
include_directories(
${PROJECT_SOURCE_DIR}
@ -546,7 +582,7 @@ if(MSVC)
WIN32_EXECUTABLE TRUE)
list(APPEND CLIENT_LIBS
${JAMID_LIB}
${LIBJAMI_LIB}
${GNUTLS_LIB}
${LIBCLIENT_NAME}
${QT_LIBS}
@ -593,7 +629,6 @@ elseif (NOT APPLE)
${GLIB_LIBRARIES}
${GIO_LIBRARIES})
# Installation rules
install(
TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin)
@ -724,7 +759,7 @@ else()
list(APPEND CLIENT_LIBS
"-framework AVFoundation"
"-framework CoreAudio -framework CoreMedia -framework CoreVideo"
"-framework VideoToolbox -framework AudioUnit"
"-framework VideoToolbox -framework AudioUnit -framework Carbon"
"-framework Security"
compression
resolv

110
build.py
View File

@ -28,6 +28,7 @@ import shutil
import subprocess
import sys
import time
import re
OSX_DISTRIBUTION_NAME = "osx"
WIN32_DISTRIBUTION_NAME = "win32"
@ -363,10 +364,10 @@ def cwd(path):
def run_install(args):
# Platforms with special compilation scripts
if args.distribution == WIN32_DISTRIBUTION_NAME:
with cwd('daemon/compat/msvc'):
execute_script(
['python winmake.py -iv '
f'-s {args.sdk} -b daemon'])
if not args.pywinmake:
with cwd('daemon/compat/msvc'):
execute_script([f'python winmake.py -iv -s {args.sdk} -b daemon'])
build_windows = 'extras/scripts/build-windows.py'
execute_script([f'python {build_windows} --init'])
execute_script([f'python {build_windows} --qt={args.qt}'])
@ -386,6 +387,8 @@ def run_install(args):
install_args.append('-u')
if args.debug:
install_args.append('-d')
if args.asan:
install_args.append('-A')
if args.no_libwrap:
install_args.append('-W')
if args.no_webengine:
@ -458,6 +461,93 @@ def run_clean():
'git submodule foreach git clean -xfd'])
def clean_contribs(contribs):
"""
Helper to clean one or more of the libjami contribs.
Takes a list of contrib names(space separated) to clean, or 'all' to clean all contribs.
Contribs are assumed to be in the contrib_dir: daemon/contrib
Artifacts to remove include:
- build directory: <contrib_dir>/<native_dir>/<contrib_name>
- build stamp: <contrib_dir>/<native_dir>/.<contrib_name>
- tarball: <contrib_dir>/tarballs/<contrib_name>*.tar.*
- build artifacts (we don't care about the contents of share):
- <contrib_dir>/<abi_triplet>/bin/<contrib_name>
- <contrib_dir>/<abi_triplet>/lib/<contrib_name>*
- <contrib_dir>/<abi_triplet>/include/<contrib_name>*
"""
# Not supported on Windows
if platform.system() == 'Windows':
print('Cleaning contribs is not supported on Windows. Exiting.')
sys.exit(1)
# Assume we are using the submodule here.
contrib_dir = 'daemon/contrib'
sub_dirs = os.listdir(contrib_dir)
# Let's find the abi triplet:
# The abi_triplet is 3 parts: <arch>-<vendor>-<sys> and should be the only directory
# named like that in the contrib directory. We can use a regex to find it.
triplet_pattern = re.compile(r'^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+-[a-zA-Z0-9_]+$')
def is_triplet(s):
return bool(triplet_pattern.match(s))
abi_triplet = ''
for sub_dir in sub_dirs:
if is_triplet(sub_dir):
abi_triplet = sub_dir
break
# If we didn't find the abi triplet, we need to stop.
if abi_triplet == '':
print('Could not find the abi triplet for the contribs. Exiting.')
sys.exit(1)
# Let's find the native build source directory (native-*)
native_dir = ''
for sub_dir in sub_dirs:
if sub_dir.startswith('native'):
native_dir = os.path.join(contrib_dir, sub_dir)
break
# If we didn't find the native build source directory, we need to stop.
if native_dir == '':
print('Could not find the native build source directory. Exiting.')
sys.exit(1)
# If contribs is 'all', construct the list of all contribs from the contrib native directory
# list of directories only
if contribs == ['all']:
contribs = [d for d in os.listdir(native_dir) if os.path.isdir(os.path.join(native_dir, d))]
# Clean each contrib
for contrib in contribs:
print(f'Cleaning contrib: {contrib} for {abi_triplet} in {native_dir}')
build_dir = os.path.join(native_dir, contrib, '*')
build_stamp = os.path.join(native_dir, f'.{contrib}*')
tarball = os.path.join(contrib_dir, 'tarballs', f'{contrib}*.tar.*')
bins = os.path.join(contrib_dir, abi_triplet, 'bin', contrib)
libs = os.path.join(contrib_dir, abi_triplet, 'lib', f'lib{contrib}*')
includes = os.path.join(contrib_dir, abi_triplet, 'include', f'{contrib}*')
# EXCEPTIONS: pjproject and ffmpeg
if contrib == 'pjproject':
libs = f' {os.path.join(contrib_dir, abi_triplet, "lib", "libpj*")}' \
f' {os.path.join(contrib_dir, abi_triplet, "lib", "libsrtp*")}'
includes = os.path.join(contrib_dir, abi_triplet, 'include', 'pj*')
elif contrib == 'ffmpeg':
libs = f' {os.path.join(contrib_dir, abi_triplet, "lib", "libav*")}' \
f' {os.path.join(contrib_dir, abi_triplet, "lib", "libsw*")}'
includes = f' {os.path.join(contrib_dir, abi_triplet, "include", "libav*")}' \
f' {os.path.join(contrib_dir, abi_triplet, "include", "libsw*")}'
# For a dry run:
# execute_script([f'find {build_dir} {build_stamp} {tarball} {bins} {libs} {includes}'], fail=False)
execute_script([f'rm -rf {build_dir} {build_stamp} {tarball} {bins} {libs} {includes}'], fail=False)
def run_run(args):
run_env = os.environ
@ -626,6 +716,8 @@ def parse_args():
ap.add_argument('--global-install', default=False, action='store_true')
ap.add_argument('--debug', default=False, action='store_true',
help='Build with debug support; run in GDB')
ap.add_argument('--asan', default=False, action='store_true',
help='Build both daemon and client with ASAN')
ap.add_argument('--background', default=False, action='store_true')
ap.add_argument('--no-priv-install', dest='priv_install',
default=True, action='store_false')
@ -640,6 +732,12 @@ def parse_args():
default=False, action='store_true',
help='Do not use Qt WebEngine.')
ap.add_argument('--arch')
ap.add_argument('--clean-contribs', nargs='+',
help='Clean the specified contribs (space separated) or \
"all" to clean all contribs before building.')
ap.add_argument('--pywinmake', dest='pywinmake',
default=False, action='store_true',
help='Build Jami for Windows using pywinmake')
dist = choose_distribution()
@ -686,6 +784,10 @@ def choose_distribution():
def main():
parsed_args = parse_args()
# Clean contribs if specified first.
if parsed_args.clean_contribs:
clean_contribs(parsed_args.clean_contribs)
if parsed_args.dependencies:
run_dependencies(parsed_args)

2
daemon

Submodule daemon updated: a87f1aaef4...8c1c74f0f3

View File

@ -53,33 +53,36 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES_orig ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so;.dll")
# Add the lib prefix for Windows checks.
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib;")
endif()
set(LIBJAMI_NAMES
jami-core
jami
ring
)
if(WITH_DAEMON_SUBMODULE)
find_library(LIBJAMI_LIB NAMES jami ring
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
PATHS ${DAEMON_DIR}/src/.libs
PATHS ${CMAKE_INSTALL_PREFIX}/lib
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
PATHS ${CMAKE_INSTALL_PREFIX}/bin
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/bin
NO_DEFAULT_PATH)
else()
# Search only in these given PATHS.
find_library(LIBJAMI_LIB NAMES jami ring
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
PATHS ${LIBJAMI_BUILD_DIR}/.libs
PATHS ${RING_BUILD_DIR}/.libs
PATHS ${CMAKE_INSTALL_PREFIX}/lib
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
PATHS ${CMAKE_INSTALL_PREFIX}/bin
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/bin
NO_DEFAULT_PATH)
# Search elsewhere as well (e.g. system-wide).
if(NOT LIBJAMI_LIB)
find_library(LIBJAMI_LIB NAMES jami ring)
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES})
endif()
endif()
@ -88,27 +91,29 @@ if(NOT LIBJAMI_LIB)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.lib")
if(WITH_DAEMON_SUBMODULE)
find_library(LIBJAMI_LIB NAMES jami ring
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
PATHS ${DAEMON_DIR}/src/.libs
PATHS ${CMAKE_INSTALL_PREFIX}
PATHS ${CMAKE_INSTALL_PREFIX}/lib
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/lib
NO_DEFAULT_PATH)
else()
# Search only in these given PATHS.
find_library(LIBJAMI_LIB NAMES jami ring
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
PATHS ${LIBJAMI_BUILD_DIR}/.libs
PATHS ${RING_BUILD_DIR}/.libs
PATHS ${CMAKE_INSTALL_PREFIX}
PATHS ${CMAKE_INSTALL_PREFIX}/lib
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/lib
NO_DEFAULT_PATH)
# Search elsewhere as well (e.g. system-wide).
if(NOT LIBJAMI_LIB)
find_library(LIBJAMI_LIB NAMES jami ring)
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES})
endif()
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows")

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,104 @@
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.10 \
cups-devel
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
CMD ["/opt/build-package-rpm.sh"]

View File

@ -70,6 +70,7 @@ RUN zypper --non-interactive install -y \
nodejs12 \
mozilla-nss-devel \
python-xml \
python-six \
libxcb* \
libxkb* \
libX11-devel \

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"
@ -84,6 +91,15 @@ cat qtbase/src/corelib/global/qendian.h
sed -i 's,#include <string.h>,#include <string.h>\n#include <limits>,g' qtbase/src/corelib/global/qfloat16.h
sed -i 's,#include <QtCore/qbytearray.h>,#include <QtCore/qbytearray.h>\n#include <limits>,g' qtbase/src/corelib/text/qbytearraymatcher.h
cat qtwebengine/configure.cmake
#https://bugreports.qt.io/browse/QTBUG-117979
if test -f "/usr/bin/python3.10"; then
/usr/bin/python3.10 -m venv env
source env/bin/activate
python -m pip install html5lib
python -m pip install six
fi
# recent gcc version do not like lto from qt
CXXFLAGS="${CXXFLAGS} -fno-lto" CFLAGS="${CFLAGS} -fno-lto" LDFLAGS="$(CFLAGS) ${LDFLAGS}" ./configure \
-opensource \

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

@ -1,5 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Build, test, and package the project.
@ -65,6 +65,15 @@ this_dir = os.path.dirname(os.path.realpath(__file__))
repo_root_dir = os.path.abspath(os.path.join(this_dir, os.pardir, os.pardir))
build_dir = os.path.join(repo_root_dir, "build")
def get_latest_toolset_version():
"""Get the latest toolset version."""
# Get the visual studio version. Use only the major version number.
# Then: toolset = 2022 ? "v143" : 2019 ? "v142" : 2017 ? "v141" : "v140"
vs_ver = get_vs_prop("installationVersion")
if vs_ver is None:
return None
vs_ver = int(vs_ver.split(".")[0])
return "v143" if vs_ver >= 16 else "v142" if vs_ver >= 15 else "v141"
def find_latest_qt_path():
"""Find the latest Qt installation path."""
@ -190,40 +199,31 @@ def init_submodules():
"""Initialize any git submodules in the project."""
print("Initializing submodules...")
if execute_cmd(["git", "submodule", "update", "--init"], False):
# Init the client submodules for Windows other than the daemon.
submodules = [
"3rdparty/qrencode-win32",
"3rdparty/SortFilterProxyModel",
"3rdparty/md4c",
"3rdparty/tidy-html5",
]
if execute_cmd(["git", "submodule", "update", "--init" ] + submodules,
False):
print("Submodule initialization error.")
else:
if execute_cmd(["git", "submodule", "update", "--recursive"], False):
print("Submodule recursive checkout error.")
else:
print("Submodule recursive checkout finished.")
sys.exit(1)
def build_deps():
"""Build the dependencies for the project."""
print('Patching and building qrencode')
apply_cmd = [
'git',
'apply',
'--reject',
'--ignore-whitespace',
'--whitespace=fix'
]
print('Building qrencode')
qrencode_dir = os.path.join(repo_root_dir, '3rdparty', 'qrencode-win32')
patch_file = os.path.join(repo_root_dir, 'qrencode-win32.patch')
apply_cmd.append(patch_file)
if execute_cmd(apply_cmd, False, None, qrencode_dir):
print("Couldn't patch qrencode-win32.")
vs_env_vars = {}
vs_env_vars.update(get_vs_env())
msbuild_args = get_ms_build_args("x64", "Release-Lib")
toolset = get_latest_toolset_version()
print(f'Using toolset {toolset}')
msbuild_args = get_ms_build_args("x64", "Release-Lib", toolset)
proj_path = os.path.join(
qrencode_dir, "qrencode-win32", "vc8", "qrcodelib", "qrcodelib.vcxproj"
qrencode_dir, "qrencode-win32", "vc15", "qrcodelib", "qrcodelib.vcxproj"
)
build_project(msbuild_args, proj_path, vs_env_vars)
@ -264,17 +264,15 @@ def build(config_str, qt_dir, tests):
# Get the daemon bin/include directories.
daemon_dir = os.path.join(repo_root_dir, "daemon")
daemon_bin_dir = os.path.join(
daemon_dir, "build", "x64", "ReleaseLib_win32", "bin")
daemon_bin_dir = os.path.join(daemon_dir, "build", "lib")
# We need to update the minimum SDK version to be able to
# build with system theme support
cmake_options = [
"-DWITH_DAEMON_SUBMODULE=ON",
"-DJAMICORE_AS_SUBDIR=ON",
"-DCMAKE_PREFIX_PATH=" + qt_dir,
"-DCMAKE_MSVCIDE_RUN_PATH=" + qt_dir + "\\bin",
"-DCMAKE_INSTALL_PREFIX=" + daemon_bin_dir,
"-DLIBJAMI_INCLUDE_DIR=" + daemon_dir + "\\src\\jami",
"-DCMAKE_INSTALL_PREFIX=" + os.getcwd(),
"-DCMAKE_SYSTEM_VERSION=" + WIN_SDK_VERSION,
"-DCMAKE_BUILD_TYPE=" + "Release",
"-DENABLE_TESTS=" + str(tests).lower(),

View File

@ -43,9 +43,10 @@ proc='1'
priv_install=true
enable_libwrap=true
enable_webengine=true
asan=
arch=''
while getopts gsc:dQ:P:p:uWwa: OPT; do
while getopts gsc:dQ:P:p:uWwa:A OPT; do
case "$OPT" in
g)
global='true'
@ -77,6 +78,9 @@ while getopts gsc:dQ:P:p:uWwa: OPT; do
a)
arch="${OPTARG}"
;;
A)
asan='true'
;;
\?)
exit 1
;;
@ -116,7 +120,7 @@ else
mkdir -p contrib/native
(
cd contrib/native
../bootstrap ${prefix:+"--prefix=$prefix"}
../bootstrap ${prefix:+"--prefix=$prefix"} ${asan:+"--enable-asan"}
make -j"${proc}"
)
@ -135,6 +139,10 @@ else
CONFIGURE_FLAGS+=" --enable-debug"
fi
if [ "${asan}" = "true" ]; then
CONFIGURE_FLAGS+=" --enable-asan"
fi
# Build the daemon itself.
test -f configure || ./autogen.sh
@ -183,6 +191,11 @@ client_cmake_flags=(-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
-DCMAKE_PREFIX_PATH="${qtpath}"
-DENABLE_LIBWRAP="${enable_libwrap}"
-DWITH_WEBENGINE="${enable_webengine}")
if [ "${asan}" = "true" ]; then
client_cmake_flags+=(-DENABLE_ASAN=true)
fi
if [[ "$OSTYPE" == "darwin"* ]]; then
#detect arch for macos
CMAKE_OSX_ARCHITECTURES="arm64"

View File

@ -1,243 +0,0 @@
From 261d830b9b4126d76519db0e6b6b51b5a730eb40 Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Tue, 4 Dec 2018 17:42:43 -0500
Subject: [PATCH] b
---
.../vc8/qrcodelib/qrcodelib.vcxproj | 129 +++++++++++++++++-
1 file changed, 125 insertions(+), 4 deletions(-)
diff --git a/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj b/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
index aabc6b6..8d8293b 100644
--- a/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
+++ b/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
@@ -5,45 +5,84 @@
<Configuration>Debug-Dll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-Dll|x64">
+ <Configuration>Debug-Dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Debug-Lib|Win32">
<Configuration>Debug-Lib</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-Lib|x64">
+ <Configuration>Debug-Lib</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Release-Dll|Win32">
<Configuration>Release-Dll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Release-Dll|x64">
+ <Configuration>Release-Dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Release-Lib|Win32">
<Configuration>Release-Lib</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Release-Lib|x64">
+ <Configuration>Release-Lib</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9A90BF5C-84B0-41F6-B83C-C20EADC1F46C}</ProjectGuid>
<RootNamespace>qrcodelib</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
- <PlatformToolset>v110_xp</PlatformToolset>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
- <PlatformToolset>v110_xp</PlatformToolset>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <PlatformToolset>v110_xp</PlatformToolset>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <PlatformToolset>v110_xp</PlatformToolset>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -52,15 +91,27 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
@@ -70,11 +121,17 @@
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
<OutDir>../.build/$(Configuration)\</OutDir>
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<OutDir>../.build/$(Configuration)\</OutDir>
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
@@ -104,6 +161,26 @@
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>libpng15d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\qrcode\png;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>qrcodelib.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -124,6 +201,26 @@
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>libpng15.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\qrcode\png;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>qrcodelib.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
@@ -137,6 +234,19 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -147,6 +257,17 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="qrcodelib.cpp" />
<ClCompile Include="..\..\bitstream.c" />
--
2.19.0.windows.1

View File

@ -36,5 +36,7 @@
<string>Jami requires to access your microphone to make calls and record audio</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>NSAppleEventsUsageDescription</key>
<string>Jami requires to monitor global key events for push-to-talk functionality.</string>
</dict>
</plist>

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,4 @@
<svg id="assignment_ind_black_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path id="Path_311" data-name="Path 311" d="M0,0H24V24H0Z" fill="none"/>
<path id="Path_312" data-name="Path 312" d="M19,3H14.82A2.988,2.988,0,0,0,9.18,3H5A2.006,2.006,0,0,0,3,5V19a2.006,2.006,0,0,0,2,2H19a2.006,2.006,0,0,0,2-2V5A2.006,2.006,0,0,0,19,3Zm-7-.25a.767.767,0,1,1-.55.25A.749.749,0,0,1,12,2.75ZM19,19H5V5H19ZM12,6a3,3,0,1,0,3,3A3.009,3.009,0,0,0,12,6Zm0,4a1,1,0,1,1,1-1A1,1,0,0,1,12,10ZM6,16.47V18H18V16.47c0-2.5-3.97-3.58-6-3.58S6,13.96,6,16.47ZM8.31,16A7.011,7.011,0,0,1,12,14.88,6.982,6.982,0,0,1,15.69,16Z" fill="#005699"/>
</svg>

After

Width:  |  Height:  |  Size: 666 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="brush_black_24dp" opacity="1">
<path id="Path_323" data-name="Path 323" d="M0,0H24V24H0Z" fill="none"/>
<path id="Path_324" data-name="Path 324" d="M7,16a1,1,0,0,1,1,1,2.006,2.006,0,0,1-2,2,2.825,2.825,0,0,1-.5-.05A3.947,3.947,0,0,0,6,17a1,1,0,0,1,1-1M18.67,3a1.024,1.024,0,0,0-.71.29L9,12.25,11.75,15l8.96-8.96a1,1,0,0,0,0-1.41L19.37,3.29a.976.976,0,0,0-.7-.29ZM7,14a3,3,0,0,0-3,3,2.029,2.029,0,0,1-2,2,5.174,5.174,0,0,0,4,2,4,4,0,0,0,4-4A3,3,0,0,0,7,14Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View File

@ -1,9 +1,4 @@
<?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 d="M20.4,2.2H8.5c-0.9,0-1.6,0.7-1.6,1.6v2.9H3.6C2.7,6.7,2,7.4,2,8.3v11.9c0,0.9,0.7,1.6,1.6,1.6h11.9c0.9,0,1.6-0.7,1.6-1.6
v-2.9h3.3c0.9,0,1.6-0.7,1.6-1.6V3.8C22,2.9,21.3,2.2,20.4,2.2z M15.8,20.2c0,0.2-0.1,0.3-0.3,0.3H3.6c-0.2,0-0.3-0.1-0.3-0.3V8.3
C3.3,8.2,3.4,8,3.6,8h11.9c0.2,0,0.3,0.1,0.3,0.3V20.2z M20.7,15.7c0,0.2-0.1,0.3-0.3,0.3h-3.3V8.3c0-0.9-0.7-1.6-1.6-1.6H8.2V3.8
c0-0.2,0.1-0.3,0.3-0.3h11.9c0.2,0,0.3,0.1,0.3,0.3V15.7z"/>
</svg>
<svg id="content_copy_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path id="Path_305" data-name="Path 305" d="M0,0H24V24H0Z" fill="none"/>
<path id="Path_306" data-name="Path 306" d="M16,1H4A2.006,2.006,0,0,0,2,3V17H4V3H16Zm3,4H8A2.006,2.006,0,0,0,6,7V21a2.006,2.006,0,0,0,2,2H19a2.006,2.006,0,0,0,2-2V7A2.006,2.006,0,0,0,19,5Zm0,16H8V7H19Z" fill="#005699"/>
</svg>

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 411 B

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

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="21.5" viewBox="0 0 18 21.5">
<path id="notification_important_black_24dp" d="M10.01,21.01a1.99,1.99,0,0,0,3.98,0ZM12,6a5,5,0,0,1,5,5v7H7V11A5,5,0,0,1,12,6Zm0-4.5A1.5,1.5,0,0,0,10.5,3V4.17A6.993,6.993,0,0,0,5,11v6L3,19v1H21V19l-2-2V11a6.993,6.993,0,0,0-5.5-6.83V3A1.5,1.5,0,0,0,12,1.5ZM11,8h2v4H11Zm0,6h2v2H11Z" transform="translate(-3 -1.5)" fill="#c02"/>
</svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1,4 @@
<svg id="person_outline_black_24dp_1_" data-name="person_outline_black_24dp (1)" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path id="Path_325" data-name="Path 325" d="M0,0H24V24H0Z" fill="none"/>
<path id="Path_326" data-name="Path 326" d="M12,5.9A2.1,2.1,0,1,1,9.9,8,2.1,2.1,0,0,1,12,5.9m0,9c2.97,0,6.1,1.46,6.1,2.1v1.1H5.9V17c0-.64,3.13-2.1,6.1-2.1M12,4a4,4,0,1,0,4,4A4,4,0,0,0,12,4Zm0,9c-2.67,0-8,1.34-8,4v3H20V17C20,14.34,14.67,13,12,13Z"/>
</svg>

After

Width:  |  Height:  |  Size: 493 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M39 38v-8.7q0-2.7-1.9-4.6-1.9-1.9-4.6-1.9H11.7l7.7 7.7-2.1 2.1L6 21.3 17.3 10l2.1 2.1-7.7 7.7h20.8q3.9 0 6.7 2.775Q42 25.35 42 29.3V38Z"/></svg>

Before

Width:  |  Height:  |  Size: 216 B

View File

@ -0,0 +1,4 @@
<svg id="reply_black_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path id="Path_333" data-name="Path 333" d="M0,0H24V24H0Z" fill="none"/>
<path id="Path_334" data-name="Path 334" d="M10,9V5L3,12l7,7V14.9c5,0,8.5,1.6,11,5.1C20,15,17,10,10,9Z" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 364 B

View File

@ -1,11 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Share</title>
<g id="Icones" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Share" fill="#000000" stroke="#000000" stroke-width="0.75">
<g id="SHARE" transform="translate(4.000000, 2.000000)">
<path d="M13.5,15.00005 C14.6105,15.00005 15.5,15.88955 15.5,17.00005 C15.5,18.1103 14.6105,19.00005 13.5,19.00005 C12.3895,19.00005 11.5,18.1103 11.5,17.00005 C11.5,15.88955 12.3895,15.00005 13.5,15.00005 M3,8.00005 C4.1105,8.00005 5,8.88955 5,10.00005 C5,11.11055 4.1105,12.00005 3,12.00005 C1.8895,12.00005 1,11.11055 1,10.00005 C1,8.88955 1.8895,8.00005 3,8.00005 M13.5,1.00005 C14.6105,1.00005 15.5,1.88955 15.5,3.00005 C15.5,4.11055 14.6105,5.00005 13.5,5.00005 C12.3895,5.00005 11.5,4.11055 11.5,3.00005 C11.5,1.88955 12.3895,1.00005 13.5,1.00005 M13.5,5e-05 C11.849,5e-05 10.5,1.34905 10.5,3.00005 C10.5,3.47555 10.6135,3.92755 10.8125,4.32805 L5.086,7.85155 C4.545,7.3263 3.8095,7.00005 3,7.00005 C1.349,7.00005 0,8.34905 0,10.00005 C0,11.65105 1.349,13.00005 3,13.00005 C3.81525,13.00005 4.552,12.67255 5.09375,12.14055 L10.82025,15.66405 C10.6165,16.0683 10.5,16.51805 10.5,17.00005 C10.5,18.65105 11.849,20.00005 13.5,20.00005 C15.151,20.00005 16.5,18.65105 16.5,17.00005 C16.5,15.34905 15.151,14.00005 13.5,14.00005 C12.6905,14.00005 11.955,14.3263 11.414,14.85155 L5.6875,11.32805 C5.8865,10.92755 6,10.47555 6,10.00005 C6,9.51805 5.8835,9.06855 5.67975,8.66405 L11.40625,5.14055 C11.94825,5.67255 12.68475,6.00005 13.5,6.00005 C15.151,6.00005 16.5,4.65105 16.5,3.00005 C16.5,1.34905 15.151,5e-05 13.5,5e-05" id="Fill-1"></path>
</g>
</g>
<svg id="share_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="Group_66" data-name="Group 66">
<rect id="Rectangle_305" data-name="Rectangle 305" width="24" height="24" fill="none"/>
</g>
<g id="Group_68" data-name="Group 68">
<g id="Group_67" data-name="Group 67">
<path id="Path_302" data-name="Path 302" d="M3,11h8V3H3ZM5,5H9V9H5Z" fill="#005699"/>
<path id="Path_303" data-name="Path 303" d="M3,21h8V13H3Zm2-6H9v4H5Z" fill="#005699"/>
<path id="Path_304" data-name="Path 304" d="M13,3v8h8V3Zm6,6H15V5h4Z" fill="#005699"/>
<rect id="Rectangle_306" data-name="Rectangle 306" width="2" height="2" transform="translate(19 19)" fill="#005699"/>
<rect id="Rectangle_307" data-name="Rectangle 307" width="2" height="2" transform="translate(13 13)" fill="#005699"/>
<rect id="Rectangle_308" data-name="Rectangle 308" width="2" height="2" transform="translate(15 15)" fill="#005699"/>
<rect id="Rectangle_309" data-name="Rectangle 309" width="2" height="2" transform="translate(13 17)" fill="#005699"/>
<rect id="Rectangle_310" data-name="Rectangle 310" width="2" height="2" transform="translate(15 19)" fill="#005699"/>
<rect id="Rectangle_311" data-name="Rectangle 311" width="2" height="2" transform="translate(17 17)" fill="#005699"/>
<rect id="Rectangle_312" data-name="Rectangle 312" width="2" height="2" transform="translate(17 13)" fill="#005699"/>
<rect id="Rectangle_313" data-name="Rectangle 313" width="2" height="2" transform="translate(19 15)" fill="#005699"/>
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 KiB

View File

@ -1,21 +1,27 @@
<h3 align="center"><span style="font-weight:600"> CREATED BY:</span></h3>
<h4 align="left"><span style="font-weight:600"> Created by</span></h4>
<p>Adrien Béraud<br>
Albert Babí<br>
Alexandre Lision<br>
Alexandr Sergheev<br>
Alexandre Viau<br>
Alexander Lussier-Cullen<br>
Aline Bonnet<br>
Aline Gondim Santos<br>
Alireza Toghiani<br>
Amin Bandali<br>
AmirHossein Naghshzan<br>
Amna Snene<br>
Andreas Traczyk<br>
Anthony Léonard<br>
Brando Tovar<br>
Capucine Berthet<br>
Charles-Francis Damedey<br>
Cyrille Béraud<br>
Dorina Mosku<br>
Eden Abitbol<br>
Édric Milaret<br>
Éloi Bail<br>
Emma Falkiewitz<br>
Emmanuel Lepage-Vallée<br>
Fadi Shehadeh<br>
Franck Laurent<br>
@ -26,7 +32,10 @@ Hadrien De Sousa<br>
Hugo Lefeuvre<br>
Julien Grossholtz<br>
Kateryna Kostiuk<br>
Léo Banno-Cloutier<br>
Liam Courdoson<br>
Loïc Siret<br>
Mathéo Joseph<br>
Mingrui Zhang<br>
Mohamed Chibani<br>
Mohamed Amine Younes Bouacida<br>
@ -40,6 +49,7 @@ Peymane Marandi<br>
Philippe Gorley<br>
Pierre Duchemin<br>
Pierre Lespagnol<br>
Pierre Nicolas<br>
Raphaël Brulé<br>
Rayan Osseiran<br>
Romain Bertozzi<br>
@ -53,7 +63,8 @@ Thibault Wittemberg<br>
Thomas Ballasi<br>
Trevor Tabah<br>
Vsevolod Ivanov<br>
Xavier Jouslin de Noray<br>
Yang Wang<br></p>
<h3 align="center"><span style="font-weight:600"> ARTWORK BY:</span></h3>
<h4 align="left"><span style="font-weight:600"> Artwork by</span></h4>
<p>Charlotte Hoffmann<br>
Marianne Forget<br></p>

View File

@ -273,7 +273,8 @@ ApplicationWindow {
"infoText": infoText,
"buttonTitles": [JamiStrings.optionOk],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": []
"buttonCallBacks": [],
"buttonRoles": [DialogButtonBox.AcceptRole]
});
}
@ -285,7 +286,8 @@ ApplicationWindow {
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": [function () {
AppVersionManager.applyUpdates(switchToBeta);
}]
}],
"buttonRoles": [DialogButtonBox.AcceptRole, DialogButtonBox.RejectRole]
});
}

View File

@ -64,7 +64,11 @@ extern const QString defaultDownloadPath;
X(ShowMardownOption, false) \
X(ChatViewEnterIsNewLine, false) \
X(ShowSendOption, false) \
X(DonateVisibleDate, "2999-02-01 05:00")
X(Donation2023VisibleDate, "2023-11-27 05:00") \
X(IsDonationVisible, true) \
X(Donation2023EndDate, "2024-01-31 00:00") \
X(EnablePtt, false) \
X(pttKey, 36)
/*
* A class to expose settings keys in both c++ and QML.
* Note: this is using a non-constructable class instead of a

View File

@ -195,8 +195,28 @@ AvAdapter::shareFile(const QString& filePath)
auto callId = lrcInstance_->getCurrentCallId();
if (!callId.isEmpty()) {
muteCamera_ = !isCapturing();
lrcInstance_->getCurrentCallModel()
->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING);
auto resource = QString("%1%2%3")
.arg(libjami::Media::VideoProtocolPrefix::FILE)
.arg(libjami::Media::VideoProtocolPrefix::SEPARATOR)
.arg(QUrl(filePath).toLocalFile());
Utils::oneShotConnect(&lrcInstance_->avModel(),
&lrc::api::AVModel::fileOpened,
this,
[this, callId, filePath, resource](bool hasAudio, bool hasVideo) {
// TODO: allow audio only sharing
if (hasVideo) { // only start sharing if video is available
lrcInstance_->avModel().pausePlayer(resource, false);
lrcInstance_->avModel().setAutoRestart(resource, true);
lrcInstance_->getCurrentCallModel()
->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING, false, hasAudio);
} else {
// Close media player because we are not going to start sharing
lrcInstance_->avModel().closeMediaPlayer(resource);
}
});
lrcInstance_->avModel().createMediaPlayer(resource);
}
}
@ -300,14 +320,16 @@ AvAdapter::stopSharing(const QString& source)
->removeMedia(callId,
libjami::Media::Details::MEDIA_TYPE_VIDEO,
libjami::Media::VideoProtocolPrefix::DISPLAY,
muteCamera_);
muteCamera_,
true);
} else {
qDebug() << "Stopping file: " << source;
lrcInstance_->getCurrentCallModel()
->removeMedia(callId,
libjami::Media::Details::MEDIA_TYPE_VIDEO,
libjami::Media::VideoProtocolPrefix::FILE,
muteCamera_);
muteCamera_,
true);
}
}
}

View File

@ -7,6 +7,7 @@
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Author: Capucine Berthet <capucine.berthet@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
@ -25,29 +26,36 @@
#include "calladapter.h"
#include "systemtray.h"
#include "utils.h"
#include "qmlregister.h"
#include <QApplication>
#include <QTimer>
#include <QJsonObject>
#include "appsettingsmanager.h"
#include <api/callmodel.h>
#include <api/callparticipantsmodel.h>
#include <media_const.h>
CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent)
#include <QApplication>
#include <QTimer>
#include <QJsonObject>
CallAdapter::CallAdapter(AppSettingsManager* settingsManager,
SystemTray* systemTray,
LRCInstance* instance,
QObject* parent)
: QmlAdapterBase(instance, parent)
, systemTray_(systemTray)
, callInformationListModel_(std::make_unique<CallInformationListModel>())
, listener_(new PTTListener(settingsManager, this))
{
// Expose the Push-to-talk listener to QML as a singleton
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, listener_, "PttListener");
set_callInformationList(QVariant::fromValue(callInformationListModel_.get()));
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
overlayModel_.reset(new CallOverlayModel(lrcInstance_, this));
overlayModel_.reset(new CallOverlayModel(lrcInstance_, listener_, this));
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, overlayModel_.get(), "CallOverlayModel");
accountId_ = lrcInstance_->get_currentAccountId();
@ -97,6 +105,65 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
&LRCInstance::selectedConvUidChanged,
this,
&CallAdapter::saveConferenceSubcalls);
#ifdef HAVE_GLOBAL_PTT
connectPtt();
#endif
}
CallAdapter::~CallAdapter()
{
#ifdef HAVE_GLOBAL_PTT
disconnectPtt();
#endif
}
void
CallAdapter::connectPtt()
{
#ifdef HAVE_GLOBAL_PTT
if (listener_->getPttState()) {
QObject::connect(
listener_,
&PTTListener::pttKeyPressed,
this,
[this]() {
const auto callId
= lrcInstance_->getCallIdForConversationUid(lrcInstance_->get_selectedConvUid(),
accountId_);
try {
isMicrophoneMuted_ = isMuted(callId);
if (isMicrophoneMuted_)
muteAudioToggle();
} catch (const std::exception& e) {
qWarning() << e.what();
}
},
Qt::QueuedConnection);
QObject::connect(
listener_,
&PTTListener::pttKeyReleased,
this,
[this]() {
if (isMicrophoneMuted_) {
muteAudioToggle();
}
},
Qt::QueuedConnection);
}
#endif
}
void
CallAdapter::disconnectPtt()
{
#ifdef HAVE_GLOBAL_PTT
if (listener_->getPttState()) {
QObject::disconnect(listener_, &PTTListener::pttKeyPressed, this, nullptr);
QObject::disconnect(listener_, &PTTListener::pttKeyReleased, this, nullptr);
}
#endif
}
void
@ -172,6 +239,12 @@ CallAdapter::onCallStarted(const QString& callId)
// update call Information list by adding the new information related to the callId
callInformationListModel_->addElement(
qMakePair(callId, callModel->advancedInformationForCallId(callId)));
if (listener_->getPttState()) {
#ifdef HAVE_GLOBAL_PTT
listener_->startListening();
toMute += callId;
#endif
}
}
void
@ -181,6 +254,10 @@ CallAdapter::onCallEnded(const QString& callId)
return;
// update call Information list by removing information related to the callId
callInformationListModel_->removeElement(callId);
#ifdef HAVE_GLOBAL_PTT
if (listener_->getPttState() && !hasCall_)
listener_->stopListening();
#endif
}
void
@ -271,6 +348,15 @@ CallAdapter::onCallStatusChanged(const QString& callId, int code)
}
}
void
CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
{
Q_UNUSED(accountId)
auto mute = toMute.remove(callId);
if (mute && listener_->getPttState())
muteAudioToggle();
}
void
CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
{
@ -494,6 +580,12 @@ CallAdapter::connectCallModel(const QString& accountId)
QOverload<const QString&, int>::of(&CallAdapter::onCallStatusChanged),
Qt::UniqueConnection);
connect(accInfo.callModel.get(),
&CallModel::callInfosChanged,
this,
&CallAdapter::onCallInfosChanged,
Qt::UniqueConnection);
connect(accInfo.callModel.get(),
&CallModel::callAddedToConference,
this,
@ -816,6 +908,23 @@ CallAdapter::holdThisCallToggle()
}
}
bool
CallAdapter::isMuted(const QString& callId)
{
if (!(callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId))) {
auto* callModel = lrcInstance_->getCurrentCallModel();
if (callModel->hasCall(callId)) {
const auto callInfo = lrcInstance_->getCurrentCallModel()->getCall(callId);
auto mute = false;
for (const auto& m : callInfo.mediaList)
if (m[libjami::Media::MediaAttributeKey::LABEL] == "audio_0")
mute = m[libjami::Media::MediaAttributeKey::MUTED] == TRUE_STR;
return mute;
}
}
throw std::runtime_error("CallAdapter::isMuted: callId is empty or call does not exist");
}
void
CallAdapter::muteAudioToggle()
{
@ -825,13 +934,10 @@ CallAdapter::muteAudioToggle()
return;
}
auto* callModel = lrcInstance_->getCurrentCallModel();
if (callModel->hasCall(callId)) {
const auto callInfo = lrcInstance_->getCurrentCallModel()->getCall(callId);
auto mute = false;
for (const auto& m : callInfo.mediaList)
if (m[libjami::Media::MediaAttributeKey::LABEL] == "audio_0")
mute = m[libjami::Media::MediaAttributeKey::MUTED] == FALSE_STR;
callModel->muteMedia(callId, "audio_0", mute);
try {
callModel->muteMedia(callId, "audio_0", !isMuted(callId));
} catch (const std::exception& e) {
qWarning() << e.what();
}
}
@ -877,7 +983,8 @@ CallAdapter::muteCameraToggle()
callModel->removeMedia(callId,
libjami::Media::Details::MEDIA_TYPE_VIDEO,
libjami::Media::VideoProtocolPrefix::CAMERA,
mute);
mute,
false);
else
callModel->addMedia(callId,
lrcInstance_->avModel().getCurrentVideoCaptureDevice(),

View File

@ -25,6 +25,10 @@
#include "screensaver.h"
#include "calloverlaymodel.h"
#ifdef HAVE_GLOBAL_PTT
#include "pttlistener.h"
#endif
#include <QObject>
#include <QString>
#include <QVariant>
@ -33,6 +37,7 @@
#include "callInformationListModel.h"
class SystemTray;
class AppSettingsManager;
class CallAdapter final : public QmlAdapterBase
{
@ -45,8 +50,11 @@ public:
enum MuteStates { UNMUTED, LOCAL_MUTED, MODERATOR_MUTED, BOTH_MUTED };
Q_ENUM(MuteStates)
explicit CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent = nullptr);
~CallAdapter() = default;
explicit CallAdapter(AppSettingsManager* settingsManager,
SystemTray* systemTray,
LRCInstance* instance,
QObject* parent = nullptr);
~CallAdapter();
public:
Q_INVOKABLE void startTimerInformation();
@ -76,6 +84,9 @@ public:
Q_INVOKABLE void holdThisCallToggle();
Q_INVOKABLE void recordThisCallToggle();
Q_INVOKABLE void muteAudioToggle();
Q_INVOKABLE bool isMuted(const QString& callId);
Q_INVOKABLE void connectPtt();
Q_INVOKABLE void disconnectPtt();
Q_INVOKABLE void muteCameraToggle();
Q_INVOKABLE bool isRecordingThisCall();
Q_INVOKABLE void muteParticipant(const QString& accountUri,
@ -109,6 +120,7 @@ public Q_SLOTS:
void onCallAddedToConference(const QString& callId, const QString& confId);
void onCallStarted(const QString& callId);
void onCallEnded(const QString& callId);
void onCallInfosChanged(const QString& accountId, const QString& callId);
private:
void showNotification(const QString& accountId, const QString& convUid);
@ -121,6 +133,9 @@ private:
SystemTray* systemTray_;
QScopedPointer<CallOverlayModel> overlayModel_;
VectorString currentConfSubcalls_;
std::unique_ptr<CallInformationListModel> callInformationListModel_;
PTTListener* listener_;
bool isMicrophoneMuted_ = true;
QSet<QString> toMute;
};

View File

@ -22,6 +22,7 @@
#include <QEvent>
#include <QMouseEvent>
#include <QQuickWindow>
#include <QKeyEvent>
IndexRangeFilterProxyModel::IndexRangeFilterProxyModel(QAbstractListModel* parent)
: QSortFilterProxyModel(parent)
@ -74,10 +75,10 @@ PendingConferenceesListModel::data(const QModelIndex& index, int role) const
using namespace PendingConferences;
// WARNING: not swarm ready
lrc::api::call::Status callStatus;
QString pendingConferenceeCallId;
QString pendingConferenceeContactUri;
ContactModel* contactModel {nullptr};
lrc::api::call::Status callStatus;
try {
auto callModel = lrcInstance_->getCurrentCallModel();
auto currentPendingConferenceeInfo = callModel->getPendingConferencees().at(index.row());
@ -268,7 +269,7 @@ CallControlListModel::clearData()
data_.clear();
}
CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
CallOverlayModel::CallOverlayModel(LRCInstance* instance, PTTListener* listener, QObject* parent)
: QObject(parent)
, lrcInstance_(instance)
, primaryModel_(new CallControlListModel(this))
@ -283,6 +284,10 @@ CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
this,
&CallOverlayModel::setControlRanges);
overflowVisibleModel_->setFilterRole(CallControl::Role::UrgentCount);
#ifndef HAVE_GLOBAL_PTT
listener_ = listener;
#endif
}
void
@ -386,6 +391,19 @@ CallOverlayModel::eventFilter(QObject* object, QEvent* event)
}
}
}
#ifndef HAVE_GLOBAL_PTT
else if (event->type() == QEvent::KeyPress && listener_->getPttState()) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == listener_->getCurrentKey() && !keyEvent->isAutoRepeat()) {
Q_EMIT pttKeyPressed();
}
} else if (event->type() == QEvent::KeyRelease && listener_->getPttState()) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == listener_->getCurrentKey() && !keyEvent->isAutoRepeat()) {
Q_EMIT pttKeyReleased();
}
}
#endif
return QObject::eventFilter(object, event);
}

View File

@ -21,6 +21,9 @@
#include "lrcinstance.h"
#include "qtutils.h"
#include "mainapplication.h"
#include "pttlistener.h"
#include <QAbstractListModel>
#include <QObject>
@ -36,7 +39,7 @@
namespace CallControl {
Q_NAMESPACE
enum Role { ItemAction = Qt::UserRole + 1, UrgentCount, Enabled};
enum Role { ItemAction = Qt::UserRole + 1, UrgentCount, Enabled };
Q_ENUM_NS(Role)
struct Item
@ -121,7 +124,7 @@ class CallOverlayModel : public QObject
QML_PROPERTY(int, overflowIndex)
public:
CallOverlayModel(LRCInstance* instance, QObject* parent = nullptr);
CallOverlayModel(LRCInstance* instance, PTTListener* listener, QObject* parent = nullptr);
Q_INVOKABLE void addPrimaryControl(const QVariant& action, bool enabled);
Q_INVOKABLE void addSecondaryControl(const QVariant& action, bool enabled);
@ -142,6 +145,8 @@ public:
Q_SIGNALS:
void mouseMoved(QQuickItem* item);
void pttKeyPressed();
void pttKeyReleased();
private Q_SLOTS:
void setControlRanges();
@ -157,4 +162,8 @@ private:
PendingConferenceesListModel* pendingConferenceesModel_;
QList<QQuickItem*> watchedItems_;
#ifndef HAVE_GLOBAL_PTT
PTTListener* listener_ {nullptr};
#endif
};

View File

@ -28,17 +28,27 @@ Popup {
// convient access to closePolicy
property bool autoClose: true
property alias backgroundColor: container.color
property alias backgroundOpacity: container.background.opacity
property alias title: titleText.text
property var popupcontainerSubContentLoader: containerSubContentLoader
property bool topLayoutVisible: true
property bool closeButtonVisible: true
property int button1Role
property int button2Role
property alias button1: action1
property alias button2: action2
property alias popupContentLoadStatus: containerSubContentLoader.status
property alias popupContent: containerSubContentLoader.sourceComponent
property int popupContentMargins: JamiTheme.preferredMarginSize
property int popupMargins: 30
property int buttonMargin: 20
property int maximumPopupWidth: 600
parent: Overlay.overlay
anchors.centerIn: parent
modal: true
padding: popupContentMargins
focus: true
closePolicy: autoClose ? (Popup.CloseOnEscape | Popup.CloseOnPressOutside) : Popup.NoAutoClose
@ -47,13 +57,13 @@ Popup {
id: container
property color color: JamiTheme.secondaryBackgroundColor
padding: popupContentMargins
anchors.margins: popupContentMargins
anchors.centerIn: parent
leftPadding: popupMargins
bottomPadding: action1.visible || action2.visible ? 10 :popupMargins
background: Rectangle {
id: bgRect
radius: JamiTheme.modalPopupRadius
radius: 5
color: container.color
layer.enabled: true
layer.effect: DropShadow {
@ -70,37 +80,95 @@ Popup {
contentItem: ColumnLayout {
id: contentLayout
RowLayout {
Layout.preferredWidth: parent.width
Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: topLayoutVisible
JamiPushButton {
id: closeButton
Label {
id: titleText
visible: closeButtonVisible
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
font.pointSize: JamiTheme.menuFontSize
color: JamiTheme.textColor
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 20
Layout.preferredWidth: 20
Layout.topMargin: 5
Layout.rightMargin: 5
imageColor: hovered ? JamiTheme.textColor : JamiTheme.buttonTintedGreyHovered
normalColor: "transparent"
visible: text.length > 0
}
JamiPushButton {
id: closeButton
Layout.alignment: Qt.AlignRight
imageColor: "grey"
normalColor: "transparent"
source: JamiResources.round_close_24dp_svg
onClicked: close()
}
source: JamiResources.round_close_24dp_svg
onClicked: close()
}
Loader {
id: containerSubContentLoader
Label {
id: titleText
Layout.rightMargin: popupMargins
Layout.bottomMargin: 20
Layout.topMargin: closeButtonVisible ? 0 : 30
Layout.alignment: Qt.AlignLeft
font.pointSize: JamiTheme.menuFontSize
color: JamiTheme.textColor
font.bold: true
visible: text.length > 0
}
JamiFlickable {
id: flickable
Layout.fillHeight: true
Layout.preferredHeight: Math.min(contentHeight, root.height)
Layout.preferredWidth: contentItem.childrenRect.width
Layout.rightMargin: popupMargins
Layout.alignment: Qt.AlignCenter
contentHeight: contentItem.childrenRect.height
contentItem.children: Loader {
id: containerSubContentLoader
}
ScrollBar.horizontal.visible: false
}
DialogButtonBox {
id: buttonBox
Layout.alignment: Qt.AlignRight
spacing: 1.5
background: Rectangle {
color: "transparent"
width: buttonBox.childrenRect.width
height: buttonBox.childrenRect.height
}
visible: action1.text.length > 0
contentHeight: childrenRect.height + 14
MaterialButton {
id: action1
visible: text.length > 0
rightPadding: buttonMargin
leftPadding: buttonMargin
tertiary: true
autoAccelerator: true
DialogButtonBox.buttonRole: root.button1Role
}
MaterialButton {
id: action2
visible: text.length > 0
rightPadding: buttonMargin
leftPadding: buttonMargin
tertiary: true
autoAccelerator: true
DialogButtonBox.buttonRole: root.button2Role
}
}
}
}

View File

@ -0,0 +1,110 @@
/*
* 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
BaseModalDialog {
id: pttPage
property string bestName: ""
property string accountId: ""
property int pressedKey: Qt.Key_unknown
closeButtonVisible: false
button1.text: JamiStrings.assign
button2.text: JamiStrings.cancel
button1Role: DialogButtonBox.ApplyRole
button2Role: DialogButtonBox.RejectRole
button1.onClicked: {
if (!(pressedKey === Qt.Key_unknown)){
PttListener.setPttKey(pressedKey);
choiceMade(pressedKey);
}
close();
}
button2.onClicked: close();
signal accepted
signal choiceMade(int chosenKey)
title: JamiStrings.changeShortcut
popupContent: ColumnLayout {
id: deleteAccountContentColumnLayout
anchors.centerIn: parent
spacing: JamiTheme.preferredMarginSize
Component.onCompleted: keyItem.forceActiveFocus()
Label {
id: instructionLabel
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: JamiTheme.preferredDialogWidth - 4*JamiTheme.preferredMarginSize
color: JamiTheme.textColor
text: JamiStrings.assignmentIndication
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: JamiTheme.textFontSize
font.kerning: true
wrapMode: Text.Wrap
}
Label {
id: keyLabel
Layout.alignment: Qt.AlignCenter
color: JamiTheme.blackColor
wrapMode: Text.WordWrap
text: ""
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
background: Rectangle {
id: backgroundRect
anchors.centerIn: parent
width: keyLabel.width + 2 * JamiTheme.preferredMarginSize
height: keyLabel.height + JamiTheme.preferredMarginSize
color: JamiTheme.lightGrey_
border.color: JamiTheme.darkGreyColor
radius: 4
}
}
Item {
id: keyItem
Keys.onPressed: (event)=>{
keyLabel.text = PttListener.keyToString(event.key);
pressedKey = event.key;
}
}
}
}

View File

@ -30,6 +30,19 @@ BaseModalDialog {
property string confirmLabel: ""
property string textLabel: ""
closeButtonVisible: false
button1.text: confirmLabel
button1.contentColorProvider: JamiTheme.redButtonColor
button1.onClicked: {
close();
accepted();
}
button2.text: JamiStrings.optionCancel
button2.onClicked: close()
button1Role: DialogButtonBox.AcceptRole
button2Role: DialogButtonBox.RejectRole
popupContent: ColumnLayout {
id: column
@ -49,51 +62,5 @@ BaseModalDialog {
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
RowLayout {
spacing: 16
Layout.alignment: Qt.AlignCenter
Layout.topMargin: JamiTheme.preferredMarginSize
MaterialButton {
id: primaryBtn
Layout.alignment: Qt.AlignHCenter
text: root.confirmLabel
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
color: JamiTheme.buttonTintedRed
hoveredColor: JamiTheme.buttonTintedRedHovered
pressedColor: JamiTheme.buttonTintedRedPressed
secondary: true
autoAccelerator: true
onClicked: {
close();
accepted();
}
}
MaterialButton {
id: btnCancel
Layout.alignment: Qt.AlignHCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
autoAccelerator: true
text: JamiStrings.optionCancel
onClicked: close()
}
}
}
}

View File

@ -29,6 +29,11 @@ BaseModalDialog {
autoClose: false
button1.text: JamiStrings.optionOk
button1Role: DialogButtonBox.AcceptRole
button1.visible: connectionFailed
button1.onClicked: Qt.quit()
Connections {
target: {
if (Qt.platform.os.toString() !== "windows" && Qt.platform.os.toString() !== "osx")
@ -51,10 +56,10 @@ BaseModalDialog {
onPopupContentLoadStatusChanged: {
if (popupContentLoadStatus === Loader.Ready) {
root.height = Qt.binding(function () {
return popupContentLoader.item.implicitHeight + 50;
return popupContent.implicitHeight + 50;
});
root.width = Qt.binding(function () {
return popupContentLoader.item.implicitWidth + 50;
return popupContent.implicitWidth + 50;
});
}
}
@ -94,24 +99,5 @@ BaseModalDialog {
smooth: true
fillMode: Image.PreserveAspectFit
}
MaterialButton {
id: btnOk
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
preferredWidth: JamiTheme.preferredFieldWidth / 2
visible: connectionFailed
text: JamiStrings.optionOk
color: JamiTheme.buttonTintedBlue
hoveredColor: JamiTheme.buttonTintedBlueHovered
pressedColor: JamiTheme.buttonTintedBluePressed
secondary: true
autoAccelerator: true
onClicked: Qt.quit()
}
}
}

View File

@ -26,22 +26,51 @@ BaseModalDialog {
id: root
property bool isSIP: false
property string bestName: ""
property string accountId: ""
signal accepted
title: JamiStrings.deleteAccount
closeButtonVisible: false
button1.text: JamiStrings.optionDelete
button1Role: DialogButtonBox.DestructiveRole
button1.onClicked: {
button1.enabled = false;
busyInd.running = true;
AccountAdapter.deleteCurrentAccount();
close();
accepted();
}
button2.text: JamiStrings.optionCancel
button2Role: DialogButtonBox.RejectRole
button2.onClicked: close();
button1.contentColorProvider: JamiTheme.deleteRedButton
BusyIndicator {
id: busyInd
running: false
Connections {
target: root
function onClosed() {
busyInd.running = false;
}
}
}
popupContent: ColumnLayout {
id: deleteAccountContentColumnLayout
anchors.centerIn: parent
spacing: 10
Label {
id: labelDeletion
Layout.alignment: Qt.AlignHCenter
Layout.alignment: Qt.AlignLeft
Layout.maximumWidth: root.width - 4*JamiTheme.preferredMarginSize
Layout.bottomMargin: 5
color: JamiTheme.textColor
text: JamiStrings.confirmDeleteQuestion
@ -52,124 +81,199 @@ BaseModalDialog {
wrapMode: Text.Wrap
}
Label {
id: labelBestId
Rectangle {
id: accountRectangle
Layout.alignment: Qt.AlignHCenter
color: JamiTheme.backgroundRectangleColor
color: JamiTheme.textColor
text: bestName
Layout.preferredWidth: parent.width
Layout.preferredHeight: userProfileDialogLayout.height
Layout.maximumWidth: root.width - 80
font.pointSize: JamiTheme.textFontSize
font.kerning: true
font.bold: true
wrapMode: Text.Wrap
}
radius: 5
Label {
id: labelAccountHash
ColumnLayout {
id: userProfileDialogLayout
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
anchors.centerIn: parent
width: parent.width
color: JamiTheme.textColor
text: accountId
RowLayout {
Layout.margins: 10
Layout.fillWidth: true
font.pointSize: JamiTheme.textFontSize
font.kerning: true
spacing: 10
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
Avatar {
id: currentAccountImage
Label {
id: labelWarning
Layout.preferredWidth: 56
Layout.preferredHeight: 56
visible: !isSIP
imageId: CurrentAccount.id
showPresenceIndicator: false
mode: Avatar.Mode.Account
}
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
ColumnLayout {
text: JamiStrings.deleteAccountInfos
spacing: 10
Layout.alignment: Qt.AlignLeft
font.pointSize: JamiTheme.textFontSize
font.kerning: true
// Visible when user alias is not empty and not equal to id.
TextEdit {
id: accountAlias
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
Layout.alignment: Qt.AlignLeft
color: JamiTheme.redColor
}
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
RowLayout {
spacing: 16
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
color: JamiTheme.textColor
visible: accountDisplayName.text ? (CurrentAccount.alias === CurrentAccount.bestId ? false : true) : false
selectByMouse: true
readOnly: true
MaterialButton {
id: btnDelete
wrapMode: Text.NoWrap
text: textMetricsAccountAliasText.elidedText
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: JamiTheme.preferredMarginSize
TextMetrics {
id: textMetricsAccountAliasText
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
font: accountAlias.font
text: CurrentAccount.alias
elideWidth: root.width - 200
elide: Qt.ElideMiddle
}
}
color: JamiTheme.buttonTintedRed
hoveredColor: JamiTheme.buttonTintedRedHovered
pressedColor: JamiTheme.buttonTintedRedPressed
secondary: true
autoAccelerator: true
// Visible when user name is not empty or equals to id.
TextEdit {
id: accountDisplayName
text: JamiStrings.optionDelete
Layout.alignment: Qt.AlignLeft
Connections {
target: root
function onClosed() {
btnDelete.enabled = true;
font.pointSize: JamiTheme.textFontSize
font.kerning: true
color: JamiTheme.faddedFontColor
visible: text.length && text !== CurrentAccount.alias
readOnly: true
selectByMouse: true
wrapMode: Text.NoWrap
text: textMetricsAccountDisplayNameText.elidedText
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
TextMetrics {
id: textMetricsAccountDisplayNameText
font: accountDisplayName.font
text: CurrentAccount.bestId
elideWidth: root.width - 200
elide: Qt.ElideMiddle
}
}
}
}
Rectangle {
Layout.fillWidth: true
onClicked: {
btnDelete.enabled = false;
busyInd.running = true;
AccountAdapter.deleteCurrentAccount();
close();
accepted();
}
}
radius: 5
color: root.backgroundColor
BusyIndicator {
id: busyInd
running: false
Layout.preferredHeight: accountId.height + 10
Layout.margins: 10
Layout.topMargin: 0
RowLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Connections {
target: root
function onClosed() {
busyInd.running = false;
spacing: 20
Text {
id: identifierText
font.pointSize: JamiTheme.textFontSize
text: JamiStrings.identifier
color: JamiTheme.faddedFontColor
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
}
Label {
id: accountId
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: root.width - 250
Layout.rightMargin: JamiTheme.preferredMarginSize
font.pointSize: JamiTheme.textFontSize
font.kerning: true
color: JamiTheme.textColor
elide: Text.ElideRight
text: CurrentAccount.uri
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
Rectangle {
id: warningRectangle
MaterialButton {
id: btnCancel
color: JamiTheme.warningRedRectangle
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.preferredWidth: parent.width
Layout.preferredHeight: labelWarning.height + 20
Layout.maximumWidth: root.width - 80
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
radius: 5
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
RowLayout{
id: warningLayout
text: JamiStrings.optionCancel
autoAccelerator: true
anchors.centerIn: parent
anchors.margins: 15
width: accountRectangle.width
onClicked: close()
Image{
id: warningIcon
Layout.fillWidth: true
Layout.leftMargin: 15
source: JamiResources.notification_important_24dp_svg
fillMode: Image.PreserveAspectFit
}
Label {
id: labelWarning
Layout.fillWidth: true
Layout.margins: 15
visible: !isSIP
text: JamiStrings.deleteAccountInfos
font.pointSize: JamiTheme.textFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
color: JamiTheme.redColor
}
}
}
}

View File

@ -25,25 +25,23 @@ import net.jami.Constants 1.1
BaseModalDialog {
id: root
width: JamiTheme.secondaryDialogDimension
property var previousBodies: undefined
popupContent: JamiListView {
width: root.width - 4 * JamiTheme.preferredMarginSize
width: 400 - 2 * root.popupMargins
height: Math.min(count * 50, 150)
model: root.previousBodies
delegate: Rectangle {
width: root.width - 2 * JamiTheme.preferredMarginSize
width: 400 - 2 * root.popupMargins
height: Math.max(JamiTheme.menuItemsPreferredHeight, rowBody.implicitHeight)
color: index % 2 === 0 ? JamiTheme.backgroundColor : JamiTheme.secondaryBackgroundColor
RowLayout {
id: rowBody
spacing: JamiTheme.preferredMarginSize
width: parent.width
anchors.centerIn: parent
Text {
@ -58,7 +56,6 @@ BaseModalDialog {
Text {
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
TextMetrics {
id: metrics

View File

@ -71,7 +71,7 @@ Rectangle {
Text {
Layout.preferredWidth: 180
Layout.preferredWidth: root.width - 10
Layout.alignment: Qt.AlignLeft
Layout.topMargin: 8
Layout.bottomMargin: 15

View File

@ -52,7 +52,7 @@ Item {
RoundedBorderRectangle {
id: leftRect
fillColor: jamiId.backgroundColor
fillColor: JamiTheme.jamiIdBackgroundColor
Layout.preferredWidth: childrenRect.width
Layout.maximumWidth: jamiId.width - rightRect.width
Layout.preferredHeight: childrenRect.height
@ -73,7 +73,7 @@ Item {
containerWidth: 40
Layout.leftMargin: JamiTheme.pushButtonMargins
source: JamiResources.jami_id_logo_svg
color: jamiId.contentColor
color: JamiTheme.tintedBlue
}
UsernameTextEdit {
@ -81,7 +81,7 @@ Item {
visible: !readOnly
Layout.preferredHeight: 40
Layout.alignment: Qt.AlignVCenter
textColor: jamiId.contentColor
textColor: JamiTheme.tintedBlue
fontPixelSize: staticText.length > 16 || dynamicText.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
editMode: false
isPersistent: false
@ -107,7 +107,7 @@ Item {
Layout.rightMargin: JamiTheme.pushButtonMargins
Layout.maximumWidth: leftRect.width - 50
elide: Text.ElideRight
color: jamiId.contentColor
color: JamiTheme.tintedBlue
font.pixelSize : text.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
property string registeredName: CurrentAccount.registeredName
property string infohash: CurrentAccount.uri
@ -118,7 +118,7 @@ Item {
RoundedBorderRectangle {
id: rightRect
fillColor: jamiId.backgroundColor
fillColor: JamiTheme.jamiIdBackgroundColor
Layout.preferredWidth: childrenRect.width + 2 * JamiTheme.pushButtonMargins
Layout.preferredHeight: leftRect.height
@ -142,8 +142,8 @@ Item {
id: btnEdit
anchors.leftMargin: JamiTheme.pushButtonMargins
visible: CurrentAccount.registeredName === ""
border.color: enabled ? jamiId.contentColor : JamiTheme.buttonTintedBlack
imageColor: enabled ? jamiId.contentColor : JamiTheme.buttonTintedBlack
imageColor: enabled ? JamiTheme.tintedBlue : JamiTheme.buttonTintedBlack
border.color: usernameTextEdit.editMode ? jamiId.contentColor : "transparent"
enabled: {
if (!usernameTextEdit.editMode)
return true;
@ -157,7 +157,7 @@ Item {
return false;
}
}
source: usernameTextEdit.editMode ? JamiResources.check_black_24dp_svg : JamiResources.round_edit_24dp_svg
source: usernameTextEdit.editMode ? JamiResources.check_black_24dp_svg : JamiResources.assignment_ind_black_24dp_svg
toolTipText: JamiStrings.chooseUsername
onClicked: {
if (usernameTextEdit.readOnly) {
@ -167,6 +167,19 @@ Item {
usernameTextEdit.accepted();
}
}
Rectangle {
width: 10
height: 10
visible: !usernameTextEdit.editMode
anchors.top: parent.top
anchors.right: parent.right
radius: width / 2
color: JamiTheme.redDotColor
border.color: JamiTheme.jamiIdBackgroundColor
border.width: 2
}
}
JamiIdControlButton {
@ -188,7 +201,7 @@ Item {
JamiIdControlButton {
id: btnId
source: JamiResources.key_black_24dp_svg
source: JamiResources.outline_info_24dp_svg
visible: CurrentAccount.registeredName !== ""
border.color: "transparent"
toolTipText: JamiStrings.identifierURI
@ -217,7 +230,7 @@ Item {
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
border.color: jamiId.contentColor
imageColor: jamiId.contentColor
imageColor: JamiTheme.tintedBlue
duration: 0
}
}

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

@ -39,12 +39,15 @@ AbstractButton {
property var hoveredColor: JamiTheme.buttonTintedBlueHovered
property var secHoveredColor: JamiTheme.secAndTertiHoveredBackgroundColor
property var pressedColor: JamiTheme.buttonTintedBluePressed
property var checkedColor: JamiTheme.secAndTertiHoveredBackgroundColor
property bool hasIcon: animatedIconSource.length !== 0 || iconSource.length !== 0
property var preferredWidth
property real textLeftPadding
property real textRightPadding
property real fontSize: JamiTheme.buttontextFontPixelSize
property real textAlignment: Text.AlignHCenter
checkable: false
checked: false
property real buttontextHeightMargin: JamiTheme.wizardButtonHeightMargin
height: buttontextHeightMargin + textButton.height
@ -187,6 +190,8 @@ AbstractButton {
if (root.secondary || root.tertiary) {
if (root.hovered && root.enabled)
return root.secHoveredColor;
if (root.checked && root.checkable)
return root.checkedColor;
return JamiTheme.transparentColor;
}
if (root.down)

View File

@ -36,6 +36,7 @@ TextField {
}
signal keyPressed
signal rejected
property bool inputIsValid: true
@ -47,7 +48,7 @@ TextField {
property alias suffixBisIconColor: suffixBisIcon.color
property alias icon: container.data
property color accent: isActive || hovered ? prefixIconColor : JamiTheme.buttonTintedBlue
property color accent: (isActive || hovered ? prefixIconColor : JamiTheme.passwordBaselineColor)
property color baseColor: JamiTheme.primaryForegroundColor
property color textColor: JamiTheme.textColor
color: textColor
@ -87,6 +88,9 @@ TextField {
root.accepted();
}
event.accepted = true;
} else if (event.key === Qt.Key_Escape) {
root.focus = false;
root.rejected();
} else {
root.keyPressed();
}
@ -110,8 +114,11 @@ TextField {
id: overBaseLineLabel
font.pixelSize: root.font.pixelSize
anchors.baseline: root.baseline
anchors.horizontalCenter: !isSwarmDetail ? root.horizontalCenter : undefined
anchors.left: root.left
anchors.leftMargin: 32
width: root.width - 64
text: root.placeholderText
elide: Text.ElideRight
color: isSwarmDetail ? root.color : root.baseColor
visible: !root.isActive && !readOnly && root.text.toString() === ""
}
@ -202,12 +209,13 @@ TextField {
TextFieldIcon {
id: suffixBisIcon
size: 20
size: 16
anchors.right: parent.right
anchors.verticalCenter: root.verticalCenter
anchors.verticalCenterOffset: -root.bottomPadding / 2
color: suffixBisIconColor
source: suffixBisIconSrc
opacity: 1
TapHandler {
cursorShape: Qt.ArrowCursor

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

@ -87,6 +87,7 @@ Loader {
MaterialTextField {
id: displayCompField
font.pixelSize: root.fontPixelSize
readOnly: root.readOnly
text: elidedText != "" ? elidedText : staticText
@ -94,6 +95,8 @@ Loader {
isSwarmDetail: root.isSwarmDetail
isSettings: root.isSettings
textColor: root.textColor
suffixBisIconSrc: root.suffixBisIconSrc
suffixBisIconColor: root.suffixBisIconColor
placeholderText: root.placeholderText
prefixIconSrc: isSwarmDetail ? "" : root.prefixIconSrc
prefixIconColor: root.prefixIconColor
@ -122,6 +125,10 @@ Loader {
echoMode: root.echoMode
placeholderText: root.placeholderText
onAccepted: root.accepted()
onRejected: {
root.editMode = false;
text = staticText;
}
onKeyPressed: root.keyPressed()
onTextChanged: dynamicText = text
text: staticText

View File

@ -24,6 +24,8 @@ import net.jami.Constants 1.1
BaseModalDialog {
id: root
closeButtonVisible: false
enum PasswordEnteringPurpose {
ChangePassword,
ExportAccount,
@ -64,26 +66,33 @@ BaseModalDialog {
"title": title,
"infoText": info,
"buttonTitles": [JamiStrings.optionOk],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue]
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonRoles": [DialogButtonBox.AcceptRole]
});
done(success, purpose);
}
button1.text: (purpose === PasswordDialog.ExportAccount) ? JamiStrings.exportAccount : JamiStrings.change
button1Role: DialogButtonBox.ApplyRole
button1.enabled: purpose === PasswordDialog.SetPassword
popupContent: ColumnLayout {
id: popupContentColumnLayout
width: JamiTheme.preferredDialogWidth
spacing: 16
function validatePassword() {
switch (purpose) {
case PasswordDialog.ExportAccount:
btnConfirm.enabled = currentPasswordEdit.dynamicText.length > 0;
button1.enabled = currentPasswordEdit.dynamicText.length > 0;
break;
case PasswordDialog.SetPassword:
btnConfirm.enabled = passwordEdit.dynamicText.length > 0 && passwordEdit.dynamicText === confirmPasswordEdit.dynamicText;
button1.enabled = passwordEdit.dynamicText.length > 0 && passwordEdit.dynamicText === confirmPasswordEdit.dynamicText;
break;
default:
btnConfirm.enabled = currentPasswordEdit.dynamicText.length > 0 && passwordEdit.dynamicText === confirmPasswordEdit.dynamicText;
button1.enabled = currentPasswordEdit.dynamicText.length > 0 && passwordEdit.dynamicText === confirmPasswordEdit.dynamicText;
}
}
@ -104,6 +113,13 @@ BaseModalDialog {
onVisibleChanged: validatePassword()
Component.onCompleted: {
root.button1.clicked.connect(function() {
button1.enabled = false;
timerToOperate.restart();
});
}
Timer {
id: timerToOperate
@ -123,10 +139,8 @@ BaseModalDialog {
id: currentPasswordEdit
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.fillWidth: true
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.ExportAccount
placeholderText: JamiStrings.enterCurrentPassword
@ -138,10 +152,8 @@ BaseModalDialog {
id: passwordEdit
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.SetPassword
@ -154,10 +166,8 @@ BaseModalDialog {
id: confirmPasswordEdit
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: visible ? 48 : 0
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
visible: purpose === PasswordDialog.ChangePassword || purpose === PasswordDialog.SetPassword
@ -165,26 +175,5 @@ BaseModalDialog {
onDynamicTextChanged: popupContentColumnLayout.validatePassword()
}
MaterialButton {
id: btnConfirm
Layout.alignment: Qt.AlignHCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
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();
}
}
}
}

View File

@ -28,7 +28,7 @@ ModalTextEdit {
prefixIconSrc: firstEntry ? JamiResources.lock_svg : JamiResources.round_edit_24dp_svg
suffixBisIconSrc: echoMode == TextInput.Password ? JamiResources.eye_cross_svg : JamiResources.noun_eye_svg
suffixBisIconColor: JamiTheme.buttonTintedBlue
suffixBisIconColor: JamiTheme.passwordEyeIconColor
placeholderText: JamiStrings.password
infoTipText: firstEntry ? JamiStrings.password : ""

View File

@ -40,6 +40,7 @@ BaseModalDialog {
signal focusOnPreviousItem
signal focusOnNextItem
signal imageValidated
function startBooth() {
recordBox.openRecorder(true)
@ -72,8 +73,10 @@ BaseModalDialog {
onValidatePhoto: function(photo) {
if (!root.newItem)
AccountAdapter.setCurrentAccountAvatarBase64(photo)
else
UtilsAdapter.setTempCreationImageFromString(photo, imageId)
else{
UtilsAdapter.setTempCreationImageFromString(photo, imageId);
imageValidated();
}
root.close()

View File

@ -34,6 +34,8 @@ Item {
property real avatarSize
property bool doubleEditAvatar: false
property alias editButton: editImage
height: avatarSize
Rectangle {

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_black_24dp_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

@ -243,6 +243,7 @@ Control {
anchors.fill: bubble
hoverEnabled: true
onClicked: function (mouse) {
if (root.hoveredLink) {
MessagesAdapter.openUrl(root.hoveredLink);
@ -277,8 +278,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,33 +288,54 @@ Control {
source: JamiResources.more_vert_24dp_svg
width: optionButtonItem.width / 2
height: optionButtonItem.height
circled: false
property bool isOpen: false
property var obj: undefined
function bind() {
more.isOpen = false;
visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered));
imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
}
onClicked: {
var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml");
var obj = component.createObject(bubble, {
"emojiReactions": emojiReactions,
"isOutgoing": isOutgoing,
"msgId": Id,
"msgBody": Body,
"type": Type,
"transferName": TransferName,
"msgBubble": bubble,
"listView": listView
});
obj.open();
if (more.isOpen) {
more.bind();
obj.close();
} else {
var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
obj = component.createObject(more, {
"emojiReactions": emojiReactions,
"isOutgoing": isOutgoing,
"msgId": Id,
"msgBody": Body,
"type": Type,
"transferName": TransferName,
"msgBubble": bubble,
"listView": listView
});
obj.open();
more.isOpen = true;
visible = true;
imageColor = JamiTheme.chatViewFooterImgHoverColor;
normalColor = JamiTheme.hoveredButtonColor;
}
}
}
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
source: JamiResources.reply_black_24dp_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,190 @@
/*
* 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;
const parentX = parent.x;
if (isOutgoing) {
return parentX - width - 21;
} else {
return parentX + 21;
}
}
x: xPositionProvider(width)
y: parent.y
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);
}
onAboutToHide: {
root.destroy();
}
Component.onDestruction: {
parent.bind();
}
}

View File

@ -36,6 +36,7 @@ BaseModalDialog {
property var buttonStyles: []
property string infoText: ""
property var innerContentData: []
property int buttonRoles: []
function openWithParameters(title, info = "") {
root.title = title;
@ -44,6 +45,45 @@ BaseModalDialog {
open();
}
button1.text: buttonTitles[0]
button1Role: buttonRoles[0]
button2.text: buttonTitles[1] ? buttonTitles[1] : null
button2Role: buttonRoles[1]
button1.onClicked: {
if (buttonCallBacks[0])
buttonCallBacks[0]();
close();
}
button2.onClicked: {
if (buttonCallBacks[1])
buttonCallBacks[1]();
close();
}
Component.onCompleted: {
for (var i = 0; i < buttonStyles.length; i++){
switch (buttonStyles[i]) {
case SimpleMessageDialog.ButtonStyle.TintedBlue:
button1.color = JamiTheme.buttonTintedBlue;
button1.hoveredColor = JamiTheme.buttonTintedBlueHovered;
button1.pressedColor = JamiTheme.buttonTintedBluePressed;
break;
case SimpleMessageDialog.ButtonStyle.TintedBlack:
button1.color = JamiTheme.buttonTintedBlack;
button1.hoveredColor = JamiTheme.buttonTintedBlackHovered;
button1.pressedColor = JamiTheme.buttonTintedBlackPressed;
break;
case SimpleMessageDialog.ButtonStyle.TintedRed:
button1.color = JamiTheme.buttonTintedRed;
button1.hoveredColor = JamiTheme.buttonTintedRedHovered;
button1.pressedColor = JamiTheme.buttonTintedRedPressed;
break;
}
}
}
popupContent: ColumnLayout {
Label {
id: infoTextLabel
@ -69,63 +109,5 @@ BaseModalDialog {
data: innerContentData
}
RowLayout {
spacing: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: JamiTheme.preferredMarginSize
Repeater {
model: buttonTitles.length
MaterialButton {
Layout.alignment: Qt.AlignVCenter
preferredWidth: JamiTheme.preferredFieldWidth / 2
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
color: {
switch (buttonStyles[modelData]) {
case SimpleMessageDialog.ButtonStyle.TintedBlue:
return JamiTheme.buttonTintedBlue;
case SimpleMessageDialog.ButtonStyle.TintedBlack:
return JamiTheme.buttonTintedBlack;
case SimpleMessageDialog.ButtonStyle.TintedRed:
return JamiTheme.buttonTintedRed;
}
}
hoveredColor: {
switch (buttonStyles[modelData]) {
case SimpleMessageDialog.ButtonStyle.TintedBlue:
return JamiTheme.buttonTintedBlueHovered;
case SimpleMessageDialog.ButtonStyle.TintedBlack:
return JamiTheme.buttonTintedBlackHovered;
case SimpleMessageDialog.ButtonStyle.TintedRed:
return JamiTheme.buttonTintedRedHovered;
}
}
pressedColor: {
switch (buttonStyles[modelData]) {
case SimpleMessageDialog.ButtonStyle.TintedBlue:
return JamiTheme.buttonTintedBluePressed;
case SimpleMessageDialog.ButtonStyle.TintedBlack:
return JamiTheme.buttonTintedBlackPressed;
case SimpleMessageDialog.ButtonStyle.TintedRed:
return JamiTheme.buttonTintedRedPressed;
}
}
secondary: true
autoAccelerator: true
text: buttonTitles[modelData]
onClicked: {
if (buttonCallBacks[modelData])
buttonCallBacks[modelData]();
close();
}
}
}
}
}
}

View File

@ -23,6 +23,8 @@ import net.jami.Constants 1.1
Menu {
id: root
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside | Popup.CloseOnPressOutsideParent
property int menuPreferredWidth: 0
property int menuItemsPreferredHeight: 0
property int menuSeparatorPreferredHeight: 0
@ -43,11 +45,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 +55,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);
@ -77,28 +88,22 @@ Menu {
root.close();
}
modal: true
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,231 @@
/*
* 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
Behavior on color {
ColorAnimation {
duration: JamiTheme.shortFadeDuration
}
}
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
Behavior on color {
ColorAnimation {
duration: JamiTheme.shortFadeDuration
}
}
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
Behavior on color {
ColorAnimation {
duration: JamiTheme.shortFadeDuration
}
}
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

@ -72,7 +72,11 @@ Item {
}
function isDonationBannerVisible() {
// The banner is visible if the current date is after the date set in the settings
return new Date() > new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonateVisibleDate)));
// 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.Donation2023EndDate)));
var donationVisibleDate = new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.Donation2023VisibleDate)));
return new Date() < endDonationDate && new Date() > donationVisibleDate && isDonationVisible;
}
}

View File

@ -48,7 +48,10 @@ Item {
property string version: qsTr("Version") + (AppVersionManager.isCurrentVersionBeta() ? " (Beta)" : "")
property string declarationYear: "© 2015-2023"
property string slogan: "Eleutheria"
property string declaration: qsTr("Jami is a free universal communication software that respects the freedom and privacy of its users.")
property string declaration: qsTr('Jami, a GNU package, is software for universal and distributed peer-to-peer communication that respects the freedom and privacy of its users. Visit <a href="https://jami.net" style="color: ' + JamiTheme.buttonTintedBlue + '">jami.net</a>' + ' to learn more.')
property string noWarranty: qsTr('This program comes with absolutely no warranty. See the <a href="https://www.gnu.org/licenses/gpl-3.0.html" style="color: ' + JamiTheme.buttonTintedBlue + '">GNU General Public License</a>, version 3 or later for details.')
property string contribute: qsTr('Contribute')
property string feedback: qsTr('Feedback')
// AccountComboBox
property string displayQRCode: qsTr("Display QR code")
@ -83,6 +86,15 @@ Item {
property string selectNewRingtone: qsTr("Select a new ringtone")
property string certificateFile: qsTr("Certificate File (*.crt)")
property string audioFile: qsTr("Audio File (*.wav *.ogg *.opus *.mp3 *.aiff *.wma)")
property string pushToTalk: qsTr("Push-to-talk")
property string enablePTT: qsTr("Enable push-to-talk")
property string keyboardShortcut: qsTr("Keyboard shortcut")
property string changeKeyboardShortcut: qsTr("Change keyboard shortcut")
// ChangePttKeyPopup
property string changeShortcut: qsTr("Change shortcut")
property string assignmentIndication: qsTr("Press the key to be assigned to push-to-talk shortcut")
property string assign: qsTr("Assign")
// AdvancedChatSettings
property string enableReadReceipts: qsTr("Enable read receipts")
@ -760,8 +772,9 @@ Item {
property string joinCall: qsTr("Join call")
property string wantToJoin: qsTr("A call is in progress. Do you want to join the call?")
property string needsHost: qsTr("Current host for this swarm seems unreachable. Do you want to host the call?")
property string chooseHoster: qsTr("Choose a dedicated device for hosting future calls in this swarm. If not set, the device starting a call will host it.")
property string chooseThisDevice: qsTr("Choose this device")
property string selectHost: qsTr("Select dedicated device for hosting future calls in this swarm. If not set, the host will be the device starting a call.")
property string selectThisDevice: qsTr("Select this device")
property string selectDevice: qsTr("Select device")
property string removeCurrentDevice: qsTr("Remove current device")
property string becomeHostOneCall: qsTr("Host only this call")
property string hostThisCall: qsTr("Host this call")
@ -819,6 +832,10 @@ Item {
// ManageAccount
property string enableAccountDescription: qsTr("Enabling your account allows you to be contacted on Jami")
// CreateAccount
property string encryptWithPassword: qsTr("Encrypt your account with a password")
property string customizeYourProfile: qsTr("Customize your profile")
// General
property string appearance: qsTr("Appearance")
@ -839,7 +856,28 @@ Item {
property string zoomLevel: qsTr("Text zoom level")
//Donation campaign
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/whydonate/\">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"
@ -88,6 +88,8 @@ Item {
property color popupOverlayColor: darkTheme ? Qt.rgba(255, 255, 255, 0.22) : Qt.rgba(0, 0, 0, 0.33)
property real formsRadius: 30
property color warningRedRectangle: darkTheme ? "#3c131a" : "#fae5e8"
// Side panel
property color presenceGreen: "#4cd964"
property color notificationRed: "#ff3b30"
@ -138,6 +140,11 @@ Item {
property color secAndTertiHoveredBackgroundColor: darkTheme ? "#123F4A" : "#E5EEF5"
property color closeButtonLighterBlack: "#4c4c4c"
property color redButtonColor: darkTheme ? "#FA2E30" : "#CC0022"
property color backgroundRectangleColor: darkTheme ? "#333333" : "#F0EFEF"
property color deleteRedButton: "#CC0022"
// Jami switch
property color switchBackgroundCheckedColor: "#8dbaea"
property color switchBackgroundColor: darkTheme ? "#626262" : "#E5EEF5"
@ -188,6 +195,9 @@ Item {
property color wizardGreenColor: "#aed581"
property color requiredFieldColor: "#ff1f62"
property color requiredFieldBackgroundColor: "#fee4e9"
property color customizePhotoColor: "#0B03DB"
property color customizePhotoHoveredColor: "#3B35E2"
property color customizeRectangleColor: darkTheme ? "#333333" : "#F0EFEF"
// Misc
property color recordIconColor: "#dc2719"
@ -367,9 +377,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
@ -436,10 +446,6 @@ Item {
property real switchPreferredWidth: 40
property real switchIndicatorPreferredWidth: 20
// Jami Identifier
property color mainColor: "#005699"
property real pushButtonSize: 22
property real pushButtonMargins: 10
// Modal Popup
property real modalPopupRadius: 20
@ -492,6 +498,7 @@ Item {
// MessageBar
property int messageBarMarginSize: 10
property int messageBarMinimumWidth: 438
// InvitationView
property real invitationViewAvatarSize: 112
@ -507,6 +514,11 @@ Item {
property real jamiIdFontSize: calcSize(19)
property real jamiIdSmallFontSize: calcSize(11)
property color jamiIdColor: darkTheme ? blackColor : sysColor
property color mainColor: "#005699"
property real pushButtonSize: 22
property real pushButtonMargins: 10
property color jamiIdBackgroundColor: darkTheme ? "#333333" : "#F0EFEF"
property color redDotColor: "#CC0022"
// MainView
property color rectColor: darkTheme ? blackColor : "#e5eef5"
@ -530,8 +542,10 @@ Item {
property real wizardViewBlocMarginSize: pixelToPoint(40)
property real wizardViewDescriptionMarginSize: pixelToPoint(20)
// 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 +555,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
@ -561,9 +575,12 @@ Item {
property real cornerIconSize: 40
property color wizardIconColor: darkTheme ? "#8c8c8c" : "#7f7f7f"
// InfoBox
property real infoBoxTitleFontSize: calcSize(13)
property real infoBoxDescFontSize: calcSize(12)
property color infoRectangleColor: JamiTheme.darkTheme ? "#143842" : "#e5eef5"
// Tipbox
property real tipBoxWidth: 200
@ -591,6 +608,10 @@ Item {
property real textEditError: calcSize(15)
property real maximumCharacters: 50
// PasswordTextEdit
property color passwordEyeIconColor: "#5d5d5d"
property color passwordBaselineColor: darkTheme ? "#6e6e6e" : "#9fbfd9"
// MaterialButton
property real buttontextPadding: 10
property real buttontextWizzardPadding: 30
@ -660,9 +681,19 @@ Item {
// Donation campaign
property color donationButtonTextColor: "#005699"
property color donationBackgroundColor: "#D5E4EF"
property string donationUrl: "https://jami.net/donate/"
property string donationUrl: "https://jami.net/whydonate/"
//Connection monitoring
property color connectionMonitoringTableColor1: darkTheme ? "#4D4D4D" : "#f0efef"
property color connectionMonitoringTableColor2: darkTheme ? "#333333" : "#f6f5f5"
property color connectionMonitoringHeaderColor: darkTheme ? "#6F6F6F" : "#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

@ -129,11 +129,12 @@ MainApplication::init()
// This 2-phase initialisation prevents ephemeral instances from
// performing unnecessary tasks, like initializing the webengine.
engine_.reset(new QQmlApplicationEngine(this));
connectivityMonitor_.reset(new ConnectivityMonitor(this));
settingsManager_.reset(new AppSettingsManager(this));
systemTray_.reset(new SystemTray(settingsManager_.get(), this));
QObject::connect(settingsManager_.get(),
connectivityMonitor_ = new ConnectivityMonitor(this);
settingsManager_ = new AppSettingsManager(this);
systemTray_ = new SystemTray(settingsManager_, this);
QObject::connect(settingsManager_,
&AppSettingsManager::retranslate,
engine_.get(),
&QQmlApplicationEngine::retranslate);
@ -146,7 +147,7 @@ MainApplication::init()
setApplicationFont();
initLrc(runOptions_[Option::UpdateUrl].toString(),
connectivityMonitor_.get(),
connectivityMonitor_,
runOptions_[Option::Debug].toBool(),
runOptions_[Option::MuteDaemon].toBool());
@ -168,7 +169,7 @@ MainApplication::init()
}
#endif
connect(connectivityMonitor_.get(), &ConnectivityMonitor::connectivityChanged, this, [this] {
connect(connectivityMonitor_, &ConnectivityMonitor::connectivityChanged, this, [this] {
QTimer::singleShot(500, this, [&]() { lrcInstance_->connectivityChanged(); });
});
@ -341,10 +342,10 @@ MainApplication::initQmlLayer()
{
// Expose custom types to the QML engine.
Utils::registerTypes(engine_.get(),
systemTray_.get(),
lrcInstance_.get(),
settingsManager_.get(),
connectivityMonitor_.get(),
systemTray_,
settingsManager_,
connectivityMonitor_,
&screenInfo_,
this);
@ -375,7 +376,7 @@ MainApplication::initSystray()
QAction* restoreAction = new QAction(tr("&Show Jami"), this);
connect(restoreAction, &QAction::triggered, this, &MainApplication::restoreApp);
connect(systemTray_.get(),
connect(systemTray_,
&QSystemTrayIcon::activated,
this,
[this](QSystemTrayIcon::ActivationReason reason) {
@ -409,10 +410,8 @@ MainApplication::cleanup()
}
}
#ifdef Q_OS_MACOS
void
MainApplication::setEventFilter()
{
installEventFilter(this);
}
#endif

View File

@ -20,7 +20,6 @@
#pragma once
#include "imagedownloader.h"
#include "lrcinstance.h"
#include "qtutils.h"
@ -36,7 +35,6 @@
class ConnectivityMonitor;
class AppSettingsManager;
class SystemTray;
class CallAdapter;
// Provides information about the screen the app is displayed on
class ScreenInfo : public QObject
@ -82,17 +80,20 @@ public:
return runOptions_[opt];
};
#ifdef Q_OS_MACOS
Q_INVOKABLE void setEventFilter();
bool eventFilter(QObject* object, QEvent* event)
{
#ifdef Q_OS_MACOS
if (event->type() == QEvent::ApplicationActivate) {
restoreApp();
}
#endif // Q_OS_MACOS
return QApplication::eventFilter(object, event);
}
#endif // Q_OS_MACOS
Q_SIGNALS:
void closeRequested();
@ -112,13 +113,14 @@ private:
private:
std::map<Option, QVariant> runOptions_;
// We want to be explicit about the destruction order of these objects
QScopedPointer<QQmlApplicationEngine> engine_;
QScopedPointer<LRCInstance> lrcInstance_;
QScopedPointer<ConnectivityMonitor> connectivityMonitor_;
QScopedPointer<AppSettingsManager> settingsManager_;
QScopedPointer<SystemTray> systemTray_;
QScopedPointer<ImageDownloader> imageDownloader_;
// These are injected into the QML layer along with our LRCInstance
ConnectivityMonitor* connectivityMonitor_;
SystemTray* systemTray_;
AppSettingsManager* settingsManager_;
ScreenInfo screenInfo_;

View File

@ -27,96 +27,107 @@ import "../../commoncomponents"
BaseModalDialog {
id: root
margins: JamiTheme.preferredMarginSize
title: JamiStrings.aboutJami
button1.text: JamiStrings.contribute
button2.text: JamiStrings.feedback
button1.onClicked: { Qt.openUrlExternally("https://jami.net/contribute/")}
button2.onClicked: { Qt.openUrlExternally("mailto:jami@gnu.org")}
popupContent: JamiFlickable {
id: aboutPopUpScrollView
width: aboutPopUpContentRectColumnLayout.implicitWidth
height: JamiTheme.preferredDialogHeight
width: aboutPopUpContentRectColumnLayout.implicitWidth
height: Math.min(root.implicitHeight, aboutPopUpContentRectColumnLayout.implicitHeight)
Component.onCompleted: print(root.height, aboutPopUpContentRectColumnLayout.implicitHeight)
contentHeight: aboutPopUpContentRectColumnLayout.implicitHeight
ColumnLayout {
id: aboutPopUpContentRectColumnLayout
anchors.centerIn: parent
ResponsiveImage {
id: aboutPopUPJamiLogoImage
RowLayout{
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: JamiTheme.aboutLogoPreferredWidth
Layout.preferredHeight: JamiTheme.aboutLogoPreferredHeight
spacing: 10
source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
}
ResponsiveImage {
id: aboutPopUPJamiLogoImage
TextEdit {
id: jamiSlogansText
Layout.alignment: Qt.AlignCenter
Layout.margins: 10
Layout.preferredWidth: 150
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
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
source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
}
}
TextEdit {
id: jamiVersionText
Rectangle {
color: JamiTheme.backgroundRectangleColor
Layout.fillHeight: true
Layout.fillWidth: true
radius: 5
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
ColumnLayout {
id: sloganLayout
font.pixelSize: JamiTheme.tinyCreditsTextSize
anchors.verticalCenter: parent.verticalCenter
padding: 0
TextEdit {
id: jamiSlogansText
text: JamiStrings.version + ": " + UtilsAdapter.getVersionStr()
selectByMouse: true
readOnly: true
color: JamiTheme.textColor
Layout.alignment: Qt.AlignLeft
Layout.margins: 10
Layout.bottomMargin: 0
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.menuFontSize
font.bold: true
TextEdit {
id: jamiDeclarationText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 15
text: textMetricsjamiSlogansText.text
selectByMouse: true
readOnly: true
color: JamiTheme.textColor
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.creditsTextSize
color: JamiTheme.textColor
TextMetrics {
id: textMetricsjamiSlogansText
font: jamiSlogansText.font
text: JamiStrings.slogan
}
}
TextEdit {
id: jamiVersionText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignLeft
Layout.margins: 10
Layout.topMargin: 0
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
// TextMetrics does not work for multi-line.
text: JamiStrings.declaration
selectByMouse: true
readOnly: true
font.pixelSize: JamiTheme.textFontSize
padding: 0
text: JamiStrings.version + ": " + UtilsAdapter.getVersionStr()
selectByMouse: true
readOnly: true
color: JamiTheme.faddedFontColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
TextEdit {
id: jamiDeclarationHyperText
Layout.alignment: Qt.AlignCenter
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
// Strangely, hoveredLink works badly when width grows too large
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
@ -124,12 +135,12 @@ BaseModalDialog {
color: JamiTheme.textColor
font.pixelSize: JamiTheme.creditsTextSize
horizontalAlignment: Text.AlignHCenter
font.pixelSize: JamiTheme.menuFontSize
verticalAlignment: Text.AlignVCenter
text: textMetricsjamiDeclarationHyperText.text
textFormat: TextEdit.RichText
wrapMode: TextEdit.WordWrap
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
@ -137,7 +148,7 @@ BaseModalDialog {
TextMetrics {
id: textMetricsjamiDeclarationHyperText
font: jamiDeclarationHyperText.font
text: '<a href="https://jami.net" style="color: ' + JamiTheme.blueLinkColor + '">jami.net</a>'
text: JamiStrings.declaration
}
MouseArea {
@ -152,13 +163,12 @@ BaseModalDialog {
TextEdit {
id: jamiNoneWarrantyHyperText
Layout.alignment: Qt.AlignCenter
Layout.alignment: Qt.AlignLeft
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.tinyCreditsTextSize
font.pixelSize: JamiTheme.menuFontSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignTop
color: JamiTheme.textColor
@ -171,7 +181,7 @@ BaseModalDialog {
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.'
text: JamiStrings.noWarranty
}
MouseArea {
@ -181,14 +191,56 @@ BaseModalDialog {
}
}
ProjectCreditsScrollView {
id: projectCreditsScrollView
Layout.alignment: Qt.AlignCenter
TextEdit {
id: jamiYears
Layout.alignment: Qt.AlignLeft
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
Layout.preferredHeight: 100
Layout.topMargin: 25
Layout.margins: JamiTheme.preferredMarginSize
Layout.topMargin: 15
wrapMode: Text.WordWrap
font.pixelSize: JamiTheme.menuFontSize
verticalAlignment: Text.AlignTop
color: JamiTheme.textColor
text: textMetricsYears.text
textFormat: TextEdit.RichText
selectByMouse: true
readOnly: true
onLinkActivated: Qt.openUrlExternally(link)
TextMetrics {
id: textMetricsYears
font: jamiDeclarationHyperText.font
text: JamiStrings.declarationYear + " " + '<a href="https://savoirfairelinux.com" style="color: ' + JamiTheme.buttonTintedBlue + '">Savoir-faire Linux</a><br>'
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
Rectangle {
width: projectCreditsScrollView.width + 20
height: projectCreditsScrollView.height + 20
color: JamiTheme.backgroundRectangleColor
radius: 5
ProjectCreditsScrollView {
id: projectCreditsScrollView
anchors.centerIn: parent
width: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
height: 140
anchors.margins: 10
}
}
}
}
}

View File

@ -123,13 +123,13 @@ Control {
"Name": JamiStrings.shareScreen,
"IconSource": JamiResources.laptop_black_24dp_svg
});
if (Qt.platform.os.toString() !== "osx") {
if (Qt.platform.os.toString() !== "osx" && !UtilsAdapter.isWayland()) {
shareModel.append({
"Name": JamiStrings.shareWindow,
"IconSource": JamiResources.window_black_24dp_svg
});
}
if (Qt.platform.os.toString() !== "windows") {
if (Qt.platform.os.toString() !== "windows" && !UtilsAdapter.isWayland()) {
// temporarily disable for windows
shareModel.append({
"Name": JamiStrings.shareScreenArea,

View File

@ -24,17 +24,15 @@ import net.jami.Constants 1.1
import Qt5Compat.GraphicalEffects
import "../../commoncomponents"
Popup {
BaseModalDialog {
id: root
property real maxHeight: parent.height * 40 / 100
property real maxTextWidth: parent.width * 30 / 100
property real maxTextWidth: parent.width * 20 / 100
property var advancedList
property var fps
width: container.width
height: container.height
maximumPopupWidth: popupContent.width + 2 * popupMargins
closePolicy: Popup.NoAutoClosed
onClosed: {
@ -48,203 +46,180 @@ Popup {
AvAdapter.setRendererInfo();
}
background: Rectangle {
color: JamiTheme.transparentColor
}
backgroundColor: JamiTheme.darkGreyColor
backgroundOpacity: 0.77
Rectangle {
id: container
popupContent: RowLayout {
id: windowContent
spacing: JamiTheme.callInformationBlockSpacing
color: JamiTheme.blackColor
opacity: 0.85
radius: 10
width: windowContent.width
height: windowContent.height
ColumnLayout {
spacing: JamiTheme.callInformationBlockSpacing
Layout.preferredWidth: callInfoListview.width
Layout.alignment: Qt.AlignTop
PushButton {
id: closeButton
anchors.top: container.top
anchors.topMargin: 5
anchors.right: container.right
anchors.rightMargin: 5
normalColor: JamiTheme.transparentColor
imageColor: JamiTheme.callInfoColor
source: JamiResources.round_close_24dp_svg
circled: false
toolTipText: JamiStrings.close
onClicked: {
root.close();
Text {
id: textTest
color: JamiTheme.callInfoColor
text: JamiStrings.callInformation
font.pointSize: JamiTheme.menuFontSize
font.bold: true
Layout.maximumWidth: root.maxTextWidth
elide: Text.ElideRight
}
}
RowLayout {
id: windowContent
ListView {
id: callInfoListview
ColumnLayout {
spacing: JamiTheme.callInformationBlockSpacing
Layout.margins: JamiTheme.callInformationlayoutMargins
Layout.preferredWidth: callInfoListview.width
Layout.alignment: Qt.AlignTop
model: advancedList
Layout.preferredWidth: root.maxTextWidth
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
clip: true
Text {
id: textTest
color: JamiTheme.callInfoColor
text: JamiStrings.callInformation
font.pointSize: JamiTheme.titleFontPointSize
}
delegate: Column {
ListView {
id: callInfoListview
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.callId + ": " + CALL_ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
model: advancedList
Layout.preferredWidth: root.maxTextWidth
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
spacing: JamiTheme.callInformationBlockSpacing
clip: true
delegate: Column {
spacing: JamiTheme.callInformationElementsSpacing
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.callId + ": " + CALL_ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
Text {
function stringWithoutRing(peerNumber) {
return peerNumber.replace("@ring.dht", "");
}
color: JamiTheme.callInfoColor
text: JamiStrings.peerNumber + ": " + stringWithoutRing(PEER_NUMBER)
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Column {
id: socketLayout
Text {
function stringWithoutRing(peerNumber) {
return peerNumber.replace("@ring.dht", "");
}
color: JamiTheme.callInfoColor
text: JamiStrings.peerNumber + ": " + stringWithoutRing(PEER_NUMBER)
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Column {
id: socketLayout
property bool showAll: false
width: callInfoListview.width
bottomPadding: JamiTheme.callInformationBlockSpacing
topPadding: JamiTheme.callInformationBlockSpacing
property bool showAll: false
width: callInfoListview.width
RowLayout {
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.sockets
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: socketLayout.width
}
PushButton {
source: socketLayout.showAll ? JamiResources.expand_less_24dp_svg : JamiResources.expand_more_24dp_svg
normalColor: JamiTheme.transparentColor
Layout.preferredWidth: 20
Layout.preferredHeight: 20
imageColor: JamiTheme.callInfoColor
onClicked: {
socketLayout.showAll = !socketLayout.showAll;
}
}
}
RowLayout {
Text {
color: JamiTheme.callInfoColor
text: SOCKETS
text: JamiStrings.sockets
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
visible: socketLayout.showAll
width: socketLayout.width
}
JamiPushButton {
source: socketLayout.showAll ? JamiResources.expand_less_24dp_svg : JamiResources.expand_more_24dp_svg
normalColor: JamiTheme.transparentColor
Layout.preferredWidth: 20
Layout.preferredHeight: 20
imageColor: JamiTheme.callInfoColor
onClicked: {
socketLayout.showAll = !socketLayout.showAll;
}
}
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.videoCodec + ": " + VIDEO_CODEC
text: SOCKETS
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
visible: socketLayout.showAll
width: socketLayout.width
}
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.audioCodec + ": " + AUDIO_CODEC + " " + AUDIO_SAMPLE_RATE + " Hz"
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.videoCodec + ": " + VIDEO_CODEC
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.hardwareAcceleration + ": " + HARDWARE_ACCELERATION
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.audioCodec + ": " + AUDIO_CODEC + " " + AUDIO_SAMPLE_RATE + " Hz"
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.videoBitrate + ": " + VIDEO_BITRATE + " bps"
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.hardwareAcceleration + ": " + HARDWARE_ACCELERATION
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.videoBitrate + ": " + VIDEO_BITRATE + " bps"
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: callInfoListview.width
}
}
}
}
ColumnLayout {
ColumnLayout {
spacing: JamiTheme.callInformationBlockSpacing
Layout.preferredWidth: renderersInfoListview.width
Layout.alignment: Qt.AlignTop
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.renderersInformation
font.pointSize: JamiTheme.menuFontSize
font.bold: true
elide: Text.ElideRight
Layout.maximumWidth: root.maxTextWidth
}
ListView {
id: renderersInfoListview
Layout.preferredWidth: root.maxTextWidth
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
spacing: JamiTheme.callInformationBlockSpacing
Layout.margins: JamiTheme.callInformationlayoutMargins
Layout.preferredWidth: renderersInfoListview.width
Layout.alignment: Qt.AlignTop
model: fps
clip: true
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.renderersInformation
font.pointSize: JamiTheme.titleFontPointSize
}
delegate: Column {
spacing: JamiTheme.callInformationElementsSpacing
ListView {
id: renderersInfoListview
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.rendererId + ": " + RENDERER_ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
Layout.preferredWidth: root.maxTextWidth
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
spacing: JamiTheme.callInformationBlockSpacing
model: fps
clip: true
Text {
id: testText
color: JamiTheme.callInfoColor
text: JamiStrings.fps_short + ": " + FPS
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
delegate: Column {
spacing: JamiTheme.callInformationElementsSpacing
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.rendererId + ": " + RENDERER_ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
Text {
id: testText
color: JamiTheme.callInfoColor
text: JamiStrings.fps_short + ": " + FPS
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.resolution + ": " + RES
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
Text {
color: JamiTheme.callInfoColor
text: JamiStrings.resolution + ": " + RES
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: renderersInfoListview.width
}
}
}

View File

@ -25,7 +25,6 @@ import "../../commoncomponents"
Item {
id: root
property alias chatViewContainer: ongoingCallPage.chatViewContainer
property alias contentView: callStackMainView
@ -49,6 +48,16 @@ Item {
}
}
Connections {
target: CallOverlayModel
function onPttKeyPressed() {
CallAdapter.muteAudioToggle();
}
function onPttKeyReleased() {
CallAdapter.muteAudioToggle();
}
}
// TODO: this should all be done by listening to
// parent visibility change or parent `Component.onDestruction`
function needToCloseInCallConversationAndPotentialWindow() {

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

@ -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

@ -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

@ -29,25 +29,45 @@ BaseModalDialog {
width: JamiTheme.secondaryDialogDimension
property string currentDeviceId
title: JamiStrings.defaultCallHost
button1.text: JamiStrings.selectDevice
button1Role: DialogButtonBox.AcceptRole
button1.toolTipText: JamiStrings.selectThisDevice
button1.enabled: false
button1.onClicked : {
CurrentConversation.setInfo("rdvAccount", CurrentAccount.uri);
CurrentConversation.setInfo("rdvDevice", currentDeviceId);
root.close();
}
button2.text: JamiStrings.removeDevice
button2Role: DialogButtonBox.ResetRole
button2.toolTipText: JamiStrings.removeCurrentDevice
button2.enabled: CurrentConversation.rdvAccount !== ""
button2.onClicked: {
CurrentConversation.setInfo("rdvAccount", "");
CurrentConversation.setInfo("rdvDevice", "");
close();
}
popupContent: ColumnLayout {
id: mainLayout
anchors.centerIn: parent
anchors.margins: JamiTheme.preferredMarginSize
spacing: JamiTheme.preferredMarginSize
spacing: 10
width: JamiTheme.preferredDialogWidth
Label {
id: informativeLabel
Layout.alignment: Qt.AlignCenter
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.preferredWidth: root.width - 4*JamiTheme.preferredMarginSize
Layout.fillWidth: true
wrapMode: Text.Wrap
text: JamiStrings.chooseHoster
text: JamiStrings.selectHost
color: JamiTheme.primaryForegroundColor
}
@ -79,15 +99,27 @@ BaseModalDialog {
property bool isCurrent: DeviceName
implicitWidth: devicesListView.width
width: root.width - 4*JamiTheme.preferredMarginSize
height: 70
highlighted: ListView.isCurrentItem
highlighted: CurrentConversation.rdvDevice === deviceId
MouseArea {
anchors.fill: parent
onClicked: {
devicesListView.currentIndex = index;
if (!highlighted){
devicesListView.currentIndex = index;
for (var i = 0; i < devicesListView.count; i++) {
devicesListView.itemAtIndex(i).highlighted = false;
}
currentDeviceId = deviceId;
button1.enabled = true;
}
else {
devicesListView.currentIndex = -1;
button1.enabled = false;
}
item.highlighted = !item.highlighted;
}
}
@ -154,65 +186,6 @@ BaseModalDialog {
}
}
}
ColumnLayout {
id: buttonLayout
spacing: JamiTheme.preferredMarginSize
Layout.preferredWidth: root.width - 240
MaterialButton {
id: chooseBtn
TextMetrics {
id: chooseBtnTextSize
font.weight: Font.Bold
font.pixelSize: JamiTheme.wizardViewButtonFontPixelSize
font.capitalization: Font.AllUppercase
text: chooseBtn.text
}
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
primary: true
enabled: devicesListView.currentItem
text: JamiStrings.chooseThisDevice
toolTipText: JamiStrings.chooseThisDevice
onClicked: {
CurrentConversation.setInfo("rdvAccount", CurrentAccount.uri);
CurrentConversation.setInfo("rdvDevice", devicesListView.currentItem.deviceId);
close();
}
}
MaterialButton {
id: rmDeviceBtn
TextMetrics {
id: rmDeviceBtnTextSize
font.weight: Font.Bold
font.pixelSize: JamiTheme.wizardViewButtonFontPixelSize
font.capitalization: Font.AllUppercase
text: rmDeviceBtn.text
}
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
primary: true
enabled: devicesListView.currentItem
text: JamiStrings.removeCurrentDevice
toolTipText: JamiStrings.removeCurrentDevice
onClicked: {
CurrentConversation.setInfo("rdvAccount", "");
CurrentConversation.setInfo("rdvDevice", "");
close();
}
}
}
}
}
}

View File

@ -45,7 +45,7 @@ Item {
ctxMenu.y = mouse.y;
ctxMenu.openMenu();
} else {
MessagesAdapter.openUrl(name.fileSource);
MessagesAdapter.openUrl("file://" + Body);
}
}
}

View File

@ -109,8 +109,7 @@ Rectangle {
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)
// TODO reset to 7 days
UtilsAdapter.setAppValue(Settings.Key.DonateVisibleDate, new Date(new Date().getTime() + 1 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
UtilsAdapter.setAppValue(Settings.Key.Donation2023VisibleDate, new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
donation.donationVisible = Qt.binding(() => JamiQmlUtils.isDonationBannerVisible());
}
}

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,55 +31,39 @@ BaseModalDialog {
return role === Member.Role.ADMIN;
}
button1.text: isAdmin ? JamiStrings.becomeHostOneCall : JamiStrings.hostThisCall
button1Role: DialogButtonBox.ApplyRole
button1.onClicked: {
MessagesAdapter.joinCall(CurrentAccount.uri, CurrentAccount.deviceId, "0");
close();
}
button2.text: JamiStrings.becomeDefaultHost
button2Role: DialogButtonBox.ApplyRole
button2.visible: isAdmin
button2.toolTipText: JamiStrings.becomeDefaultHost
button2.onClicked: {
CurrentConversation.setInfo("rdvAccount", CurrentAccount.uri);
CurrentConversation.setInfo("rdvDevice", CurrentAccount.deviceId);
MessagesAdapter.joinCall(CurrentAccount.uri, CurrentAccount.deviceId, "0");
close();
}
popupContent: ColumnLayout {
id: mainLayout
spacing: JamiTheme.preferredMarginSize
id: mainLayout
Label {
id: informativeLabel
Label {
id: informativeLabel
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Layout.maximumWidth: root.parent.width - 4*JamiTheme.preferredMarginSize
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: JamiStrings.needsHost
color: JamiTheme.primaryForegroundColor
}
MaterialButton {
id: becomeHostBtn
Layout.alignment: Qt.AlignCenter
Layout.margins: JamiTheme.preferredMarginSize
text: isAdmin ? JamiStrings.becomeHostOneCall : JamiStrings.hostThisCall
onClicked: {
MessagesAdapter.joinCall(CurrentAccount.uri, CurrentAccount.deviceId, "0");
close();
}
}
MaterialButton {
id: becomeDefaultHostBtn
Layout.alignment: Qt.AlignCenter
Layout.margins: JamiTheme.preferredMarginSize
text: JamiStrings.becomeDefaultHost
toolTipText: JamiStrings.becomeDefaultHost
visible: isAdmin
onClicked: {
CurrentConversation.setInfo("rdvAccount", CurrentAccount.uri);
CurrentConversation.setInfo("rdvDevice", devicesListView.currentItem.deviceId);
MessagesAdapter.joinCall(CurrentAccount.uri, CurrentAccount.deviceId, "0");
close();
}
}
Layout.alignment: Qt.AlignCenter
Layout.bottomMargin: 10
Layout.fillWidth: true
Layout.maximumWidth: root.parent.width - 4*JamiTheme.preferredMarginSize
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: JamiStrings.needsHost
color: JamiTheme.primaryForegroundColor
}
}
//}
}

View File

@ -61,6 +61,7 @@ RowLayout {
color: JamiTheme.transparentColor
ComboBox {
id: showMoreButton
focus: true
width: JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
anchors.bottom: parent.bottom
@ -103,19 +104,20 @@ RowLayout {
toolTipMoreButton.text = sharePopup.opened ? JamiStrings.showLess : JamiStrings.showMore;
}
onPressedChanged: {
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: showMoreButton.y + 31
x: showMoreButton.x - 3
}
}
}
@ -141,12 +143,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;
}
}
@ -307,6 +307,8 @@ RowLayout {
context: Qt.ApplicationShortcut
onActivated: {
showTypo = !showTypo;
messageBarTextArea.isShowTypo = showTypo;
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
}
}
@ -761,7 +763,7 @@ RowLayout {
id: markdownPopup
y: 1.5 * parent.height
x: -parent.width * 2
width: 155
width: 105
height: JamiTheme.chatViewFooterButtonSize
menuTypoActionsSecond: listViewTypoSecond.menuTypoActionsSecond
@ -817,20 +819,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);
}
}
]
@ -906,17 +894,11 @@ RowLayout {
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);
}
@ -1160,7 +1142,7 @@ 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

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