Compare commits

..

125 Commits

Author SHA1 Message Date
Albert Astals Cid
c77dee09f5 GIT_SILENT Upgrade release service version to 23.07.90. 2023-08-10 21:00:24 +02:00
l10n daemon script
26dde017d0 GIT_SILENT Sync po/docbooks with svn 2023-08-10 03:07:45 +00:00
l10n daemon script
5b27a84bcc GIT_SILENT Sync po/docbooks with svn 2023-08-09 03:12:18 +00:00
Carl Schwan
fc3c36838c Display big emoji correctly
We already check with a regex if the message only contains emoji so it is safe
to hardcode the font family as emoji for these messages.


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

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


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


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


(cherry picked from commit 75cd77facb)
2023-07-24 10:46:57 +02:00
Carl Schwan
9906ba8b7d Move no connection info message to the top
(cherry picked from commit f8d3e25f8e)
2023-07-24 10:46:35 +02:00
Tobias Fella
b949092bc6 Fix clearing user search field text when switching rooms
(cherry picked from commit 9ba6b2f0a5)
2023-07-24 10:46:16 +02:00
Tobias Fella
5cce3bd692 Fix nullptr check 2023-07-23 23:12:01 +02:00
Carl Schwan
ef5d67e5bf Add back some spacing around the avatar in the timeline
(cherry picked from commit b486cb905c)
2023-07-22 22:32:28 +02:00
Carl Schwan
4711b954c5 Fix accessibility of StartChatPage and port to new components
(cherry picked from commit cdd5c9f484)
2023-07-22 22:32:27 +02:00
Carl Schwan
1688b00f48 Port Avatar usage in Settings KirigamiAddons
(cherry picked from commit 3e6c426397)
2023-07-22 22:32:27 +02:00
Carl Schwan
410befa4bf Port most Avatar usage to new KirigamiAddons Avatar
(cherry picked from commit 847f41e1ad)
2023-07-22 22:32:27 +02:00
Carl Schwan
b380c74b0e Remove hover effect on timeline events 2023-07-22 22:32:20 +02:00
Carl Schwan
da8227931f Remove duplicated code in QuickSwitcher for RoomDelegate 2023-07-22 22:31:42 +02:00
Carl Schwan
fdc45ec5c8 Redesign room list
Use KirigamiAddons.Delegated.RoundedItemDelegate
2023-07-22 22:31:38 +02:00
Carl Schwan
94dd69ea02 Scroll to top of RoomDrawer on loading of header
(cherry picked from commit c8b4da2b96)
2023-07-22 17:53:06 +00:00
Carl Schwan
80c3253a6e Discard wrong avatar urls
(cherry picked from commit ed5bb270ff)
2023-07-22 17:51:46 +00:00
l10n daemon script
c5f6a6607e GIT_SILENT Sync po/docbooks with svn 2023-07-21 03:39:31 +00:00
l10n daemon script
a10d5cbe75 GIT_SILENT Sync po/docbooks with svn 2023-07-20 03:31:32 +00:00
l10n daemon script
584cad19b1 GIT_SILENT made messages (after extraction) 2023-07-20 02:45:39 +00:00
Carl Schwan
3745414635 Port to KirigamAddons.Banner
(cherry picked from commit 3263a69880)
2023-07-19 22:48:56 +02:00
l10n daemon script
147ce42c04 GIT_SILENT Sync po/docbooks with svn 2023-07-19 05:18:38 +00:00
l10n daemon script
928feeca82 GIT_SILENT made messages (after extraction) 2023-07-18 08:31:37 +00:00
Tobias Fella
fc04af536d Fix opening user mentions
(cherry picked from commit 646c8ba8fe)
2023-07-18 08:06:16 +02:00
Tobias Fella
12b949d6cb Fix image loading in room avatars
(cherry picked from commit 918e805718)
2023-07-18 05:26:04 +00:00
l10n daemon script
6aaaabf159 GIT_SILENT Sync po/docbooks with svn 2023-07-18 04:13:52 +00:00
l10n daemon script
fe45ef85a6 GIT_SILENT made messages (after extraction) 2023-07-18 02:55:30 +00:00
Albert Astals Cid
13e38ed982 GIT_SILENT Upgrade release service version to 23.07.80. 2023-07-17 11:25:34 +02:00
Laurent Montel
3855922ad2 Add explicit moc includes to sources for moc-covered headers 2023-07-16 11:08:19 +02:00
l10n daemon script
89a094ce8f GIT_SILENT Sync po/docbooks with svn 2023-07-16 01:58:12 +00:00
l10n daemon script
d4421aaecf GIT_SILENT made messages (after extraction) 2023-07-16 00:48:59 +00:00
Tobias Fella
80b451c27b Only create consent sheet if required 2023-07-15 20:52:03 +00:00
Tobias Fella
32ff22ba89 Fix most compilation warnings 2023-07-15 20:39:38 +00:00
Tobias Fella
b990e3fbcb Stop using the AccountRegistry Singleton 2023-07-15 20:31:24 +00:00
Laurent Montel
8d1baab89f Add missing explicit keyword 2023-07-15 16:01:19 +00:00
Laurent Montel
62ecbc8d6b Includes is already defined in header 2023-07-15 16:58:34 +02:00
Laurent Montel
0e1c7f8c47 Fix qml Audio/Video support in qt6 too.
in Audio qt6 we don't have autoload feature but we disable it in qt5 => it seems ok

In Video qml qt6 we don't have flushMode.
2023-07-15 12:51:13 +00:00
Tobias Fella
c963966f1d Enforce namespaced includes for libQuotient 2023-07-15 14:05:11 +02:00
Tobias Fella
8db2526153 Improve DevicesPage and DevicesModel
- Split the list into sections for "this devices", "verified devices", "unverified devices", and "devices without encryption support"
- Sort the lists by last activity
2023-07-15 13:31:28 +02:00
Tobias Fella
7587a1a418 Drop ifdefs for libQuotient 0.7 2023-07-15 09:18:05 +02:00
Tobias Fella
294812956a Require libQuotient 0.7 2023-07-15 00:53:43 +02:00
Tobias Fella
d01aac6fa3 Remove libQuotient 0.6 based CI 2023-07-15 00:53:19 +02:00
l10n daemon script
5cda1ca3ce GIT_SILENT Sync po/docbooks with svn 2023-07-14 02:01:40 +00:00
Laurent Montel
bf26a463e0 Ignore build* 2023-07-13 07:13:47 +02:00
l10n daemon script
30180c1ac8 GIT_SILENT Sync po/docbooks with svn 2023-07-13 01:56:46 +00:00
l10n daemon script
41c296061c SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-07-13 01:45:17 +00:00
l10n daemon script
461420af0a GIT_SILENT made messages (after extraction) 2023-07-13 00:49:09 +00:00
Laurent Montel
052a7ed571 Ignore src/res.generated.qrc file 2023-07-12 22:28:08 +00:00
Laurent Montel
98e86f887b Adapt qml for qt5 and qt6 2023-07-12 22:28:08 +00:00
Laurent Montel
63a17b5985 Remove duplicate headers between header/cpp 2023-07-12 22:27:39 +00:00
Tobias Fella
025b367a7e Always enable E2EE in libQuotient
It's off-by-default in libQuotient 0.8
2023-07-12 22:10:37 +00:00
Laurent Montel
a8536b0634 Remove extra ; 2023-07-12 18:16:55 +00:00
Laurent Montel
0c43d3eeee Fix equal operator deprecated in c++20 2023-07-12 18:16:19 +00:00
Laurent Montel
bf1614256b Qt::AA_EnableHighDpiScaling is by default in qt6 2023-07-12 18:14:28 +00:00
Laurent Montel
99614d1b27 Use QString::isEmpty here 2023-07-12 14:27:24 +00:00
Laurent Montel
e1e57ef27a Use qt new header 2023-07-12 13:15:58 +00:00
Laurent Montel
6d45d126f8 Add explicit moc includes to sources for moc-covered headers
Add missing #pragma once + missing include

* speeds up incremental builds as changes to a header will not always
  need the full mocs_compilation.cpp for all the target's headers rebuild,
  while having a moc file sourced into a source file only adds minor
  extra costs, due to small own code and the used headers usually
  already covered by the source file, being for the same class/struct
* seems to not slow down clean builds, due to empty mocs_compilation.cpp
  resulting in those quickly processed, while the minor extra cost of the
  sourced moc files does not outweigh that in summary.
  Measured times actually improved by some percent points.
  (ideally CMake would just skip empty mocs_compilation.cpp & its object
  file one day)
* enables compiler to see all methods of a class in same compilation unit
  to do some sanity checks
* potentially more inlining in general, due to more in the compilation unit
* allows to keep using more forward declarations in the header, as with the
  moc code being sourced into the cpp file there definitions can be ensured
  and often are already for the needs of the normal class methods
2023-07-12 13:15:19 +00:00
Laurent Montel
732b43cbd6 Use const'ref 2023-07-12 11:55:50 +00:00
Laurent Montel
a5da17b000 Use explicit keyword 2023-07-12 11:49:12 +00:00
Laurent Montel
10a294f99e Fix show headers in qtc6 2023-07-12 13:17:30 +02:00
Laurent Montel
882a0d4901 Autogenerate + Install debug category file 2023-07-12 09:50:58 +00:00
Laurent Montel
506d31f53f "This" is not used 2023-07-12 09:50:41 +00:00
l10n daemon script
110f007b41 GIT_SILENT made messages (after extraction) 2023-07-12 00:47:42 +00:00
l10n daemon script
a90943d9ac GIT_SILENT Sync po/docbooks with svn 2023-07-11 01:50:22 +00:00
l10n daemon script
cbe7d8c2c2 GIT_SILENT made messages (after extraction) 2023-07-11 00:47:06 +00:00
James Graham
ae4943dd71 Use new mobileform heading
Does what is says on the tin. Use the recently merged new `MobileForm.FormHeader` component in all settings pages.
2023-07-10 16:46:35 +00:00
James Graham
7bd84bf51e Push Rule Model Rework
This is a significant rework of the handling of push rules. Rather than using a lot of boilerplate code for the default models `KeywordNotificationModel` has been converted to `PushRuleModel` and now handles all push rules.

The new model has the following features:
- Handles all push rules
- Has special handling for the names of default keywords (i.e. it still gives the same text as previously for showing in the settings menus)
- Push rules for blocking individuals or room overrides are still there but hidden so will be available for developer tools (to follow)
- Room specific keywords are now supported.

The notification settings pages have also been refactored to take advantage of the new models. Each section is now just a repeater with a filter for the rules that it should contain. The push rule delegate has now been cleaned up and uses required properties.

Implements network/neochat#574
2023-07-10 16:17:17 +00:00
l10n daemon script
a6ce44eb24 GIT_SILENT Sync po/docbooks with svn 2023-07-10 01:56:36 +00:00
Carl Schwan
b1c42c3d3d Make the whole right sidebar scrollable
The sidebar grew a lot and now contains some tools. This makes the space
left for the room members very small. Particuliary on mobile.

So make the whole sidebar contained inside the ScrollView

This also refactor a few things (e.g. use a plain ToolBar for the header)
2023-07-09 22:41:28 +00:00
Carl Schwan
213aaf3ac4 Ensure chat box and userInfo have the same height 2023-07-09 22:32:46 +00:00
James Graham
c55b40c9c6 Media Model
Create a media model for all the media message in the timeline and then setup `NeoChatMaximizeComponent` so that it can use the media model to scroll through all loaded images and video in the current room.

Depends upon libraries/kirigami-addons!105

FEATURE: 467411
2023-07-08 11:07:04 +00:00
Volker Krause
81928d8b93 Fix binary stripping of APKs with Qt 5.15.10
This fixes APKs on binary factory having exploded in size 3x-5x after
the Qt 5.15.10 update. This also affects release packages and will need
to be backported to those (in Craft).
2023-07-08 07:51:24 +02:00
Ingo Klöcker
b7bddba053 Add Windows-specific screenshots as custom values for Microsoft Store
This is an interim solution until AppStream (hopefully) gets support
for platform-specific screenshots. The captions will be extracted for
translation.
2023-07-07 15:55:11 +02:00
l10n daemon script
307a9370db GIT_SILENT Sync po/docbooks with svn 2023-07-07 01:54:27 +00:00
Volker Krause
2f65cbeb36 Show location descriptions in the timeline when available 2023-07-06 15:08:42 +00:00
l10n daemon script
e0c0b1f0e8 GIT_SILENT Sync po/docbooks with svn 2023-07-06 02:28:47 +00:00
l10n daemon script
74f767aa82 GIT_SILENT Sync po/docbooks with svn 2023-07-04 02:36:05 +00:00
l10n daemon script
7176dd4476 GIT_SILENT Sync po/docbooks with svn 2023-07-03 02:15:16 +00:00
l10n daemon script
f75fe31571 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-07-03 01:58:53 +00:00
l10n daemon script
61bdb1ed5f GIT_SILENT made messages (after extraction) 2023-07-03 00:55:03 +00:00
l10n daemon script
527e9d93a5 GIT_SILENT Sync po/docbooks with svn 2023-07-02 02:21:48 +00:00
l10n daemon script
7d22b30217 GIT_SILENT Sync po/docbooks with svn 2023-06-30 01:54:09 +00:00
Heiko Becker
c0d2333a3d GIT_SILENT Update Appstream for new release
(cherry picked from commit c72cf64369)
2023-06-30 01:16:59 +02:00
l10n daemon script
4a7e1d058c GIT_SILENT Sync po/docbooks with svn 2023-06-29 01:52:16 +00:00
l10n daemon script
66974615f6 GIT_SILENT Sync po/docbooks with svn 2023-06-28 01:55:40 +00:00
Ingo Klöcker
116c888686 Add "16:9 Super hero art" for Microsoft Store 2023-06-27 12:29:01 +02:00
Ingo Klöcker
f6d6a804d2 Add some logos in different sizes for the Microsoft Store 2023-06-27 12:28:06 +02:00
l10n daemon script
6d6d702b97 GIT_SILENT Sync po/docbooks with svn 2023-06-27 01:59:23 +00:00
216 changed files with 28384 additions and 27976 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,4 @@
build
build*
.clang-format
.DS_Store
.kdev4/
@@ -11,3 +11,4 @@ kate.project.ctags.*
.flatpak-builder/
.idea/
cmake-build-*
src/res.generated.qrc

View File

@@ -5,10 +5,10 @@ include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml

View File

@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "23")
set(RELEASE_SERVICE_VERSION_MINOR "07")
set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION_MICRO "90")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
@@ -17,7 +17,7 @@ project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
set(KF_MIN_VERSION "5.105.0")
set(QT_MIN_VERSION "5.15.2")
if (ANDROID)
set(QT_MIN_VERSION "5.15.8")
set(QT_MIN_VERSION "5.15.10")
endif()
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
@@ -48,6 +48,30 @@ if(NEOCHAT_FLATPAK)
include(cmake/Flatpak.cmake)
endif()
if(QT_MAJOR_VERSION STREQUAL "6")
set(BASICLISTITEM_BOLD "font.bold")
set(OVERLAYSHEET_OPEN "onOpened")
set(QTQUICK_MODULE_QML_VERSION "")
set(QTLOCATION_MODULE_QML_VERSION "")
set(QTMULTIMEDIA_MODULE_QML_VERSION "")
set(QTMULTIMEDIA_AUDIO "MediaPlayer")
# in Audio qt6 we don't have it but we disable it in qt5 => it seems ok
set(QTMULTIMEDIA_AUDIO_AUTOLOAD "")
# In Video qml qt6 we don't have it.
set(QTMULTIMEDIA_VIDEO_FLUSHMODE "")
else()
set(BASICLISTITEM_BOLD "bold")
set(OVERLAYSHEET_OPEN "onSheetOpenChanged")
set(QTQUICK_MODULE_QML_VERSION "2.15")
set(QTLOCATION_MODULE_QML_VERSION "5.15")
set(QTMULTIMEDIA_MODULE_QML_VERSION "5.15")
set(QTMULTIMEDIA_AUDIO "Audio")
set(QTMULTIMEDIA_AUDIO_AUTOLOAD "autoLoad: false")
set(QTMULTIMEDIA_VIDEO_FLUSHMODE "flushMode: VideoOutput.FirstFrame")
endif()
set(QUOTIENT_FORCE_NAMESPACED_INCLUDES TRUE)
ecm_setup_version(${PROJECT_VERSION}
VARIABLE_PREFIX NEOCHAT
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
@@ -98,7 +122,7 @@ if(QT_MAJOR_VERSION STREQUAL "6" AND NOT ANDROID AND NOT WIN32)
set(QUOTIENT_SUFFIX "Qt6")
endif()
find_package(Quotient${QUOTIENT_SUFFIX} 0.6)
find_package(Quotient${QUOTIENT_SUFFIX} 0.7)
set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES
TYPE REQUIRED
DESCRIPTION "Qt wrapper around Matrix API"
@@ -178,3 +202,9 @@ file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.qml)
# Fixes the test by excluding this directory
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX [[_(install|build)/.*]])
ecm_check_outbound_license(LICENSES GPL-3.0-only FILES ${ALL_SOURCE_FILES})
ecm_qt_install_logging_categories(
EXPORT NEOCHAT
FILE neochat.categories
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)

View File

@@ -47,6 +47,7 @@ android {
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion
sourceSets {
main {

View File

@@ -7,9 +7,9 @@
#include "neochatroom.h"
#include <connection.h>
#include <quotient_common.h>
#include <syncdata.h>
#include <Quotient/connection.h>
#include <Quotient/quotient_common.h>
#include <Quotient/syncdata.h>
using namespace Quotient;

View File

@@ -6,9 +6,9 @@
#include "texthandler.h"
#include <Quotient/quotient_common.h>
#include <Quotient/syncdata.h>
#include <qnamespace.h>
#include <quotient_common.h>
#include <syncdata.h>
using namespace Quotient;
@@ -71,7 +71,6 @@ private Q_SLOTS:
void linkPreviewsReject();
};
#ifdef QUOTIENT_07
void TextHandlerTest::initTestCase()
{
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
@@ -204,7 +203,6 @@ void TextHandlerTest::initTestCase()
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, json.object());
room->update(std::move(roomData));
}
#endif
void TextHandlerTest::allowedAttributes()
{
@@ -479,7 +477,6 @@ void TextHandlerTest::receiveRichtextIn()
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
}
#ifdef QUOTIENT_07
void TextHandlerTest::receiveRichMxcUrl()
{
const QString testInputString = QStringLiteral(
@@ -497,7 +494,6 @@ void TextHandlerTest::receiveRichMxcUrl()
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString);
}
#endif
/**
* For when your rich input string has a plain text url left in.

View File

@@ -18,6 +18,7 @@
<name xml:lang="de">NeoChat</name>
<name xml:lang="el">NeoChat</name>
<name xml:lang="en-GB">NeoChat</name>
<name xml:lang="eo">NeoChat</name>
<name xml:lang="es">NeoChat</name>
<name xml:lang="eu">NeoChat</name>
<name xml:lang="fi">NeoChat</name>
@@ -54,11 +55,12 @@
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
<summary xml:lang="eo">Kliento por matrix, la malcentra komunikprotokolo</summary>
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
<summary xml:lang="fr">Un client pour « Matrix », le protocole décentralisé de communications.</summary>
<summary xml:lang="gl">Un cliente para Matrix, o protocolo de comunicación descentralizada</summary>
<summary xml:lang="gl">Un cliente para Matrix, o protocolo de comunicación descentralizada.</summary>
<summary xml:lang="hu">Kliens a matrixhoz, a decentralizált kommunikációs protokollhoz</summary>
<summary xml:lang="ia">Un cliente per Matrix, le protocollo de communication decentralisate</summary>
<summary xml:lang="id">Klien untuk matrix, protokol komunikasi terdesentralisasi</summary>
@@ -67,7 +69,7 @@
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</summary>
<summary xml:lang="nn">Ein klient for Matrix, den desentraliserte lynmeldings­protokollen</summary>
<summary xml:lang="nn">Ein klient for Matrix  protokollen for desentralisert kommunikasjon</summary>
<summary xml:lang="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
@@ -88,17 +90,22 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ca">El NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Fa servir els Frameworks de KDE i, sobretot, el Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
<p xml:lang="ca-valencia">NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Utilitza els Frameworks de KDE i, sobretot, Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
<p xml:lang="en-GB">NeoChat is a client for Matrix, the decentralised communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.</p>
<p xml:lang="eo">NeoChat estas kliento por Matrix, la malcentra komunikoprotokolo por tuja mesaĝado. Ĝi ebligas al vi sendi tekstmesaĝojn, filmetojn kaj sondosierojn al via familio, kolegoj kaj amikoj. Ĝi uzas KDE-framojn kaj precipe Kirigami por disponigi konverĝan sperton tra pluraj platformoj.</p>
<p xml:lang="es">NeoChat es un cliente para Matrix, el protocolo de comunicaciones descentralizado para mensajería instantánea. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos. Usa la infraestructura de KDE y, en particular, Kirigami para proporcionar una experiencia convergente en muchas plataformas.</p>
<p xml:lang="eu">NeoChat «Matrix»erako, bat-bateko mezularitzarako komunikazio deszentralizatuko protokolorako, bezero bat da. Zure sendiari, kide eta lagunei testu mezuak, bideo eta audio fitxategiak bidaltzeko aukera ematen dizu. «KDE Frameworks» eta bereziki «Kirigami» erabiltzen ditu plataforma anitzen artean esperientzia konbergente bat eskaintzeko.</p>
<p xml:lang="fi">NeoChat on asiakassovellus Matrixille, hajautetulle pikaviestinyhteyskäytännölle. Sillä voi lähettää teksti-, video- ja ääniviestejä perheelle, tutuille ja ystäville. Se käyttää KDE-kehystä ja erityisesti Kirigamia tuottaakseen mukautuvan monialustaisen käyttökokemuksen.</p>
<p xml:lang="fr">NeoChat est un client pour le protocole Matrix, un protocole décentralisé de communications pour messagerie instantané. Il vous permet d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos amis. Il utilise les environnements de développement et plus précisément Kirigami pour fournir une expérience convergente sur plusieurs plate-formes. </p>
<p xml:lang="gl">NeoChat é un cliente para Matrix, o protocolo de comunicación descentralizada para mensaxería instantánea. Podes enviar mensaxes de texto, vídeos e ficheiros de son á túa familia, colegas e amizades. Usas infraestruturas de KDE e principalmente Kirigami para proporcionar unha experiencia de uso converxente para varias plataformas.</p>
<p xml:lang="gl">NeoChat é un cliente para Matrix, o protocolo de comunicación descentralizada para mensaxaría instantánea. Podes enviar mensaxes de texto, vídeos e ficheiros de son á túa familia, colegas e amizades. Usas infraestruturas de KDE e principalmente Kirigami para proporcionar unha experiencia de uso converxente para varias plataformas.</p>
<p xml:lang="ia">NeoChat es un cliente per Matrix, le protocollo de communication decentralisate per messager instantanee. Illo te permitte inviar messager de texto, files de video e audio a tu familia, collegas e amicos usante. Illo usa KDE frameworks e super toto Kirigamii forni un experientia convergente trans platteforme multiple.</p>
<p xml:lang="it">NeoChat è un client per Matrix, il protocollo di comunicazione decentralizzato per la messaggistica istantanea. Ti consente di inviare messaggi di testo, video e file audio a familiari, colleghi e amici. Utilizza i framework KDE e in particolare Kirigami per fornire un'esperienza convergente su più piattaforme.</p>
<p xml:lang="ka">NeoChat არის Matrix კლიენტი. ის საშუალებას გაძლევთ გაგზავნოთ ტექსტური შეტყობინებები, ვიდეოები და აუდიო ფაილები თქვენს ოჯახს, კოლეგებსა და მეგობრებს მატრიქსის პროტოკოლის გამოყენებით.</p>
<p xml:lang="ko">NeoChat은 분산형 인스턴트 메시징 통신 프로토콜인 Matrix 클라이언트입니다. 가족, 동료, 친구에게 텍스트 메시지, 동영상, 오디오 파일을 전송할 수 있습니다. KDE 프레임워크와 Kirigami를 사용하여 다양한 플랫폼에서 일관적인 사용자 경험을 제공합니다.</p>
<p xml:lang="nl">NeoChat is een client voor Matrix, het gedecentraliseerde communicatieprotocol voor instant messages. Het biedt u het verzenden van tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden. Het gebruik KDE frameworks en het meest opmerkelijk Kirigami om een convergente ervaring te leveren op meerdere platforms.</p>
<p xml:lang="nn">NeoChat er ein klient for Matrix, ein protokoll for desentralisert kommunikasjon. Du kan utveksla tekst, lyd og videoar med kollegaar, vennar og familie. Programmet brukar KDE Frameworks og Kirigami for å gje ei brukarflate tilpassa ulike plattformer.</p>
<p xml:lang="pl">NeoChat jest programem do Matriksa, protokołu rozproszonego porozumiewania się w czasie rzeczywistym. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół. Używa szkieletów KDE i głównie Kirigami, aby zapewnić spójne wrażenia na wielu platformach</p>
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix. Usa as plataformas do KDE, e principalmente o Kirigami, para oferecer uma experiência convergente entre várias plataformas.</p>
<p xml:lang="sl">Neochat je odjemalec za Matrix, decentralizirani komunikacijski protokol za takojšnje sporočanje. Omogoča vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek svoji družini, sodelavcem in prijateljem. Uporablja okvire ogrodje KDE frameworks in predvsem Kirigami za zagotavljanje konvergentne izkušnje na več platformah.</p>
<p xml:lang="sv">NeoChat är en klient för Matrix, det decentraliserade kommunikationsprotokollet för direktmeddelanden. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner. Den använder KDE Ramverk, i synnerhet Kirigami, för att tillhandahålla en konvergent upplevelse på flera plattformar.</p>
<p xml:lang="tr">NeoChat, anlık iletileşme için merkezi olmayan iletişim protokolü olan Matrix için bir istemcidir. Ailenize, iş arkadaşlarınıza ve arkadaşlarınıza metin iletiler, videolar ve ses dosyaları göndermenize olanak tanır. Birden çok platformda yakınsak bir deneyim sağlamak için KDE Frameworks ve en önemlilerinden Kirigami'yi kullanır.</p>
<p xml:lang="uk">NeoChat — клієнт Matrix, децентралізованого протоколу спілкування для миттєвого обміну повідомленнями. За його допомогою ви можете надсилати текстові повідомлення, відео та звукові файли вашій родин, колегами та друзям. У програмі використано бібліотеки KDE, зокрема Kirigami, для надання однорідного середовища на декількох програмних та апаратних платформах.</p>
<p xml:lang="x-test">xxNeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.xx</p>
@@ -108,16 +115,20 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
<p xml:lang="en-GB">NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
<p xml:lang="es">NeoChat pretende ser una aplicación con todas las funciones para la especificación de Matrix. Como tal, admite todo en la especificación estable actual, con las notables excepciones de VoIP, subprocesos y algunas funciones de cifrado de extremo a extremo. Existen algunas omisiones menos importantes debido al hecho de que la especificación de Matrix está en constante evolución, pero el objetivo sigue siendo brindar compatibilidad final con toda la especificación.</p>
<p xml:lang="eu">«NeoChat»ek «Matrix» zehaztapenaren ezaugarri guztiak eskaintzen dituen aplikazio bat izan nahi du. Beraz, egungo zehaztapen egonkorrean dagoen guztiaren euskarria du, VoIP, hariak eta muturren artean zifratzeko salbuespen nabarmenekin. Badira beste ez-betetze txikiago batzuk, «Matrix»en zehaztapena etengabe eboluzioan dagoelako, baina azken helburua zehaztapen osoaren euskarria ematea izaten jarraitzen du.</p>
<p xml:lang="fi">NeoChat pyrkii olemaan Matrix-määritelmän täysominaisuuksinen sovellus, joten se tukee kaikkea nykyisessä vakaassa määritelmässä muutamaa huomattavaa poikkeusta lukuun ottamatta (VoIP, säikeet ja jotkin piirteet päästä päähän -salauksessa). Joitakin pienempiäkin puutteita on Matrix-määritelmän jatkuvan kehityksen vuoksi, mutta lopputavoitteena on tarjota määritelmän täysi tuki.</p>
<p xml:lang="fr">L'objectif de NeoChat est d'être une application complète pour le protocole Matrix. En tant que tel, tout dans la spécification stable actuelle avec les exceptions notables de VoIP, les processus et certains aspects du chiffrement de bout en bout sont pris en charge. Il y a quelques autres petites omissions en raison du fait que la spécification du protocole Matrix est en constante évolution. Cependant, l'objectif reste de fournir un soutien éventuel pour l'ensemble de la spécification.</p>
<p xml:lang="gl">NeoChat pretende ser unha aplicación completa para a especificación de Matrix. Coas excepcións de VoIP, conversas fiadas e algúns aspectos da cifraxe de extremo a extremo, a versión estábel segue as especificacións. Existen algunhas outras pequenas omisións debido ao feito de que Matrix está en continua evolución pero a intención é implementar a especificación completa.</p>
<p xml:lang="ia">NeoChat aspira a esser un application plenemente eminente per le specification de Matrix. Tal como omne cosas in le specification currentemente stabile con le exceptiones notabile de VOIP, threads e alcun aspectos del cryptation End-to-End es supportate. Il ha ltere pauc omissiones, debite al facto que le specification de Matrix es in evolution constante ma le aspiration remane a fornir supporto eventual per le integre specification.</p>
<p xml:lang="it">NeoChat mira ad essere un'applicazione completa per le specifiche Matrix. Pertanto, sono supportati tutti gli elementi dell'attuale specifica stabile con le notevoli eccezioni di VoIP, conversazioni e alcuni aspetti della cifratura end-to-end. Ci sono alcune altre piccole omissioni dovute al fatto che le specifiche Matrix sono in continua evoluzione, ma l'obiettivo rimane quello di fornire un eventuale supporto per l'intera specifica.</p>
<p xml:lang="ka">NeoChat-ი მიზნად ისახავს Matrix სპეციფიკაციის სრული განხორციელება ჰქონდეს. როგორც ასეთი, ყველაფერი მიმდინარე სპეციფიკაციიდან, VoIP-ის, ძაფებისა და გამჭოლი დაშიფვრის ზოგიერთი ასპექტის გარდა, მხარდაჭერილია. შეძლება ასევე იყოს მცირე ლაფსუსებიც იმის გამო, რომ Matrix-ის სპეციფიკაცია მუდმივად ვითარგდება, მაგრამ ჩვენი მიზანი მისი სრული მხარდაჭერაა.</p>
<p xml:lang="ko">NeoChat은 Matrix 표준을 따르는 프로그램을 목표로 합니다. 현재 안정 버전의 표준에서 제공하는 기능의 대부분을 지원하며, VoIP, 스레드, 일부 종단간 암호화와 같은 기능은 아직 지원하지 않습니다. Matrix 표준은 계속하여 진화 중이기 때문에 일부 기능이 빠져 있을 수도 있지만 장기적으로는 전체 표준을 지원하는 것이 목표입니다.</p>
<p xml:lang="nl">NeoChat richt zich op het volledig bieden van alle mogelijkheden van de Matrix-specificatie. Alles in de huidige stabiele specificatie met merkbare uitzondering van VoIP, gekoppelde discussies en sommige aspecten van eind-tot-eind versleuteling worden ondersteund. Er zijn een paar andere kleinere omissies vanwege het feit dat de Matrix specificatie constant evolueert maar het doel blijft het eventueel bieden van ondersteuning van de gehele specificatie.</p>
<p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme'nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
<p xml:lang="uk">Метою створення NeoChat є повноцінна реалізація програми для специфікації Matrix. Як наслідок, реалізовано усе у поточній стабільній специфікації, окрім голосового інтернет-зв'язку, потоків та деяких аспектів міжвузлового шифрування. Є також декілька інших незначних прогалин через те, що специфікація Matrix постійно змінюється, але метою лишається повна підтримка специфікації.</p>
<p xml:lang="x-test">xxNeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.xx</p>
@@ -127,16 +138,21 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ca-valencia">A causa de la naturalea del desenvolupament de l'especificació de Matrix, NeoChat també implementa nombroses característiques inestables. Actualment són:</p>
<p xml:lang="en-GB">Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:</p>
<p xml:lang="es">Debido a la naturaleza del desarrollo de la especificación de Matrix, NeoChat también permite numerosas funciones no estables, como:</p>
<p xml:lang="eu">«Matrix» zehaztapenaren garapenaren izaeragatik, «Neo¢hat»ek ezaugarri ezegonkor ugari ere onartzen ditu. Gaur egun hauek:</p>
<p xml:lang="fi">Matrix-määritelmän kehittyessä NeoChat tukee myös monia epävakaita ominaisuuksia. Tällä hetkellä näitä ovat:</p>
<p xml:lang="fr">En raison de la nature du développement des spécifications du protocole Matrix, NeoChat prend également en charge de nombreuses fonctionnalités instables. Actuellement, ce sont :</p>
<p xml:lang="gl">Debido á natureza do desenvolvemento da especificación de Matrix, NeoChat tamén inclúe varias funcionalidades non estábeis:</p>
<p xml:lang="ia">Debite al natura del disveloppamento de specification de Matrix NeoChat tamben supporta numerose characteristicas instabile. Currentemente istes es:</p>
<p xml:lang="it">A causa della natura dello sviluppo delle specifiche Matrix, NeoChat supporta anche numerose funzionalità instabili. Attualmente queste sono:</p>
<p xml:lang="ka">Matrix-ის სპეციფიკაციის განვითარების ბუნების გამო NeoChat-ს ასევე აქვს უამრავი არასტაბილური ფუნქციაც. ახლა ისინია:</p>
<p xml:lang="ko">Matrix 표준 개발의 특징으로 인하여 NeoChat은 일부 실험적인 기능을 지원합니다. 현재 지원하는 기능은 다음과 같습니다.</p>
<p xml:lang="nl">Vanwege de aard van de ontwikkeling van de Matrix specificatie ondersteunt NeoChat ook talloze onstabiele mogelijkheden. Dit zijn nu:</p>
<p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் வித‍த்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
<p xml:lang="tr">NeoChat, Matrix belirtimi geliştirmesinin doğası gereği çok sayıda kararsız özelliği de destekler. Şu anda bunlar:</p>
<p xml:lang="uk">Через природу розробки специфікації Matrix, у NeoChat також передбачено підтримку численних нестабільних можливостей. У поточній версії цими можливостями є:</p>
<p xml:lang="x-test">xxDue to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:xx</p>
@@ -147,15 +163,19 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ca-valencia">Enquestes - MSC3381</li>
<li xml:lang="en-GB">Polls - MSC3381</li>
<li xml:lang="es">Encuestas - MSC3381</li>
<li xml:lang="eu">Polls - MSC3381</li>
<li xml:lang="fi">Kyselyt MSC3381</li>
<li xml:lang="fr">Sondages - MSC3381</li>
<li xml:lang="gl">Enquisas - MSC3381</li>
<li xml:lang="gl">Enquisas MSC3381</li>
<li xml:lang="ia">Inquestas - MSC3381</li>
<li xml:lang="it">Sondaggi - MSC3381</li>
<li xml:lang="ka">Polls - MSC3381</li>
<li xml:lang="ko">투표 - MSC3381</li>
<li xml:lang="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="sv">Polls - MSC3381</li>
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
<li xml:lang="tr">Anketler - MSC3381</li>
<li xml:lang="uk">Опитування - MSC3381</li>
@@ -166,15 +186,19 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ca-valencia">Paquets d'adhesius - MSC2545</li>
<li xml:lang="en-GB">Sticker Packs - MSC2545</li>
<li xml:lang="es">Paquetes de pegatinas - MSC2545</li>
<li xml:lang="eu">Eranskailu paketeak - MSC2545</li>
<li xml:lang="fi">Tarrapakkaukset MSC2545</li>
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
<li xml:lang="gl">Paquetes de adhesivos - MSC2545</li>
<li xml:lang="gl">Paquetes de adhesivos MSC2545</li>
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
<li xml:lang="ka">სტიკერების პაკეტები - MSC2545</li>
<li xml:lang="ko">스티커 팩 - MSC2545</li>
<li xml:lang="nl">Sticker Packs - MSC2545</li>
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="sv">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
<li xml:lang="tr">Yapışkan Paketleri - MSC2545</li>
<li xml:lang="uk">Пакунки наліпок - MSC2545</li>
@@ -185,26 +209,25 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ca-valencia">Esdeveniments d'ubicació - MSC3488</li>
<li xml:lang="en-GB">Location Events - MSC3488</li>
<li xml:lang="es">Eventos de ubicación - MSC3488</li>
<li xml:lang="eu">Kokaleku-gertaerak - MSC3488</li>
<li xml:lang="fi">Sijaintitapahtumat MSC3488</li>
<li xml:lang="fr">Événements de lieu - MSC3488</li>
<li xml:lang="gl">Localización de eventos - MSC3488</li>
<li xml:lang="gl">Localización de eventos MSC3488</li>
<li xml:lang="ia">Eventos de Location - MSC3488</li>
<li xml:lang="it">Località eventi - MSC3488</li>
<li xml:lang="ka">მდებარეობის მოვლენები - MSC3488</li>
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
<li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="sv">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
<li xml:lang="tr">Konum Etkinlikleri - MSC3488</li>
<li xml:lang="uk">Місцеві зустрічі - MSC3488</li>
<li xml:lang="x-test">xxLocation Events - MSC3488xx</li>
</ul>
</description>
<keywords>
<keyword>instant messaging</keyword>
<keyword>chat</keyword>
<keyword>matrix</keyword>
</keywords>
<url type="homepage">https://apps.kde.org/neochat/</url>
<url type="bugtracker">https://bugs.kde.org/buglist.cgi?component=General&amp;product=NeoChat</url>
<categories>
@@ -219,6 +242,7 @@ to provide a convergent experience across multiple platforms.</p>
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
<developer_name xml:lang="el">Η Κοινότητα του KDE</developer_name>
<developer_name xml:lang="en-GB">The KDE Community</developer_name>
<developer_name xml:lang="eo">La KDE-Komunumo</developer_name>
<developer_name xml:lang="es">La comunidad KDE</developer_name>
<developer_name xml:lang="eu">KDE komunitatea</developer_name>
<developer_name xml:lang="fi">KDE-yhteisö</developer_name>
@@ -256,15 +280,48 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
<value key="KDE::feature1">Supports the Matrix protocol for instant messaging.</value>
<value key="KDE::feature2">End-to-End Encryption</value>
<value key="KDE::feature3">Polls (experimental)</value>
<value key="KDE::feature4">Sticker Packs (experimental)</value>
<value key="KDE::feature5">Location Events (experimental)</value>
<value key="KDE::windows_store::DesktopScreenshot1">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::DesktopScreenshotCaption1">Main view of NeoChat with room list, chat, and room information pane</value>
<value key="KDE::windows_store::DesktopScreenshot2">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
<value key="KDE::windows_store::DesktopScreenshotCaption2">Login screen of NeoChat</value>
<value key="KDE::windows_store::screenshots::1::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::screenshots::1::caption">Main view with room list, chat, and room information</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ia">Vista principal con lista de sala, chat e information de sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
<value key="KDE::windows_store::screenshots::2::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
<value key="KDE::windows_store::screenshots::2::caption">Login screen</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca-valencia">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="es">Pantalla de inicio de sesión</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="eu">Saio-hasteko pantaila</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="gl">Pantalla de identificación.</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ia">Schermo de accesso</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="it">Schermata di accesso</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ko">로그인 화면</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nn">Innloggingsbilete</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="pt">Ecrã de autenticação</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sl">Prijavni zaslon</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sv">Inloggningsfönster</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ta">நுழைவுத் திரை</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="tr">Oturum açma ekranı</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="uk">Вікно входу</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>
</custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots>
@@ -279,6 +336,7 @@ to provide a convergent experience across multiple platforms.</p>
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="23.04.3" date="2023-07-06"/>
<release version="23.04.2" date="2023-06-08"/>
<release version="23.04.1" date="2023-05-11"/>
<release version="23.04.0" date="2023-04-20">

View File

@@ -11,6 +11,7 @@ Name[cs]=NeoChat
Name[de]=NeoChat
Name[el]=NeoChat
Name[en_GB]=NeoChat
Name[eo]=NeoChat
Name[es]=NeoChat
Name[eu]=NeoChat
Name[fi]=NeoChat
@@ -49,6 +50,7 @@ GenericName[cs]=Klient protokolu Matrix
GenericName[de]=Matrix-Programm
GenericName[el]=Εφαρμογή του Matrix
GenericName[en_GB]=Matrix Client
GenericName[eo]=Matrix-Kliento
GenericName[es]=Cliente para Matrix
GenericName[eu]=Matrix bezeroa
GenericName[fi]=Matrix-asiakas
@@ -86,11 +88,12 @@ 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[gl]=Cliente para o protocolo Matrix.
Comment[hu]=Kliens a Matrix protokollhoz
Comment[ia]=Cliente per le protocollo de Matrix
Comment[id]=Klien untuk protokol Matrix
@@ -100,7 +103,7 @@ Comment[ka]=კლიენტი Matrix-ის პროტოკოლის
Comment[ko]=Matrix 프로토콜용 클라이언트
Comment[lt]=Matrix protokolo kliento programa
Comment[nl]=Client voor het Matrix-protocol
Comment[nn]=Lynmeldings­klient for Matrix-protokollen
Comment[nn]=Klient for Matrix-protokollen
Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ
Comment[pl]=Program obsługi protokołu Matriksa
Comment[pt]=Cliente para o protocolo Matrix

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

@@ -3,74 +3,144 @@
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
configure_file(qml/Page/RoomList/RoomDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Page/RoomList/RoomDelegate.qml)
configure_file(qml/Component/QuickSwitcher.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/QuickSwitcher.qml)
configure_file(qml/Dialog/UserDetailDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/UserDetailDialog.qml)
configure_file(qml/Dialog/PowerLevelDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/PowerLevelDialog.qml)
configure_file(qml/Component/Timeline/AudioDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/AudioDelegate.qml)
configure_file(qml/Component/Timeline/VideoDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/VideoDelegate.qml)
configure_file(qml/Component/Timeline/OsmLocationPlugin.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/OsmLocationPlugin.qml)
configure_file(res.qrc ${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc)
add_library(neochat STATIC
controller.cpp
controller.h
actionshandler.cpp
actionshandler.h
models/emojimodel.cpp
models/emojimodel.h
emojitones.cpp
emojitones.h
models/customemojimodel.cpp
models/customemojimodel.h
clipboard.cpp
clipboard.h
matriximageprovider.cpp
matriximageprovider.h
models/messageeventmodel.cpp
models/messageeventmodel.h
models/messagefiltermodel.cpp
models/messagefiltermodel.h
models/roomlistmodel.cpp
models/roomlistmodel.h
models/sortfilterspacelistmodel.cpp
models/sortfilterspacelistmodel.h
models/accountemoticonmodel.cpp
models/accountemoticonmodel.h
spacehierarchycache.cpp
spacehierarchycache.h
roommanager.cpp
roommanager.h
neochatroom.cpp
neochatroom.h
neochatuser.cpp
neochatuser.h
models/userlistmodel.cpp
models/userlistmodel.h
models/userfiltermodel.cpp
models/userfiltermodel.h
models/publicroomlistmodel.cpp
models/publicroomlistmodel.h
models/userdirectorylistmodel.cpp
models/keywordnotificationrulemodel.cpp
models/userdirectorylistmodel.h
models/pushrulemodel.cpp
models/pushrulemodel.h
models/emoticonfiltermodel.cpp
models/emoticonfiltermodel.h
notificationsmanager.cpp
notificationsmanager.h
models/sortfilterroomlistmodel.cpp
models/sortfilterroomlistmodel.h
chatdocumenthandler.cpp
chatdocumenthandler.h
models/devicesmodel.cpp
models/devicesmodel.h
models/devicesproxymodel.cpp
filetypesingleton.cpp
filetypesingleton.h
login.cpp
login.h
models/webshortcutmodel.cpp
models/webshortcutmodel.h
blurhash.cpp
blurhash.h
blurhashimageprovider.cpp
blurhashimageprovider.h
models/collapsestateproxymodel.cpp
models/collapsestateproxymodel.h
models/mediamessagefiltermodel.cpp
models/mediamessagefiltermodel.h
urlhelper.cpp
urlhelper.h
windowcontroller.cpp
windowcontroller.h
linkpreviewer.cpp
linkpreviewer.h
models/completionmodel.cpp
models/completionmodel.h
models/completionproxymodel.cpp
models/completionproxymodel.h
models/actionsmodel.cpp
models/actionsmodel.h
models/serverlistmodel.cpp
models/serverlistmodel.h
models/statemodel.cpp
models/statemodel.h
models/statefiltermodel.cpp
models/statefiltermodel.h
filetransferpseudojob.cpp
filetransferpseudojob.h
models/searchmodel.cpp
models/searchmodel.h
texthandler.cpp
texthandler.h
logger.cpp
logger.h
models/stickermodel.cpp
models/stickermodel.h
models/imagepacksmodel.cpp
models/imagepacksmodel.h
events/imagepackevent.cpp
events/imagepackevent.h
events/joinrulesevent.cpp
events/stickerevent.cpp
events/joinrulesevent.h
models/reactionmodel.cpp
models/reactionmodel.h
delegatesizehelper.cpp
delegatesizehelper.h
models/livelocationsmodel.cpp
models/livelocationsmodel.h
models/locationsmodel.cpp
models/locationsmodel.h
locationhelper.cpp
locationhelper.h
events/pollevent.cpp
pollhandler.cpp
)
ecm_qt_declare_logging_category(neochat
HEADER "messageeventmodel_logging.h"
IDENTIFIER "MessageEvent"
CATEGORY_NAME "org.kde.neochat.messageeventmodel"
DESCRIPTION "Neochat: messageeventmodel"
DEFAULT_SEVERITY Info
EXPORT NEOCHAT
)
add_executable(neochat-app
main.cpp
res.qrc
${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc
)
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
@@ -79,24 +149,16 @@ target_link_libraries(neochat-app PRIVATE
neochat
)
if(Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
target_compile_definitions(neochat PUBLIC QUOTIENT_07)
target_sources(neochat PRIVATE events/pollevent.cpp pollhandler.cpp)
else()
target_compile_definitions(neochat PUBLIC QUOTIENT_VERSION=\"${Quotient${QUOTIENT_SUFFIX}_VERSION}\")
target_sources(neochat PRIVATE neochataccountregistry.cpp)
endif()
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID)
target_sources(neochat PRIVATE colorschemer.cpp)
target_sources(neochat PRIVATE colorschemer.cpp colorschemer.h)
if (NOT WIN32 AND NOT APPLE)
target_sources(neochat PRIVATE trayicon_sni.cpp)
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
else()
target_sources(neochat PRIVATE trayicon.cpp)
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
endif()
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem)
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)

View File

@@ -3,8 +3,8 @@
#include "actionshandler.h"
#include <csapi/joining.h>
#include <events/roommemberevent.h>
#include <Quotient/csapi/joining.h>
#include <Quotient/events/roommemberevent.h>
#include <cmark.h>
@@ -14,7 +14,6 @@
#include "models/actionsmodel.h"
#include "models/customemojimodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "texthandler.h"
using namespace Quotient;
@@ -183,3 +182,5 @@ void ActionsHandler::checkEffects(const QString &text)
Q_EMIT showEffect(*effect);
}
}
#include "moc_actionshandler.cpp"

View File

@@ -5,7 +5,7 @@
#include <QObject>
#include <events/roommessageevent.h>
#include <Quotient/events/roommessageevent.h>
#include "neochatroom.h"
@@ -47,7 +47,7 @@ public:
Q_SIGNALS:
void roomChanged();
void showEffect(QString effect);
void showEffect(const QString &effect);
public Q_SLOTS:

View File

@@ -14,8 +14,6 @@
#include <Sonnet/BackgroundChecker>
#include <Sonnet/Settings>
#include "neochatroom.h"
class SyntaxHighlighter : public QSyntaxHighlighter
{
public:
@@ -220,8 +218,8 @@ void ChatDocumentHandler::setRoom(NeoChatRoom *room)
void ChatDocumentHandler::complete(int index)
{
if (m_completionModel->autoCompletionType() == CompletionModel::User) {
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString();
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString();
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::DisplayNameRole).toString();
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument());
@@ -234,7 +232,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, name, 0, 0, id});
m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Command) {
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('/'));
QTextCursor cursor(document()->textDocument());
@@ -242,7 +240,7 @@ void ChatDocumentHandler::complete(int index)
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
cursor.insertText(QStringLiteral("/%1 ").arg(command));
} else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString();
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument());
@@ -255,7 +253,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, alias, 0, 0, alias});
m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText();
auto at = text.lastIndexOf(QLatin1Char(':'));
QTextCursor cursor(document()->textDocument());
@@ -355,3 +353,5 @@ void ChatDocumentHandler::setErrorColor(const QColor &color)
m_highlighter->rehighlight();
Q_EMIT errorColorChanged();
}
#include "moc_chatdocumenthandler.cpp"

View File

@@ -79,3 +79,5 @@ void Clipboard::setImage(const QUrl &url)
}
}
}
#include "moc_clipboard.cpp"

View File

@@ -44,3 +44,5 @@ QString ColorSchemer::nameForIndex(int index) const
{
return c->model()->data(c->model()->index(index, 0), Qt::DisplayRole).toString();
}
#include "moc_colorschemer.cpp"

View File

@@ -28,7 +28,7 @@ class ColorSchemer : public QObject
Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT)
public:
ColorSchemer(QObject *parent = nullptr);
explicit ColorSchemer(QObject *parent = nullptr);
~ColorSchemer();
QAbstractItemModel *model() const;

View File

@@ -31,22 +31,15 @@
#include <signal.h>
#ifdef QUOTIENT_07
#include "accountregistry.h"
#else
#include "neochataccountregistry.h"
#endif
#include <connection.h>
#include <csapi/content-repo.h>
#include <csapi/logout.h>
#include <csapi/profile.h>
#include <jobs/downloadfilejob.h>
#include <qt_connection_util.h>
#ifdef QUOTIENT_07
#include <eventstats.h>
#endif
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include <Quotient/csapi/logout.h>
#include <Quotient/csapi/profile.h>
#include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h>
#include <Quotient/csapi/notifications.h>
#include <Quotient/eventstats.h>
#include "neochatconfig.h"
#include "neochatroom.h"
@@ -108,24 +101,22 @@ Controller::Controller(QObject *parent)
}
#endif
#ifdef QUOTIENT_07
connect(&Accounts, &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
#else
connect(&AccountRegistry::instance(), &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
#endif
connect(&m_accountRegistry, &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
#ifdef QUOTIENT_07
static int oldAccountCount = 0;
connect(&Accounts, &AccountRegistry::accountCountChanged, this, [this]() {
if (Accounts.size() > oldAccountCount) {
auto connection = Accounts.accounts()[Accounts.size() - 1];
connect(&m_accountRegistry, &AccountRegistry::accountCountChanged, this, [this]() {
if (m_accountRegistry.size() > oldAccountCount) {
auto connection = m_accountRegistry.accounts()[m_accountRegistry.size() - 1];
connect(connection, &Connection::syncDone, this, [connection]() {
NotificationsManager::instance().handleNotifications(connection);
});
}
oldAccountCount = Accounts.size();
oldAccountCount = m_accountRegistry.size();
});
QTimer::singleShot(0, this, [this] {
m_pushRuleModel = new PushRuleModel;
});
#endif
}
Controller &Controller::instance()
@@ -156,18 +147,10 @@ void Controller::logout(Connection *conn, bool serverSideLogout)
job.start();
loop.exec();
#ifdef QUOTIENT_07
if (Accounts.count() > 1) {
#else
if (AccountRegistry::instance().count() > 1) {
#endif
if (m_accountRegistry.count() > 1) {
// Only set the connection if the the account being logged out is currently active
if (conn == activeConnection()) {
#ifdef QUOTIENT_07
setActiveConnection(Accounts.accounts()[0]);
#else
setActiveConnection(AccountRegistry::instance().accounts()[0]);
#endif
setActiveConnection(m_accountRegistry.accounts()[0]);
}
} else {
setActiveConnection(nullptr);
@@ -182,11 +165,7 @@ void Controller::addConnection(Connection *c)
{
Q_ASSERT_X(c, __FUNCTION__, "Attempt to add a null connection");
#ifdef QUOTIENT_07
Accounts.add(c);
#else
AccountRegistry::instance().add(c);
#endif
m_accountRegistry.add(c);
c->setLazyLoading(true);
@@ -201,7 +180,7 @@ void Controller::addConnection(Connection *c)
});
connect(c, &Connection::requestFailed, this, [this](BaseJob *job) {
if (job->error() == BaseJob::UserConsentRequiredError) {
if (job->error() == BaseJob::UserConsentRequired) {
Q_EMIT userConsentRequired(job->errorUrl());
}
});
@@ -216,15 +195,8 @@ void Controller::dropConnection(Connection *c)
{
Q_ASSERT_X(c, __FUNCTION__, "Attempt to drop a null connection");
#ifndef QUOTIENT_07
AccountRegistry::instance().drop(c);
#endif
Q_EMIT connectionDropped(c);
Q_EMIT accountCountChanged();
#ifndef QUOTIENT_07
c->deleteLater();
#endif
}
void Controller::invokeLogin()
@@ -275,7 +247,7 @@ void Controller::invokeLogin()
connect(connection, &Connection::networkError, this, [this](const QString &error, const QString &, int, int) {
Q_EMIT errorOccured(i18n("Network Error: %1", error));
});
connection->assumeIdentity(account.userId(), accessToken, account.deviceId());
connection->assumeIdentity(account.userId(), accessToken);
});
}
}
@@ -291,7 +263,7 @@ QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const Accoun
job->setKey(account.userId());
// Handling of errors
connect(job, &QKeychain::Job::finished, this, [this, &account, job]() {
connect(job, &QKeychain::Job::finished, this, [this, job]() {
if (job->error() == QKeychain::Error::NoError) {
return;
}
@@ -397,11 +369,7 @@ bool Controller::setAvatar(Connection *connection, const QUrl &avatarSource)
User *localUser = connection->user();
QString decoded = avatarSource.path();
if (decoded.isEmpty()) {
#ifdef QUOTIENT_07
connection->callApi<SetAvatarUrlJob>(localUser->id(), avatarSource);
#else
connection->callApi<SetAvatarUrlJob>(localUser->id(), QString());
#endif
return true;
}
if (QImageReader(decoded).read().isNull()) {
@@ -412,11 +380,7 @@ bool Controller::setAvatar(Connection *connection, const QUrl &avatarSource)
}
NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const Omittable<QJsonObject> &auth)
#ifdef QUOTIENT_07
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), "/_matrix/client/r0/account/password")
#else
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), QStringLiteral("/_matrix/client/r0/account/password"))
#endif
{
QJsonObject _data;
addParam<>(_data, QStringLiteral("new_password"), newPassword);
@@ -427,11 +391,7 @@ NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, b
int Controller::accountCount() const
{
#ifdef QUOTIENT_07
return Accounts.count();
#else
return AccountRegistry::instance().count();
#endif
return m_accountRegistry.count();
}
void Controller::setQuitOnLastWindowClosed()
@@ -507,17 +467,18 @@ void Controller::setActiveConnection(Connection *connection)
Q_EMIT activeAccountLabelChanged();
}
PushRuleModel *Controller::pushRuleModel() const
{
return m_pushRuleModel;
}
void Controller::saveWindowGeometry()
{
WindowController::instance().saveGeometry();
}
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const Omittable<QJsonObject> &auth)
#ifdef QUOTIENT_07
: Quotient::BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId).toLatin1())
#else
: Quotient::BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId))
#endif
{
QJsonObject _data;
addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
@@ -623,11 +584,7 @@ bool Controller::hasWindowSystem() const
bool Controller::encryptionSupported() const
{
#ifdef QUOTIENT_07
return Quotient::encryptionSupported();
#else
return false;
#endif
}
void Controller::forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item)
@@ -668,29 +625,16 @@ void Controller::setApplicationProxy()
int Controller::activeConnectionIndex() const
{
#ifdef QUOTIENT_07
auto result = std::find_if(Accounts.accounts().begin(), Accounts.accounts().end(), [this](const auto &it) {
auto result = std::find_if(m_accountRegistry.accounts().begin(), m_accountRegistry.accounts().end(), [this](const auto &it) {
return it == m_connection;
});
return result - Accounts.accounts().begin();
#else
for (int i = 0; i < AccountRegistry::instance().rowCount(); i++) {
if (AccountRegistry::instance().data(AccountRegistry::instance().index(i, 0), AccountRegistry::UserIdRole).toString() == m_connection->userId()) {
return i;
}
}
return 0;
#endif
return result - m_accountRegistry.accounts().begin();
}
int Controller::quotientMinorVersion() const
{
// TODO libQuotient 0.7: Replace with version function from libQuotient
#ifdef QUOTIENT_07
// TODO libQuotient 0.7: Replace with version function from libQuotient
return 7;
#else
return 6;
#endif
}
bool Controller::isFlatpak() const
@@ -736,3 +680,10 @@ QVariantList Controller::getSupportedRoomVersions(Quotient::Connection *connecti
return supportedRoomVersions;
}
AccountRegistry &Controller::accounts()
{
return m_accountRegistry;
}
#include "moc_controller.cpp"

View File

@@ -3,13 +3,15 @@
#pragma once
#include "models/pushrulemodel.h"
#include <QObject>
#include <QQuickItem>
#include <KFormat>
#include <jobs/basejob.h>
#include <settings.h>
#include <Quotient/accountregistry.h>
#include <Quotient/jobs/basejob.h>
#include <Quotient/settings.h>
class NeoChatRoom;
class NeoChatUser;
@@ -50,6 +52,11 @@ class Controller : public QObject
*/
Q_PROPERTY(Quotient::Connection *activeConnection READ activeConnection WRITE setActiveConnection NOTIFY activeConnectionChanged)
/**
* @brief The PushRuleModel that has the active connection's push rules.
*/
Q_PROPERTY(PushRuleModel *pushRuleModel READ pushRuleModel CONSTANT)
/**
* @brief The row number in the accounts directory of the active connection.
*/
@@ -110,7 +117,7 @@ public:
Wrong, /**< The current password entered was wrong. */
Other, /**< An unknown problem occurred. */
};
Q_ENUM(PasswordStatus);
Q_ENUM(PasswordStatus)
static Controller &instance();
@@ -119,6 +126,8 @@ public:
void setActiveConnection(Quotient::Connection *connection);
[[nodiscard]] Quotient::Connection *activeConnection() const;
[[nodiscard]] PushRuleModel *pushRuleModel() const;
/**
* @brief Add a new connection to the account registry.
*/
@@ -221,6 +230,8 @@ public:
Q_INVOKABLE QVariantList getSupportedRoomVersions(Quotient::Connection *connection);
Quotient::AccountRegistry &accounts();
private:
explicit Controller(QObject *parent = nullptr);
@@ -236,6 +247,9 @@ private:
bool hasWindowSystem() const;
QPointer<PushRuleModel> m_pushRuleModel;
Quotient::AccountRegistry m_accountRegistry;
private Q_SLOTS:
void invokeLogin();
void showWindow();

View File

@@ -151,3 +151,5 @@ qreal DelegateSizeHelper::currentWidth() const
return std::ceil(std::min(absoluteWidth, m_maxWidth));
}
}
#include "moc_delegatesizehelper.cpp"

View File

@@ -77,7 +77,7 @@ class DelegateSizeHelper : public QObject
Q_PROPERTY(qreal currentWidth READ currentWidth NOTIFY currentWidthChanged)
public:
DelegateSizeHelper(QObject *parent = nullptr);
explicit DelegateSizeHelper(QObject *parent = nullptr);
qreal parentWidth() const;
void setParentWidth(qreal parentWidth);

View File

@@ -11,11 +11,7 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
if (json.contains(QStringLiteral("pack"))) {
pack = ImagePackEventContent::Pack{
fromJson<Omittable<QString>>(json["pack"].toObject()["display_name"]),
#ifdef QUOTIENT_07
fromJson<Omittable<QUrl>>(json["pack"].toObject()["avatar_url"]),
#else
QUrl(),
#endif
fromJson<Omittable<QStringList>>(json["pack"].toObject()["usage"]),
fromJson<Omittable<QString>>(json["pack"].toObject()["attribution"]),
};
@@ -27,21 +23,13 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
for (const auto &k : keys) {
Omittable<EventContent::ImageInfo> info;
if (json["images"][k].toObject().contains(QStringLiteral("info"))) {
#ifdef QUOTIENT_07
info = EventContent::ImageInfo(QUrl(json["images"][k]["url"].toString()), json["images"][k]["info"].toObject(), k);
#else
info = EventContent::ImageInfo(QUrl(json["images"][k]["url"].toString()), json["images"][k].toObject(), k);
#endif
} else {
info = none;
}
images += ImagePackImage{
k,
#ifdef QUOTIENT_07
fromJson<QUrl>(json["images"][k]["url"].toString()),
#else
QUrl(),
#endif
fromJson<Omittable<QString>>(json["images"][k]["body"]),
info,
fromJson<Omittable<QStringList>>(json["images"][k]["usage"]),

View File

@@ -4,8 +4,8 @@
#pragma once
#include <QVector>
#include <events/eventcontent.h>
#include <events/stateevent.h>
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/stateevent.h>
namespace Quotient
{
@@ -83,23 +83,11 @@ public:
*
* @sa Quotient::StateEvent, ImagePackEventContent
*/
#ifdef QUOTIENT_07
class ImagePackEvent : public KeyedStateEventBase<ImagePackEvent, ImagePackEventContent>
#else
class ImagePackEvent : public StateEvent<ImagePackEventContent>
#endif
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
using KeyedStateEventBase::KeyedStateEventBase;
#else
DEFINE_EVENT_TYPEID("im.ponies.room_emotes", ImagePackEvent)
explicit ImagePackEvent(const QJsonObject &obj)
: StateEvent(typeId(), obj)
{
}
#endif
};
REGISTER_EVENT_TYPE(ImagePackEvent)

View File

@@ -3,7 +3,7 @@
#pragma once
#include <events/stateevent.h>
#include <Quotient/events/stateevent.h>
namespace Quotient
{
@@ -14,25 +14,13 @@ namespace Quotient
*
* @sa Quotient::StateEvent
*/
#ifdef QUOTIENT_07
class JoinRulesEvent : public StateEvent
#else
class JoinRulesEvent : public StateEventBase
#endif
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(JoinRulesEvent, "m.room.join_rules")
#else
DEFINE_EVENT_TYPEID("m.room.join_rules", JoinRulesEvent)
#endif
explicit JoinRulesEvent(const QJsonObject &obj)
#ifdef QUOTIENT_07
: StateEvent(obj)
#else
: StateEventBase(typeId(), obj)
#endif
{
}

View File

@@ -3,8 +3,7 @@
#pragma once
#include <events/eventcontent.h>
#include <events/roomevent.h>
#include <Quotient/events/roomevent.h>
namespace Quotient
{

View File

@@ -1,35 +0,0 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "stickerevent.h"
using namespace Quotient;
StickerEvent::StickerEvent(const QJsonObject &obj)
#ifdef QUOTIENT_07
: RoomEvent(obj)
#else
: RoomEvent(typeId(), obj)
#endif
, m_imageContent(EventContent::ImageContent(obj["content"_ls].toObject()))
{
}
QString StickerEvent::body() const
{
return content<QString>("body"_ls);
}
const EventContent::ImageContent &StickerEvent::image() const
{
return m_imageContent;
}
QUrl StickerEvent::url() const
{
#ifdef QUOTIENT_07
return m_imageContent.url();
#else
return m_imageContent.url;
#endif
}

View File

@@ -1,55 +0,0 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include <events/eventcontent.h>
#include <events/roomevent.h>
namespace Quotient
{
/**
* @class StickerEvent
*
* Class to define a sticker event.
*
* Sticker messages are specialised image messages that are displayed without
* controls (e.g. no "download" link, or light-box view on click, as would be
* displayed for for m.image events).
*
* @sa Quotient::RoomEvent
*/
class StickerEvent : public RoomEvent
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(StickerEvent, "m.sticker")
#else
DEFINE_EVENT_TYPEID("m.sticker", StickerEvent)
#endif
explicit StickerEvent(const QJsonObject &obj);
/**
* @brief A textual representation or associated description of the sticker image.
*
* This could be the alt text of the original image, or a message to accompany
* and further describe the sticker.
*/
QString body() const;
/**
* @brief Metadata about the image referred to in url including a thumbnail representation.
*/
const EventContent::ImageContent &image() const;
/**
* @brief The URL to the sticker image. This must be a valid mxc:// URI.
*/
QUrl url() const;
private:
EventContent::ImageContent m_imageContent;
};
REGISTER_EVENT_TYPE(StickerEvent)
}

View File

@@ -14,7 +14,7 @@ FileTransferPseudoJob::FileTransferPseudoJob(Operation operation, const QString
{
}
void FileTransferPseudoJob::fileTransferProgress(QString id, qint64 progress, qint64 total)
void FileTransferPseudoJob::fileTransferProgress(const QString &id, qint64 progress, qint64 total)
{
if (id != m_eventId) {
return;
@@ -23,7 +23,7 @@ void FileTransferPseudoJob::fileTransferProgress(QString id, qint64 progress, qi
setTotalAmount(Unit::Bytes, total);
}
void FileTransferPseudoJob::fileTransferCompleted(QString id, QUrl localFile)
void FileTransferPseudoJob::fileTransferCompleted(const QString &id, const QUrl &localFile)
{
Q_UNUSED(localFile);
if (id != m_eventId) {
@@ -32,7 +32,7 @@ void FileTransferPseudoJob::fileTransferCompleted(QString id, QUrl localFile)
emitResult();
}
void FileTransferPseudoJob::fileTransferFailed(QString id, QString errorMessage)
void FileTransferPseudoJob::fileTransferFailed(const QString &id, const QString &errorMessage)
{
if (id != m_eventId) {
return;

View File

@@ -20,23 +20,23 @@ public:
Download,
Upload,
};
Q_ENUM(Operation);
Q_ENUM(Operation)
FileTransferPseudoJob(Operation operation, const QString &srcDest, const QString &path);
/**
* @brief Set the current number of bytes transferred.
*/
void fileTransferProgress(QString id, qint64 progress, qint64 total);
void fileTransferProgress(const QString &id, qint64 progress, qint64 total);
/**
* @brief Set the file transfer as complete.
*/
void fileTransferCompleted(QString id, QUrl localFile);
void fileTransferCompleted(const QString &id, const QUrl &localFile);
/**
* @brief Set the file transfer as failed.
*/
void fileTransferFailed(QString id, QString errorMessage = {});
void fileTransferFailed(const QString &id, const QString &errorMessage = {});
/**
* @brief Start the file transfer.

View File

@@ -112,3 +112,5 @@ QStringList FileTypeSingleton::supportedAnimatedImageFormats() const
Q_D(const FileTypeSingleton);
return d->supportedAnimatedImageFormats;
}
#include "moc_filetypesingleton.cpp"

View File

@@ -5,6 +5,7 @@
#pragma once
#include <QFileInfo>
#include <QMimeDatabase>
#include <QObject>
#include <qqml.h>

View File

@@ -3,14 +3,16 @@
#include "linkpreviewer.h"
#include <connection.h>
#include <csapi/content-repo.h>
#include "controller.h"
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include "neochatroom.h"
using namespace Quotient;
LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, QUrl url)
LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, const QUrl &url)
: QObject(parent)
, m_currentRoom(room)
, m_loaded(false)
@@ -69,14 +71,7 @@ void LinkPreviewer::loadUrlPreview()
auto imageUrl = QUrl(json["og:image"].toString());
if (imageUrl.isValid() && imageUrl.scheme() == QStringLiteral("mxc")) {
#ifdef QUOTIENT_07
m_imageSource = conn->makeMediaUrl(imageUrl);
#else
QUrlQuery q(imageUrl.query());
q.addQueryItem(QStringLiteral("user_id"), conn->userId());
imageUrl.setQuery(q);
m_imageSource = imageUrl;
#endif
} else {
m_imageSource = QUrl();
}
@@ -89,3 +84,5 @@ void LinkPreviewer::loadUrlPreview()
});
}
}
#include "moc_linkpreviewer.cpp"

View File

@@ -45,7 +45,7 @@ class LinkPreviewer : public QObject
Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
public:
explicit LinkPreviewer(QObject *parent = nullptr, NeoChatRoom *room = nullptr, QUrl url = {});
explicit LinkPreviewer(QObject *parent = nullptr, NeoChatRoom *room = nullptr, const QUrl &url = {});
[[nodiscard]] QUrl url() const;
void setUrl(QUrl);

View File

@@ -42,3 +42,5 @@ float LocationHelper::zoomToFit(const QRectF &r, float mapWidth, float mapHeight
return std::clamp(z, 5.0, 18.0);
}
#include "moc_locationhelper.cpp"

View File

@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include "linkpreviewer.h"
#include <QMetaType>

View File

@@ -3,14 +3,9 @@
#include "login.h"
#ifdef QUOTIENT_07
#include <accountregistry.h>
#else
#include "neochataccountregistry.h"
#endif
#include <connection.h>
#include <qt_connection_util.h>
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/qt_connection_util.h>
#include "controller.h"
@@ -47,11 +42,7 @@ void Login::init()
return;
}
#ifdef QUOTIENT_07
m_isLoggedIn = Accounts.isLoggedIn(m_matrixId);
#else
m_isLoggedIn = AccountRegistry::instance().isLoggedIn(m_matrixId);
#endif
m_isLoggedIn = Controller::instance().accounts().isLoggedIn(m_matrixId);
Q_EMIT isLoggedInChanged();
if (m_isLoggedIn) {
return;
@@ -105,7 +96,7 @@ void Login::init()
Q_EMIT Controller::instance().globalErrorOccured(i18n("Network Error"), std::move(error));
});
connectSingleShot(m_connection, &Connection::syncDone, this, [this]() {
connectSingleShot(m_connection, &Connection::syncDone, this, []() {
Q_EMIT Controller::instance().initiated();
});
}
@@ -207,3 +198,5 @@ bool Login::isLoggedIn() const
{
return m_isLoggedIn;
}
#include "moc_login.cpp"

View File

@@ -112,7 +112,7 @@ Q_SIGNALS:
void loginFlowsChanged();
void ssoUrlChanged();
void connected();
void errorOccured(QString message);
void errorOccured(const QString &message);
void testingChanged();
void isLoggingInChanged();
void isLoggedInChanged();

View File

@@ -28,15 +28,11 @@
#include "neochat-version.h"
#ifdef QUOTIENT_07
#include <accountregistry.h>
#else
#include "neochataccountregistry.h"
#endif
#include <networkaccessmanager.h>
#include <room.h>
#include <util.h>
#include <Quotient/keyverificationsession.h>
#include <Quotient/accountregistry.h>
#include <Quotient/networkaccessmanager.h>
#include <Quotient/room.h>
#include <Quotient/util.h>
#include "actionshandler.h"
#include "blurhashimageprovider.h"
@@ -54,21 +50,25 @@
#include "models/collapsestateproxymodel.h"
#include "models/customemojimodel.h"
#include "models/devicesmodel.h"
#include "models/devicesproxymodel.h"
#include "models/emojimodel.h"
#include "models/emoticonfiltermodel.h"
#include "models/imagepacksmodel.h"
#include "models/keywordnotificationrulemodel.h"
#include "models/livelocationsmodel.h"
#include "models/locationsmodel.h"
#include "models/mediamessagefiltermodel.h"
#include "models/messageeventmodel.h"
#include "models/messagefiltermodel.h"
#include "models/publicroomlistmodel.h"
#include "models/pushrulemodel.h"
#include "models/reactionmodel.h"
#include "models/roomlistmodel.h"
#include "models/searchmodel.h"
#include "models/serverlistmodel.h"
#include "models/sortfilterroomlistmodel.h"
#include "models/sortfilterspacelistmodel.h"
#include "models/statefiltermodel.h"
#include "models/stickermodel.h"
#include "models/userdirectorylistmodel.h"
#include "models/userfiltermodel.h"
#include "models/userlistmodel.h"
@@ -77,18 +77,12 @@
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
#ifdef QUOTIENT_07
#include "pollhandler.h"
#endif
#include "models/statefiltermodel.h"
#include "models/stickermodel.h"
#include "roommanager.h"
#include "spacehierarchycache.h"
#include "urlhelper.h"
#include "windowcontroller.h"
#ifdef QUOTIENT_07
#include <keyverificationsession.h>
#endif
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
@@ -128,7 +122,9 @@ Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QNetworkProxyFactory::setUseSystemConfiguration(true);
@@ -176,14 +172,10 @@ int main(int argc, char *argv[])
about.addComponent(QStringLiteral("libQuotient"),
i18n("A Qt5 library to write cross-platform clients for Matrix"),
#ifdef QUOTIENT_07
i18nc("<version number> (built against <possibly different version number>)",
"%1 (built against %2)",
Quotient::versionString(),
QStringLiteral(Quotient_VERSION_STRING)),
#else
QStringLiteral(QUOTIENT_VERSION),
#endif
QStringLiteral("https://github.com/quotient-im/libquotient"),
KAboutLicense::LGPL_V2_1);
@@ -192,6 +184,12 @@ int main(int argc, char *argv[])
initLogging();
#if Quotient_VERSION_MINOR == 8
#ifdef Quotient_E2EE_ENABLED
Connection::setEncryptionDefault(true);
#endif
#endif
#ifdef NEOCHAT_FLATPAK
// Copy over the included FontConfig configuration to the
// app's config dir:
@@ -222,11 +220,7 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", &EmojiModel::instance());
#ifdef QUOTIENT_07
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
#else
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::AccountRegistry::instance());
#endif
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Controller::instance().accounts());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "SpaceHierarchyCache", &SpaceHierarchyCache::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CustomEmojiModel", &CustomEmojiModel::instance());
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
@@ -237,6 +231,7 @@ int main(int argc, char *argv[])
qmlRegisterType<MessageEventModel>("org.kde.neochat", 1, 0, "MessageEventModel");
qmlRegisterType<ReactionModel>("org.kde.neochat", 1, 0, "ReactionModel");
qmlRegisterType<CollapseStateProxyModel>("org.kde.neochat", 1, 0, "CollapseStateProxyModel");
qmlRegisterType<MediaMessageFilterModel>("org.kde.neochat", 1, 0, "MediaMessageFilterModel");
qmlRegisterType<MessageFilterModel>("org.kde.neochat", 1, 0, "MessageFilterModel");
qmlRegisterType<UserFilterModel>("org.kde.neochat", 1, 0, "UserFilterModel");
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
@@ -245,6 +240,7 @@ int main(int argc, char *argv[])
qmlRegisterType<SortFilterRoomListModel>("org.kde.neochat", 1, 0, "SortFilterRoomListModel");
qmlRegisterType<SortFilterSpaceListModel>("org.kde.neochat", 1, 0, "SortFilterSpaceListModel");
qmlRegisterType<DevicesModel>("org.kde.neochat", 1, 0, "DevicesModel");
qmlRegisterType<DevicesProxyModel>("org.kde.neochat", 1, 0, "DevicesProxyModel");
qmlRegisterType<LinkPreviewer>("org.kde.neochat", 1, 0, "LinkPreviewer");
qmlRegisterType<CompletionModel>("org.kde.neochat", 1, 0, "CompletionModel");
qmlRegisterType<StateModel>("org.kde.neochat", 1, 0, "StateModel");
@@ -252,16 +248,16 @@ int main(int argc, char *argv[])
qmlRegisterType<SearchModel>("org.kde.neochat", 1, 0, "SearchModel");
qmlRegisterType<LiveLocationsModel>("org.kde.neochat", 1, 0, "LiveLocationsModel");
qmlRegisterType<LocationsModel>("org.kde.neochat", 1, 0, "LocationsModel");
#ifdef QUOTIENT_07
qmlRegisterType<PollHandler>("org.kde.neochat", 1, 0, "PollHandler");
#endif
qmlRegisterType<KeywordNotificationRuleModel>("org.kde.neochat", 1, 0, "KeywordNotificationRuleModel");
qmlRegisterType<PushRuleModel>("org.kde.neochat", 1, 0, "PushRuleModel");
qmlRegisterType<StickerModel>("org.kde.neochat", 1, 0, "StickerModel");
qmlRegisterType<ImagePacksModel>("org.kde.neochat", 1, 0, "ImagePacksModel");
qmlRegisterType<AccountEmoticonModel>("org.kde.neochat", 1, 0, "AccountEmoticonModel");
qmlRegisterType<EmoticonFilterModel>("org.kde.neochat", 1, 0, "EmoticonFilterModel");
qmlRegisterType<DelegateSizeHelper>("org.kde.neochat", 1, 0, "DelegateSizeHelper");
qmlRegisterUncreatableType<RoomMessageEvent>("org.kde.neochat", 1, 0, "RoomMessageEvent", "ENUM");
qmlRegisterUncreatableType<PushNotificationKind>("org.kde.neochat", 1, 0, "PushNotificationKind", "ENUM");
qmlRegisterUncreatableType<PushNotificationSection>("org.kde.neochat", 1, 0, "PushNotificationSection", "ENUM");
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM");
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM");
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
@@ -278,12 +274,10 @@ int main(int argc, char *argv[])
qRegisterMetaType<NeoChatUser *>("NeoChatUser*");
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType");
#ifdef QUOTIENT_07
#ifdef Quotient_E2EE_ENABLED
qRegisterMetaType<KeyVerificationSession *>("KeyVerificationSession*");
qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
qRegisterMetaType<QVector<EmojiEntry>>("QVector<EmojiEntry>");
#endif
#endif
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(KAboutData::applicationData());

View File

@@ -13,7 +13,7 @@
#include <KLocalizedString>
#include "controller.h"
#include <connection.h>
#include <Quotient/connection.h>
using namespace Quotient;
@@ -32,11 +32,17 @@ ThumbnailResponse::ThumbnailResponse(QString id, QSize size)
requestedSize.setWidth(100);
}
if (mediaId.count('/') != 1) {
errorStr = i18n("Media id '%1' doesn't follow server/mediaId pattern", mediaId);
Q_EMIT finished();
return;
if (mediaId.startsWith(QLatin1Char('/'))) {
mediaId = mediaId.mid(1);
} else {
errorStr = i18n("Media id '%1' doesn't follow server/mediaId pattern", mediaId);
Q_EMIT finished();
return;
}
}
mediaId = mediaId.split(QLatin1Char('?'))[0];
QImage cachedImage;
if (cachedImage.load(localFile)) {
image = cachedImage;
@@ -114,3 +120,5 @@ QQuickImageResponse *MatrixImageProvider::requestImageResponse(const QString &id
{
return new ThumbnailResponse(id, requestedSize);
}
#include "moc_matriximageprovider.cpp"

View File

@@ -6,7 +6,7 @@
#include <QQuickAsyncImageProvider>
#include <jobs/mediathumbnailjob.h>
#include <Quotient/jobs/mediathumbnailjob.h>
#include <QReadWriteLock>
@@ -26,7 +26,7 @@ class ThumbnailResponse : public QQuickImageResponse
{
Q_OBJECT
public:
ThumbnailResponse(QString mediaId, QSize requestedSize);
explicit ThumbnailResponse(QString mediaId, QSize requestedSize);
~ThumbnailResponse() override = default;
private Q_SLOTS:
@@ -34,7 +34,7 @@ private Q_SLOTS:
void prepareResult();
private:
const QString mediaId;
QString mediaId;
QSize requestedSize;
const QString localFile;
Quotient::MediaThumbnailJob *job = nullptr;

View File

@@ -3,7 +3,7 @@
#include "accountemoticonmodel.h"
#include <csapi/content-repo.h>
#include <Quotient/csapi/content-repo.h>
#include <qcoro/qcorosignal.h>
using namespace Quotient;
@@ -27,11 +27,7 @@ QVariant AccountEmoticonModel::data(const QModelIndex &index, int role) const
const auto &row = index.row();
const auto &image = m_images->images[row];
if (role == UrlRole) {
#ifdef QUOTIENT_07
return m_connection->makeMediaUrl(image.url);
#else
return QUrl();
#endif
}
if (role == BodyRole) {
if (image.body) {
@@ -142,11 +138,7 @@ QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl sourc
if (job->error() != BaseJob::NoError) {
co_return;
}
#ifdef QUOTIENT_07
m_images->images[index].url = job->contentUri().toString();
#else
m_images->images[index].url = job->contentUri();
#endif
m_images->images[index].info = none;
QJsonObject data;
m_images->fillJson(&data);
@@ -176,3 +168,5 @@ void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortc
{
doAddEmoticon(source, shortcode, description, type);
}
#include "moc_accountemoticonmodel.cpp"

View File

@@ -4,12 +4,14 @@
#pragma once
#include "events/imagepackevent.h"
#include <QAbstractListModel>
#include <QCoroTask>
#include <QObject>
#include <QPointer>
#include <QVector>
#include <connection.h>
#include <Quotient/connection.h>
class ImagePacksModel;

View File

@@ -6,8 +6,8 @@
#include "controller.h"
#include "neochatroom.h"
#include "roommanager.h"
#include <events/roommemberevent.h>
#include <events/roompowerlevelsevent.h>
#include <Quotient/events/roommemberevent.h>
#include <Quotient/events/roompowerlevelsevent.h>
#include <KLocalizedString>
@@ -191,7 +191,6 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
#ifdef QUOTIENT_07
const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text);
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already invited to this room.", "%1 is already invited to this room.", text));
@@ -201,7 +200,6 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString();
}
#endif
if (room->localUser()->id() == text) {
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room."));
return QString();
@@ -243,7 +241,6 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id>"),
kli18n("Joins the given room"),
},
#ifdef QUOTIENT_07
Action{
QStringLiteral("knock"),
[](const QString &text, NeoChatRoom *room) {
@@ -276,7 +273,6 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id> [<reason>]"),
kli18n("Requests to join the given room"),
},
#endif
Action{
QStringLiteral("j"),
[](const QString &text, NeoChatRoom *room) {
@@ -435,14 +431,15 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(parts[0]);
if (state && state->membership() == Membership::Ban) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text));
return QString();
}
#endif
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
return QString();
@@ -472,18 +469,19 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
return QString();
}
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(text);
if (state && state->membership() != Membership::Ban) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is not banned from this room.", "%1 is not banned from this room.", text));
return QString();
}
#endif
room->unban(text);
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18nc("<username> was unbanned from this room.", "%1 was unbanned from this room.", text));
@@ -510,13 +508,14 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You cannot kick yourself from the room."));
return QString();
}
#ifdef QUOTIENT_07
if (!room->isMember(parts[0])) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0]));
return QString();
}
#endif
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
auto kick = plEvent->kick();
if (plEvent->powerLevelForUser(room->localUser()->id()) < kick) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to kick users from this room."));

View File

@@ -5,7 +5,7 @@
#include <KLazyLocalizedString>
#include <QAbstractListModel>
#include <events/roommessageevent.h>
#include <Quotient/events/roommessageevent.h>
class NeoChatRoom;
@@ -61,7 +61,7 @@ public:
CompletionType, /**< The completion type (always "action" for this model). */
Parameters, /**< The input parameters expected by the action. */
};
Q_ENUM(Roles);
Q_ENUM(Roles)
/**
* @brief Get the given role value at the given index.

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "collapsestateproxymodel.h"
#include "messageeventmodel.h"
#include <KLocalizedString>
@@ -82,7 +81,7 @@ QString CollapseStateProxyModel::aggregateEventToString(int sourceRow) const
: QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a> ")
.arg(uniqueAuthors[0].toMap()["id"].toString(),
uniqueAuthors[0].toMap()["color"].toString(),
uniqueAuthors[0].toMap()["displayName"].toString());
uniqueAuthors[0].toMap()["displayName"].toString().toHtmlEscaped());
text += userText;
text += chunks.takeFirst();
@@ -174,3 +173,5 @@ QString CollapseStateProxyModel::excessAuthors(int row) const
return QStringLiteral("+ %1").arg(excessAuthors);
}
}
#include "moc_collapsestateproxymodel.cpp"

View File

@@ -27,6 +27,7 @@ public:
StateEventsRole, /**< List of state events in the aggregated state. */
AuthorListRole, /**< List of the first 5 unique authors of the aggregated state event. */
ExcessAuthorsRole, /**< The number of unique authors beyond the first 5. */
LastRole, // Keep this last
};
/**

View File

@@ -53,54 +53,54 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
}
auto filterIndex = m_filterModel->index(index.row(), 0);
if (m_autoCompletionType == User) {
if (role == Text) {
if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
}
if (role == Subtitle) {
if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
}
if (role == Icon) {
if (role == IconNameRole) {
return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
}
}
if (m_autoCompletionType == Command) {
if (role == Text) {
if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ")
+ m_filterModel->data(filterIndex, ActionsModel::Parameters).toString();
}
if (role == Subtitle) {
if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, ActionsModel::Description);
}
if (role == Icon) {
if (role == IconNameRole) {
return QStringLiteral("invalid");
}
if (role == ReplacedText) {
if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix);
}
}
if (m_autoCompletionType == Room) {
if (role == Text) {
if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
}
if (role == Subtitle) {
if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
}
if (role == Icon) {
if (role == IconNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole);
}
}
if (m_autoCompletionType == Emoji) {
if (role == Text) {
if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
}
if (role == Icon) {
if (role == IconNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
}
if (role == ReplacedText) {
if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
}
if (role == Subtitle) {
if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
}
}
@@ -111,10 +111,10 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> CompletionModel::roleNames() const
{
return {
{Text, "text"},
{Subtitle, "subtitle"},
{Icon, "icon"},
{ReplacedText, "replacedText"},
{DisplayNameRole, "displayName"},
{SubtitleRole, "subtitle"},
{IconNameRole, "iconName"},
{ReplacedTextRole, "replacedText"},
};
}
@@ -193,3 +193,5 @@ void CompletionModel::setRoomListModel(RoomListModel *roomListModel)
m_roomListModel = roomListModel;
Q_EMIT roomListModelChanged();
}
#include "moc_completionmodel.cpp"

View File

@@ -64,14 +64,14 @@ public:
* @brief Defines the model roles.
*/
enum Roles {
Text = Qt::DisplayRole, /**< The main text to show. */
Subtitle, /**< The subtitle text to show. */
Icon, /**< The icon to show. */
ReplacedText, /**< The text to replace the input text with for the completion. */
DisplayNameRole = Qt::DisplayRole, /**< The main text to show. */
SubtitleRole, /**< The subtitle text to show. */
IconNameRole, /**< The icon to show. */
ReplacedTextRole, /**< The text to replace the input text with for the completion. */
};
Q_ENUM(Roles);
Q_ENUM(Roles)
CompletionModel(QObject *parent = nullptr);
explicit CompletionModel(QObject *parent = nullptr);
/**
* @brief Get the given role value at the given index.

View File

@@ -59,3 +59,5 @@ void CompletionProxyModel::setFullText(const QString &fullText)
{
m_fullText = fullText;
}
#include "moc_completionproxymodel.cpp"

View File

@@ -9,10 +9,9 @@
#include "controller.h"
#include "emojimodel.h"
#include <connection.h>
#include <csapi/account-data.h>
#include <csapi/content-repo.h>
#include <events/eventcontent.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/account-data.h>
#include <Quotient/csapi/content-repo.h>
using namespace Quotient;
@@ -62,11 +61,7 @@ void CustomEmojiModel::addEmoji(const QString &name, const QUrl &location)
auto emojiData = json["images"].toObject();
QString url;
#ifdef QUOTIENT_07
url = job->contentUri().toString();
#else
url = job->contentUri();
#endif
QImage image(location.toLocalFile());
QJsonObject imageInfo;
@@ -208,3 +203,5 @@ QVariantList CustomEmojiModel::filterModel(const QString &filter)
}
return results;
}
#include "moc_customemojimodel.cpp"

View File

@@ -41,7 +41,7 @@ public:
ReplacedTextRole = 52, /**< The name of the emoji. For compatibility with EmojiModel. */
DescriptionRole = 53, /**< Invalid, reserved. For compatibility with EmojiModel. */
};
Q_ENUM(Roles);
Q_ENUM(Roles)
static CustomEmojiModel &instance()
{

View File

@@ -3,23 +3,22 @@
#include "devicesmodel.h"
#include <csapi/device_management.h>
#include "controller.h"
#include <connection.h>
#include <user.h>
#include <QDateTime>
#include <QLocale>
#include <KLocalizedString>
#include <Quotient/csapi/device_management.h>
#include <Quotient/connection.h>
#include <Quotient/user.h>
using namespace Quotient;
DevicesModel::DevicesModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, [this]() {
DevicesModel::fetchDevices();
Q_EMIT connectionChanged();
});
fetchDevices();
}
void DevicesModel::fetchDevices()
@@ -30,6 +29,7 @@ void DevicesModel::fetchDevices()
beginResetModel();
m_devices = job->devices();
endResetModel();
Q_EMIT countChanged();
});
}
}
@@ -40,16 +40,43 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
return {};
}
const auto &device = m_devices[index.row()];
switch (role) {
case Id:
return m_devices[index.row()].deviceId;
return device.deviceId;
case DisplayName:
return m_devices[index.row()].displayName;
return device.displayName;
case LastIp:
return m_devices[index.row()].lastSeenIp;
return device.lastSeenIp;
case LastTimestamp:
if (m_devices[index.row()].lastSeenTs)
return *m_devices[index.row()].lastSeenTs;
if (device.lastSeenTs) {
return *device.lastSeenTs;
} else {
return false;
}
case TimestampString:
if (device.lastSeenTs) {
return QDateTime::fromMSecsSinceEpoch(*device.lastSeenTs).toString(QLocale().dateTimeFormat(QLocale::ShortFormat));
} else {
return false;
}
case Type:
if (device.deviceId == m_connection->deviceId()) {
return This;
}
#ifdef Quotient_E2EE_ENABLED
if (!m_connection->isKnownE2eeCapableDevice(m_connection->userId(), device.deviceId)) {
return Unencrypted;
}
if (m_connection->isVerifiedDevice(m_connection->userId(), device.deviceId)) {
return Verified;
} else {
return Unverified;
}
#else
return Unverified;
#endif
}
return {};
}
@@ -62,11 +89,22 @@ int DevicesModel::rowCount(const QModelIndex &parent) const
QHash<int, QByteArray> DevicesModel::roleNames() const
{
return {{Id, "id"}, {DisplayName, "displayName"}, {LastIp, "lastIp"}, {LastTimestamp, "lastTimestamp"}};
return {
{Id, "id"},
{DisplayName, "displayName"},
{LastIp, "lastIp"},
{LastTimestamp, "lastTimestamp"},
{TimestampString, "timestamp"},
{Type, "type"},
};
}
void DevicesModel::logout(int index, const QString &password)
void DevicesModel::logout(const QString &deviceId, const QString &password)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++)
;
auto job = Controller::instance().activeConnection()->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId);
connect(job, &BaseJob::result, this, [this, job, password, index] {
@@ -74,6 +112,7 @@ void DevicesModel::logout(int index, const QString &password)
beginRemoveRows(QModelIndex(), index, index);
m_devices.remove(index);
endRemoveRows();
Q_EMIT countChanged();
};
if (job->error() != BaseJob::Success) {
QJsonObject replyData = job->jsonData();
@@ -91,8 +130,11 @@ void DevicesModel::logout(int index, const QString &password)
});
}
void DevicesModel::setName(int index, const QString &name)
void DevicesModel::setName(const QString &deviceId, const QString &name)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++);
auto job = Controller::instance().activeConnection()->callApi<UpdateDeviceJob>(m_devices[index].deviceId, name);
QString oldName = m_devices[index].displayName;
beginResetModel();
@@ -107,5 +149,29 @@ void DevicesModel::setName(int index, const QString &name)
Connection *DevicesModel::connection() const
{
return Controller::instance().activeConnection();
return m_connection;
}
void DevicesModel::setConnection(Connection *connection)
{
if (m_connection) {
disconnect(m_connection, nullptr, this, nullptr);
}
m_connection = connection;
Q_EMIT connectionChanged();
fetchDevices();
#ifdef Quotient_E2EE_ENABLED
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &userId, const QString &deviceId) {
Q_UNUSED(deviceId);
if (userId == Controller::instance().activeConnection()->userId()) {
fetchDevices();
}
});
connect(m_connection, &Connection::finishedQueryingKeys, this, [this]() {
fetchDevices();
});
#endif
}
#include "moc_devicesmodel.cpp"

View File

@@ -4,8 +4,9 @@
#pragma once
#include <QAbstractListModel>
#include <QPointer>
#include <csapi/definitions/client_device.h>
#include <Quotient/csapi/definitions/client_device.h>
namespace Quotient
{
@@ -28,7 +29,7 @@ class DevicesModel : public QAbstractListModel
/**
* @brief The current connection that the model is getting its devices from.
*/
Q_PROPERTY(Quotient::Connection *connection READ connection NOTIFY connectionChanged)
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
public:
/**
@@ -39,10 +40,18 @@ public:
DisplayName, /**< Display name set by the user for this device. */
LastIp, /**< The IP address where this device was last seen. */
LastTimestamp, /**< The timestamp when this devices was last seen. */
TimestampString, /**< String for the timestamp when this devices was last seen. */
Type, /**< The category to sort this device into. */
};
Q_ENUM(Roles);
Q_ENUM(Roles)
DevicesModel(QObject *parent = nullptr);
enum DeviceType {
This,
Verified,
Unverified,
Unencrypted,
};
Q_ENUM(DeviceType);
/**
* @brief Get the given role value at the given index.
@@ -66,21 +75,27 @@ public:
QHash<int, QByteArray> roleNames() const override;
/**
* @brief Logout the device at the given index.
* @brief Logout the device with the given id.
*/
Q_INVOKABLE void logout(int index, const QString &password);
Q_INVOKABLE void logout(const QString &deviceId, const QString &password);
/**
* @brief Set the display name of the device at the given index.
* @brief Set the display name of the device with the given id.
*/
Q_INVOKABLE void setName(int index, const QString &name);
Q_INVOKABLE void setName(const QString &deviceId, const QString &name);
Quotient::Connection *connection() const;
explicit DevicesModel(QObject *parent = nullptr);
[[nodiscard]] Quotient::Connection *connection() const;
void setConnection(Quotient::Connection *connection);
Q_SIGNALS:
void connectionChanged();
void countChanged();
private:
void fetchDevices();
QVector<Quotient::Device> m_devices;
QPointer<Quotient::Connection> m_connection;
};

View File

@@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "devicesproxymodel.h"
#include "devicesmodel.h"
int DevicesProxyModel::type() const
{
return m_type;
}
void DevicesProxyModel::setType(int type)
{
m_type = type;
Q_EMIT typeChanged();
}
bool DevicesProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
return sourceModel()->data(sourceModel()->index(source_row, 0), DevicesModel::Type).toInt() == m_type;
}
DevicesProxyModel::DevicesProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
, m_type(0)
{
setSortRole(DevicesModel::LastTimestamp);
sort(0, Qt::DescendingOrder);
}
#include "moc_devicesproxymodel.cpp"

View File

@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QSortFilterProxyModel>
class DevicesProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(int type READ type WRITE setType NOTIFY typeChanged);
public:
DevicesProxyModel(QObject *parent = nullptr);
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
void setType(int type);
[[nodiscard]] int type() const;
Q_SIGNALS:
void typeChanged();
private:
int m_type;
};

View File

@@ -216,3 +216,5 @@ QVariantList EmojiModel::categoriesWithCustom() const
;
return cats;
}
#include "moc_emojimodel.cpp"

View File

@@ -95,7 +95,7 @@ public:
ReplacedTextRole = 52, /**< The text to replace the short name with (i.e. the unicode character). */
DescriptionRole = 53, /**< The long description of an emoji. */
};
Q_ENUM(RoleNames);
Q_ENUM(RoleNames)
/**
* @brief Defines the potential categories an emoji can be placed in.

View File

@@ -53,3 +53,5 @@ void EmoticonFilterModel::setShowEmojis(bool showEmojis)
endResetModel();
Q_EMIT showEmojisChanged();
}
#include "moc_emoticonfiltermodel.cpp"

View File

@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QSortFilterProxyModel>
/**

View File

@@ -33,13 +33,9 @@ QVariant ImagePacksModel::data(const QModelIndex &index, int role) const
}
if (role == AvatarUrlRole) {
if (event.pack->avatarUrl) {
#ifdef QUOTIENT_07
return m_room->connection()->makeMediaUrl(*event.pack->avatarUrl);
#endif
} else if (!event.images.empty()) {
#ifdef QUOTIENT_07
return m_room->connection()->makeMediaUrl(event.images[0].url);
#endif
}
}
return {};
@@ -106,7 +102,6 @@ void ImagePacksModel::reloadImages()
auto packs = rooms[roomId].toObject();
const auto &stickerRoom = m_room->connection()->room(roomId);
for (const auto &packKey : packs.keys()) {
#ifdef QUOTIENT_07
if (const auto &pack = stickerRoom->currentState().get<ImagePackEvent>(packKey)) {
const auto packContent = pack->content();
if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons())
@@ -115,11 +110,9 @@ void ImagePacksModel::reloadImages()
m_events += packContent;
}
}
#endif
}
}
}
#ifdef QUOTIENT_07
// Load emoticons from the current room
auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes");
@@ -132,7 +125,6 @@ void ImagePacksModel::reloadImages()
}
}
}
#endif
Q_EMIT imagesLoaded();
endResetModel();
}
@@ -165,3 +157,5 @@ QVector<Quotient::ImagePackEventContent::ImagePackImage> ImagePacksModel::images
}
return m_events[index].images;
}
#include "moc_imagepacksmodel.cpp"

View File

@@ -47,7 +47,7 @@ public:
AttributionRole, /**< The attribution for the pack author(s). */
IdRole, /**< The ID of the image pack. */
};
Q_ENUM(Roles);
Q_ENUM(Roles)
explicit ImagePacksModel(QObject *parent = nullptr);

View File

@@ -6,11 +6,11 @@
#include "notificationsmanager.h"
#include <QDebug>
#include <connection.h>
#include <converters.h>
#include <csapi/definitions/push_ruleset.h>
#include <csapi/pushrules.h>
#include <jobs/basejob.h>
#include <Quotient/connection.h>
#include <Quotient/converters.h>
#include <Quotient/csapi/definitions/push_ruleset.h>
#include <Quotient/csapi/pushrules.h>
#include <Quotient/jobs/basejob.h>
KeywordNotificationRuleModel::KeywordNotificationRuleModel(QObject *parent)
: QAbstractListModel(parent)
@@ -108,3 +108,5 @@ QHash<int, QByteArray> KeywordNotificationRuleModel::roleNames() const
{
return {{NameRole, QByteArrayLiteral("name")}};
}
#include "moc_keywordnotificationrulemodel.cpp"

View File

@@ -3,7 +3,7 @@
#pragma once
#include <csapi/definitions/push_rule.h>
#include <Quotient/csapi/definitions/push_rule.h>
#include <QAbstractListModel>

View File

@@ -169,3 +169,5 @@ void LiveLocationsModel::updateLocationData(LiveLocationData &&data)
Q_EMIT dataChanged(idx, idx);
}
#include "moc_livelocationsmodel.cpp"

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