Compare commits

...

113 Commits

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

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

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

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

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

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

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

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

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

Change-Id: Iba1265fbdb8ab18bfb44fc7c2c70ebfe6000ee2c
GitLab: #1305
2023-09-18 10:25:12 -04:00
1a12cb3b8c misc: replace Swarm Created message in 1:1
Change-Id: I71388da217d4912a4f89c36e8a539cdc65f40097
GitLab: #1342
2023-09-18 10:23:13 -04:00
75a154f4fe plugins: fix background of installed plugin
Change-Id: I0b890270dc10ddb3d77d10f07252d5da7266ba7f
2023-09-18 10:10:25 -04:00
b95abbc891 misc: fix shortcut for tile screenshot
Change-Id: Ic2e18dc9aef3e01d7d8f1f935b90fe73b527127b
GitLab: #1344
2023-09-15 12:34:57 -04:00
bc51b74692 misc: add search tooltip
Change-Id: I55e29557eca3b32c714a313cd18aff66a870fd0f
GitLab: #1343
2023-09-15 12:33:03 -04:00
899ff6120c misc: move GenericErrorsRow in MainApplicationWindow
Change-Id: I09fea85e9fa603481bd2cfe81b15a4d94dcc3ebd
Gitlab: #1135
2023-09-15 12:29:27 -04:00
b77012baae misc: bump daemon
Change-Id: Ibf34d81f97f5d601e7357096279e07833a940a33
2023-09-14 13:35:43 -04:00
bc34abc8f4 misc: add tooltip for show preview button
Change-Id: I8b292bdb157c0fed6f873263dc97c4f7f2fa1f02
GitLab: #1337
2023-09-14 13:35:02 -04:00
69b59ad2dd misc: bump daemon
Change-Id: Ie3c7b8665c87e0b7e1b051816f72ec223e559c92
2023-09-14 10:44:33 -04:00
1f2401bc7e PluginDescription: handle language to send request to the plugin store
Change-Id: Id96578cf238246ebe69a6f9b77b0ed1d1f465f38
2023-09-14 10:44:19 -04:00
06b0f1d39c plugins: use pluginId for getIconUrl
Change-Id: I560429fa6604a595c945ffca73fed3c43b152e40
2023-09-14 10:18:01 -04:00
d5b36e7a6d Icon local Path: change identifier plugin name to plugin id
Change-Id: I5091b6f4d5a8d42c73b574d4f889d5795b7ec0db
2023-09-13 15:22:25 -04:00
4e2ae6cde0 misc: bump daemon
Change-Id: I5b014d9c1bf5541fef6dc0af0eda57357c149e9c
2023-09-13 15:28:34 -03:00
0895a9f183 TextEditor: patch height binding after tap big message
Change-Id: I91111ff3b4d54dda85e649e62eef91ad9b935bb8
2023-09-13 11:06:22 -04:00
e8075a412e misc: bump daemon
Change-Id: Ie3c9570dd55e442a6b1e996801e0bb1a7f92b77c
2023-09-12 11:34:20 -04:00
4d55a1430d misc: remove ubuntu 22.10 (EOL)
Change-Id: I9a7bbd77a91b885666519e726530df2ebd7097ca
2023-09-12 11:26:27 -04:00
8de099e38d MessageOptionsPopup: add option to locally delete file
This button offers an option to remove sent/downloaded files
from the device.

Change-Id: Ida1b135681243fd6055034d8a2d699d11bf040e5
GitLab: #1287
2023-09-12 10:59:23 -04:00
306c428019 misc: fix log warning
Change-Id: I943bf58612dc7e6f95fab064c3cd18afda60d9f2
2023-09-12 10:36:46 -04:00
c0a5ced044 misc: fix message bar buttons background color
Change-Id: Ie934835952180803473645bd041bbbba06f02d4f
2023-09-12 10:36:46 -04:00
9f570a3cee Plugin Queries: resolve architecture to be able to handle dynamically all platform
Change-Id: I35ea5be7dc87dcf2e15b5803f9819887c946b91a
2023-09-12 07:32:34 -04:00
2371f0c09f conv-avatar: show a placeholder avatar when base64 data won't load
This does not fix the issue, it's a workaround in case the image data can't load. This may be related to loading large PNGs directly from base 64 strings.

Gitlab: #1329
Change-Id: I45729d10a33b8c8ad0adffb339dbcae40c4b18f9
2023-09-11 15:06:14 -04:00
f605cfce81 white-labeling: fix local file paths
Fixes white-labeling not working on Windows

- use portable local file URI prefixes
- emit download failed when the file can't be created locally
- light refactor

Change-Id: Id6c4c07a9b0edcc18d0d5f5c8852308aaf1e8b44
2023-09-11 10:17:38 -04:00
2aa3212b8f misc: bump daemon
Change-Id: I78e305b020902010dfc9a1c3b1c82d09f0ed2870
2023-09-08 10:59:40 -04:00
031d4348bc build.py: Provide the TARBALLS hint for all distributions.
There's nothing particular about Guix in the handling of TARBALLS, so
display the hint for all distributions.

Change-Id: Icc5f224f08dd0d57f53ee7bed46b11048bff303b
2023-09-07 07:52:00 -04:00
e7436dbc05 accessibility: make the shortcuts focusable
Gitlab: #1211
Change-Id: Idf6a9971ceb06d1f9d42a907f948f402623fccd2
2023-09-06 15:16:37 -04:00
b291728472 tips: center tips when only one or two are left
GitLab: #1184

Change-Id: I9791565e371ca1a5693e85417c9b253802e0b2b3
2023-09-05 09:33:48 -04:00
5820052a53 i18n: automatic bump
Change-Id: I5b0ece4c53706cb698ac904b57fece4c120c1cb2
2023-09-04 16:42:37 -04:00
65cc7a36ed messageBar: hide the popup when you click on show less
GitLab: #1322
Change-Id: I87d4b94a53a4720da5fdf2940ad23f6e17c8fd48
2023-09-01 10:16:43 -04:00
46e2354274 messageBar: display "showLess" when needed
GitLab: #1309
GitLab: #1125
Change-Id: I2b443750731170bebe3532338517e5e0e0ed594b
2023-09-01 10:16:41 -04:00
1bbd8e31af cmake: fix check for minimum major/minor version
The current check only fails if the major and minor version are less than the minimum.
This simplifies the check even removing the major version check which is a find requirement already.

Gitlab: #1330
Change-Id: Id066953c50ef4a925713dbd9203ebe7a3a36f4a1
2023-08-30 14:04:15 -04:00
0bd24bf8c5 misc: bump daemon
Change-Id: I9ccaed3f275b0573e98628c66ebc605fe5764c14
2023-08-25 18:19:29 -03:00
a028696e57 Plugin: change remote plugin margin
Change-Id: Id2289e5f22f23f0a1295dc63d00b6e36133e27b7
2023-08-25 16:40:55 -04:00
c8b371e77a Conversation : remove zero member conversation
(Note: this is a work around, need investigation)

Change-Id: I43d3c26352a068d29486da38b3e25487f10cd9fa
2023-08-25 15:27:17 -04:00
b26259dac8 misc: fix error log in emojipicker
Change-Id: I2dc5ac7743de921469f0b14e12de46b8827184a7
2023-08-24 09:38:18 -03:00
423290a09a emojiPicker: automatic keyboard focus
GitLab: #1220
Change-Id: I848b5352b8214c2112dddc8e69b7bc96d0e372e7
2023-08-24 08:02:41 -04:00
3195fa9b22 sendFile: sending with Enter and automatic focus on the text area
GitLab: #1275
Change-Id: I70036b158cfede3a6c6a7de9bb63a049c8fec39a
2023-08-24 08:02:01 -04:00
4619f04f7b emojireaction: fix maxMsgWidth is not defined error
Change-Id: Id6229ff59c5b896ffe72068e91fc70e334c11aad
2023-08-23 15:46:25 -04:00
ae2380c71b misc: removed unecessary log
Change-Id: I768f32e3bbc2780becc83fe92d6f6f8c9215cec2
2023-08-23 15:55:34 -03:00
2bdf8e088c fix: missing pluginId value
Change-Id: Id1b30c2b35affc3beb3dc2a5646e45c855196a82
2023-08-23 15:17:35 -03:00
9947021394 PluginId: add handler for the plugin id
Change-Id: I377d5856491d38f127fe422e84a6c93839295447
2023-08-23 11:50:14 -04:00
80fe376e3c i18n: automatic bump
Change-Id: Ie2b458e17eb1ecbf7a517c2588e7b87ef36b5752
2023-08-23 09:09:48 -04:00
d1eb1f5885 macOS: fix crash on force quit
This patch ensures that views are destroyed when the user quits
the application.

Change-Id: I173643136d277fe604838bdf19a6c292b066ee8d
2023-08-22 09:07:35 -04:00
b1ca6cf861 PluginView: refactor the ui to a better view
Gitlab: #1306

Change-Id: Ic3d952408c352715f2cd611dad63cf92cfb81ff0
2023-08-21 10:54:35 -04:00
8c728374a7 emojiReactions: change the emojis layout
Gitlab: #1230
Co-authored-by: Charles <charles-francis.damedey@savoirfairelinux.com>
Co-authored-by: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
Change-Id: I5bff3a811caa9bec8ee9b80733165aaaaae5db24
2023-08-18 17:15:33 -04:00
3a693536e4 MessageBar: Fixed issue where sending a message would break the layout.
Change-Id: Iacdea26427e48b00f9edd9aacf57f88860717e0c
2023-08-18 16:42:36 -04:00
ffcd3e59a4 incomingcall: use callstatechanged signal
To be able to show calls that are transfered, we must catch new calls
from callstatechanged signal. Move all logic from newincomingcall to
callstatechanged.

Change-Id: Ibd3ff5f8b4009895b3165348fd1638956f5f66d9
2023-08-08 10:48:50 -04:00
77935de893 welcomepage: fix title translation
Change-Id: Ied989089c59293802b16cf252a538f56d1fbc147
2023-08-08 10:20:37 -03:00
386ef224d1 jamistrings: cleanup
Change-Id: I10c7aa2c77a752c508821d018b7d54dfeb64d7df
2023-08-08 10:15:49 -03:00
d62c2ff98e misc: update title label
Change-Id: I2baa2915398803550fcc161aa7e1ce7cb59ca300
GitLab: #1293
2023-08-07 13:24:46 -04:00
3b00b42213 RTL: fix sparse side panel options
+ fix splitview width resize
+ fix tips row in the WelcomePage

GitLab: #1290
Change-Id: I458e6a96e496b35b7659c5a061949f135511a2e4
2023-08-04 15:06:22 -03:00
21f3479a96 messagebar: fix rtl layout
GitLab: #1279

Change-Id: I746fd86a4cf32cbb369ba2c5d57182800d7da0d0
2023-08-02 12:40:37 -03:00
8307089900 jamiid: change look of jami id to be more compact
Change-Id: I5f39b5f28d4447cdd5b10f37ad2d8780260d5ed8
2023-08-02 10:38:38 -04:00
2916b4c523 swarmdetailpanel: fix avatar position
Change-Id: I9a94c11056be4e176cb01400b2023021a98b6a51
GitLab: #1288
2023-08-02 09:01:37 -03:00
5530649f07 PluginStore: add view for plugin store
Gitlab: #1163
Change-Id: If9d9a27a296c5810b9f99126bed6453cc6ab6852
2023-08-01 13:42:49 -04:00
7581f9397a updateManager: create a plugin store and a plugin manager
Change-Id: I57ebec72c1cb6e2f245af011def82f880bc9573f
2023-08-01 13:42:49 -04:00
7f2c98a594 shortcuttable: update strings
Change-Id: I9428df58376a6cf84c9736d40b07db88089230d1
GitLab: #1282
2023-08-01 10:00:17 -04:00
6341f32618 updatemanager: refactor windows update and macos update manager
To be able to use an update manager for the plugins store, a refactor of windows update manager is done. The windows and macos update manager is used for updating jami. The plugins store update manager is to update plugins to the newest version.

Gitlab: #1229
Change-Id: I0541b6191401f2aa2c6d6034722796455e9c18d2
2023-07-31 15:46:16 -04:00
a652a3d20f messagelistview: fix isFirst/isLast with isEmojiOnly
Change-Id: I4f9a8b037c14e48f12f42f73f0b44b9a78945567
GitLab: #1198
2023-07-31 13:20:06 -04:00
46da989a59 settings: move link device button
Change-Id: Ibafb7afb3eb4fa373a02120ae3575254c645a5c8
GitLab: #1253
2023-07-31 12:56:56 -04:00
1a463ec662 misc: bump daemon
Change-Id: Ib2ad7deed9e27855c1dd6e7c75930a3d4f7f880c
2023-07-31 11:08:30 -04:00
293 changed files with 136129 additions and 136647 deletions

View File

@ -74,16 +74,19 @@ set(TESTS_DIR ${PROJECT_SOURCE_DIR}/tests)
# Here we let find_package(<PackageName>...) try to find Qt 6,
# If it is found, find_package will succeed, and the CMake variable
# QT_VERSION_MAJOR will be defined 6.
set(QT6_MINVER_MINOR 4)
if(QT6_VER AND QT6_PATH)
find_package(QT NAMES Qt6 REQUIRED
PATHS ${QT6_PATH} NO_DEFAULT_PATH)
else()
message(STATUS "Looking for Qt 6" ${CMAKE_PREFIX_PATH})
find_package(QT NAMES Qt6 REQUIRED)
endif()
if (${QT_VERSION_MAJOR} STRLESS 6)
if (${QT_VERSION_MINOR} STRLESS 4)
message(FATAL_ERROR "Qt 6.4 or higher is required.")
endif()
if (${QT_VERSION_MINOR} GREATER_EQUAL ${QT6_MINVER_MINOR})
# Qt version is 6.4 or higher
message(STATUS "Found a suitable Qt version ${QT_VERSION}")
else()
message(FATAL_ERROR "Qt 6.4 or higher is required. Found ${QT_VERSION}")
endif()
if(MSVC)
@ -206,6 +209,7 @@ set(COMMON_SOURCES
${APP_SRC_DIR}/pluginadapter.cpp
${APP_SRC_DIR}/deviceitemlistmodel.cpp
${APP_SRC_DIR}/pluginlistmodel.cpp
${APP_SRC_DIR}/pluginstorelistmodel.cpp
${APP_SRC_DIR}/pluginhandlerlistmodel.cpp
${APP_SRC_DIR}/preferenceitemlistmodel.cpp
${APP_SRC_DIR}/mediacodeclistmodel.cpp
@ -239,13 +243,15 @@ set(COMMON_SOURCES
${APP_SRC_DIR}/currentcall.cpp
${APP_SRC_DIR}/messageparser.cpp
${APP_SRC_DIR}/previewengine.cpp
${APP_SRC_DIR}/imagedownloader.cpp)
${APP_SRC_DIR}/imagedownloader.cpp
${APP_SRC_DIR}/pluginversionmanager.cpp
${APP_SRC_DIR}/connectioninfolistmodel.cpp)
set(COMMON_HEADERS
${APP_SRC_DIR}/avatarimageprovider.h
${APP_SRC_DIR}/networkmanager.h
${APP_SRC_DIR}/smartlistmodel.h
${APP_SRC_DIR}/updatemanager.h
${APP_SRC_DIR}/appversionmanager.h
${APP_SRC_DIR}/utils.h
${APP_SRC_DIR}/bannedlistmodel.h
${APP_SRC_DIR}/version.h
@ -267,6 +273,7 @@ set(COMMON_HEADERS
${APP_SRC_DIR}/pluginadapter.h
${APP_SRC_DIR}/deviceitemlistmodel.h
${APP_SRC_DIR}/pluginlistmodel.h
${APP_SRC_DIR}/pluginstorelistmodel.h
${APP_SRC_DIR}/pluginhandlerlistmodel.h
${APP_SRC_DIR}/preferenceitemlistmodel.h
${APP_SRC_DIR}/mediacodeclistmodel.h
@ -303,8 +310,9 @@ set(COMMON_HEADERS
${APP_SRC_DIR}/currentcall.h
${APP_SRC_DIR}/messageparser.h
${APP_SRC_DIR}/htmlparser.h
${APP_SRC_DIR}/imagedownloader.h)
${APP_SRC_DIR}/imagedownloader.h
${APP_SRC_DIR}/pluginversionmanager.h
${APP_SRC_DIR}/connectioninfolistmodel.h)
# For libavutil/avframe.
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")
@ -336,7 +344,7 @@ if(MSVC)
list(APPEND COMMON_SOURCES
${APP_SRC_DIR}/connectivitymonitor.cpp
${APP_SRC_DIR}/updatemanager.cpp)
${APP_SRC_DIR}/appversionmanager.cpp)
# preprocessor defines
add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG)
@ -388,7 +396,7 @@ elseif (NOT APPLE)
${APP_SRC_DIR}/xrectsel.c
${APP_SRC_DIR}/connectivitymonitor.cpp
${APP_SRC_DIR}/dbuserrorhandler.cpp
${APP_SRC_DIR}/updatemanager.cpp)
${APP_SRC_DIR}/appversionmanager.cpp)
list(APPEND COMMON_HEADERS
${APP_SRC_DIR}/xrectsel.h
${APP_SRC_DIR}/dbuserrorhandler.h)
@ -440,7 +448,7 @@ elseif (NOT APPLE)
find_library(X11 X11)
else() # APPLE
list(APPEND COMMON_SOURCES
${APP_SRC_DIR}/os/macos/updatemanager.mm
${APP_SRC_DIR}/os/macos/appversionmanager.mm
${APP_SRC_DIR}/os/macos/connectivitymonitor.mm
${APP_SRC_DIR}/os/macos/macutils.mm)
list(APPEND COMMON_HEADERS

View File

@ -416,6 +416,11 @@ def run_install(args):
command = ['extras/scripts/install.sh'] + install_args
if 'TARBALLS' not in os.environ:
print('info: consider setting the TARBALLS environment variable '
'to a stable writable location to avoid loosing '
'cached tarballs')
if args.distribution == 'guix':
if args.global_install:
print('error: global install is not supported when using Guix.')
@ -425,10 +430,6 @@ def run_install(args):
if 'TARBALLS' in os.environ:
share_tarballs_args = ['--preserve=TARBALLS',
f'--share={os.environ["TARBALLS"]}']
else:
print('info: consider setting the TARBALLS environment variable '
'to a stable writable location to avoid loosing '
'cached tarballs')
command = ['guix', 'shell', f'--manifest={GUIX_MANIFEST}',
'--symlink=/usr/bin/env=bin/env',
'--symlink=/etc/ssl/certs=etc/ssl/certs',

2
daemon

Submodule daemon updated: e77b247a23...24f8c52acf

View File

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

View File

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

View File

@ -1,4 +1,4 @@
FROM ubuntu:22.10
FROM ubuntu:23.10
ENV DEBIAN_FRONTEND=noninteractive

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

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

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

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

After

Width:  |  Height:  |  Size: 448 B

View File

@ -0,0 +1,41 @@
<?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 428 428" style="enable-background:new 0 0 428 428;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_2_);}
.st2{fill:url(#SVGID_3_);}
.st3{fill:url(#SVGID_4_);}
</style>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-12.625" y1="262.475" x2="165.425" y2="84.425" gradientTransform="matrix(1 0 0 -1 0 428)">
<stop offset="0" style="stop-color:#7E7E7E"/>
<stop offset="1" style="stop-color:#E9FFFF"/>
</linearGradient>
<path class="st0" d="M1.6,154v21.5v1.4c0.2,0,0.4,0,0.6,0c21.8,0,39.5,17.7,39.5,39.5S24,255.9,2.2,255.9c-0.2,0-0.4,0-0.6,0V408
H101V152c0.2,0.1,0.3,0.1,0.5,0.2V51.4L1.6,154z"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="227.375" y1="343.175" x2="405.475" y2="165.075" gradientTransform="matrix(1 0 0 -1 0 428)">
<stop offset="0" style="stop-color:#999999"/>
<stop offset="0.3476" style="stop-color:#9B9B9B"/>
<stop offset="0.525" style="stop-color:#A1A3A3"/>
<stop offset="0.6639" style="stop-color:#ABB0B0"/>
<stop offset="0.7828" style="stop-color:#BAC3C3"/>
<stop offset="0.8889" style="stop-color:#CDDCDC"/>
<stop offset="0.9845" style="stop-color:#E5F9F9"/>
<stop offset="1" style="stop-color:#E9FFFF"/>
</linearGradient>
<path class="st1" d="M386.9,176.8L386.9,176.8V19h-93.7v256c-0.1-0.1-0.3-0.1-0.4-0.2v100.8l94.2-96.7v-23.2l0,0
c21.8,0,39.5-17.7,39.5-39.5C426.4,194.5,408.7,176.8,386.9,176.8z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1.6" y1="341.5" x2="395.2748" y2="341.5" gradientTransform="matrix(1 0 0 -1 0 428)">
<stop offset="0" style="stop-color:#999999"/>
<stop offset="0.9889" style="stop-color:#E9FFFF"/>
</linearGradient>
<path class="st2" d="M181.3,19C126.4,19,1.6,31.5,1.6,154c0,0,49.3-42.7,136.9-25s160.9-0.7,207.6-49.1
c18.6-19.3,32.4-39.6,40.2-60.9H181.3z"/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-723.2346" y1="1360.2583" x2="-329.5598" y2="1360.2583" gradientTransform="matrix(-1 0 0 1 -336.3346 -1016.8083)">
<stop offset="0" style="stop-color:#E9FFFF"/>
<stop offset="1" style="stop-color:#999999"/>
</linearGradient>
<path class="st3" d="M207.2,408c54.9,0,179.7-11.9,179.7-129.1c0,0-49.3,40.8-136.9,23.9s-160.9,0.7-207.6,47
C23.8,368.3,10.1,387.6,2.2,408H207.2z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -65,6 +65,15 @@ ApplicationWindow {
}
}
header: Loader {
active: true
sourceComponent: GenericErrorsRow {
id: genericError
text: CurrentAccount.enabled ? JamiStrings.noNetworkConnectivity : JamiStrings.disabledAccount
height: visible? JamiTheme.chatViewHeaderPreferredHeight : 0
}
}
Rectangle {
id: focusOverlay
objectName: "focusOverlay"
@ -122,9 +131,6 @@ ApplicationWindow {
// If we're in the onboarding wizard or 'MinimizeOnClose'
// is set, then we can quit
if (force || !UtilsAdapter.getAppValue(Settings.MinimizeOnClose) || !UtilsAdapter.getAccountListSize()) {
if (checkLoadedSource() === MainApplicationWindow.LoadedSource.MainView) {
cleanupMainView();
}
Qt.quit();
} else {
layoutManager.closeToTray();
@ -205,8 +211,8 @@ ApplicationWindow {
// Quiet check for updates on start if set to.
if (Qt.platform.os.toString() === "windows") {
if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) {
UpdateManager.checkForUpdates(true);
UpdateManager.setAutoUpdateCheck(true);
AppVersionManager.checkForUpdates(true);
AppVersionManager.setAutoUpdateCheck(true);
}
}
@ -233,6 +239,10 @@ ApplicationWindow {
Connections {
target: MainApplication
function onAboutToQuit() {
cleanupMainView()
}
function onCloseRequested() {
close(true);
}
@ -258,7 +268,7 @@ ApplicationWindow {
}
function presentUpdateInfoDialog(infoText) {
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
return viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": infoText,
"buttonTitles": [JamiStrings.optionOk],
@ -267,8 +277,38 @@ ApplicationWindow {
});
}
function presentUpdateConfirmInstallDialog(switchToBeta=false) {
return viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": switchToBeta ? JamiStrings.confirmBeta : JamiStrings.updateFound,
"buttonTitles": [JamiStrings.optionUpgrade, JamiStrings.optionLater],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": [function () {
AppVersionManager.applyUpdates(switchToBeta);
}]
});
}
function translateErrorToString(error) {
switch (error) {
case NetworkManager.DISCONNECTED:
return JamiStrings.networkDisconnected;
case NetworkManager.CONTENT_NOT_FOUND:
return JamiStrings.contentNotFoundError;
case NetworkManager.ACCESS_DENIED:
return JamiStrings.accessError;
case NetworkManager.SSL_ERROR:
return JamiStrings.updateSSLError;
case NetworkManager.CANCELED:
return JamiStrings.updateDownloadCanceled;
case NetworkManager.NETWORK_ERROR:
default:
return JamiStrings.updateNetworkError;
}
}
Connections {
target: UpdateManager
target: AppVersionManager
function onDownloadStarted() {
viewCoordinator.presentDialog(appWindow, "settingsview/components/UpdateDownloadDialog.qml", {
@ -278,41 +318,22 @@ ApplicationWindow {
function onUpdateCheckReplyReceived(ok, found) {
if (!ok) {
// Show an error dialog describing that we could not successfully check for an update.
presentUpdateInfoDialog(JamiStrings.updateCheckError);
return;
}
if (!found) {
// Show a dialog describing that no update was found.
presentUpdateInfoDialog(JamiStrings.updateNotFound);
} else {
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
"title": JamiStrings.updateDialogTitle,
"infoText": JamiStrings.updateFound,
"buttonTitles": [JamiStrings.optionUpgrade, JamiStrings.optionLater],
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlue],
"buttonCallBacks": [function () {
UpdateManager.applyUpdates();
}]
});
// Show a dialog describing that an update were found, and offering to install it.
presentUpdateConfirmInstallDialog()
}
}
function onUpdateErrorOccurred(error) {
presentUpdateInfoDialog((function () {
switch (error) {
case NetworkManager.ACCESS_DENIED:
return JamiStrings.genericError;
case NetworkManager.DISCONNECTED:
return JamiStrings.networkDisconnected;
case NetworkManager.NETWORK_ERROR:
return JamiStrings.updateNetworkError;
case NetworkManager.SSL_ERROR:
return JamiStrings.updateSSLError;
case NetworkManager.CANCELED:
return JamiStrings.updateDownloadCanceled;
default:
return {};
}
})());
function onNetworkErrorOccurred(error) {
var errorStr = translateErrorToString(error);
presentUpdateInfoDialog(errorStr);
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,220 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "appversionmanager.h"
#include "lrcinstance.h"
#include "version.h"
#include <QProcess>
#include <QTimer>
#include <QDir>
#ifdef BETA
static constexpr bool isBeta = true;
#else
static constexpr bool isBeta = false;
#endif
static constexpr int updatePeriod = 1000 * 60 * 60 * 24; // one day in millis
static constexpr char downloadUrl[] = "https://dl.jami.net/windows";
static constexpr char versionSubUrl[] = "/version";
static constexpr char betaVersionSubUrl[] = "/beta/version";
static constexpr char msiSubUrl[] = "/jami.release.x64.msi";
static constexpr char betaMsiSubUrl[] = "/beta/jami.beta.x64.msi";
struct AppVersionManager::Impl : public QObject
{
Impl(const QString& url, LRCInstance* instance, AppVersionManager& parent)
: QObject(nullptr)
, parent_(parent)
, lrcInstance_(instance)
, baseUrlString_(url.isEmpty() ? downloadUrl : url)
, updateTimer_(new QTimer(this))
{
connect(updateTimer_, &QTimer::timeout, this, [this] {
// Quiet period update check.
parent_.checkForUpdates(true);
});
};
~Impl() = default;
void checkForUpdates(bool quiet)
{
parent_.disconnect();
// Fail without UI if this is a programmatic check.
if (!quiet)
connect(&parent_,
&NetworkManager::errorOccurred,
&parent_,
&AppVersionManager::networkErrorOccurred);
cleanUpdateFiles();
const QUrl versionUrl {isBeta ? QUrl::fromUserInput(baseUrlString_ + betaVersionSubUrl)
: QUrl::fromUserInput(baseUrlString_ + versionSubUrl)};
parent_.sendGetRequest(versionUrl, [this, quiet](const QByteArray& latestVersionString) {
if (latestVersionString.isEmpty()) {
qWarning() << "Error checking version";
if (!quiet)
Q_EMIT parent_.updateCheckReplyReceived(false);
return;
}
auto currentVersion = QString(VERSION_STRING).toULongLong();
auto latestVersion = latestVersionString.toULongLong();
const QString channelStr = isBeta ? "beta" : "stable";
const auto newVersionFound = latestVersion > currentVersion;
qInfo().noquote() << "--------- Version info ------------"
<< QString("\n - Current: %1 (%2)").arg(currentVersion).arg(channelStr);
if (newVersionFound) {
qDebug() << " - Latest: " << latestVersion;
Q_EMIT parent_.updateCheckReplyReceived(true, true);
} else if (!quiet) {
Q_EMIT parent_.updateCheckReplyReceived(true, false);
}
});
};
void applyUpdates(bool beta = false)
{
parent_.disconnect();
connect(&parent_,
&NetworkManager::errorOccurred,
&parent_,
&AppVersionManager::networkErrorOccurred);
const QUrl downloadUrl {(beta || isBeta)
? QUrl::fromUserInput(baseUrlString_ + betaMsiSubUrl)
: QUrl::fromUserInput(baseUrlString_ + msiSubUrl)};
const auto lastDownloadReplyId = parent_.replyId_;
parent_.replyId_ = parent_.downloadFile(
downloadUrl,
lastDownloadReplyId,
[downloadUrl](bool success, const QString& errorMessage) {
Q_UNUSED(success)
Q_UNUSED(errorMessage)
QProcess process;
auto basePath = QDir::tempPath() + QDir::separator();
auto msiPath = QDir::toNativeSeparators(basePath + downloadUrl.fileName());
auto logPath = QDir::toNativeSeparators(basePath + "jami_x64_install.log");
process.startDetached("msiexec",
QStringList() << "/i" << msiPath << "/passive"
<< "/norestart"
<< "WIXNONUILAUNCH=1"
<< "/L*V" << logPath);
},
QDir::tempPath());
};
void cancelUpdate()
{
parent_.cancelDownload(parent_.replyId_);
};
void setAutoUpdateCheck(bool state)
{
// Quiet check for updates periodically, if set to.
if (!state) {
updateTimer_->stop();
return;
}
updateTimer_->start(updatePeriod);
};
void cleanUpdateFiles()
{
// Delete all logs and msi in the temporary directory before launching.
const QString dir = QDir::tempPath();
QDir log_dir(dir, {"jami*.log"});
for (const QString& filename : log_dir.entryList()) {
log_dir.remove(filename);
}
QDir msi_dir(dir, {"jami*.msi"});
for (const QString& filename : msi_dir.entryList()) {
msi_dir.remove(filename);
}
QDir version_dir(dir, {"version"});
for (const QString& filename : version_dir.entryList()) {
version_dir.remove(filename);
}
};
AppVersionManager& parent_;
LRCInstance* lrcInstance_ {nullptr};
QString baseUrlString_;
QTimer* updateTimer_;
};
AppVersionManager::AppVersionManager(const QString& url,
ConnectivityMonitor* cm,
LRCInstance* instance,
QObject* parent)
: NetworkManager(cm, parent)
, replyId_(0)
, pimpl_(std::make_unique<Impl>(url, instance, *this))
{}
AppVersionManager::~AppVersionManager()
{
cancelDownload(replyId_);
}
void
AppVersionManager::checkForUpdates(bool quiet)
{
pimpl_->checkForUpdates(quiet);
}
void
AppVersionManager::applyUpdates(bool beta)
{
pimpl_->applyUpdates(beta);
}
void
AppVersionManager::cancelUpdate()
{
pimpl_->cancelUpdate();
}
void
AppVersionManager::setAutoUpdateCheck(bool state)
{
pimpl_->setAutoUpdateCheck(state);
}
bool
AppVersionManager::isCurrentVersionBeta()
{
return isBeta;
}
bool
AppVersionManager::isUpdaterEnabled()
{
#ifdef Q_OS_WIN
return true;
#endif
return false;
}
bool
AppVersionManager::isAutoUpdaterEnabled()
{
return false;
}

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,51 +24,35 @@
class LRCInstance;
class ConnectivityMonitor;
class UpdateManager final : public NetworkManager
class AppVersionManager final : public NetworkManager
{
Q_OBJECT
Q_DISABLE_COPY(UpdateManager)
Q_DISABLE_COPY(AppVersionManager)
public:
explicit UpdateManager(const QString& url,
ConnectivityMonitor* cm,
LRCInstance* instance = nullptr,
QObject* parent = nullptr);
~UpdateManager();
enum Status { STARTED, FINISHED };
Q_ENUM(Status)
explicit AppVersionManager(const QString& url,
ConnectivityMonitor* cm,
LRCInstance* instance = nullptr,
QObject* parent = nullptr);
~AppVersionManager();
Q_INVOKABLE void checkForUpdates(bool quiet = false);
Q_INVOKABLE void applyUpdates(bool beta = false);
Q_INVOKABLE void cancelUpdate();
Q_INVOKABLE void setAutoUpdateCheck(bool state);
Q_INVOKABLE bool isCurrentVersionBeta();
Q_INVOKABLE bool isUpdaterEnabled();
Q_INVOKABLE bool isAutoUpdaterEnabled();
Q_INVOKABLE void cancelDownload();
void downloadFile(const QUrl& url,
std::function<void(bool, const QString&)> onDoneCallback,
const QString& filePath);
Q_INVOKABLE void setAutoUpdateCheck(bool state);
Q_INVOKABLE void cancelUpdate();
Q_INVOKABLE bool isCurrentVersionBeta();
Q_SIGNALS:
void statusChanged(UpdateManager::Status status);
void downloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
void updateCheckReplyReceived(bool ok, bool found = false);
void updateErrorOccurred(const NetworkManager::GetError& error);
void updateDownloadStarted();
void updateDownloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
void updateDownloadFinished();
void appCloseRequested();
void updateCheckReplyReceived(bool ok, bool found = false);
void updateDownloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
void networkErrorOccurred(const NetworkManager::GetError& error);
private:
void resetDownload();
QNetworkReply* downloadReply_ {nullptr};
QScopedPointer<QFile> file_;
private:
int replyId_;
struct Impl;
friend struct Impl;
std::unique_ptr<Impl> pimpl_;
};
Q_DECLARE_METATYPE(UpdateManager*)
Q_DECLARE_METATYPE(AppVersionManager*)

View File

@ -53,21 +53,21 @@ public:
return {};
}
auto imageId = idInfo.at(1);
const auto& imageId = idInfo.at(1);
if (!imageId.size()) {
qWarning() << Q_FUNC_INFO << "Missing id in the image url";
return {};
}
auto type = idInfo.at(0);
const auto& type = idInfo.at(0);
if (type == "conversation") {
if (imageId == "temp")
return Utils::tempConversationAvatar(requestedSize);
return Utils::conversationAvatar(lrcInstance_, imageId, requestedSize);
} else if (type == "account")
}
if (type == "account")
return Utils::accountPhoto(lrcInstance_, imageId, requestedSize);
else if (type == "contact")
if (type == "contact")
return Utils::contactPhoto(lrcInstance_, imageId, requestedSize);
qWarning() << Q_FUNC_INFO << "Missing valid prefix in the image url";

View File

@ -38,7 +38,7 @@ Item {
property string imageId
readonly property string divider: '_'
readonly property string baseProviderPrefix: 'image://avatarImage'
readonly property string baseProviderPrefix: 'image://avatarimage'
property string typePrefix: {
switch (mode) {
case Avatar.Mode.Account:

View File

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

View File

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

View File

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

View File

@ -88,8 +88,11 @@ Loader {
target: parent
enabled: canOpen
onHoveredChanged: {
dataTransferItem.hoveredLink = enabled && hovered ?
("file:///" + Body) : ""
if (enabled && hovered) {
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(Body)
} else {
dataTransferItem.hoveredLink = ""
}
}
cursorShape: enabled ?
Qt.PointingHandCursor :
@ -199,10 +202,12 @@ Loader {
Qt.PointingHandCursor :
Qt.ArrowCursor
onClicked: function (mouse) {
dataTransferItem.hoveredLink = canOpen ?
("file:///" + Body) : ""
if (dataTransferItem.hoveredLink)
if (canOpen) {
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(Body)
Qt.openUrlExternally(new Url(dataTransferItem.hoveredLink))
} else {
dataTransferItem.hoveredLink = ""
}
}
}
}
@ -303,7 +308,7 @@ Loader {
antialiasing: true
autoTransform: true
asynchronous: true
source: "file:///" + Body
source: UtilsAdapter.urlFromLocalPath(Body)
property real aspectRatio: implicitWidth / implicitHeight
property real adjustedWidth: Math.min(maxSize,
Math.max(minSize,
@ -348,7 +353,7 @@ Loader {
antialiasing: true
autoTransform: true
asynchronous: true
source: Body !== undefined ? "file:///" + Body : ''
source: Body !== undefined ? UtilsAdapter.urlFromLocalPath(Body) : ''
// The sourceSize represents the maximum source dimensions.
// This should not be a dynamic binding, as property changes

View File

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

View File

@ -85,10 +85,12 @@ BaseView {
clip: true
required property bool isMinorPane
onWidthChanged: {
if (!isSinglePane && ((isRTL && !isMinorPane) || (!isRTL && isMinorPane)))
if (!isSinglePane && isMinorPane)
previousMinorPaneWidth = width
if (!isSinglePane && ((isRTL && isMinorPane) || (!isRTL && !isMinorPane)))
if (!isSinglePane && !isMinorPane)
previousMajorPaneWidth = width
if (isMinorPane)
JamiTheme.currentLeftPaneWidth = width
}
Connections {
@ -101,8 +103,9 @@ BaseView {
}
}
SplitView.minimumWidth: isSinglePane ? viewNode.width : (isMinorPane && !isRTL ? minorPaneMinWidth : majorPaneMinWidth)
SplitView.maximumWidth: isSinglePane ? viewNode.width : viewNode.width - (isMinorPane && !isRTL ? majorPaneMinWidth : minorPaneMinWidth)
SplitView.preferredWidth: isMinorPane && !isRTL ? minorPaneMinWidth : majorPaneMinWidth
SplitView.minimumWidth: isSinglePane ? undefined : (isMinorPane ? minorPaneMinWidth : majorPaneMinWidth)
SplitView.maximumWidth: isSinglePane || !isMinorPane ? undefined : Math.abs(viewNode.width - majorPaneMinWidth)
SplitView.preferredWidth: isSinglePane || !isMinorPane ? undefined : JamiTheme.currentLeftPaneWidth
SplitView.fillWidth: !isMinorPane || isSinglePane
}
}

View File

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

View File

@ -24,9 +24,13 @@ import net.jami.Constants 1.1
Item {
id: root
width: reactionBubble.width
property var reactions
property real contentHeight: bubble.height
property real contentWidth: bubble.width
property real contentHeight: reactionBubble.height
property real contentWidth: reactionBubble.width
property color borderColor: undefined
property int maxWidth: JamiTheme.defaulMaxWidthReaction
visible: emojis.length && Body !== ""
@ -80,36 +84,30 @@ Item {
return [];
}
// TODO:
// -order emojis based on the timestamp of the reaction and/or the quantity of emojis
Rectangle {
id: bubble
id: reactionBubble
color: JamiTheme.emojiReactBubbleBgColor
width: textEmojis.width + 6
height: textEmojis.height + 6
radius: 10
Text {
id: textEmojis
anchors.margins: 10
anchors.centerIn: bubble
font.pointSize: JamiTheme.emojiReactSize
color: JamiTheme.chatviewTextColor
text: root.emojis
}
width: textEmojis.width + 10
height: textEmojis.height + 10
anchors.centerIn: textEmojis
radius: 5
border.color: root.borderColor
border.width: 1
}
DropShadow {
z: -1
Text {
id: textEmojis
anchors.margins: 10
anchors.centerIn: root
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
font.pointSize: JamiTheme.emojiReactSize
color: JamiTheme.chatviewTextColor
text: root.emojis
width: Math.min(implicitWidth,root.maxWidth)
wrapMode: Text.Wrap
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Author: Xavier Jouslin <xavier.jouslindenoray@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 Qt.labs.platform
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
RowLayout {
id: root
property string labelText: ""
property int widthOfSwitch: 50
property int heightOfSwitch: 10
property string tooltipText: ""
property alias toggleSwitch: autoupdate
property alias checked: autoupdate.checked
signal switchToggled
Layout.alignment: Qt.AlignRight
JamiSwitch {
id: autoupdate
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: widthOfSwitch
hoverEnabled: true
toolTipText: tooltipText
Accessible.role: Accessible.Button
Accessible.name: JamiStrings.autoUpdate
Accessible.description: root.tooltipText
onToggled: switchToggled()
}
Text {
id: description
Layout.rightMargin: JamiTheme.preferredMarginSize
text: JamiStrings.autoUpdate
font.pixelSize: JamiTheme.wizardViewButtonFontPixelSize
visible: labelText !== ""
font.kerning: true
wrapMode: Text.WordWrap
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
TapHandler {
target: parent
enabled: parent.visible
onTapped: function onTapped(eventPoint) {
// switchToggled should be emitted as onToggled is not called (because it's only called if the user click on the switch)
autoupdate.toggle();
switchToggled();
}
}
}

View File

@ -24,9 +24,11 @@ import net.jami.Constants 1.1
Item {
id: jamiId
property bool slimDisplay: true
property color backgroundColor: JamiTheme.welcomeBlockColor
property color contentColor: JamiTheme.tintedBlue
property bool centered: true
height: getHeight()
function getHeight() {
@ -44,12 +46,15 @@ Item {
RowLayout {
id: outerRow
width: parent.width
anchors.horizontalCenter: jamiId.centered ? parent.horizontalCenter : undefined
anchors.left: jamiId.centered ? undefined : parent.left
spacing: 2
RoundedBorderRectangle {
id: leftRect
fillColor: jamiId.backgroundColor
Layout.fillWidth: true
Layout.preferredWidth: childrenRect.width
Layout.maximumWidth: jamiId.width - rightRect.width
Layout.preferredHeight: childrenRect.height
radius: {
"tl": 5,
@ -59,7 +64,6 @@ Item {
}
RowLayout {
width: parent.width
anchors.verticalCenter: parent.verticalCenter
ResponsiveImage {
@ -74,11 +78,11 @@ Item {
UsernameTextEdit {
id: usernameTextEdit
Layout.fillWidth: true
visible: !readOnly
Layout.preferredHeight: 40
Layout.alignment: Qt.AlignVCenter
textColor: jamiId.contentColor
fontPixelSize: staticText.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.jamiIdFontSize
fontPixelSize: staticText.length > 16 || dynamicText.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
editMode: false
isPersistent: false
readOnly: true
@ -96,6 +100,19 @@ Item {
});
}
}
Label{
id: usernameLabel
visible: usernameTextEdit.readOnly
Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: JamiTheme.pushButtonMargins
Layout.maximumWidth: leftRect.width - 50
elide: Text.ElideRight
color: jamiId.contentColor
font.pixelSize : text.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
property string registeredName: CurrentAccount.registeredName
property string infohash: CurrentAccount.uri
text: registeredName ? registeredName : infohash
}
}
}
@ -116,7 +133,6 @@ Item {
id: controlsLayout
height: childrenRect.height
width: childrenRect.width
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: JamiTheme.pushButtonMargins
anchors.leftMargin: JamiTheme.pushButtonMargins
@ -178,10 +194,12 @@ Item {
toolTipText: JamiStrings.identifierURI
onClicked: {
if (clicked) {
usernameTextEdit.staticText = CurrentAccount.uri;
usernameLabel.text = Qt.binding(function() {return CurrentAccount.uri} );
usernameTextEdit.staticText = Qt.binding(function() {return CurrentAccount.uri} );
btnId.toolTipText = JamiStrings.identifierRegisterName;
} else {
usernameTextEdit.staticText = CurrentAccount.registeredName;
usernameLabel.text = Qt.binding(function() {return CurrentAccount.registeredName} );
usernameTextEdit.staticText = Qt.binding(function() {return CurrentAccount.registeredName} );
btnId.toolTipText = JamiStrings.identifierURI;
}
clicked = !clicked;
@ -196,7 +214,6 @@ Item {
preferredSize: 30
radius: 5
normalColor: JamiTheme.transparentColor
//hoveredColor: JamiTheme.hoveredButtonColorWizard
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
border.color: jamiId.contentColor

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

@ -36,11 +36,12 @@ Popup {
contentItem: ListView {
id: listViewTypoSecond
width: contentWidth + leftMargin
width: contentWidth + leftMargin + rightMargin
height: JamiTheme.chatViewFooterButtonSize
orientation: ListView.Horizontal
interactive: false
leftMargin: 10
rightMargin: 10
spacing: 10
Rectangle {
@ -53,7 +54,7 @@ Popup {
model: menuTypoActionsSecond
delegate: PushButton {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
preferredSize: JamiTheme.chatViewFooterRealButtonSize
imageContainerWidth: 20

View File

@ -1,297 +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 {
id: buttonEdit
visible: root.isOutgoing && type === Interaction.Type.TEXT
textButton: JamiStrings.editMessage
iconSource: JamiResources.edit_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.replyToId = ""
MessagesAdapter.editId = root.msgId
close()
}
}
MessageOptionButton {
visible: root.isOutgoing && type === Interaction.Type.TEXT
textButton: JamiStrings.deleteMessage
iconSource: JamiResources.delete_svg
Layout.fillWidth: true
Layout.margins: 5
onClicked: {
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId)
close()
}
}
}
}
Overlay.modal: Rectangle {
color: JamiTheme.transparentColor
// Color animation for overlay when pop up is shown.
ColorAnimation on color {
to: JamiTheme.popupOverlayColor
duration: 500
}
}
DropShadow {
z: -1
width: bubble.width
height: bubble.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: bubble.radius * 4
color: JamiTheme.shadowColor
source: bubble
transparentBorder: true
samples: radius + 1
}
enter: Transition {
NumberAnimation {
properties: "opacity"; from: 0.0; to: 1.0
duration: JamiTheme.shortFadeDuration
}
}
exit: Transition {
NumberAnimation {
properties: "opacity"; from: 1.0; to: 0.0
duration: root.closeWithoutAnimation ? 0 : JamiTheme.shortFadeDuration
}
}
}

View File

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

View File

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

View File

@ -85,7 +85,7 @@ ItemDelegate {
id: prefLlabel
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: 8
Layout.leftMargin: 20
text: preferenceName
color: JamiTheme.textColor
@ -103,7 +103,7 @@ ItemDelegate {
normalColor: JamiTheme.primaryBackgroundColor
Layout.alignment: Qt.AlignRight | Qt.AlingVCenter
Layout.rightMargin: 8
Layout.rightMargin: 20
Layout.preferredWidth: preferredSize
Layout.preferredHeight: preferredSize
imageColor: JamiTheme.textColor
@ -119,7 +119,7 @@ ItemDelegate {
visible: preferenceType === PreferenceItemListModel.SWITCH
Layout.alignment: Qt.AlignRight | Qt.AlingVCenter
Layout.rightMargin: 16
Layout.rightMargin: 20
Layout.preferredHeight: 30
Layout.preferredWidth: 30
checked: preferenceCurrentValue === "1"
@ -134,7 +134,7 @@ ItemDelegate {
visible: preferenceType === PreferenceItemListModel.LIST
Layout.preferredWidth: root.width / 2 - 8
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.rightMargin: 4
Layout.rightMargin: 20
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
@ -157,7 +157,7 @@ ItemDelegate {
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.rightMargin: 4
Layout.rightMargin: 20
text: UtilsAdapter.fileName(preferenceCurrentValue)
toolTipText: JamiStrings.chooseImageFile
@ -176,7 +176,7 @@ ItemDelegate {
Layout.preferredWidth: root.width / 2 - 8
Layout.preferredHeight: 30
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.rightMargin: 4
Layout.rightMargin: 20
visible: preferenceType === PreferenceItemListModel.EDITTEXT
width: root.width / 2 - 8

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

@ -31,7 +31,9 @@ Item {
property alias source: image.source
property alias status: image.status
property alias fillMode: image.fillMode
property alias cache: image.cache
property alias image: image
property alias mirror: image.mirror
property string color: "transparent"
property bool hovered: false
@ -68,6 +70,7 @@ Item {
antialiasing: true
asynchronous: true
visible: false
mipmap: true
function setSourceSize() {
sourceSize = undefined;

View File

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

View File

@ -60,10 +60,21 @@ Control {
property real textContentHeight
property bool isReply: ReplyTo !== ""
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
// If the ListView attached properties are not available,
// then the root delegate is likely a Loader.
readonly property ListView listView: ListView.view ? ListView.view : parent.ListView.view
function getBaseColor() {
var baseColor = isOutgoing ? CurrentConversation.color : JamiTheme.messageInBgColor;
if (Id === MessagesAdapter.replyToId || Id === MessagesAdapter.editId) {
// If we are replying to or editing the message
return Qt.darker(baseColor, 1.5);
}
return baseColor;
}
rightPadding: hPadding
leftPadding: hPadding
@ -115,7 +126,7 @@ Control {
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
Layout.topMargin: visible? JamiTheme.sbsMessageBaseReplyTopMargin : 0
Layout.topMargin: visible ? JamiTheme.sbsMessageBaseReplyTopMargin : 0
Layout.leftMargin: isOutgoing ? undefined : JamiTheme.sbsMessageBaseReplyMargin
Layout.rightMargin: !isOutgoing ? undefined : JamiTheme.sbsMessageBaseReplyMargin
@ -201,7 +212,7 @@ Control {
RowLayout {
id: msgRowlayout
Layout.preferredHeight: innerContent.height + root.extraHeight
Layout.preferredHeight: innerContent.height + root.extraHeight + (emojiReactions.emojis === "" ? 0 : emojiReactions.height - 8)
Layout.topMargin: ((seq === MsgSeq.first || seq === MsgSeq.single) && !root.isReply) ? 6 : 0
Item {
@ -266,8 +277,8 @@ Control {
anchors.rightMargin: isOutgoing ? 10 : 0
anchors.leftMargin: !isOutgoing ? 10 : 0
imageColor: JamiTheme.emojiReactPushButtonColor
normalColor: JamiTheme.transparentColor
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
toolTipText: JamiStrings.moreOptions
anchors.verticalCenter: parent.verticalCenter
anchors.right: isOutgoing ? optionButtonItem.right : undefined
@ -276,9 +287,10 @@ Control {
source: JamiResources.more_vert_24dp_svg
width: optionButtonItem.width / 2
height: optionButtonItem.height
circled: false
onClicked: {
var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml");
var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
var obj = component.createObject(bubble, {
"emojiReactions": emojiReactions,
"isOutgoing": isOutgoing,
@ -296,13 +308,15 @@ Control {
PushButton {
id: reply
imageColor: JamiTheme.emojiReactPushButtonColor
normalColor: JamiTheme.transparentColor
circled: false
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
toolTipText: JamiStrings.reply
source: JamiResources.reply_svg
width: optionButtonItem.width / 2
height: optionButtonItem.height
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 5
anchors.right: isOutgoing ? more.left : undefined
anchors.left: !isOutgoing ? more.right : undefined
visible: CurrentAccount.type !== Profile.Type.SIP && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || bgHandler.hovered)
@ -323,17 +337,7 @@ Control {
out: isOutgoing
type: seq
isReply: root.isReply
function getBaseColor() {
var baseColor = isOutgoing ? CurrentConversation.color : JamiTheme.messageInBgColor;
if (Id === MessagesAdapter.replyToId || Id === MessagesAdapter.editId) {
// If we are replying to or editing the message
return Qt.darker(baseColor, 1.5);
}
return baseColor;
}
color: getBaseColor()
color: root.getBaseColor()
radius: msgRadius
anchors.right: isOutgoing ? parent.right : undefined
anchors.top: parent.top
@ -342,6 +346,55 @@ Control {
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0)
}
EmojiReactions {
id: emojiReactions
anchors.top: bubble.bottom
anchors.topMargin: -8
height: contentHeight + 5
reactions: Reactions
borderColor: root.getBaseColor()
maxWidth: 2 / 3 * maxMsgWidth - JamiTheme.emojiMargins
state: root.isOutgoing ? "anchorsRight" : (emojiReactions.width > bubble.width - JamiTheme.emojiMargins ? "anchorsLeft" : "anchorsRight")
TapHandler {
onTapped: {
reactionPopup.open();
}
}
states: [
State {
name: "anchorsRight"
AnchorChanges {
target: emojiReactions
anchors.right: bubble.right
anchors.left: undefined
}
PropertyChanges {
target: emojiReactions
anchors.rightMargin: JamiTheme.emojiMargins
anchors.leftMargin: 0
}
},
State {
name: "anchorsLeft"
AnchorChanges {
target: emojiReactions
anchors.right: undefined
anchors.left: bubble.left
}
PropertyChanges {
target: emojiReactions
anchors.rightMargin: 0
anchors.leftMargin: JamiTheme.emojiMargins
}
}
]
}
Rectangle {
id: bg
@ -440,25 +493,6 @@ Control {
}
}
EmojiReactions {
id: emojiReactions
property bool isOutgoing: Author === CurrentAccount.uri
Layout.alignment: isOutgoing ? Qt.AlignRight : Qt.AlignLeft
Layout.rightMargin: isOutgoing ? status.width : undefined
Layout.leftMargin: !isOutgoing ? avatarBlock.width : undefined
Layout.topMargin: -contentHeight / 4
Layout.preferredHeight: contentHeight + 5
Layout.preferredWidth: contentWidth
reactions: Reactions
TapHandler {
onTapped: {
reactionPopup.open();
}
}
}
ListView {
id: infoCell

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import net.jami.Constants 1.1
import "contextmenu"
BaseContextMenu {
id: root
property var modelList
signal audioRecordMessageButtonClicked
signal videoRecordMessageButtonClicked
signal showMapClicked
property list<GeneralMenuItem> menuItems: [
GeneralMenuItem {
id: audioMessage
canTrigger: true
iconSource: JamiResources.message_audio_black_24dp_svg
itemName: JamiStrings.leaveAudioMessage
onClicked: {
root.audioRecordMessageButtonClicked();
}
},
GeneralMenuItem {
id: videoMessage
canTrigger: true
iconSource: JamiResources.message_video_black_24dp_svg
itemName: JamiStrings.leaveVideoMessage
onClicked: {
root.videoRecordMessageButtonClicked();
}
},
GeneralMenuItem {
id: shareLocation
canTrigger: true
iconSource: JamiResources.localisation_sharing_send_pin_svg
itemName: JamiStrings.shareLocation
onClicked: {
root.showMapClicked();
}
}
]
Component.onCompleted: {
root.loadMenuItems(menuItems);
}
}

View File

@ -1,134 +0,0 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.platform
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../mainview/components"
Popup {
id: root
padding: 0
property list<Action> menuMoreButton
height: childrenRect.height
width: childrenRect.width
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
Rectangle {
id: rect
color: JamiTheme.primaryBackgroundColor
border.color: JamiTheme.chatViewFooterRectangleBorderColor
border.width: 2
radius: 5
height: listViewMoreButton.childrenRect.height + 16
width: listViewMoreButton.childrenRect.width + 16
ListView {
id: listViewMoreButton
anchors.centerIn: parent
orientation: ListView.Vertical
spacing: 0
width: contentItem.childrenRect.width
height: contentHeight
model: menuMoreButton
Rectangle {
z: -1
anchors.fill: parent
color: "transparent"
}
onCountChanged: {
for (var i = 0; i < count; i++) {
var item = listViewMoreButton.itemAtIndex(i);
item.width = listViewMoreButton.width;
}
}
delegate: ItemDelegate {
id: control
text: modelData.toolTip
contentItem: RowLayout {
Rectangle {
id: image
width: 26
height: 26
radius: 5
color: JamiTheme.transparentColor
ResponsiveImage {
anchors.fill: parent
source: modelData.iconSrc
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
}
}
Text {
Layout.alignment: Qt.AlignLeft
text: control.text
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : "#7f7f7f"
}
}
background: Rectangle {
color: control.hovered ? JamiTheme.showMoreButtonOpenColor : JamiTheme.transparentColor
}
action: modelData
onClicked: {
root.close();
}
}
}
}
background: Rectangle {
anchors.fill: parent
color: JamiTheme.transparentColor
radius: 5
z: -1
}
enter: Transition {
NumberAnimation {
properties: "opacity"
from: 0.0
to: 1.0
duration: JamiTheme.shortFadeDuration
}
}
exit: Transition {
NumberAnimation {
properties: "opacity"
from: 1.0
to: 0.0
duration: JamiTheme.shortFadeDuration
}
}
}

View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import net.jami.Constants 1.1
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import "contextmenu"
BaseContextMenu {
id: root
required property var emojiReactions
property var emojiReplied: emojiReactions.ownEmojis
required property string msgId
required property string msgBody
required property bool isOutgoing
required property int type
required property string transferName
required property Item msgBubble
required property ListView listView
property string location: msgBody
property bool closeWithoutAnimation: false
property var emojiPicker
function xPositionProvider(width) {
// Use the width at function scope to retrigger property evaluation.
const listViewWidth = listView.width;
if (isOutgoing) {
const leftMargin = msgBubble.mapToItem(listView, 0, 0).x;
return width > leftMargin ? -leftMargin - 35 : -width - 35;
} else {
const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width);
return width > rightMargin ? msgBubble.width - width + 35 : msgBubble.width + 35;
}
}
function yPositionProvider(height) {
const topOffset = msgBubble.mapToItem(listView, 0, 0).y;
if (topOffset < 0)
return -topOffset;
const bottomOffset = topOffset + height - listView.height;
if (bottomOffset > 0)
return -bottomOffset;
return 0;
}
x: xPositionProvider(width)
y: yPositionProvider(height)
signal addMoreEmoji
onAddMoreEmoji: {
JamiQmlUtils.updateMessageBarButtonsPoints();
openEmojiPicker();
}
function openEmojiPicker() {
var component = WITH_WEBENGINE ? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") : Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml");
emojiPicker = component.createObject(root.parent, {
"listView": listView
});
emojiPicker.emojiIsPicked.connect(function (content) {
if (emojiReplied.includes(content)) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId);
}
});
if (emojiPicker !== null) {
root.opacity = 0;
emojiPicker.closed.connect(() => close());
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth);
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight);
emojiPicker.open();
} else {
console.log("Error creating emojiPicker from message options popup");
}
}
// Close the picker when listView vertical properties change.
property real listViewHeight: listView.height
onListViewHeightChanged: close()
property bool isScrolling: listView.verticalScrollBar.active
onIsScrollingChanged: close()
onOpened: root.closeWithoutAnimation = false
onClosed: if (emojiPicker)
emojiPicker.closeEmojiPicker()
function getModel() {
const defaultModel = ["👍", "👎", "😂"];
const reactedEmojis = Array.isArray(emojiReplied) ? emojiReplied.slice(0, defaultModel.length) : [];
const uniqueEmojis = Array.from(new Set(reactedEmojis));
const missingEmojis = defaultModel.filter(emoji => !uniqueEmojis.includes(emoji));
return uniqueEmojis.concat(missingEmojis);
}
property list<MenuItem> menuItems: [
GeneralMenuItemList {
id: audioMessage
modelList: getModel()
canTrigger: true
iconSource: JamiResources.add_reaction_svg
itemName: JamiStrings.copy
addMenuSeparatorAfter: true
messageId: msgId
},
GeneralMenuItem {
id: saveFile
canTrigger: type === Interaction.Type.DATA_TRANSFER
iconSource: JamiResources.save_file_svg
itemName: JamiStrings.saveFile
onClicked: {
MessagesAdapter.copyToDownloads(root.msgId, root.transferName);
}
},
GeneralMenuItem {
id: openLocation
canTrigger: type === Interaction.Type.DATA_TRANSFER
iconSource: JamiResources.round_folder_24dp_svg
itemName: JamiStrings.openLocation
onClicked: {
MessagesAdapter.openDirectory(root.location);
}
},
GeneralMenuItem {
id: removeLocally
canTrigger: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
iconSource: JamiResources.trash_black_24dp_svg
itemName: JamiStrings.removeLocally
onClicked: {
MessagesAdapter.removeFile(msgId, root.location);
;
}
},
GeneralMenuItem {
id: editMessage
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
iconSource: JamiResources.edit_svg
itemName: JamiStrings.editMessage
onClicked: {
MessagesAdapter.replyToId = "";
MessagesAdapter.editId = root.msgId;
}
},
GeneralMenuItem {
id: deleteMessage
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
iconSource: JamiResources.delete_svg
itemName: JamiStrings.deleteMessage
onClicked: {
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId);
}
},
GeneralMenuItem {
id: copyMessage
canTrigger: true
iconSource: JamiResources.copy_svg
itemName: JamiStrings.copy
onClicked: {
UtilsAdapter.setClipboardText(msgBody);
}
}
]
Component.onCompleted: {
root.loadMenuItems(menuItems);
}
}

View File

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

View File

@ -32,9 +32,8 @@ Item {
property int spinningAnimationWidth: 4
property real outerCutRadius: root.height / 2
property int spinningAnimationDuration: 1000
property color color: "white"
visible: mode !== SpinningAnimation.Mode.Disabled
ConicalGradient {
id: conicalGradientOne
@ -48,7 +47,7 @@ Item {
}
GradientStop {
position: 1.0
color: "white"
color: mode === SpinningAnimation.Mode.Disabled ? "transparent" : root.color
}
}
@ -90,7 +89,7 @@ Item {
}
GradientStop {
position: 1.0
color: "white"
color: mode === SpinningAnimation.Mode.Disabled ? "transparent" : root.color
}
}

View File

@ -30,15 +30,14 @@ SBSMessageBase {
property bool isRemoteImage
property bool isEmojiOnly: IsEmojiOnly
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
property string colorUrl: UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewLinkColorLight : JamiTheme.chatviewLinkColorDark
property string colorText: UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark
Connections {
target: bubble
function onColorChanged(color) {
root.colorUrl = UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewLinkColorLight : JamiTheme.chatviewLinkColorDark
root.colorText = UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark
root.colorUrl = UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewLinkColorLight : JamiTheme.chatviewLinkColorDark;
root.colorText = UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark;
// Update parsed body with correct colors
if (Body !== "")
MessagesAdapter.parseMessage(Id, Body, UtilsAdapter.getAppValue(Settings.DisplayHyperlinkPreviews), root.colorUrl, bubble.color);
@ -65,7 +64,7 @@ SBSMessageBase {
text: {
if (Body !== "" && ParsedBody.length === 0) {
MessagesAdapter.parseMessage(Id, Body, UtilsAdapter.getAppValue(Settings.DisplayHyperlinkPreviews), root.colorUrl, bubble.color);
return ""
return "";
}
return (ParsedBody !== "") ? ParsedBody : "<i>(" + JamiStrings.deletedMessage + ")</i>";
}
@ -277,5 +276,5 @@ SBSMessageBase {
duration: 100
}
}
Component.onCompleted: opacity = 1;
Component.onCompleted: opacity = 1
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,216 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Constants 1.1
import "../"
import net.jami.Adapters 1.1
// General menu item.
// Can control top, bottom, left, right border width.
// Use onClicked slot to simulate item click event.
// Can have image icon at the left of the text.
MenuItem {
id: menuItem
property var modelList: undefined
property string itemName: ""
property var iconSource: undefined
property string iconColor: ""
property bool canTrigger: true
property bool hasIcon: true
property bool addMenuSeparatorAfter: false
property bool autoTextSizeAdjustment: true
property bool dangerous: false
property BaseContextMenu parentMenu
property string messageId
signal addMoreEmoji
property int itemPreferredWidth: 207
property int itemRealWidth: itemPreferredWidth
property int itemPreferredHeight: JamiTheme.menuItemsPreferredHeight
property int leftBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int rightBorderWidth: JamiTheme.menuItemsCommonBorderWidth
property int itemImageLeftMargin: 18
signal clicked
width: itemRealWidth
contentItem: Item {
id: menuItemContentRect
anchors.fill: parent
RowLayout {
spacing: 0
anchors.fill: menuItemContentRect
Rectangle {
id: contextMenuItemImage
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin
height: 36
width: 36
color: emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[0]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage.color = emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[0])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[0], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[0], msgId);
}
close();
}
}
}
Rectangle {
id: contextMenuItemImage2
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
height: 36
width: 36
color: emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[1]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage2.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage2.color = emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[1])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[1], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[1], msgId);
}
close();
}
}
}
Rectangle {
id: contextMenuItemImage3
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
height: 36
width: 36
color: emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
radius: 5
Text {
anchors.centerIn: parent
text: modelList[2]
font.pointSize: JamiTheme.emojiBubbleSize
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
contextMenuItemImage3.color = JamiTheme.hoveredButtonColor;
}
onExited: {
contextMenuItemImage3.color = emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
}
onClicked: {
if (emojiReplied.includes(modelList[2])) {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[2], msgId);
} else {
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[2], msgId);
}
close();
}
}
}
PushButton {
id: contextMenuItemImage4
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: itemImageLeftMargin / 2
Layout.rightMargin: itemImageLeftMargin
height: 36
width: 36
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
normalColor: JamiTheme.primaryBackgroundColor
radius: 5
source: iconSource
onClicked: {
root.addMoreEmoji();
}
}
}
}
highlighted: true
background: Rectangle {
id: contextMenuBackgroundRect
anchors.fill: parent
anchors.leftMargin: leftBorderWidth
anchors.rightMargin: rightBorderWidth
color: JamiTheme.primaryBackgroundColor
implicitWidth: itemRealWidth
implicitHeight: itemPreferredHeight
border.width: 0
CustomBorder {
commonBorder: false
lBorderwidth: leftBorderWidth
rBorderwidth: rightBorderWidth
tBorderwidth: 0
bBorderwidth: 0
borderColor: JamiTheme.primaryBackgroundColor
}
}
}

View File

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

View File

@ -0,0 +1,228 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "connectioninfolistmodel.h"
ConnectionInfoListModel::ConnectionInfoListModel(LRCInstance* instance, QObject* parent)
: AbstractListModelBase(parent)
{
lrcInstance_ = instance;
connect(lrcInstance_,
&LRCInstance::currentAccountIdChanged,
this,
&ConnectionInfoListModel::resetData);
}
int
ConnectionInfoListModel::rowCount(const QModelIndex& parent) const
{
return peerIds_.size();
}
QVariant
ConnectionInfoListModel::data(const QModelIndex& index, int role) const
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
qWarning() << "ConnectionInfoListModel::data: accountId or peerID is empty";
return {};
}
const auto peerId = peerIds_[index.row()];
const auto peerData = peerData_[peerId];
switch (role) {
case ConnectionInfoList::ChannelsMap: {
QVariantMap channelsMapMap;
int i = 0;
for (const auto& device : peerData.keys()) {
QString channelsId = peerData[device]["id"].toString();
QVariantMap channelsMap;
const auto channelInfoList = lrcInstance_->getChannelList(accountId, channelsId);
for (const auto& channelInfo : channelInfoList) {
channelsMap.insert(channelInfo["id"], channelInfo["name"]);
}
channelsMapMap.insert(QString::number(i++), channelsMap);
}
return QVariant(channelsMapMap);
}
case ConnectionInfoList::ConnectionDatas: {
QString peerString;
peerString += "Peer:" + peerId;
for (const auto& device : peerData.keys()) {
peerString += "{";
peerString += "Device:" + device + ",";
peerString += "Status:" + peerData[device]["status"].toString() + ",";
peerString += "Channels:" + peerData[device]["channels"].toString() + ",";
peerString += "Remote Address" + peerData[device]["remoteAddress"].toString();
peerString += "}";
}
return peerString;
}
case ConnectionInfoList::PeerId:
return peerId;
case ConnectionInfoList::RemoteAddress: {
QVariantMap remoteAddressMap;
int i = 0;
for (const auto& device : peerData.keys()) {
remoteAddressMap.insert(QString::number(i++), peerData[device]["remoteAddress"]);
}
return QVariant(remoteAddressMap);
}
case ConnectionInfoList::DeviceId: {
QVariantMap deviceMap;
int i = 0;
for (const auto& device : peerData.keys()) {
deviceMap.insert(QString::number(i++), device);
}
return QVariant(deviceMap);
}
case ConnectionInfoList::Status: {
QVariantMap statusMap;
int i = 0;
for (const auto& device : peerData.keys()) {
statusMap.insert(QString::number(i++), peerData[device]["status"]);
}
return QVariantMap(statusMap);
}
case ConnectionInfoList::Channels: {
QVariantMap channelsMap;
int i = 0;
for (const auto& device : peerData.keys()) {
channelsMap.insert(QString::number(i++), peerData[device]["channels"]);
}
return QVariant(channelsMap);
}
case ConnectionInfoList::Count:
return peerData.size();
}
return {};
}
QHash<int, QByteArray>
ConnectionInfoListModel::roleNames() const
{
using namespace ConnectionInfoList;
QHash<int, QByteArray> roles;
#define X(role) roles[role] = #role;
CONNECTONINFO_ROLES
#undef X
return roles;
}
void
ConnectionInfoListModel::update()
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
return;
}
aggregateData();
}
template<typename T>
std::tuple<QVector<T>, QVector<T>>
getSetDiff(QVector<T> u, QVector<T> v)
{
using namespace std;
QVector<T> a, r;
set_difference(v.begin(), v.end(), u.begin(), u.end(), inserter(a, a.begin()));
set_difference(u.begin(), u.end(), v.begin(), v.end(), inserter(r, r.begin()));
return {a, r};
}
void
ConnectionInfoListModel::aggregateData()
{
const auto accountId = lrcInstance_->get_currentAccountId();
if (accountId.isEmpty()) {
return;
}
connectionInfoList_ = lrcInstance_->getConnectionList(accountId);
peerData_ = {};
QSet<QString> newPeerIds;
for (const auto& connectionInfo : connectionInfoList_) {
if (!connectionInfo["peer"].isEmpty()) {
newPeerIds.insert(connectionInfo["peer"]);
}
const auto channelInfoList = lrcInstance_->getChannelList(accountId, connectionInfo["id"]);
peerData_[connectionInfo["peer"]][connectionInfo["device"]] = {};
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["status"]
= connectionInfo["status"];
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["channels"] = channelInfoList
.size();
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["id"] = connectionInfo["id"];
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["remoteAddress"]
= connectionInfo["remoteAddress"];
}
QVector<QString> oldVector;
for (const auto& peerId : peerIds_) {
oldVector << peerId;
}
QVector<QString> newVector;
for (const auto& peerId : newPeerIds) {
newVector << peerId;
}
std::sort(oldVector.begin(), oldVector.end());
std::sort(newVector.begin(), newVector.end());
QVector<QString> removed, added;
std::tie(added, removed) = getSetDiff(oldVector, newVector);
Q_FOREACH (const auto& key, added) {
auto index = std::distance(newVector.begin(),
std::find(newVector.begin(), newVector.end(), key));
beginInsertRows(QModelIndex(), index, index);
peerIds_.insert(index, key);
endInsertRows();
}
Q_FOREACH (const auto& key, removed) {
auto index = std::distance(oldVector.begin(),
std::find(oldVector.begin(), oldVector.end(), key));
beginRemoveRows(QModelIndex(), index, index);
if (peerIds_.size() > index) {
peerIds_.remove(index);
} else {
qWarning() << "ConnectionInfoListModel::aggregateData: index out of range";
qWarning() << "index: " << index;
qWarning() << "key: " << key;
}
endRemoveRows();
}
// HACK: loop through all the peerIds_ and update the data for each one.
// This is not efficient, but it works.
Q_FOREACH (const auto& peerId, peerIds_) {
auto index = std::distance(peerIds_.begin(),
std::find(peerIds_.begin(), peerIds_.end(), peerId));
Q_EMIT dataChanged(this->index(index), this->index(index));
}
}
void
ConnectionInfoListModel::resetData()
{
beginResetModel();
peerIds_.clear();
peerData_.clear();
endResetModel();
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "abstractlistmodelbase.h"
#define CONNECTONINFO_ROLES \
X(ConnectionDatas) \
X(ChannelsMap) \
X(PeerName) \
X(PeerId) \
X(DeviceId) \
X(Status) \
X(Channels) \
X(RemoteAddress) \
X(Count) // this is the number of connections (convenience)
namespace ConnectionInfoList {
Q_NAMESPACE
enum Role {
DummyRole = Qt::UserRole + 1,
#define X(role) role,
CONNECTONINFO_ROLES
#undef X
};
Q_ENUM_NS(Role)
} // namespace ConnectionInfoList
class ConnectionInfoListModel : public AbstractListModelBase
{
public:
explicit ConnectionInfoListModel(LRCInstance* instance, QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void update();
private:
using Role = ConnectionInfoList::Role;
VectorMapStringString connectionInfoList_;
QVector<QString> peerIds_;
QMap<QString, QMap<QString, QMap<QString, QVariant>>> peerData_;
void aggregateData();
void resetData();
};

View File

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

View File

@ -35,7 +35,6 @@ Item {
property string incomingVideoCallFrom: qsTr("Incoming video call from {}")
property string startSwarm: qsTr("Start swarm")
property string createSwarm: qsTr("Create swarm")
property string showInvitations: qsTr("Show invitations")
property string invitations: qsTr("Invitations")
property string description: qsTr("Jami is a universal communication platform, with privacy as its foundation, that relies on a free distributed network for everyone.")
property string updateToSwarm: qsTr("Migrating to the Swarm technology will enable synchronizing this conversation across multiple devices and improve reliability. The legacy conversation history will be cleared in the process.")
@ -46,13 +45,10 @@ Item {
property string reconnectTry: qsTr("Trying to reconnect to the Jami daemon (jamid)…")
// AboutPopUp
property string version: qsTr("Version") + (UpdateManager.isCurrentVersionBeta() ? " (Beta)" : "")
property string companyDeclarationYear: declarationYear + " " + companyName
property string version: qsTr("Version") + (AppVersionManager.isCurrentVersionBeta() ? " (Beta)" : "")
property string declarationYear: "© 2015-2023"
property string companyName: "Savoir-faire Linux Inc."
property string slogan: "Világfa"
property string slogan: "Eleutheria"
property string declaration: qsTr("Jami is a free universal communication software that respects the freedom and privacy of its users.")
property string credits: qsTr("Credits")
// AccountComboBox
property string displayQRCode: qsTr("Display QR code")
@ -84,7 +80,6 @@ Item {
property string autoAnswerCalls: qsTr("Automatically answer calls")
property string enableCustomRingtone: qsTr("Enable custom ringtone")
property string selectCustomRingtone: qsTr("Select custom ringtone")
property string addCustomRingtone: qsTr("Add a custom ringtone")
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)")
@ -109,7 +104,6 @@ Item {
property string verifyCertificatesClient: qsTr("Verify server TLS certificates")
property string tlsRequireConnections: qsTr("Require certificate for incoming TLS connections")
property string disableSecureDlgCheck: qsTr("Disable secure dialog check for incoming TLS data")
property string audioDeviceSelector: qsTr("Audio input device selector")
property string selectPrivateKey: qsTr("Select a private key")
property string selectUserCert: qsTr("Select a user certificate")
property string selectCACert: qsTr("Select a CA certificate")
@ -166,7 +160,7 @@ Item {
property string back: qsTr("Back")
property string accountSettingsMenuTitle: qsTr("Account")
property string generalSettingsTitle: qsTr("General")
property string pluginSettingsTitle: qsTr("Plugins")
property string pluginSettingsTitle: qsTr("Extensions")
property string enableAccountSettingsTitle: qsTr("Enable account")
property string manageAccountSettingsTitle: qsTr("Manage account")
property string linkedDevicesSettingsTitle: qsTr("Linked devices")
@ -196,7 +190,6 @@ Item {
property string selectFPS: qsTr("Select video frame rate (frames per second)")
property string enableHWAccel: qsTr("Enable hardware acceleration")
property string mirrorLocalVideo: qsTr("Mirror local video")
property string previewUnavailable: qsTr("Preview unavailable")
property string screenSharing: qsTr("Screen sharing")
property string selectScreenSharingFPS: qsTr("Select screen sharing frame rate (frames per second)")
property string noVideo: qsTr("no video")
@ -206,11 +199,8 @@ Item {
property string backupAccountInfos: qsTr("Your account only exists on this device. " + "If you lose your device or uninstall the application, " + "your account will be deleted and CANNOT be recovered. " + "You can <a href='blank'> back up your account </a> now or later (in the Account Settings).")
property string backupAccountHere: qsTr("Back up account here")
property string backupAccountBtn: qsTr("Back up account")
property string skip: qsTr("Skip")
property string success: qsTr("Success")
property string error: qsTr("Error")
property string neverShowAgain: qsTr("Never show me this again")
property string recommended: qsTr("Recommended")
property string jamiArchiveFiles: qsTr("Jami archive files (*.gz)")
property string allFiles: qsTr("All files (*)")
@ -222,8 +212,6 @@ Item {
// CallOverlay
property string isRecording: qsTr("is recording")
property string areRecording: qsTr("are recording")
property string peerStoppedRecording: qsTr("Peer stopped recording")
property string isCallingYou: qsTr("is calling you")
property string mute: qsTr("Mute")
property string unmute: qsTr("Unmute")
property string pauseCall: qsTr("Pause call")
@ -270,12 +258,10 @@ Item {
property string contactDetails: qsTr("Contact details")
// CallViewContextMenu
property string hold: qsTr("Hold")
property string sipInputPanel: qsTr("Sip input panel")
property string transferCall: qsTr("Transfer call")
property string stopRec: qsTr("Stop recording")
property string startRec: qsTr("Start recording")
property string exitFullScreen: qsTr("Exit full screen")
property string viewFullScreen: qsTr("View full screen")
property string shareScreen: qsTr("Share screen")
property string shareWindow: qsTr("Share window")
@ -310,10 +296,6 @@ Item {
// Share location/position
property string shareLocation: qsTr("Share location")
property string stopSharingLocation: qsTr("Stop sharing")
property string shortSharing: qsTr("10 minutes")
property string longSharing: qsTr("One hour")
property string minutesLeft: qsTr("%1 minutes left")
property string minuteLeft: qsTr("%1 minute left")
property string locationServicesError: qsTr("Your precise location could not be determined.\nIn Device Settings, please turn on \"Location Services\".\nOther participants' location can still be received.")
property string locationServicesClosedError: qsTr("Your precise location could not be determined. Please check your Internet connection.")
property string stopAllSharings: qsTr("Turn off location sharing")
@ -323,20 +305,22 @@ Item {
property string unpinStopSharingTooltip: qsTr("Pin map to be able to share location or to turn off location in specific conversations")
property string stopSharingSeveralConversationTooltip: qsTr("Location is shared in several conversations, click to choose how to turn off location sharing")
property string shareLocationToolTip: qsTr("Share location to participants of this conversation (%1)")
property string minimizeMapTooltip: qsTr("Minimize")
property string maximizeMapTooltip: qsTr("Maximize")
property string reduceMapTooltip: qsTr("Reduce")
property string extendMapTooltip: qsTr("Extend")
property string dragMapTooltip: qsTr("Drag")
property string centerMapTooltip: qsTr("Center")
property string closeMapTooltip: qsTr("Close")
property string unpin: qsTr("Unpin")
property string pinWindow: qsTr("Pin")
property string positionShareDuration: qsTr("Position share duration")
property string positionShareLimit: qsTr("Limit the duration of location sharing")
property string locationSharingLabel: qsTr("Location sharing")
property string maxLocationDuration: qsTr("Unlimited")
property string minLocationDuration: qsTr("1 min")
property string xhourxmin: qsTr("%1h%2min")
property string xhour: qsTr("%1h")
property string xminxsec: qsTr("%1min%2s")
property string xmin: qsTr("%1min")
property string xsec: qsTr("%sec")
// Chatview header
property string hideChat: qsTr("Hide chat")
@ -365,24 +349,16 @@ Item {
// ConnectToAccountManager
property string enterJAMSURL: qsTr("Enter the Jami Account Management Server (JAMS) URL")
property string required: qsTr("Required")
property string jamiManagementServerURL: qsTr("Jami Account Management Server URL")
property string jamsCredentials: qsTr("Enter JAMS credentials")
property string connect: qsTr("Connect")
property string creatingAccount: qsTr("Creating account…")
property string backToWelcome: qsTr("Back to welcome page")
// CreateAccountPage
property string chooseName: qsTr("Choose name")
property string chooseUsername: qsTr("Choose username")
property string chooseAUsername: qsTr("Choose a username")
property string chooseIdentifier: qsTr("Choose an identifier")
property string identifierNotAvailable: qsTr("The identifier is not available")
property string createPassword: qsTr("Encrypt account with password")
property string createAccount: qsTr("Create account")
property string confirmPassword: qsTr("Confirm password")
property string notePasswordRecovery: qsTr("Choose a password to encrypt your account on this device. Note that the password CANNOT be recovered.")
property string optional: qsTr("Optional")
property string chooseUsernameForAccount: qsTr("You can choose a username to help others more easily find and reach you on Jami.")
property string chooseUsernameForRV: qsTr("Choose a name for your rendezvous point")
property string chooseAName: qsTr("Choose a name")
@ -406,7 +382,6 @@ Item {
property string sipAccount: qsTr("SIP account")
property string proxy: qsTr("Proxy")
property string server: qsTr("Server")
property string createSIPAccount: qsTr("Create SIP account")
property string configureExistingSIP: qsTr("Configure an existing SIP account")
property string personalizeAccount: qsTr("Personalize account")
property string addSip: qsTr("Add SIP account")
@ -417,7 +392,7 @@ Item {
// accountSettingsPages
property string customizeAccountDescription: qsTr("Your profile is only shared with your contacts.\nYour picture and your nickname can be changed at all time in the settings of your account.")
property string usernameAccountDescription: qsTr("A chosen username can help to be found more easily on Jami.\nIf a username is not chosen, a randomly generated 40-character identifier will be assigned to this account as a username. It is more difficult to be found and reached with this identifier.")
property string ecryptAccountDescription: qsTr("Your Jami account is registered only on this device as an archive containing the keys of your account. Access to this archive can be protected by a password.")
property string encryptAccountDescription: qsTr("Your Jami account is registered only on this device as an archive containing the keys of your account. Access to this archive can be protected by a password.")
property string saveAccountTitle: qsTr("Backup account")
property string saveAccountDescription: qsTr("This Jami account exists only on this device.\nThe account will be lost if this device is lost or the application is uninstalled. It is recommended to make a backup of this account.")
property string deleteAccountTitle: qsTr("Delete your account")
@ -425,7 +400,6 @@ Item {
property string linkedAccountList: qsTr("List of the devices that are linked to this account:")
property string linkedThisDevice: qsTr("This device")
property string linkedOtherDevices: qsTr("Other linked devices")
property string linkedAccountDescription: qsTr("Linking this account to other devices enables it to be used on other devices.")
// CurrentAccountSettings && AdvancedSettings
property string backupSuccessful: qsTr("Backup successful")
@ -448,30 +422,28 @@ Item {
property string encryptTitle: qsTr("Encrypt account with a password")
property string encryptDescription: qsTr("A Jami account is created and stored locally only on this device, as an archive containing your account keys. Access to this archive can optionally be protected by a password.")
property string encryptWarning: qsTr("Please note that if you lose your password, it CANNOT be recovered!")
property string enterNickname: qsTr("Enter a nickname, surname...")
property string enterNickname: qsTr("Enter a nickname, surname")
property string linkTitle: qsTr("Use this account on other devices")
property string linkDescription: qsTr("This account is created and stored locally, if you want to use it on another device you have to link the new device to this account.")
property string linkAnotherDevice: qsTr("Link device")
// NameRegistrationDialog
property string setUsername: qsTr("Set username")
property string registeringName: qsTr("Registering name")
// JamiUserIdentity
property string registerAUsername: qsTr("Register a username")
property string registerUsername: qsTr("Register username")
property string identity: qsTr("Identity")
// LinkedDevices
property string tipLinkNewDevice: qsTr("Link a new device to this account")
property string linkAnotherDevice: qsTr("Link a new device")
property string linkNewDevice: qsTr("Exporting account…")
property string linkDevice: qsTr("Exporting account…")
property string removeDevice: qsTr("Remove Device")
property string sureToRemoveDevice: qsTr("Are you sure you wish to remove this device?")
property string yourPinIs: qsTr("Your PIN is:")
property string linkDeviceNetWorkError: qsTr("Error connecting to the network.\nPlease try again later.")
// BannedContacts
property string tipBannedContactsDisplay: qsTr("Display banned contacts")
property string banned: qsTr("Banned")
property string tipBannedContactsHide: qsTr("Hide banned contacts")
property string bannedContacts: qsTr("Banned contacts")
// DeleteAccountDialog
@ -491,16 +463,12 @@ Item {
property string light: qsTr("Light")
property string selectFolder: qsTr("Select a folder")
property string enableNotifications: qsTr("Enable notifications")
property string applicationTheme: qsTr("Application theme")
property string showNotifications: qsTr("Show notifications")
property string keepMinimized: qsTr("Minimize on close")
property string tipRunStartup: qsTr("Run at system startup")
property string runStartup: qsTr("Launch at startup")
property string downloadFolder: qsTr("Choose download directory")
property string tipChooseDownloadFolder: qsTr("Choose download directory")
property string includeLocalVideo: qsTr("Include local video in recording")
property string textZoom: qsTr("Text zoom")
property string changeTextSize: qsTr("Change text size (%)")
property string defaultSettings: qsTr("Default settings")
// ChatviewSettings
@ -509,7 +477,6 @@ Item {
property string displayHyperlinkPreviews: qsTr("Show link preview in conversations")
property string displayHyperlinkPreviewsDescription: qsTr("Preview requires downloading content from third-party servers.")
property string layout: qsTr("Layout")
property string language: qsTr("User interface language")
property string verticalViewOpt: qsTr("Vertical view")
property string horizontalViewOpt: qsTr("Horizontal view")
@ -529,13 +496,12 @@ Item {
// Context Menu
property string saveFile: qsTr("Save file")
property string openLocation: qsTr("Open location")
property string me: qsTr("Me")
property string removeLocally: qsTr("Delete file from device")
// Updates
property string betaInstall: qsTr("Install beta version")
property string checkForUpdates: qsTr("Check for updates now")
property string enableAutoUpdates: qsTr("Enable/Disable automatic updates")
property string tipAutoUpdate: qsTr("Toggle automatic updates")
property string updatesTitle: qsTr("Updates")
property string updateDialogTitle: qsTr("Update")
property string updateFound: qsTr("A new version of Jami was found\nWould you like to update now?")
@ -547,6 +513,8 @@ Item {
property string updateDownloading: "Downloading"
property string confirmBeta: qsTr("This will uninstall your current Release version and you can always download the latest Release version on our website")
property string networkDisconnected: qsTr("Network disconnected")
property string accessError: qsTr("Content access error")
property string contentNotFoundError: qsTr("Content not found")
property string genericError: qsTr("Something went wrong")
//Troubleshoot Settings
@ -558,7 +526,6 @@ Item {
property string experimentalCallSwarmTooltip: qsTr("This feature will enable call buttons in swarms with multiple participants.")
// Recording Settings
property string tipRecordFolder: qsTr("Select a record directory")
property string quality: qsTr("Quality")
property string saveRecordingsTo: qsTr("Save recordings to")
property string saveScreenshotsTo: qsTr("Save screenshots to")
@ -572,27 +539,9 @@ Item {
property string callKeyboardShortcuts: qsTr("Call")
property string settings: qsTr("Settings")
property string markdownKeyboardShortcuts: qsTr("Markdown")
property string openAccountList: qsTr("Open account list")
property string focusConversationsList: qsTr("Focus conversations list")
property string requestsList: qsTr("Requests list")
property string previousConversation: qsTr("Previous conversation")
property string nextConversation: qsTr("Next conversation")
property string searchBar: qsTr("Search bar")
property string fullScreen: qsTr("Full screen")
property string clearHistory: qsTr("Clear history")
property string mediaSettings: qsTr("Media settings")
property string generalSettings: qsTr("General settings")
property string pluginSettings: qsTr("Plugin settings")
property string answerIncoming: qsTr("Answer an incoming call")
property string declineCallRequest: qsTr("Decline the call request")
property string openAccountCreationWizard: qsTr("Open account creation wizard")
property string openKeyboardShortcutTable: qsTr("Open keyboard shortcut table")
// View Logs
property string logsViewTitle: qsTr("Debug")
property string logsViewShowStats: qsTr("Show Stats")
property string logsViewStart: qsTr("Start")
property string logsViewStop: qsTr("Stop")
property string logsViewCopy: qsTr("Copy")
property string logsViewReport: qsTr("Report Bug")
property string logsViewClear: qsTr("Clear")
@ -604,19 +553,14 @@ Item {
property string archive: qsTr("Archive")
property string openFile: qsTr("Open file")
property string importAccountArchive: qsTr("Create account from backup")
property string importAccountExplanation: qsTr("You can obtain an archive by clicking on \"Back up account\" " + "in the Account Settings. " + "This will create a .gz file on your device.")
property string connectFromBackup: qsTr("Restore account from backup")
property string generatingAccount: qsTr("Generating account…")
property string importFromBackup: qsTr("Import from backup")
property string importFromArchiveBackup: qsTr("Import from archive backup")
property string importFromArchiveBackupDescription: qsTr("Import Jami account from local archive file.")
property string selectArchiveFile: qsTr("Select archive file")
property string passwordArchive: qsTr("If the account is encrypted with a password, please fill the following field.")
// ImportFromDevicePage
property string mainAccountPassword: qsTr("Enter Jami account password")
property string enterPIN: qsTr("Enter the PIN from another configured Jami account. " + "Use the \"Link Another Device\" feature to obtain a PIN.")
property string connectFromAnotherDevice: qsTr("Link device")
property string importButton: qsTr("Import")
property string pin: qsTr("Enter the PIN code")
property string importFromDeviceDescription: qsTr("A PIN is required to use an existing Jami account on this device.")
@ -633,62 +577,70 @@ Item {
// LinkDevicesDialog
property string pinTimerInfos: qsTr("The PIN and the account password should be entered in your device within 10 minutes.")
property string close: qsTr("Close")
property string enterAccountPassword: qsTr("Enter account's password")
property string enterAccountPassword: qsTr("Enter account password")
property string enterPasswordPinCode: qsTr("This account is password encrypted, enter the password to generate a PIN code.")
property string addDevice: qsTr("Add Device")
property string pinExpired: qsTr("PIN expired")
property string onAnotherDevice: qsTr("On another device")
property string onAnotherDeviceInstruction: qsTr("Install and launch Jami, select \"Import from another device\" and scan the QR code.")
property string linkNewDevice: qsTr("Link new device")
property string linkingInstructions: qsTr("In Jami, scan QR code or manually enter the PIN.")
property string pinValidity: qsTr("The PIN code is valid for: ")
// PasswordDialog
property string enterPassword: qsTr("Enter the password")
property string enterPassword: qsTr("Enter password")
property string enterCurrentPassword: qsTr("Enter current password")
property string confirmRemoval: qsTr("Enter this account's password to confirm the removal of this device")
property string confirmRemoval: qsTr("Enter account password to confirm the removal of this device")
property string enterNewPassword: qsTr("Enter new password")
property string confirmNewPassword: qsTr("Confirm new password")
property string change: qsTr("Change")
property string confirm: qsTr("Confirm")
property string exportAccount: qsTr("Export")
// PhotoBoothView
property string chooseAvatarImage: qsTr("Choose a picture as your avatar")
property string chooseAvatarPicture: qsTr("Choose a picture")
property string importFromFile: qsTr("Import avatar from image file")
property string stopTakingPhoto: qsTr("Stop taking photo")
property string clearAvatar: qsTr("Clear avatar image")
property string takePhoto: qsTr("Take photo")
property string imageFiles: qsTr("Image Files (*.png *.jpg *.jpeg *.JPG *.JPEG *.PNG)")
// Plugins
property string enable: qsTr("Enable")
property string autoUpdate: qsTr("Auto update")
property string disableAll: qsTr("Disable all")
property string installed: qsTr("Installed")
property string install: qsTr("Install")
property string installing: qsTr("Installing")
property string installManually: qsTr("Install manually")
property string installMannuallyDescription: qsTr("Install an extension directly from your device.")
property string pluginStoreTitle: qsTr("Available")
property string pluginStoreNotAvailable: qsTr("Plugins store is not available")
property string pluginPreferences: qsTr("Preferences")
property string installationFailed: qsTr("Installation failed")
property string pluginInstallationFailed: qsTr("The installation of the plugin failed")
property string reset: qsTr("Reset")
property string uninstall: qsTr("Uninstall")
property string resetPreferences: qsTr("Reset Preferences")
property string selectPluginInstall: qsTr("Select a plugin to install")
property string installPlugin: qsTr("Install plugin")
property string uninstallPlugin: qsTr("Uninstall plugin")
property string pluginResetConfirmation: qsTr("Are you sure you wish to reset %1 preferences?")
property string pluginUninstallConfirmation: qsTr("Are you sure you wish to uninstall %1?")
property string showHidePrefs: qsTr("Display or hide preferences")
property string addNewPlugin: qsTr("Add new plugin")
property string goBackToPluginsList: qsTr("Go back to plugins list")
property string selectFile: qsTr("Select a file")
property string select: qsTr("Select")
property string chooseImageFile: qsTr("Choose image file")
property string tipGeneralPluginSettingsDisplay: qsTr("Display or hide General plugin settings")
property string tipAccountPluginSettingsDisplay: qsTr("Display or hide Account plugin settings")
property string installedPlugins: qsTr("Installed plugins")
property string pluginFiles: qsTr("Plugin Files (*.jpl)")
property string loadUnload: qsTr("Load/Unload")
property string selectAnImage: qsTr("Select An Image to %1")
property string editPreference: qsTr("Edit preference")
property string onOff: qsTr("On/Off")
property string choosePlugin: qsTr("Choose Plugin")
property string versionPlugin: qsTr("Version %1")
property string lastUpdate: qsTr("Last update %1")
property string by: qsTr("By %1")
property string proposedBy: qsTr("Proposed by %1")
// ProfilePage
property string profileSharedWithContacts: qsTr("Profile is only shared with contacts")
property string saveProfile: qsTr("Save profile")
property string enterYourName: qsTr("Enter your name")
property string enterRVName: qsTr("Enter the rendezvous point's name")
property string generatingRV: qsTr("Creating rendezvous point…")
property string information: qsTr("Information")
property string moreInformation: qsTr("More information")
property string profile: qsTr("Profile")
// RevokeDevicePasswordDialog
@ -705,11 +657,7 @@ Item {
// UserProfile
property string qrCode: qsTr("QR code")
// Account QR
property string accountQr: qsTr("Account QR")
// WelcomePage
property string shareInvite: qsTr("This is your Jami username.\nCopy and share it with your friends!")
property string linkFromAnotherDevice: qsTr("Link this device to an existing account")
property string importAccountFromAnotherDevice: qsTr("Import from another device")
property string importAccountFromBackup: qsTr("Import from an archive backup")
@ -721,12 +669,10 @@ Item {
property string addSIPAccount: qsTr("Configure a SIP account")
property string errorCreateAccount: qsTr("Error while creating your account. Check your credentials.")
property string createNewRV: qsTr("Create a rendezvous point")
property string createAJamiAccount: qsTr("Create a Jami account")
property string joinJami: qsTr("Join Jami")
property string createNewJamiAccount: qsTr("Create new Jami account")
property string createNewSipAccount: qsTr("Create new SIP account")
property string aboutJami: qsTr("About Jami")
property string welcomeTo: qsTr("Welcome to")
property string introductionJami: qsTr("Share freely and privately with Jami")
property string alreadyHaveAccount: qsTr("I already have an account")
property string useExistingAccount: qsTr("Use existing Jami account")
@ -735,7 +681,6 @@ Item {
// SmartList
property string clearText: qsTr("Clear Text")
property string conversations: qsTr("Conversations")
property string conversation: qsTr("Conversation")
property string searchResults: qsTr("Search Results")
// SmartList context menu
@ -767,7 +712,6 @@ Item {
property string localMuted: qsTr("Local muted")
// Settings moderation
property string conferenceModeration: qsTr("Conference moderation")
property string defaultModerators: qsTr("Default moderators")
property string enableLocalModerators: qsTr("Enable local moderators")
property string enableAllModerators: qsTr("Make all participants moderators")
@ -779,11 +723,6 @@ Item {
property string reconnectDaemon: qsTr("Trying to reconnect to the Jami daemon (jamid)…")
property string reconnectionFailed: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
// Is Swarm
property string isSwarm: qsTr("Is swarm:")
property string trueStr: qsTr("True")
property string falseStr: qsTr("False")
// Message view
property string addEmoji: qsTr("Add emoji")
property string moreEmojis: qsTr("more emojis")
@ -793,10 +732,13 @@ Item {
property string showMore: qsTr("Show more")
property string showLess: qsTr("Show less")
property string showPreview: qsTr("Show preview")
property string continueEditing: qsTr("Continue editing")
property string bold: qsTr("Bold")
property string italic: qsTr("Italic")
property string strikethrough: qsTr("Strikethrough")
property string title: qsTr("Title")
property string heading: qsTr("Heading")
property string link: qsTr("Link")
property string code: qsTr("Code")
property string quote: qsTr("Quote")
@ -807,7 +749,6 @@ Item {
property string shiftEnterNewLine: qsTr("Press Shift+Enter to insert a new line")
property string enterNewLine: qsTr("Press Enter to insert a new line")
property string send: qsTr("Send")
property string remove: qsTr("Remove")
property string replyTo: qsTr("Reply to")
property string inReplyTo: qsTr("In reply to")
property string repliedTo: qsTr(" replied to")
@ -833,7 +774,6 @@ Item {
property string invitationViewWaitingForSync: qsTr("Waiting until %1\nconnects to synchronize the conversation.")
// SwarmDetailsPanel
property string about: qsTr("About")
property string members: qsTr("%1 Members")
property string member: qsTr("Member")
property string swarmName: qsTr("Swarm's name")
@ -845,14 +785,12 @@ Item {
property string chooseAColor: qsTr("Choose a color")
property string defaultCallHost: qsTr("Default host (calls)")
property string leaveConversation: qsTr("Leave conversation")
property string leave: qsTr("Leave")
property string typeOfSwarm: qsTr("Type of swarm")
property string none: qsTr("None")
// NewSwarmPage
property string createTheSwarm: qsTr("Create the swarm")
property string goToConversation: qsTr("Go to conversation")
property string promoteAdministrator: qsTr("Promote to administrator")
property string kickMember: qsTr("Kick member")
property string reinstateMember: qsTr("Reinstate member")
property string administrator: qsTr("Administrator")
@ -865,9 +803,7 @@ Item {
property string tip: qsTr("Tip")
property string dismiss: qsTr("Dismiss")
property string customizeText: qsTr("Add a profile picture and nickname to complete your profile")
property string customizationDescription: qsTr("This profile is only shared with this account's contacts")
property string customizationDescription2: qsTr("Your profile is only shared with your contacts")
property string whySaveAccount: qsTr("Why should I save my account?")
property string customizationDescription: qsTr("Your profile is only shared with your contacts")
// Message options
property string deleteMessage: qsTr("Delete message")
@ -875,7 +811,6 @@ Item {
property string editMessage: qsTr("Edit message")
// Jami identifier
property string identifierDescription: qsTr("Share this Jami identifier to be contacted on this account!")
property string hereIsIdentifier: qsTr("Share your Jami identifier in order to be contacted more easily!")
property string jamiIdentity: qsTr("Jami identity")
property string identifierURI: qsTr("Show fingerprint")
@ -902,4 +837,30 @@ Item {
// Appearence
property string theme: qsTr("Theme")
property string zoomLevel: qsTr("Text zoom level")
//Donation campaign
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/donate/\">Donate</a> to expand it.")
property string donation: qsTr("Donate")
property string donationText: qsTr("If you enjoy using Jami and believe in our mission, would you make a donation?")
property string notNow: qsTr("Not now")
property string enableDonation: qsTr("Enable donation campaign")
//Chat setting page
property string enter: qsTr("Enter")
property string shiftEnter: qsTr("Shift+Enter")
property string textFormattingDescription: qsTr("Enter or Shift+Enter to insert a new line")
property string textFormatting: qsTr("Text formatting")
//Connection monitoring
property string connected: qsTr("Connected")
property string connectingTLS: qsTr("Connecting TLS")
property string connectingICE: qsTr("Connecting ICE")
property string connecting: qsTr("Connecting")
property string waiting: qsTr("Waiting")
property string contact: qsTr("Contact")
property string connection: qsTr("Connection")
property string channels: qsTr("Channels")
property string copyAllData: qsTr("Copy all data")
property string remote: qsTr("Remote: ")
property string view: qsTr("View")
}

View File

@ -58,10 +58,12 @@ Item {
property color blackColor: "#000000"
property color redColor: "red"
property color whiteColor: "#ffffff"
property color darkBlueGreen: "#123F4A"
property color darkGreyColor: "#272727"
property color darkGreyColorOpacityFade: "#cc000000" // 80%
property color darkGreyColorOpacity: "#be272727" // 77%
property color tintedBlue: darkTheme ? lightTintedBlue : darkTintedBlue
property color lightTintedBlue:"#03B9E9"
property color lightTintedBlue: "#03B9E9"
property color darkTintedBlue: "#005699"
property color sysColor: "#F0EFEF"
@ -74,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"
@ -265,12 +267,13 @@ Item {
property real namePopupFontsize: calcSize(15)
property real avatarSize: 30
property int emojiPushButtonSize: 30
property int emojiMargins: 20
property int emojiMargins: 16
property color emojiReactBubbleBgColor: darkTheme ? darkGreyColor : whiteColor
property color emojiReactPushButtonColor: darkTheme ? "#bbb" : "#003b4e"
property real messageOptionTextFontSize: calcSize(15)
property int emojiPickerWidth: 400
property int emojiPickerHeight: 425
property int defaulMaxWidthReaction: 350
// Files To Send Container
property color removeFileButtonColor: Qt.rgba(96, 95, 97, 0.5)
@ -307,6 +310,7 @@ Item {
// Sizes
property real mainViewLeftPaneMinWidth: 300
property real currentLeftPaneWidth: mainViewLeftPaneMinWidth
property real mainViewPaneMinWidth: 490
property real qrCodeImageSize: 256
property real splitViewHandlePreferredWidth: 4
@ -363,9 +367,9 @@ Item {
property int avatarReadReceiptSize: 18
property int menuItemsPreferredWidth: 220
property int menuItemsPreferredHeight: 48
property int menuItemsPreferredHeight: 36
property int menuItemsCommonBorderWidth: 1
property int menuBorderPreferredHeight: 8
property int menuBorderPreferredHeight: 5
property real maximumWidthSettingsView: 516
property real settingsHeaderpreferredHeight: 64
@ -383,6 +387,15 @@ Item {
property real minimumMapWidth: 250
property real pluginHandlersPopupViewHeight: 200
property real pluginHandlersPopupViewDelegateHeight: 50
property color pluginDefaultBackgroundColor: "#666666"
property real remotePluginMinimumDelegateWidth: 430
property real remotePluginMinimumDelegateHeight: 275
property real remotePluginMaximumDelegateWidth: 645
property real remotePluginMaximumDelegateHeight: 413
property real iconMargin: 30 * baseZoom
property real remotePluginDelegateWidth: remotePluginMinimumDelegateWidth * baseZoom
property real remotePluginDelegateHeight: remotePluginMinimumDelegateHeight * baseZoom
property color pluginViewBackgroundColor: darkTheme ? "#000000" : "#F0EFEF"
property real secondaryDialogDimension: 500
property real lineEditContextMenuItemsHeight: 15
@ -479,6 +492,7 @@ Item {
// MessageBar
property int messageBarMarginSize: 10
property int messageBarMinimumWidth: 438
// InvitationView
property real invitationViewAvatarSize: 112
@ -519,6 +533,7 @@ Item {
// WizardView Welcome Page
property real welcomeLabelPointSize: 30
property var welcomeLogo: darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
property real welcomeLogoWidth: 100
property real welcomeLogoHeight: 100
property real wizardButtonWidth: 400
@ -528,9 +543,9 @@ Item {
property real welcomeRectTopMargin: 90
property real welcomePageSpacing: 13
property real welcomeGridWidth: 3 * JamiTheme.tipBoxWidth + 2 * JamiTheme.welcomePageSpacing
property real welcomeHalfGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 2
property real welcomeThirdGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 3
property real welcomeShortGridWidth: 2 * JamiTheme.tipBoxWidth + JamiTheme.welcomePageSpacing
readonly property string welcomeBg: darkTheme ? JamiResources.bg_darkmode_id_jami_png : JamiResources.bg_lightmode_id_jami_png
readonly property string welcomeBg: darkTheme ? JamiResources.background_don_dark_jpg : JamiResources.background_don_white_jpg
property color welcomeBlockColor: darkTheme ? "#4D000000" : "#4DFFFFFF"
// WizardView Advanced Account Settings
@ -630,6 +645,9 @@ Item {
property int settingsMenuHeaderButtonHeight: 50
property int settingsListViewsSpacing: 10
// Link Device
property color pinBackgroundColor: "#D6E4EF"
// MaterialRadioButton
property int radioImageSize: 30
property color radioBackgroundColor: darkTheme ? "#303030" : "#F0EFEF"
@ -641,7 +659,22 @@ Item {
property color darkThemeCheckedColor: "#03B9E9"
property color darkThemeBorderColor: "#03B9E9"
// Donation campaign
property color donationButtonTextColor: "#005699"
property color donationBackgroundColor: "#D5E4EF"
property string donationUrl: "https://jami.net/donate/"
//Connection monitoring
property color connectionMonitoringTableColor1: "#f0efef"
property color connectionMonitoringTableColor2: "#f6f5f5"
property color connectionMonitoringHeaderColor: "#d1d1d1"
function setTheme(dark) {
darkTheme = dark;
}
//Chat setting page
property color chatSettingButtonBackgroundColor: darkTheme ? "#303030" : "#F0EFEF"
property color chatSettingButtonBorderColor: darkTheme ? "#03B9E9" : "#005699"
property color chatSettingButtonTextColor: textColor
}

View File

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

View File

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

View File

@ -93,6 +93,7 @@ bool
ConversationListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
auto rx = filterRegularExpression();
auto uriStripper = URI(rx.pattern());
bool stripScheme = (uriStripper.schemeType() < URI::SchemeType::COUNT__);
@ -104,6 +105,11 @@ ConversationListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s
rx.setPattern(uriStripper.format(flags));
using namespace ConversationList;
if (index.data(Role::Uris).toStringList().isEmpty()) {
// TODO: Find out why, and fix in libjami/libjamiclient.
qCritical() << "Filtering 0 member conversation. Fix me";
return false;
}
QStringList toFilter;
toFilter += index.data(Role::Title).toString();

View File

@ -16,6 +16,7 @@
*/
#include "imagedownloader.h"
#include <QDir>
#include <QLockFile>
@ -26,7 +27,7 @@ ImageDownloader::ImageDownloader(ConnectivityMonitor* cm, QObject* parent)
void
ImageDownloader::downloadImage(const QUrl& url, const QString& localPath)
{
Utils::oneShotConnect(this, &NetworkManager::errorOccured, this, [this, localPath]() {
Utils::oneShotConnect(this, &NetworkManager::errorOccurred, this, [this, localPath]() {
onDownloadImageFinished({}, localPath);
});
@ -38,29 +39,29 @@ ImageDownloader::downloadImage(const QUrl& url, const QString& localPath)
void
ImageDownloader::onDownloadImageFinished(const QByteArray& data, const QString& localPath)
{
if (!data.isEmpty()) {
// Check if the parent folders exist create them if not
QString dirPath = localPath.left(localPath.lastIndexOf('/'));
QDir dir;
dir.mkpath(dirPath);
if (data.isEmpty()) {
Q_EMIT downloadImageFailed(localPath);
return;
}
QLockFile lf(localPath + ".lock");
QFile file(localPath);
if (!lf.lock()) {
qWarning().noquote() << "Can't lock file for writing: " << file.fileName();
return;
}
if (!file.open(QIODevice::WriteOnly)) {
qWarning().noquote() << "Can't open file for writing: " << file.fileName();
return;
}
// Make sure the parent folders exists.
const QString dirPath = localPath.left(localPath.lastIndexOf('/'));
const QDir dir;
if (!dir.mkpath(dirPath)) {
qWarning() << Q_FUNC_INFO << "Failed to create directory" << dirPath;
Q_EMIT downloadImageFailed(localPath);
return;
}
QLockFile lf(localPath + ".lock");
QFile file(localPath);
if (lf.lock() && file.open(QIODevice::WriteOnly)) {
file.write(data);
file.close();
qWarning() << Q_FUNC_INFO;
Q_EMIT downloadImageSuccessful(localPath);
return;
}
qWarning() << Q_FUNC_INFO << "Failed to write image to" << localPath;
Q_EMIT downloadImageFailed(localPath);
}

View File

@ -19,6 +19,7 @@
*/
#include "lrcinstance.h"
#include "connectivitymonitor.h"
#include <QBuffer>
#include <QMutex>
@ -34,7 +35,8 @@ LRCInstance::LRCInstance(migrateCallback willMigrateCb,
bool debugMode,
bool muteDaemon)
: lrc_(std::make_unique<Lrc>(willMigrateCb, didMigrateCb, !debugMode || muteDaemon))
, updateManager_(std::make_unique<UpdateManager>(updateUrl, connectivityMonitor, this))
, updateManager_(std::make_unique<AppVersionManager>(updateUrl, connectivityMonitor, this))
, connectivityMonitor_(*connectivityMonitor)
, threadPool_(new QThreadPool(this))
{
debugMode_ = debugMode;
@ -75,8 +77,8 @@ LRCInstance::LRCInstance(migrateCallback willMigrateCb,
}
};
UpdateManager*
LRCInstance::getUpdateManager()
AppVersionManager*
LRCInstance::getAppVersionManager()
{
return updateManager_.get();
}
@ -111,6 +113,12 @@ LRCInstance::pluginModel()
return lrc_->getPluginModel();
}
ConnectivityMonitor&
LRCInstance::connectivityMonitor()
{
return connectivityMonitor_;
}
bool
LRCInstance::isConnected()
{
@ -450,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

@ -24,7 +24,7 @@
#undef ERROR
#endif
#include "updatemanager.h"
#include "appversionmanager.h"
#include "qtutils.h"
#include "utils.h"
@ -71,7 +71,7 @@ public:
void finish();
UpdateManager* getUpdateManager();
AppVersionManager* getAppVersionManager();
AccountModel& accountModel();
ConversationModel* getCurrentConversationModel();
@ -79,6 +79,7 @@ public:
ContactModel* getCurrentContactModel();
AVModel& avModel();
PluginModel& pluginModel();
ConnectivityMonitor& connectivityMonitor();
BehaviorController& behaviorController();
void subscribeToDebugReceived();
@ -134,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();
@ -145,7 +150,9 @@ Q_SIGNALS:
private:
std::unique_ptr<Lrc> lrc_;
std::unique_ptr<UpdateManager> updateManager_;
std::unique_ptr<AppVersionManager> updateManager_;
ConnectivityMonitor& connectivityMonitor_;
QString selectedConvUid_;
MapStringString contentDrafts_;

View File

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

View File

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

View File

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

View File

@ -29,9 +29,11 @@ Item {
property alias source: image.source
property string defaultImage: ""
property string downloadUrl: ""
property alias imageLayer: image.layer
property string fileExtension: downloadUrl.substring(downloadUrl.lastIndexOf("."), downloadUrl.length)
property string localPath: ""
property int imageFillMode: 0
property alias image: image
AnimatedImage {
id: image
@ -40,43 +42,24 @@ Item {
fillMode: imageFillMode
smooth: true
antialiasing: true
property bool isGif: getIsGif(this)
Image {
id: default_img
objectName: "default_img"
anchors.fill: parent
source: defaultImage
visible: image.status != Image.Ready
smooth: true
antialiasing: true
property bool isGif: getIsGif(this)
property bool isGif: {
// True only for local gifs.
UtilsAdapter.getMimeNameForUrl(source).startsWith("image/gif");
}
}
function getIsGif(img) {
if (img.source && img.source != "") {
var localPath = img.source.toString();
if (localPath.startsWith("file://")) {
localPath = localPath.substring(7);
source: defaultImage
onStatusChanged: {
if (status === Image.Error) {
source = defaultImage;
}
return UtilsAdapter.getMimeName(localPath).startsWith("image/gif");
}
return false;
}
Connections {
target: ImageDownloader
function onDownloadImageSuccessful(localPath) {
if (localPath === cachedImage.localPath) {
image.source = "file://" + localPath;
print("onDownloadImageSuccessful", localPath);
}
}
function onDownloadImageFailed(localPath) {
if (localPath === cachedImage.localPath) {
print("Failed to download image: " + downloadUrl);
image.source = defaultImage;
image.source = UtilsAdapter.urlFromLocalPath(localPath);
}
}
}
@ -99,10 +82,9 @@ Item {
}
if (downloadUrl && downloadUrl !== "" && localPath !== "") {
if (!UtilsAdapter.fileExists(localPath)) {
print("ImageDownloader.downloadImage", downloadUrl, localPath);
ImageDownloader.downloadImage(downloadUrl, localPath);
} else {
image.source = "file://" + localPath;
image.source = UtilsAdapter.urlFromLocalPath(localPath);
if (image.isGif) {
image.playing = true;
}

View File

@ -420,7 +420,7 @@ Control {
icon.source: JamiResources.plugins_24dp_svg
icon.color: "white"
text: JamiStrings.viewPlugin
enabled: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
enabled: PluginAdapter.callMediaHandlersListCount
onEnabledChanged: CallOverlayModel.setEnabled(this, pluginsAction.enabled)
},
Action {

View File

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

View File

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

View File

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

View File

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

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;
}
@ -221,7 +220,7 @@ Rectangle {
JamiPushButton {
id: selectPluginButton
visible: PluginAdapter.isEnabled && PluginAdapter.chatHandlersListCount && interactionButtonsVisibility
visible: PluginAdapter.chatHandlersListCount && interactionButtonsVisibility
source: JamiResources.plugins_24dp_svg
toolTipText: JamiStrings.showPlugins

View File

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

View File

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

View File

@ -128,7 +128,7 @@ ColumnLayout {
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: opened
wrapMode: Text.WordWrap
text: JamiStrings.customizationDescription2
text: JamiStrings.customizationDescription
color: column.textColor
}
}

View File

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

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import net.jami.Enums 1.1
import net.jami.Models 1.1
import "../../commoncomponents"
import "../../settingsview/components"
Rectangle {
id: donation
property bool donationVisible: JamiQmlUtils.isDonationBannerVisible()
width: parent.width - 30
height: donationTextRect.height + 45 > donationIcon.height + 20 ? donationTextRect.height + 45 : donationIcon.height + 20
radius: 5
color: JamiTheme.donationBackgroundColor
GridLayout {
id: donationLayout
anchors.fill: parent
columns: 3
rows: 2
rowSpacing: 0
columnSpacing: 10
Rectangle {
id: donationIcon
Layout.row: 0
Layout.column: 0
Layout.rowSpan: 2
Layout.preferredHeight: 70
Layout.preferredWidth: 45
Layout.leftMargin: 10
Layout.topMargin: 10
Layout.bottomMargin: 15
color: JamiTheme.transparentColor
Image {
id: donationImage
height: parent.height
width: 50
anchors.centerIn: parent
source: JamiResources.icon_donate_svg
}
}
Rectangle {
id: donationTextRect
Layout.topMargin: 10
Layout.row: 0
Layout.column: 1
Layout.columnSpan: 2
Layout.preferredHeight: donationText.height
Layout.preferredWidth: parent.width - 74
Layout.bottomMargin: 5
color: JamiTheme.transparentColor
Text {
id: donationText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: parent.width
height: contentHeight
text: JamiStrings.donationText
wrapMode: Text.WordWrap
font.pointSize: JamiTheme.textFontSize
}
}
Rectangle {
id: notNowRect
Layout.row: 1
Layout.column: 1
Layout.preferredHeight: 30
Layout.preferredWidth: (parent.width - 55) / 2
color: JamiTheme.transparentColor
Text {
id: notNowText
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
// When the user clicks on "Not now", we set the donation date to 7 days from now (1 for the test)
UtilsAdapter.setAppValue(Settings.Key.DonationVisibleDate, new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
donation.donationVisible = Qt.binding(() => JamiQmlUtils.isDonationBannerVisible());
}
}
text: JamiStrings.notNow
color: JamiTheme.donationButtonTextColor
anchors.top: parent.top
anchors.left: parent.left
font.pointSize: JamiTheme.textFontSize
}
}
Rectangle {
id: donateRect
Layout.row: 1
Layout.column: 2
Layout.preferredHeight: 30
Layout.preferredWidth: (parent.width - 50) / 2
color: JamiTheme.transparentColor
Text {
id: donateText
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
Qt.openUrlExternally(JamiTheme.donationUrl);
}
}
text: JamiStrings.donation
font.pointSize: JamiTheme.textFontSize
color: JamiTheme.donationButtonTextColor
anchors.top: parent.top
anchors.left: parent.left
}
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
Item {
id: root
focus: true
width: parent.width
height: backupLayout.height
property real iconSize: 26
property real margin: 5
property real preferredWidth: 170
property real maxHeight: 250
property color textColor: JamiTheme.textColor
property color iconColor: JamiTheme.tintedBlue
ColumnLayout {
id: backupLayout
anchors.top: parent.top
width: parent.width
RowLayout {
id: rowlayout
Layout.leftMargin: 15
Layout.alignment: Qt.AlignLeft
ResponsiveImage {
id: icon
visible: !opened
Layout.alignment: Qt.AlignLeft
Layout.topMargin: root.margin
Layout.preferredWidth: root.iconSize
Layout.preferredHeight: root.iconSize
containerHeight: Layout.preferredHeight
containerWidth: Layout.preferredWidth
color: JamiTheme.tintedBlue
source: JamiResources.favorite_black_24dp_svg
}
Text {
id: title
text: JamiStrings.donation
color: root.textColor
font.weight: Font.Medium
Layout.topMargin: root.margin
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: root.margin
Layout.preferredWidth: root.preferredWidth - 2 * root.margin - root.iconSize
font.pixelSize: JamiTheme.tipBoxTitleFontSize
horizontalAlignment: Text.AlignLeft
elide: Qt.ElideRight
}
}
Text {
id: content
Layout.preferredWidth: root.preferredWidth
focus: true
Layout.leftMargin: 20
Layout.topMargin: 8
Layout.bottomMargin: 8
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: true
wrapMode: Text.WordWrap
font.weight: Font.Normal
text: JamiStrings.donationTipBoxText
color: root.textColor
horizontalAlignment: Text.AlignLeft
linkColor: JamiTheme.buttonTintedBlue
onLinkActivated: {
Qt.openUrlExternally(JamiTheme.donationUrl);
}
}
}
}

View File

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

View File

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

View File

@ -25,6 +25,9 @@ RowLayout {
layoutDirection: UtilsAdapter.isRTL ? Qt.RightToLeft : Qt.LeftToRight
focus: true
// Needs to get focus so Orca can read the shortcut
Rectangle {
id: descriptionTextRect
@ -36,6 +39,8 @@ RowLayout {
color: JamiTheme.transparentColor
focus: true
Text {
id: descriptionText
@ -48,6 +53,7 @@ RowLayout {
}
}
// Needs to get focus as well so Orca can read the shortcut
Rectangle {
id: shortcutTextRect
@ -58,6 +64,7 @@ RowLayout {
Layout.rightMargin: 10
color: JamiTheme.backgroundColor
radius: JamiTheme.primaryRadius
Text {

View File

@ -32,342 +32,317 @@ Window {
height: 480
minimumHeight: 300
ListModel {
id: keyboardGeneralShortcutsModel
readonly property list<ListModel> keyboardShortcutsModelList: [
ListModel {
id: keyboardGeneralShortcutsModel
ListElement {
shortcut: "Ctrl + J"
shortcut2: ""
description: qsTr("Open account list")
}
ListElement {
shortcut: "Ctrl + L"
shortcut2: ""
description: qsTr("Focus conversations list")
}
ListElement {
shortcut: "Ctrl + R"
shortcut2: ""
description: qsTr("Requests list")
}
ListElement {
shortcut: "Ctrl + ↑"
shortcut2: ""
description: qsTr("Previous conversation")
}
ListElement {
shortcut: "Ctrl + "
shortcut2: ""
description: qsTr("Next conversation")
}
ListElement {
shortcut: "Ctrl + F"
shortcut2: ""
description: qsTr("Search bar")
}
ListElement {
shortcut: "F11"
shortcut2: ""
description: qsTr("Full screen")
}
ListElement {
shortcut: "Ctrl + +"
shortcut2: ""
description: qsTr("Increase font size")
}
ListElement {
shortcut: "Ctrl + -"
shortcut2: ""
description: qsTr("Decrease font size")
}
ListElement {
shortcut: "Ctrl + 0"
shortcut2: ""
description: qsTr("Reset font size")
}
}
ListElement {
shortcut: "Ctrl + J"
description: qsTr("Open account list")
}
ListElement {
shortcut: "Ctrl + L"
description: qsTr("Focus conversations list")
}
ListElement {
shortcut: "Ctrl + R"
description: qsTr("Requests list")
}
ListElement {
shortcut: "Ctrl + ↑"
description: qsTr("Previous conversation")
}
ListElement {
shortcut: "Ctrl + ↓"
description: qsTr("Next conversation")
}
ListElement {
shortcut: "Ctrl + F"
description: qsTr("Search bar")
}
ListElement {
shortcut: "F11"
description: qsTr("Full screen")
}
ListElement {
shortcut: "Ctrl + +"
description: qsTr("Increase font size")
}
ListElement {
shortcut: "Ctrl + -"
description: qsTr("Decrease font size")
}
ListElement {
shortcut: "Ctrl + 0"
description: qsTr("Reset font size")
}
},
ListModel {
id: keyboardConversationShortcutsModel
ListModel {
id: keyboardConversationShortcutsModel
ListElement {
shortcut: "Ctrl + Shift + C"
description: qsTr("Start an audio call")
}
ListElement {
shortcut: "Ctrl + Shift + X"
description: qsTr("Start a video call")
}
ListElement {
shortcut: "Ctrl + Shift + L"
description: qsTr("Clear history")
}
ListElement {
shortcut: "Ctrl + Shift + F"
description: qsTr("Search messages/files")
}
ListElement {
shortcut: "Ctrl + Shift + B"
description: qsTr("Block contact")
}
ListElement {
shortcut: "Ctrl + Shift + Delete"
description: qsTr("Remove conversation")
}
ListElement {
shortcut: "Ctrl + Shift + A"
description: qsTr("Accept contact request")
}
ListElement {
shortcut: "↑"
description: qsTr("Edit last message")
}
ListElement {
shortcut: "Esc"
description: qsTr("Cancel message edition")
}
},
ListModel {
id: keyboardSettingsShortcutsModel
ListElement {
shortcut: "Ctrl + Shift + C"
shortcut2: ""
description: qsTr("Start an audio call")
}
ListElement {
shortcut: "Ctrl + Shift + X"
shortcut2: ""
description: qsTr("Start a video call")
}
ListElement {
shortcut: "Ctrl + Shift + L"
shortcut2: ""
description: qsTr("Clear history")
}
ListElement {
shortcut: "Ctrl + Shift + F"
shortcut2: ""
description: qsTr("Search messages/files")
}
ListElement {
shortcut: "Ctrl + Shift + B"
shortcut2: ""
description: qsTr("Block contact")
}
ListElement {
shortcut: "Ctrl + Shift + Delete"
shortcut2: ""
description: qsTr("Remove conversation")
}
ListElement {
shortcut: "Ctrl + Shift + A"
shortcut2: ""
description: qsTr("Accept contact request")
}
ListElement {
shortcut: "↑"
shortcut2: ""
description: qsTr("Edit last message")
}
ListElement {
shortcut: "Esc"
shortcut2: ""
description: qsTr("Cancel message edition")
}
}
ListElement {
shortcut: "Ctrl + M"
description: qsTr("Media settings")
}
ListElement {
shortcut: "Ctrl + G"
description: qsTr("General settings")
}
ListElement {
shortcut: "Ctrl + Alt + I"
description: qsTr("Account settings")
}
ListElement {
shortcut: "Ctrl + P"
description: qsTr("Plugin settings")
}
ListElement {
shortcut: "Ctrl + Shift + N"
description: qsTr("Open account creation wizard")
}
ListElement {
shortcut: "F10"
shortcut2: ""
description: qsTr("Open keyboard shortcut table")
}
},
ListModel {
id: keyboardCallsShortcutsModel
ListModel {
id: keyboardSettingsShortcutsModel
ListElement {
shortcut: "Ctrl + Y"
description: qsTr("Answer an incoming call")
}
ListElement {
shortcut: "Ctrl + D"
description: qsTr("End call")
}
ListElement {
shortcut: "Ctrl + Shift + D"
description: qsTr("Decline the call request")
}
ListElement {
shortcut: "M"
description: qsTr("Mute microphone")
}
ListElement {
shortcut: "V"
description: qsTr("Stop camera")
}
ListElement {
shortcut: "Ctrl + Mouse middle click"
description: qsTr("Take tile screenshot")
}
},
ListModel {
id: keyboardMarkdownShortcutsModel
ListElement {
shortcut: "Ctrl + M"
shortcut2: ""
description: qsTr("Media settings")
ListElement {
shortcut: "Ctrl + B"
description: qsTr("Bold")
}
ListElement {
shortcut: "Ctrl + I"
description: qsTr("Italic")
}
ListElement {
shortcut: "Shift + Alt + X"
description: qsTr("Strikethrough")
}
ListElement {
shortcut: "Ctrl + Alt + H"
description: qsTr("Heading")
}
ListElement {
shortcut: "Ctrl + Alt + K"
description: qsTr("Link")
}
ListElement {
shortcut: "Ctrl + Alt + C"
description: qsTr("Code")
}
ListElement {
shortcut: "Shift + Alt + 9"
description: qsTr("Quote")
}
ListElement {
shortcut: "Shift + Alt + 8"
description: qsTr("Unordered list")
}
ListElement {
shortcut: "Shift + Alt + 7"
description: qsTr("Ordered list")
}
ListElement {
shortcut: "Shift + Alt + T"
description: qsTr("Show formatting")
}
ListElement {
shortcut: "Shift + Alt + P"
description: qsTr("Show preview")
}
}
ListElement {
shortcut: "Ctrl + G"
shortcut2: ""
description: qsTr("General settings")
}
ListElement {
shortcut: "Ctrl + Alt + I"
shortcut2: ""
description: qsTr("Account settings")
}
ListElement {
shortcut: "Ctrl + P"
shortcut2: ""
description: qsTr("Plugin settings")
}
ListElement {
shortcut: "Ctrl + Shift + N"
shortcut2: ""
description: qsTr("Open account creation wizard")
}
ListElement {
shortcut: "F10"
shortcut2: ""
description: qsTr("Open keyboard shortcut table")
}
}
]
ListModel {
id: keyboardCallsShortcutsModel
ListElement {
shortcut: "Ctrl + Y"
shortcut2: ""
description: qsTr("Answer an incoming call")
}
ListElement {
shortcut: "Ctrl + D"
shortcut2: ""
description: qsTr("End call")
}
ListElement {
shortcut: "Ctrl + Shift + D"
shortcut2: ""
description: qsTr("Decline the call request")
}
ListElement {
shortcut: "M"
shortcut2: ""
description: qsTr("Mute microphone")
}
ListElement {
shortcut: "V"
shortcut2: ""
description: qsTr("Stop camera")
}
ListElement {
shortcut: "Ctrl"
shortcut2: qsTr("Mouse middle click")
description: qsTr("Take tile screenshot")
}
}
ListModel {
id: keyboardMarkdownShortcutsModel
ListElement {
shortcut: "Ctrl + B"
shortcut2: ""
description: qsTr("Bold")
}
ListElement {
shortcut: "Ctrl + I"
shortcut2: ""
description: qsTr("Italic")
}
ListElement {
shortcut: "Shift + Alt + X"
shortcut2: ""
description: qsTr("Strikethrough")
}
ListElement {
shortcut: "Ctrl + Alt + H"
shortcut2: ""
description: qsTr("Heading")
}
ListElement {
shortcut: "Ctrl + Alt + K"
shortcut2: ""
description: qsTr("Link")
}
ListElement {
shortcut: "Ctrl + Alt + C"
shortcut2: ""
description: qsTr("Code")
}
ListElement {
shortcut: "Shift + Alt + 9"
shortcut2: ""
description: qsTr("Quote")
}
ListElement {
shortcut: "Shift + Alt + 8"
shortcut2: ""
description: qsTr("Unordered list")
}
ListElement {
shortcut: "Shift + Alt + 7"
shortcut2: ""
description: qsTr("Ordered list")
}
ListElement {
shortcut: "Shift + Alt + T"
shortcut2: ""
description: qsTr("Show Formatting")
}
ListElement {
shortcut: "Shift + Alt + P"
shortcut2: ""
description: qsTr("Show Preview")
}
}
Rectangle {
id: windowRect
Page {
id: page
anchors.fill: parent
color: JamiTheme.secondaryBackgroundColor
// make a list view of keyboardShortcutsModelList[selectionBar.currentIndex]
JamiListView {
id: keyboardShortcutsListView
Rectangle {
id: titleRect
anchors.fill: parent
anchors.leftMargin: 48
anchors.rightMargin: 48
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: JamiTheme.titleRectMargin
Keys.onUpPressed: keyboardShortcutsListView.decrementCurrentIndex()
Keys.onDownPressed: keyboardShortcutsListView.incrementCurrentIndex()
height: titleName.contentHeight + JamiTheme.titleRectMargin
width: titleName.contentWidth + JamiTheme.titleRectMargin
// on key tab forceActiveFocus
Keys.onTabPressed: if (activeFocus)
selectionBar.forceActiveFocus()
color: JamiTheme.backgroundColor
radius: JamiTheme.primaryRadius
model: keyboardShortcutsModelList[selectionBar.currentIndex]
spacing: 24
delegate: FocusScope {
id: fs
height: childrenRect.height
focus: true
Text {
id: titleName
// Accessible.role: Accessible.Button
Accessible.name: descriptionLabel.text
Accessible.description: shortcutLabel.text
anchors.centerIn: parent
font.pointSize: JamiTheme.titleFontSize
text: {
var modelId = UtilsAdapter.isRTL ? 4 - selectionBar.currentIndex : selectionBar.currentIndex
switch (modelId) {
case 0:
return JamiStrings.generalSettingsTitle;
case 1:
return JamiStrings.conversationKeyboardShortcuts;
case 2:
return JamiStrings.callKeyboardShortcuts;
case 3:
return JamiStrings.settings;
case 4:
return JamiStrings.markdownKeyboardShortcuts;
RowLayout {
width: keyboardShortcutsListView.width
Label {
id: descriptionLabel
Layout.alignment: Qt.AlignLeft
Layout.topMargin: 8
Layout.leftMargin: 20
text: description
background: Rectangle {
width: parent.width + 16
height: parent.height + 16
border.color: fs.activeFocus ? "darkblue" : "transparent"
border.width: 2
radius: 5
anchors.centerIn: parent
}
}
Label {
id: shortcutLabel
Layout.alignment: Qt.AlignRight
Layout.topMargin: 8
Layout.rightMargin: 20
text: shortcut
background: Rectangle {
width: parent.width + 16
height: parent.height + 16
border.color: fs.activeFocus ? "darkblue" : "transparent"
border.width: 2
radius: 5
anchors.centerIn: parent
}
}
}
color: JamiTheme.textColor
}
}
JamiListView {
id: keyboardShortCutList
anchors.top: titleRect.bottom
anchors.topMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: parent.height - titleRect.height - JamiTheme.titleRectMargin - keyboardShortCutList.anchors.topMargin - selectionBar.height - selectionBar.anchors.bottomMargin
model: {
var modelId = UtilsAdapter.isRTL ? 4 - selectionBar.currentIndex : selectionBar.currentIndex
switch (modelId) {
case 0:
return keyboardGeneralShortcutsModel;
case 1:
return keyboardConversationShortcutsModel;
case 2:
return keyboardCallsShortcutsModel;
case 3:
return keyboardSettingsShortcutsModel;
case 4:
return keyboardMarkdownShortcutsModel;
}
}
delegate: KeyboardShortcutKeyDelegate {
width: keyboardShortCutList.width
height: Math.max(JamiTheme.keyboardShortcutDelegateSize, implicitHeight)
}
}
TabBar {
header: TabBar {
id: selectionBar
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
readonly property real lambda: 12
width: 96
height: JamiTheme.keyboardShortcutTabBarSize
contentHeight: JamiTheme.keyboardShortcutTabBarSize
background: Rectangle {
color: windowRect.color
}
spacing: lambda
padding: lambda
focus: true
Repeater {
model: UtilsAdapter.isRTL ? ["5", "4", "3", "2", "1"] : ["1", "2", "3", "4", "5"]
model: [JamiStrings.generalSettingsTitle, JamiStrings.conversationKeyboardShortcuts, JamiStrings.callKeyboardShortcuts, JamiStrings.settings, JamiStrings.markdownKeyboardShortcuts]
KeyboardShortcutTabButton {
currentIndex: selectionBar.currentIndex
text: modelData
TabButton {
id: tabButton
Accessible.name: modelData + "shortcuts category"
Keys.onTabPressed: if (activeFocus)
keyboardShortcutsListView.forceActiveFocus()
contentItem: Text {
text: modelData
color: JamiTheme.textColor
font.pixelSize: JamiTheme.titleFontSize
horizontalAlignment: Text.AlignHCenter
}
background: Rectangle {
border.color: tabButton.activeFocus ? "darkblue" : "transparent"
border.width: 2
color: {
if (tabButton.checked || tabButton.pressed)
return JamiTheme.pressedButtonColor;
if (tabButton.hovered)
return JamiTheme.hoveredButtonColor;
else
return JamiTheme.normalButtonColor;
}
radius: JamiTheme.primaryRadius
}
}
}
}
Component.onCompleted: {
setCurrentIndex(UtilsAdapter.isRTL ? 4 : 0);
footer: Item {
height: JamiTheme.keyboardShortcutTabBarSize
PageIndicator {
anchors.centerIn: parent
count: selectionBar.count
currentIndex: selectionBar.currentIndex
}
}
}

View File

@ -25,16 +25,11 @@ import net.jami.Enums 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
Rectangle {
RowLayout {
id: root
Layout.fillWidth: true
Layout.leftMargin: marginSize
Layout.rightMargin: marginSize
Layout.bottomMargin: marginSize
property alias text: textArea.text
property var textAreaObj: textArea
property alias text: messageBarTextArea.text
property var textAreaObj: messageBarTextArea
property real marginSize: JamiTheme.messageBarMarginSize
property bool sendButtonVisibility: true
property bool animate: false
@ -43,7 +38,7 @@ Rectangle {
property bool chatViewEnterIsNewLine: UtilsAdapter.getAppValue(Settings.Key.ChatViewEnterIsNewLine)
property bool showTypoSecond: false
property bool showPreview: false
property bool multiLine: textArea.tooMuch
property bool multiLine: messageBarTextArea.tooMuch
property int messageBarLayoutMaximumWidth: 486
@ -56,61 +51,80 @@ Rectangle {
signal showMapClicked
signal emojiButtonClicked
color: JamiTheme.transparentColor
height: showTypo || multiLine ? textArea.height + 25 + 3 * marginSize + 1 : textArea.height + marginSize + 1
height: showTypo || multiLine ? messageBarTextArea.height + 25 + 3 * marginSize + 1 : textAreaObj.height + marginSize + 1
ComboBox {
id: showMoreButton
Rectangle {
Layout.preferredHeight: parent.height
Layout.preferredWidth: childrenRect.width
visible: !CurrentConversation.isSip
width: CurrentConversation.isSip ? 0 : JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
color: JamiTheme.transparentColor
ComboBox {
id: showMoreButton
focus: true
width: JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
anchors.bottom: parent.bottom
anchors.bottomMargin: marginSize / 2
anchors.leftMargin: marginSize
anchors.bottom: parent.bottom
anchors.bottomMargin: marginSize / 2
background: Rectangle {
implicitWidth: showMoreButton.width
implicitHeight: showMoreButton.height
radius: 5
color: JamiTheme.transparentColor
}
MaterialToolTip {
id: toolTipMoreButton
parent: showMoreButton
visible: showMoreButton.hovered && (text.length > 0)
delay: Qt.styleHints.mousePressAndHoldInterval
text: JamiStrings.showMore
}
indicator: ResponsiveImage {
width: 25
height: 25
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
source: JamiResources.more_menu_black_24dp_svg
color: JamiTheme.chatViewFooterImgColor
}
onHoveredChanged: {
if (!sharePopup.opened) {
showMoreButton.indicator.color = hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor;
showMoreButton.background.color = hovered ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor;
background: Rectangle {
implicitWidth: showMoreButton.width
implicitHeight: showMoreButton.height
radius: 5
color: JamiTheme.transparentColor
}
}
popup: SharePopup {
id: sharePopup
y: -180
x: -20
MaterialToolTip {
id: toolTipMoreButton
menuMoreButton: listViewMoreButton.menuMoreButton
parent: showMoreButton
visible: showMoreButton.hovered && (text.length > 0)
delay: Qt.styleHints.mousePressAndHoldInterval
text: JamiStrings.showMore
}
indicator: ResponsiveImage {
width: 25
height: 25
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
source: JamiResources.more_menu_black_24dp_svg
color: JamiTheme.chatViewFooterImgColor
}
onHoveredChanged: {
console.log("Hovered changed");
if (!sharePopup.opened) {
showMoreButton.indicator.color = hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor;
showMoreButton.background.color = hovered ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor;
}
toolTipMoreButton.text = sharePopup.opened ? JamiStrings.showLess : JamiStrings.showMore;
}
onPressedChanged: {
console.log("Pressed changed");
if (sharePopup.enabled)
sharePopup.close();
}
popup: ShareMenu {
id: sharePopup
onAudioRecordMessageButtonClicked: {
root.audioRecordMessageButtonClicked();
}
onVideoRecordMessageButtonClicked: {
root.videoRecordMessageButtonClicked();
}
onShowMapClicked: {
root.showMapClicked();
}
modelList: listViewMoreButton.menuMoreButton
y: -140
}
}
}
@ -125,11 +139,8 @@ Rectangle {
Rectangle {
id: rectangle
anchors.top: parent.top
anchors.left: showMoreButton.right
anchors.right: sendButtonRow.left
anchors.rightMargin: marginSize
anchors.leftMargin: marginSize
Layout.fillWidth: true
Layout.fillHeight: true
radius: 5
color: JamiTheme.transparentColor
@ -138,12 +149,10 @@ Rectangle {
onWidthChanged: {
height = Qt.binding(() => root.height);
if (width < 468) {
if (width < JamiTheme.messageBarMinimumWidth) {
showTypoSecond = false;
} else {
if (width >= 468) {
showTypoSecond = true;
}
showTypoSecond = true;
}
}
@ -158,7 +167,7 @@ Rectangle {
anchors.fill: parent
MessageBarTextArea {
id: textArea
id: messageBarTextArea
objectName: "messageBarTextArea"
maxWidth: rectangle.width - messageBarRowLayout.width - 35
@ -179,17 +188,19 @@ Rectangle {
Layout.topMargin: marginSize / 2
Layout.bottomMargin: marginSize / 2
Layout.rightMargin: marginSize / 2
Layout.preferredHeight: {
JamiTheme.chatViewFooterPreferredHeight > contentHeight ? JamiTheme.chatViewFooterPreferredHeight : contentHeight;
}
Layout.minimumHeight: JamiTheme.chatViewFooterPreferredHeight
Layout.preferredHeight: contentHeight
Layout.maximumHeight: JamiTheme.chatViewFooterTextAreaMaximumHeight - marginSize / 2
onSendMessagesRequired: {
sendMessageButtonClicked();
textArea.heightBinding();
}
onTextChanged: MessagesAdapter.userIsComposing(text ? true : false)
onTextChanged: {
MessagesAdapter.userIsComposing(text ? true : false);
if (!text) {
messageBarTextArea.heightBinding();
}
}
property var markdownShortCut: {
"Bold": function () {
if (!showPreview) {
@ -213,32 +224,32 @@ Rectangle {
},
"Link": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(0).action.triggered();
listViewTypoFirst.itemAtIndex(4).action.triggered();
}
},
"Code": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(1).action.triggered();
listViewTypoFirst.itemAtIndex(5).action.triggered();
}
},
"Quote": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(2).action.triggered();
listViewTypoSecond.itemAtIndex(0).action.triggered();
}
},
"Unordered list": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(3).action.triggered();
listViewTypoSecond.itemAtIndex(1).action.triggered();
}
},
"Ordered list": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(4).action.triggered();
listViewTypoSecond.itemAtIndex(2).action.triggered();
}
},
"Enter is new line": function () {
if (!showPreview) {
listViewTypoSecond.itemAtIndex(5).action.triggered();
listViewTypoSecond.itemAtIndex(3).action.triggered();
}
}
}
@ -246,55 +257,55 @@ Rectangle {
Shortcut {
sequence: "Ctrl+B"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Bold"]()
onActivated: messageBarTextArea.markdownShortCut["Bold"]()
}
Shortcut {
sequence: "Ctrl+I"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Italic"]()
onActivated: messageBarTextArea.markdownShortCut["Italic"]()
}
Shortcut {
sequence: "Shift+Alt+X"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Barre"]()
onActivated: messageBarTextArea.markdownShortCut["Barre"]()
}
Shortcut {
sequence: "Ctrl+Alt+H"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Heading"]()
onActivated: messageBarTextArea.markdownShortCut["Heading"]()
}
Shortcut {
sequence: "Ctrl+Alt+K"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Link"]()
onActivated: messageBarTextArea.markdownShortCut["Link"]()
}
Shortcut {
sequence: "Ctrl+Alt+C"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Code"]()
onActivated: messageBarTextArea.markdownShortCut["Code"]()
}
Shortcut {
sequence: "Shift+Alt+9"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Quote"]()
onActivated: messageBarTextArea.markdownShortCut["Quote"]()
}
Shortcut {
sequence: "Shift+Alt+8"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Unordered list"]()
onActivated: messageBarTextArea.markdownShortCut["Unordered list"]()
}
Shortcut {
sequence: "Shift+Alt+7"
context: Qt.ApplicationShortcut
onActivated: textArea.markdownShortCut["Ordered list"]()
onActivated: messageBarTextArea.markdownShortCut["Ordered list"]()
}
Shortcut {
@ -302,6 +313,8 @@ Rectangle {
context: Qt.ApplicationShortcut
onActivated: {
showTypo = !showTypo;
messageBarTextArea.isShowTypo = showTypo;
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
}
}
@ -310,7 +323,7 @@ Rectangle {
context: Qt.ApplicationShortcut
onActivated: {
showPreview = !showPreview;
textArea.showPreview = showPreview;
messageBarTextArea.showPreview = showPreview;
}
}
}
@ -326,7 +339,6 @@ Rectangle {
Layout.rightMargin: 0
Row {
anchors.bottom: parent.bottom
anchors.bottomMargin: marginSize / 2
@ -370,11 +382,11 @@ Rectangle {
// If the selected text is already formatted with the given characters, remove them
selectedText = text.substring(start, end);
root.text = text.substring(0, start - char1.length) + selectedText + text.substring(end + char2.length);
textArea.selectText(start - char1.length, end - char1.length);
messageBarTextArea.selectText(start - char1.length, end - char1.length);
} else {
// Otherwise, add the formatting characters to the selected text
root.text = text.substring(0, start) + char1 + text.substring(start, end) + char2 + text.substring(end);
textArea.selectText(start + char1.length, end + char1.length);
messageBarTextArea.selectText(start + char1.length, end + char1.length);
}
}
@ -558,7 +570,7 @@ Rectangle {
newEnd = Math.max(startPos + multilineSelectionLength, 0);
}
root.text = newValue;
textArea.selectText(newStart, newEnd);
messageBarTextArea.selectText(newStart, newEnd);
}
ListView {
@ -566,8 +578,8 @@ Rectangle {
objectName: "listViewTypoFirst"
visible: width > 0
width: showTypo ? contentWidth + 2 * leftMargin : 0
visible: showTypo
width: contentWidth + 2 * leftMargin
Behavior on width {
NumberAnimation {
@ -588,9 +600,9 @@ Rectangle {
property var iconSrc: JamiResources.bold_black_24dp_svg
property var shortcutText: JamiStrings.bold
property string shortcutKey: "Ctrl+B"
property bool isStyle: listViewTypo.isStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/)
property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/)
onTriggered: function clickAction() {
listViewTypo.addStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/);
listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "**", "**", /\\*\*.+\\*\*/);
}
},
Action {
@ -598,9 +610,9 @@ Rectangle {
property var iconSrc: JamiResources.italic_black_24dp_svg
property var shortcutText: JamiStrings.italic
property string shortcutKey: "Ctrl+I"
property bool isStyle: listViewTypo.isStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/)
property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/)
onTriggered: function clickAction() {
listViewTypo.addStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/);
listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "*", "*", /(?:\*.+\*|\*\*\*.+\*\*\*)/);
}
},
Action {
@ -608,19 +620,19 @@ Rectangle {
property var iconSrc: JamiResources.s_barre_black_24dp_svg
property var shortcutText: JamiStrings.strikethrough
property string shortcutKey: "Shift+Alt+X"
property bool isStyle: listViewTypo.isStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/)
property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/)
onTriggered: function clickAction() {
listViewTypo.addStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/);
listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "~~", "~~", /\~\~.+\~\~/);
}
},
Action {
id: titleAction
property var iconSrc: JamiResources.title_black_24dp_svg
property var shortcutText: JamiStrings.title
property var shortcutText: JamiStrings.heading
property string shortcutKey: "Ctrl+Alt+H"
property bool isStyle: listViewTypo.isPrefixSyle(root.text, textArea.selectionStart, textArea.selectionEnd, "### ", false)
property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "### ", false)
onTriggered: function clickAction() {
listViewTypo.addPrefixStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "### ", false);
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "### ", false);
}
},
Action {
@ -628,9 +640,9 @@ Rectangle {
property var iconSrc: JamiResources.link_web_black_24dp_svg
property var shortcutText: JamiStrings.link
property string shortcutKey: "Ctrl+Alt+K"
property bool isStyle: listViewTypo.isStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/)
property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/)
onTriggered: function clickAction() {
listViewTypo.addStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/);
listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "[", "](url)", /\[.+\]\(.+\)/);
}
},
Action {
@ -638,9 +650,9 @@ Rectangle {
property var iconSrc: JamiResources.code_black_24dp_svg
property var shortcutText: JamiStrings.code
property string shortcutKey: "Ctrl+Alt+C"
property bool isStyle: listViewTypo.isStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/)
property bool isStyle: listViewTypo.isStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/)
onTriggered: function clickAction() {
listViewTypo.addStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/);
listViewTypo.addStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "```", "```", /\`\`\`.+\`\`\`/);
}
}
]
@ -648,8 +660,7 @@ Rectangle {
model: menuTypoActionsFirst
delegate: PushButton {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
preferredSize: JamiTheme.chatViewFooterRealButtonSize
imageContainerWidth: 15
imageContainerHeight: 15
@ -667,11 +678,11 @@ Rectangle {
normalColor: {
if (showPreview) {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
} else if (modelData.isStyle) {
return JamiTheme.hoveredButtonColor;
} else {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
}
}
imageColor: {
@ -693,11 +704,10 @@ Rectangle {
}
Rectangle {
height: JamiTheme.chatViewFooterButtonSize
color: JamiTheme.transparentColor
visible: width > 0
width: showTypo && showTypoSecond ? 2 : 0
color: JamiTheme.primaryBackgroundColor
visible: showTypo && showTypoSecond
width: 2
Rectangle {
anchors.verticalCenter: parent.verticalCenter
@ -710,7 +720,7 @@ Rectangle {
Rectangle {
z: -1
radius: 0
color: JamiTheme.transparentColor
color: JamiTheme.primaryBackgroundColor
width: JamiTheme.chatViewFooterButtonSize
height: JamiTheme.chatViewFooterButtonSize
@ -721,17 +731,17 @@ Rectangle {
width: JamiTheme.chatViewFooterRealButtonSize
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
enabled: !showPreview
hoverEnabled: !showPreview
MaterialToolTip {
id: toolTip
parent: showMoreTypoButton
visible: showMoreTypoButton.hovered && (text.length > 0)
delay: Qt.styleHints.mousePressAndHoldInterval
text: JamiStrings.showMore
text: markdownPopup.visible ? JamiStrings.showLess : JamiStrings.showMore
}
background: Rectangle {
@ -756,9 +766,10 @@ Rectangle {
}
popup: MarkdownPopup {
id: markdownPopup
y: 1.5 * parent.height
x: -parent.width * 2
width: 155
width: 105
height: JamiTheme.chatViewFooterButtonSize
menuTypoActionsSecond: listViewTypoSecond.menuTypoActionsSecond
@ -768,8 +779,8 @@ Rectangle {
ListView {
id: listViewTypoSecond
visible: width > 0
width: showTypo && showTypoSecond ? contentWidth + 2 * leftMargin : 0
visible: showTypo && showTypoSecond
width: contentWidth + 2 * leftMargin
height: JamiTheme.chatViewFooterButtonSize
orientation: ListView.Horizontal
@ -790,9 +801,9 @@ Rectangle {
property var iconSrc: JamiResources.quote_black_24dp_svg
property var shortcutText: JamiStrings.quote
property string shortcutKey: "Shift+Alt+9"
property bool isStyle: listViewTypo.isPrefixSyle(root.text, textArea.selectionStart, textArea.selectionEnd, "> ", false)
property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "> ", false)
onTriggered: function clickAction() {
listViewTypo.addPrefixStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "> ", false);
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "> ", false);
}
},
Action {
@ -800,9 +811,9 @@ Rectangle {
property var iconSrc: JamiResources.bullet_point_black_24dp_svg
property var shortcutText: JamiStrings.unorderedList
property string shortcutKey: "Shift+Alt+8"
property bool isStyle: listViewTypo.isPrefixSyle(root.text, textArea.selectionStart, textArea.selectionEnd, "- ", false)
property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "- ", false)
onTriggered: function clickAction() {
listViewTypo.addPrefixStyle(root.text, textArea.selectionStart, textArea.selectionEnd, "- ", false);
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "- ", false);
}
},
Action {
@ -810,23 +821,9 @@ Rectangle {
property var iconSrc: JamiResources.bullet_number_black_24dp_svg
property var shortcutText: JamiStrings.orderedList
property string shortcutKey: "Shift+Alt+7"
property bool isStyle: listViewTypo.isPrefixSyle(root.text, textArea.selectionStart, textArea.selectionEnd, "", true)
property bool isStyle: listViewTypo.isPrefixSyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true)
onTriggered: function clickAction() {
listViewTypo.addPrefixStyle(root.text, textArea.selectionStart, textArea.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);
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true);
}
}
]
@ -834,8 +831,7 @@ Rectangle {
model: menuTypoActionsSecond
delegate: PushButton {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
preferredSize: JamiTheme.chatViewFooterRealButtonSize
imageContainerWidth: 20
imageContainerHeight: 20
@ -852,13 +848,13 @@ Rectangle {
normalColor: {
if (showPreview) {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
} else if (modelData.normalColor != null) {
return modelData.normalColor;
} else if (modelData.isStyle) {
return JamiTheme.hoveredButtonColor;
} else {
return JamiTheme.transparentColor;
return JamiTheme.primaryBackgroundColor;
}
}
imageColor: {
@ -897,24 +893,18 @@ Rectangle {
toolTipText: showTypo ? JamiStrings.hideFormatting : JamiStrings.showFormatting
source: JamiResources.text_edit_black_24dp_svg
normalColor: showPreview ? JamiTheme.transparentColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor)
normalColor: showPreview ? JamiTheme.primaryBackgroundColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor)
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered || showTypo ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
onClicked: {
showTypo = !showTypo;
if (messageBar.width < messageBarLayoutMaximumWidth + sendButtonRow.width + 2 * JamiTheme.preferredMarginSize)
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);
}
@ -922,7 +912,6 @@ Rectangle {
}
Row {
anchors.bottom: parent.bottom
anchors.bottomMargin: marginSize / 2
@ -956,6 +945,7 @@ Rectangle {
property bool noSip: false
onTriggered: function clickAction() {
sendFileButtonClicked();
textAreaObj.forceActiveFocus();
}
},
Action {
@ -1019,7 +1009,7 @@ Rectangle {
toolTipText: modelData.toolTip
source: modelData.iconSrc
normalColor: JamiTheme.transparentColor
normalColor: JamiTheme.primaryBackgroundColor
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
@ -1158,34 +1148,32 @@ Rectangle {
imageContainerHeight: 25
radius: 5
source: JamiResources.preview_black_24dp_svg
normalColor: showPreview ? hoveredColor : JamiTheme.transparentColor
normalColor: showPreview ? hoveredColor : JamiTheme.primaryBackgroundColor
imageColor: (hovered || showPreview) ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
hoveredColor: JamiTheme.hoveredButtonColor
pressedColor: hoveredColor
toolTipText: showPreview ? JamiStrings.continueEditing : JamiStrings.showPreview
onClicked: {
showPreview = !showPreview;
textArea.showPreview = showPreview;
messageBarTextArea.showPreview = showPreview;
}
}
}
}
}
Row {
id: sendButtonRow
spacing: JamiTheme.chatViewFooterRowSpacing
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: sendMessageButton.visible ? marginSize / 2 : 0
anchors.bottomMargin: marginSize / 2
Rectangle {
Layout.preferredHeight: parent.height
Layout.preferredWidth: childrenRect.width
visible: sendButtonVisibility
color: JamiTheme.transparentColor
PushButton {
id: sendMessageButton
objectName: "sendMessageButton"
anchors.bottom: parent.bottom
anchors.bottomMargin: marginSize / 2
enabled: sendButtonVisibility
hoverEnabled: enabled
@ -1210,7 +1198,6 @@ Rectangle {
pressedColor: hoveredColor
opacity: 1
visible: opacity
scale: opacity
Behavior on opacity {

View File

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

View File

@ -109,7 +109,7 @@ JamiListView {
function isFirst() {
if (!nItem) return true
else {
if (item.showTime || item.isReply ) {
if (item.showTime || item.isReply || nItem.isEmojiOnly ) {
return true
} else if (nItem.author !== item.author) {
return true
@ -121,7 +121,7 @@ JamiListView {
function isLast() {
if (!pItem) return true
else {
if (pItem.showTime || pItem.isReply) {
if (pItem.showTime || pItem.isReply || pItem.isEmojiOnly) {
return true
} else if (pItem.author !== item.author) {
return true

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