Compare commits

..

163 Commits

Author SHA1 Message Date
Ingo Klöcker
3b367b7c9d Build Windows installers on invent 2023-12-04 08:43:36 +01:00
l10n daemon script
71cda237b1 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-12-03 03:01:48 +00:00
l10n daemon script
bb6f7ce985 GIT_SILENT Sync po/docbooks with svn 2023-12-01 03:08:22 +00:00
Heiko Becker
17b14aa556 GIT_SILENT Update Appstream for new release 2023-11-30 18:34:56 +01:00
Heiko Becker
7341e5824a GIT_SILENT Upgrade release service version to 23.08.4. 2023-11-30 17:50:36 +01:00
l10n daemon script
b9b5264fcf GIT_SILENT made messages (after extraction) 2023-11-29 14:32:26 +00:00
l10n daemon script
3388f8a60d GIT_SILENT Sync po/docbooks with svn 2023-11-29 03:19:07 +00:00
l10n daemon script
d878ef1804 GIT_SILENT Sync po/docbooks with svn 2023-11-26 04:08:29 +00:00
Tobias Fella
7e8a8615b1 Fix crash for forbidden non-mxc media
BUG: 476698
2023-11-24 18:47:26 +01:00
l10n daemon script
c0f9b6ba93 GIT_SILENT Sync po/docbooks with svn 2023-11-24 03:05:25 +00:00
l10n daemon script
4c0eb363fa GIT_SILENT Sync po/docbooks with svn 2023-11-20 04:00:29 +00:00
l10n daemon script
2ee3e4d81d GIT_SILENT made messages (after extraction) 2023-11-19 02:41:07 +00:00
l10n daemon script
2cf3070e9f GIT_SILENT Sync po/docbooks with svn 2023-11-18 03:04:23 +00:00
l10n daemon script
207b554c78 GIT_SILENT Sync po/docbooks with svn 2023-11-15 03:10:40 +00:00
l10n daemon script
2a54dbc108 GIT_SILENT Sync po/docbooks with svn 2023-11-13 03:08:15 +00:00
l10n daemon script
0aea54a119 GIT_SILENT Sync po/docbooks with svn 2023-11-12 03:38:37 +00:00
Heiko Becker
753e879556 GIT_SILENT Update Appstream for new release 2023-11-04 12:33:12 +01:00
Heiko Becker
6e6636e384 GIT_SILENT Upgrade release service version to 23.08.3. 2023-11-04 11:43:54 +01:00
l10n daemon script
3574c2e077 GIT_SILENT Sync po/docbooks with svn 2023-11-04 03:06:08 +00:00
Scarlett Moore
f947320191 snapcraft: remove dbus slots rejected by store. 2023-11-03 10:45:12 +00:00
Ingo Klöcker
0f8ed0bfc7 Add CI template for building APKs 2023-11-02 15:06:57 +01:00
l10n daemon script
ccd0bd5c6d GIT_SILENT Sync po/docbooks with svn 2023-11-02 03:08:48 +00:00
Scarlett Moore
a4020a7def snapcraft: Fix libsecret support! BUndle gnomekeychain. Set XDG variables so it finds keychain. Update qtkeychain. 2023-11-01 16:26:13 +00:00
l10n daemon script
1c9487df7e GIT_SILENT Sync po/docbooks with svn 2023-11-01 03:12:16 +00:00
l10n daemon script
526db7b73a GIT_SILENT Sync po/docbooks with svn 2023-10-26 03:29:34 +00:00
l10n daemon script
d9024e98c9 GIT_SILENT made messages (after extraction) 2023-10-26 02:47:31 +00:00
l10n daemon script
8697dde08d GIT_SILENT Sync po/docbooks with svn 2023-10-25 03:25:44 +00:00
l10n daemon script
9607424389 GIT_SILENT Sync po/docbooks with svn 2023-10-24 03:10:54 +00:00
l10n daemon script
9e22b0b61a GIT_SILENT Sync po/docbooks with svn 2023-10-22 04:04:00 +00:00
Scarlett Moore
148ac2f91a snapcraft: initial import snapcraft files. 2023-10-18 17:20:14 +00:00
Tobias Fella
9c4a4bb77f Use KF5 version of kirigami-addons in flatpak builds 2023-10-18 18:27:11 +02:00
l10n daemon script
00f880f7ff GIT_SILENT Sync po/docbooks with svn 2023-10-18 03:12:02 +00:00
l10n daemon script
703678ccea GIT_SILENT Sync po/docbooks with svn 2023-10-17 03:04:30 +00:00
l10n daemon script
d2ac959a1c GIT_SILENT Sync po/docbooks with svn 2023-10-14 03:21:31 +00:00
l10n daemon script
da0e84eacb GIT_SILENT Sync po/docbooks with svn 2023-10-13 03:11:05 +00:00
l10n daemon script
463172eca6 GIT_SILENT Sync po/docbooks with svn 2023-10-11 04:05:47 +00:00
Heiko Becker
ffbd92317e GIT_SILENT Update Appstream for new release 2023-10-07 18:01:35 +02:00
Heiko Becker
7c9173eb65 GIT_SILENT Upgrade release service version to 23.08.2. 2023-10-07 17:05:08 +02:00
l10n daemon script
c6a5a119e8 GIT_SILENT Sync po/docbooks with svn 2023-10-01 03:38:21 +00:00
l10n daemon script
edf2da1413 GIT_SILENT Sync po/docbooks with svn 2023-09-30 03:10:36 +00:00
l10n daemon script
3cacb10b9c GIT_SILENT Sync po/docbooks with svn 2023-09-26 03:21:35 +00:00
l10n daemon script
ce19275d8d GIT_SILENT Sync po/docbooks with svn 2023-09-20 03:07:35 +00:00
l10n daemon script
1d050c5264 GIT_SILENT Sync po/docbooks with svn 2023-09-19 03:12:29 +00:00
l10n daemon script
5f3ab888d0 GIT_SILENT Sync po/docbooks with svn 2023-09-17 04:02:52 +00:00
l10n daemon script
a7993d7b59 GIT_SILENT Sync po/docbooks with svn 2023-09-15 03:06:42 +00:00
l10n daemon script
eb837d2435 GIT_SILENT Sync po/docbooks with svn 2023-09-13 03:19:15 +00:00
l10n daemon script
c57354f974 GIT_SILENT Sync po/docbooks with svn 2023-09-11 03:12:35 +00:00
l10n daemon script
81a3ab95c5 GIT_SILENT made messages (after extraction) 2023-09-11 02:29:47 +00:00
q234 rty
0408956364 Use shortcode as a fallback for body when sending stickers
(cherry picked from commit 50551541ed)
2023-09-10 12:32:35 +02:00
Antonio Rojas
161412cbcf Add cmake check for qtlocation QML module
So that packagers are notified that it is a dependency

(cherry picked from commit 763198b2c3)
2023-09-10 12:32:32 +02:00
l10n daemon script
fdb02bebf5 GIT_SILENT Sync po/docbooks with svn 2023-09-10 03:04:18 +00:00
l10n daemon script
a756288a07 GIT_SILENT made messages (after extraction) 2023-09-10 02:23:23 +00:00
Ingo Klöcker
4853212326 Add Windows-specific screenshots as screenshots with custom attribute
Instead of using translated custom values (which are not accepted by
AppStream validation) this adds the Windows-specific screenshots as
normal screenshots with custom attribute x-kde-os="windows". AppStream
validation accepts custom attributes (in fact, it ignores any attributes
other than "type").

Upstream appstream tooling will treat those screenshots as any other
extra screenshots (screenshots without type="default").

(cherry picked from commit 6f4d2c0216)
2023-09-09 17:59:04 +02:00
Heiko Becker
3f36cbc2a4 Revert "GIT_SILENT made messages (after extraction)"
And restore the mistakenly removeed appdata file.

This reverts commit fe3933c96a.
2023-09-09 15:54:52 +02:00
Heiko Becker
ac9629258f GIT_SILENT Upgrade release service version to 23.08.1. 2023-09-09 10:23:39 +02:00
l10n daemon script
c085a5815b GIT_SILENT made messages (after extraction) 2023-09-09 02:24:55 +00:00
Luigi Toscano
7a25b151d4 Revert "GIT_SILENT made messages (after extraction)"
Restore a file which was removed by mistake.
Maybe we need to check the new ITS file.
This reverts commit fe3933c96a.
2023-09-08 11:24:29 +02:00
l10n daemon script
fe3933c96a GIT_SILENT made messages (after extraction) 2023-09-08 02:24:52 +00:00
l10n daemon script
3f59d988e7 GIT_SILENT Sync po/docbooks with svn 2023-09-06 03:02:15 +00:00
l10n daemon script
4355afae30 GIT_SILENT Sync po/docbooks with svn 2023-09-04 03:10:19 +00:00
l10n daemon script
99c7d0f5cc GIT_SILENT Sync po/docbooks with svn 2023-09-03 04:04:27 +00:00
l10n daemon script
528ad54136 GIT_SILENT Sync po/docbooks with svn 2023-09-02 03:15:32 +00:00
l10n daemon script
ee18e92d12 GIT_SILENT Sync po/docbooks with svn 2023-09-01 03:05:30 +00:00
l10n daemon script
67c0bf1881 GIT_SILENT Sync po/docbooks with svn 2023-08-31 03:04:57 +00:00
l10n daemon script
4e0c0fc3e4 GIT_SILENT Sync po/docbooks with svn 2023-08-29 03:04:34 +00:00
Tobias Fella
4886f1c3b9 Deselect space when leaving it
BUG: 473271
(cherry picked from commit cc60dde62d)
2023-08-28 11:48:40 +02:00
l10n daemon script
d1efa96b79 GIT_SILENT Sync po/docbooks with svn 2023-08-28 04:04:14 +00:00
Tobias Fella
56d7d1f313 Fix opening settings
BUG: 473789
(cherry picked from commit d11d6c74b3)
2023-08-27 19:17:49 +02:00
Tobias Fella
04682b077a Fix opening report sheet
(cherry picked from commit 68298f038d)
2023-08-27 14:59:43 +02:00
Tobias Fella
ed496e04bb Force plain text user display name in user detail sheet
(cherry picked from commit 5da9bba844)
2023-08-27 14:59:29 +02:00
Tobias Fella
8439768cc3 Fix opening ban sheet
(cherry picked from commit 405fd5841a)
2023-08-27 14:59:19 +02:00
Carl Schwan
33a4d476c6 Add release note for last two version
(cherry picked from commit 550d55cb1a)
2023-08-25 15:23:53 +02:00
Carl Schwan
bb2e2fddcc Remove debuging value
Otherwise like of connectivity never disapear

(cherry picked from commit 1e3c3dd1f4)
2023-08-24 16:11:06 +02:00
l10n daemon script
0d890ce3d6 GIT_SILENT Sync po/docbooks with svn 2023-08-21 03:07:33 +00:00
l10n daemon script
081dd5f1b0 GIT_SILENT made messages (after extraction) 2023-08-21 02:26:15 +00:00
l10n daemon script
79bba63864 GIT_SILENT Sync po/docbooks with svn 2023-08-20 03:05:14 +00:00
l10n daemon script
2b131b58a9 GIT_SILENT Sync po/docbooks with svn 2023-08-17 03:05:43 +00:00
Carl Schwan
97b7047a48 Don't inherit color in TimelineContainer
(cherry picked from commit 3bd93996c0)
2023-08-16 23:45:04 +02:00
Heiko Becker
91b5573016 GIT_SILENT Update Appstream for new release 2023-08-16 23:33:42 +02:00
Heiko Becker
8e9bb8a7e4 GIT_SILENT Upgrade release service version to 23.08.0. 2023-08-16 23:33:39 +02:00
Joshua Goins
916755b4ad Use view-list-details instead of expand icon in room drawer
(cherry picked from commit 24d0082048)
2023-08-16 16:24:13 -04:00
Joshua Goins
9ce288fe47 Destroy the correct component in space list context menu
(cherry picked from commit 2980af11b0)
2023-08-16 16:24:12 -04:00
Joshua Goins
aa461fe078 Prevent the TapHandler in AvatarTabButton from triggering clicked()
This caused right-clicks on this component (for example, in the space
drawer) to cause clicked() to be called on the delegate.

(cherry picked from commit 91d9406c38)
2023-08-16 16:24:12 -04:00
Joshua Goins
15d8c39185 Add icons to the space list context menu items
(cherry picked from commit 280d1e38e2)
2023-08-16 16:24:12 -04:00
Joshua Goins
4a1aa97d7b Prevent the chat bar from pasting a local file URL if we save the bitmap
There's no point in also putting the file:// URL, so catch the event if
saving the bitmap from the clipboard is successful.

(cherry picked from commit 7b520da4b4)
2023-08-16 16:24:12 -04:00
Joshua Goins
e332179ac4 Ensure that the notification avatar is drawn with no pen
(cherry picked from commit 419b4cea98)
2023-08-16 16:22:38 -04:00
Joshua Goins
7534f293c5 Further notification avatar improvements
The correct render hint is actually SmoothPixmapTransform, as
Antialiasing only matters for primitives. Also, render a white
background for potentially transparent avatars.

(cherry picked from commit 38824f30ac)
2023-08-16 16:22:38 -04:00
Joshua Goins
fc60a7c13e Fix the account switcher width so it doesn't spill off the side
(cherry picked from commit 9c4d8ef823)
2023-08-16 16:22:38 -04:00
Joshua Goins
48b8703156 Pick a better shadow and clean up emoji popup backgrounds
These shadows are now closer to how other popups look.

(cherry picked from commit fe3bf3a638)
2023-08-16 16:22:38 -04:00
Joshua Goins
5ca85dc670 Don't clip the emoji popups as they destroy shadows
(cherry picked from commit d678a446e2)
2023-08-16 16:22:38 -04:00
l10n daemon script
bf8ea41e6a GIT_SILENT Sync po/docbooks with svn 2023-08-16 03:06:00 +00:00
l10n daemon script
fda4ae8735 GIT_SILENT Sync po/docbooks with svn 2023-08-15 03:08:17 +00:00
Tobias Fella
aa0e9fff15 Improve tooltips in chatbar
(cherry picked from commit 4ea183b139)
2023-08-14 09:55:08 +02:00
Tobias Fella
28391b53e5 Wrap room display name in Room Drawer
(cherry picked from commit 22fd24549b)
2023-08-14 09:51:34 +02:00
l10n daemon script
a8d7744b42 GIT_SILENT Sync po/docbooks with svn 2023-08-13 03:05:29 +00:00
l10n daemon script
9fcc858841 GIT_SILENT made messages (after extraction) 2023-08-13 02:23:56 +00:00
l10n daemon script
f7092eee69 GIT_SILENT Sync po/docbooks with svn 2023-08-12 03:11:35 +00:00
l10n daemon script
9a426f941a GIT_SILENT Sync po/docbooks with svn 2023-08-11 03:06:07 +00:00
Albert Astals Cid
c77dee09f5 GIT_SILENT Upgrade release service version to 23.07.90. 2023-08-10 21:00:24 +02:00
l10n daemon script
26dde017d0 GIT_SILENT Sync po/docbooks with svn 2023-08-10 03:07:45 +00:00
l10n daemon script
5b27a84bcc GIT_SILENT Sync po/docbooks with svn 2023-08-09 03:12:18 +00:00
Carl Schwan
fc3c36838c Display big emoji correctly
We already check with a regex if the message only contains emoji so it is safe
to hardcode the font family as emoji for these messages.


(cherry picked from commit 58213ee3e6)
2023-08-08 15:00:29 +02:00
l10n daemon script
1fd2072cf8 GIT_SILENT Sync po/docbooks with svn 2023-08-08 03:23:23 +00:00
l10n daemon script
7770d412b3 GIT_SILENT made messages (after extraction) 2023-08-08 02:36:56 +00:00
Tobias Fella
56184920b4 Force plain text in room delegate
(cherry picked from commit 3ab04583ae)
2023-08-07 23:14:58 +02:00
l10n daemon script
b61685b151 GIT_SILENT Sync po/docbooks with svn 2023-08-07 03:49:13 +00:00
l10n daemon script
be0212a686 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-08-07 03:39:29 +00:00
l10n daemon script
37ed09f957 GIT_SILENT made messages (after extraction) 2023-08-07 03:00:36 +00:00
l10n daemon script
1b7e8ae77a GIT_SILENT Sync po/docbooks with svn 2023-08-06 03:13:44 +00:00
Tobias Fella
7571b0a9a3 Remove leftover debug statement
(cherry picked from commit 88368cefaa)
2023-08-06 00:52:20 +02:00
Tobias Fella
9477e6343f Fix last active time in devices page
(cherry picked from commit ab4bb41979)
2023-08-05 20:34:00 +02:00
l10n daemon script
83241ea956 GIT_SILENT Sync po/docbooks with svn 2023-08-03 04:06:32 +00:00
l10n daemon script
f054467878 GIT_SILENT made messages (after extraction) 2023-08-03 03:11:57 +00:00
l10n daemon script
fb7154b492 GIT_SILENT Sync po/docbooks with svn 2023-08-02 03:20:51 +00:00
l10n daemon script
973a75128c SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-08-02 03:13:39 +00:00
l10n daemon script
9ea70d7eac GIT_SILENT made messages (after extraction) 2023-08-02 02:35:56 +00:00
l10n daemon script
7f8285037c GIT_SILENT Sync po/docbooks with svn 2023-08-01 03:26:38 +00:00
Carl Schwan
c5f19f12e5 Redesign timeline
Remove border von bubbles and only hilight the bubble on hover

(cherry picked from commit 7f459cb90f)
2023-07-31 21:51:12 +02:00
Carl Schwan
ed6379ff85 Fix opening account menu on right click
(cherry picked from commit 5f41b7b4c1)
2023-07-31 09:03:01 +02:00
l10n daemon script
9750df90e0 GIT_SILENT Sync po/docbooks with svn 2023-07-31 04:06:19 +00:00
l10n daemon script
bd90658668 GIT_SILENT made messages (after extraction) 2023-07-31 03:12:56 +00:00
l10n daemon script
f78b634720 GIT_SILENT Sync po/docbooks with svn 2023-07-30 03:13:52 +00:00
Tobias Fella
250476f77c Html-escape display names in state delegates
(cherry picked from commit 163c1ef407)
2023-07-29 22:31:46 +02:00
Tobias Fella
e293d1f644 Fix room list icon size in compact room list
BUG: 472682
(cherry picked from commit 3bd639775a)
2023-07-29 22:31:14 +02:00
l10n daemon script
cde50588cb GIT_SILENT Sync po/docbooks with svn 2023-07-29 03:09:59 +00:00
l10n daemon script
3972dab7b9 GIT_SILENT made messages (after extraction) 2023-07-29 02:26:29 +00:00
Carl Schwan
7c1b43bcad Fix compilation with e2ee disabled 2023-07-28 13:01:54 +02:00
l10n daemon script
c22c74f735 GIT_SILENT Sync po/docbooks with svn 2023-07-28 03:18:59 +00:00
l10n daemon script
9c42b3c1a7 GIT_SILENT Sync po/docbooks with svn 2023-07-27 03:12:00 +00:00
l10n daemon script
d45cd5d9c9 GIT_SILENT made messages (after extraction) 2023-07-27 02:26:28 +00:00
Joshua Goins
8c503b8258 Use prettier notification images
Avatars are shown rounded in the main interface, so they should look the
same in the notification tray too. On top of that, if the room is a
group then show that group's icon when applicable in the bottom right.


(cherry picked from commit 470418f14f)
2023-07-26 10:31:47 +02:00
Joshua Goins
7078caac15 Fix errors preventing the avatar from being shown when uploaded
(cherry picked from commit 807a9ee779)
2023-07-26 10:29:06 +02:00
Joshua Goins
94bf65ab43 Add an obvious "upload" button in the account editor
It's not obvious at first glance that you can click on the avatar in the
account editor to upload an image. This adds a new button when there is
no image uploaded.


(cherry picked from commit 0ac3932303)
2023-07-26 10:28:32 +02:00
Joshua Goins
244e93c926 Fix settings button tooltip
(cherry picked from commit 4f32a168cd)
2023-07-26 08:38:06 +02:00
l10n daemon script
412856e882 GIT_SILENT Sync po/docbooks with svn 2023-07-26 03:13:49 +00:00
l10n daemon script
2421f11717 GIT_SILENT Sync po/docbooks with svn 2023-07-25 03:20:17 +00:00
l10n daemon script
2d42cfedec GIT_SILENT made messages (after extraction) 2023-07-25 02:30:45 +00:00
l10n daemon script
9308c84696 GIT_SILENT Sync po/docbooks with svn 2023-07-24 11:06:34 +00:00
l10n daemon script
72fc242364 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-07-24 10:47:48 +00:00
Carl Schwan
7d3240c597 Refactor completion menu
- Use new Avatar
- Use required property in delegate


(cherry picked from commit 75cd77facb)
2023-07-24 10:46:57 +02:00
Carl Schwan
9906ba8b7d Move no connection info message to the top
(cherry picked from commit f8d3e25f8e)
2023-07-24 10:46:35 +02:00
Tobias Fella
b949092bc6 Fix clearing user search field text when switching rooms
(cherry picked from commit 9ba6b2f0a5)
2023-07-24 10:46:16 +02:00
Tobias Fella
5cce3bd692 Fix nullptr check 2023-07-23 23:12:01 +02:00
Carl Schwan
ef5d67e5bf Add back some spacing around the avatar in the timeline
(cherry picked from commit b486cb905c)
2023-07-22 22:32:28 +02:00
Carl Schwan
4711b954c5 Fix accessibility of StartChatPage and port to new components
(cherry picked from commit cdd5c9f484)
2023-07-22 22:32:27 +02:00
Carl Schwan
1688b00f48 Port Avatar usage in Settings KirigamiAddons
(cherry picked from commit 3e6c426397)
2023-07-22 22:32:27 +02:00
Carl Schwan
410befa4bf Port most Avatar usage to new KirigamiAddons Avatar
(cherry picked from commit 847f41e1ad)
2023-07-22 22:32:27 +02:00
Carl Schwan
b380c74b0e Remove hover effect on timeline events 2023-07-22 22:32:20 +02:00
Carl Schwan
da8227931f Remove duplicated code in QuickSwitcher for RoomDelegate 2023-07-22 22:31:42 +02:00
Carl Schwan
fdc45ec5c8 Redesign room list
Use KirigamiAddons.Delegated.RoundedItemDelegate
2023-07-22 22:31:38 +02:00
Carl Schwan
94dd69ea02 Scroll to top of RoomDrawer on loading of header
(cherry picked from commit c8b4da2b96)
2023-07-22 17:53:06 +00:00
Carl Schwan
80c3253a6e Discard wrong avatar urls
(cherry picked from commit ed5bb270ff)
2023-07-22 17:51:46 +00:00
l10n daemon script
c5f6a6607e GIT_SILENT Sync po/docbooks with svn 2023-07-21 03:39:31 +00:00
l10n daemon script
a10d5cbe75 GIT_SILENT Sync po/docbooks with svn 2023-07-20 03:31:32 +00:00
l10n daemon script
584cad19b1 GIT_SILENT made messages (after extraction) 2023-07-20 02:45:39 +00:00
Carl Schwan
3745414635 Port to KirigamAddons.Banner
(cherry picked from commit 3263a69880)
2023-07-19 22:48:56 +02:00
l10n daemon script
147ce42c04 GIT_SILENT Sync po/docbooks with svn 2023-07-19 05:18:38 +00:00
l10n daemon script
928feeca82 GIT_SILENT made messages (after extraction) 2023-07-18 08:31:37 +00:00
Tobias Fella
fc04af536d Fix opening user mentions
(cherry picked from commit 646c8ba8fe)
2023-07-18 08:06:16 +02:00
Tobias Fella
12b949d6cb Fix image loading in room avatars
(cherry picked from commit 918e805718)
2023-07-18 05:26:04 +00:00
l10n daemon script
6aaaabf159 GIT_SILENT Sync po/docbooks with svn 2023-07-18 04:13:52 +00:00
l10n daemon script
fe45ef85a6 GIT_SILENT made messages (after extraction) 2023-07-18 02:55:30 +00:00
Albert Astals Cid
13e38ed982 GIT_SILENT Upgrade release service version to 23.07.80. 2023-07-17 11:25:34 +02:00
109 changed files with 11143 additions and 12124 deletions

5
.craft.ini Normal file
View File

@@ -0,0 +1,5 @@
; SPDX-FileCopyrightText: None
; SPDX-License-Identifier: CC0-1.0
[BlueprintSettings]
kde/applications/neochat.packageAppx = True

View File

@@ -26,7 +26,7 @@
"name": "kirigamiaddons",
"config-opts": [ "-DBUILD_TESTING=OFF" ],
"buildsystem": "cmake-ninja",
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git" } ]
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git", "branch": "kf5" } ]
},
{
"name": "kquickimageeditor",

View File

@@ -2,13 +2,14 @@
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml
- project: sysadmin/ci-utilities
file:
- /gitlab-templates/reuse-lint.yml
- /gitlab-templates/android.yml
# - /gitlab-templates/linux.yml
- /gitlab-templates/linux-qt6.yml
- /gitlab-templates/windows.yml
# - /gitlab-templates/freebsd.yml
- /gitlab-templates/flatpak.yml
- /gitlab-templates/craft-android-apks.yml
- /gitlab-templates/craft-windows-x86-64.yml

View File

@@ -58,9 +58,5 @@ Dependencies:
'require':
'frameworks/kdbusaddons': '@latest-kf6'
- 'on': ['Linux/Qt6', 'Linux/Qt5']
'require':
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
Options:
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD' ]

View File

@@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "23")
set(RELEASE_SERVICE_VERSION_MINOR "11")
set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION_MINOR "08")
set(RELEASE_SERVICE_VERSION_MICRO "4")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
@@ -93,6 +93,12 @@ set_package_properties(KF${QT_MAJOR_VERSION}Kirigami2 PROPERTIES
)
find_package(KF${QT_MAJOR_VERSION}KirigamiAddons 0.7.2 REQUIRED)
find_package(Qt${QT_MAJOR_VERSION}Keychain)
set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
TYPE REQUIRED
PURPOSE "Secure storage of account secrets"
)
if(ANDROID)
find_package(OpenSSL)
set_package_properties(OpenSSL PROPERTIES
@@ -124,11 +130,6 @@ set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES
PURPOSE "Talk with matrix server"
)
if (NOT TARGET Olm::Olm)
message(FATAL_ERROR "NeoChat requires Quotient with the E2EE feature enabled")
endif()
find_package(cmark)
set_package_properties(cmark PROPERTIES
TYPE REQUIRED
@@ -140,6 +141,7 @@ set_package_properties(cmark PROPERTIES
ecm_find_qmlmodule(org.kde.kquickimageeditor 1.0)
ecm_find_qmlmodule(org.kde.kitemmodels 1.0)
ecm_find_qmlmodule(org.kde.quickcharts 1.0)
ecm_find_qmlmodule(QtLocation ${QTLOCATION_MODULE_QML_VERSION})
find_package(KQuickImageEditor COMPONENTS)
set_package_properties(KQuickImageEditor PROPERTIES
@@ -159,6 +161,10 @@ set_package_properties(KF${QT_MAJOR_VERSION}DocTools PROPERTIES DESCRIPTION
TYPE OPTIONAL
)
if(NOT Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
cmake_policy(SET CMP0063 OLD)
endif()
if(ANDROID)
find_package(Sqlite3)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
@@ -174,11 +180,9 @@ install(FILES org.kde.neochat.tray.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/h
add_definitions(-DQT_NO_FOREACH)
add_subdirectory(src)
if (BUILD_TESTING)
if (BUILD_TESTING AND Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
add_subdirectory(autotests)
add_subdirectory(appiumtests)
endif()
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)

View File

@@ -1,23 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
if(NOT BUILD_TESTING OR NOT CMAKE_SYSTEM_NAME MATCHES "Linux")
return()
endif()
find_package(SeleniumWebDriverATSPI)
set_package_properties(SeleniumWebDriverATSPI PROPERTIES
DESCRIPTION "Server component for selenium tests using Linux accessibility infrastructure"
PURPOSE "Needed for GUI tests"
URL "https://invent.kde.org/sdk/selenium-webdriver-at-spi"
TYPE OPTIONAL
)
if(NOT SeleniumWebDriverATSPI_FOUND)
return()
endif()
add_test(
NAME logintest
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/logintest.py
)

View File

@@ -1,42 +0,0 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
from flask import Flask, request, abort
app = Flask(__name__)
@app.route("/_matrix/client/v3/login", methods=["GET"])
def login_get():
result = dict()
result["flows"] = [dict()]
result["flows"][0]["type"] = "m.login.password"
return result
@app.route("/_matrix/client/v3/login", methods=["POST"])
def login_post():
data = request.get_json()
if data["identifier"]["user"] != "user" or data["password"] != "1234":
abort(403)
print(data)
result = dict()
result["access_token"] = "token_1234"
result["device_id"] = "device_1234"
result["user_id"] = "@user:localhost:1234"
return result
@app.route("/_matrix/client/r0/sync")
def sync():
result = dict()
result["next_batch"] = "batch1234"
return result
@app.route("/.well-known/matrix/client")
def well_known():
reply = dict()
reply["m.homeserver"] = dict()
reply["m.homeserver"]["base_url"] = "https://localhost:1234"
return reply
if __name__ == "__main__":
app.run(ssl_context='adhoc', port=1234)

View File

@@ -1,44 +0,0 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
import unittest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
import time
import subprocess
class LoginTest(unittest.TestCase):
@classmethod
def setUpClass(self):
desired_caps = {}
desired_caps["app"] = "neochat --ignore-ssl-errors"
desired_caps["timeouts"] = {'implicit': 10000}
self.driver = webdriver.Remote(
command_executor='http://127.0.0.1:4723',
desired_capabilities=desired_caps)
subprocess.Popen(["python","login-server.py"])
def setUp(self):
pass
def tearDown(self):
if not self._outcome.result.wasSuccessful():
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
@classmethod
def tearDownClass(self):
self.driver.quit()
def test_login(self):
self.driver.find_element(by=AppiumBy.NAME, value="Matrix ID").send_keys("@user:localhost:1234")
self.driver.find_element(by=AppiumBy.NAME, value="Continue").click()
self.driver.find_element(by=AppiumBy.NAME, value="Password").send_keys("1234")
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
self.driver.find_element(by=AppiumBy.NAME, value="Join some rooms to get started").click()
if __name__ == '__main__':
unittest.main()

View File

@@ -10,8 +10,6 @@
#include <Quotient/syncdata.h>
#include <qnamespace.h>
#include "utils.h"
using namespace Quotient;
class TestRoom : public NeoChatRoom
@@ -557,10 +555,10 @@ void TextHandlerTest::receiveRichPlainUrl()
void TextHandlerTest::receiveRichEmote()
{
auto event = room->messageEvents().at(1).get();
auto author = room->user(event->senderId());
auto author = static_cast<NeoChatUser *>(room->user(event->senderId()));
const QString testInputString = QStringLiteral("This is an emote.");
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:")
+ Utils::getUserColor(author->hueF()).name() + QStringLiteral("\">@example:example.org</a> This is an emote.");
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:") + author->color().name()
+ QStringLiteral("\">@example:example.org</a> This is an emote.");
TextHandler testTextHandler;
testTextHandler.setData(testInputString);
@@ -646,5 +644,5 @@ void TextHandlerTest::linkPreviewsReject()
QCOMPARE(testTextHandler.getLinkPreviews(), testOutputLinks);
}
QTEST_MAIN(TextHandlerTest)
QTEST_GUILESS_MAIN(TextHandlerTest)
#include "texthandlertest.moc"

View File

@@ -46,22 +46,43 @@
<name xml:lang="uk">NeoChat</name>
<name xml:lang="x-test">xxNeoChatxx</name>
<name xml:lang="zh-CN">NeoChat</name>
<summary>Chat with your friends on matrix</summary>
<summary xml:lang="ca">Xategeu amb els vostres amics a Matrix</summary>
<summary xml:lang="ca-valencia">Xategeu amb els vostres amics a Matrix</summary>
<summary xml:lang="eo">Babilu kun viaj amikoj sur matrix</summary>
<summary xml:lang="eu">Berriketan jardun zure lagunekin «Matrix»en</summary>
<summary xml:lang="gl">Charle coas súas amizades en Matrix.</summary>
<summary xml:lang="it">Conversa con i tuoi contatti su matrix</summary>
<summary xml:lang="ka">ესაუბრეთ მეგობრებს Matrix-ზე</summary>
<summary xml:lang="nl">Met uw vrienden chatten op matrix</summary>
<summary xml:lang="nn">Prat med vennar på Matrix</summary>
<summary xml:lang="sl">Klepet z vašimi prijatelji na matrixu</summary>
<summary xml:lang="sv">Chatta med dina vänner på Matrix</summary>
<summary xml:lang="ta">மேட்ரிக்ஸு மூலம் உங்கள் நண்பர்களிடம் பேசலாம்</summary>
<summary xml:lang="tr">Matrix'te arkadaşlarınızla sohbet edin</summary>
<summary xml:lang="uk">Спілкуйтеся з вашими друзями у matrix</summary>
<summary xml:lang="x-test">xxChat with your friends on matrixxx</summary>
<summary>A client for matrix, the decentralized communication protocol</summary>
<summary xml:lang="ar">عميل لماتركس، ميفاق الاتصال اللامركزي</summary>
<summary xml:lang="az">Matrix üçün müştəri, mərkəzləşməmiş kommunikasiya protokolu</summary>
<summary xml:lang="ca">Un client de Matrix, el protocol de comunicacions descentralitzat</summary>
<summary xml:lang="ca-valencia">Un client de Matrix, el protocol de comunicacions descentralitzat</summary>
<summary xml:lang="cs">Klient pro decentralizovaný komunikační protokol matrix</summary>
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
<summary xml:lang="eo">Kliento por matrix, la malcentra komunikprotokolo</summary>
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
<summary xml:lang="fr">Un client pour « Matrix », le protocole décentralisé de communications.</summary>
<summary xml:lang="gl">Un cliente para Matrix, o protocolo de comunicación descentralizada.</summary>
<summary xml:lang="hu">Kliens a matrixhoz, a decentralizált kommunikációs protokollhoz</summary>
<summary xml:lang="ia">Un cliente per Matrix, le protocollo de communication decentralisate</summary>
<summary xml:lang="id">Klien untuk matrix, protokol komunikasi terdesentralisasi</summary>
<summary xml:lang="ie">Un cliente de Matrix, li protocol de communication decentralisat</summary>
<summary xml:lang="it">Un client per matrix, il protocollo di comunicazione decentralizzato</summary>
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</summary>
<summary xml:lang="nn">Ein klient for Matrix  protokollen for desentralisert kommunikasjon</summary>
<summary xml:lang="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
<summary xml:lang="pt-BR">Um cliente do Matrix, o protocolo de comunicação descentralizado</summary>
<summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary>
<summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary>
<summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary>
<summary xml:lang="sv">En klient för Matrix, det decentraliserade kommunikationsprotokollet</summary>
<summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary>
<summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary>
<summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary>
<summary xml:lang="x-test">xxA client for matrix, the decentralized communication protocolxx</summary>
<summary xml:lang="zh-CN">分布式通讯协议 Matrix 的客户端</summary>
<description>
<p>NeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami
to provide a convergent experience across multiple platforms.</p>
@@ -83,6 +104,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="nn">NeoChat er ein klient for Matrix, ein protokoll for desentralisert kommunikasjon. Du kan utveksla tekst, lyd og videoar med kollegaar, vennar og familie. Programmet brukar KDE Frameworks og Kirigami for å gje ei brukarflate tilpassa ulike plattformer.</p>
<p xml:lang="pl">NeoChat jest programem do Matriksa, protokołu rozproszonego porozumiewania się w czasie rzeczywistym. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół. Używa szkieletów KDE i głównie Kirigami, aby zapewnić spójne wrażenia na wielu platformach</p>
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix. Usa as plataformas do KDE, e principalmente o Kirigami, para oferecer uma experiência convergente entre várias plataformas.</p>
<p xml:lang="ru">NeoChat — клиент для Matrix, децентрализованного коммуникационного протокола для мгновенного обмена сообщениями. С его помощью возможно отправлять текстовые сообщения, видео- и звуковые файлы родственникам, коллегам и друзьям. В программе использованы библиотеки KDE, в частности Kirigami, для обеспечения единообразной работы на различных платформах.</p>
<p xml:lang="sl">Neochat je odjemalec za Matrix, decentralizirani komunikacijski protokol za takojšnje sporočanje. Omogoča vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek svoji družini, sodelavcem in prijateljem. Uporablja okvire ogrodje KDE frameworks in predvsem Kirigami za zagotavljanje konvergentne izkušnje na več platformah.</p>
<p xml:lang="sv">NeoChat är en klient för Matrix, det decentraliserade kommunikationsprotokollet för direktmeddelanden. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner. Den använder KDE Ramverk, i synnerhet Kirigami, för att tillhandahålla en konvergent upplevelse på flera plattformar.</p>
<p xml:lang="tr">NeoChat, anlık iletileşme için merkezi olmayan iletişim protokolü olan Matrix için bir istemcidir. Ailenize, iş arkadaşlarınıza ve arkadaşlarınıza metin iletiler, videolar ve ses dosyaları göndermenize olanak tanır. Birden çok platformda yakınsak bir deneyim sağlamak için KDE Frameworks ve en önemlilerinden Kirigami'yi kullanır.</p>
@@ -91,7 +113,7 @@ to provide a convergent experience across multiple platforms.</p>
<p>NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
<p xml:lang="ar">يهدف نيوتشات إلى أن يكون تطبيقًا كامل الميزات لمواصفات ماتركس. على هذا النحو يتم دعم كل شيء في المواصفات المستقرة الحالية مع الاستثناءات الملحوظة لـ VoIP والخيوط وبعض جوانب التشفير من طرف إلى طرف. هناك عدد قليل من الإغفالات الصغيرة الأخرى بسبب حقيقة أن مواصفات ماتركس تتطور باستمرار ، ولكن يبقى الهدف توفير الدعم النهائي للمواصفات بأكملها.</p>
<p xml:lang="ca">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptatge d'extrem a extrem. Hi ha algunes altres omissions més petites a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu segueix sent proporcionar suport eventual per a tota l'especificació.</p>
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
<p xml:lang="en-GB">NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
<p xml:lang="eo">NeoChat celas esti plene kapabla aplikaĵo por la Matrix-specifo. Kiel tia, ĉio en la nuna stabila specifo kun la rimarkindaj esceptoj de VoIP, fadenoj kaj kelkaj aspektoj de Fin-al-Fina Ĉifrado estas subtenataj. Estas kelkaj aliaj pli malgrandaj preterlasoj pro la fakto, ke la Matrix-speco konstante evoluas, sed la celo restas provizi finfine subtenon por la tuta specifaĵo.</p>
<p xml:lang="es">NeoChat pretende ser una aplicación con todas las funciones para la especificación de Matrix. Como tal, admite todo en la especificación estable actual, con las notables excepciones de VoIP, subprocesos y algunas funciones de cifrado de extremo a extremo. Existen algunas omisiones menos importantes debido al hecho de que la especificación de Matrix está en constante evolución, pero el objetivo sigue siendo brindar compatibilidad final con toda la especificación.</p>
@@ -107,6 +129,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme'nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
@@ -131,6 +154,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் வித‍த்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
@@ -155,7 +179,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">투표 - MSC3381</li>
<li xml:lang="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pl">Ankiety - MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="ru">Голосования — MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="sv">Polls - MSC3381</li>
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
@@ -179,7 +205,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">스티커 팩 - MSC2545</li>
<li xml:lang="nl">Sticker Packs - MSC2545</li>
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="ru">Наборы наклеек — MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="sv">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
@@ -203,7 +231,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
<li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="ru">События местоположения — MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="sv">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
@@ -264,50 +294,6 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
<value key="KDE::windows_store::screenshots::1::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::screenshots::1::caption">Main view with room list, chat, and room information</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="eo">Ĉefa vido kun ĉambra listo, babilejo kaj ĉambra informo</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
<value key="KDE::windows_store::screenshots::2::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
<value key="KDE::windows_store::screenshots::2::caption">Login screen</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca-valencia">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="eo">Ensaluta ekrano</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="es">Pantalla de inicio de sesión</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="eu">Saio-hasteko pantaila</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fi">Kirjautumisnäkymä</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="gl">Pantalla de identificación.</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="it">Schermata di accesso</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ko">로그인 화면</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nn">Innloggingsbilete</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="pt">Ecrã de autenticação</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sl">Prijavni zaslon</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sv">Inloggningsfönster</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ta">நுழைவுத் திரை</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="tr">Oturum açma ekranı</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="uk">Вікно входу</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>
</custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots>
@@ -317,15 +303,86 @@ to provide a convergent experience across multiple platforms.</p>
<screenshot type="default">
<image>https://cdn.kde.org/screenshots/neochat/application.png</image>
</screenshot>
<screenshot x-kde-os="windows">
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</image>
<caption>Main view with room list, chat, and room information</caption>
<caption xml:lang="ar">العرض الرئيسة مع قائمة الغرف والدردشات و معلومات الغرفة</caption>
<caption xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</caption>
<caption xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</caption>
<caption xml:lang="eo">Ĉefa vido kun ĉambra listo, babilejo kaj ĉambra informo</caption>
<caption xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</caption>
<caption xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</caption>
<caption xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</caption>
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
<caption xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</caption>
<caption xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</caption>
<caption xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</caption>
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
<caption xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</caption>
<caption xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</caption>
<caption xml:lang="x-test">xxMain view with room list, chat, and room informationxx</caption>
</screenshot>
<screenshot x-kde-os="windows">
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</image>
<caption>Login screen</caption>
<caption xml:lang="ar">شاشة الدخول</caption>
<caption xml:lang="ca">Pantalla d'inici de sessió</caption>
<caption xml:lang="ca-valencia">Pantalla d'inici de sessió</caption>
<caption xml:lang="eo">Ensaluta ekrano</caption>
<caption xml:lang="es">Pantalla de inicio de sesión</caption>
<caption xml:lang="eu">Saio-hasteko pantaila</caption>
<caption xml:lang="fi">Kirjautumisnäkymä</caption>
<caption xml:lang="fr">Écran de connexion</caption>
<caption xml:lang="gl">Pantalla de identificación.</caption>
<caption xml:lang="ia">Schermo de accesso</caption>
<caption xml:lang="it">Schermata di accesso</caption>
<caption xml:lang="ka">შესვლის ეკრანი</caption>
<caption xml:lang="ko">로그인 화면</caption>
<caption xml:lang="nl">Aanmeldscherm</caption>
<caption xml:lang="nn">Innloggingsbilete</caption>
<caption xml:lang="pl">Ekran logowania</caption>
<caption xml:lang="pt">Ecrã de autenticação</caption>
<caption xml:lang="ru">Окно входа</caption>
<caption xml:lang="sl">Prijavni zaslon</caption>
<caption xml:lang="sv">Inloggningsfönster</caption>
<caption xml:lang="ta">நுழைவுத் திரை</caption>
<caption xml:lang="tr">Oturum açma ekranı</caption>
<caption xml:lang="uk">Вікно входу</caption>
<caption xml:lang="x-test">xxLogin screenxx</caption>
</screenshot>
</screenshots>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="23.08.4" date="2023-12-07"/>
<release version="23.08.3" date="2023-11-09"/>
<release version="23.08.2" date="2023-10-12"/>
<release version="23.08.0" date="2023-08-24">
<url>https://kde.org/announcements/gear/23.08.0/#neochathttpsappskdeorgneochat</url>
<description>
<p>Apart from a visual overhaul, NeoChat can now display location events and also a map with the location of all the users currently broadcasting their location using Itineray's Matrix integration. Great for locating where your friends are.</p>
</description>
</release>
<release version="23.04.3" date="2023-07-06"/>
<release version="23.04.2" date="2023-06-08"/>
<release version="23.04.1" date="2023-05-11"/>
<release version="23.04.0" date="2023-04-20">
<url>https://kde.org/announcements/gear/23.04.0/#neochathttpsappskdeorgneochat</url>
<description>
<p>NeoChat improves its design with tweaks that provide a more compact layout and a simpler menu which works better for the collapsed room list.</p>
<p>We have also improved the video controls, added a new command /knock &lt;room-id&gt; to send a knock event to a room, and you can now edit a prior message inline, within the chat pane.</p>
<p>Other usability improvements include an overhaul of the keyboard navigation and shortcuts like Ctrl+PgUp/PgDn that allow you to skip from room to room.</p>
</description>
<artifacts>
<artifact type="binary" platform="x86_64-windows-msvc">
<location>https://download.kde.org/stable/release-service/23.04.0/windows/neochat-23.04.0-512-windows-cl-msvc2019-x86_64.exe</location>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

225
snapcraft.yaml Normal file
View File

@@ -0,0 +1,225 @@
# SPDX-FileCopyrightText: 2023 Scarlett Moore <sgmoore@kde.org>
#
# SPDX-License-Identifier: CC0-1.0
---
name: neochat
base: core22
adopt-info: neochat
grade: stable
confinement: strict
apps:
neochat:
# extensions:
# - kde-neon
command: usr/bin/neochat
common-id: org.kde.neochat
desktop: usr/share/applications/org.kde.neochat.desktop
plugs:
- home
- removable-media
- desktop
- desktop-legacy
- opengl
- wayland
- x11
- audio-playback
- unity7
- network
- network-bind
- network-manager-observe
- password-manager-service
- accounts-service
command-chain:
- snap/command-chain/desktop-launch
assumes:
- snapd2.58.3
compression: lzo
plugs:
desktop:
mount-host-font-cache: false
icon-themes:
interface: content
target: $SNAP/data-dir/icons
default-provider: gtk-common-themes
sound-themes:
interface: content
target: $SNAP/data-dir/sounds
default-provider: gtk-common-themes
kf5-5-111-qt-5-15-11-core22:
content: kf5-5-111-qt-5-15-11-core22-all
interface: content
default-provider: kf5-5-111-qt-5-15-11-core22
target: $SNAP/kf5
environment:
SNAP_DESKTOP_RUNTIME: $SNAP/kf5
QML2_IMPORT_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/qml:$SNAP/kf5/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/qml:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/qml"
QT_QUICK_CONTROLS_STYLE: org.kde.desktop
XDG_DATA_DIRS: "$SNAP/.local"
XDG_CONFIG_DIRS: "$SNAP/etc/xdg"
hooks:
configure:
plugs:
- desktop
command-chain:
- snap/command-chain/hooks-configure-desktop
layout:
/usr/share/X11:
symlink: $SNAP/kf5/usr/share/X11
slots:
session-dbus-interface:
interface: dbus
name: org.kde.neochat
bus: session
package-repositories:
- type: apt
components:
- main
suites:
- jammy
key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
url: http://origin.archive.neon.kde.org/user
key-server: keyserver.ubuntu.com
parts:
kde-neon:
source: /snap/snapcraft/current/share/snapcraft/extensions/desktop/kde-neon
source-type: local
plugin: make
make-parameters:
- PLATFORM_PLUG=kf5-5-111-qt-5-15-11-core22
build-snaps:
- kf5-5-111-qt-5-15-11-core22-sdk
build-environment:
- &id001
PATH: /snap/kf5-5-111-qt-5-15-11-core22-sdk/current/usr/bin${PATH:+:$PATH}
- &id002
XDG_DATA_DIRS: $CRAFT_STAGE/usr/share:/snap/kf5-5-111-qt-5-15-11-core22-sdk/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}
- &id003
XDG_CONFIG_HOME: $CRAFT_STAGE/etc/xdg:/snap/kf5-5-111-qt-5-15-11-core22-sdk/current/etc/xdg:/etc/xdg${XDG_CONFIG_HOME:+:$XDG_CONFIG_HOME}
- &id004
CRAFT_CMAKE_ARGS: -DCMAKE_FIND_ROOT_PATH=/snap/kf5-5-111-qt-5-15-11-core22-sdk/current${CRAFT_CMAKE_ARGS:+:$CRAFT_CMAKE_ARGS}
qtkeychain:
after:
- kde-neon
source: https://github.com/frankosterfeld/qtkeychain.git
source-tag: v0.14.0
source-depth: 0
plugin: cmake
build-packages:
- libsecret-1-dev
stage-packages:
- libsecret-1-0
- gnome-keyring
cmake-parameters:
- "-DKDE_INSTALL_USE_QT_SYS_PATHS=FALSE"
- "-DCMAKE_INSTALL_PREFIX=/usr"
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
- "-DENABLE_TESTING=OFF"
- "-DBUILD_TESTING=OFF"
- "-DKDE_SKIP_TEST_SETTINGS=ON"
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22/current"
- "-DBUILD_TRANSLATIONS=OFF"
- "-DLIBSECRET_SUPPORT=ON"
- "-DKEYCHAIN_DBUS=1"
prime:
- "-usr/include/qt5keychain"
- "-usr/lib/$CRAFT_ARCH_TRIPLET/libqt5keychain.so"
- "-usr/mkspecs"
- "-usr/lib/$CRAFT_ARCH_TRIPLET/cmake"
libmatrixclient:
after:
- kde-neon
- qtkeychain
source: https://github.com/quotient-im/libQuotient.git
source-tag: 0.8.1.2
source-depth: 0
plugin: cmake
build-packages:
- qtmultimedia5-dev
- libolm-dev
- libssl-dev
cmake-parameters:
- "-DCMAKE_INSTALL_PREFIX=/usr"
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
- "-DENABLE_TESTING=OFF"
- "-DBUILD_TESTING=OFF"
- "-DKDE_SKIP_TEST_SETTINGS=ON"
- "-DQuotient_ENABLE_E2EE=ON"
- "-DBUILDING_SHARED_QUOTIENT=ON"
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22/current"
neochat:
after:
- kde-neon
- qtkeychain
- libmatrixclient
parse-info:
- usr/share/metainfo/org.kde.neochat.appdata.xml
source: .
source-type: local
plugin: cmake
build-packages:
- cmark
- gcc-10
- g++-10
- libcmark-dev
- kquickimageeditor-dev
- libkf5qqc2desktopstyle-dev
- qcoro-qt5-dev
- kirigami-addons-dev
- reuse
- libkf5doctools-dev
- qtbase5-private-dev
- qml-module-org-kde-kquickimageeditor
- qml-module-org-kde-qqc2desktopstyle
- kirigami-addons-data
- qml-module-org-kde-kirigamiaddons
- qml-module-org-kde-quickcharts
- libsqlite3-dev
- libolm-dev
stage-packages:
- libcmark0.30.2
- qml-module-org-kde-kquickimageeditor
- qml-module-org-kde-qqc2desktopstyle
- kirigami-addons-data
- qml-module-org-kde-kirigamiaddons
- qml-module-org-kde-quickcharts
- qml-module-org-kde-kirigami2
- reuse
- libsqlite3-0
- libolm3
cmake-parameters:
- "-DKDE_INSTALL_USE_QT_SYS_PATHS=FALSE"
- "-DCMAKE_INSTALL_PREFIX=/usr"
- "-DCMAKE_BUILD_TYPE=Release"
- "-DENABLE_TESTING=OFF"
- "-DBUILD_TESTING=OFF"
- "-DKDE_SKIP_TEST_SETTINGS=ON"
- "-DNEOCHAT_FLATPAK=ON"
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22-sdk/current"
- "-DKDE_INSTALL_PLUGINDIR=/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/plugins/"
prime:
- "-usr/lib/*/cmake/*"
- "-usr/include/*"
- "-usr/share/ECM/*"
- "-usr/share/doc/*"
- "-usr/share/man/*"
- "-usr/share/icons/breeze-dark*"
- "-usr/bin/X11"
- "-usr/lib/gcc/$CRAFT_ARCH_TRIPLET/6.0.0"
- "-usr/lib/aspell/*"
- "-usr/share/lintian"
build-environment: &id005
- *id001
- *id002
- *id003
- *id004
cleanup:
after:
- kde-neon
- neochat
plugin: nil
override-prime: |
set -eux
# find $CRAFT_PRIME/usr/share/doc/ -type f -not -name 'copyright' -delete
# find $CRAFT_PRIME/usr/share -type d -empty -delete | /bin/true
# # Unused libraries found by linter

View File

@@ -5,6 +5,7 @@
configure_file(qml/Page/RoomList/RoomDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Page/RoomList/RoomDelegate.qml)
configure_file(qml/Component/QuickSwitcher.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/QuickSwitcher.qml)
configure_file(qml/Dialog/UserDetailDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/UserDetailDialog.qml)
configure_file(qml/Dialog/PowerLevelDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/PowerLevelDialog.qml)
configure_file(qml/Component/Timeline/AudioDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/AudioDelegate.qml)
configure_file(qml/Component/Timeline/VideoDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/VideoDelegate.qml)
@@ -43,6 +44,8 @@ add_library(neochat STATIC
roommanager.h
neochatroom.cpp
neochatroom.h
neochatuser.cpp
neochatuser.h
models/userlistmodel.cpp
models/userlistmodel.h
models/userfiltermodel.cpp
@@ -124,7 +127,6 @@ add_library(neochat STATIC
locationhelper.h
events/pollevent.cpp
pollhandler.cpp
utils.h
)
ecm_qt_declare_logging_category(neochat
@@ -173,7 +175,7 @@ else()
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark QCoro::Core)
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
if(NEOCHAT_FLATPAK)

View File

@@ -35,15 +35,15 @@
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include <Quotient/csapi/logout.h>
#include <Quotient/csapi/notifications.h>
#include <Quotient/csapi/profile.h>
#include <Quotient/eventstats.h>
#include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h>
#include <Quotient/user.h>
#include <Quotient/csapi/notifications.h>
#include <Quotient/eventstats.h>
#include "neochatconfig.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
#include "roommanager.h"
#include "windowcontroller.h"
@@ -60,6 +60,7 @@ Controller::Controller(QObject *parent)
: QObject(parent)
{
Connection::setRoomType<NeoChatRoom>();
Connection::setUserType<NeoChatUser>();
setApplicationProxy();
@@ -531,7 +532,7 @@ void Controller::joinRoom(const QString &alias)
RoomManager::instance().joinRoom(m_connection, alias, QStringList{knownServer});
}
void Controller::openOrCreateDirectChat(User *user)
void Controller::openOrCreateDirectChat(NeoChatUser *user)
{
const auto existing = activeConnection()->directChats();
@@ -581,6 +582,11 @@ bool Controller::hasWindowSystem() const
#endif
}
bool Controller::encryptionSupported() const
{
return Quotient::encryptionSupported();
}
void Controller::forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item)
{
// HACK: Workaround bug QTBUG 93281

View File

@@ -14,6 +14,7 @@
#include <Quotient/settings.h>
class NeoChatRoom;
class NeoChatUser;
class TrayIcon;
class QWindow;
class QQuickTextDocument;
@@ -22,7 +23,6 @@ namespace Quotient
{
class Connection;
class Room;
class User;
}
namespace QKeychain
@@ -87,6 +87,11 @@ class Controller : public QObject
*/
Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged)
/**
* @brief Whether the ecryption support has been enabled.
*/
Q_PROPERTY(bool encryptionSupported READ encryptionSupported CONSTANT)
/**
* @brief The current minor version number of libQuotient being used.
*
@@ -178,7 +183,7 @@ public:
*
* If a direct chat with the user doesn't exist one is created and then joined.
*/
Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user);
[[nodiscard]] bool supportSystemTray() const;
@@ -189,6 +194,8 @@ public:
bool isOnline() const;
bool encryptionSupported() const;
/**
* @brief Sets the QNetworkProxy for the application.
*

View File

@@ -4,7 +4,6 @@
#include <QCommandLineParser>
#include <QIcon>
#include <QNetworkProxyFactory>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlNetworkAccessManagerFactory>
@@ -29,11 +28,10 @@
#include "neochat-version.h"
#include <Quotient/accountregistry.h>
#include <Quotient/keyverificationsession.h>
#include <Quotient/accountregistry.h>
#include <Quotient/networkaccessmanager.h>
#include <Quotient/room.h>
#include <Quotient/user.h>
#include <Quotient/util.h>
#include "actionshandler.h"
@@ -77,6 +75,7 @@
#include "models/webshortcutmodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
#include "pollhandler.h"
#include "roommanager.h"
@@ -89,6 +88,7 @@
#endif
#include "models/completionmodel.h"
#include "models/statemodel.h"
#include "neochatuser.h"
#ifdef HAVE_RUNNER
#include "runner.h"
@@ -185,8 +185,10 @@ int main(int argc, char *argv[])
initLogging();
#if Quotient_VERSION_MINOR == 8
#ifdef Quotient_E2EE_ENABLED
Connection::setEncryptionDefault(true);
#endif
#endif
#ifdef NEOCHAT_FLATPAK
// Copy over the included FontConfig configuration to the
@@ -259,23 +261,24 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM");
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM");
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
qmlRegisterUncreatableType<User>("org.kde.neochat", 1, 0, "User", {});
qmlRegisterUncreatableType<NeoChatUser>("org.kde.neochat", 1, 0, "NeoChatUser", {});
qmlRegisterUncreatableType<NeoChatRoom>("org.kde.neochat", 1, 0, "NeoChatRoom", {});
qRegisterMetaType<User *>("User*");
qRegisterMetaType<User *>("const User*");
qRegisterMetaType<User *>("const Quotient::User*");
qRegisterMetaType<RoomMember *>("RoomMember*");
qRegisterMetaType<Room *>("Room*");
qRegisterMetaType<Connection *>("Connection*");
qRegisterMetaType<MessageEventType>("MessageEventType");
qRegisterMetaType<NeoChatRoom *>("NeoChatRoom*");
qRegisterMetaType<User *>("User*");
qRegisterMetaType<NeoChatUser *>("NeoChatUser*");
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType");
#ifdef Quotient_E2EE_ENABLED
qRegisterMetaType<KeyVerificationSession *>("KeyVerificationSession*");
qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
qRegisterMetaType<QVector<EmojiEntry>>("QVector<EmojiEntry>");
#endif
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(KAboutData::applicationData());
});
@@ -322,18 +325,11 @@ int main(int argc, char *argv[])
QCommandLineParser parser;
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
parser.addOption(QCommandLineOption("ignore-ssl-errors", i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
about.setupCommandLine(&parser);
parser.process(app);
about.processCommandLine(&parser);
if (parser.isSet("ignore-ssl-errors")) {
QObject::connect(NetworkAccessManager::instance(), &QNetworkAccessManager::sslErrors, NetworkAccessManager::instance(), [](QNetworkReply *reply) {
reply->ignoreSslErrors();
});
}
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);

View File

@@ -65,6 +65,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
if (device.deviceId == m_connection->deviceId()) {
return This;
}
#ifdef Quotient_E2EE_ENABLED
if (!m_connection->isKnownE2eeCapableDevice(m_connection->userId(), device.deviceId)) {
return Unencrypted;
}
@@ -73,6 +74,9 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
} else {
return Unverified;
}
#else
return Unverified;
#endif
}
return {};
}
@@ -157,6 +161,7 @@ void DevicesModel::setConnection(Connection *connection)
Q_EMIT connectionChanged();
fetchDevices();
#ifdef Quotient_E2EE_ENABLED
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &userId, const QString &deviceId) {
Q_UNUSED(deviceId);
if (userId == Controller::instance().activeConnection()->userId()) {
@@ -166,6 +171,7 @@ void DevicesModel::setConnection(Connection *connection)
connect(m_connection, &Connection::finishedQueryingKeys, this, [this]() {
fetchDevices();
});
#endif
}
#include "moc_devicesmodel.cpp"

View File

@@ -8,8 +8,6 @@
#include <QDebug>
#include <cmath>
using namespace Quotient;
bool operator<(const LiveLocationData &lhs, const LiveLocationData &rhs)
@@ -90,11 +88,6 @@ QVariant LiveLocationsModel::data(const QModelIndex &index, int roleName) const
const auto timeout = data.beaconInfo.value("timeout"_ls).toDouble(600000);
return lastTs + timeout >= QDateTime::currentDateTime().toMSecsSinceEpoch();
}
case HeadingRole: {
bool success = false;
const auto heading = data.beacon["org.matrix.msc3488.location"_ls].toObject()["org.kde.itinerary.heading"_ls].toString().toDouble(&success);
return success ? heading : NAN;
}
}
return {};
@@ -108,7 +101,6 @@ QHash<int, QByteArray> LiveLocationsModel::roleNames() const
r.insert(AssetRole, "asset");
r.insert(AuthorRole, "author");
r.insert(IsLiveRole, "isLive");
r.insert(HeadingRole, "heading");
return r;
}

View File

@@ -49,7 +49,6 @@ public:
AssetRole, /**< Type of location event, e.g. self pin of the user location. */
AuthorRole, /**< The author of the event. */
IsLiveRole, /**< Boolean that indicates whether a live location beacon is still live. */
HeadingRole, /**< Heading in degree (not part of any MSC yet, using an Itinerary extension). */
};
Q_ENUM(Roles)

View File

@@ -3,8 +3,6 @@
#include "locationsmodel.h"
#include <QGuiApplication>
using namespace Quotient;
LocationsModel::LocationsModel(QObject *parent)
@@ -45,10 +43,6 @@ LocationsModel::LocationsModel(QObject *parent)
});
connect(this, &LocationsModel::rowsInserted, this, &LocationsModel::boundingBoxChanged);
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole});
});
}
void LocationsModel::addLocation(const RoomMessageEvent *event)
@@ -67,7 +61,7 @@ void LocationsModel::addLocation(const RoomMessageEvent *event)
.latitude = latitude,
.longitude = longitude,
.content = event->contentJson(),
.author = m_room->user(event->senderId()),
.author = dynamic_cast<NeoChatUser *>(m_room->user(event->senderId())),
};
endInsertRows();
}

View File

@@ -10,7 +10,6 @@
#include "neochatroom.h"
#include <Quotient/events/roommessageevent.h>
#include <Quotient/user.h>
class LocationsModel : public QAbstractListModel
{
@@ -52,7 +51,7 @@ private:
float latitude;
float longitude;
QJsonObject content;
Quotient::User *author;
NeoChatUser *author;
};
QList<LocationData> m_locations;
void addLocation(const Quotient::RoomMessageEvent *event);

View File

@@ -25,6 +25,7 @@
#include <KLocalizedString>
#include "models/reactionmodel.h"
#include "neochatuser.h"
#include "texthandler.h"
using namespace Quotient;
@@ -77,7 +78,7 @@ MessageEventModel::MessageEventModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReplyAuthor, ReadMarkersRole});
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReplyRole});
});
}
@@ -530,7 +531,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == AuthorRole) {
auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
return m_currentRoom->getUser(author);
}
@@ -678,7 +679,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
auto replyPtr = m_currentRoom->getReplyForEvent(evt);
if (replyPtr) {
auto replyUser = m_currentRoom->user(replyPtr->senderId());
auto replyUser = static_cast<NeoChatUser *>(m_currentRoom->user(replyPtr->senderId()));
return m_currentRoom->getUser(replyUser);
} else {
return m_currentRoom->getUser(nullptr);
@@ -807,7 +808,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
QVariantList users;
users.reserve(userIds.size());
for (const auto &userId : userIds) {
auto user = m_currentRoom->user(userId);
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
users += m_currentRoom->getUser(user);
}
@@ -835,7 +836,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
*/
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
for (const auto &userId : userIds) {
auto user = m_currentRoom->user(userId);
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
readMarkersString += user->displayname(m_currentRoom) + i18nc("list separator", ", ");
}
readMarkersString.chop(2);
@@ -865,16 +866,18 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == VerifiedRole) {
#ifdef Quotient_E2EE_ENABLED
if (evt.originalEvent()) {
auto encrypted = dynamic_cast<const EncryptedEvent *>(evt.originalEvent());
Q_ASSERT(encrypted);
return m_currentRoom->connection()->isVerifiedSession(encrypted->sessionId().toLatin1());
}
#endif
return false;
}
if (role == DisplayNameForInitialsRole) {
auto user = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
auto user = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
return user->displayname(m_currentRoom).remove(QStringLiteral(" (%1)").arg(user->id()));
}
@@ -886,7 +889,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
return previousDisplayName;
} else {
auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
return m_currentRoom->htmlSafeMemberName(author->id());
}
}
@@ -941,12 +944,12 @@ QVariantMap MessageEventModel::getMediaInfoFromFileInfo(const EventContent::File
QVariantMap mediaInfo;
// Get the mxc URL for the media.
if (!fileInfo->url().isValid() || eventId.isEmpty()) {
if (!fileInfo->url().isValid() || fileInfo->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
mediaInfo["source"] = QUrl();
} else {
QUrl source = m_currentRoom->makeMediaUrl(eventId, fileInfo->url());
if (source.isValid() && source.scheme() == QStringLiteral("mxc")) {
if (source.isValid()) {
mediaInfo["source"] = source;
} else {
mediaInfo["source"] = QUrl();
@@ -1059,13 +1062,13 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
return;
};
QMap<QString, QList<Quotient::User *>> reactions = {};
QMap<QString, QList<NeoChatUser *>> reactions = {};
for (const auto &a : annotations) {
if (a->isRedacted()) { // Just in case?
continue;
}
if (const auto &e = eventCast<const ReactionEvent>(a)) {
reactions[e->key()].append(m_currentRoom->user(e->senderId()));
reactions[e->key()].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId())));
}
}
@@ -1092,7 +1095,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
if (m_reactionModels.contains(eventId)) {
m_reactionModels[eventId]->setReactions(res);
} else if (res.size() > 0) {
m_reactionModels[eventId] = new ReactionModel(this, res, m_currentRoom->localUser());
m_reactionModels[eventId] = new ReactionModel(this, res, static_cast<NeoChatUser *>(m_currentRoom->localUser()));
} else {
if (m_reactionModels.contains(eventId)) {
delete m_reactionModels[eventId];

View File

@@ -7,9 +7,9 @@
#include <KLocalizedString>
#include <Quotient/user.h>
#include "neochatuser.h"
ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, Quotient::User *localUser)
ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, NeoChatUser *localUser)
: QAbstractListModel(parent)
, m_localUser(localUser)
{

View File

@@ -5,10 +5,7 @@
#include <QAbstractListModel>
namespace Quotient
{
class User;
}
class NeoChatUser;
/**
* @class ReactionModel
@@ -39,7 +36,7 @@ public:
HasLocalUser, /**< Whether the local user is in the list of authors. */
};
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, Quotient::User *localUser = nullptr);
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, NeoChatUser *localUser = nullptr);
/**
* @brief Get the given role value at the given index.
@@ -70,6 +67,6 @@ public:
private:
QList<Reaction> m_reactions;
Quotient::User *m_localUser;
NeoChatUser *m_localUser;
};
Q_DECLARE_METATYPE(ReactionModel *)

View File

@@ -5,14 +5,13 @@
#include "messageeventmodel.h"
#include "neochatroom.h"
#include <QGuiApplication>
#include <Quotient/connection.h>
#include "neochatuser.h"
#include <Quotient/events/stickerevent.h>
#include <KLocalizedString>
#include <Quotient/connection.h>
using namespace Quotient;
// TODO search only in the current room
@@ -20,9 +19,6 @@ using namespace Quotient;
SearchModel::SearchModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReadMarkersRole});
});
}
QString SearchModel::searchText() const
@@ -113,7 +109,7 @@ QVariant SearchModel::data(const QModelIndex &index, int role) const
return false;
case ReplyAuthorRole:
if (const auto &replyPtr = m_room->getReplyForEvent(event)) {
return m_room->getUser(m_room->user(replyPtr->senderId()));
return m_room->getUser(static_cast<NeoChatUser *>(m_room->user(replyPtr->senderId())));
} else {
return m_room->getUser(nullptr);
}

View File

@@ -109,7 +109,7 @@ void StickerModel::setRoom(NeoChatRoom *room)
void StickerModel::postSticker(int index)
{
const auto &image = m_images[index];
const auto &body = image.body ? *image.body : QString();
const auto &body = image.body ? *image.body : image.shortcode;
QJsonObject infoJson;
if (image.info) {
infoJson["w"] = image.info->imageSize.width();

View File

@@ -3,8 +3,6 @@
#include "userlistmodel.h"
#include <QGuiApplication>
#include <Quotient/connection.h>
#include <Quotient/events/roompowerlevelsevent.h>
@@ -16,9 +14,6 @@ UserListModel::UserListModel(QObject *parent)
: QAbstractListModel(parent)
, m_currentRoom(nullptr)
{
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this]() {
refreshAllUsers();
});
}
void UserListModel::setRoom(NeoChatRoom *room)
@@ -33,9 +28,11 @@ void UserListModel::setRoom(NeoChatRoom *room)
m_currentRoom = room;
if (m_currentRoom) {
connect(m_currentRoom, &Room::memberAdded, this, &UserListModel::memberAdded);
connect(m_currentRoom, &Room::memberRemoved, this, &UserListModel::memberRemoved);
connect(m_currentRoom, &Room::memberUpdated, this, &UserListModel::memberUpdated);
connect(m_currentRoom, &Room::userAdded, this, &UserListModel::userAdded);
connect(m_currentRoom, &Room::userRemoved, this, &UserListModel::userRemoved);
connect(m_currentRoom, &Room::memberAboutToRename, this, &UserListModel::userRemoved);
connect(m_currentRoom, &Room::memberRenamed, this, &UserListModel::userAdded);
connect(m_currentRoom, &Room::changed, this, &UserListModel::refreshAllUsers);
}
refreshAllUsers();
@@ -47,29 +44,38 @@ NeoChatRoom *UserListModel::room() const
return m_currentRoom;
}
Quotient::User *UserListModel::userAt(QModelIndex index) const
{
if (index.row() < 0 || index.row() >= m_users.size()) {
return nullptr;
}
return m_users.at(index.row());
}
QVariant UserListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= rowCount()) {
if (index.row() >= m_users.count()) {
qDebug() << "UserListModel, something's wrong: index.row() >= "
"users.count()";
return {};
}
auto user = m_members.at(index.row());
auto user = m_users.at(index.row());
if (role == DisplayNameRole) {
return user->displayName();
return user->displayname(m_currentRoom);
}
if (role == UserIdRole) {
return user->id();
}
if (role == AvatarRole) {
return user->avatarUrl();
auto neoChatUser = static_cast<NeoChatUser *>(user);
return m_currentRoom->avatarForMember(neoChatUser);
}
if (role == ObjectRole) {
return QVariant::fromValue<RoomMember *>(user.get());
return QVariant::fromValue(user);
}
if (role == PowerLevelRole) {
auto plEvent = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
@@ -108,47 +114,59 @@ int UserListModel::rowCount(const QModelIndex &parent) const
if (parent.isValid()) {
return 0;
}
return m_members.count();
return m_users.count();
}
void UserListModel::memberAdded(QString memberId)
void UserListModel::userAdded(Quotient::User *user)
{
if (m_currentRoom->memberIds().contains(memberId)) {
return;
}
beginInsertRows(QModelIndex(), m_currentRoom->memberIds().size(), m_currentRoom->memberIds().size());
auto pos = findUserPos(user);
beginInsertRows(QModelIndex(), pos, pos);
m_users.insert(pos, user);
endInsertRows();
connect(user, &User::defaultAvatarChanged, this, [this, user]() {
refreshUser(user, {AvatarRole});
});
}
void UserListModel::memberUpdated(QString memberId)
void UserListModel::userRemoved(Quotient::User *user)
{
if (!m_currentRoom->memberIds().contains(memberId)) {
return;
}
auto row = m_currentRoom->memberIds().indexOf(memberId);
if (row >= 0 && row < m_currentRoom->memberIds().size()) {
Q_EMIT dataChanged(index(row), index(row));
}
}
void UserListModel::memberRemoved(QString memberId)
{
if (!m_currentRoom->memberIds().contains(memberId)) {
return;
}
auto row = m_currentRoom->memberIds().indexOf(memberId);
if (row >= 0 && row < m_currentRoom->memberIds().size()) {
beginRemoveRows(QModelIndex(), row, row);
auto pos = findUserPos(user);
if (pos != m_users.size()) {
beginRemoveRows(QModelIndex(), pos, pos);
m_users.removeAt(pos);
endRemoveRows();
user->disconnect(this);
} else {
qWarning() << "Trying to remove a room member not in the user list";
}
}
void UserListModel::refreshUser(Quotient::User *user, const QVector<int> &roles)
{
auto pos = findUserPos(user);
if (pos != m_users.size()) {
Q_EMIT dataChanged(index(pos), index(pos), roles);
} else {
qWarning() << "Trying to access a room member not in the user list";
}
}
void UserListModel::refreshAllUsers()
{
beginResetModel();
m_members.clear();
m_members = m_currentRoom->members();
for (User *user : std::as_const(m_users)) {
user->disconnect(this);
}
m_users.clear();
m_users = m_currentRoom->users();
std::sort(m_users.begin(), m_users.end(), m_currentRoom->memberSorter());
for (User *user : std::as_const(m_users)) {
connect(user, &User::defaultAvatarChanged, this, [this, user]() {
refreshUser(user, {AvatarRole});
});
}
connect(m_currentRoom->connection(), &Connection::loggedOut, this, [this]() {
setRoom(nullptr);
});
@@ -156,6 +174,19 @@ void UserListModel::refreshAllUsers()
Q_EMIT usersRefreshed();
}
int UserListModel::findUserPos(Quotient::User *user) const
{
return findUserPos(m_currentRoom->safeMemberName(user->id()));
}
int UserListModel::findUserPos(const QString &username) const
{
if (!m_currentRoom) {
return 0;
}
return m_currentRoom->memberSorter().lowerBoundIndex(m_users, username);
}
QHash<int, QByteArray> UserListModel::roleNames() const
{
QHash<int, QByteArray> roles;

View File

@@ -54,6 +54,11 @@ public:
[[nodiscard]] NeoChatRoom *room() const;
void setRoom(NeoChatRoom *room);
/**
* @brief The user at the given index of the model.
*/
[[nodiscard]] Quotient::User *userAt(QModelIndex index) const;
/**
* @brief Get the given role value at the given index.
*
@@ -80,12 +85,15 @@ Q_SIGNALS:
void usersRefreshed();
private Q_SLOTS:
void memberAdded(QString memberId);
void memberUpdated(QString memberId);
void memberRemoved(QString memberId);
void userAdded(Quotient::User *user);
void userRemoved(Quotient::User *user);
void refreshUser(Quotient::User *user, const QVector<int> &roles = {});
void refreshAllUsers();
private:
QPointer<NeoChatRoom> m_currentRoom;
QList<QSharedPointer<Quotient::RoomMember>> m_members;
QList<Quotient::User *> m_users;
int findUserPos(Quotient::User *user) const;
[[nodiscard]] int findUserPos(const QString &username) const;
};

View File

@@ -116,7 +116,7 @@ Name[sk]=Nová správa
Name[sl]=Novo sporočilo
Name[sv]=Nytt meddelande
Name[ta]=புதிய செய்தி
Name[tr]=Yeni ileti
Name[tr]=Yeni İleti
Name[uk]=Нове повідомлення
Name[x-test]=xxNew messagexx
Name[zh_CN]=新消息

View File

@@ -4,10 +4,8 @@
#include "neochatroom.h"
#include <QFileInfo>
#include <QGuiApplication>
#include <QMetaObject>
#include <QMimeDatabase>
#include <QPalette>
#include <QTemporaryFile>
#include <QTextDocument>
@@ -15,7 +13,6 @@
#include <QMediaPlayer>
#include <Quotient/jobs/basejob.h>
#include <Quotient/user.h>
#include <qcoro/qcorosignal.h>
#include <Quotient/connection.h>
@@ -46,7 +43,6 @@
#include "neochatconfig.h"
#include "notificationsmanager.h"
#include "texthandler.h"
#include "utils.h"
#include <KConfig>
#include <KConfigGroup>
@@ -416,11 +412,11 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const
int count = 0;
for (const auto u : userList) {
if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) {
Quotient::User user(u->id(), u->connection());
NeoChatUser user(u->id(), u->connection());
QVariantMap userVariant{{QStringLiteral("id"), user.id()},
{QStringLiteral("displayName"), user.displayname(this)},
{QStringLiteral("avatarMediaId"), user.avatarMediaId(this)},
{QStringLiteral("color"), Utils::getUserColor(user.hueF())}};
{QStringLiteral("color"), user.color()}};
matchedList.append(QVariant::fromValue(userVariant));
count++;
@@ -446,10 +442,11 @@ static const QVariantMap emptyUser = {
QVariantMap NeoChatRoom::getUser(const QString &userID) const
{
return getUser(user(userID));
NeoChatUser *userObject = static_cast<NeoChatUser *>(user(userID));
return getUser(userObject);
}
QVariantMap NeoChatRoom::getUser(User *user) const
QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const
{
if (user == nullptr) {
return emptyUser;
@@ -461,7 +458,7 @@ QVariantMap NeoChatRoom::getUser(User *user) const
{QStringLiteral("displayName"), user->displayname(this)},
{QStringLiteral("avatarSource"), avatarForMember(user)},
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)},
{QStringLiteral("color"), Utils::getUserColor(user->hueF())},
{QStringLiteral("color"), user->color()},
{QStringLiteral("object"), QVariant::fromValue(user)},
};
}
@@ -542,7 +539,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
if (prettyPrint) {
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
.arg(e.userId(), Utils::getUserColor(user(e.userId())->hueF()).name(), subjectName);
.arg(e.userId(), static_cast<NeoChatUser *>(user(e.userId()))->color().name(), subjectName);
}
// The below code assumes senderName output in AuthorRole
@@ -1685,7 +1682,7 @@ QVariantMap NeoChatRoom::chatBoxReplyUser() const
if (m_chatBoxReplyId.isEmpty()) {
return emptyUser;
}
return getUser(user((*findInTimeline(m_chatBoxReplyId))->senderId()));
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxReplyId))->senderId())));
}
QString NeoChatRoom::chatBoxReplyMessage() const
@@ -1701,7 +1698,7 @@ QVariantMap NeoChatRoom::chatBoxEditUser() const
if (m_chatBoxEditId.isEmpty()) {
return emptyUser;
}
return getUser(user((*findInTimeline(m_chatBoxEditId))->senderId()));
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxEditId))->senderId())));
}
QString NeoChatRoom::chatBoxEditMessage() const
@@ -1812,7 +1809,10 @@ void NeoChatRoom::editLastMessage()
bool NeoChatRoom::canEncryptRoom() const
{
#ifdef Quotient_E2EE_ENABLED
return !usesEncryption() && canSendState("m.room.encryption");
#endif
return false;
}
PollHandler *NeoChatRoom::poll(const QString &eventId)
@@ -1904,10 +1904,9 @@ int NeoChatRoom::maxRoomVersion() const
}
return maxVersion;
}
Quotient::User *NeoChatRoom::directChatRemoteUser() const
NeoChatUser *NeoChatRoom::directChatRemoteUser() const
{
return connection()->directChatUsers(this)[0];
return dynamic_cast<NeoChatUser *>(connection()->directChatUsers(this)[0]);
}
void NeoChatRoom::sendLocation(float lat, float lon, const QString &description)
@@ -1939,7 +1938,7 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
return QJsonDocument(accountData(eventType)->fullJson()).toJson();
}
QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const
QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const
{
const auto &url = memberAvatarUrl(user->id());
if (url.isEmpty() || url.scheme() != "mxc"_ls) {

View File

@@ -10,15 +10,10 @@
#include <QTextCursor>
#include <QCoroTask>
#include <Quotient/user.h>
#include "neochatuser.h"
#include "pollhandler.h"
namespace Quotient
{
class User;
}
class PushNotificationState : public QObject
{
Q_OBJECT
@@ -69,7 +64,7 @@ class NeoChatRoom : public Quotient::Room
*
* The list does not include the local user.
*
* This is different to getting a list of Quotient::User objects
* This is different to getting a list of NeoChatUser objects or Quotient::User objects
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function
* provides the room context and puts the result as a list of QVariantMap objects.
@@ -81,7 +76,7 @@ class NeoChatRoom : public Quotient::Room
* - displayName - Display name in the context of this room.
* - display - Name in the context of this room.
*
* @sa Quotient::User
* @sa Quotient::User, NeoChatUser
*/
Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged)
@@ -124,7 +119,7 @@ class NeoChatRoom : public Quotient::Room
/**
* @brief Get a user object for the other person in a direct chat.
*/
Q_PROPERTY(Quotient::User *directChatRemoteUser READ directChatRemoteUser CONSTANT)
Q_PROPERTY(NeoChatUser *directChatRemoteUser READ directChatRemoteUser CONSTANT)
/**
* @brief If the room is a space.
@@ -186,6 +181,9 @@ class NeoChatRoom : public Quotient::Room
/**
* @brief Whether the local user can encrypt the room.
*
* Requires libQuotient 0.7 compiled with the Quotient_E2EE_ENABLED parameter to
* be able to return true.
*
* A local user can encrypt a room if they have permission to send the m.room.encryption
* state event.
*
@@ -318,7 +316,7 @@ class NeoChatRoom : public Quotient::Room
/**
* @brief Get the user for the message being replied to.
*
* This is different to getting a Quotient::User object
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room.
*
@@ -331,9 +329,9 @@ class NeoChatRoom : public Quotient::Room
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The Quotient::User object for the user.
* - object - The NeoChatUser object for the user.
*
* @sa getUser, Quotient::User
* @sa getUser, Quotient::User, NeoChatUser
*/
Q_PROPERTY(QVariantMap chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged)
@@ -347,7 +345,7 @@ class NeoChatRoom : public Quotient::Room
/**
* @brief Get the user for the message being edited.
*
* This is different to getting a Quotient::User object
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room.
*
@@ -360,9 +358,9 @@ class NeoChatRoom : public Quotient::Room
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The Quotient::User object for the user.
* - object - The NeoChatUser object for the user.
*
* @sa getUser, Quotient::User
* @sa getUser, Quotient::User, NeoChatUser
*/
Q_PROPERTY(QVariantMap chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged)
@@ -394,7 +392,7 @@ public:
/**
* @brief Get a list of users in the context of this room.
*
* This is different to getting a list of Quotient::User objects
* This is different to getting a list of NeoChatUser objects or Quotient::User objects
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function
* provides the room context and returns the result as a list of QVariantMap objects.
@@ -409,14 +407,14 @@ public:
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
*
* @sa Quotient::User
* @sa Quotient::User, NeoChatUser
*/
Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword, int limit = -1) const;
/**
* @brief Get a user in the context of this room.
*
* This is different to getting a Quotient::User object
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap.
@@ -433,16 +431,16 @@ public:
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The Quotient::User object for the user.
* - object - The NeoChatUser object for the user.
*
* @sa Quotient::User
* @sa Quotient::User, NeoChatUser
*/
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const;
/**
* @brief Get a user in the context of this room.
*
* This is different to getting a Quotient::User object
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap.
@@ -459,11 +457,11 @@ public:
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The Quotient::User object for the user.
* - object - The NeoChatUser object for the user.
*
* @sa Quotient::User
* @sa Quotient::User, NeoChatUser
*/
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(Quotient::User *user) const;
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(NeoChatUser *user) const;
[[nodiscard]] QVariantList getUsersTyping() const;
@@ -604,7 +602,7 @@ public:
[[nodiscard]] QString avatarMediaId() const;
Quotient::User *directChatRemoteUser() const;
NeoChatUser *directChatRemoteUser() const;
[[nodiscard]] bool isSpace();
@@ -820,7 +818,7 @@ public:
*/
Q_INVOKABLE QByteArray roomAcountDataJson(const QString &eventType);
Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(Quotient::User *user) const;
Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(NeoChatUser *user) const;
/**
* @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply.

43
src/neochatuser.cpp Normal file
View File

@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
// SPDX-License-Identifier: GPL-3.0-only
#include "neochatuser.h"
#include <QGuiApplication>
#include <QJsonObject>
#include <QPalette>
#include <Quotient/connection.h>
using namespace Quotient;
NeoChatUser::NeoChatUser(QString userId, Connection *connection)
: User(std::move(userId), connection)
{
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, &NeoChatUser::polishColor);
polishColor();
}
QColor NeoChatUser::color()
{
return m_color;
}
void NeoChatUser::setColor(const QColor &color)
{
if (m_color == color) {
return;
}
m_color = color;
Q_EMIT colorChanged(m_color);
}
void NeoChatUser::polishColor()
{
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
setColor(QColor::fromHslF(hueF(), 1, -0.7 * lightness + 0.9, 1));
}
#include "moc_neochatuser.cpp"

39
src/neochatuser.h Normal file
View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <QObject>
#include <Quotient/user.h>
/**
* @class NeoChatUser
*
* A class inherited from Quotient::User to add a user color function.
*
* @sa Quotient::User
*/
class NeoChatUser : public Quotient::User
{
Q_OBJECT
/**
* @brief The color to use for the user.
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
explicit NeoChatUser(QString userId, Quotient::Connection *connection);
public Q_SLOTS:
QColor color();
void setColor(const QColor &color);
Q_SIGNALS:
void colorChanged(QColor _t1);
private:
QColor m_color;
void polishColor();
};

View File

@@ -122,8 +122,10 @@ void NotificationsManager::processNotificationJob(QPointer<Quotient::Connection>
}
if (notification["event"]["type"] == "m.room.encrypted") {
#ifdef Quotient_E2EE_ENABLED
auto decrypted = connection->decryptNotification(notification);
body = decrypted["content"].toObject()["body"].toString();
#endif
if (body.isEmpty()) {
body = i18n("Encrypted Message");
}
@@ -291,7 +293,12 @@ QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoCha
roundedImage.fill(Qt::transparent);
QPainter painter(&roundedImage);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.setPen(Qt::NoPen);
// Fill background for transparent avatars
painter.setBrush(Qt::white);
painter.drawRoundedRect(imageRect, imageRect.width(), imageRect.height());
QBrush brush(icon.scaledToHeight(biggestDimension));
painter.setBrush(brush);
@@ -302,6 +309,9 @@ QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoCha
if (icon != roomAvatar) {
const QRect lowerQuarter{imageRect.center(), imageRect.size() / 2};
painter.setBrush(Qt::white);
painter.drawRoundedRect(lowerQuarter, lowerQuarter.width(), lowerQuarter.height());
painter.setBrush(roomAvatar.scaled(lowerQuarter.size()));
painter.drawRoundedRect(lowerQuarter, lowerQuarter.width(), lowerQuarter.height());
}

View File

@@ -28,6 +28,8 @@ Delegates.RoundedItemDelegate {
TapHandler {
acceptedButtons: Qt.RightButton
acceptedDevices: PointerDevice.Mouse
grabPermissions: PointerHandler.TakeOverForbidden
gesturePolicy: TapHandler.WithinBounds
onTapped: root.contextMenuRequested()
}

View File

@@ -36,7 +36,7 @@ QQC2.Control {
/**
* @brief The current room that user is viewing.
*/
required property NeoChatRoom currentRoom
property NeoChatRoom currentRoom
/**
* @brief The QQC2.TextArea object.
@@ -55,10 +55,10 @@ QQC2.Control {
Kirigami.Action {
id: attachmentAction
property bool isBusy: root.currentRoom && root.currentRoom.hasFileUploading
property bool isBusy: currentRoom && currentRoom.hasFileUploading
// Matrix does not allow sending attachments in replies
visible: root.currentRoom.chatBoxReplyId.length === 0 && root.currentRoom.chatBoxAttachmentPath.length === 0
visible: currentRoom.chatBoxReplyId.length === 0 && currentRoom.chatBoxAttachmentPath.length === 0
icon.name: "mail-attachment"
text: i18n("Attach an image or file")
displayHint: Kirigami.DisplayHint.IconOnly
@@ -72,7 +72,7 @@ QQC2.Control {
if (!path) {
return;
}
root.currentRoom.chatBoxAttachmentPath = path;
currentRoom.chatBoxAttachmentPath = path;
})
fileDialog.open()
}
@@ -85,19 +85,19 @@ QQC2.Control {
property bool isBusy: false
visible: !Kirigami.Settings.isMobile
icon.name: "smiley"
text: i18n("Emojis & Stickers")
displayHint: Kirigami.DisplayHint.IconOnly
checkable: true
onTriggered: {
if (emojiDialog.item.visible) {
emojiDialog.item.close()
if (emojiDialog.visible) {
emojiDialog.close()
} else {
emojiDialog.item.open()
emojiDialog.open()
}
}
tooltip: text
},
Kirigami.Action {
id: mapButton
@@ -107,8 +107,9 @@ QQC2.Control {
displayHint: QQC2.AbstractButton.IconOnly
onTriggered: {
locationChooserComponent.createObject(QQC2.ApplicationWindow.overlay, {room: root.currentRoom}).open()
locationChooserComponent.createObject(QQC2.ApplicationWindow.overlay, {room: currentRoom}).open()
}
tooltip: text
},
Kirigami.Action {
id: sendAction
@@ -163,11 +164,10 @@ QQC2.Control {
leftPadding: LayoutMirroring.enabled ? actionsRow.width : Kirigami.Units.largeSpacing
rightPadding: LayoutMirroring.enabled ? Kirigami.Units.largeSpacing : actionsRow.width + x * 2 + Kirigami.Units.largeSpacing * 2
placeholderText: root.currentRoom.usesEncryption ? i18n("Send an encrypted message…") : root.currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
placeholderText: readOnly ? i18n("This room is encrypted. Build libQuotient with encryption enabled to send encrypted messages.") : currentRoom.usesEncryption ? i18n("Send an encrypted message…") : currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
verticalAlignment: TextEdit.AlignVCenter
wrapMode: Text.Wrap
Accessible.description: placeholderText
readOnly: (currentRoom.usesEncryption && !Controller.encryptionSupported)
Timer {
id: repeatTimer
@@ -177,10 +177,10 @@ QQC2.Control {
onTextChanged: {
if (!repeatTimer.running && Config.typingNotifications) {
var textExists = text.length > 0
root.currentRoom.sendTypingNotification(textExists)
currentRoom.sendTypingNotification(textExists)
textExists ? repeatTimer.start() : repeatTimer.stop()
}
root.currentRoom.chatBoxText = text
currentRoom.chatBoxText = text
}
onCursorRectangleChanged: chatBarScrollView.ensureVisible(cursorRectangle)
onSelectedTextChanged: {
@@ -207,7 +207,7 @@ QQC2.Control {
remove(cursorPosition, cursorPosition + 1)
}
if (textField.text == selectedText || textField.text.length <= 1) {
root.currentRoom.sendTypingNotification(false)
currentRoom.sendTypingNotification(false)
repeatTimer.stop()
}
if (quickFormatBar.visible) {
@@ -237,20 +237,20 @@ QQC2.Control {
completionMenu.complete()
}
}
Keys.onPressed: {
Keys.onPressed: (event) => {
if (event.key === Qt.Key_V && event.modifiers & Qt.ControlModifier) {
root.pasteImage();
event.accepted = root.pasteImage();
} else if (event.key === Qt.Key_Up && event.modifiers & Qt.ControlModifier) {
root.currentRoom.replyLastMessage();
currentRoom.replyLastMessage();
} else if (event.key === Qt.Key_Up && textField.text.length === 0) {
root.currentRoom.editLastMessage();
currentRoom.editLastMessage();
} else if (event.key === Qt.Key_Up && completionMenu.visible) {
completionMenu.decrementIndex()
} else if (event.key === Qt.Key_Down && completionMenu.visible) {
completionMenu.incrementIndex()
} else if (event.key === Qt.Key_Backspace) {
if (textField.text == selectedText || textField.text.length <= 1) {
root.currentRoom.sendTypingNotification(false)
currentRoom.sendTypingNotification(false)
repeatTimer.stop()
}
if (quickFormatBar.visible && selectedText.length > 0) {
@@ -282,19 +282,19 @@ QQC2.Control {
Component {
id: replyPane
ReplyPane {
userName: root.currentRoom.chatBoxReplyUser.displayName
userColor: root.currentRoom.chatBoxReplyUser.color
userAvatar: root.currentRoom.chatBoxReplyUser.avatarSource
text: root.currentRoom.chatBoxReplyMessage
userName: currentRoom.chatBoxReplyUser.displayName
userColor: currentRoom.chatBoxReplyUser.color
userAvatar: currentRoom.chatBoxReplyUser.avatarSource
text: currentRoom.chatBoxReplyMessage
}
}
Component {
id: attachmentPane
AttachmentPane {
attachmentPath: root.currentRoom.chatBoxAttachmentPath
attachmentPath: currentRoom.chatBoxAttachmentPath
onAttachmentCancelled: {
root.currentRoom.chatBoxAttachmentPath = "";
currentRoom.chatBoxAttachmentPath = "";
root.forceActiveFocus()
}
}
@@ -346,8 +346,8 @@ QQC2.Control {
text: i18nc("@action:button", "Cancel reply")
icon.name: "dialog-close"
onTriggered: {
root.currentRoom.chatBoxReplyId = "";
root.currentRoom.chatBoxAttachmentPath = "";
currentRoom.chatBoxReplyId = "";
currentRoom.chatBoxAttachmentPath = "";
root.forceActiveFocus()
}
}
@@ -384,32 +384,28 @@ QQC2.Control {
QQC2.ToolTip.visible: modelData.tooltip !== "" && hoverHandler.hovered
QQC2.ToolTip.text: modelData.tooltip
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
HoverHandler { id: hoverHandler }
PieProgressBar {
visible: modelData.isBusy
progress: root.currentRoom.fileUploadingProgress
progress: currentRoom.fileUploadingProgress
}
}
}
}
Loader {
EmojiDialog {
id: emojiDialog
active: !Kirigami.Settings.isMobile
sourceComponent: EmojiDialog {
x: root.width - width
y: -implicitHeight // - Kirigami.Units.smallSpacing
x: parent.width - width
y: -implicitHeight // - Kirigami.Units.smallSpacing
modal: false
includeCustom: true
closeOnChosen: false
modal: false
includeCustom: true
closeOnChosen: false
currentRoom: root.currentRoom
onChosen: insertText(emoji)
onClosed: if (emojiAction.checked) emojiAction.checked = false
}
onChosen: insertText(emoji)
onClosed: if (emojiButton.checked) emojiButton.checked = false
}
background: Rectangle {
@@ -471,17 +467,18 @@ QQC2.Control {
function pasteImage() {
let localPath = Clipboard.saveImage();
if (localPath.length === 0) {
return;
return false;
}
root.currentRoom.chatBoxAttachmentPath = localPath
root.currentRoom.chatBoxAttachmentPath = localPath;
return true;
}
function postMessage() {
actionsHandler.handleNewMessage();
repeatTimer.stop()
root.currentRoom.markAllMessagesAsRead();
currentRoom.markAllMessagesAsRead();
textField.clear();
root.currentRoom.chatBoxReplyId = "";
currentRoom.chatBoxReplyId = "";
messageSent()
}

View File

@@ -30,12 +30,12 @@ import org.kde.neochat 1.0
* @sa ChatBar
*/
ColumnLayout {
id: root
id: chatBox
/**
* @brief The current room that user is viewing.
*/
required property NeoChatRoom currentRoom
property NeoChatRoom currentRoom
/**
* @brief A message has been sent from the chat bar.
@@ -63,7 +63,7 @@ ColumnLayout {
ChatBar {
id: chatBar
visible: root.currentRoom.canSendEvent("m.room.message")
visible: currentRoom.canSendEvent("m.room.message")
Layout.fillWidth: true
Layout.minimumHeight: Math.max(Kirigami.Units.gridUnit * 2, implicitHeight + Kirigami.Units.largeSpacing)
@@ -78,7 +78,7 @@ ColumnLayout {
}
onMessageSent: {
root.messageSent();
chatBox.messageSent();
}
}

View File

@@ -10,11 +10,6 @@ import org.kde.neochat 1.0
ColumnLayout {
id: root
/**
* @brief The current room that user is viewing.
*/
property NeoChatRoom currentRoom
property bool includeCustom: false
property bool showQuickReaction: false
@@ -156,7 +151,7 @@ ColumnLayout {
ImagePacksModel {
id: stickerPackModel
room: root.currentRoom
room: currentRoom
showStickers: true
showEmoticons: false
}
@@ -165,7 +160,7 @@ ColumnLayout {
id: stickerModel
model: stickerPackModel
packIndex: 0
room: root.currentRoom
room: currentRoom
}
EmoticonFilterModel {

View File

@@ -26,14 +26,20 @@ QQC2.Popup {
padding: 2
modal: true
dim: true
clip: false
onOpened: x = Math.min(parent.mapFromGlobal(QQC2.Overlay.overlay.width - tones.width, 0).x, -(width - parent.width) / 2)
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: 1
radius: Kirigami.Units.mediumSpacing
shadow {
size: Kirigami.Units.largeSpacing
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
yOffset: 2
}
border {
color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
width: 1
}
}
ListView {

View File

@@ -46,7 +46,6 @@ ApplicationWindow {
asset: root.asset
author: root.author
isLive: true
heading: NaN
visible: !isNaN(root.latitude) && !isNaN(root.longitude)
}
MapItemView {

View File

@@ -6,7 +6,6 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
/**
* @brief A component that provides a set of actions when a message is hovered in the timeline.
@@ -17,11 +16,6 @@ import org.kde.neochat 1.0
QQC2.Control {
id: root
/**
* @brief The current room that user is viewing.
*/
required property NeoChatRoom currentRoom
/**
* @brief Whether the actions should be shown.
*/
@@ -114,7 +108,6 @@ QQC2.Control {
EmojiDialog {
id: emojiDialog
currentRoom: root.currentRoom
showQuickReaction: true
onChosen: (emoji) => root.reactClicked(emoji)
}

View File

@@ -24,14 +24,11 @@ MapQuickItem {
required property bool isLive
required property real heading
anchorPoint.x: sourceItem.width / 2
anchorPoint.y: sourceItem.height
coordinate: QtPositioning.coordinate(root.latitude, root.longitude)
autoFadeIn: false
sourceItem: Kirigami.Icon {
id: mainIcon
width: height
height: Kirigami.Units.iconSizes.huge
source: "gps"
@@ -58,19 +55,5 @@ MapQuickItem {
source: root.author.avatarSource
color: root.author.color
}
Kirigami.Icon {
id: headingIcon
source: "go-up-symbolic"
color: parent.color
visible: !isNaN(root.heading) && root.isLive
anchors.bottom: mainIcon.top
anchors.horizontalCenter: mainIcon.horizontalCenter
transform: Rotation {
origin.x: headingIcon.width/2
origin.y: headingIcon.height + mainIcon.height/2
angle: root.heading
}
}
}
}

View File

@@ -36,7 +36,6 @@ Kirigami.Page {
}
delegate: LocationMapItem {
isLive: true
heading: NaN
}
}

View File

@@ -28,7 +28,6 @@ LoginStep {
id: matrixIdField
Kirigami.FormData.label: i18n("Matrix ID:")
placeholderText: "@user:matrix.org"
Accessible.name: i18n("Matrix ID")
onTextChanged: {
LoginHelper.matrixId = text
}

View File

@@ -38,7 +38,6 @@ LoginStep {
id: passwordField
onTextChanged: LoginHelper.password = text
enabled: !LoginHelper.isLoggingIn
Accessible.name: i18n("Password")
Component.onCompleted: {
passwordField.forceActiveFocus()

View File

@@ -57,7 +57,6 @@ TimelineContainer {
asset: root.asset
author: root.author
isLive: true
heading: NaN
}
TapHandler {

View File

@@ -50,12 +50,6 @@ TimelineContainer {
isReply: root.isReply
textMessage: root.display
TapHandler {
enabled: !label.hoveredLink
acceptedButtons: Qt.LeftButton
onLongPressed: root.openContextMenu()
}
}
Loader {
Layout.fillWidth: true

View File

@@ -34,9 +34,9 @@ Item {
* - displayName - The display name of the reply author.
* - display - The name of the reply author.
* - color - The color for the reply author.
* - object - The Quotient::User object for the reply author.
* - object - The NeoChatUser object for the reply author.
*
* @sa Quotient::User
* @sa NeoChatUser
*/
required property var author

View File

@@ -54,9 +54,9 @@ ColumnLayout {
* - displayName - The display name of the author.
* - display - The name of the author.
* - color - The color for the author.
* - object - The Quotient::User object for the author.
* - object - The NeoChatUser object for the author.
*
* @sa Quotient::User
* @sa NeoChatUser
*/
required property var author
@@ -137,9 +137,9 @@ ColumnLayout {
* - displayName - The display name of the reply author.
* - display - The name of the reply author.
* - color - The color for the reply author.
* - object - The Quotient::User object for the reply author.
* - object - The NeoChatUser object for the reply author.
*
* @sa Quotient::User
* @sa NeoChatUser
*/
required property var replyAuthor
@@ -485,7 +485,7 @@ ColumnLayout {
Layout.maximumWidth: contentMaxWidth
active: root.isReply && root.reply
active: root.isReply
visible: active
sourceComponent: ReplyComponent {
@@ -518,7 +518,8 @@ ColumnLayout {
visible: cardBackground && !Config.compactLayout
anchors.fill: parent
Kirigami.Theme.colorSet: Kirigami.Theme.View
color: if (root.author.isLocalUser) {
Kirigami.Theme.inherit: false
color: if (root.author.isLocalUser) {
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15)
} else if (root.showHighlight) {
return Kirigami.Theme.positiveBackgroundColor

View File

@@ -16,19 +16,9 @@ import org.kde.neochat 1.0
QQC2.ScrollView {
id: root
required property NeoChatRoom currentRoom
onCurrentRoomChanged: {
roomChanging = true;
applicationWindow().hoverLinkIndicator.text = "";
messageListView.positionViewAtBeginning();
hasScrolledUpBefore = false;
roomChanging = true;
}
property bool roomChanging: false
readonly property bool isLoaded: root.width * root.height > 10
readonly property bool atYEnd: messageListView.atYEnd
/// Used to determine if scrolling to the bottom should mark the message as unread
property bool hasScrolledUpBefore: false;
signal focusChatBox()
ListView {
@@ -48,7 +38,7 @@ QQC2.ScrollView {
interactive: Kirigami.Settings.isMobile
bottomMargin: Kirigami.Units.largeSpacing + Math.round(Kirigami.Theme.defaultFont.pointSize * 2)
model: collapseStateProxyModel
model: !isLoaded ? undefined : collapseStateProxyModel
MessageEventModel {
id: messageEventModel
@@ -80,15 +70,13 @@ QQC2.ScrollView {
messageEventModel.fetchMore(messageEventModel.index(0, 0));
}
onAtYEndChanged: if (!root.roomChanging) {
if (atYEnd && root.hasScrolledUpBefore) {
if (QQC2.ApplicationWindow.window && (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden)) {
root.currentRoom.markAllMessagesAsRead();
}
root.hasScrolledUpBefore = false;
} else if (!atYEnd) {
root.hasScrolledUpBefore = true;
onAtYEndChanged: if (atYEnd && hasScrolledUpBefore) {
if (QQC2.ApplicationWindow.window && (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden)) {
root.currentRoom.markAllMessagesAsRead();
}
hasScrolledUpBefore = false;
} else if (!atYEnd) {
hasScrolledUpBefore = true;
}
// Not rendered because the sections are part of the TimelineContainer.qml, this is only so that items have the section property available for use by sectionBanner.
@@ -322,7 +310,6 @@ QQC2.ScrollView {
y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0
width: delegate ? delegate.bubbleWidth : Kirigami.Units.gridUnit * 4
currentRoom: root.currentRoom
showActions: delegate && delegate.hovered
verified: delegate && delegate.verified
editable: delegate && delegate.author.isLocalUser && (delegate.delegateType === MessageEventModel.Emote || delegate.delegateType === MessageEventModel.Message)

View File

@@ -11,11 +11,6 @@ import org.kde.neochat 1.0
QQC2.Popup {
id: emojiPopup
/**
* @brief The current room that user is viewing.
*/
property NeoChatRoom currentRoom
property bool includeCustom: false
property bool closeOnChosen: true
property bool showQuickReaction: false
@@ -39,15 +34,21 @@ QQC2.Popup {
background: Kirigami.ShadowedRectangle {
Kirigami.Theme.colorSet: Kirigami.Theme.View
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: 2
radius: Kirigami.Units.mediumSpacing
shadow {
size: Kirigami.Units.largeSpacing
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
yOffset: 2
}
border {
color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
width: 2
}
}
modal: true
focus: true
clip: false
closePolicy: QQC2.Popup.CloseOnEscape | QQC2.Popup.CloseOnPressOutsideParent
margins: 0
padding: 2
@@ -57,7 +58,6 @@ QQC2.Popup {
contentItem: EmojiPicker {
id: emojiPicker
height: 400
currentRoom: root.currentRoom
includeCustom: emojiPopup.includeCustom
showQuickReaction: emojiPopup.showQuickReaction
onChosen: {

View File

@@ -11,7 +11,7 @@ import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
Kirigami.Dialog {
Kirigami.OverlaySheet {
id: root
signal closed()
@@ -26,9 +26,6 @@ Kirigami.Dialog {
topPadding: 0
bottomPadding: 0
standardButtons: Kirigami.Dialog.NoButton
width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24)
title: i18nc("@title:menu Account detail dialog", "Account detail")
contentItem: ColumnLayout {
@@ -61,6 +58,7 @@ Kirigami.Dialog {
elide: Text.ElideRight
wrapMode: Text.NoWrap
text: user.displayName
textFormat: Text.PlainText
}
Kirigami.SelectableLabel {
@@ -199,5 +197,10 @@ Kirigami.Dialog {
}
}
}
@OVERLAYSHEET_OPEN@: {
if (!sheetOpen) {
closed()
}
}
}

View File

@@ -24,7 +24,9 @@ Labs.MenuBar {
text: i18nc("menu", "Configure NeoChat...")
shortcut: StandardKey.Preferences
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {
connection: Controller.activeConnection
}, {
title: i18n("Configure")
})
}

View File

@@ -7,6 +7,8 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: banSheet

View File

@@ -7,6 +7,8 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: reportSheet

View File

@@ -193,12 +193,6 @@ Kirigami.Page {
width: Kirigami.Units.iconSizes.small
height: Kirigami.Units.iconSizes.small
}
text: roomListModel.categoryVisible(section) ? i18nc("Collapse <section name>", "Collapse %1", roomListModel.categoryName(section)) : i18nc("Expand <section name", "Expand %1", roomListModel.categoryName(section))
display: QQC2.Button.IconOnly
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
onClicked: roomListModel.setCategoryVisible(section, !roomListModel.categoryVisible(section))
}

View File

@@ -31,8 +31,6 @@ Delegates.RoundedItemDelegate {
readonly property bool hasNotifications: notificationCount > 0
Accessible.name: root.displayName
onPressAndHold: createRoomListContextMenu()
TapHandler {

View File

@@ -72,7 +72,12 @@ QQC2.Control {
connection: Controller.activeConnection
}
}
onCountChanged: root.enabled = count > 0
onCountChanged: {
root.enabled = count > 0
if (!Controller.activeConnection.room(root.selectedSpaceId)) {
root.selectedSpaceId = ""
}
}
Component.onCompleted: root.enabled = count > 0
delegate: AvatarTabButton {

View File

@@ -24,11 +24,13 @@ Loader {
QQC2.Menu {
QQC2.MenuItem {
text: i18nc("'Space' is a matrix space", "View Space")
icon.name: "view-list-details"
onTriggered: RoomManager.enterRoom(room);
}
QQC2.MenuItem {
text: i18nc("@action:inmenu", "Copy Address to Clipboard")
icon.name: "edit-copy"
onTriggered: if (room.canonicalAlias.length === 0) {
Clipboard.saveText(room.id)
} else {
@@ -38,6 +40,7 @@ Loader {
QQC2.MenuItem {
text: i18nc("'Space' is a matrix space", "Space Settings")
icon.name: 'settings-configure'
onTriggered: QQC2.ApplicationWindow.window.pageStack.pushDialogLayer('qrc:/Categories.qml', {room: room}, { title: i18n("Space Settings") })
}
@@ -45,12 +48,13 @@ Loader {
QQC2.MenuItem {
text: i18nc("'Space' is a matrix space", "Leave Space")
icon.name: "go-previous"
onTriggered: RoomManager.leaveRoom(room)
}
onClosed: {
root.closed()
destroy()
regularMenu.destroy()
}
}
}

View File

@@ -95,7 +95,7 @@ QQC2.ToolBar {
}
}
width: parent.width
Layout.fillWidth: true
Layout.preferredHeight: contentHeight
delegate: Delegates.RoundedItemDelegate {
id: userDelegate

View File

@@ -19,17 +19,25 @@ Kirigami.Page {
/// Not readonly because of the separate window view.
property NeoChatRoom currentRoom: RoomManager.currentRoom
property bool loading: !root.currentRoom || (root.currentRoom.timelineSize === 0 && !root.currentRoom.allHistoryLoaded)
/// Used to determine if scrolling to the bottom should mark the message as unread
property bool hasScrolledUpBefore: false;
/// Disable cancel shortcut. Used by the separate window since it provides its own cancel implementation.
property bool disableCancelShortcut: false
title: root.currentRoom.displayName
title: currentRoom.displayName
focus: true
padding: 0
KeyNavigation.left: pageStack.get(0)
onCurrentRoomChanged: {
if (!timelineViewLoader.item) {
return
}
applicationWindow().hoverLinkIndicator.text = "";
timelineViewLoader.item.positionViewAtBeginning();
hasScrolledUpBefore = false;
if (!Kirigami.Settings.isMobile && chatBoxLoader.item) {
chatBoxLoader.item.forceActiveFocus();
}
@@ -38,7 +46,7 @@ Kirigami.Page {
Connections {
target: Controller
function onIsOnlineChanged() {
if (true || !Controller.isOnline) {
if (!Controller.isOnline) {
banner.text = i18n("NeoChat is offline. Please check your network connection.");
banner.visible = true;
banner.type = Kirigami.MessageType.Error;
@@ -58,7 +66,7 @@ Kirigami.Page {
Loader {
id: timelineViewLoader
anchors.fill: parent
active: root.currentRoom && !root.currentRoom.isInvite && !root.loading
active: currentRoom && !currentRoom.isInvite && !root.loading
sourceComponent: TimelineView {
id: timelineView
currentRoom: root.currentRoom
@@ -72,7 +80,7 @@ Kirigami.Page {
Loader {
id: invitationLoader
active: root.currentRoom && root.currentRoom.isInvite
active: currentRoom && currentRoom.isInvite
anchors.centerIn: parent
sourceComponent: InvitationView {
currentRoom: root.currentRoom
@@ -98,7 +106,7 @@ Kirigami.Page {
sourceComponent: ChatBox {
id: chatBox
width: parent.width
currentRoom: root.currentRoom
currentRoom: currentRoom
onMessageSent: {
if (!timelineViewLoader.item.atYEnd) {
timelineViewLoader.item.goToLastMessage();
@@ -132,9 +140,9 @@ Kirigami.Page {
Shortcut {
sequence: StandardKey.Cancel
onActivated: {
if (!timelineViewLoader.item.atYEnd || root.currentRoom.hasUnreadMessages) {
if (!timelineViewLoader.item.atYEnd || currentRoom.hasUnreadMessages) {
goToLastMessage();
root.currentRoom.markAllMessagesAsRead();
currentRoom.markAllMessagesAsRead();
} else {
applicationWindow().pageStack.get(0).forceActiveFocus();
}

View File

@@ -61,6 +61,7 @@ ColumnLayout {
Layout.fillWidth: true
text: room ? room.displayName : i18n("No name")
textFormat: Text.PlainText
wrapMode: Text.Wrap
}
Kirigami.SelectableLabel {

View File

@@ -156,7 +156,8 @@ Kirigami.OverlayDrawer {
Layout.fillWidth: true
onClicked: {
applicationWindow().pageStack.pushDialogLayer("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")})
applicationWindow().pageStack.layers.push("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")})
roomDrawer.close();
}
}
@@ -228,7 +229,8 @@ Kirigami.OverlayDrawer {
icon.name: "list-add-user"
onClicked: {
applicationWindow().pageStack.pushDialogLayer("qrc:/InviteUserPage.qml", {room: roomDrawer.room}, {title: i18nc("@title", "Invite a User")})
applicationWindow().pageStack.layers.push("qrc:/InviteUserPage.qml", {room: roomDrawer.room})
roomDrawer.close();
}
QQC2.ToolTip.text: i18n("Invite user to room")

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