Compare commits

...

155 Commits

Author SHA1 Message Date
Tobias Fella
ebd521e2ee Don't crash when leaving an opened room
Should fix #568
2023-01-29 13:51:52 +00:00
Tobias Fella
9d5303113e Close login window after the account is loaded 2023-01-29 09:26:09 +00:00
l10n daemon script
3850fe15a5 GIT_SILENT Sync po/docbooks with svn 2023-01-29 02:21:51 +00:00
Tobias Fella
5392481d06 Try fixing sqlite on android 2023-01-28 23:50:14 +01:00
Tobias Fella
0ce048517b Update gitignore 2023-01-28 22:57:15 +01:00
James Graham
c51e16e16c Add basic video controls
Add play, volume and duration slider

![image](/uploads/e85c6685c3d81c7a3839727a995b816f/image.png)
2023-01-28 19:17:17 +00:00
Joshua Goins
765a95050d Replace deprecated usage of iconName with icon.name 2023-01-28 17:48:45 +00:00
l10n daemon script
38dcefffcb GIT_SILENT Sync po/docbooks with svn 2023-01-28 02:22:22 +00:00
Carl Schwan
391b61dcb4 Bump cmake version to 23.01
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
2023-01-27 20:47:44 +00:00
Tobias Fella
d76c9fcbcf Add release notes for 23.01 2023-01-27 20:47:44 +00:00
Tobias Fella
f7b8ae2af2 Link against sqlite on android
This is needed to ensure that the sqlite lib is packaged into the apk
2023-01-27 21:33:57 +01:00
l10n daemon script
ddbf9b60d4 GIT_SILENT Sync po/docbooks with svn 2023-01-27 02:17:55 +00:00
James Graham
8948ff5faa Add padding to the right of the timeline delegate highlight same as left 2023-01-26 15:50:52 +00:00
l10n daemon script
d270e202a8 GIT_SILENT Sync po/docbooks with svn 2023-01-26 02:09:20 +00:00
l10n daemon script
61e1dd14ba GIT_SILENT Sync po/docbooks with svn 2023-01-25 02:22:18 +00:00
James Graham
eee93e0f1f Chatbar Refactor
This is mostly a stylistic rework of the chatbar but there are some buxfixes / improvements in here as well. The aim was to make the chatbar so it's size was managed in the same manner as the timeline in both bubble and compactmode in the same manner as network/neochat!476.

The other features are:
- Replies, attachments and edits now look like they are inside the chatbar and use a similar styling to edits in message bubbles
- Replies and edits now part of the message so they arte part of the ScrollView and will scroll away when the text is long
- ~~The emoji picker is now a popup so it doesn't mess with the timeline layout when activated~~ (done in network/neochat!697)
- ~~Emoji dialog is now no longer required as the picker itself is a popup now~~ (no longer the case see above)
- The scrollbar now sits on the right of the chatbar actions rather than weirdly to the left
- The action icons will always stay in the same place even as the chatbar gets taller


Updated\
![2022-12-10_14-13-41.mkv](/uploads/ccbe14843834a19bf98ef0028e023eae/2022-12-10_14-13-41.mkv)

Scrollbar behaviour before
![chatbar_refactor_scrollbar_before](/uploads/2f3b91a79eb302ccf83dd35e51004e6a/chatbar_refactor_scrollbar_before.png)

Scrollbar behaviour after
![chatbar_refactor_scrollbar_after](/uploads/fcab044d8a4338ed9bcff6721b65e89c/chatbar_refactor_scrollbar_after.png)
2023-01-24 18:02:19 +00:00
l10n daemon script
826760a55c GIT_SILENT Sync po/docbooks with svn 2023-01-24 02:18:50 +00:00
Tamara Schmitz
749398df8f remove execute bit from LICENSE file 2023-01-23 11:29:01 +01:00
l10n daemon script
150968d226 GIT_SILENT Sync po/docbooks with svn 2023-01-23 02:10:28 +00:00
l10n daemon script
d81df24e7c 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-01-23 01:56:42 +00:00
James Graham
594a5cf6ca Move the qt models to their own folder
Felt like the src folder was getting a bit crowded so move all the models to a folder named models.
2023-01-22 21:33:30 +00:00
Joshua Goins
0af420b824 Improve link regex to fix handling paranthesis and question marks
This patch fixes two key issues:
* `?` is considered part of the URL, even if there might not be anything past it. I've seen people now putting spaces after URLs to get around this issue.
* `)` is also part of the URL, as well as `:` despite those not being valid characters at the end of URLs.
2023-01-22 18:35:31 +00:00
l10n daemon script
31fed8362a GIT_SILENT Sync po/docbooks with svn 2023-01-22 02:19:48 +00:00
Joshua Goins
dbcf8c6327 Change placeholder text to make it clear that it's going to be a caption
When sending an image as an attachment, the message you type into the
chat box becomes its caption. However, it's not clear when in the chat
box itself, which confusingly says you're typing a message.
2023-01-21 22:10:50 +00:00
l10n daemon script
8012392400 GIT_SILENT Sync po/docbooks with svn 2023-01-21 02:13:08 +00:00
l10n daemon script
3e48578b44 GIT_SILENT Sync po/docbooks with svn 2023-01-20 02:15:42 +00:00
Nicolas Fella
d7e656e57f Activate window first thing when clicking on notification
Currently we enter the room first, which introduces a noticeable delay between clicking the notification and the window being activated
2023-01-19 17:56:26 +00:00
Volker Krause
8e83b923d9 Adapt APK build to Qt 5.15.8
This should fix the binary factory build, but it unfortunately not backward
compatible below Qt 5.15.8. Qt 6 will need the same changes anyway, so it's
not all bad at least.
2023-01-19 17:17:47 +01:00
l10n daemon script
a739f0f09f GIT_SILENT Sync po/docbooks with svn 2023-01-19 02:26:37 +00:00
Gary Wang
bc74737b0f Avoid logout when loginError caused by network error 2023-01-18 12:01:10 +08:00
l10n daemon script
e92fccf904 GIT_SILENT Sync po/docbooks with svn 2023-01-18 02:12:14 +00:00
l10n daemon script
20cbedfff5 GIT_SILENT Sync po/docbooks with svn 2023-01-17 02:30:38 +00:00
Xaver Hugl
e0d508d3dd hide the time header in chats if it would be transparent
Text over other text without a background is unreadable and looks horrible,
it's better to not have the header at all
2023-01-16 21:18:17 +01:00
l10n daemon script
af318a2bae GIT_SILENT Sync po/docbooks with svn 2023-01-16 02:19:17 +00:00
l10n daemon script
6b4e81c763 GIT_SILENT Sync po/docbooks with svn 2023-01-15 02:07:37 +00:00
l10n daemon script
dcac63aa04 GIT_SILENT Sync po/docbooks with svn 2023-01-14 17:44:16 +00:00
Nicolas Fella
7818747e45 Also handle notification startupId on X11
On X11 we can get a startupId/token from the notification too, so don't waste it
2023-01-14 12:51:15 +00:00
l10n daemon script
7cb1f856ca GIT_SILENT Sync po/docbooks with svn 2023-01-14 12:42:44 +00:00
James Graham
5955c8e7dc Improve global notification settings
Separate the setting for globally setting push rules on/off from the configuration to decide whether desktop popup notifications are sent.

The current master setting is pulling double duty and should probably be separate as some people may want to see notification counts in Neochat but don't want to see popup notifications on their desktop.
2023-01-14 12:29:08 +00:00
Gary Wang
dee3c279e8 fix crash when open invitation page 2023-01-14 06:17:32 +00:00
l10n daemon script
94427280d8 GIT_SILENT Sync po/docbooks with svn 2023-01-14 02:15:51 +00:00
Gary Wang
8b245b1cc9 fix crash on invite via /invite command 2023-01-13 22:15:22 +08:00
l10n daemon script
0513cd10c4 GIT_SILENT Sync po/docbooks with svn 2023-01-13 02:56:44 +00:00
James Graham
28b5631d06 Update userlistmodel permission roles
Change the userlist model so that permission names are based upon the following power level convention:
- 0: member
- 50: moderator
- 100: admin
- other: custom

This is inline with the new permission room page. Follow on from network/neochat!712
2023-01-12 19:13:20 +00:00
l10n daemon script
5f2cd92da7 GIT_SILENT Sync po/docbooks with svn 2023-01-12 02:16:04 +00:00
Tobias Fella
4535125c54 Change message shown when encryption is disabled in libQuotient 2023-01-11 19:03:29 +00:00
James Graham
8831da956a Notifications for all accounts
- Handle notifications from all accounts not just the active one.
- When a notification from the non-active account is clicked the active account is changed over to enter the correct room.

network/neochat#121
2023-01-11 19:02:51 +00:00
Akseli Lahtinen
f2ec6e1d4c Write inside .cache folder in home, instead of just home
Back when testing !745, i was using `kdesrc-run` and this bug slipped through my fingers: It began to create folder named after the file inside the home (or in this case, kdesrc-run home) folder.

This fixes that. Now the clipboard image files go correctly to `~/.cache/KDE/screenshots/` folder.

Anyhow, my bad, should've done more print debugging.. 😓
2023-01-11 12:58:23 +00:00
l10n daemon script
93f7def532 GIT_SILENT Sync po/docbooks with svn 2023-01-11 02:17:17 +00:00
Wang Zichong
782f5517d3 Fix falsely treat some symbols as emoji 2023-01-10 22:20:49 +00:00
Brent Mackey
f238c18ce8 Fix last message read receipt reporting time in GMT instead of localtime 2023-01-10 20:59:31 +10:00
l10n daemon script
4fe0ea373f GIT_SILENT Sync po/docbooks with svn 2023-01-10 02:13:38 +00:00
l10n daemon script
982d21dd58 GIT_SILENT Sync po/docbooks with svn 2023-01-09 02:16:57 +00:00
l10n daemon script
7002132bde GIT_SILENT Sync po/docbooks with svn 2023-01-08 02:18:44 +00:00
l10n daemon script
1ef931f7e7 GIT_SILENT Sync po/docbooks with svn 2023-01-07 02:50:39 +00:00
l10n daemon script
8797015c6a GIT_SILENT Sync po/docbooks with svn 2023-01-06 02:39:53 +00:00
Gary Wang
85a562d469 Move encrypt room option to Security page 2023-01-05 16:13:59 +00:00
Akseli Lahtinen
f50c62ba12 Use local file path instead of url
If the localFile url is used, it creates a folder called `file:` in the home folder.

So get filepath from url instead :)
2023-01-05 16:09:20 +00:00
Gary Wang
13f05a0995 Move invite option to header of members section
This patch moves the invite option to header of members section. We also check if user can send invitation event and we won't show the invite button if it's not allowed.

This patch also added an toggle button to show the member search bar since it won't needed by the user in most of the cases.
2023-01-05 14:56:29 +00:00
l10n daemon script
1adddcc0d9 GIT_SILENT Sync po/docbooks with svn 2023-01-05 02:21:03 +00:00
Gary Wang
f03cd3f4c6 Fix SSO login button needs to click twice to open login URL
Before this patch, the `ssoUrlChanged` signal might emitted before the URL actually get changed. This patch ensure the signal emitted at the correct place, and also disable the Login button before `LoginHelper` done its work.

To test this change, you can simply enter `@a:mozilla.org` (or whatever the account name is) and attempt to login it by click "continue". Then click the "Login" button and see if the first click can let your browser open the SSO login URL.
2023-01-05 00:42:56 +00:00
James Graham
29a2e4eb99 Room Settings - Permissions
Work to add the ability to set user power levels and modify the power levels required for certain actions.

Updated

![image](/uploads/50bce18f5eb31bb0c3508e03a39e7589/image.png)
2023-01-05 00:36:13 +00:00
Tobias Fella
7137a5808f Fix building room test on windows
Making protected public seems to mess things up
2023-01-04 19:27:49 +00:00
l10n daemon script
fa6f451e11 GIT_SILENT Sync po/docbooks with svn 2023-01-04 02:46:43 +00:00
James Graham
666f247185 Fix Ctrl + F not working
Fix Crtl + F not working by only having the shortcut assigned to a single searchfield. 
- Ctrl + F is now for the roomlist search
- The user search in the room drawer is now ctrl + shift + f
- for the emoji picker and qucik switcher these have the shortcut removed and focus is managed by the popup.

BUG: 462524
2023-01-03 18:06:51 +00:00
Ingo Klöcker
93dd25f954 Add the Microsoft Store URL 2023-01-03 08:13:57 +01:00
l10n daemon script
8e2ba9552f GIT_SILENT Sync po/docbooks with svn 2023-01-03 03:02:20 +00:00
l10n daemon script
1f02c5ea5e 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-01-03 02:01:04 +00:00
l10n daemon script
112b26c39d GIT_SILENT made messages (after extraction) 2023-01-03 00:47:28 +00:00
l10n daemon script
5e243ed01b GIT_SILENT Sync po/docbooks with svn 2023-01-02 02:55:40 +00:00
Carl Schwan
706809d12a Make space list smaller
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
2023-01-01 23:38:15 +00:00
l10n daemon script
3fc06c2a74 GIT_SILENT Sync po/docbooks with svn 2023-01-01 02:52:37 +00:00
James Graham
4bc2c42982 Remove stary consol.log statement 2022-12-31 15:25:00 +00:00
James Graham
6651fa4fa3 Improve the sizing of notification count with longer numbers
![image](/uploads/ad2128bbfc0ebfd58e2d58926fceb844/image.png)
2022-12-31 12:54:45 +00:00
l10n daemon script
07d65a0046 GIT_SILENT Sync po/docbooks with svn 2022-12-31 02:17:03 +00:00
Gary Wang
4c9f062a70 Fix from and to is not defined in NetworkProxyPage 2022-12-30 14:08:20 +00:00
James Graham
893ee4a763 Add room upgrade button
Add button to upgrade the room if the user has a high enough power level and the room is not at the highest available version.
2022-12-30 13:51:34 +00:00
Tobias Fella
fa67d174d2 Move room actions out of RoomDrawer header 2022-12-30 13:14:00 +00:00
Gary Wang
bb542521fb Support opening space in room list
While it's not *that* useful since we cannot view all the rooms under the space, it can be useful to view all members inside a Space, and invite people to the Space.
2022-12-30 13:13:39 +00:00
l10n daemon script
85d3cf2d77 GIT_SILENT Sync po/docbooks with svn 2022-12-30 02:30:36 +00:00
Nicolas Fella
ebf4cfb825 Add QCoro to third-party deps 2022-12-29 20:50:52 +01:00
l10n daemon script
d7daa697df GIT_SILENT Sync po/docbooks with svn 2022-12-29 02:20:28 +00:00
James Graham
884484922d Fix Room Initial Position
When the room is changed set the roomlist view to the bottom making sure that it isn't in some random place.

BUG: 456647
2022-12-28 17:36:17 +00:00
James Graham
83ab751d4a Add room id and room version to room settings
Add internal room ID and room version number
2022-12-28 13:06:43 +00:00
l10n daemon script
fcee5bfa92 GIT_SILENT Sync po/docbooks with svn 2022-12-28 02:16:59 +00:00
Gary Wang
eb610ffe81 Allow set room join rule to knock 2022-12-27 13:22:35 +00:00
James Graham
647cc25e57 Improve fileDelegate
Make the buttons in file delegate always align left even in compact layout as this looks better. Also fix margins.

BUG: 463327
2022-12-27 13:19:04 +00:00
Wang Zichong
3912b8e096 Support inviting people from UserDetailDialog 2022-12-27 19:22:38 +08:00
Gary Wang
67f88416f1 Use the correct config option for 'In sidebar'
BUG: 463512
2022-12-27 18:13:33 +08:00
James Graham
8e3398df34 Fix icons only mode
- Fix the headers in icons only mode.
- Allow section collapsing
- Show scrollbar when needed

[2022-12-12_19-06-46.mkv](/uploads/e1633058b2b4a24ef7b6144bf5392b9c/2022-12-12_19-06-46.mkv)

BUG: 462576
2022-12-27 09:57:53 +00:00
l10n daemon script
1a09405829 GIT_SILENT Sync po/docbooks with svn 2022-12-27 02:09:12 +00:00
Gary Wang
304054a4bb Add a compact room list option 2022-12-26 21:31:36 +00:00
James Graham
3c33bea7db Improve UserDetailDialog
- Cleanup Layout.
- Remove broken show avatar as FullScreenImage as I see no value and it hasn't worked for a while now and no one complained.
2022-12-26 18:05:58 +00:00
l10n daemon script
15a7cc6e08 GIT_SILENT Sync po/docbooks with svn 2022-12-26 02:17:33 +00:00
l10n daemon script
19b530d34b 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"
2022-12-26 02:03:49 +00:00
l10n daemon script
7fe8bc9f3b GIT_SILENT made messages (after extraction) 2022-12-26 00:53:18 +00:00
l10n daemon script
422fca4dc9 GIT_SILENT Sync po/docbooks with svn 2022-12-25 02:46:50 +00:00
l10n daemon script
142dbe2c2c GIT_SILENT Sync po/docbooks with svn 2022-12-24 02:12:04 +00:00
l10n daemon script
dced8ace1d GIT_SILENT Sync po/docbooks with svn 2022-12-23 02:07:44 +00:00
Tobias Fella
de1fa71d8c Fix uploading files
BUG: 462751
2022-12-22 20:53:57 +00:00
James Graham
158c99daef Improve timeline image sizing
Improve the initial resizing of an image in the timeline by always looking to see whether sourcesize or image.info is populated first.

This allows the actual size of the image to be calculated as soon as possible while still maintaining the fix fo CCBUG: 460205

May also help CCBUG: 463235 I need help testing this it currently no longer happens for me.
2022-12-22 20:23:00 +00:00
Tobias Fella
51e0023384 Implement searching in rooms
BUG: 457839
2022-12-22 19:49:48 +00:00
l10n daemon script
7f27056a34 GIT_SILENT Sync po/docbooks with svn 2022-12-22 02:04:02 +00:00
l10n daemon script
cdbf5ea8e7 GIT_SILENT Sync po/docbooks with svn 2022-12-21 02:07:31 +00:00
l10n daemon script
8bbd5e5a88 GIT_SILENT Sync po/docbooks with svn 2022-12-20 02:04:45 +00:00
James Graham
2e3c2c2424 Fix roompage sectionBanner visible check
change check to `messageListView.sectionBannerItem != undefined` so that the command line isn't spammed with qrc:/RoomPage.qml:263:13: Unable to assign [undefined] to bool
2022-12-19 16:00:41 +00:00
James Graham
80faa4bd4f Set the page title for room/space settings windows 2022-12-19 15:26:51 +00:00
Wang Zichong
de6f93b200 Remove no longer existed property 2022-12-19 22:20:21 +08:00
Laurent Montel
c46bfe05c1 Remove duplicate headers between cpp/h files 2022-12-19 13:32:39 +01:00
l10n daemon script
0d50af6285 GIT_SILENT Sync po/docbooks with svn 2022-12-17 12:30:52 +00:00
l10n daemon script
efb9ca5ac8 GIT_SILENT Sync po/docbooks with svn 2022-12-17 02:14:51 +00:00
l10n daemon script
3ad5b62e27 GIT_SILENT Sync po/docbooks with svn 2022-12-16 02:20:30 +00:00
Nicolas Fella
8985aadcf1 Process KDBusService before loading QML
Otherwise we start loading QML before we attach to an existing instance

Not only is this wasteful but it also breaks raising the existing window on X11 since showing a window clears the startup id
2022-12-15 22:32:40 +01:00
l10n daemon script
907d52d693 GIT_SILENT Sync po/docbooks with svn 2022-12-15 02:16:49 +00:00
James Graham
eb5523a69c Make sure the function createRoomListContextMenu doesn't make the roomlist settings button visible on mobile 2022-12-14 18:22:42 +00:00
James Graham
f475965cf7 Fix code formatting 2022-12-14 16:14:13 +00:00
James Graham
1176cf029b Now allow links to be clicked in replies 2022-12-14 16:14:13 +00:00
James Graham
d68fb81bcf Show a Qt.PointingHandCursor when hovering over a reply 2022-12-14 16:14:13 +00:00
James Graham
81f7afe730 Fix the hover text for add alias button.
Only show the add alias textfield if the user has the appropriate permissions
2022-12-14 16:04:58 +00:00
l10n daemon script
60e43a2794 GIT_SILENT Sync po/docbooks with svn 2022-12-14 02:45:30 +00:00
Nicolas Fella
76f686b580 Require QCoro 0.4 2022-12-13 18:06:51 +00:00
l10n daemon script
cba4fdc397 GIT_SILENT Sync po/docbooks with svn 2022-12-13 02:30:29 +00:00
l10n daemon script
62ea4bc67d GIT_SILENT Sync po/docbooks with svn 2022-12-12 02:22:30 +00:00
James Graham
25c7b7b780 Hide loading item and show info message when on the devices page and not logged in. 2022-12-11 16:47:16 +00:00
James Graham
6b3f44e923 Fix crash when opening notification settings with no account by making sure that the keyword model doesn't try to update the noficiation settings when there is no active connection.
Also make sure that ability to add a keyword or change the global notiifcaiton state is disabled without an active connection as these will cause the same crash.
2022-12-11 13:11:02 +00:00
James Graham
9334585e0f Add missing icons to CMakeLists.txt so they are available on mobile 2022-12-11 13:08:59 +00:00
James Graham
1190511b54 Don't show the settings button in the RoomListPage if on mobile 2022-12-11 11:00:00 +00:00
l10n daemon script
b40d51841e GIT_SILENT Sync po/docbooks with svn 2022-12-11 02:12:55 +00:00
Nicolas Fella
f2ddee09c0 Add third-party deps to .kde-ci.yml
The CI system already provides these so it doesn't have any effect there, but this allows to generate correct dependency data for kdesrc-build from .kde-ci.yml
2022-12-10 13:54:08 +01:00
l10n daemon script
698cbceda3 GIT_SILENT Sync po/docbooks with svn 2022-12-10 02:00:43 +00:00
l10n daemon script
66b1499fad GIT_SILENT Sync po/docbooks with svn 2022-12-09 02:00:06 +00:00
l10n daemon script
e8748ce733 GIT_SILENT Sync po/docbooks with svn 2022-12-08 02:12:20 +00:00
James Graham
4bfa9c783c Move check for RoomPage being visible on the pagestack to enabled so the RoomDrawer can't be swiped on mobile. 2022-12-07 20:12:31 +00:00
Gary Wang
5cdfa086b2 Move tones data to another file to workaround msvc bigobj issue 2022-12-07 15:38:39 +00:00
Gary Wang
e8824edfd4 Add description for emoji 2022-12-07 15:38:39 +00:00
Gary Wang
507bd44bbf Add Quick Reaction to EmojiDialog 2022-12-07 14:44:05 +00:00
Tobias Fella
bfa08d178f Remove \r\n linebreaks in roomlist subtitles
BUG: 462575
2022-12-07 08:36:41 +00:00
Zhang Dingyuan
9e01c96476 feat: support proxy user and password 2022-12-07 11:48:17 +08:00
l10n daemon script
fe855f16f8 GIT_SILENT Sync po/docbooks with svn 2022-12-07 02:08:08 +00:00
Carl Schwan
0fbc1b2121 Improve sizing of emoji delegate
* Use Kirigami.Units.gridUnit * 2.5 for normal emoji
* Use Kirigami.Units.gridUnit * 3 for custom emoji
* Add small background padding to delegate
* Add rounded hover effect

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
2022-12-06 23:40:25 +01:00
James Graham
b5d8acf9de Use EmojiDialog popup in chatbar
This converts the emoji dialog in the chatbar to be the same popup as for reactions. This includes:

- EmojiPicker and ReactionPicker were already similar and are made identical, as such ReactionPicker no longer needed
- Emoji dialog used for both reactions and chatbar emojis
- Add some parameters to allow for different use cases (include custom emojis and whether selection closes the popup)

![image](/uploads/c71bb5ffdc6914efad654998a886ade6/image.png)
2022-12-06 14:49:25 +00:00
l10n daemon script
1ab5bdb600 GIT_SILENT Sync po/docbooks with svn 2022-12-06 01:59:17 +00:00
Tobias Fella
9060de1d60 Improve emojis & reactions 2022-12-05 16:46:55 +00:00
Tobias Fella
1f83ab4450 Remove Keys from FullScreenImage
Broken apparently
2022-12-05 16:29:25 +01:00
Gary Wang
e5680da5ce Use more commonly-used emoji shortname 2022-12-05 09:50:27 +00:00
Tobias Fella
66bfcd6239 Fix cursorShape for avatar in StateDelegate
BUG: 454893
2022-12-05 00:35:40 +01:00
l10n daemon script
8f19c73908 GIT_SILENT Sync po/docbooks with svn 2022-12-04 02:02:15 +00:00
l10n daemon script
716616210f GIT_SILENT Sync po/docbooks with svn 2022-12-03 02:08:50 +00:00
l10n daemon script
cc414f71f4 GIT_SILENT Sync po/docbooks with svn 2022-12-02 02:56:27 +00:00
Tobias Fella
d107dfcab1 Fix file size when uploading files
BUG: 462416
2022-12-01 14:55:10 +00:00
Wang Zichong
875c03a0f6 fix: add missing QQC2 for InviteUserPage 2022-12-01 12:00:25 +08:00
l10n daemon script
4145987c65 GIT_SILENT Sync po/docbooks with svn 2022-12-01 02:04:01 +00:00
Ingo Klöcker
232f3f624b Add icons for the appx bundle for the Microsoft Store 2022-11-30 17:49:15 +00:00
Tobias Fella
2a2791c37f Try fixing windows icon 2022-11-30 17:16:36 +01:00
Tobias Fella
f1c9f5902a Hide account switcher in collapsed roomlist mode 2022-11-30 14:35:34 +01:00
159 changed files with 52377 additions and 36160 deletions

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ compile_commands.json
kate.project.ctags.*
*.user
.flatpak-builder/
.idea/

View File

@@ -15,6 +15,10 @@ Dependencies:
'libraries/kquickimageeditor': '@stable'
'frameworks/sonnet': '@stable'
'libraries/kirigami-addons': '@latest'
'third-party/libquotient': '@latest'
'third-party/qtkeychain': '@latest'
'third-party/cmark': '@latest'
'third-party/qcoro': '@latest'
- 'on': ['Windows', 'Linux', 'FreeBSD']
'require':
'frameworks/qqc2-desktop-style': '@stable'

View File

@@ -6,11 +6,14 @@
cmake_minimum_required(VERSION 3.16)
project(NeoChat)
set(PROJECT_VERSION "22.11")
set(PROJECT_VERSION "23.01")
project(NeoChat VERSION ${PROJECT_VERSION})
set(KF5_MIN_VERSION "5.91.0")
set(QT_MIN_VERSION "5.15.2")
if (ANDROID)
set(QT_MIN_VERSION "5.15.8")
endif()
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
@@ -112,10 +115,7 @@ set_package_properties(KQuickImageEditor PROPERTIES
PURPOSE "Add image editing capability to image attachments"
)
find_package(QCoro${QT_MAJOR_VERSION} COMPONENTS Core QUIET)
if(NOT QCoro${QT_MAJOR_VERSION}_FOUND)
find_package(QCoro REQUIRED)
endif()
find_package(QCoro${QT_MAJOR_VERSION} 0.4 COMPONENTS Core REQUIRED)
qcoro_enable_coroutines()
@@ -125,6 +125,8 @@ set_package_properties(KF5DocTools PROPERTIES DESCRIPTION
TYPE OPTIONAL
)
find_package(Sqlite3)
if(NOT Quotient_VERSION_MINOR GREATER 6)
cmake_policy(SET CMP0063 OLD)
endif()

0
LICENSES/MIT.txt Executable file → Normal file
View File

View File

@@ -14,7 +14,8 @@
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="NeoChat"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTop">
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -22,7 +23,6 @@
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="neochat-app"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
@@ -38,8 +38,6 @@
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Splash screen -->

View File

@@ -12,7 +12,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath 'com.android.tools.build:gradle:7.0.2'
}
}
@@ -73,6 +73,10 @@ android {
defaultConfig {
minSdkVersion qtMinSdkVersion
targetSdkVersion qtTargetSdkVersion
applicationId "org.kde.neochat"
namespace "org.kde.neochat"
versionCode timestamp
versionName projectVersionFull
manifestPlaceholders = [versionName: projectVersionFull, versionCode: timestamp]
}

View File

@@ -5,9 +5,7 @@
#include <QSignalSpy>
#include <QTest>
#define protected public // please don't hate me
#include "neochatroom.h"
#undef protected
#include <connection.h>
#include <quotient_common.h>
@@ -15,12 +13,23 @@
using namespace Quotient;
class TestRoom : public NeoChatRoom
{
public:
using NeoChatRoom::NeoChatRoom;
void update(SyncRoomData &&data, bool fromCache = false)
{
Room::updateData(std::move(data), fromCache);
}
};
class NeoChatRoomTest : public QObject {
Q_OBJECT
private:
Connection *connection = nullptr;
NeoChatRoom *room = nullptr;
TestRoom *room = nullptr;
private Q_SLOTS:
void initTestCase();
@@ -31,7 +40,7 @@ private Q_SLOTS:
void NeoChatRoomTest::initTestCase()
{
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new NeoChatRoom(connection, QStringLiteral("#myroom:kde.org"), JoinState::Join);
room = new TestRoom(connection, QStringLiteral("#myroom:kde.org"), JoinState::Join);
auto json = QJsonDocument::fromJson(R"EVENT({
"account_data": {
@@ -121,7 +130,7 @@ void NeoChatRoomTest::initTestCase()
}
})EVENT");
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, json.object());
room->updateData(std::move(roomData));
room->update(std::move(roomData));
}
void NeoChatRoomTest::subtitleTextTest()

BIN
icons/150-apps-neochat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/44-apps-neochat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -16,6 +16,7 @@
<name xml:lang="ca-valencia">NeoChat</name>
<name xml:lang="cs">NeoChat</name>
<name xml:lang="de">NeoChat</name>
<name xml:lang="el">NeoChat</name>
<name xml:lang="en-GB">NeoChat</name>
<name xml:lang="es">NeoChat</name>
<name xml:lang="eu">NeoChat</name>
@@ -34,6 +35,7 @@
<name xml:lang="pl">NeoChat</name>
<name xml:lang="pt">NeoChat</name>
<name xml:lang="pt-BR">NeoChat</name>
<name xml:lang="ru">NeoChat</name>
<name xml:lang="sk">NeoChat</name>
<name xml:lang="sl">NeoChat</name>
<name xml:lang="sv">NeoChat</name>
@@ -49,6 +51,7 @@
<summary xml:lang="ca-valencia">Un client per a 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="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
@@ -67,6 +70,7 @@
<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>
@@ -81,6 +85,7 @@
<p xml:lang="ca">El NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics usant el protocol Matrix.</p>
<p xml:lang="ca-valencia">NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics utilitzant el protocol Matrix.</p>
<p xml:lang="de">NeoChat ist ein Matrix-Client. Er ermöglicht Ihnen das Senden von Textnachrichten, Videos und Audiodateien an Ihre Familie, Kollegen und Freunde unter Verwendung des Matrix-Protokolls.</p>
<p xml:lang="el">Το NeoChat είναι μια εφαρμογή του Matrix. Σας επιτρέπει να στέλνετε μηνύματα κειμένου, βίντεο και ήχο στην οικογένειά σας, σε συναδέλφους και φίλους με το πρωτόκολλο Matrix.</p>
<p xml:lang="en-GB">NeoChat is a Matrix client. It allows you to send text messages, videos and audio files to your family, colleagues and friends using the Matrix protocol.</p>
<p xml:lang="es">NeoChat es un cliente para Matrix. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos usando el protocolo Matrix.</p>
<p xml:lang="eu">NeoChat Matrix bezero bat da. Familiari, lankideei eta lagunei testu-mezuak, bideoak eta audio-fitxategiak bidaltzeko aukera ematen du, Matrix protokoloa erabiliz.</p>
@@ -97,6 +102,7 @@
<p xml:lang="pl">NeoChat jest programem do Matrisa. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół poprzez protokół Matriksa.</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.</p>
<p xml:lang="pt-BR">O NeoChat é um cliente Matrix. Ele permite a você enviar mensagens de texto, arquivos de vídeo e áudio para seus familiares, colegas e amigos usando o protocolo Matrix.</p>
<p xml:lang="ru">NeoChat — это клиент, поддерживающий работу с протоколом Matrix. Он позволяет отправлять текстовые сообщения, видео и аудиофайлы.</p>
<p xml:lang="sk">NeoChat je Matrix klient. Umožňuje vám posielať textové správy, videá a zvukové súbory rodine, kolegom a priateľom pomocou protokolu Matrix.</p>
<p xml:lang="sl">NeoChat je odjemalec Matrixa. Dovoljuje vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, kolegom in prijateljem z uporabo protokola Matrix.</p>
<p xml:lang="sv">NeoChat är en Matrix-klient. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner med användning av Matrix-protokollet.</p>
@@ -110,6 +116,7 @@
<p xml:lang="ca">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment el NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
<p xml:lang="ca-valencia">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
<p xml:lang="de">Matrix ist ein dezentralisiertes Kommunikationsprotokoll, das dem Benutzer wieder die Kontrolle zurückgibt. Derzeit implementiert NeoChat einen großen Teil des Protokolls mit der Ausnahme von verschlüsselten Chats und Video-Chat.</p>
<p xml:lang="el">Το Matrix είναι ένα αποκεντρωμένο πρωτόκολλο επικοινωνίας, δίνοντας πίσω στον χρήστη τον έλεγχο. Προς το παρόν το NeoChat υλοποιεί ένα μεγάλο μέρος του πρωτοκόλλου με εξαίρεση τις κρυπτογραφημένες συνομιλίες και τη συνομιλία με βίντεο.</p>
<p xml:lang="en-GB">Matrix is a decentralised communication protocol, putting the user back in control. Currently NeoChat implements large part of the protocol with the exception of encrypted chats and video chat.</p>
<p xml:lang="es">Matrix es un protocolo de comunicaciones descentralizado, que devuelve el control al usuario. En la actualidad, NeoChat implementa gran parte del protocolo con la excepción de chats cifrados y chats de vídeo.</p>
<p xml:lang="eu">Matrix komunikazio-protokolo deszentralizatu bat da, erabiltzaileari kontrola itzultzen diona. Gaur egun, NeoChat-ek protokoloaren zati handi bat inplementatzen du, berriketa zifratuak eta bideo berriketak izan ezik.</p>
@@ -126,6 +133,7 @@
<p xml:lang="pl">Matrix jest protokołem rozproszonego porozumiewania się oddający użytkownikowi jego władzę. Obecnie NeoChat obsługuje dużą część protokołu poza szyfrowanymi rozmowami tekstowymi i z obrazem.</p>
<p xml:lang="pt">O Matrix é um protocolo de comunicações descentralizado, colocando de novo o utilizador no poder. De momento, o NeoChat implementa uma boa parte do protocolo, com a excepção das conversas encriptadas e as conversas de vídeo.</p>
<p xml:lang="pt-BR">O Matrix é um protocolo de comunicação descentralizado, colocando o usuário de volta no controle. Atualmente o NeoChat implementa grande parte do protocolo com a exceção de bate-papos criptografados e bate-papo por vídeo.</p>
<p xml:lang="ru">Matrix — это децентрализованный коммуникационный протокол, возвращающий пользователю контроль над своими данными. В настоящее время в приложении NeoChat реализована поддержка большей части протокола, за исключением зашифрованных чатов и видеочата.</p>
<p xml:lang="sk">Matrix je decentralizovaný komunikačný protokol, ktorý používateľovi vracia kontrolu. V súčasnosti NeoChat implementuje veľkú časť protokolu s výnimkou šifrovaných chatov a videohovorov.</p>
<p xml:lang="sl">Matrix je decentraliziran komunikacijski protokol, kjer ima uporabnik uporabnik kontrolo rabe. Trenutno ima NeoChat izveden velik del protokola z izjemo šifriranih klepetov in video klepetov.</p>
<p xml:lang="sv">Matrix är ett decentraliserat kommunikationsprotokoll, som ger tillbaka kontrollen till användaren. För närvarande implementerar NeoChat en stor del av protokollet, med undantag för krypterad chatt och videochatt.</p>
@@ -138,7 +146,8 @@
<p xml:lang="az">Vahid istifadəçi interfeysi ilə təmin olunan NeoChat, həm mobil telefonda həm də kompyuterlərdə işləyir.</p>
<p xml:lang="ca">El NeoChat funciona en els mòbils i a l'escriptori, proporcionant una experiència d'usuari coherent.</p>
<p xml:lang="ca-valencia">NeoChat funciona en els mòbils i en l'escriptori, proporcionant una experiència d'usuari coherent.</p>
<p xml:lang="de">NeoChat funktioniert sowohl auf dem Mobiltelefon als auch auf dem Arbeitsfläche und bietet ein einheitliches Benutzererlebnis. </p>
<p xml:lang="de">NeoChat funktioniert sowohl auf Mobilgeräten als auch auf dem PC und bietet ein einheitliches Benutzererlebnis.</p>
<p xml:lang="el">Το NeoChat λειτουργεί και στα κινητά και στους υπολογιστές γραφείου παρέχοντας μια αδιάλειπτη εμπειρία χρήσης.</p>
<p xml:lang="en-GB">NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
<p xml:lang="es">NeoChat funciona en móviles y en el escritorio a la vez que proporciona una experiencia de usuario consistente.</p>
<p xml:lang="eu">NeoChat mugikorretan eta mahaigainean dabil, erabiltzaile esperientzia koherentea eskainiz.</p>
@@ -155,6 +164,7 @@
<p xml:lang="pl">NeoChat działa zarówno na urządzeniach przenośnych jak i biurkowych, zapewniając spójne wrażenia użytkownika</p>
<p xml:lang="pt">O NeoChat funciona tanto em dispositivos móveis como no computador, fornecendo uma experiência de utilizador consistente.</p>
<p xml:lang="pt-BR">O NeoChat funciona tanto no celular como no computador enquanto fornece uma experiência consistente ao usuário.</p>
<p xml:lang="ru">NeoChat работает как на мобильных устройствах, так и на настольных компьютерах, обеспечивая единый пользовательский интерфейс.</p>
<p xml:lang="sk">NeoChat funguje na mobilných aj stolových počítačoch a poskytuje konzistentný používateľský zážitok.</p>
<p xml:lang="sl">NeoChat deluje tako na mobilnih kot na namiznih platformah z zagotavljanjem konsistentne uporabniške izkušnje.</p>
<p xml:lang="sv">NeoChat fungerar både på mobil och skrivbord och tillhandahåller en konsekvent användarupplevelse.</p>
@@ -175,6 +185,7 @@
<developer_name xml:lang="ca-valencia">La comunitat KDE</developer_name>
<developer_name xml:lang="cs">Komunita KDE</developer_name>
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
<developer_name xml:lang="el">Η Κοινότητα του KDE</developer_name>
<developer_name xml:lang="en-GB">The KDE Community</developer_name>
<developer_name xml:lang="es">La comunidad KDE</developer_name>
<developer_name xml:lang="eu">KDE komunitatea</developer_name>
@@ -193,6 +204,7 @@
<developer_name xml:lang="pl">Społeczność KDE</developer_name>
<developer_name xml:lang="pt">A Comunidade do KDE</developer_name>
<developer_name xml:lang="pt-BR">A comunidade KDE</developer_name>
<developer_name xml:lang="ru">Сообщество KDE</developer_name>
<developer_name xml:lang="sk">KDE Komunita</developer_name>
<developer_name xml:lang="sl">Skupnost KDE</developer_name>
<developer_name xml:lang="sv">KDE-gemenskapen</developer_name>
@@ -204,6 +216,7 @@
<project_license>GPL-3.0</project_license>
<custom>
<value key="KDE::matrix">#neochat:kde.org</value>
<value key="KDE::windows_store">https://www.microsoft.com/store/apps/9PNXWVNRC29H</value>
</custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots>
@@ -218,6 +231,20 @@
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="23.01" date="2023-01-30">
<url>https://plasma-mobile.org/2023/01/30/january-blog-post/</url>
<description>
<p>New features and bugfixes:</p>
<ul>
<li>Notifications will now be shown for all accounts, not just the active one</li>
<li>There is a new "compact" mode for the room list</li>
<li>You can now search in the room history</li>
<li>Emojis and Reactions have been significantly improved</li>
<li>Fixed several crashes around user invitations</li>
<li>Room permission settings can now be configured</li>
</ul>
</description>
</release>
<release version="22.11" date="2022-11-30">
<url>https://plasma-mobile.org/2022/11/30/plasma-mobile-gear-22-11/</url>
</release>

View File

@@ -9,6 +9,7 @@ Name[ca]=NeoChat
Name[ca@valencia]=NeoChat
Name[cs]=NeoChat
Name[de]=NeoChat
Name[el]=NeoChat
Name[en_GB]=NeoChat
Name[es]=NeoChat
Name[eu]=NeoChat
@@ -29,6 +30,7 @@ Name[pl]=NeoChat
Name[pt]=NeoChat
Name[pt_BR]=NeoChat
Name[ro]=NeoChat
Name[ru]=NeoChat
Name[sk]=NeoChat
Name[sl]=NeoChat
Name[sv]=NeoChat
@@ -44,6 +46,7 @@ GenericName[ca]=Client de Matrix
GenericName[ca@valencia]=Client de Matrix
GenericName[cs]=Klient protokolu Matrix
GenericName[de]=Matrix-Programm
GenericName[el]=Εφαρμογή του Matrix
GenericName[en_GB]=Matrix Client
GenericName[es]=Cliente para Matrix
GenericName[eu]=Matrix bezeroa
@@ -64,6 +67,7 @@ GenericName[pl]=Program Matriksa
GenericName[pt]=Cliente de Matrix
GenericName[pt_BR]=Cliente Matrix
GenericName[ro]=Client Matrix
GenericName[ru]=Клиент Matrix
GenericName[sk]=Matrix Client
GenericName[sl]=Odjemalec Matrix
GenericName[sv]=Matrix-klient
@@ -78,6 +82,7 @@ Comment[az]=Matrix protokolu üçün müştəri
Comment[ca]=Client per al protocol Matrix
Comment[ca@valencia]=Client per al protocol Matrix
Comment[de]=Programm für das Matrix-Protokoll
Comment[el]=Πελάτης για το πρωτόκολλο Matrix
Comment[en_GB]=Client for the Matrix protocol
Comment[es]=Cliente para el protocolo Matrix
Comment[eu]=Matrix protokolorako bezeroa
@@ -98,6 +103,7 @@ Comment[pl]=Program obsługi protokołu Matriksa
Comment[pt]=Cliente para o protocolo Matrix
Comment[pt_BR]=Cliente para o protocolo Matrix
Comment[ro]=Client pentru protocolul Matrix
Comment[ru]=Клиент для протокола Matrix
Comment[sk]=Klient protokolu Matrix
Comment[sl]=Odjemalec za protokol Matrix
Comment[sv]=Klient för protokollet Matrix

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

3619
po/el/neochat.po Normal file

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

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" ?>
<!DOCTYPE refentry PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
<!ENTITY % Italian "INCLUDE">
]>
<!--
SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
SPDX-License-Identifier: CC-BY-SA-4.0
-->
<refentry lang="&language;">
<refentryinfo>
<title
>Manuale utente di NeoChat</title>
<author
><firstname
>Carl</firstname
><surname
>Schwan</surname
> <contrib
>Pagina man di NeoChat.</contrib
> <email
>carl@carlschwan.eu</email
></author>
<date
>1/11/2022</date>
<releaseinfo
>22.09</releaseinfo>
<productname
>NeoChat</productname>
</refentryinfo>
<refmeta>
<refentrytitle>
<command
>neochat</command>
</refentrytitle>
<manvolnum
>1</manvolnum>
</refmeta>
<refnamediv>
<refname
>neochat</refname>
<refpurpose
>Client per l'interazione con il protocollo di messaggistica matrix</refpurpose>
</refnamediv>
<!-- body begins here -->
<refsynopsisdiv id='synopsis'>
<cmdsynopsis
><command
>neochat</command
> <arg choice="opt"
><replaceable
>URI</replaceable
></arg
> </cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="description">
<title
>Descrizione</title>
<para
><command
>neochat</command
> è un'applicazione di chat per il protocollo Matrix che funziona sia su desktop che su dispositivi mobili. </para>
</refsect1>
<refsect1 id="options"
><title
>Opzioni</title>
<variablelist>
<varlistentry>
<term
><option
>URI</option
></term>
<listitem>
<para
>L'URI matrix per un utente o una stanza. ad esempio matrix:u/utente:esempio.org e matrix:r/stanza:esempio.org. Questo farà in modo che NeoChat provi ad aprire la stanza o la conversazione specificata. </para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="bug">
<title
>Segnalazione bug</title>
<para
>Puoi segnalare bug e richiedere funzionalità su <ulink url="https://bugs.kde.org/enter_bug.cgi?product=NeoChat&amp;component=General"
>https://bugs.kde.org/enter_bug.cgi? product=NeoChat&amp;component=General</ulink
></para>
</refsect1>
<refsect1>
<title
>Vedi anche</title>
<simplelist>
<member
>Un elenco di domande frequenti su Matrix <ulink url="https://matrix.org/faq/"
>https://matrix.org/faq/</ulink
> </member>
<member
>kf5options(7)</member>
<member
>qt5options(7)</member>
</simplelist>
</refsect1>
<refsect1 id="copyright"
><title
>Copyright</title>
<para
>Copyright &copy; 2020-2022 Tobias Fella </para>
<para
>Copyright &copy; 2020-2022 Carl Schwan </para>
<para
>Licenza: GNU General Public Version 3 o successiva &lt;<ulink url="https://www.gnu.org/licenses/gpl-3.0.html"
>https://www.gnu.org/licenses/gpl-3.0.html</ulink
>&gt;</para>
</refsect1>
</refentry>

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

View File

@@ -6,44 +6,47 @@
add_library(neochat STATIC
controller.cpp
actionshandler.cpp
emojimodel.cpp
customemojimodel.cpp
models/emojimodel.cpp
emojitones.cpp
models/customemojimodel.cpp
clipboard.cpp
matriximageprovider.cpp
messageeventmodel.cpp
messagefiltermodel.cpp
roomlistmodel.cpp
sortfilterspacelistmodel.cpp
models/messageeventmodel.cpp
models/messagefiltermodel.cpp
models/roomlistmodel.cpp
models/sortfilterspacelistmodel.cpp
spacehierarchycache.cpp
roommanager.cpp
neochatroom.cpp
neochatuser.cpp
userlistmodel.cpp
publicroomlistmodel.cpp
userdirectorylistmodel.cpp
keywordnotificationrulemodel.cpp
models/userlistmodel.cpp
models/userfiltermodel.cpp
models/publicroomlistmodel.cpp
models/userdirectorylistmodel.cpp
models/keywordnotificationrulemodel.cpp
utils.cpp
notificationsmanager.cpp
sortfilterroomlistmodel.cpp
models/sortfilterroomlistmodel.cpp
chatdocumenthandler.cpp
devicesmodel.cpp
models/devicesmodel.cpp
filetypesingleton.cpp
login.cpp
stickerevent.cpp
webshortcutmodel.cpp
models/webshortcutmodel.cpp
blurhash.cpp
blurhashimageprovider.cpp
joinrulesevent.cpp
collapsestateproxymodel.cpp
models/collapsestateproxymodel.cpp
urlhelper.cpp
windowcontroller.cpp
linkpreviewer.cpp
completionmodel.cpp
completionproxymodel.cpp
actionsmodel.cpp
serverlistmodel.cpp
statemodel.cpp
models/completionmodel.cpp
models/completionproxymodel.cpp
models/actionsmodel.cpp
models/serverlistmodel.cpp
models/statemodel.cpp
filetransferpseudojob.cpp
models/searchmodel.cpp
)
add_executable(neochat-app
@@ -67,7 +70,7 @@ endif()
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat PRIVATE ${NEOCHAT_ICON})
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID)
target_sources(neochat PRIVATE colorschemer.cpp)
@@ -90,12 +93,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 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore KF5::ItemModels Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES})
if(TARGET QCoro5::Coro)
target_link_libraries(neochat PUBLIC QCoro5::Coro)
else()
target_link_libraries(neochat PUBLIC QCoro::QCoro)
endif()
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore KF5::ItemModels Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
if(NEOCHAT_FLATPAK)
@@ -105,6 +103,9 @@ endif()
if(ANDROID)
target_sources(neochat PRIVATE notifyrc.qrc)
target_link_libraries(neochat PRIVATE Qt::Svg OpenSSL::SSL)
if(SQLite3_FOUND)
target_link_libraries(neochat-app PRIVATE SQLite::SQLite3)
endif()
target_sources(neochat-app PRIVATE notifyrc.qrc)
target_link_libraries(neochat PUBLIC Qt::Svg OpenSSL::SSL)
kirigami_package_breeze_icons(ICONS
@@ -161,12 +162,18 @@ if(ANDROID)
"zoom-out"
"image-rotate-left-symbolic"
"image-rotate-right-symbolic"
"channel-insecure-symbolic"
"channel-secure-symbolic"
"download"
"smiley"
"tools-check-spelling"
"username-copy"
"edit-copy"
"system-switch-user"
"bookmark-new"
"bookmark-remove"
"favorite"
"window-new"
"globe"
"visibility"
)
else()
target_link_libraries(neochat PUBLIC Qt::Widgets KF5::KIOWidgets)

View File

@@ -13,13 +13,12 @@
#include <KLocalizedString>
#include <QStringBuilder>
#include "actionsmodel.h"
#include "controller.h"
#include "customemojimodel.h"
#include "models/actionsmodel.h"
#include "models/customemojimodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "roommanager.h"
#include "neochatuser.h"
#include "roommanager.h"
using namespace Quotient;

View File

@@ -5,7 +5,6 @@
#include <QQmlFile>
#include <QQmlFileSelector>
#include <QQuickTextDocument>
#include <QStringBuilder>
#include <QSyntaxHighlighter>
#include <QTextBlock>
@@ -15,10 +14,9 @@
#include <Sonnet/BackgroundChecker>
#include <Sonnet/Settings>
#include "actionsmodel.h"
#include "completionmodel.h"
#include "models/actionsmodel.h"
#include "models/roomlistmodel.h"
#include "neochatroom.h"
#include "roomlistmodel.h"
class SyntaxHighlighter : public QSyntaxHighlighter
{
@@ -107,7 +105,7 @@ ChatDocumentHandler::ChatDocumentHandler(QObject *parent)
{
connect(this, &ChatDocumentHandler::roomChanged, this, [this]() {
m_completionModel->setRoom(m_room);
static NeoChatRoom *previousRoom = nullptr;
static QPointer<NeoChatRoom> previousRoom = nullptr;
if (previousRoom) {
disconnect(previousRoom, &NeoChatRoom::chatBoxTextChanged, this, nullptr);
}

View File

@@ -7,8 +7,8 @@
#include <QQuickTextDocument>
#include <QTextCursor>
#include "completionmodel.h"
#include "userlistmodel.h"
#include "models/completionmodel.h"
#include "models/userlistmodel.h"
class QTextDocument;
class NeoChatRoom;

View File

@@ -33,13 +33,14 @@ QImage Clipboard::image() const
QString Clipboard::saveImage(QString localPath) const
{
if (!QDir().exists(QStringLiteral("%1/screenshots").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)))) {
QDir().mkdir(QStringLiteral("%1/screenshots").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
QString imageDir(QStringLiteral("%1/screenshots").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
if (!QDir().exists(imageDir)) {
QDir().mkdir(imageDir);
}
if (localPath.isEmpty()) {
localPath = QStringLiteral("file://%1/screenshots/%2.png")
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation),
QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd-hh-mm-ss")));
localPath = QStringLiteral("file://%1/%2.png").arg(imageDir, QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd-hh-mm-ss")));
}
QUrl url(localPath);
if (!url.isLocalFile()) {
@@ -51,14 +52,11 @@ QString Clipboard::saveImage(QString localPath) const
return {};
}
QDir dir;
if (!dir.exists(localPath)) {
dir.mkpath(localPath);
if (image.save(url.toLocalFile())) {
return localPath;
} else {
return {};
}
image.save(url.toLocalFile());
return localPath;
}
void Clipboard::saveText(QString message)

View File

@@ -19,7 +19,6 @@
#include <QGuiApplication>
#include <QImageReader>
#include <QNetworkProxy>
#include <QQuickItem>
#include <QQuickTextDocument>
#include <QQuickWindow>
#include <QStandardPaths>
@@ -129,16 +128,7 @@ Controller::Controller(QObject *parent)
if (AccountRegistry::instance().size() > oldAccountCount) {
auto connection = AccountRegistry::instance().accounts()[AccountRegistry::instance().size() - 1];
connect(connection, &Connection::syncDone, this, [=]() {
bool changes = false;
for (const auto &room : connection->allRooms()) {
if (m_notificationCounts[room] != room->unreadStats().notableCount) {
m_notificationCounts[room] = room->unreadStats().notableCount;
changes = true;
}
}
if (changes) {
handleNotifications();
}
handleNotifications(connection);
});
}
oldAccountCount = AccountRegistry::instance().size();
@@ -147,19 +137,16 @@ Controller::Controller(QObject *parent)
}
#ifdef QUOTIENT_07
void Controller::handleNotifications()
void Controller::handleNotifications(QPointer<Quotient::Connection> connection)
{
static bool initial = true;
static QStringList initial;
static QStringList oldNotifications;
if (!m_connection) {
return;
}
auto job = m_connection->callApi<GetNotificationsJob>();
auto job = connection->callApi<GetNotificationsJob>();
connect(job, &BaseJob::success, this, [this, job]() {
connect(job, &BaseJob::success, this, [job, connection]() {
const auto notifications = job->jsonData()["notifications"].toArray();
if (initial) {
initial = false;
if (!initial.contains(connection->user()->id())) {
initial.append(connection->user()->id());
for (const auto &n : notifications) {
oldNotifications += n.toObject()["event"].toObject()["event_id"].toString();
}
@@ -175,7 +162,7 @@ void Controller::handleNotifications()
continue;
}
oldNotifications += notification["event"].toObject()["event_id"].toString();
auto room = m_connection->room(notification["room_id"].toString());
auto room = connection->room(notification["room_id"].toString());
// If room exists, room is NOT active OR the application is NOT active, show notification
if (room && !(room->id() == RoomManager::instance().currentRoom()->id() && QGuiApplication::applicationState() == Qt::ApplicationActive)) {
@@ -197,7 +184,7 @@ void Controller::handleNotifications()
if (notification["event"]["type"] == "m.room.encrypted") {
#ifdef Quotient_E2EE_ENABLED
auto decrypted = m_connection->decryptNotification(notification);
auto decrypted = connection->decryptNotification(notification);
body = decrypted["content"].toObject()["body"].toString();
#endif
if (body.isEmpty()) {
@@ -382,6 +369,11 @@ void Controller::invokeLogin()
if (error == "Unrecognised access token") {
Q_EMIT errorOccured(i18n("Login Failed: Access Token invalid or revoked"));
logout(connection, false);
} else if (error == "Connection closed") {
Q_EMIT errorOccured(i18n("Login Failed: %1", error));
// Failed due to network connection issue. This might happen when the homeserver is
// temporary down, or the user trying to re-launch NeoChat in a network that cannot
// connect to the homeserver. In this case, we don't want to do logout().
} else {
Q_EMIT errorOccured(i18n("Login Failed: %1", error));
logout(connection, true);
@@ -743,11 +735,15 @@ void Controller::setApplicationProxy()
proxy.setType(QNetworkProxy::HttpProxy);
proxy.setHostName(cfg->proxyHost());
proxy.setPort(cfg->proxyPort());
proxy.setUser(cfg->proxyUser());
proxy.setPassword(cfg->proxyPassword());
break;
case 2: // SOCKS 5
proxy.setType(QNetworkProxy::Socks5Proxy);
proxy.setHostName(cfg->proxyHost());
proxy.setPort(cfg->proxyPort());
proxy.setUser(cfg->proxyUser());
proxy.setPassword(cfg->proxyPassword());
break;
case 0: // System Default
default:

View File

@@ -119,7 +119,7 @@ private:
bool hasWindowSystem() const;
#ifdef QUOTIENT_07
void handleNotifications();
void handleNotifications(QPointer<Quotient::Connection> connection);
#endif
private Q_SLOTS:

File diff suppressed because it is too large Load Diff

9
src/emojitones.cpp Normal file
View File

@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: None
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "emojitones.h"
#include "models/emojimodel.h"
QMultiHash<QString, QVariant> EmojiTones::_tones = {
#include "emojitones_data.h"
};

File diff suppressed because it is too large Load Diff

1784
src/emojitones_data.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,8 +14,6 @@
#include "controller.h"
#include <QUrl>
#include <KLocalizedString>
using namespace Quotient;
@@ -183,8 +181,8 @@ void Login::loginWithSso()
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
SsoSession *session = m_connection->prepareForSso(m_deviceName);
m_ssoUrl = session->ssoUrl();
Q_EMIT ssoUrlChanged();
});
Q_EMIT ssoUrlChanged();
}
bool Login::testing() const

View File

@@ -42,19 +42,29 @@
#include "blurhashimageprovider.h"
#include "chatdocumenthandler.h"
#include "clipboard.h"
#include "collapsestateproxymodel.h"
#include "controller.h"
#include "customemojimodel.h"
#include "devicesmodel.h"
#include "emojimodel.h"
#include "filetypesingleton.h"
#include "joinrulesevent.h"
#include "linkpreviewer.h"
#include "keywordnotificationrulemodel.h"
#include "login.h"
#include "matriximageprovider.h"
#include "messageeventmodel.h"
#include "messagefiltermodel.h"
#include "models/collapsestateproxymodel.h"
#include "models/customemojimodel.h"
#include "models/devicesmodel.h"
#include "models/emojimodel.h"
#include "models/keywordnotificationrulemodel.h"
#include "models/messageeventmodel.h"
#include "models/messagefiltermodel.h"
#include "models/publicroomlistmodel.h"
#include "models/roomlistmodel.h"
#include "models/searchmodel.h"
#include "models/serverlistmodel.h"
#include "models/sortfilterroomlistmodel.h"
#include "models/sortfilterspacelistmodel.h"
#include "models/userdirectorylistmodel.h"
#include "models/userfiltermodel.h"
#include "models/userlistmodel.h"
#include "models/webshortcutmodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "neochatuser.h"
@@ -62,17 +72,9 @@
#ifdef QUOTIENT_07
#include "pollhandler.h"
#endif
#include "publicroomlistmodel.h"
#include "roomlistmodel.h"
#include "roommanager.h"
#include "serverlistmodel.h"
#include "sortfilterroomlistmodel.h"
#include "sortfilterspacelistmodel.h"
#include "spacehierarchycache.h"
#include "urlhelper.h"
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
#include "webshortcutmodel.h"
#include "windowcontroller.h"
#ifdef QUOTIENT_07
#include <keyverificationsession.h>
@@ -80,9 +82,9 @@
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
#include "completionmodel.h"
#include "models/completionmodel.h"
#include "models/statemodel.h"
#include "neochatuser.h"
#include "statemodel.h"
#ifdef HAVE_RUNNER
#include "runner.h"
@@ -219,6 +221,7 @@ int main(int argc, char *argv[])
qmlRegisterType<MessageEventModel>("org.kde.neochat", 1, 0, "MessageEventModel");
qmlRegisterType<CollapseStateProxyModel>("org.kde.neochat", 1, 0, "CollapseStateProxyModel");
qmlRegisterType<MessageFilterModel>("org.kde.neochat", 1, 0, "MessageFilterModel");
qmlRegisterType<UserFilterModel>("org.kde.neochat", 1, 0, "UserFilterModel");
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
qmlRegisterType<UserDirectoryListModel>("org.kde.neochat", 1, 0, "UserDirectoryListModel");
qmlRegisterType<ServerListModel>("org.kde.neochat", 1, 0, "ServerListModel");
@@ -228,6 +231,7 @@ int main(int argc, char *argv[])
qmlRegisterType<LinkPreviewer>("org.kde.neochat", 1, 0, "LinkPreviewer");
qmlRegisterType<CompletionModel>("org.kde.neochat", 1, 0, "CompletionModel");
qmlRegisterType<StateModel>("org.kde.neochat", 1, 0, "StateModel");
qmlRegisterType<SearchModel>("org.kde.neochat", 1, 0, "SearchModel");
#ifdef QUOTIENT_07
qmlRegisterType<PollHandler>("org.kde.neochat", 1, 0, "PollHandler");
#endif
@@ -265,6 +269,32 @@ int main(int argc, char *argv[])
#endif
QQmlApplicationEngine engine;
#ifdef HAVE_KDBUSADDONS
KDBusService service(KDBusService::Unique);
service.connect(&service,
&KDBusService::activateRequested,
&RoomManager::instance(),
[&engine](const QStringList &arguments, const QString &workingDirectory) {
Q_UNUSED(workingDirectory);
QWindow *window = windowFromEngine(&engine);
KWindowSystem::updateStartupId(window);
WindowController::instance().showAndRaiseWindow(QString());
// Open matrix uri
if (arguments.isEmpty()) {
return;
}
auto args = arguments;
args.removeFirst();
for (const auto &arg : args) {
RoomManager::instance().openResource(arg);
}
});
#endif
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
QObject::connect(&engine, &QQmlApplicationEngine::quit, &app, &QCoreApplication::quit);
engine.setNetworkAccessManagerFactory(new NetworkAccessManagerFactory());
@@ -294,31 +324,6 @@ int main(int argc, char *argv[])
QDBusConnection::sessionBus().registerObject("/RoomRunner", &runner, QDBusConnection::ExportScriptableContents);
#endif
#ifdef HAVE_KDBUSADDONS
KDBusService service(KDBusService::Unique);
service.connect(&service,
&KDBusService::activateRequested,
&RoomManager::instance(),
[&engine](const QStringList &arguments, const QString &workingDirectory) {
Q_UNUSED(workingDirectory);
QWindow *window = windowFromEngine(&engine);
KWindowSystem::updateStartupId(window);
WindowController::instance().showAndRaiseWindow(QString());
// Open matrix uri
if (arguments.isEmpty()) {
return;
}
auto args = arguments;
args.removeFirst();
for (const auto &arg : args) {
RoomManager::instance().openResource(arg);
}
});
#endif
QWindow *window = windowFromEngine(&engine);
WindowController::instance().setWindow(window);

View File

@@ -158,11 +158,12 @@ QVector<ActionsModel::Action> actions{
return QString();
}
#ifdef QUOTIENT_07
if (room->currentState().get<RoomMemberEvent>(text)->membership() == Membership::Invite) {
const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text);
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already invited to this room.", "%1 is already invited to this room.", text));
return QString();
}
if (room->currentState().get<RoomMemberEvent>(text)->membership() == Membership::Ban) {
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Ban) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString();
}

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "collapsestateproxymodel.h"
#include "messageeventmodel.h"
#include <KLocalizedString>

View File

@@ -10,7 +10,6 @@
#include "customemojimodel.h"
#include "emojimodel.h"
#include "neochatroom.h"
#include "roomlistmodel.h"
#include "userlistmodel.h"
CompletionModel::CompletionModel(QObject *parent)
@@ -102,6 +101,9 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
if (role == ReplacedText) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
}
if (role == Subtitle) {
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
}
}
return {};
@@ -149,7 +151,7 @@ void CompletionModel::updateCompletion()
m_filterModel->setSourceModel(m_emojiModel);
m_autoCompletionType = Emoji;
m_filterModel->setFilterRole(CustomEmojiModel::Name);
m_filterModel->setSecondaryFilterRole(-1);
m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole);
m_filterModel->setFullText(m_fullText);
m_filterModel->setFilterText(m_text);
m_filterModel->invalidate();

View File

@@ -25,6 +25,17 @@ bool CompletionProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &so
#endif
}
bool CompletionProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (m_secondaryFilterRole == -1)
return QSortFilterProxyModel::lessThan(source_left, source_right);
bool left_primary = sourceModel()->data(source_left, filterRole()).toString().startsWith(m_filterText, Qt::CaseInsensitive);
bool right_primary = sourceModel()->data(source_right, filterRole()).toString().startsWith(m_filterText, Qt::CaseInsensitive);
if (left_primary != right_primary)
return left_primary;
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
int CompletionProxyModel::secondaryFilterRole() const
{
return m_secondaryFilterRole;

View File

@@ -13,6 +13,7 @@ class CompletionProxyModel : public QSortFilterProxyModel
public:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
int secondaryFilterRole() const;
void setSecondaryFilterRole(int role);

View File

@@ -4,13 +4,17 @@
#pragma once
#include <QAbstractListModel>
#include <memory>
#include <QRegularExpression>
#include <memory>
struct CustomEmoji {
QString name; // with :semicolons:
QString url; // mxc://
QRegularExpression regexp;
Q_GADGET
Q_PROPERTY(QString unicode MEMBER url)
Q_PROPERTY(QString name MEMBER name)
};
class CustomEmojiModel : public QAbstractListModel
@@ -25,6 +29,7 @@ public:
MxcUrl = 50,
DisplayRole = 51,
ReplacedTextRole = 52,
DescriptionRole = 53, // also invalid, reserved
};
Q_ENUM(Roles);

View File

@@ -4,12 +4,13 @@
#include <QVariant>
#include "emojimodel.h"
#include "emojitones.h"
#include <QDebug>
#include <algorithm>
#include "customemojimodel.h"
#include <KLocalizedString>
#include <qnamespace.h>
EmojiModel::EmojiModel(QObject *parent)
: QAbstractListModel(parent)
@@ -48,6 +49,8 @@ QVariant EmojiModel::data(const QModelIndex &index, int role) const
return QStringLiteral("invalid");
case DisplayRole:
return QStringLiteral("%2 :%1:").arg(emoji.shortName, emoji.unicode);
case DescriptionRole:
return emoji.description;
}
}
return {};
@@ -58,16 +61,19 @@ QHash<int, QByteArray> EmojiModel::roleNames() const
return {{ShortNameRole, "shortName"}, {UnicodeRole, "unicode"}};
}
QMultiHash<QString, QVariant> EmojiModel::_tones = {
#include "emojitones.h"
};
QVariantList EmojiModel::history() const
{
return m_settings.value("Editor/emojis", QVariantList()).toList();
}
QVariantList EmojiModel::filterModel(const QString &filter, bool limit)
{
auto emojis = CustomEmojiModel::instance().filterModel(filter);
emojis += filterModelNoCustom(filter, limit);
return emojis;
}
QVariantList EmojiModel::filterModelNoCustom(const QString &filter, bool limit)
{
QVariantList result;
@@ -82,7 +88,6 @@ QVariantList EmojiModel::filterModel(const QString &filter, bool limit)
}
}
}
return result;
}
@@ -110,12 +115,28 @@ QVariantList EmojiModel::emojis(Category category) const
if (category == History) {
return history();
}
if (category == HistoryNoCustom) {
QVariantList list;
for (const auto &e : history()) {
auto emoji = qvariant_cast<Emoji>(e);
if (!emoji.isCustom) {
list.append(e);
}
}
return list;
}
if (category == Custom) {
return CustomEmojiModel::instance().filterModel({});
}
return _emojis[category];
}
QVariantList EmojiModel::tones(const QString &baseEmoji) const
{
return _tones.values(baseEmoji);
if (baseEmoji.endsWith("tone")) {
return EmojiTones::_tones.values(baseEmoji.split(":")[0]);
}
return EmojiTones::_tones.values(baseEmoji);
}
QHash<EmojiModel::Category, QVariantList> EmojiModel::_emojis;
@@ -123,21 +144,11 @@ QHash<EmojiModel::Category, QVariantList> EmojiModel::_emojis;
QVariantList EmojiModel::categories() const
{
return QVariantList{
// {QVariantMap{
// {"category", EmojiModel::Search},
// {"name", i18nc("Search for emojis", "Search")},
// {"emoji", QStringLiteral("🔎")},
// }},
{QVariantMap{
{"category", EmojiModel::History},
{"category", EmojiModel::HistoryNoCustom},
{"name", i18nc("Previously used emojis", "History")},
{"emoji", QStringLiteral("⌛️")},
}},
{QVariantMap{
{"category", EmojiModel::Custom},
{"name", i18nc("'Custom' is a category of emoji", "Custom")},
{"emoji", QStringLiteral("😏")},
}},
{QVariantMap{
{"category", EmojiModel::Smileys},
{"name", i18nc("'Smileys' is a category of emoji", "Smileys")},
@@ -185,3 +196,23 @@ QVariantList EmojiModel::categories() const
}},
};
}
QVariantList EmojiModel::categoriesWithCustom() const
{
auto cats = categories();
cats.removeAt(0);
cats.insert(0,
QVariantMap{
{"category", EmojiModel::History},
{"name", i18nc("Previously used emojis", "History")},
{"emoji", QStringLiteral("⌛️")},
});
cats.insert(1,
QVariantMap{
{"category", EmojiModel::Custom},
{"name", i18nc("'Custom' is a category of emoji", "Custom")},
{"emoji", QStringLiteral("🖼️")},
});
;
return cats;
}

View File

@@ -8,12 +8,18 @@
#include <QSettings>
struct Emoji {
Emoji(QString u, QString s, bool isCustom = false)
: unicode(std::move(std::move(u)))
, shortName(std::move(std::move(s)))
Emoji(QString unicode, QString shortname, bool isCustom = false)
: unicode(std::move(unicode))
, shortName(std::move(shortname))
, isCustom(isCustom)
{
}
Emoji(QString unicode, QString shortname, QString description)
: unicode(std::move(unicode))
, shortName(std::move(shortname))
, description(std::move(description))
{
}
Emoji() = default;
friend QDataStream &operator<<(QDataStream &arch, const Emoji &object)
@@ -33,11 +39,13 @@ struct Emoji {
QString unicode;
QString shortName;
QString description;
bool isCustom = false;
Q_GADGET
Q_PROPERTY(QString unicode MEMBER unicode)
Q_PROPERTY(QString shortName MEMBER shortName)
Q_PROPERTY(QString description MEMBER description)
Q_PROPERTY(bool isCustom MEMBER isCustom)
};
@@ -49,6 +57,7 @@ class EmojiModel : public QAbstractListModel
Q_PROPERTY(QVariantList history READ history NOTIFY historyChanged)
Q_PROPERTY(QVariantList categories READ categories CONSTANT)
Q_PROPERTY(QVariantList categoriesWithCustom READ categoriesWithCustom CONSTANT)
public:
static EmojiModel &instance()
@@ -63,13 +72,16 @@ public:
InvalidRole = 50,
DisplayRole = 51,
ReplacedTextRole = 52,
DescriptionRole = 53,
};
Q_ENUM(RoleNames);
enum Category {
Custom,
Search,
SearchNoCustom,
History,
HistoryNoCustom,
Smileys,
People,
Nature,
@@ -89,11 +101,14 @@ public:
Q_INVOKABLE QVariantList history() const;
Q_INVOKABLE static QVariantList filterModel(const QString &filter, bool limit = true);
Q_INVOKABLE static QVariantList filterModelNoCustom(const QString &filter, bool limit = true);
Q_INVOKABLE QVariantList emojis(Category category) const;
Q_INVOKABLE QVariantList tones(const QString &baseEmoji) const;
QVariantList categories() const;
QVariantList categoriesWithCustom() const;
Q_SIGNALS:
void historyChanged();
@@ -103,7 +118,6 @@ public Q_SLOTS:
private:
static QHash<Category, QVariantList> _emojis;
static QMultiHash<QString, QVariant> _tones;
// TODO: Port away from QSettings
QSettings m_settings;

View File

@@ -15,7 +15,9 @@
KeywordNotificationRuleModel::KeywordNotificationRuleModel(QObject *parent)
: QAbstractListModel(parent)
{
controllerConnectionChanged();
if (Controller::instance().activeConnection()) {
controllerConnectionChanged();
}
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, &KeywordNotificationRuleModel::controllerConnectionChanged);
}

View File

@@ -439,7 +439,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
case EventTypeRole:
return DelegateType::ReadMarker;
case TimeRole: {
const QDateTime eventDate = data(index(m_lastReadEventIndex.row() + 1, 0), TimeRole).toDateTime();
const QDateTime eventDate = data(index(m_lastReadEventIndex.row() + 1, 0), TimeRole).toDateTime().toLocalTime();
const KFormat format;
return format.formatRelativeDateTime(eventDate, QLocale::ShortFormat);
}

180
src/models/searchmodel.cpp Normal file
View File

@@ -0,0 +1,180 @@
// SPDX-FileCopyrightText: 2022 Tobias Fella <fella@posteo.de>
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "searchmodel.h"
#include "messageeventmodel.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include <KLocalizedString>
#include <connection.h>
#ifdef QUOTIENT_07
#include <csapi/search.h>
#endif
using namespace Quotient;
// TODO search only in the current room
SearchModel::SearchModel(QObject *parent)
: QAbstractListModel(parent)
{
}
QString SearchModel::searchText() const
{
return m_searchText;
}
void SearchModel::setSearchText(const QString &searchText)
{
m_searchText = searchText;
Q_EMIT searchTextChanged();
}
void SearchModel::search()
{
#ifdef QUOTIENT_07
Q_ASSERT(m_connection);
setSearching(true);
if (m_job) {
m_job->abandon();
m_job = nullptr;
}
SearchJob::RoomEventsCriteria criteria{
m_searchText,
{},
RoomEventFilter{
.rooms = {m_room->id()},
},
"recent",
SearchJob::IncludeEventContext{3, 3, true},
false,
none,
};
auto job = m_connection->callApi<SearchJob>(SearchJob::Categories{criteria});
m_job = job;
connect(job, &BaseJob::finished, this, [=] {
beginResetModel();
m_result = job->searchCategories().roomEvents;
endResetModel();
setSearching(false);
m_job = nullptr;
// TODO error handling
});
#endif
}
Connection *SearchModel::connection() const
{
return m_connection;
}
void SearchModel::setConnection(Connection *connection)
{
m_connection = connection;
Q_EMIT connectionChanged();
}
QVariant SearchModel::data(const QModelIndex &index, int role) const
{
#ifdef QUOTIENT_07
auto row = index.row();
const auto &event = *m_result->results[row].result;
switch (role) {
case DisplayRole:
return m_room->eventToString(*m_result->results[row].result);
case ShowAuthorRole:
return true;
case AuthorRole:
return QVariantMap{
{"isLocalUser", event.senderId() == m_room->localUser()->id()},
{"id", event.senderId()},
{"avatarMediaId", m_connection->user(event.senderId())->avatarMediaId(m_room)},
{"avatarUrl", m_connection->user(event.senderId())->avatarUrl(m_room)},
{"displayName", m_connection->user(event.senderId())->displayname(m_room)},
{"display", m_connection->user(event.senderId())->name()},
{"color", dynamic_cast<NeoChatUser *>(m_connection->user(event.senderId()))->color()},
{"object", QVariant::fromValue(m_connection->user(event.senderId()))},
};
case ShowSectionRole:
if (row == 0) {
return true;
}
return event.originTimestamp().date() != m_result->results[row - 1].result->originTimestamp().date();
case SectionRole:
return renderDate(event.originTimestamp());
case TimeRole:
return event.originTimestamp();
}
return MessageEventModel::DelegateType::Message;
#endif
return {};
}
int SearchModel::rowCount(const QModelIndex &parent) const
{
#ifdef QUOTIENT_07
if (m_result.has_value()) {
return m_result->results.size();
}
#endif
return 0;
}
QHash<int, QByteArray> SearchModel::roleNames() const
{
return {
{EventTypeRole, "eventType"},
{DisplayRole, "display"},
{AuthorRole, "author"},
{ShowSectionRole, "showSection"},
{SectionRole, "section"},
{TimeRole, "time"},
{ShowAuthorRole, "showAuthor"},
};
}
NeoChatRoom *SearchModel::room() const
{
return m_room;
}
void SearchModel::setRoom(NeoChatRoom *room)
{
m_room = room;
Q_EMIT roomChanged();
}
// TODO deduplicate with messageeventmodel
QString renderDate(const QDateTime &timestamp)
{
auto date = timestamp.toLocalTime().date();
if (date == QDate::currentDate()) {
return i18n("Today");
}
if (date == QDate::currentDate().addDays(-1)) {
return i18n("Yesterday");
}
if (date == QDate::currentDate().addDays(-2)) {
return i18n("The day before yesterday");
}
if (date > QDate::currentDate().addDays(-7)) {
return date.toString("dddd");
}
return QLocale::system().toString(date, QLocale::ShortFormat);
}
bool SearchModel::searching() const
{
return m_searching;
}
void SearchModel::setSearching(bool searching)
{
m_searching = searching;
Q_EMIT searchingChanged();
}

78
src/models/searchmodel.h Normal file
View File

@@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2022 Tobias Fella <fella@posteo.de>
// SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include <QAbstractListModel>
#include <QString>
#ifdef QUOTIENT_07
#include <csapi/search.h>
#endif
namespace Quotient
{
class Connection;
}
class NeoChatRoom;
class SearchModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged)
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
Q_PROPERTY(bool searching READ searching NOTIFY searchingChanged)
public:
enum Roles {
DisplayRole = Qt::DisplayRole,
EventTypeRole,
ShowAuthorRole,
AuthorRole,
ShowSectionRole,
SectionRole,
TimeRole,
};
Q_ENUM(Roles);
SearchModel(QObject *parent = nullptr);
QString searchText() const;
void setSearchText(const QString &searchText);
Quotient::Connection *connection() const;
void setConnection(Quotient::Connection *connection);
NeoChatRoom *room() const;
void setRoom(NeoChatRoom *room);
Q_INVOKABLE void search();
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
bool searching() const;
Q_SIGNALS:
void searchTextChanged();
void connectionChanged();
void roomChanged();
void searchingChanged();
private:
void setSearching(bool searching);
QString m_searchText;
Quotient::Connection *m_connection = nullptr;
NeoChatRoom *m_room = nullptr;
#ifdef QUOTIENT_07
Quotient::Omittable<Quotient::SearchJob::ResultRoomEvents> m_result = Quotient::none;
Quotient::SearchJob *m_job = nullptr;
#endif
bool m_searching = false;
};
QString renderDate(const QDateTime &dateTime);

View File

@@ -16,7 +16,7 @@ class Connection;
class UserDirectoryListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
Q_PROPERTY(QString keyword READ keyword WRITE setKeyword NOTIFY keywordChanged)
Q_PROPERTY(bool limited READ limited NOTIFY limitedChanged)

View File

@@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2022 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "userfiltermodel.h"
#include "userlistmodel.h"
bool UserFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
Q_UNUSED(sourceParent);
if (m_filterText.length() < 1) {
return false;
}
return sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::NameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|| sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::UserIdRole).toString().contains(m_filterText, Qt::CaseInsensitive);
}
QString UserFilterModel::filterText() const
{
return m_filterText;
}
void UserFilterModel::setFilterText(const QString &filterText)
{
m_filterText = filterText;
Q_EMIT filterTextChanged();
invalidateFilter();
}

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