Compare commits

...

95 Commits

Author SHA1 Message Date
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
218 changed files with 26711 additions and 30917 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,4 @@
build build*
.clang-format .clang-format
.DS_Store .DS_Store
.kdev4/ .kdev4/
@@ -11,3 +11,4 @@ kate.project.ctags.*
.flatpak-builder/ .flatpak-builder/
.idea/ .idea/
cmake-build-* 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/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.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/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/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.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/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/freebsd-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.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. # KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "23") set(RELEASE_SERVICE_VERSION_MAJOR "23")
set(RELEASE_SERVICE_VERSION_MINOR "07") set(RELEASE_SERVICE_VERSION_MINOR "07")
set(RELEASE_SERVICE_VERSION_MICRO "70") set(RELEASE_SERVICE_VERSION_MICRO "80")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION}) project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
@@ -17,7 +17,7 @@ project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
set(KF_MIN_VERSION "5.105.0") set(KF_MIN_VERSION "5.105.0")
set(QT_MIN_VERSION "5.15.2") set(QT_MIN_VERSION "5.15.2")
if (ANDROID) if (ANDROID)
set(QT_MIN_VERSION "5.15.8") set(QT_MIN_VERSION "5.15.10")
endif() endif()
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE) find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
@@ -48,6 +48,30 @@ if(NEOCHAT_FLATPAK)
include(cmake/Flatpak.cmake) include(cmake/Flatpak.cmake)
endif() 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} ecm_setup_version(${PROJECT_VERSION}
VARIABLE_PREFIX NEOCHAT VARIABLE_PREFIX NEOCHAT
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h 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") set(QUOTIENT_SUFFIX "Qt6")
endif() endif()
find_package(Quotient${QUOTIENT_SUFFIX} 0.6) find_package(Quotient${QUOTIENT_SUFFIX} 0.7)
set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES
TYPE REQUIRED TYPE REQUIRED
DESCRIPTION "Qt wrapper around Matrix API" 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 # Fixes the test by excluding this directory
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX [[_(install|build)/.*]]) list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX [[_(install|build)/.*]])
ecm_check_outbound_license(LICENSES GPL-3.0-only FILES ${ALL_SOURCE_FILES}) 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() compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion
sourceSets { sourceSets {
main { main {

View File

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

View File

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -18,6 +18,7 @@
<name xml:lang="de">NeoChat</name> <name xml:lang="de">NeoChat</name>
<name xml:lang="el">NeoChat</name> <name xml:lang="el">NeoChat</name>
<name xml:lang="en-GB">NeoChat</name> <name xml:lang="en-GB">NeoChat</name>
<name xml:lang="eo">NeoChat</name>
<name xml:lang="es">NeoChat</name> <name xml:lang="es">NeoChat</name>
<name xml:lang="eu">NeoChat</name> <name xml:lang="eu">NeoChat</name>
<name xml:lang="fi">NeoChat</name> <name xml:lang="fi">NeoChat</name>
@@ -39,7 +40,6 @@
<name xml:lang="ru">NeoChat</name> <name xml:lang="ru">NeoChat</name>
<name xml:lang="sk">NeoChat</name> <name xml:lang="sk">NeoChat</name>
<name xml:lang="sl">NeoChat</name> <name xml:lang="sl">NeoChat</name>
<name xml:lang="sv">NeoChat</name>
<name xml:lang="ta">நியோச்சாட்</name> <name xml:lang="ta">நியோச்சாட்</name>
<name xml:lang="tr">NeoChat</name> <name xml:lang="tr">NeoChat</name>
<name xml:lang="uk">NeoChat</name> <name xml:lang="uk">NeoChat</name>
@@ -54,6 +54,7 @@
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary> <summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary> <summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</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="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="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary> <summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
@@ -67,7 +68,7 @@
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary> <summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary> <summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</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="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary> <summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary> <summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
@@ -75,7 +76,6 @@
<summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary> <summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary>
<summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary> <summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary>
<summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary> <summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary>
<summary xml:lang="sv">En klient för Matrix, det decentraliserade kommunikationsprotokollet</summary>
<summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary> <summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary>
<summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary> <summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary>
<summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary> <summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary>
@@ -88,6 +88,7 @@ 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">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="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="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="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="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="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="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>
@@ -95,7 +96,9 @@ to provide a convergent experience across multiple platforms.</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="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="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="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="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="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="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="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>
@@ -114,7 +117,9 @@ to provide a convergent experience across multiple platforms.</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="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="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="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="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="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="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="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>
@@ -133,7 +138,9 @@ to provide a convergent experience across multiple platforms.</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="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="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="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="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="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="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="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
@@ -153,7 +160,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Inquestas - MSC3381</li> <li xml:lang="ia">Inquestas - MSC3381</li>
<li xml:lang="it">Sondaggi - MSC3381</li> <li xml:lang="it">Sondaggi - MSC3381</li>
<li xml:lang="ka">Polls - 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="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li> <li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li> <li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li> <li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
@@ -172,7 +181,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li> <li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li> <li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
<li xml:lang="ka">სტიკერების პაკეტები - 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="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="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li> <li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li> <li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
@@ -191,7 +202,9 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Eventos de Location - MSC3488</li> <li xml:lang="ia">Eventos de Location - MSC3488</li>
<li xml:lang="it">Località eventi - MSC3488</li> <li xml:lang="it">Località eventi - MSC3488</li>
<li xml:lang="ka">მდებარეობის მოვლენები - 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="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="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li> <li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li> <li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
@@ -214,6 +227,7 @@ to provide a convergent experience across multiple platforms.</p>
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name> <developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
<developer_name xml:lang="el">Η Κοινότητα του KDE</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="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="es">La comunidad KDE</developer_name>
<developer_name xml:lang="eu">KDE komunitatea</developer_name> <developer_name xml:lang="eu">KDE komunitatea</developer_name>
<developer_name xml:lang="fi">KDE-yhteisö</developer_name> <developer_name xml:lang="fi">KDE-yhteisö</developer_name>
@@ -235,7 +249,6 @@ to provide a convergent experience across multiple platforms.</p>
<developer_name xml:lang="ru">Сообщество KDE</developer_name> <developer_name xml:lang="ru">Сообщество KDE</developer_name>
<developer_name xml:lang="sk">KDE Komunita</developer_name> <developer_name xml:lang="sk">KDE Komunita</developer_name>
<developer_name xml:lang="sl">Skupnost KDE</developer_name> <developer_name xml:lang="sl">Skupnost KDE</developer_name>
<developer_name xml:lang="sv">KDE-gemenskapen</developer_name>
<developer_name xml:lang="ta">கே.டீ.யீ. சமூகம்</developer_name> <developer_name xml:lang="ta">கே.டீ.யீ. சமூகம்</developer_name>
<developer_name xml:lang="tr">KDE Topluluğu</developer_name> <developer_name xml:lang="tr">KDE Topluluğu</developer_name>
<developer_name xml:lang="uk">Спільнота KDE</developer_name> <developer_name xml:lang="uk">Спільнота KDE</developer_name>
@@ -247,6 +260,44 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::matrix">#neochat:kde.org</value> <value key="KDE::matrix">#neochat:kde.org</value>
<value key="KDE::windows_store">https://www.microsoft.com/store/apps/9PNXWVNRC29H</value> <value key="KDE::windows_store">https://www.microsoft.com/store/apps/9PNXWVNRC29H</value>
<value key="KDE::mastodon">https://kde.social/@neochat</value> <value key="KDE::mastodon">https://kde.social/@neochat</value>
<value key="KDE::windows_store::StoreLogo9x16">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-720x1080.png</value>
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
<value key="KDE::windows_store::screenshots::1::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::screenshots::1::caption">Main view with room list, chat, and room information</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="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="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="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="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="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="fr">Écran de connexion</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="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="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> </custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable> <launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots> <screenshots>
@@ -261,6 +312,7 @@ to provide a convergent experience across multiple platforms.</p>
<content_attribute id="social-chat">intense</content_attribute> <content_attribute id="social-chat">intense</content_attribute>
</content_rating> </content_rating>
<releases> <releases>
<release version="23.04.3" date="2023-07-06"/>
<release version="23.04.2" date="2023-06-08"/> <release version="23.04.2" date="2023-06-08"/>
<release version="23.04.1" date="2023-05-11"/> <release version="23.04.1" date="2023-05-11"/>
<release version="23.04.0" date="2023-04-20"> <release version="23.04.0" date="2023-04-20">

View File

@@ -11,6 +11,7 @@ Name[cs]=NeoChat
Name[de]=NeoChat Name[de]=NeoChat
Name[el]=NeoChat Name[el]=NeoChat
Name[en_GB]=NeoChat Name[en_GB]=NeoChat
Name[eo]=NeoChat
Name[es]=NeoChat Name[es]=NeoChat
Name[eu]=NeoChat Name[eu]=NeoChat
Name[fi]=NeoChat Name[fi]=NeoChat
@@ -34,7 +35,6 @@ Name[ro]=NeoChat
Name[ru]=NeoChat Name[ru]=NeoChat
Name[sk]=NeoChat Name[sk]=NeoChat
Name[sl]=NeoChat Name[sl]=NeoChat
Name[sv]=NeoChat
Name[ta]=நியோச்சாட் Name[ta]=நியோச்சாட்
Name[tr]=NeoChat Name[tr]=NeoChat
Name[uk]=NeoChat Name[uk]=NeoChat
@@ -49,6 +49,7 @@ GenericName[cs]=Klient protokolu Matrix
GenericName[de]=Matrix-Programm GenericName[de]=Matrix-Programm
GenericName[el]=Εφαρμογή του Matrix GenericName[el]=Εφαρμογή του Matrix
GenericName[en_GB]=Matrix Client GenericName[en_GB]=Matrix Client
GenericName[eo]=Matrix-Kliento
GenericName[es]=Cliente para Matrix GenericName[es]=Cliente para Matrix
GenericName[eu]=Matrix bezeroa GenericName[eu]=Matrix bezeroa
GenericName[fi]=Matrix-asiakas GenericName[fi]=Matrix-asiakas
@@ -72,7 +73,6 @@ GenericName[ro]=Client Matrix
GenericName[ru]=Клиент Matrix GenericName[ru]=Клиент Matrix
GenericName[sk]=Matrix Client GenericName[sk]=Matrix Client
GenericName[sl]=Odjemalec Matrix GenericName[sl]=Odjemalec Matrix
GenericName[sv]=Matrix-klient
GenericName[ta]=Matrix வாங்கி GenericName[ta]=Matrix வாங்கி
GenericName[tr]=Matrix İstemcisi GenericName[tr]=Matrix İstemcisi
GenericName[uk]=Клієнт Matrix GenericName[uk]=Клієнт Matrix
@@ -86,6 +86,7 @@ Comment[ca@valencia]=Client per al protocol Matrix
Comment[de]=Programm für das Matrix-Protokoll Comment[de]=Programm für das Matrix-Protokoll
Comment[el]=Πελάτης για το πρωτόκολλο Matrix Comment[el]=Πελάτης για το πρωτόκολλο Matrix
Comment[en_GB]=Client for the Matrix protocol Comment[en_GB]=Client for the Matrix protocol
Comment[eo]=Kliento por la Matrix-protokolo
Comment[es]=Cliente para el protocolo Matrix Comment[es]=Cliente para el protocolo Matrix
Comment[eu]=Matrix protokolorako bezeroa Comment[eu]=Matrix protokolorako bezeroa
Comment[fi]=Asiakas Matrix-yhteyskäytännölle Comment[fi]=Asiakas Matrix-yhteyskäytännölle
@@ -100,7 +101,7 @@ Comment[ka]=კლიენტი Matrix-ის პროტოკოლის
Comment[ko]=Matrix 프로토콜용 클라이언트 Comment[ko]=Matrix 프로토콜용 클라이언트
Comment[lt]=Matrix protokolo kliento programa Comment[lt]=Matrix protokolo kliento programa
Comment[nl]=Client voor het Matrix-protocol Comment[nl]=Client voor het Matrix-protocol
Comment[nn]=Lynmeldings­klient for Matrix-protokollen Comment[nn]=Klient for Matrix-protokollen
Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ
Comment[pl]=Program obsługi protokołu Matriksa Comment[pl]=Program obsługi protokołu Matriksa
Comment[pt]=Cliente para o protocolo Matrix Comment[pt]=Cliente para o protocolo Matrix
@@ -109,7 +110,6 @@ Comment[ro]=Client pentru protocolul Matrix
Comment[ru]=Клиент для протокола Matrix Comment[ru]=Клиент для протокола Matrix
Comment[sk]=Klient protokolu Matrix Comment[sk]=Klient protokolu Matrix
Comment[sl]=Odjemalec za protokol Matrix Comment[sl]=Odjemalec za protokol Matrix
Comment[sv]=Klient för protokollet Matrix
Comment[ta]=Matrix நெறிமுறைக்கான வாங்கி Comment[ta]=Matrix நெறிமுறைக்கான வாங்கி
Comment[tr]=Matrix protokolü için istemci Comment[tr]=Matrix protokolü için istemci
Comment[uk]=Клієнт протоколу Matrix Comment[uk]=Клієнт протоколу 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-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
# SPDX-License-Identifier: BSD-2-Clause # 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 add_library(neochat STATIC
controller.cpp controller.cpp
controller.h
actionshandler.cpp actionshandler.cpp
actionshandler.h
models/emojimodel.cpp models/emojimodel.cpp
models/emojimodel.h
emojitones.cpp emojitones.cpp
emojitones.h
models/customemojimodel.cpp models/customemojimodel.cpp
models/customemojimodel.h
clipboard.cpp clipboard.cpp
clipboard.h
matriximageprovider.cpp matriximageprovider.cpp
matriximageprovider.h
models/messageeventmodel.cpp models/messageeventmodel.cpp
models/messageeventmodel.h
models/messagefiltermodel.cpp models/messagefiltermodel.cpp
models/messagefiltermodel.h
models/roomlistmodel.cpp models/roomlistmodel.cpp
models/roomlistmodel.h
models/sortfilterspacelistmodel.cpp models/sortfilterspacelistmodel.cpp
models/sortfilterspacelistmodel.h
models/accountemoticonmodel.cpp models/accountemoticonmodel.cpp
models/accountemoticonmodel.h
spacehierarchycache.cpp spacehierarchycache.cpp
spacehierarchycache.h
roommanager.cpp roommanager.cpp
roommanager.h
neochatroom.cpp neochatroom.cpp
neochatroom.h
neochatuser.cpp neochatuser.cpp
neochatuser.h
models/userlistmodel.cpp models/userlistmodel.cpp
models/userlistmodel.h
models/userfiltermodel.cpp models/userfiltermodel.cpp
models/userfiltermodel.h
models/publicroomlistmodel.cpp models/publicroomlistmodel.cpp
models/publicroomlistmodel.h
models/userdirectorylistmodel.cpp models/userdirectorylistmodel.cpp
models/keywordnotificationrulemodel.cpp models/userdirectorylistmodel.h
models/pushrulemodel.cpp
models/pushrulemodel.h
models/emoticonfiltermodel.cpp models/emoticonfiltermodel.cpp
models/emoticonfiltermodel.h
notificationsmanager.cpp notificationsmanager.cpp
notificationsmanager.h
models/sortfilterroomlistmodel.cpp models/sortfilterroomlistmodel.cpp
models/sortfilterroomlistmodel.h
chatdocumenthandler.cpp chatdocumenthandler.cpp
chatdocumenthandler.h
models/devicesmodel.cpp models/devicesmodel.cpp
models/devicesmodel.h
models/devicesproxymodel.cpp
filetypesingleton.cpp filetypesingleton.cpp
filetypesingleton.h
login.cpp login.cpp
login.h
models/webshortcutmodel.cpp models/webshortcutmodel.cpp
models/webshortcutmodel.h
blurhash.cpp blurhash.cpp
blurhash.h
blurhashimageprovider.cpp blurhashimageprovider.cpp
blurhashimageprovider.h
models/collapsestateproxymodel.cpp models/collapsestateproxymodel.cpp
models/collapsestateproxymodel.h
models/mediamessagefiltermodel.cpp
models/mediamessagefiltermodel.h
urlhelper.cpp urlhelper.cpp
urlhelper.h
windowcontroller.cpp windowcontroller.cpp
windowcontroller.h
linkpreviewer.cpp linkpreviewer.cpp
linkpreviewer.h
models/completionmodel.cpp models/completionmodel.cpp
models/completionmodel.h
models/completionproxymodel.cpp models/completionproxymodel.cpp
models/completionproxymodel.h
models/actionsmodel.cpp models/actionsmodel.cpp
models/actionsmodel.h
models/serverlistmodel.cpp models/serverlistmodel.cpp
models/serverlistmodel.h
models/statemodel.cpp models/statemodel.cpp
models/statemodel.h
models/statefiltermodel.cpp models/statefiltermodel.cpp
models/statefiltermodel.h
filetransferpseudojob.cpp filetransferpseudojob.cpp
filetransferpseudojob.h
models/searchmodel.cpp models/searchmodel.cpp
models/searchmodel.h
texthandler.cpp texthandler.cpp
texthandler.h
logger.cpp logger.cpp
logger.h
models/stickermodel.cpp models/stickermodel.cpp
models/stickermodel.h
models/imagepacksmodel.cpp models/imagepacksmodel.cpp
models/imagepacksmodel.h
events/imagepackevent.cpp events/imagepackevent.cpp
events/imagepackevent.h
events/joinrulesevent.cpp events/joinrulesevent.cpp
events/stickerevent.cpp events/joinrulesevent.h
models/reactionmodel.cpp models/reactionmodel.cpp
models/reactionmodel.h
delegatesizehelper.cpp delegatesizehelper.cpp
delegatesizehelper.h
models/livelocationsmodel.cpp models/livelocationsmodel.cpp
models/livelocationsmodel.h
models/locationsmodel.cpp models/locationsmodel.cpp
models/locationsmodel.h
locationhelper.cpp locationhelper.cpp
locationhelper.h
events/pollevent.cpp
pollhandler.cpp
) )
ecm_qt_declare_logging_category(neochat ecm_qt_declare_logging_category(neochat
HEADER "messageeventmodel_logging.h" HEADER "messageeventmodel_logging.h"
IDENTIFIER "MessageEvent" IDENTIFIER "MessageEvent"
CATEGORY_NAME "org.kde.neochat.messageeventmodel" CATEGORY_NAME "org.kde.neochat.messageeventmodel"
DESCRIPTION "Neochat: messageeventmodel"
DEFAULT_SEVERITY Info DEFAULT_SEVERITY Info
EXPORT NEOCHAT
) )
add_executable(neochat-app add_executable(neochat-app
main.cpp main.cpp
res.qrc ${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc
) )
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR}) target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
@@ -79,24 +149,16 @@ target_link_libraries(neochat-app PRIVATE
neochat 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) ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON}) target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID) if(NOT ANDROID)
target_sources(neochat PRIVATE colorschemer.cpp) target_sources(neochat PRIVATE colorschemer.cpp colorschemer.h)
if (NOT WIN32 AND NOT APPLE) if (NOT WIN32 AND NOT APPLE)
target_sources(neochat PRIVATE trayicon_sni.cpp) target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
else() else()
target_sources(neochat PRIVATE trayicon.cpp) target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
endif() endif()
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem) target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem)
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME) target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -151,3 +151,5 @@ qreal DelegateSizeHelper::currentWidth() const
return std::ceil(std::min(absoluteWidth, m_maxWidth)); 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) Q_PROPERTY(qreal currentWidth READ currentWidth NOTIFY currentWidthChanged)
public: public:
DelegateSizeHelper(QObject *parent = nullptr); explicit DelegateSizeHelper(QObject *parent = nullptr);
qreal parentWidth() const; qreal parentWidth() const;
void setParentWidth(qreal parentWidth); void setParentWidth(qreal parentWidth);

View File

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

View File

@@ -4,8 +4,8 @@
#pragma once #pragma once
#include <QVector> #include <QVector>
#include <events/eventcontent.h> #include <Quotient/events/eventcontent.h>
#include <events/stateevent.h> #include <Quotient/events/stateevent.h>
namespace Quotient namespace Quotient
{ {
@@ -83,23 +83,11 @@ public:
* *
* @sa Quotient::StateEvent, ImagePackEventContent * @sa Quotient::StateEvent, ImagePackEventContent
*/ */
#ifdef QUOTIENT_07
class ImagePackEvent : public KeyedStateEventBase<ImagePackEvent, ImagePackEventContent> class ImagePackEvent : public KeyedStateEventBase<ImagePackEvent, ImagePackEventContent>
#else
class ImagePackEvent : public StateEvent<ImagePackEventContent>
#endif
{ {
public: public:
#ifdef QUOTIENT_07
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes") QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
using KeyedStateEventBase::KeyedStateEventBase; 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) REGISTER_EVENT_TYPE(ImagePackEvent)

View File

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

View File

@@ -3,8 +3,7 @@
#pragma once #pragma once
#include <events/eventcontent.h> #include <Quotient/events/roomevent.h>
#include <events/roomevent.h>
namespace Quotient 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) { if (id != m_eventId) {
return; return;
@@ -23,7 +23,7 @@ void FileTransferPseudoJob::fileTransferProgress(QString id, qint64 progress, qi
setTotalAmount(Unit::Bytes, total); setTotalAmount(Unit::Bytes, total);
} }
void FileTransferPseudoJob::fileTransferCompleted(QString id, QUrl localFile) void FileTransferPseudoJob::fileTransferCompleted(const QString &id, const QUrl &localFile)
{ {
Q_UNUSED(localFile); Q_UNUSED(localFile);
if (id != m_eventId) { if (id != m_eventId) {
@@ -32,7 +32,7 @@ void FileTransferPseudoJob::fileTransferCompleted(QString id, QUrl localFile)
emitResult(); emitResult();
} }
void FileTransferPseudoJob::fileTransferFailed(QString id, QString errorMessage) void FileTransferPseudoJob::fileTransferFailed(const QString &id, const QString &errorMessage)
{ {
if (id != m_eventId) { if (id != m_eventId) {
return; return;

View File

@@ -20,23 +20,23 @@ public:
Download, Download,
Upload, Upload,
}; };
Q_ENUM(Operation); Q_ENUM(Operation)
FileTransferPseudoJob(Operation operation, const QString &srcDest, const QString &path); FileTransferPseudoJob(Operation operation, const QString &srcDest, const QString &path);
/** /**
* @brief Set the current number of bytes transferred. * @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. * @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. * @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. * @brief Start the file transfer.

View File

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

View File

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

View File

@@ -3,14 +3,16 @@
#include "linkpreviewer.h" #include "linkpreviewer.h"
#include <connection.h> #include "controller.h"
#include <csapi/content-repo.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include "neochatroom.h" #include "neochatroom.h"
using namespace Quotient; using namespace Quotient;
LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, QUrl url) LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, const QUrl &url)
: QObject(parent) : QObject(parent)
, m_currentRoom(room) , m_currentRoom(room)
, m_loaded(false) , m_loaded(false)
@@ -69,14 +71,7 @@ void LinkPreviewer::loadUrlPreview()
auto imageUrl = QUrl(json["og:image"].toString()); auto imageUrl = QUrl(json["og:image"].toString());
if (imageUrl.isValid() && imageUrl.scheme() == QStringLiteral("mxc")) { if (imageUrl.isValid() && imageUrl.scheme() == QStringLiteral("mxc")) {
#ifdef QUOTIENT_07
m_imageSource = conn->makeMediaUrl(imageUrl); 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 { } else {
m_imageSource = QUrl(); 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) Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
public: 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; [[nodiscard]] QUrl url() const;
void setUrl(QUrl); 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); 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-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later // SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include "linkpreviewer.h" #include "linkpreviewer.h"
#include <QMetaType> #include <QMetaType>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,8 +6,8 @@
#include "controller.h" #include "controller.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "roommanager.h" #include "roommanager.h"
#include <events/roommemberevent.h> #include <Quotient/events/roommemberevent.h>
#include <events/roompowerlevelsevent.h> #include <Quotient/events/roompowerlevelsevent.h>
#include <KLocalizedString> #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)); 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(); return QString();
} }
#ifdef QUOTIENT_07
const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text); const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text);
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) { 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)); 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)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString(); return QString();
} }
#endif
if (room->localUser()->id() == text) { if (room->localUser()->id() == text) {
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room.")); Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room."));
return QString(); return QString();
@@ -243,7 +241,6 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id>"), kli18n("<room alias or id>"),
kli18n("Joins the given room"), kli18n("Joins the given room"),
}, },
#ifdef QUOTIENT_07
Action{ Action{
QStringLiteral("knock"), QStringLiteral("knock"),
[](const QString &text, NeoChatRoom *room) { [](const QString &text, NeoChatRoom *room) {
@@ -276,7 +273,6 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id> [<reason>]"), kli18n("<room alias or id> [<reason>]"),
kli18n("Requests to join the given room"), kli18n("Requests to join the given room"),
}, },
#endif
Action{ Action{
QStringLiteral("j"), QStringLiteral("j"),
[](const QString &text, NeoChatRoom *room) { [](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)); 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(); return QString();
} }
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(parts[0]); auto state = room->currentState().get<RoomMemberEvent>(parts[0]);
if (state && state->membership() == Membership::Ban) { 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)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text));
return QString(); return QString();
} }
#endif auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>(); if (!plEvent) {
return QString();
}
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) { 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
return QString(); 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)); 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(); 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())) { 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
return QString(); return QString();
} }
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(text); auto state = room->currentState().get<RoomMemberEvent>(text);
if (state && state->membership() != Membership::Ban) { 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)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is not banned from this room.", "%1 is not banned from this room.", text));
return QString(); return QString();
} }
#endif
room->unban(text); room->unban(text);
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18nc("<username> was unbanned from this room.", "%1 was unbanned from this room.", 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You cannot kick yourself from the room."));
return QString(); return QString();
} }
#ifdef QUOTIENT_07
if (!room->isMember(parts[0])) { 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])); Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0]));
return QString(); return QString();
} }
#endif auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>(); if (!plEvent) {
return QString();
}
auto kick = plEvent->kick(); auto kick = plEvent->kick();
if (plEvent->powerLevelForUser(room->localUser()->id()) < 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.")); 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 <KLazyLocalizedString>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <events/roommessageevent.h> #include <Quotient/events/roommessageevent.h>
class NeoChatRoom; class NeoChatRoom;
@@ -61,7 +61,7 @@ public:
CompletionType, /**< The completion type (always "action" for this model). */ CompletionType, /**< The completion type (always "action" for this model). */
Parameters, /**< The input parameters expected by the action. */ Parameters, /**< The input parameters expected by the action. */
}; };
Q_ENUM(Roles); Q_ENUM(Roles)
/** /**
* @brief Get the given role value at the given index. * @brief Get the given role value at the given index.

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LGPL-2.0-or-later // SPDX-License-Identifier: LGPL-2.0-or-later
#include "collapsestateproxymodel.h" #include "collapsestateproxymodel.h"
#include "messageeventmodel.h"
#include <KLocalizedString> #include <KLocalizedString>
@@ -174,3 +173,5 @@ QString CollapseStateProxyModel::excessAuthors(int row) const
return QStringLiteral("+ %1").arg(excessAuthors); 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. */ StateEventsRole, /**< List of state events in the aggregated state. */
AuthorListRole, /**< List of the first 5 unique authors of the aggregated state event. */ AuthorListRole, /**< List of the first 5 unique authors of the aggregated state event. */
ExcessAuthorsRole, /**< The number of unique authors beyond the first 5. */ 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); auto filterIndex = m_filterModel->index(index.row(), 0);
if (m_autoCompletionType == User) { if (m_autoCompletionType == User) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole); return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, UserListModel::UserIdRole); return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, UserListModel::AvatarRole); return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Command) { if (m_autoCompletionType == Command) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ") return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ")
+ m_filterModel->data(filterIndex, ActionsModel::Parameters).toString(); + m_filterModel->data(filterIndex, ActionsModel::Parameters).toString();
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, ActionsModel::Description); return m_filterModel->data(filterIndex, ActionsModel::Description);
} }
if (role == Icon) { if (role == IconNameRole) {
return QStringLiteral("invalid"); return QStringLiteral("invalid");
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix); return m_filterModel->data(filterIndex, ActionsModel::Prefix);
} }
} }
if (m_autoCompletionType == Room) { if (m_autoCompletionType == Room) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole); return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole); return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole); return m_filterModel->data(filterIndex, RoomListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Emoji) { if (m_autoCompletionType == Emoji) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole); return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl); return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole); return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole); 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 QHash<int, QByteArray> CompletionModel::roleNames() const
{ {
return { return {
{Text, "text"}, {DisplayNameRole, "displayName"},
{Subtitle, "subtitle"}, {SubtitleRole, "subtitle"},
{Icon, "icon"}, {IconNameRole, "iconName"},
{ReplacedText, "replacedText"}, {ReplacedTextRole, "replacedText"},
}; };
} }
@@ -193,3 +193,5 @@ void CompletionModel::setRoomListModel(RoomListModel *roomListModel)
m_roomListModel = roomListModel; m_roomListModel = roomListModel;
Q_EMIT roomListModelChanged(); Q_EMIT roomListModelChanged();
} }
#include "moc_completionmodel.cpp"

View File

@@ -64,14 +64,14 @@ public:
* @brief Defines the model roles. * @brief Defines the model roles.
*/ */
enum Roles { enum Roles {
Text = Qt::DisplayRole, /**< The main text to show. */ DisplayNameRole = Qt::DisplayRole, /**< The main text to show. */
Subtitle, /**< The subtitle text to show. */ SubtitleRole, /**< The subtitle text to show. */
Icon, /**< The icon to show. */ IconNameRole, /**< The icon to show. */
ReplacedText, /**< The text to replace the input text with for the completion. */ 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. * @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; m_fullText = fullText;
} }
#include "moc_completionproxymodel.cpp"

View File

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

View File

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

View File

@@ -3,23 +3,19 @@
#include "devicesmodel.h" #include "devicesmodel.h"
#include <csapi/device_management.h>
#include "controller.h" #include "controller.h"
#include <connection.h>
#include <user.h> #include <KLocalizedString>
#include <Quotient/csapi/device_management.h>
#include <Quotient/connection.h>
#include <Quotient/user.h>
using namespace Quotient; using namespace Quotient;
DevicesModel::DevicesModel(QObject *parent) DevicesModel::DevicesModel(QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
{ {
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, [this]() {
DevicesModel::fetchDevices();
Q_EMIT connectionChanged();
});
fetchDevices();
} }
void DevicesModel::fetchDevices() void DevicesModel::fetchDevices()
@@ -30,6 +26,7 @@ void DevicesModel::fetchDevices()
beginResetModel(); beginResetModel();
m_devices = job->devices(); m_devices = job->devices();
endResetModel(); endResetModel();
Q_EMIT countChanged();
}); });
} }
} }
@@ -40,16 +37,33 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
return {}; return {};
} }
const auto &device = m_devices[index.row()];
switch (role) { switch (role) {
case Id: case Id:
return m_devices[index.row()].deviceId; return device.deviceId;
case DisplayName: case DisplayName:
return m_devices[index.row()].displayName; return device.displayName;
case LastIp: case LastIp:
return m_devices[index.row()].lastSeenIp; return device.lastSeenIp;
case LastTimestamp: case LastTimestamp:
if (m_devices[index.row()].lastSeenTs) if (device.lastSeenTs) {
return *m_devices[index.row()].lastSeenTs; return *device.lastSeenTs;
} else {
return false;
}
case Type:
if (device.deviceId == m_connection->deviceId()) {
return This;
}
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;
}
} }
return {}; return {};
} }
@@ -62,11 +76,21 @@ int DevicesModel::rowCount(const QModelIndex &parent) const
QHash<int, QByteArray> DevicesModel::roleNames() 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"},
{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); auto job = Controller::instance().activeConnection()->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId);
connect(job, &BaseJob::result, this, [this, job, password, index] { connect(job, &BaseJob::result, this, [this, job, password, index] {
@@ -74,6 +98,7 @@ void DevicesModel::logout(int index, const QString &password)
beginRemoveRows(QModelIndex(), index, index); beginRemoveRows(QModelIndex(), index, index);
m_devices.remove(index); m_devices.remove(index);
endRemoveRows(); endRemoveRows();
Q_EMIT countChanged();
}; };
if (job->error() != BaseJob::Success) { if (job->error() != BaseJob::Success) {
QJsonObject replyData = job->jsonData(); QJsonObject replyData = job->jsonData();
@@ -91,8 +116,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); auto job = Controller::instance().activeConnection()->callApi<UpdateDeviceJob>(m_devices[index].deviceId, name);
QString oldName = m_devices[index].displayName; QString oldName = m_devices[index].displayName;
beginResetModel(); beginResetModel();
@@ -107,5 +135,27 @@ void DevicesModel::setName(int index, const QString &name)
Connection *DevicesModel::connection() const 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();
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();
});
}
#include "moc_devicesmodel.cpp"

View File

@@ -4,8 +4,9 @@
#pragma once #pragma once
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QPointer>
#include <csapi/definitions/client_device.h> #include <Quotient/csapi/definitions/client_device.h>
namespace Quotient namespace Quotient
{ {
@@ -28,7 +29,7 @@ class DevicesModel : public QAbstractListModel
/** /**
* @brief The current connection that the model is getting its devices from. * @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: public:
/** /**
@@ -39,10 +40,17 @@ public:
DisplayName, /**< Display name set by the user for this device. */ DisplayName, /**< Display name set by the user for this device. */
LastIp, /**< The IP address where this device was last seen. */ LastIp, /**< The IP address where this device was last seen. */
LastTimestamp, /**< The timestamp when this devices was last seen. */ LastTimestamp, /**< 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. * @brief Get the given role value at the given index.
@@ -66,21 +74,27 @@ public:
QHash<int, QByteArray> roleNames() const override; 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: Q_SIGNALS:
void connectionChanged(); void connectionChanged();
void countChanged();
private: private:
void fetchDevices(); void fetchDevices();
QVector<Quotient::Device> m_devices; 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; 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). */ ReplacedTextRole = 52, /**< The text to replace the short name with (i.e. the unicode character). */
DescriptionRole = 53, /**< The long description of an emoji. */ 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. * @brief Defines the potential categories an emoji can be placed in.

View File

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

View File

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

View File

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

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