Compare commits

...

92 Commits

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

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

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


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

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

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

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

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

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

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

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

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

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

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

Updated

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

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

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

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

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

BUG: 462576
2022-12-27 09:57:53 +00:00
l10n daemon script
1a09405829 GIT_SILENT Sync po/docbooks with svn 2022-12-27 02:09:12 +00:00
Gary Wang
304054a4bb Add a compact room list option 2022-12-26 21:31:36 +00:00
142 changed files with 43914 additions and 29989 deletions

1
.gitignore vendored
View File

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

View File

@@ -18,6 +18,7 @@ Dependencies:
'third-party/libquotient': '@latest'
'third-party/qtkeychain': '@latest'
'third-party/cmark': '@latest'
'third-party/qcoro': '@latest'
- 'on': ['Windows', 'Linux', 'FreeBSD']
'require':
'frameworks/qqc2-desktop-style': '@stable'

View File

@@ -6,11 +6,14 @@
cmake_minimum_required(VERSION 3.16)
project(NeoChat)
set(PROJECT_VERSION "22.11")
set(PROJECT_VERSION "23.01")
project(NeoChat VERSION ${PROJECT_VERSION})
set(KF5_MIN_VERSION "5.91.0")
set(QT_MIN_VERSION "5.15.2")
if (ANDROID)
set(QT_MIN_VERSION "5.15.8")
endif()
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
@@ -122,6 +125,8 @@ set_package_properties(KF5DocTools PROPERTIES DESCRIPTION
TYPE OPTIONAL
)
find_package(Sqlite3)
if(NOT Quotient_VERSION_MINOR GREATER 6)
cmake_policy(SET CMP0063 OLD)
endif()

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

View File

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

View File

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

View File

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

View File

@@ -16,6 +16,7 @@
<name xml:lang="ca-valencia">NeoChat</name>
<name xml:lang="cs">NeoChat</name>
<name xml:lang="de">NeoChat</name>
<name xml:lang="el">NeoChat</name>
<name xml:lang="en-GB">NeoChat</name>
<name xml:lang="es">NeoChat</name>
<name xml:lang="eu">NeoChat</name>
@@ -50,6 +51,7 @@
<summary xml:lang="ca-valencia">Un client per a Matrix, el protocol de comunicacions descentralitzat</summary>
<summary xml:lang="cs">Klient pro decentralizovaný komunikační protokol matrix</summary>
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
@@ -83,6 +85,7 @@
<p xml:lang="ca">El NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics usant el protocol Matrix.</p>
<p xml:lang="ca-valencia">NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics utilitzant el protocol Matrix.</p>
<p xml:lang="de">NeoChat ist ein Matrix-Client. Er ermöglicht Ihnen das Senden von Textnachrichten, Videos und Audiodateien an Ihre Familie, Kollegen und Freunde unter Verwendung des Matrix-Protokolls.</p>
<p xml:lang="el">Το NeoChat είναι μια εφαρμογή του Matrix. Σας επιτρέπει να στέλνετε μηνύματα κειμένου, βίντεο και ήχο στην οικογένειά σας, σε συναδέλφους και φίλους με το πρωτόκολλο Matrix.</p>
<p xml:lang="en-GB">NeoChat is a Matrix client. It allows you to send text messages, videos and audio files to your family, colleagues and friends using the Matrix protocol.</p>
<p xml:lang="es">NeoChat es un cliente para Matrix. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos usando el protocolo Matrix.</p>
<p xml:lang="eu">NeoChat Matrix bezero bat da. Familiari, lankideei eta lagunei testu-mezuak, bideoak eta audio-fitxategiak bidaltzeko aukera ematen du, Matrix protokoloa erabiliz.</p>
@@ -113,6 +116,7 @@
<p xml:lang="ca">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment el NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
<p xml:lang="ca-valencia">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
<p xml:lang="de">Matrix ist ein dezentralisiertes Kommunikationsprotokoll, das dem Benutzer wieder die Kontrolle zurückgibt. Derzeit implementiert NeoChat einen großen Teil des Protokolls mit der Ausnahme von verschlüsselten Chats und Video-Chat.</p>
<p xml:lang="el">Το Matrix είναι ένα αποκεντρωμένο πρωτόκολλο επικοινωνίας, δίνοντας πίσω στον χρήστη τον έλεγχο. Προς το παρόν το NeoChat υλοποιεί ένα μεγάλο μέρος του πρωτοκόλλου με εξαίρεση τις κρυπτογραφημένες συνομιλίες και τη συνομιλία με βίντεο.</p>
<p xml:lang="en-GB">Matrix is a decentralised communication protocol, putting the user back in control. Currently NeoChat implements large part of the protocol with the exception of encrypted chats and video chat.</p>
<p xml:lang="es">Matrix es un protocolo de comunicaciones descentralizado, que devuelve el control al usuario. En la actualidad, NeoChat implementa gran parte del protocolo con la excepción de chats cifrados y chats de vídeo.</p>
<p xml:lang="eu">Matrix komunikazio-protokolo deszentralizatu bat da, erabiltzaileari kontrola itzultzen diona. Gaur egun, NeoChat-ek protokoloaren zati handi bat inplementatzen du, berriketa zifratuak eta bideo berriketak izan ezik.</p>
@@ -142,7 +146,8 @@
<p xml:lang="az">Vahid istifadəçi interfeysi ilə təmin olunan NeoChat, həm mobil telefonda həm də kompyuterlərdə işləyir.</p>
<p xml:lang="ca">El NeoChat funciona en els mòbils i a l'escriptori, proporcionant una experiència d'usuari coherent.</p>
<p xml:lang="ca-valencia">NeoChat funciona en els mòbils i en l'escriptori, proporcionant una experiència d'usuari coherent.</p>
<p xml:lang="de">NeoChat funktioniert sowohl auf dem Mobiltelefon als auch auf dem Arbeitsfläche und bietet ein einheitliches Benutzererlebnis. </p>
<p xml:lang="de">NeoChat funktioniert sowohl auf Mobilgeräten als auch auf dem PC und bietet ein einheitliches Benutzererlebnis.</p>
<p xml:lang="el">Το NeoChat λειτουργεί και στα κινητά και στους υπολογιστές γραφείου παρέχοντας μια αδιάλειπτη εμπειρία χρήσης.</p>
<p xml:lang="en-GB">NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
<p xml:lang="es">NeoChat funciona en móviles y en el escritorio a la vez que proporciona una experiencia de usuario consistente.</p>
<p xml:lang="eu">NeoChat mugikorretan eta mahaigainean dabil, erabiltzaile esperientzia koherentea eskainiz.</p>
@@ -180,6 +185,7 @@
<developer_name xml:lang="ca-valencia">La comunitat KDE</developer_name>
<developer_name xml:lang="cs">Komunita KDE</developer_name>
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
<developer_name xml:lang="el">Η Κοινότητα του KDE</developer_name>
<developer_name xml:lang="en-GB">The KDE Community</developer_name>
<developer_name xml:lang="es">La comunidad KDE</developer_name>
<developer_name xml:lang="eu">KDE komunitatea</developer_name>
@@ -210,6 +216,7 @@
<project_license>GPL-3.0</project_license>
<custom>
<value key="KDE::matrix">#neochat:kde.org</value>
<value key="KDE::windows_store">https://www.microsoft.com/store/apps/9PNXWVNRC29H</value>
</custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots>
@@ -224,6 +231,20 @@
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="23.01" date="2023-01-30">
<url>https://plasma-mobile.org/2023/01/30/january-blog-post/</url>
<description>
<p>New features and bugfixes:</p>
<ul>
<li>Notifications will now be shown for all accounts, not just the active one</li>
<li>There is a new "compact" mode for the room list</li>
<li>You can now search in the room history</li>
<li>Emojis and Reactions have been significantly improved</li>
<li>Fixed several crashes around user invitations</li>
<li>Room permission settings can now be configured</li>
</ul>
</description>
</release>
<release version="22.11" date="2022-11-30">
<url>https://plasma-mobile.org/2022/11/30/plasma-mobile-gear-22-11/</url>
</release>

View File

@@ -9,6 +9,7 @@ Name[ca]=NeoChat
Name[ca@valencia]=NeoChat
Name[cs]=NeoChat
Name[de]=NeoChat
Name[el]=NeoChat
Name[en_GB]=NeoChat
Name[es]=NeoChat
Name[eu]=NeoChat
@@ -45,6 +46,7 @@ GenericName[ca]=Client de Matrix
GenericName[ca@valencia]=Client de Matrix
GenericName[cs]=Klient protokolu Matrix
GenericName[de]=Matrix-Programm
GenericName[el]=Εφαρμογή του Matrix
GenericName[en_GB]=Matrix Client
GenericName[es]=Cliente para Matrix
GenericName[eu]=Matrix bezeroa
@@ -80,6 +82,7 @@ Comment[az]=Matrix protokolu üçün müştəri
Comment[ca]=Client per al protocol Matrix
Comment[ca@valencia]=Client per al protocol Matrix
Comment[de]=Programm für das Matrix-Protokoll
Comment[el]=Πελάτης για το πρωτόκολλο Matrix
Comment[en_GB]=Client for the Matrix protocol
Comment[es]=Cliente para el protocolo Matrix
Comment[eu]=Matrix protokolorako bezeroa

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3619
po/el/neochat.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,46 +6,47 @@
add_library(neochat STATIC
controller.cpp
actionshandler.cpp
emojimodel.cpp
models/emojimodel.cpp
emojitones.cpp
customemojimodel.cpp
models/customemojimodel.cpp
clipboard.cpp
matriximageprovider.cpp
messageeventmodel.cpp
messagefiltermodel.cpp
roomlistmodel.cpp
sortfilterspacelistmodel.cpp
models/messageeventmodel.cpp
models/messagefiltermodel.cpp
models/roomlistmodel.cpp
models/sortfilterspacelistmodel.cpp
spacehierarchycache.cpp
roommanager.cpp
neochatroom.cpp
neochatuser.cpp
userlistmodel.cpp
publicroomlistmodel.cpp
userdirectorylistmodel.cpp
keywordnotificationrulemodel.cpp
models/userlistmodel.cpp
models/userfiltermodel.cpp
models/publicroomlistmodel.cpp
models/userdirectorylistmodel.cpp
models/keywordnotificationrulemodel.cpp
utils.cpp
notificationsmanager.cpp
sortfilterroomlistmodel.cpp
models/sortfilterroomlistmodel.cpp
chatdocumenthandler.cpp
devicesmodel.cpp
models/devicesmodel.cpp
filetypesingleton.cpp
login.cpp
stickerevent.cpp
webshortcutmodel.cpp
models/webshortcutmodel.cpp
blurhash.cpp
blurhashimageprovider.cpp
joinrulesevent.cpp
collapsestateproxymodel.cpp
models/collapsestateproxymodel.cpp
urlhelper.cpp
windowcontroller.cpp
linkpreviewer.cpp
completionmodel.cpp
completionproxymodel.cpp
actionsmodel.cpp
serverlistmodel.cpp
statemodel.cpp
models/completionmodel.cpp
models/completionproxymodel.cpp
models/actionsmodel.cpp
models/serverlistmodel.cpp
models/statemodel.cpp
filetransferpseudojob.cpp
searchmodel.cpp
models/searchmodel.cpp
)
add_executable(neochat-app
@@ -102,6 +103,9 @@ endif()
if(ANDROID)
target_sources(neochat PRIVATE notifyrc.qrc)
target_link_libraries(neochat PRIVATE Qt::Svg OpenSSL::SSL)
if(SQLite3_FOUND)
target_link_libraries(neochat-app PRIVATE SQLite::SQLite3)
endif()
target_sources(neochat-app PRIVATE notifyrc.qrc)
target_link_libraries(neochat PUBLIC Qt::Svg OpenSSL::SSL)
kirigami_package_breeze_icons(ICONS
@@ -158,7 +162,7 @@ if(ANDROID)
"zoom-out"
"image-rotate-left-symbolic"
"image-rotate-right-symbolic"
"channel-insecure-symbolic"
"channel-secure-symbolic"
"download"
"smiley"
"tools-check-spelling"
@@ -169,6 +173,7 @@ if(ANDROID)
"favorite"
"window-new"
"globe"
"visibility"
)
else()
target_link_libraries(neochat PUBLIC Qt::Widgets KF5::KIOWidgets)

View File

@@ -13,9 +13,9 @@
#include <KLocalizedString>
#include <QStringBuilder>
#include "actionsmodel.h"
#include "controller.h"
#include "customemojimodel.h"
#include "models/actionsmodel.h"
#include "models/customemojimodel.h"
#include "neochatconfig.h"
#include "neochatuser.h"
#include "roommanager.h"

View File

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

View File

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

View File

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

View File

@@ -128,16 +128,7 @@ Controller::Controller(QObject *parent)
if (AccountRegistry::instance().size() > oldAccountCount) {
auto connection = AccountRegistry::instance().accounts()[AccountRegistry::instance().size() - 1];
connect(connection, &Connection::syncDone, this, [=]() {
bool changes = false;
for (const auto &room : connection->allRooms()) {
if (m_notificationCounts[room] != room->unreadStats().notableCount) {
m_notificationCounts[room] = room->unreadStats().notableCount;
changes = true;
}
}
if (changes) {
handleNotifications();
}
handleNotifications(connection);
});
}
oldAccountCount = AccountRegistry::instance().size();
@@ -146,19 +137,16 @@ Controller::Controller(QObject *parent)
}
#ifdef QUOTIENT_07
void Controller::handleNotifications()
void Controller::handleNotifications(QPointer<Quotient::Connection> connection)
{
static bool initial = true;
static QStringList initial;
static QStringList oldNotifications;
if (!m_connection) {
return;
}
auto job = m_connection->callApi<GetNotificationsJob>();
auto job = connection->callApi<GetNotificationsJob>();
connect(job, &BaseJob::success, this, [this, job]() {
connect(job, &BaseJob::success, this, [job, connection]() {
const auto notifications = job->jsonData()["notifications"].toArray();
if (initial) {
initial = false;
if (!initial.contains(connection->user()->id())) {
initial.append(connection->user()->id());
for (const auto &n : notifications) {
oldNotifications += n.toObject()["event"].toObject()["event_id"].toString();
}
@@ -174,7 +162,7 @@ void Controller::handleNotifications()
continue;
}
oldNotifications += notification["event"].toObject()["event_id"].toString();
auto room = m_connection->room(notification["room_id"].toString());
auto room = connection->room(notification["room_id"].toString());
// If room exists, room is NOT active OR the application is NOT active, show notification
if (room && !(room->id() == RoomManager::instance().currentRoom()->id() && QGuiApplication::applicationState() == Qt::ApplicationActive)) {
@@ -196,7 +184,7 @@ void Controller::handleNotifications()
if (notification["event"]["type"] == "m.room.encrypted") {
#ifdef Quotient_E2EE_ENABLED
auto decrypted = m_connection->decryptNotification(notification);
auto decrypted = connection->decryptNotification(notification);
body = decrypted["content"].toObject()["body"].toString();
#endif
if (body.isEmpty()) {
@@ -381,6 +369,11 @@ void Controller::invokeLogin()
if (error == "Unrecognised access token") {
Q_EMIT errorOccured(i18n("Login Failed: Access Token invalid or revoked"));
logout(connection, false);
} else if (error == "Connection closed") {
Q_EMIT errorOccured(i18n("Login Failed: %1", error));
// Failed due to network connection issue. This might happen when the homeserver is
// temporary down, or the user trying to re-launch NeoChat in a network that cannot
// connect to the homeserver. In this case, we don't want to do logout().
} else {
Q_EMIT errorOccured(i18n("Login Failed: %1", error));
logout(connection, true);

View File

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

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "emojitones.h"
#include "emojimodel.h"
#include "models/emojimodel.h"
QMultiHash<QString, QVariant> EmojiTones::_tones = {
#include "emojitones_data.h"

View File

@@ -181,8 +181,8 @@ void Login::loginWithSso()
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
SsoSession *session = m_connection->prepareForSso(m_deviceName);
m_ssoUrl = session->ssoUrl();
Q_EMIT ssoUrlChanged();
});
Q_EMIT ssoUrlChanged();
}
bool Login::testing() const

View File

@@ -42,38 +42,39 @@
#include "blurhashimageprovider.h"
#include "chatdocumenthandler.h"
#include "clipboard.h"
#include "collapsestateproxymodel.h"
#include "controller.h"
#include "customemojimodel.h"
#include "devicesmodel.h"
#include "emojimodel.h"
#include "filetypesingleton.h"
#include "joinrulesevent.h"
#include "linkpreviewer.h"
#include "keywordnotificationrulemodel.h"
#include "login.h"
#include "matriximageprovider.h"
#include "messageeventmodel.h"
#include "messagefiltermodel.h"
#include "models/collapsestateproxymodel.h"
#include "models/customemojimodel.h"
#include "models/devicesmodel.h"
#include "models/emojimodel.h"
#include "models/keywordnotificationrulemodel.h"
#include "models/messageeventmodel.h"
#include "models/messagefiltermodel.h"
#include "models/publicroomlistmodel.h"
#include "models/roomlistmodel.h"
#include "models/searchmodel.h"
#include "models/serverlistmodel.h"
#include "models/sortfilterroomlistmodel.h"
#include "models/sortfilterspacelistmodel.h"
#include "models/userdirectorylistmodel.h"
#include "models/userfiltermodel.h"
#include "models/userlistmodel.h"
#include "models/webshortcutmodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
#include "searchmodel.h"
#ifdef QUOTIENT_07
#include "pollhandler.h"
#endif
#include "publicroomlistmodel.h"
#include "roomlistmodel.h"
#include "roommanager.h"
#include "serverlistmodel.h"
#include "sortfilterroomlistmodel.h"
#include "sortfilterspacelistmodel.h"
#include "spacehierarchycache.h"
#include "urlhelper.h"
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
#include "webshortcutmodel.h"
#include "windowcontroller.h"
#ifdef QUOTIENT_07
#include <keyverificationsession.h>
@@ -81,9 +82,9 @@
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
#include "completionmodel.h"
#include "models/completionmodel.h"
#include "models/statemodel.h"
#include "neochatuser.h"
#include "statemodel.h"
#ifdef HAVE_RUNNER
#include "runner.h"
@@ -220,6 +221,7 @@ int main(int argc, char *argv[])
qmlRegisterType<MessageEventModel>("org.kde.neochat", 1, 0, "MessageEventModel");
qmlRegisterType<CollapseStateProxyModel>("org.kde.neochat", 1, 0, "CollapseStateProxyModel");
qmlRegisterType<MessageFilterModel>("org.kde.neochat", 1, 0, "MessageFilterModel");
qmlRegisterType<UserFilterModel>("org.kde.neochat", 1, 0, "UserFilterModel");
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
qmlRegisterType<UserDirectoryListModel>("org.kde.neochat", 1, 0, "UserDirectoryListModel");
qmlRegisterType<ServerListModel>("org.kde.neochat", 1, 0, "ServerListModel");

View File

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

View File

@@ -4,8 +4,8 @@
#pragma once
#include <QAbstractListModel>
#include <memory>
#include <QRegularExpression>
#include <memory>
struct CustomEmoji {
QString name; // with :semicolons:

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2022 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#pragma once
#include <QSortFilterProxyModel>
/**
* @class UserFilterModel
*
* This class creates a custom QSortFilterProxyModel for filtering a users by either
* display name or matrix ID. The filter can accept a full matrix id i.e. example:kde.org
* to separate between accounts on different servers with similar names.
*/
class UserFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
/**
* @brief This property hold the text of the filter.
*
* The text is either a desired display name or matrix id.
*/
Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged)
public:
/**
* @brief Custom filter function checking boith the display name and matrix ID.
*
* @note The filter cannot be modified and will always use the same filter properties.
*/
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
QString filterText() const;
void setFilterText(const QString &filterText);
Q_SIGNALS:
void filterTextChanged();
private:
QString m_filterText;
};

View File

@@ -38,6 +38,7 @@ void UserListModel::setRoom(NeoChatRoom *room)
connect(m_currentRoom, &Room::userRemoved, this, &UserListModel::userRemoved);
connect(m_currentRoom, &Room::memberAboutToRename, this, &UserListModel::userRemoved);
connect(m_currentRoom, &Room::memberRenamed, this, &UserListModel::userAdded);
connect(m_currentRoom, &Room::changed, this, &UserListModel::refreshAll);
{
m_users = m_currentRoom->users();
std::sort(m_users.begin(), m_users.end(), room->memberSorter());
@@ -94,43 +95,34 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
if (role == ObjectRole) {
return QVariant::fromValue(user);
}
if (role == PermRole) {
if (role == PowerLevelRole) {
auto pl = m_currentRoom->getCurrentState<RoomPowerLevelsEvent>();
return pl->powerLevelForUser(user->id());
}
if (role == PowerLevelStringRole) {
#ifdef QUOTIENT_07
auto pl = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
#else
auto pl = m_currentRoom->getCurrentState<RoomPowerLevelsEvent>();
#endif
// User might not in the room yet, in this case pl can be nullptr.
// e.g. When invited but user not accepted or denied the invitation.
if (!pl) {
return QStringLiteral("Not Available");
}
auto userPl = pl->powerLevelForUser(user->id());
if (userPl == pl->content().usersDefault) { // Shortcut
return UserType::Member;
switch (userPl) {
case 0:
return QStringLiteral("Member");
case 50:
return QStringLiteral("Moderator");
case 100:
return QStringLiteral("Admin");
default:
return QStringLiteral("Custom");
}
if (userPl < pl->powerLevelForEvent("m.room.message")) {
return UserType::Muted;
}
auto userPls = pl->users();
int highestPl = pl->usersDefault();
QHash<QString, int>::const_iterator i = userPls.constBegin();
while (i != userPls.constEnd()) {
if (i.value() > highestPl) {
highestPl = i.value();
}
++i;
}
if (userPl == highestPl) {
return UserType::Owner;
}
if (userPl >= pl->powerLevelForState("m.room.power_levels")) {
return UserType::Admin;
}
if (userPl >= pl->ban() || userPl >= pl->kick() || userPl >= pl->redact()) {
return UserType::Moderator;
}
return UserType::Member;
}
return {};
@@ -183,6 +175,34 @@ void UserListModel::refresh(Quotient::User *user, const QVector<int> &roles)
}
}
void UserListModel::refreshAll()
{
beginResetModel();
for (User *user : std::as_const(m_users)) {
user->disconnect(this);
}
m_users.clear();
{
m_users = m_currentRoom->users();
std::sort(m_users.begin(), m_users.end(), m_currentRoom->memberSorter());
}
for (User *user : std::as_const(m_users)) {
#ifdef QUOTIENT_07
connect(user, &User::defaultAvatarChanged, this, [this, user]() {
avatarChanged(user, m_currentRoom);
});
#else
connect(user, &User::avatarChanged, this, &UserListModel::avatarChanged);
#endif
}
connect(m_currentRoom->connection(), &Connection::loggedOut, this, [this]() {
setRoom(nullptr);
});
endResetModel();
Q_EMIT usersRefreshed();
}
void UserListModel::avatarChanged(Quotient::User *user, const Quotient::Room *context)
{
if (context == m_currentRoom) {
@@ -208,7 +228,8 @@ QHash<int, QByteArray> UserListModel::roleNames() const
roles[UserIdRole] = "userId";
roles[AvatarRole] = "avatar";
roles[ObjectRole] = "user";
roles[PermRole] = "perm";
roles[PowerLevelRole] = "powerLevel";
roles[PowerLevelStringRole] = "powerLevelString";
return roles;
}

View File

@@ -3,8 +3,11 @@
#pragma once
#include <room.h>
#include <QAbstractListModel>
#include <QObject>
#include <QPointer>
class NeoChatRoom;
@@ -25,6 +28,7 @@ public:
Moderator,
Member,
Muted,
Custom,
};
Q_ENUM(Types)
};
@@ -39,7 +43,8 @@ public:
UserIdRole,
AvatarRole,
ObjectRole,
PermRole,
PowerLevelRole,
PowerLevelStringRole,
};
UserListModel(QObject *parent = nullptr);
@@ -56,15 +61,17 @@ public:
Q_SIGNALS:
void roomChanged();
void usersRefreshed();
private Q_SLOTS:
void userAdded(Quotient::User *user);
void userRemoved(Quotient::User *user);
void refresh(Quotient::User *user, const QVector<int> &roles = {});
void refreshAll();
void avatarChanged(Quotient::User *user, const Quotient::Room *context);
private:
NeoChatRoom *m_currentRoom;
QPointer<NeoChatRoom> m_currentRoom;
QList<Quotient::User *> m_users;
int findUserPos(Quotient::User *user) const;

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