Compare commits

...

133 Commits

Author SHA1 Message Date
Joshua Goins
ee02abfe37 snap: Update libquotient 2024-12-04 20:04:56 +00:00
James Graham
f0de235f37 Fix removeConnection
Check m_accountsLoading and m_connectionsLoading separately for removal as when loadAccessTokenFromKeyChain() fails m_connectionsLoading won't have an entry for it


(cherry picked from commit 57e7004e05)

9aadd773 Check m_accountsLoading and m_connectionsLoading separately for removal as...

Co-authored-by: James Graham <james.h.graham@protonmail.com>
2024-12-04 17:01:38 +00:00
l10n daemon script
9e9fe6d275 GIT_SILENT Sync po/docbooks with svn 2024-12-04 03:10:16 +00:00
l10n daemon script
f4ca5f0f34 GIT_SILENT Sync po/docbooks with svn 2024-12-03 03:18:08 +00:00
l10n daemon script
5f240fa05c GIT_SILENT made messages (after extraction) 2024-12-03 02:33:48 +00:00
Heiko Becker
1e29eca59a GIT_SILENT Update Appstream for new release 2024-12-03 01:09:52 +01:00
Heiko Becker
1f71ec3bf8 GIT_SILENT Upgrade release service version to 24.12.0. 2024-12-03 00:09:15 +01:00
Carl Schwan
64c5ad88f6 Remove system information from device display name
BUG: 496901


(cherry picked from commit 9d887ba3e7)

Co-authored-by: Tobias Fella <fella@posteo.de>
2024-12-02 16:07:56 +00:00
l10n daemon script
fb5a3c1c5c GIT_SILENT Sync po/docbooks with svn 2024-12-02 04:15:51 +00:00
l10n daemon script
4a5a83f94a GIT_SILENT Sync po/docbooks with svn 2024-11-29 03:16:44 +00:00
l10n daemon script
133edc249f 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"
2024-11-29 03:11:59 +00:00
Albert Astals Cid
da30e66127 GIT_SILENT Upgrade release service version to 24.11.90. 2024-11-28 09:19:03 +01:00
l10n daemon script
4516e1e0f4 GIT_SILENT Sync po/docbooks with svn 2024-11-28 03:07:16 +00:00
l10n daemon script
bd80f65163 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"
2024-11-28 03:04:07 +00:00
l10n daemon script
f828ecf282 GIT_SILENT Sync po/docbooks with svn 2024-11-27 03:10:17 +00:00
l10n daemon script
a0483167c5 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"
2024-11-27 03:07:27 +00:00
l10n daemon script
87288f508c GIT_SILENT made messages (after extraction) 2024-11-27 02:32:20 +00:00
l10n daemon script
dc184ed2fd GIT_SILENT Sync po/docbooks with svn 2024-11-26 03:08:20 +00:00
l10n daemon script
49e1bf9ab1 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"
2024-11-26 03:05:24 +00:00
l10n daemon script
74acf3f9dc GIT_SILENT made messages (after extraction) 2024-11-24 02:34:26 +00:00
l10n daemon script
38205d2791 GIT_SILENT Sync po/docbooks with svn 2024-11-23 03:05:59 +00:00
l10n daemon script
81da926d4f 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"
2024-11-23 03:02:07 +00:00
Carl Schwan
1018fe5d3f Remove layout attached properties
They don't do anything

(cherry picked from commit fbb2afdb49)
2024-11-22 09:05:04 -05:00
Thiago Sueto
58b32dd50f Make height of chatbar, userinfo bar and side tab bar the same
|Current state|With this MR|
|-|-|
|![Screenshot_20241115_171736](/uploads/858a8ca21a6f4024a20f6ba32225aece/Screenshot_20241115_171736.png)|![Screenshot_20241115_171650](/uploads/115f99c7bb2b93a542c42647f9cc25c7/Screenshot_20241115_171650.png)|

(cherry picked from commit 240cf6a0ed)
2024-11-22 09:05:04 -05:00
Tobias Fella
82184b895a Escape display name in WelcomePage
(cherry picked from commit dcd9ee93de)
2024-11-22 09:05:04 -05:00
Joshua Goins
da0f6f78a4 Fix undefined access when loading stickers in chat
We need a check here, because stickers (and really, any images without a
tempSource) will try to access an undefined object.

This fixes the error:
"qrc:/qt/qml/org/kde/neochat/timeline/ImageComponent.qml:106: TypeError: Cannot read property 'source' of undefined"

(cherry picked from commit 2a8cd74ab1)
2024-11-22 09:05:03 -05:00
Joshua Goins
cfd06d064c Default to a more sensible sticker size
If we do not set the width/height for stickers (which don't have any)
then the height is okay, but the message has the maximum width which
looks odd.

Instead, let's limit all stickers to 256px and it makes them look much
nicer in chat.

(cherry picked from commit 63bc7055c2)
2024-11-22 09:05:03 -05:00
Joshua Goins
a90e9ae92a Add a comment that these are not normal quotation marks
It can be hard to tell depending on which font you're viewing the code
with.

(cherry picked from commit 1cca9733d6)
2024-11-22 09:05:03 -05:00
Joshua Goins
8ab0002057 TextHandler: Use the fancy Unicode quotation characters
As per our HIG, we should use these in quotations instead of the normal
quote characters.

(cherry picked from commit 1104da5e2c)
2024-11-22 09:05:03 -05:00
Joshua Goins
e1840be234 Limit the width of a user's QR code
This fixes the lopsided layout in the user details dialog.

(cherry picked from commit 3a9718c09d)
2024-11-22 09:05:02 -05:00
Joshua Goins
d6ecaaa344 RoomManager: Unify the resolveResource overloads
Every time I look at how resource resolving works, I always trip over
this unused overload. This behaves *different* than the other overload,
which has special cases for handling invalid Uris.

Now whether you pass in a Uri or a QString, it should behave the same.

(cherry picked from commit 55362c5573)
2024-11-22 09:05:02 -05:00
Joshua Goins
0c08c2ab89 Set the size of custom emoticons to the font height, and fix alignment
Currently custom emojis render weirdly in NeoChat. Not only are they
large, they're also in charge and like to mess up the layout of the
text.

Now that's fixed and they'll take up the same height as the surrounding
text. It's now centered in the text too.

(cherry picked from commit 0bba2299b3)
2024-11-22 09:05:02 -05:00
Joshua Goins
39ff11e059 Add icons to the recommended space actions, fix spacing of the items
(cherry picked from commit 45685af9e9)
2024-11-22 09:05:01 -05:00
Joshua Goins
93254431c5 Fix restoring the last used space on desktop
This was supposed to work, but it's done in the wrong order. We need to
set the current space first, and then select the room - otherwise
it doesn't get restored.

(cherry picked from commit 6c416a9338)
2024-11-22 09:05:01 -05:00
Joshua Goins
fc14a8eac8 Ensure it's not possible for the recommended space avatar to assert
(cherry picked from commit 1b0027e1d2)
2024-11-22 09:05:01 -05:00
Joshua Goins
50759bb3ca Fix avatars not loading in the room completion model
(cherry picked from commit 2409adf516)
2024-11-22 09:05:01 -05:00
Joshua Goins
23134d8e72 Make sure RoomInformation's source is type url
(cherry picked from commit 554801dfe4)
2024-11-22 09:05:01 -05:00
Joshua Goins
7cd095f76a Remove now unused NeoChatRoomMember::avatarMediaId()
(cherry picked from commit 20c23917e9)
2024-11-22 09:05:01 -05:00
Joshua Goins
d5c3054da4 Remove more needless usages of makeMediaUrl
This is only really needed in specific cases, e.g. localUser which isn't
attached to a connection and thus needs a little help. Notes for when
this is needed is added for future readers.

(cherry picked from commit ef953b7574)
2024-11-22 09:05:00 -05:00
Joshua Goins
ae12c838bd Change how room avatars are passed, fix friend avatars not loading
The problem lies in how media URLs work, in this case it the old
NeoChatRoom::avatarMediaId could pass a mxc url *or* a path that can
be put into root.connection.makeMediaUrl. So normal rooms with avatars
loaded, but never friends because room members gave the mxc URL.

Instead, change everything to use avatarMediaUrl which corrects this
issue by always passing a mxc URL to QML. This also removes the need to
call makeMediaUrl.

Fixes #675

(cherry picked from commit 6b79795229)
2024-11-22 09:05:00 -05:00
Joshua Goins
51727dd345 Fix ShareActionStub for Windows and Android
Apparently, we are supposed to be setting source file properties for our QML files *before*
the QML module is created. Doing it after seemed to work until Qt 6.8, where it finally
broke. Notably, this makes the Android version work again but might also affect Windows.

(cherry picked from commit a39194b2ad)

Co-authored-by: Joshua Goins <josh@redstrate.com>
2024-11-22 13:45:04 +00:00
l10n daemon script
5611b000fb GIT_SILENT Sync po/docbooks with svn 2024-11-20 03:11:39 +00:00
l10n daemon script
461896e228 GIT_SILENT Sync po/docbooks with svn 2024-11-19 03:09:14 +00:00
Carl Schwan
e388536a03 Make sure the loading text for a new login wraps
Title

BUG: 493869


(cherry picked from commit aff0402f71)

58b69cf1 Make sure the loading text for a new login wraps

Co-authored-by: James Graham <james.h.graham@protonmail.com>
2024-11-18 08:42:36 +00:00
Carl Schwan
61f22edd86 Make sure that for multiple sed edits we grab the eventID of the original message not the replacement
(cherry picked from commit 24e1a0a596)

Co-authored-by: James Graham <james.h.graham@protonmail.com>
2024-11-18 08:35:24 +00:00
l10n daemon script
9e368691d6 GIT_SILENT Sync po/docbooks with svn 2024-11-18 03:18:50 +00:00
l10n daemon script
dad2b3ec8f 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"
2024-11-18 03:14:09 +00:00
Joshua Goins
8821c37ff8 Don't show the file name underneath the image
This still keeps custom image descriptions, but no longer shows it for
images where it was the same as their filename.

(cherry picked from commit 437c981d30)
2024-11-16 13:54:46 -05:00
Thiago Sueto
c105170eca Make top margin consistent across Neochat settings
This standardizes on the same value used for KirigamiAddons pages like AboutKDE and About, namely largeSpacing * 4.

Now, when switching between settings pages you no longer have settings inconsistently changing heights willy nilly, header notwithstanding.

The only page that's missing is the Spellchecking page, as that needs to be fixed in Kirigami Addons' private Sonnet page.

(cherry picked from commit 396cc8e8ef)
2024-11-16 13:41:58 -05:00
Joshua Goins
b07c04eddc Change the room alias text color to disabled
It's less important than the title, and this should reduce it's visual
prominence.

(cherry picked from commit 0334cae4c8)
2024-11-16 13:30:20 -05:00
Joshua Goins
7aa0f68b10 DelegateContextMenu: Add support for separators in the mobile menu too
(cherry picked from commit a3f5962809)
2024-11-16 13:30:20 -05:00
Joshua Goins
cbdae4c312 DelegateContextMenu: Add support for separator actions
(cherry picked from commit d34f89fc4b)
2024-11-16 13:30:20 -05:00
Joshua Goins
9210940556 Hide the category list in the emoji picker when there is none
This is easy to test if you have no stickers. It should no longer have
a weird empty space above the placeholder message.

(cherry picked from commit a909ed498f)
2024-11-16 13:30:19 -05:00
Joshua Goins
d8489527b4 Improve how stickers appear in the emoji picker
First, the fill mode for the sticker images shouldn't stretch them.
Also make sure there is enough padding in the category so the image
doesn't appear larger than the button. Finally, set the source size for
the images so Qt can smooth them out better.

(cherry picked from commit 16f4e17e8f)
2024-11-16 13:30:19 -05:00
Joshua Goins
64c9cd97de Settings: Use symbolic version of the NeoChat icon
To match the rest of the icons in this sidebar, we can reuse our tray
icon.

(cherry picked from commit 0e9592a96c)
2024-11-16 13:30:19 -05:00
Joshua Goins
119a9890b1 Add placeholder icon when there's no emojis or stickers
(cherry picked from commit 704ee6a53a)
2024-11-16 13:30:19 -05:00
Joshua Goins
69be6b5939 Settings: Request symbolic versions of the icons
According to the HIG, we should be using symbolic versions of these
icons at this size. Not that we have symbolic versions for these icons
yet, but it's still safe to do as they'll fall back to the old ones.

(cherry picked from commit 5b9afbce9a)
2024-11-16 13:30:19 -05:00
Joshua Goins
112152f2df Port from deprecated AboutKDE component to AboutKDEPage
(cherry picked from commit f802dbe686)
2024-11-16 13:30:18 -05:00
Joshua Goins
2ef634a6cb Don't scroll up when clicking on the same room over and over
If you try to click on your current room in the list, it scrolls up the
messages a bit. This is because in RoomManager::visitRoom it's being
called with an empty eventId and we will happily emit a goToEvent. This
is despite there being nothing to go to.

Fixes #677.

(cherry picked from commit 2379e3d83b)
2024-11-16 13:30:18 -05:00
Joshua Goins
fd31b4fb74 Add margins to the room drawer header to match Kirigami
Otherwise it sticks to the left of the drawer and looks kinda ugly.

(cherry picked from commit 9e90ac0412)
2024-11-16 13:30:18 -05:00
Joshua Goins
3b12520fa2 Make it so the filename is filled out by default when saving files
This was never ported from the Qt labs platform FileDialog, because
currentFile doesn't exist anymore. It's now called selectedFile.

(cherry picked from commit 31ef0a5223)
2024-11-16 13:30:18 -05:00
Joshua Goins
24718a5f72 Improve the appearance of the welcome page user list
Before it only listed the user id, and nothing else. If you had multiple
accounts, it's a little difficult to tell them apart. Now the user
selection appears like how they are displayed elsewhere in NeoChat, with
the display name and avatar.

| Before | After |
| ------ | ------ |
|   ![Screenshot_20241115_221425](/uploads/3986e4c7bbb7dcdca67ee30bb529767e/Screenshot_20241115_221425.png){width=786 height=822}     |        ![Screenshot_20241115_221149](/uploads/57eb1a7e57ba5ae8c41dd922cbf39c62/Screenshot_20241115_221149.png){width=786 height=822} |

(cherry picked from commit 14c58acea1)
2024-11-16 13:30:18 -05:00
Joshua Goins
db62bacc7e Port from Kirigami Add-ons Banner to Kirigami InlineMessage
(cherry picked from commit 3f6fa94289)
2024-11-16 13:30:18 -05:00
l10n daemon script
6500669b67 GIT_SILENT Sync po/docbooks with svn 2024-11-15 03:10:56 +00:00
l10n daemon script
557d151ed4 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"
2024-11-15 03:06:59 +00:00
l10n daemon script
95ffd485b4 GIT_SILENT made messages (after extraction) 2024-11-15 02:31:39 +00:00
l10n daemon script
ebd38fb435 GIT_SILENT Sync po/docbooks with svn 2024-11-14 03:10:10 +00:00
l10n daemon script
a5b999e682 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"
2024-11-14 03:06:40 +00:00
l10n daemon script
41d34fc0e4 GIT_SILENT Sync po/docbooks with svn 2024-11-13 03:08:49 +00:00
l10n daemon script
b51194f90f 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"
2024-11-13 03:05:22 +00:00
l10n daemon script
80ac9e1ba7 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"
2024-11-12 03:11:52 +00:00
l10n daemon script
e3874c824a GIT_SILENT Sync po/docbooks with svn 2024-11-11 03:23:01 +00:00
l10n daemon script
6599c6b609 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"
2024-11-11 03:15:47 +00:00
l10n daemon script
13d522221c GIT_SILENT made messages (after extraction) 2024-11-11 02:40:16 +00:00
Joshua Goins
dd8f926f32 PollHandler: Make sure it's not constructible from QML
(cherry picked from commit d6b780762e)
2024-11-10 10:29:26 -05:00
Joshua Goins
258312e798 PollHandler: Ensure that m_pollStartEvent is always initialized to null
Otherwise it may be undefined, and we DO create default-constructed
PollHandler. For example, one is used as a fallback poll object
in NeoChatRoom::poll.

This is blind fix for a pretty nasty poll-related crash we saw a few
months ago.

BUG: 493649
(cherry picked from commit 5ef66b5cf6)
2024-11-10 10:29:17 -05:00
Joshua Goins
43d40c7e75 Add m.room.create state events to sync_response
In case we need to access the creation state in an appium test in the
future.

(cherry picked from commit 85ee5084b6)
2024-11-10 07:40:41 -05:00
Joshua Goins
cbcc9a6514 Hide rooms that have a defined room type
I have a room with a custom type that's only for holding data, and
doesn't need to be shown in the room list. Currently the spec is a bit
vague about what clients should do, but hiding them is probably fine
for now.

(cherry picked from commit bb9ce117de)
2024-11-10 07:40:41 -05:00
l10n daemon script
625048610b GIT_SILENT Sync po/docbooks with svn 2024-11-10 03:30:48 +00:00
l10n daemon script
fa47b67e3d 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"
2024-11-10 03:16:42 +00:00
Carl Schwan
9347a66acf RoomGeneralPage: Add missing separator
And some other minor fixes

(cherry picked from commit 00c5aa26bb)
2024-11-09 18:12:25 -05:00
Joshua Goins
317df56ffa Make closing link previews instant, as it should be
We were missing a endResetModel() call, now with it added the removal
happens instantly.

(cherry picked from commit bae4de227c)
2024-11-09 18:12:25 -05:00
Joshua Goins
fed9197716 Stop being able to crash NeoChat by pressing a button repeatedly
If you spam click the "Close link preview" button, it's possible to
crash NeoChat. This is because the index check is wrong for the array
size.

It's possible to even do this due to a bug causing the removal to be
reflected visually too slowly, that's fixed in the next commit.

(cherry picked from commit 253f891c5a)
2024-11-09 18:12:25 -05:00
Joshua Goins
1e892599e9 Improve clicking link previews
First of all, clicking on them actually works - because we were missing
an import for RoomManager. Secondly, we use a dedicated TapHandler
since onLinkActivated sucks. We want to be able to click anywhere on the
preview to go to the website/room anyway.

(cherry picked from commit 6966159062)
2024-11-09 18:12:25 -05:00
Joshua Goins
b7229ca0cf Don't set isThread on the message and file delegate context menus
It doesn't have a property called isThread, and I don't know where it
went - if it ever existed?

(cherry picked from commit 07d3b80c3e)
2024-11-09 18:12:25 -05:00
Joshua Goins
953b711823 Make fullscreen images focused when they're opened
Otherwise keyboard shortcuts don't work until you tap the image, which
makes no sense.

BUG: 484322
(cherry picked from commit a41d0f3214)
2024-11-09 18:12:25 -05:00
Joshua Goins
01d903efd3 Fix viewing any kind of data in developer tools
Fix pageStack being undefined, so we're able to view event data again.

(cherry picked from commit 1ee15de78b)
2024-11-09 18:12:25 -05:00
Carl Schwan
241dd81932 Update checkbox of PollComponent
Use FormCheckDelegate instead of a CheckBox inside a RowLayout. This
increase the click area particularly on mobile.

(cherry picked from commit b044358970)
2024-11-09 18:12:24 -05:00
Oliver Beard
f6dfe0cbcf timeline: Round separators for replies and link previews
(cherry picked from commit d2e11bb3bb)
2024-11-09 18:12:24 -05:00
Joshua Goins
f10b97139c README: Change snap store badge to the one from apps.kde.org
It seems CORS is blocking access to the badge, but we have rehosted on
apps.kde.org.

(cherry picked from commit a55bac899c)
2024-11-09 18:12:24 -05:00
Joshua Goins
385c5b3405 Update network proxy page with the improved version from Tokodon
This functions the same, but looks a bit nicer.

(cherry picked from commit c2380fb8df)
2024-11-09 16:28:47 -05:00
Joshua Goins
7bc6f906f8 Update desktop file and app description to match AppStream data
This was updated to "Chat on Matrix" but in other places it was never
switched from "Matrix client" and the like. Now it should be more
consistent.

(cherry picked from commit f31c644b13)
2024-11-09 16:28:47 -05:00
Joshua Goins
b8b1434a95 Clarify that sorting rooms by activity isn't the only thing it does
Recently, it also sorts rooms based on unread notification count and
importance. This adds a clarification to the setting so users (like me)
aren't confused why it isn't sorting only by activity.

(cherry picked from commit 26cd621d0e)
2024-11-09 16:28:47 -05:00
l10n daemon script
85c7a4bcb3 GIT_SILENT Sync po/docbooks with svn 2024-11-09 03:10:22 +00:00
Albert Astals Cid
84b698a7e8 GIT_SILENT Upgrade release service version to 24.11.80. 2024-11-08 19:06:28 +01:00
l10n daemon script
7b249e9fa6 GIT_SILENT Sync po/docbooks with svn 2024-11-08 01:30:13 +00:00
l10n daemon script
46593ef68f GIT_SILENT Sync po/docbooks with svn 2024-11-07 01:31:11 +00:00
Eren Karakas
b70f73c7d6 Make send message and insert newline shortcuts configurable
Currently both Enter and Ctrl+Enter send the message in ChatBar on
desktop. This might be unexpected behavior to users coming from other
chat applications (eg. WhatsApp, Telegram, Element) as those send
with Enter only by default. They allow changing send to Ctrl+Enter
in settings and other option is used to insert a newline.

BUG: 476758
2024-11-06 21:09:58 +00:00
l10n daemon script
ece5e34fa2 GIT_SILENT Sync po/docbooks with svn 2024-11-06 01:31:11 +00:00
Joshua Goins
74b400288d ManualRoomDialog: Use Window.window attached property
This fixes a runtime error since applicationWindow is undefined.
2024-11-05 16:45:37 +00:00
Joshua Goins
83f19b0631 ExploreRoomsPage: Fix "Enter a room address" button not working
This was due to an undefined applicationWindow singleton, but we don't
actually need it and can use Overlay.overlay directly.
2024-11-05 16:45:37 +00:00
l10n daemon script
c905d2d6fb GIT_SILENT Sync po/docbooks with svn 2024-11-05 01:30:46 +00:00
l10n daemon script
d0c1eb2f04 GIT_SILENT Sync po/docbooks with svn 2024-11-04 01:28:25 +00:00
Tobias Fella
d7d9d29c1d Remove no longer needed ifdefs 2024-11-03 18:42:56 +01:00
Tobias Fella
2a3f019ec6 Port away from Quotient::Omittable 2024-11-03 18:26:46 +01:00
Tobias Fella
d384d50b0d Remove olm target check
Olm isn't option in libQuotient anymore, there's no point in checking
2024-11-03 18:21:19 +01:00
Tobias Fella
be8cb12bba Require libQuotient 0.9 2024-11-03 17:48:40 +01:00
l10n daemon script
a1aa2918be GIT_SILENT Sync po/docbooks with svn 2024-11-03 01:27:04 +00:00
l10n daemon script
d7536bccb3 GIT_SILENT Sync po/docbooks with svn 2024-11-02 01:29:54 +00:00
l10n daemon script
6b677355e1 GIT_SILENT made messages (after extraction) 2024-11-02 00:39:52 +00:00
James Graham
85d625f6ac Delete ActionsHandler
Move the fucntionality of ActionsHandler into ChatbarCache and ActionsModel.

At this stage there wasn't much left that is was doing and the functionality could easily move.
2024-11-01 17:00:08 +00:00
l10n daemon script
f5d6f87afe GIT_SILENT Sync po/docbooks with svn 2024-11-01 01:29:19 +00:00
Joshua Goins
31d755f407 ManualRoomDialog: Change title of the dialog to reduce duplication
"Room ID or Alias" is duplicated twice here, once in the dialog title
and a second time as the label for the text field. Let's change it to a
more suitable name "Manually Enter a Room".
2024-10-30 22:25:53 -04:00
Joshua Goins
ebfc20d4b4 ExploreRoomsPage: Add better text to the "Enter a room address" button
This adds a short explanatory label to the "Enter a room address" button
in this list, in case the user does not know where to find their room
address.

Also changes the name of the button to "Enter a Room Manually" to refer
that you can enter aliases here as well.
2024-10-30 22:24:20 -04:00
l10n daemon script
b83d42103f GIT_SILENT Sync po/docbooks with svn 2024-10-31 01:30:42 +00:00
Heiko Becker
c9856347fe GIT_SILENT Update Appstream for new release
(cherry picked from commit 4b7011fe14)
2024-10-31 01:14:26 +01:00
l10n daemon script
7224c92caf 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"
2024-10-30 01:23:46 +00:00
l10n daemon script
a84f98c96f GIT_SILENT made messages (after extraction) 2024-10-30 00:39:47 +00:00
l10n daemon script
a40bccc29d GIT_SILENT Sync po/docbooks with svn 2024-10-28 01:33:27 +00:00
l10n daemon script
171897161c GIT_SILENT made messages (after extraction) 2024-10-28 00:40:09 +00:00
l10n daemon script
013ad49e2b GIT_SILENT Sync po/docbooks with svn 2024-10-27 01:34:19 +00:00
l10n daemon script
b357586164 GIT_SILENT made messages (after extraction) 2024-10-27 00:40:08 +00:00
James Graham
5642f3416a Pester Network Error Messages
Stop sending a pester message using showPassiveNotification every time there is a network error. There is already a proper handling with `isOnline` in `NeochatConnection`. This just causes issues overlapping content.

BUG: 488572
2024-10-26 12:28:28 +00:00
l10n daemon script
9bbb1710df GIT_SILENT made messages (after extraction) 2024-10-26 00:40:19 +00:00
l10n daemon script
e2b7679252 GIT_SILENT Sync po/docbooks with svn 2024-10-25 01:30:33 +00:00
l10n daemon script
5c353cd4b5 GIT_SILENT made messages (after extraction) 2024-10-25 00:40:01 +00:00
l10n daemon script
cba6dc994f GIT_SILENT Sync po/docbooks with svn 2024-10-24 01:29:20 +00:00
l10n daemon script
b0c4b7fc2a GIT_SILENT made messages (after extraction) 2024-10-24 00:39:47 +00:00
James Graham
ed7aff1f24 Updates for further event content changes
Adapt to https://github.com/quotient-im/libQuotient/pull/812
2024-10-23 16:38:51 +00:00
l10n daemon script
33f4be0d88 GIT_SILENT made messages (after extraction) 2024-10-23 00:40:25 +00:00
l10n daemon script
1178cafef0 GIT_SILENT made messages (after extraction) 2024-10-22 00:39:47 +00:00
l10n daemon script
1be97e65b4 GIT_SILENT Sync po/docbooks with svn 2024-10-21 01:30:29 +00:00
Carl Schwan
634cefc694 Simplify appstream summary
- matrix -> Matrix
- Remove "with your friends" as NeoChat is not only about chatting with
  your friend

CCBUG: 480167
2024-10-20 23:33:48 +00:00
154 changed files with 20222 additions and 20310 deletions

View File

@@ -110,7 +110,7 @@
{
"type": "git",
"url": "https://github.com/quotient-im/libQuotient.git",
"branch": "0.8.x",
"branch": "dev",
"disable-submodules": true
}
],

View File

@@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "24")
set(RELEASE_SERVICE_VERSION_MINOR "11")
set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION_MINOR "12")
set(RELEASE_SERVICE_VERSION_MICRO "0")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
@@ -107,7 +107,7 @@ if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
endif()
find_package(QuotientQt6 0.8.2)
find_package(QuotientQt6 0.9)
set_package_properties(QuotientQt6 PROPERTIES
TYPE REQUIRED
DESCRIPTION "Qt wrapper around Matrix API"
@@ -115,11 +115,6 @@ set_package_properties(QuotientQt6 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

View File

@@ -11,7 +11,7 @@ A Qt/QML based Matrix client.
<a href='https://matrix.org'><img src='https://matrix.org/docs/legacy/made-for-matrix.png' alt='Made for Matrix' height=64 target=_blank /></a>
<a href='https://flathub.org/apps/details/org.kde.neochat'><img width='190px' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-i-en.png'/></a>
<a href='https://snapcraft.io/neochat'><img width='190px' alt='Download on the Snap Store' src='https://snapcraft.io/static/images/badges/en/snap-store-black.svg'/></a>
<a href='https://snapcraft.io/neochat'><img width='190px' alt='Download on the Snap Store' src='https://apps.kde.org/store_badges/snapstore/en.svg'/></a>
## Introduction

View File

@@ -5,6 +5,26 @@
"!room_id_1234:localhost:1234": {
"state": {
"events": [
{
"content": {
"m.federate": true,
"predecessor": {
"event_id": "$something:example.org",
"room_id": "!oldroom:example.org"
},
"room_version": "11"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.create",
"unsigned": {
"age": 1234,
"membership": "join"
}
},
{
"type": "m.room.member",
"state_key": "@user:localhost:1234",
@@ -26,6 +46,26 @@
},
"timeline": {
"events": [
{
"content": {
"m.federate": true,
"predecessor": {
"event_id": "$something:example.org",
"room_id": "!oldroom:example.org"
},
"room_version": "11"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.create",
"unsigned": {
"age": 1234,
"membership": "join"
}
},
{
"type": "m.room.message",
"sender": "@user:localhost:1234",

View File

@@ -53,12 +53,6 @@ ecm_add_test(
TEST_NAME messageeventmodeltest
)
ecm_add_test(
actionshandlertest.cpp
LINK_LIBRARIES neochat Qt::Test
TEST_NAME actionshandlertest
)
ecm_add_test(
windowcontrollertest.cpp
LINK_LIBRARIES neochat Qt::Test

View File

@@ -1,41 +0,0 @@
// SPDX-FileCopyrightText: 2023 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 <QTest>
#include "actionshandler.h"
#include "chatbarcache.h"
#include "testutils.h"
class ActionsHandlerTest : public QObject
{
Q_OBJECT
private:
Quotient::Connection *connection = Quotient::Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
private Q_SLOTS:
void nullObject();
};
void ActionsHandlerTest::nullObject()
{
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
ActionsHandler::handleMessageEvent(nullptr, nullptr);
auto chatBarCache = new ChatBarCache(this);
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
ActionsHandler::handleMessageEvent(nullptr, chatBarCache);
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
ActionsHandler::handleMessageEvent(room, nullptr);
// The final one should throw no warning so we make sure.
QTest::failOnWarning("ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
ActionsHandler::handleMessageEvent(room, chatBarCache);
}
QTEST_GUILESS_MAIN(ActionsHandlerTest)
#include "actionshandlertest.moc"

View File

@@ -535,7 +535,7 @@ void TextHandlerTest::componentOutput_data()
QVariantMap{{QStringLiteral("class"), QStringLiteral("html")}}}};
QTest::newRow("quote") << QStringLiteral("<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>")
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
MessageComponent{MessageComponentType::Quote, QStringLiteral("\"blockquote\""), {}}};
MessageComponent{MessageComponentType::Quote, QStringLiteral("blockquote"), {}}};
QTest::newRow("no tag first paragraph") << QStringLiteral("Text\n<p>Text</p>")
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};

View File

@@ -50,38 +50,31 @@
<name xml:lang="x-test">xxNeoChatxx</name>
<name xml:lang="zh-CN">NeoChat</name>
<name xml:lang="zh-TW">NeoChat</name>
<summary>Chat with your friends on matrix</summary>
<summary xml:lang="ar">دردش مع أصدقائك على ماتركس</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="cs">Mluvte se svými přáteli na Matrixu</summary>
<summary xml:lang="de">Mit den Freunden auf Matrix unterhalten</summary>
<summary xml:lang="el">Συνομιλήστε με τους φίλους σας στο matrix</summary>
<summary xml:lang="en-GB">Chat with your friends on matrix</summary>
<summary xml:lang="eo">Babilu kun viaj amikoj sur matrix</summary>
<summary xml:lang="es">Charle con sus amigos en matrix</summary>
<summary xml:lang="eu">Berriketan jardun zure lagunekin «Matrix»en</summary>
<summary xml:lang="fi">Keskustelu ystäviesi kanssa Matrixissa</summary>
<summary xml:lang="fr">Discuter avec vos ami(e)s sur le réseau Matrix</summary>
<summary xml:lang="gl">Charle coas súas amizades en Matrix.</summary>
<summary xml:lang="he">התכתבות עם החברים שלך ב־matrix</summary>
<summary xml:lang="hu">Csevegjen barátaival a matrixon</summary>
<summary xml:lang="ia">Starta Conversation con tu amicos sur matrix</summary>
<summary xml:lang="it">Conversa con i tuoi contatti su matrix</summary>
<summary xml:lang="ka">ესაუბრეთ მეგობრებს Matrix-ზე</summary>
<summary xml:lang="ko">Matrix를 사용하여 친구들과 대화하기</summary>
<summary xml:lang="lv">Tērzējiet ar saviem draugiem „Matrix“ tīklā</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="pl">Rozmawiaj ze swoimi znajomymi w Matriksie</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">Matrixte 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 xml:lang="zh-CN">在 Matrix 上与朋友聊天</summary>
<summary xml:lang="zh-TW">在 Matrix 上與您的朋友聊天</summary>
<summary>Chat on Matrix</summary>
<summary xml:lang="ar">دردش على ماتركس</summary>
<summary xml:lang="ca">Xat a Matrix</summary>
<summary xml:lang="ca-valencia">Xat a Matrix</summary>
<summary xml:lang="de">Über Matrix unterhalten</summary>
<summary xml:lang="en-GB">Chat on Matrix</summary>
<summary xml:lang="es">Charle en Matrix</summary>
<summary xml:lang="eu">Berriketa Matrix-en</summary>
<summary xml:lang="fi">Keskustelu Matrixissä</summary>
<summary xml:lang="fr">Discuter sur Matrix</summary>
<summary xml:lang="gl">Charlar en Matrix</summary>
<summary xml:lang="hu">Csevegés Matrixon</summary>
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
<summary xml:lang="it">Chat su Matrix</summary>
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
<summary xml:lang="nl">Chat op Matrix</summary>
<summary xml:lang="nn">Prat med via Matrix</summary>
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
<summary xml:lang="sl">Klepet na Matrixu</summary>
<summary xml:lang="sv">Chatta på Matrix</summary>
<summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary>
<summary xml:lang="tr">Matrix Üzerinde Sohbet</summary>
<summary xml:lang="uk">Спілкування у Matrix</summary>
<summary xml:lang="x-test">xxChat on Matrixxx</summary>
<summary xml:lang="zh-TW">在 Matrix 上聊天</summary>
<description>
<p>NeoChat is a chat app that lets you take full advantage of the Matrix network. It provides you with a secure way to send text messages, videos and audio files to your family, colleagues and friends.</p>
<p xml:lang="ar">نيوتشات هو تطبيق دردشة يتيح لك الاستفادة الكاملة من شبكة Matrix. فهو يوفر لك طريقة آمنة لإرسال الرسائل النصية ومقاطع الفيديو والملفات الصوتية إلى عائلتك وزملائك وأصدقائك.</p>
@@ -105,6 +98,7 @@
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
<p xml:lang="pl">NoeChat to aplikacja do rozmów, która umożliwia wykorzystanie wszystkich możliwości Matriksa. Umożliwia wysyłanie wiadomości tekstowych, filmów i dźwięków w bezpieczny sposób do twojej rodziny, kolegów i przyjaciół.</p>
<p xml:lang="ru">NeoChat — приложение для общения, предоставляющее все преимущества сети Matrix. С его помощью можно безопасно отправлять текстовые сообщения, видеозаписи и звуковые файлы родственникам, коллегам и друзьям.</p>
<p xml:lang="sl">NeoChat je aplikacija za klepet, ki vam omogoča, da v celoti izkoristite omrežje Matrix. Zagotavlja vam varen način za pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, sodelavcem in prijateljem.</p>
<p xml:lang="sv">NeoChat är ett chattprogram som låter dig dra full nytta av Matrix-nätverket. Det ger dig ett säkert sätt att skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner.</p>
<p xml:lang="tr">NeoChat, Matrix ağının tüm özelliklerini kullanan bir sohbet uygulamasıdır. Ailenize, arkadaşlarınıza ve iş arkadaşlarınıza metin iletileri, ses ve video dosyaları göndermenin kolay bir yolunu sunar.</p>
@@ -198,6 +192,7 @@
<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>
@@ -358,8 +353,10 @@
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
<caption xml:lang="pl">Odkrywaj nowe społeczności w Przestrzeniach Matriksa</caption>
<caption xml:lang="ru">Поиск новых сообществ с помощью Matrix Spaces</caption>
<caption xml:lang="sl">Odkrijte nove skupnosti z Matrix Spaces</caption>
<caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption>
<caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption>
<caption xml:lang="tr">Matrix Alanlar ile yeni topluluklar keşfedin</caption>
<caption xml:lang="uk">Пошук нових спільнот за допомогою Matrix Spaces</caption>
<caption xml:lang="x-test">xxDiscover new communities with Matrix Spacesxx</caption>
@@ -448,6 +445,8 @@
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="24.12.0" date="2024-12-12"/>
<release version="24.08.3" date="2024-11-07"/>
<release version="24.08.2" date="2024-10-10"/>
<release version="24.08.1" date="2024-09-12"/>
<release version="24.08.0" date="2024-08-22"/>

View File

@@ -87,47 +87,27 @@ GenericName[uk]=Клієнт Matrix
GenericName[x-test]=xxMatrix Clientxx
GenericName[zh_CN]=Matrix 客户端
GenericName[zh_TW]=Matrix 用戶端
Comment=Client for the Matrix protocol
Comment[ar]=عميل لميفاق ماتركس
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[eo]=Kliento por la Matrix-protokolo
Comment[es]=Cliente para el protocolo Matrix
Comment[eu]=Matrix protokolorako bezeroa
Comment[fi]=Asiakas Matrix-yhteyskäytännölle
Comment[fr]=Client pour le protocole « Matrix »
Comment[gl]=Cliente para o protocolo Matrix.
Comment[he]=לקוח לפרוטוקול Matrix
Comment[hu]=Kliens a Matrix protokollhoz
Comment[ia]=Cliente per le protocollo de Matrix
Comment[id]=Klien untuk protokol Matrix
Comment[ie]=Un cliente del protocol Matrix
Comment[it]=Client per il protocollo Matrix
Comment[ka]=კლიენტი Matrix-ის პროტოკოლისთვის
Comment[ko]=Matrix 프로토콜용 클라이언트
Comment[lt]=Matrix protokolo kliento programa
Comment[lv]=Klients „Matrix“ protokolam
Comment[nl]=Client voor het Matrix-protocol
Comment[nn]=Klient for Matrix-protokollen
Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ
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
Comment[ta]=Matrix நெறிமுறைக்கான வாங்கி
Comment[tr]=Matrix protokolü için istemci
Comment[uk]=Клієнт протоколу Matrix
Comment[x-test]=xxClient for the Matrix protocolxx
Comment[zh_CN]=为 Matrix 协议打造的客户端
Comment[zh_TW]=Matrix 通訊協定的用戶端
Comment=Chat on Matrix
Comment[ar]=دردش على ماتركس
Comment[ca]=Xat a Matrix
Comment[ca@valencia]=Xat a Matrix
Comment[de]=Über Matrix unterhalten
Comment[en_GB]=Chat on Matrix
Comment[es]=Chat en Matrix
Comment[eu]=Berriketa Matrix-en
Comment[fr]=Clavarder sur Matrix
Comment[gl]=Charle en Matrix
Comment[hu]=Csevegés Matrixon
Comment[ia]=Conversation en ditecto sur Matrix
Comment[it]= su Matrix
Comment[ka]=საუბარი Matrix-ზე
Comment[pl]=Rozmawiaj na Matriksie
Comment[sl]=Klepet na Matrixu
Comment[sv]=Chatta på Matrix
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
Comment[tr]=Matrix Üzerinde Sohbet Et
Comment[uk]=Спілкування у Matrix
Comment[zh_TW]=在 Matrix 上聊天
MimeType=x-scheme-handler/matrix;
Exec=neochat %u
Terminal=false

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

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

@@ -92,7 +92,7 @@ parts:
- olm
- qtkeychain
source: https://github.com/quotient-im/libQuotient.git
source-tag: 0.8.2
source-tag: 0.9.1
source-depth: 1
plugin: cmake
build-packages:

View File

@@ -10,8 +10,6 @@ endif()
add_library(neochat STATIC
controller.cpp
controller.h
actionshandler.cpp
actionshandler.h
models/emojimodel.cpp
models/emojimodel.h
emojitones.cpp
@@ -202,6 +200,12 @@ set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
QT_QML_SINGLETON_TYPE TRUE
)
if(ANDROID OR WIN32)
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
QT_QML_SOURCE_TYPENAME ShareAction
)
endif()
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
QML_FILES
@@ -313,13 +317,9 @@ if(NOT ANDROID AND NOT WIN32)
qml/EditMenu.qml
)
else()
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
QT_RESOURCE_ALIAS qml/ShareAction.qml
)
qt_target_qml_sources(neochat QML_FILES qml/ShareActionStub.qml)
endif()
configure_file(config-neochat.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-neochat.h)
if(WIN32)

View File

@@ -1,140 +0,0 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "actionshandler.h"
#include "chatbarcache.h"
#include "models/actionsmodel.h"
#include "neochatconfig.h"
#include "texthandler.h"
using namespace Quotient;
using namespace Qt::StringLiterals;
void ActionsHandler::handleMessageEvent(NeoChatRoom *room, ChatBarCache *chatBarCache)
{
if (room == nullptr || chatBarCache == nullptr) {
qWarning() << "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.";
return;
}
if (!chatBarCache->attachmentPath().isEmpty()) {
QUrl url(chatBarCache->attachmentPath());
auto path = url.isLocalFile() ? url.toLocalFile() : url.toString();
room->uploadFile(QUrl(path), chatBarCache->text().isEmpty() ? path.mid(path.lastIndexOf(u'/') + 1) : chatBarCache->text());
chatBarCache->setAttachmentPath({});
chatBarCache->setText({});
return;
}
const auto handledText = handleMentions(chatBarCache);
const auto result = handleQuickEdit(room, handledText);
if (!result) {
handleMessage(room, handledText, chatBarCache);
}
}
QString ActionsHandler::handleMentions(ChatBarCache *chatBarCache)
{
const auto mentions = chatBarCache->mentions();
std::sort(mentions->begin(), mentions->end(), [](const auto &a, const auto &b) -> bool {
return a.cursor.anchor() > b.cursor.anchor();
});
auto handledText = chatBarCache->text();
for (const auto &mention : *mentions) {
if (mention.text.isEmpty() || mention.id.isEmpty()) {
continue;
}
handledText = handledText.replace(mention.cursor.anchor(),
mention.cursor.position() - mention.cursor.anchor(),
QStringLiteral("[%1](https://matrix.to/#/%2)").arg(mention.text.toHtmlEscaped(), mention.id));
}
mentions->clear();
return handledText;
}
bool ActionsHandler::handleQuickEdit(NeoChatRoom *room, const QString &handledText)
{
if (room == nullptr) {
return false;
}
if (NeoChatConfig::allowQuickEdit()) {
QRegularExpression sed(QStringLiteral("^s/([^/]*)/([^/]*)(/g)?$"));
auto match = sed.match(handledText);
if (match.hasMatch()) {
const QString regex = match.captured(1);
const QString replacement = match.captured(2).toHtmlEscaped();
const QString flags = match.captured(3);
for (auto it = room->messageEvents().crbegin(); it != room->messageEvents().crend(); it++) {
if (const auto event = eventCast<const RoomMessageEvent>(&**it)) {
if (event->senderId() == room->localMember().id() && event->hasTextContent()) {
QString originalString;
if (event->content()) {
#if Quotient_VERSION_MINOR > 8
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content().get())->body;
#else
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body;
#endif
} else {
originalString = event->plainBody();
}
if (flags == "/g"_L1) {
room->postHtmlMessage(handledText, originalString.replace(regex, replacement), event->msgtype(), {}, event->id());
} else {
room->postHtmlMessage(handledText,
originalString.replace(originalString.indexOf(regex), regex.size(), replacement),
event->msgtype(),
{},
event->id());
}
return true;
}
}
}
}
}
return false;
}
void ActionsHandler::handleMessage(NeoChatRoom *room, QString handledText, ChatBarCache *chatBarCache)
{
if (room == nullptr) {
return;
}
auto messageType = RoomMessageEvent::MsgType::Text;
if (handledText.startsWith(QLatin1Char('/'))) {
for (const auto &action : ActionsModel::instance().allActions()) {
if (handledText.indexOf(action.prefix) == 1
&& (handledText.indexOf(" "_ls) == action.prefix.length() + 1 || handledText.length() == action.prefix.length() + 1)) {
handledText = action.handle(handledText.mid(action.prefix.length() + 1).trimmed(), room, chatBarCache);
if (action.messageType.has_value()) {
messageType = *action.messageType;
}
if (action.messageAction) {
break;
} else {
return;
}
}
}
}
TextHandler textHandler;
textHandler.setData(handledText);
handledText = textHandler.handleSendText();
if (handledText.length() == 0) {
return;
}
room->postMessage(chatBarCache->text(), handledText, messageType, chatBarCache->replyId(), chatBarCache->editId(), chatBarCache->threadId());
}
#include "moc_actionshandler.cpp"

View File

@@ -1,43 +0,0 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QString>
class ChatBarCache;
class NeoChatRoom;
/**
* @class ActionsHandler
*
* This class contains functions to handle chat messages ready for posting to a room.
*
* Everything that needs to be done to prepare the message for posting in a room
* including:
* - File handling
* - User mentions
* - Quick edits
* - Chat actions
* - Custom emojis
*
* @note A chat action is a message starting with /, resulting in something other
* than a normal message being sent (e.g. /me, /join).
*
* @sa ActionsModel, NeoChatRoom
*/
class ActionsHandler
{
public:
/**
* @brief Pre-process text and send message event.
*/
static void handleMessageEvent(NeoChatRoom *room, ChatBarCache *chatBarCache);
private:
static QString handleMentions(ChatBarCache *chatBarCache);
static bool handleQuickEdit(NeoChatRoom *room, const QString &handledText);
static void handleMessage(NeoChatRoom *room, QString handledText, ChatBarCache *chatBarCache);
};

View File

@@ -176,13 +176,14 @@ QQC2.Control {
RowLayout {
QQC2.ScrollView {
id: chatBarScrollView
Layout.topMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.leftMargin: Kirigami.Units.largeSpacing
Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.fillWidth: true
Layout.maximumHeight: Kirigami.Units.gridUnit * 8
Layout.topMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.minimumHeight: Kirigami.Units.gridUnit * 2
Layout.minimumHeight: Kirigami.Units.gridUnit * 3
// HACK: This is to stop the ScrollBar flickering on and off as the height is increased
QQC2.ScrollBar.vertical.policy: chatBarHeightAnimation.running && implicitHeight <= height ? QQC2.ScrollBar.AlwaysOff : QQC2.ScrollBar.AsNeeded
@@ -251,20 +252,22 @@ QQC2.Control {
}
}
Keys.onEnterPressed: event => {
const controlIsPressed = event.modifiers & Qt.ControlModifier;
if (completionMenu.visible) {
completionMenu.complete();
} else if (event.modifiers & Qt.ShiftModifier || Kirigami.Settings.isMobile) {
} else if (event.modifiers & Qt.ShiftModifier || Kirigami.Settings.isMobile || NeoChatConfig.sendMessageWith === 1 && !controlIsPressed || NeoChatConfig.sendMessageWith === 0 && controlIsPressed) {
textField.insert(cursorPosition, "\n");
} else {
} else if (NeoChatConfig.sendMessageWith === 0 && !controlIsPressed || NeoChatConfig.sendMessageWith === 1 && controlIsPressed) {
_private.postMessage();
}
}
Keys.onReturnPressed: event => {
const controlIsPressed = event.modifiers & Qt.ControlModifier;
if (completionMenu.visible) {
completionMenu.complete();
} else if (event.modifiers & Qt.ShiftModifier || Kirigami.Settings.isMobile) {
} else if (event.modifiers & Qt.ShiftModifier || Kirigami.Settings.isMobile || NeoChatConfig.sendMessageWith === 1 && !controlIsPressed || NeoChatConfig.sendMessageWith === 0 && controlIsPressed) {
textField.insert(cursorPosition, "\n");
} else {
} else if (NeoChatConfig.sendMessageWith === 0 && !controlIsPressed || NeoChatConfig.sendMessageWith === 1 && controlIsPressed) {
_private.postMessage();
}
}
@@ -318,12 +321,11 @@ QQC2.Control {
id: actionsRow
spacing: 0
Layout.alignment: Qt.AlignBottom
Layout.bottomMargin: Kirigami.Units.smallSpacing * 1.5
Layout.bottomMargin: Kirigami.Units.smallSpacing * 4
Repeater {
model: root.actions
delegate: QQC2.ToolButton {
Layout.alignment: Qt.AlignVCenter
icon.name: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
onClicked: modelData.trigger()
@@ -340,7 +342,6 @@ QQC2.Control {
}
}
}
DelegateSizeHelper {
id: chatBarSizeHelper
startBreakpoint: Kirigami.Units.gridUnit * 46
@@ -405,7 +406,6 @@ QQC2.Control {
repeatTimer.stop();
root.currentRoom.markAllMessagesAsRead();
textField.clear();
_private.chatBarCache.clearRelations();
messageSent();
}

View File

@@ -43,6 +43,9 @@ QQC2.ItemDelegate {
anchors.fill: parent
visible: root.emoji.startsWith("mxc") || root.isImage
source: visible ? root.emoji : ""
fillMode: Image.PreserveAspectFit
sourceSize.width: width
sourceSize.height: height
}
}

View File

@@ -84,6 +84,7 @@ QQC2.ScrollView {
Kirigami.PlaceholderMessage {
anchors.centerIn: parent
icon.name: root.stickers ? "stickers" : "preferences-desktop-emoticons"
text: root.stickers ? i18n("No stickers") : i18n("No emojis")
visible: emojis.count === 0
}

View File

@@ -66,6 +66,7 @@ ColumnLayout {
Layout.fillWidth: true
Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height
QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0
visible: categories.count !== 0
ListView {
id: categories
@@ -201,8 +202,13 @@ ColumnLayout {
width: root.categoryIconSize
height: width
checked: stickerModel.packIndex === model.index
padding: Kirigami.Units.largeSpacing
contentItem: Image {
source: model.avatarUrl
fillMode: Image.PreserveAspectFit
sourceSize.width: width
sourceSize.height: height
}
QQC2.ToolTip.text: model.name
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay

View File

@@ -5,10 +5,11 @@
#include <Quotient/roommember.h>
#include "actionshandler.h"
#include "chatdocumenthandler.h"
#include "eventhandler.h"
#include "models/actionsmodel.h"
#include "neochatroom.h"
#include "texthandler.h"
ChatBarCache::ChatBarCache(QObject *parent)
: QObject(parent)
@@ -29,6 +30,37 @@ void ChatBarCache::setText(const QString &text)
Q_EMIT textChanged();
}
QString ChatBarCache::sendText() const
{
if (!attachmentPath().isEmpty()) {
QUrl url(attachmentPath());
auto path = url.isLocalFile() ? url.toLocalFile() : url.toString();
return text().isEmpty() ? path.mid(path.lastIndexOf(u'/') + 1) : text();
}
return formatMentions();
}
QString ChatBarCache::formatMentions() const
{
auto mentions = m_mentions;
std::sort(mentions.begin(), mentions.end(), [](const auto &a, const auto &b) {
return a.cursor.anchor() > b.cursor.anchor();
});
auto formattedText = text();
for (const auto &mention : mentions) {
if (mention.text.isEmpty() || mention.id.isEmpty()) {
continue;
}
formattedText = formattedText.replace(mention.cursor.anchor(),
mention.cursor.position() - mention.cursor.anchor(),
QStringLiteral("[%1](https://matrix.to/#/%2)").arg(mention.text.toHtmlEscaped(), mention.id));
}
return formattedText;
}
bool ChatBarCache::isReplying() const
{
return m_relationType == Reply && !m_relationId.isEmpty();
@@ -268,7 +300,35 @@ void ChatBarCache::postMessage()
return;
}
ActionsHandler::handleMessageEvent(room, this);
if (!attachmentPath().isEmpty()) {
room->uploadFile(QUrl(attachmentPath()), sendText());
clearCache();
return;
}
const auto result = ActionsModel::handleAction(room, this);
if (!result.first.has_value()) {
return;
}
TextHandler textHandler;
textHandler.setData(*std::get<std::optional<QString>>(result));
const auto sendText = textHandler.handleSendText();
if (sendText.length() == 0) {
return;
}
room->postMessage(text(), sendText, *std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result), replyId(), editId(), threadId());
clearCache();
}
void ChatBarCache::clearCache()
{
setText({});
m_mentions.clear();
m_savedText = QString();
clearRelations();
}
#include "moc_chatbarcache.cpp"

View File

@@ -153,6 +153,7 @@ public:
explicit ChatBarCache(QObject *parent = nullptr);
QString text() const;
QString sendText() const;
void setText(const QString &text);
bool isReplying() const;
@@ -215,6 +216,8 @@ Q_SIGNALS:
private:
QString m_text = QString();
QString formatMentions() const;
QString m_relationId = QString();
RelationType m_relationType = RelationType::None;
QString m_threadId = QString();
@@ -223,4 +226,6 @@ private:
QString m_savedText;
QPointer<MessageContentModel> m_relationContentModel;
void clearCache();
};

View File

@@ -63,11 +63,7 @@ Controller::Controller(QObject *parent)
});
} else {
auto c = new NeoChatConnection(this);
#if Quotient_VERSION_MINOR > 8
c->assumeIdentity(QStringLiteral("@user:localhost:1234"), QStringLiteral("device_1234"), QStringLiteral("token_1234"));
#else
c->assumeIdentity(QStringLiteral("@user:localhost:1234"), QStringLiteral("token_1234"));
#endif
connect(c, &Connection::connected, this, [c, this]() {
m_accountRegistry.add(c);
c->syncLoop();
@@ -230,14 +226,7 @@ void Controller::invokeLogin()
Qt::SingleShotConnection);
}
});
connect(connection, &NeoChatConnection::networkError, this, [this](const QString &error, const QString &, int, int) {
Q_EMIT errorOccured(i18n("Network Error: %1", error));
});
#if Quotient_VERSION_MINOR > 8
connection->assumeIdentity(account.userId(), account.deviceId(), accessToken);
#else
connection->assumeIdentity(account.userId(), accessToken);
#endif
});
}
}
@@ -434,21 +423,21 @@ void Controller::setTestMode(bool test)
void Controller::removeConnection(const QString &userId)
{
if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) {
auto connection = m_connectionsLoading[userId];
// When loadAccessTokenFromKeyChain() fails m_connectionsLoading won't have an
// entry for it so we need to check both separately.
if (m_accountsLoading.contains(userId)) {
m_accountsLoading.removeAll(userId);
Q_EMIT accountsLoadingChanged();
}
if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) {
auto connection = m_connectionsLoading[userId];
SettingsGroup("Accounts"_ls).remove(userId);
}
}
bool Controller::csSupported() const
{
#if Quotient_VERSION_MINOR > 8
return true;
#else
return false;
#endif
}
void Controller::revertToDefaultConfig()

View File

@@ -4,6 +4,7 @@
import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import QtQuick.Window
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
@@ -23,7 +24,7 @@ ColumnLayout {
model: root.connection.accountDataEventTypes
delegate: FormCard.FormButtonDelegate {
text: modelData
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
onClicked: root.Window.window.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
sourceText: root.connection.accountDataJsonString(modelData)
}, {
title: i18nc("@title:window", "Event Source"),

View File

@@ -3,6 +3,7 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
@@ -47,7 +48,7 @@ ColumnLayout {
model: root.room.accountDataEventTypes
delegate: FormCard.FormButtonDelegate {
text: modelData
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
onClicked: root.Window.window.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
sourceText: root.room.roomAcountDataJson(text)
}, {
title: i18n("Event Source"),
@@ -77,7 +78,7 @@ ColumnLayout {
if (model.eventCount === 1) {
openEventSource(model.type, model.stateKey);
} else {
pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.devtools', 'StateKeys'), {
root.Window.window.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.devtools', 'StateKeys'), {
room: root.room,
eventType: model.type
}, {
@@ -89,7 +90,7 @@ ColumnLayout {
}
}
function openEventSource(type: string, stateKey: string): void {
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
onClicked: root.Window.window.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
model: stateModel,
allowEdit: true,
room: root.room,

View File

@@ -225,14 +225,10 @@ QString EventHandler::rawMessageBody(const Quotient::RoomMessageEvent &event)
{
QString body;
if (event.hasFileContent()) {
if (event.has<EventContent::FileContent>()) {
// if filename is given or body is equal to filename,
// then body is a caption
#if Quotient_VERSION_MINOR > 8
QString filename = event.fileContent()->originalName;
#else
QString filename = event.content()->fileInfo()->originalName;
#endif
QString filename = event.get<EventContent::FileContent>()->originalName;
QString body = event.plainBody();
if (filename.isEmpty() || filename == body) {
return QString();
@@ -240,12 +236,8 @@ QString EventHandler::rawMessageBody(const Quotient::RoomMessageEvent &event)
return body;
}
if (event.hasTextContent() && event.content()) {
#if Quotient_VERSION_MINOR > 8
body = event.richTextContent()->body;
#else
body = static_cast<const EventContent::TextContent *>(event.content())->body;
#endif
if (event.has<EventContent::TextContent>() && event.content()) {
body = event.get<EventContent::TextContent>()->body;
} else {
body = event.plainBody();
}
@@ -472,12 +464,8 @@ QString EventHandler::getMessageBody(const NeoChatRoom *room, const RoomMessageE
{
TextHandler textHandler;
if (event.hasFileContent()) {
#if Quotient_VERSION_MINOR > 8
QString fileCaption = event.fileContent()->originalName;
#else
QString fileCaption = event.content()->fileInfo()->originalName;
#endif
if (event.has<EventContent::FileContent>()) {
QString fileCaption = event.get<EventContent::FileContent>()->originalName;
if (fileCaption.isEmpty()) {
fileCaption = event.plainBody();
} else if (fileCaption != event.plainBody()) {
@@ -488,12 +476,8 @@ QString EventHandler::getMessageBody(const NeoChatRoom *room, const RoomMessageE
}
QString body;
if (event.hasTextContent() && event.content()) {
#if Quotient_VERSION_MINOR > 8
body = event.richTextContent()->body;
#else
body = static_cast<const EventContent::TextContent *>(event.content())->body;
#endif
if (event.has<EventContent::TextContent>() && event.content()) {
body = event.get<EventContent::TextContent>()->body;
} else {
body = event.plainBody();
}
@@ -708,25 +692,15 @@ QVariantMap EventHandler::getMediaInfoForEvent(const NeoChatRoom *room, const Qu
// Get the file info for the event.
if (event->is<RoomMessageEvent>()) {
auto roomMessageEvent = eventCast<const RoomMessageEvent>(event);
if (!roomMessageEvent->hasFileContent()) {
if (!roomMessageEvent->has<EventContent::FileContentBase>()) {
return {};
}
#if Quotient_VERSION_MINOR > 8
const auto content = roomMessageEvent->content();
QVariantMap mediaInfo = getMediaInfoFromFileInfo(room, static_cast<EventContent::FileContent *>(content.get()), eventId, false, false);
#else
const auto content = static_cast<const EventContent::FileContent *>(roomMessageEvent->content());
QVariantMap mediaInfo = getMediaInfoFromFileInfo(room, content, eventId, false, false);
#endif
const auto content = roomMessageEvent->get<EventContent::FileContentBase>();
QVariantMap mediaInfo = getMediaInfoFromFileInfo(room, content.get(), eventId, false, false);
// if filename isn't specifically given, it is in body
// https://spec.matrix.org/latest/client-server-api/#mfile
#if Quotient_VERSION_MINOR > 8
mediaInfo["filename"_ls] =
(roomMessageEvent->fileContent()->originalName.isEmpty()) ? roomMessageEvent->plainBody() : roomMessageEvent->fileContent()->originalName;
#else
mediaInfo["filename"_ls] = (content->fileInfo()->originalName.isEmpty()) ? roomMessageEvent->plainBody() : content->fileInfo()->originalName;
#endif
mediaInfo["filename"_ls] = content->commonInfo().originalName.isEmpty() ? roomMessageEvent->plainBody() : content->commonInfo().originalName;
return mediaInfo;
} else if (event->is<StickerEvent>()) {
@@ -740,11 +714,7 @@ QVariantMap EventHandler::getMediaInfoForEvent(const NeoChatRoom *room, const Qu
}
QVariantMap EventHandler::getMediaInfoFromFileInfo(const NeoChatRoom *room,
#if Quotient_VERSION_MINOR > 8
const Quotient::EventContent::FileContentBase *fileContent,
#else
const Quotient::EventContent::TypedBase *fileContent,
#endif
const QString &eventId,
bool isThumbnail,
bool isSticker)
@@ -752,18 +722,10 @@ QVariantMap EventHandler::getMediaInfoFromFileInfo(const NeoChatRoom *room,
QVariantMap mediaInfo;
// Get the mxc URL for the media.
#if Quotient_VERSION_MINOR > 8
if (!fileContent->url().isValid() || fileContent->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
#else
if (!fileContent->fileInfo()->url().isValid() || fileContent->fileInfo()->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
#endif
mediaInfo["source"_ls] = QUrl();
} else {
#if Quotient_VERSION_MINOR > 8
QUrl source = room->makeMediaUrl(eventId, fileContent->url());
#else
QUrl source = room->makeMediaUrl(eventId, fileContent->fileInfo()->url());
#endif
if (source.isValid()) {
mediaInfo["source"_ls] = source;
@@ -780,25 +742,15 @@ QVariantMap EventHandler::getMediaInfoFromFileInfo(const NeoChatRoom *room,
mediaInfo["mimeIcon"_ls] = mimeType.iconName();
// Add media size if available.
#if Quotient_VERSION_MINOR > 8
mediaInfo["size"_ls] = static_cast<const EventContent::FileContent *>(fileContent)->payloadSize;
#else
mediaInfo["size"_ls] = static_cast<const EventContent::FileContent *>(fileContent)->fileInfo()->payloadSize;
#endif
mediaInfo["size"_ls] = fileContent->commonInfo().payloadSize;
mediaInfo["isSticker"_ls] = isSticker;
// Add parameter depending on media type.
if (mimeType.name().contains(QStringLiteral("image"))) {
if (auto castInfo = static_cast<const EventContent::ImageContent *>(fileContent)) {
#if Quotient_VERSION_MINOR > 8
mediaInfo["width"_ls] = castInfo->imageSize.width();
mediaInfo["height"_ls] = castInfo->imageSize.height();
#else
const auto imageInfo = static_cast<const EventContent::ImageInfo *>(castInfo->fileInfo());
mediaInfo["width"_ls] = imageInfo->imageSize.width();
mediaInfo["height"_ls] = imageInfo->imageSize.height();
#endif
// TODO: Images in certain formats (e.g. WebP) will be erroneously marked as animated, even if they are static.
mediaInfo["animated"_ls] = QMovie::supportedFormats().contains(mimeType.preferredSuffix().toUtf8());

View File

@@ -290,11 +290,7 @@ private:
static QVariantMap getMediaInfoForEvent(const NeoChatRoom *room, const Quotient::RoomEvent *event);
QVariantMap static getMediaInfoFromFileInfo(const NeoChatRoom *room,
#if Quotient_VERSION_MINOR > 8
const Quotient::EventContent::FileContentBase *fileContent,
#else
const Quotient::EventContent::TypedBase *fileContent,
#endif
const QString &eventId,
bool isThumbnail = false,
bool isSticker = false);

View File

@@ -3,7 +3,6 @@
#include "imagepackevent.h"
#include <QJsonObject>
#include <Quotient/omittable.h>
using namespace Quotient;
@@ -11,10 +10,10 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
{
if (json.contains(QStringLiteral("pack"))) {
pack = ImagePackEventContent::Pack{
fromJson<Omittable<QString>>(json["pack"_ls].toObject()["display_name"_ls]),
fromJson<Omittable<QUrl>>(json["pack"_ls].toObject()["avatar_url"_ls]),
fromJson<Omittable<QStringList>>(json["pack"_ls].toObject()["usage"_ls]),
fromJson<Omittable<QString>>(json["pack"_ls].toObject()["attribution"_ls]),
fromJson<std::optional<QString>>(json["pack"_ls].toObject()["display_name"_ls]),
fromJson<std::optional<QUrl>>(json["pack"_ls].toObject()["avatar_url"_ls]),
fromJson<std::optional<QStringList>>(json["pack"_ls].toObject()["usage"_ls]),
fromJson<std::optional<QString>>(json["pack"_ls].toObject()["attribution"_ls]),
};
} else {
pack = std::nullopt;
@@ -31,9 +30,9 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
images += ImagePackImage{
k,
fromJson<QUrl>(json["images"_ls][k]["url"_ls].toString()),
fromJson<Omittable<QString>>(json["images"_ls][k]["body"_ls]),
fromJson<std::optional<QString>>(json["images"_ls][k]["body"_ls]),
info,
fromJson<Omittable<QStringList>>(json["images"_ls][k]["usage"_ls]),
fromJson<std::optional<QStringList>>(json["images"_ls][k]["usage"_ls]),
};
}
}

View File

@@ -7,13 +7,10 @@
#include <Quotient/accountregistry.h>
#include <Quotient/e2ee/sssshandler.h>
#include <Quotient/keyimport.h>
#include <Quotient/keyverificationsession.h>
#include <Quotient/roommember.h>
#if Quotient_VERSION_MINOR > 8
#include <Quotient/keyimport.h>
#endif
#include "controller.h"
#include "neochatconfig.h"
@@ -43,11 +40,9 @@ struct ForeignSSSSHandler {
QML_NAMED_ELEMENT(SSSSHandler)
};
#if Quotient_VERSION_MINOR > 8
struct ForeignKeyImport {
Q_GADGET
QML_SINGLETON
QML_FOREIGN(Quotient::KeyImport)
QML_NAMED_ELEMENT(KeyImport)
};
#endif

View File

@@ -5,7 +5,7 @@
using namespace Quotient;
NeochatAdd3PIdJob::NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const Omittable<QJsonObject> &auth)
NeochatAdd3PIdJob::NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const std::optional<QJsonObject> &auth)
: BaseJob(HttpVerb::Post, QStringLiteral("Add3PIDJob"), makePath("/_matrix/client/v3", "/account/3pid/add"))
{
QJsonObject _dataJson;

View File

@@ -4,10 +4,9 @@
#pragma once
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
class NeochatAdd3PIdJob : public Quotient::BaseJob
{
public:
explicit NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const Quotient::Omittable<QJsonObject> &auth = {});
explicit NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const std::optional<QJsonObject> &auth = {});
};

View File

@@ -5,7 +5,7 @@
using namespace Quotient;
NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const Omittable<QJsonObject> &auth)
NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const std::optional<QJsonObject> &auth)
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), "/_matrix/client/r0/account/password")
{
QJsonObject _data;

View File

@@ -5,10 +5,8 @@
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
class NeochatChangePasswordJob : public Quotient::BaseJob
{
public:
explicit NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const Quotient::Omittable<QJsonObject> &auth = {});
explicit NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const std::optional<QJsonObject> &auth = {});
};

View File

@@ -5,7 +5,7 @@
using namespace Quotient;
NeoChatDeactivateAccountJob::NeoChatDeactivateAccountJob(const Omittable<QJsonObject> &auth)
NeoChatDeactivateAccountJob::NeoChatDeactivateAccountJob(const std::optional<QJsonObject> &auth)
: BaseJob(HttpVerb::Post, QStringLiteral("DisableDeviceJob"), "_matrix/client/v3/account/deactivate")
{
QJsonObject data;

View File

@@ -4,10 +4,9 @@
#pragma once
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
class NeoChatDeactivateAccountJob : public Quotient::BaseJob
{
public:
explicit NeoChatDeactivateAccountJob(const Quotient::Omittable<QJsonObject> &auth = {});
explicit NeoChatDeactivateAccountJob(const std::optional<QJsonObject> &auth = {});
};

View File

@@ -5,7 +5,7 @@
using namespace Quotient;
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const Omittable<QJsonObject> &auth)
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const std::optional<QJsonObject> &auth)
: BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId).toLatin1())
{
QJsonObject _data;

View File

@@ -4,10 +4,9 @@
#pragma once
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
class NeochatDeleteDeviceJob : public Quotient::BaseJob
{
public:
explicit NeochatDeleteDeviceJob(const QString &deviceId, const Quotient::Omittable<QJsonObject> &auth = {});
explicit NeochatDeleteDeviceJob(const QString &deviceId, const std::optional<QJsonObject> &auth = {});
};

View File

@@ -4,7 +4,6 @@
#pragma once
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
// TODO: Upstream to libQuotient
class NeochatGetCommonRoomsJob : public Quotient::BaseJob

View File

@@ -25,8 +25,7 @@ void LoginHelper::init()
m_connection = new NeoChatConnection();
m_matrixId = QString();
m_password = QString();
m_deviceName = QStringLiteral("NeoChat %1 %2 %3 %4")
.arg(QSysInfo::machineHostName(), QSysInfo::productType(), QSysInfo::productVersion(), QSysInfo::currentCpuArchitecture());
m_deviceName = QStringLiteral("NeoChat");
m_supportsSso = false;
m_supportsPassword = false;
m_ssoUrl = QUrl();

View File

@@ -13,6 +13,7 @@ LoginStep {
id: root
FormCard.FormTextDelegate {
textItem.wrapMode: Text.Wrap
text: i18n("Please wait while your messages are loaded from the server. This might take a little while.")
}
FormCard.AbstractFormDelegate {

View File

@@ -7,6 +7,7 @@ import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
import org.kde.neochat
import org.kde.neochat.settings
@@ -90,11 +91,27 @@ Kirigami.Page {
id: loadedAccounts
model: AccountRegistry
delegate: FormCard.FormButtonDelegate {
text: model.userId
id: delegate
required property string userId
required property NeoChatConnection connection
text: QmlUtils.escapeString(connection.localUser.displayName)
description: connection.localUser.id
leadingPadding: Kirigami.Units.largeSpacing
onClicked: {
Controller.activeConnection = model.connection;
Controller.activeConnection = delegate.connection;
root.connectionChosen();
}
leading: KirigamiComponents.Avatar {
id: avatar
name: delegate.text
// Note: User::avatarUrl does not set user_id, and thus cannot be used directly here. Hence the makeMediaUrl.
source: delegate.connection.localUser.avatarUrl.toString().length > 0 ? delegate.connection.makeMediaUrl(delegate.connection.localUser.avatarUrl) : ""
implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium
}
}
}
Repeater {

View File

@@ -140,7 +140,7 @@ int main(int argc, char *argv[])
KAboutData about(QStringLiteral("neochat"),
i18n("NeoChat"),
QStringLiteral(NEOCHAT_VERSION_STRING),
i18n("Matrix client"),
i18n("Chat on Matrix"),
KAboutLicense::GPL_V3,
i18n("© 2018-2020 Black Hat, 2020-2024 KDE Community"));
about.addAuthor(i18n("Carl Schwan"),

View File

@@ -163,11 +163,7 @@ void AccountEmoticonModel::setEmoticonImage(int index, const QUrl &source)
QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl source)
{
auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
#if Quotient_VERSION_MINOR > 8
co_await qCoro(job.get(), &BaseJob::finished);
#else
co_await qCoro(job, &BaseJob::finished);
#endif
if (job->error() != BaseJob::NoError) {
co_return;
}
@@ -189,11 +185,7 @@ QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl sourc
QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString shortcode, QString description, QString type)
{
auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
#if Quotient_VERSION_MINOR > 8
co_await qCoro(job.get(), &BaseJob::finished);
#else
co_await qCoro(job, &BaseJob::finished);
#endif
if (job->error() != BaseJob::NoError) {
co_return;
}

View File

@@ -5,9 +5,11 @@
#include "chatbarcache.h"
#include "enums/messagetype.h"
#include "neochatconfig.h"
#include "neochatconnection.h"
#include "neochatroom.h"
#include "roommanager.h"
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/roommemberevent.h>
#include <Quotient/events/roompowerlevelsevent.h>
#include <Quotient/user.h>
@@ -16,6 +18,7 @@
using Action = ActionsModel::Action;
using namespace Quotient;
using namespace Qt::StringLiterals;
QStringList rainbowColors{"#ff2b00"_ls, "#ff5500"_ls, "#ff8000"_ls, "#ffaa00"_ls, "#ffd500"_ls, "#ffff00"_ls, "#d4ff00"_ls, "#aaff00"_ls, "#80ff00"_ls,
"#55ff00"_ls, "#2bff00"_ls, "#00ff00"_ls, "#00ff2b"_ls, "#00ff55"_ls, "#00ff80"_ls, "#00ffaa"_ls, "#00ffd5"_ls, "#00ffff"_ls,
@@ -573,3 +576,78 @@ QList<Action> &ActionsModel::allActions() const
{
return actions;
}
bool ActionsModel::handleQuickEditAction(NeoChatRoom *room, const QString &messageText)
{
if (room == nullptr) {
return false;
}
if (NeoChatConfig::allowQuickEdit()) {
QRegularExpression sed(QStringLiteral("^s/([^/]*)/([^/]*)(/g)?$"));
auto match = sed.match(messageText);
if (match.hasMatch()) {
const QString regex = match.captured(1);
const QString replacement = match.captured(2).toHtmlEscaped();
const QString flags = match.captured(3);
for (auto it = room->messageEvents().crbegin(); it != room->messageEvents().crend(); it++) {
if (const auto event = eventCast<const RoomMessageEvent>(&**it)) {
if (event->senderId() == room->localMember().id() && event->has<EventContent::TextContent>()) {
QString originalString;
if (event->content()) {
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content().get())->body;
} else {
originalString = event->plainBody();
}
QString replaceId = event->id();
const auto eventRelation = event->relatesTo();
if (eventRelation && eventRelation->type == "m.replace"_L1) {
replaceId = eventRelation->eventId;
}
if (flags == "/g"_L1) {
room->postHtmlMessage(messageText, originalString.replace(regex, replacement), event->msgtype(), {}, replaceId);
} else {
room->postHtmlMessage(messageText,
originalString.replace(originalString.indexOf(regex), regex.size(), replacement),
event->msgtype(),
{},
replaceId);
}
return true;
}
}
}
}
}
return false;
}
std::pair<std::optional<QString>, std::optional<Quotient::RoomMessageEvent::MsgType>> ActionsModel::handleAction(NeoChatRoom *room, ChatBarCache *chatBarCache)
{
auto sendText = chatBarCache->sendText();
const auto edited = handleQuickEditAction(room, sendText);
if (edited) {
return std::make_pair(std::nullopt, std::nullopt);
}
std::optional<Quotient::RoomMessageEvent::MsgType> messageType = std::nullopt;
if (sendText.startsWith(QLatin1Char('/'))) {
for (const auto &action : ActionsModel::instance().allActions()) {
if (sendText.indexOf(action.prefix) == 1
&& (sendText.indexOf(" "_ls) == action.prefix.length() + 1 || sendText.length() == action.prefix.length() + 1)) {
sendText = action.handle(sendText.mid(action.prefix.length() + 1).trimmed(), room, chatBarCache);
if (action.messageType.has_value()) {
messageType = action.messageType;
}
if (action.messageAction) {
break;
} else {
return std::make_pair(std::nullopt, std::nullopt);
}
}
}
}
return std::make_pair(sendText, messageType);
}

View File

@@ -90,6 +90,21 @@ public:
*/
QList<Action> &allActions() const;
/**
* @brief Handle special sed style edit action.
*
* @return True if the message has a sed edit which was actioned. False otherwise.
*/
static bool handleQuickEditAction(NeoChatRoom *room, const QString &messageText);
/**
* @brief Handle any action within the message contained in the given ChatBarCache.
*
* @return A modified or unmodified string that needs to be sent or an empty string if
* the handled action replaces sending a normal message.
*/
static std::pair<std::optional<QString>, std::optional<Quotient::RoomMessageEvent::MsgType>> handleAction(NeoChatRoom *room, ChatBarCache *chatBarCache);
private:
ActionsModel() = default;
};

View File

@@ -85,13 +85,7 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
}
if (role == IconNameRole) {
auto mediaId = m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
if (mediaId.isEmpty()) {
return QVariant();
}
if (m_room) {
return m_room->connection()->makeMediaUrl(QUrl(QStringLiteral("mxc://%1").arg(mediaId)));
}
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
}
}
if (m_autoCompletionType == Emoji) {

View File

@@ -129,11 +129,7 @@ void DevicesModel::logout(const QString &deviceId, const QString &password)
QJsonObject identifier = {{"type"_ls, "m.id.user"_ls}, {"user"_ls, m_connection->user()->id()}};
authData["identifier"_ls] = identifier;
auto innerJob = m_connection->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId, authData);
#if Quotient_VERSION_MINOR > 8
connect(innerJob.get(), &BaseJob::success, this, onSuccess);
#else
connect(innerJob, &BaseJob::success, this, onSuccess);
#endif
} else {
onSuccess();
}

View File

@@ -7,6 +7,7 @@
#include <QImageReader>
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/redactionevent.h>
#include <Quotient/events/roommessageevent.h>
#include <Quotient/events/stickerevent.h>
@@ -521,18 +522,10 @@ QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentT
auto fileTransferInfo = m_room->cachedFileTransferInfo(event);
#ifndef Q_OS_ANDROID
Q_ASSERT(roomMessageEvent->content() != nullptr && roomMessageEvent->hasFileContent());
#if Quotient_VERSION_MINOR > 8
const QMimeType mimeType = roomMessageEvent->fileContent()->mimeType;
#else
const QMimeType mimeType = roomMessageEvent->content()->fileInfo()->mimeType;
#endif
Q_ASSERT(roomMessageEvent->content() != nullptr && roomMessageEvent->has<EventContent::FileContent>());
const QMimeType mimeType = roomMessageEvent->get<EventContent::FileContent>()->mimeType;
if (mimeType.name() == QStringLiteral("text/plain") || mimeType.parentMimeTypes().contains(QStringLiteral("text/plain"))) {
#if Quotient_VERSION_MINOR > 8
QString originalName = roomMessageEvent->fileContent()->originalName;
#else
QString originalName = roomMessageEvent->content()->fileInfo()->originalName;
#endif
QString originalName = roomMessageEvent->get<EventContent::FileContent>()->originalName;
if (originalName.isEmpty()) {
originalName = roomMessageEvent->plainBody();
}
@@ -576,15 +569,22 @@ QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentT
case MessageComponentType::Video: {
if (!event->is<StickerEvent>()) {
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event);
QList<MessageComponent> components;
components += MessageComponent{type, QString(), {}};
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
components += TextHandler().textComponents(body,
EventHandler::messageBodyInputFormat(*roomMessageEvent),
m_room,
roomMessageEvent,
roomMessageEvent->isReplaced());
return components;
const auto fileContent = roomMessageEvent->get<EventContent::FileContentBase>();
if (fileContent != nullptr) {
const auto fileInfo = fileContent->commonInfo();
const auto body = EventHandler::rawMessageBody(*roomMessageEvent);
// Do not attach the description to the image, if it's the same as the original filename.
if (fileInfo.originalName != body) {
QList<MessageComponent> components;
components += MessageComponent{type, QString(), {}};
components += TextHandler().textComponents(body,
EventHandler::messageBodyInputFormat(*roomMessageEvent),
m_room,
roomMessageEvent,
roomMessageEvent->isReplaced());
return components;
}
}
}
}
default:
@@ -642,7 +642,7 @@ QList<MessageComponent> MessageContentModel::addLinkPreviews(QList<MessageCompon
void MessageContentModel::closeLinkPreview(int row)
{
if (row < 0 || row > m_components.size()) {
if (row < 0 || row >= m_components.size()) {
qWarning() << "closeLinkPreview() called with row" << row << "which does not exist. m_components.size() =" << m_components.size();
return;
}
@@ -652,6 +652,7 @@ void MessageContentModel::closeLinkPreview(int row)
m_removedLinkPreviews += m_components[row].attributes["link"_ls].toUrl();
m_components.remove(row);
m_components.squeeze();
endResetModel();
resetContent();
}
}
@@ -664,7 +665,7 @@ void MessageContentModel::updateItineraryModel()
}
if (auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event)) {
if (roomMessageEvent->hasFileContent()) {
if (roomMessageEvent->has<EventContent::FileContent>()) {
auto filePath = m_room->cachedFileTransferInfo(event).localPath;
if (filePath.isEmpty() && m_itineraryModel != nullptr) {
delete m_itineraryModel;

View File

@@ -8,6 +8,7 @@
#include "neochatconfig.h"
#include <Quotient/csapi/rooms.h>
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/redactionevent.h>
#include <Quotient/events/roommessageevent.h>
#include <Quotient/events/stickerevent.h>
@@ -504,7 +505,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (role == ProgressInfoRole) {
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
if (e->hasFileContent()) {
if (e->has<EventContent::FileContent>()) {
return QVariant::fromValue(m_currentRoom->cachedFileTransferInfo(&evt));
}
}

View File

@@ -311,12 +311,7 @@ void PushRuleModel::addKeyword(const QString &keyword, const QString &roomId)
pushConditions.append(keywordCondition);
}
#if Quotient_VERSION_MINOR > 8
auto job = m_connection->callApi<Quotient::SetPushRuleJob>(PushRuleKind::kindString(kind),
#else
auto job = m_connection->callApi<Quotient::SetPushRuleJob>(QLatin1String("global"),
PushRuleKind::kindString(kind),
#endif
keyword,
actions,
QString(),
@@ -341,11 +336,7 @@ void PushRuleModel::removeKeyword(const QString &keyword)
}
auto kind = PushRuleKind::kindString(m_rules[index].kind);
#if Quotient_VERSION_MINOR > 8
auto job = m_connection->callApi<Quotient::DeletePushRuleJob>(kind, m_rules[index].id);
#else
auto job = m_connection->callApi<Quotient::DeletePushRuleJob>(QStringLiteral("global"), kind, m_rules[index].id);
#endif
connect(job, &Quotient::BaseJob::failure, this, [this, job, index]() {
qWarning() << QLatin1String("Unable to remove push rule for keyword %1: ").arg(m_rules[index].id) << job->errorString();
});
@@ -353,18 +344,10 @@ void PushRuleModel::removeKeyword(const QString &keyword)
void PushRuleModel::setNotificationRuleEnabled(const QString &kind, const QString &ruleId, bool enabled)
{
#if Quotient_VERSION_MINOR > 8
auto job = m_connection->callApi<Quotient::IsPushRuleEnabledJob>(kind, ruleId);
#else
auto job = m_connection->callApi<Quotient::IsPushRuleEnabledJob>(QStringLiteral("global"), kind, ruleId);
#endif
connect(job, &Quotient::BaseJob::success, this, [job, kind, ruleId, enabled, this]() {
if (job->enabled() != enabled) {
#if Quotient_VERSION_MINOR > 8
m_connection->callApi<Quotient::SetPushRuleEnabledJob>(kind, ruleId, enabled);
#else
m_connection->callApi<Quotient::SetPushRuleEnabledJob>(QStringLiteral("global"), kind, ruleId, enabled);
#endif
}
});
}
@@ -378,11 +361,7 @@ void PushRuleModel::setNotificationRuleActions(const QString &kind, const QStrin
actions = actionToVariant(action);
}
#if Quotient_VERSION_MINOR > 8
m_connection->callApi<Quotient::SetPushRuleActionsJob>(kind, ruleId, actions);
#else
m_connection->callApi<Quotient::SetPushRuleActionsJob>(QStringLiteral("global"), kind, ruleId, actions);
#endif
}
PushRuleAction::Action PushRuleModel::variantToAction(const QList<QVariant> &actions, bool enabled)

View File

@@ -212,7 +212,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
return room->displayName().toHtmlEscaped();
}
if (role == AvatarRole) {
return room->avatarMediaId();
return room->avatarMediaUrl();
}
if (role == CanonicalAliasRole) {
return room->canonicalAlias();

View File

@@ -286,6 +286,7 @@ QHash<int, QByteArray> RoomTreeModel::roleNames() const
roles[IconRole] = "icon";
roles[AttentionRole] = "attention";
roles[FavouriteRole] = "favourite";
roles[RoomTypeRole] = "roomType";
return roles;
}
@@ -323,7 +324,7 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
return room->displayName();
}
if (role == AvatarRole) {
return room->avatarMediaId();
return room->avatarMediaUrl();
}
if (role == CanonicalAliasRole) {
return room->canonicalAlias();
@@ -385,6 +386,11 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
if (role == FavouriteRole) {
return room->isFavourite();
}
if (role == RoomTypeRole) {
if (room->creation()) {
return room->creation()->contentPart<QString>("type"_L1);
}
}
return {};
}

View File

@@ -50,6 +50,7 @@ public:
IconRole,
AttentionRole, /**< Whether there are any notifications. */
FavouriteRole, /**< Whether the room is favourited. */
RoomTypeRole, /**< The room's type. */
};
Q_ENUM(EventRoles)
explicit RoomTreeModel(QObject *parent = nullptr);

View File

@@ -157,6 +157,11 @@ bool SortFilterRoomTreeModel::filterAcceptsRow(int source_row, const QModelIndex
return false;
}
// Hide rooms with defined types, assuming that data-holding rooms have a defined type
if (!sourceModel()->data(index, RoomTreeModel::RoomTypeRole).toString().isEmpty()) {
return false;
}
static auto config = NeoChatConfig::self();
if (config->allRoomsInHome() && RoomManager::instance().currentSpace().isEmpty()) {
return acceptRoom;

View File

@@ -93,11 +93,7 @@ void SpaceChildrenModel::refreshModel()
});
}
#if Quotient_VERSION_MINOR >= 9
void SpaceChildrenModel::insertChildren(std::vector<Quotient::GetSpaceHierarchyJob::SpaceHierarchyRoomsChunk> children, const QModelIndex &parent)
#else
void SpaceChildrenModel::insertChildren(std::vector<Quotient::GetSpaceHierarchyJob::ChildRoomsChunk> children, const QModelIndex &parent)
#endif
{
SpaceTreeItem *parentItem = getItem(parent);

View File

@@ -144,9 +144,5 @@ private:
void refreshModel();
#if Quotient_VERSION_MINOR >= 9
void insertChildren(std::vector<Quotient::GetSpaceHierarchyJob::SpaceHierarchyRoomsChunk> children, const QModelIndex &parent = QModelIndex());
#else
void insertChildren(std::vector<Quotient::GetSpaceHierarchyJob::ChildRoomsChunk> children, const QModelIndex &parent = QModelIndex());
#endif
};

View File

@@ -6,7 +6,6 @@
#include <Quotient/events/event.h>
#include <Quotient/events/stickerevent.h>
#include <Quotient/jobs/basejob.h>
#include <Quotient/omittable.h>
#include <memory>
#include "chatbarcache.h"

View File

@@ -87,11 +87,7 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
return memberId;
}
if (role == AvatarRole) {
#if Quotient_VERSION_MINOR > 8
return m_currentRoom->member(memberId).avatarUrl();
#else
return m_currentRoom->memberAvatar(memberId).url();
#endif
}
if (role == ObjectRole) {
return QVariant::fromValue(memberId);
@@ -176,11 +172,7 @@ void UserListModel::refreshAllMembers()
if (m_currentRoom != nullptr) {
m_members = m_currentRoom->joinedMemberIds();
#if Quotient_VERSION_MINOR > 8
MemberSorter sorter;
#else
MemberSorter sorter(m_currentRoom);
#endif
std::sort(m_members.begin(), m_members.end(), [&sorter, this](const auto &left, const auto &right) {
const auto leftPl = m_currentRoom->getUserPowerLevel(left);
const auto rightPl = m_currentRoom->getUserPowerLevel(right);

View File

@@ -261,7 +261,7 @@ Action=Popup
Name=Share
Name[ar]=شارك
Name[ca]=Compartició
Name[ca@valencia]=Compartició
Name[ca@valencia]=Compartiu
Name[cs]=Sdílet
Name[de]=Teilen
Name[el]=Κοινοποίηση
@@ -282,6 +282,7 @@ Name[nl]=Gedeelde
Name[nn]=Del
Name[pl]=Udostępnij
Name[pt_BR]=Compartilhar
Name[ru]=Публикация
Name[sl]=Deli
Name[sv]=Dela
Name[ta]=பகிர்
@@ -312,6 +313,7 @@ Comment[nl]=Het resultaat van het delen van een stukje inhoud
Comment[nn]=Resultatet av deling av innhald
Comment[pl]=Wynik udostępniania kawałka treści
Comment[pt_BR]=O resultado de compartilhar um conteúdo
Comment[ru]=Результат публикации данных
Comment[sl]=Rezultat deljenega kosa vsebine
Comment[sv]=Resultatet av att dela innehåll
Comment[ta]=எதையோ பகிர்ந்த‍தன் விளைவு

View File

@@ -27,6 +27,18 @@
<label>Use s/text/replacement syntax to edit your last message.</label>
<default>false</default>
</entry>
<entry name="SendMessageWith" type="Enum">
<label>Key combination to send a message</label>
<choices>
<choice name="Enter">
<label>Enter</label>
</choice>
<choice name="CtrlEnter">
<label>Ctrl+Enter</label>
</choice>
<default>Enter</default>
</choices>
</entry>
<entry name="ShowLocalMessagesOnRight" type="bool">
<label>"Show your messages on the right</label>
<default>true</default>

View File

@@ -533,7 +533,6 @@ LinkPreviewer *NeoChatConnection::previewerForLink(const QUrl &link)
return previewer;
}
#if Quotient_VERSION_MINOR > 8
KeyImport::Error NeoChatConnection::exportMegolmSessions(const QString &passphrase, const QString &path)
{
KeyImport keyImport;
@@ -548,6 +547,5 @@ KeyImport::Error NeoChatConnection::exportMegolmSessions(const QString &passphra
file.close();
return KeyImport::Success;
}
#endif
#include "moc_neochatconnection.cpp"

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