Compare commits
4 Commits
work/nvrwh
...
v25.03.80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32bea56a6d | ||
|
|
661cf22667 | ||
|
|
ad1254fb71 | ||
|
|
7514a8a6f7 |
@@ -170,24 +170,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "kunifiedpush",
|
|
||||||
"buildsystem": "cmake-ninja",
|
|
||||||
"builddir": true,
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"type": "archive",
|
|
||||||
"url": "https://download.kde.org/stable/kunifiedpush/kunifiedpush-1.0.0.tar.xz",
|
|
||||||
"sha256": "2ddeba21306d0307114ec50a2c38159ec62359f9fc6cdd58da30a369fbd550cf",
|
|
||||||
"x-checker-data": {
|
|
||||||
"type": "anitya",
|
|
||||||
"project-id": 375055,
|
|
||||||
"stable-only": true,
|
|
||||||
"url-template": "https://download.kde.org/stable/kunifiedpush/kunifiedpush-$version.tar.xz"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "neochat",
|
"name": "neochat",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ include:
|
|||||||
- /gitlab-templates/linux-qt6.yml
|
- /gitlab-templates/linux-qt6.yml
|
||||||
- /gitlab-templates/linux-qt6-next.yml
|
- /gitlab-templates/linux-qt6-next.yml
|
||||||
- /gitlab-templates/windows-qt6.yml
|
- /gitlab-templates/windows-qt6.yml
|
||||||
- /gitlab-templates/freebsd-qt6.yml
|
# - /gitlab-templates/freebsd-qt6.yml
|
||||||
- /gitlab-templates/flatpak.yml
|
- /gitlab-templates/flatpak.yml
|
||||||
- /gitlab-templates/snap-snapcraft-lxd.yml
|
- /gitlab-templates/snap-snapcraft-lxd.yml
|
||||||
- /gitlab-templates/craft-android-qt6-apks.yml
|
- /gitlab-templates/craft-android-qt6-apks.yml
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ Dependencies:
|
|||||||
'require':
|
'require':
|
||||||
'frameworks/kdbusaddons': '@latest-kf6'
|
'frameworks/kdbusaddons': '@latest-kf6'
|
||||||
'frameworks/purpose': '@latest-kf6'
|
'frameworks/purpose': '@latest-kf6'
|
||||||
'libraries/kunifiedpush': '@latest-kf6'
|
|
||||||
|
|
||||||
- 'on': ['Linux']
|
- 'on': ['Linux']
|
||||||
'require':
|
'require':
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ 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 "25")
|
set(RELEASE_SERVICE_VERSION_MAJOR "25")
|
||||||
set(RELEASE_SERVICE_VERSION_MINOR "07")
|
set(RELEASE_SERVICE_VERSION_MINOR "03")
|
||||||
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})
|
||||||
|
|
||||||
set(KF_MIN_VERSION "6.12")
|
set(KF_MIN_VERSION "6.6")
|
||||||
set(QT_MIN_VERSION "6.5")
|
set(QT_MIN_VERSION "6.5")
|
||||||
|
|
||||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
@@ -56,7 +56,7 @@ ecm_setup_version(${PROJECT_VERSION}
|
|||||||
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg TextToSpeech WebView)
|
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg WebView)
|
||||||
set_package_properties(Qt6 PROPERTIES
|
set_package_properties(Qt6 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Basic application components"
|
PURPOSE "Basic application components"
|
||||||
@@ -75,7 +75,7 @@ set_package_properties(KF6Kirigami PROPERTIES
|
|||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Kirigami application UI framework"
|
PURPOSE "Kirigami application UI framework"
|
||||||
)
|
)
|
||||||
find_package(KF6KirigamiAddons 1.6.0 REQUIRED)
|
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Purpose)
|
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Purpose)
|
||||||
@@ -107,7 +107,7 @@ if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
|||||||
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(QuotientQt6 0.9.1)
|
find_package(QuotientQt6 0.9)
|
||||||
set_package_properties(QuotientQt6 PROPERTIES
|
set_package_properties(QuotientQt6 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
DESCRIPTION "Qt wrapper around Matrix API"
|
DESCRIPTION "Qt wrapper around Matrix API"
|
||||||
@@ -147,23 +147,16 @@ set_package_properties(KF6DocTools PROPERTIES DESCRIPTION
|
|||||||
TYPE OPTIONAL
|
TYPE OPTIONAL
|
||||||
)
|
)
|
||||||
|
|
||||||
option(WITH_UNIFIEDPUSH "Build with KUnifiedPush support" ON)
|
find_package(KUnifiedPush QUIET)
|
||||||
|
set_package_properties(KUnifiedPush PROPERTIES
|
||||||
if (ANDROID OR APPLE OR WIN32 OR HAIKU)
|
TYPE OPTIONAL
|
||||||
set(WITH_UNIFIEDPUSH OFF)
|
PURPOSE "Push notification support"
|
||||||
endif()
|
URL "https://invent.kde.org/libraries/kunifiedpush"
|
||||||
|
)
|
||||||
if (WITH_UNIFIEDPUSH)
|
|
||||||
find_package(KUnifiedPush)
|
|
||||||
set_package_properties(KUnifiedPush PROPERTIES
|
|
||||||
TYPE REQUIRED
|
|
||||||
PURPOSE "Push notification support"
|
|
||||||
URL "https://invent.kde.org/libraries/kunifiedpush"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
find_package(Sqlite3)
|
find_package(Sqlite3)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ki18n_install(po)
|
ki18n_install(po)
|
||||||
@@ -180,7 +173,7 @@ add_subdirectory(src)
|
|||||||
if (BUILD_TESTING)
|
if (BUILD_TESTING)
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||||
add_subdirectory(autotests)
|
add_subdirectory(autotests)
|
||||||
# add_subdirectory(appiumtests)
|
add_subdirectory(appiumtests)
|
||||||
if (NOT ANDROID)
|
if (NOT ANDROID)
|
||||||
add_subdirectory(memorytests)
|
add_subdirectory(memorytests)
|
||||||
endif()
|
endif()
|
||||||
@@ -191,7 +184,7 @@ if(KF6DocTools_FOUND)
|
|||||||
add_subdirectory(doc)
|
add_subdirectory(doc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||||
|
|
||||||
if (NOT ANDROID)
|
if (NOT ANDROID)
|
||||||
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES src/*.cpp src/*.h)
|
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES src/*.cpp src/*.h)
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ SPDX-FileCopyrightText = "2021 Carl Schwan <carlschwan@kde.org>"
|
|||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
SPDX-License-Identifier = "BSD-2-Clause"
|
||||||
|
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
path = "src/app/neochatconfig.kcfg"
|
path = "src/neochatconfig.kcfg"
|
||||||
precedence = "aggregate"
|
precedence = "aggregate"
|
||||||
SPDX-FileCopyrightText = "2020-2021 Carl Schwan <carlschwan@kde.org>, Tobias Fella <tobias.fella@kde.org>"
|
SPDX-FileCopyrightText = "2020-2021 Carl Schwan <carlschwan@kde.org>, Tobias Fella <tobias.fella@kde.org>"
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
SPDX-License-Identifier = "BSD-2-Clause"
|
||||||
|
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
path = "src/app/neochat.notifyrc"
|
path = "src/neochat.notifyrc"
|
||||||
precedence = "aggregate"
|
precedence = "aggregate"
|
||||||
SPDX-FileCopyrightText = "2020 Tobias Fella <tobias.fella@kde.org>"
|
SPDX-FileCopyrightText = "2020 Tobias Fella <tobias.fella@kde.org>"
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
SPDX-License-Identifier = "BSD-2-Clause"
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ repositories {
|
|||||||
|
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply from: '../ecm-version.gradle'
|
apply from: '../version.gradle'
|
||||||
|
def timestamp = (int)(new Date().getTime()/1000)
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||||
@@ -78,9 +79,9 @@ android {
|
|||||||
targetSdkVersion qtTargetSdkVersion
|
targetSdkVersion qtTargetSdkVersion
|
||||||
applicationId "org.kde.neochat"
|
applicationId "org.kde.neochat"
|
||||||
namespace "org.kde.neochat"
|
namespace "org.kde.neochat"
|
||||||
versionCode ecmVersionCode
|
versionCode timestamp
|
||||||
versionName ecmVersionName
|
versionName projectVersionFull
|
||||||
manifestPlaceholders = [versionName: ecmVersionName, versionCode: ecmVersionCode]
|
manifestPlaceholders = [versionName: projectVersionFull, versionCode: timestamp]
|
||||||
}
|
}
|
||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
|
|||||||
6
android/version.gradle.in
Normal file
6
android/version.gradle.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
ext {
|
||||||
|
projectVersionFull = "@NEOCHAT_VERSION@"
|
||||||
|
}
|
||||||
@@ -11,11 +11,13 @@ ecm_add_test(
|
|||||||
TEST_NAME neochatroomtest
|
TEST_NAME neochatroomtest
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_test(
|
if (NOT $ENV{KDE_CI})
|
||||||
texthandlertest.cpp
|
ecm_add_test(
|
||||||
LINK_LIBRARIES neochat Qt::Test
|
texthandlertest.cpp
|
||||||
TEST_NAME texthandlertest
|
LINK_LIBRARIES neochat Qt::Test
|
||||||
)
|
TEST_NAME texthandlertest
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
ecm_add_test(
|
ecm_add_test(
|
||||||
delegatesizehelpertest.cpp
|
delegatesizehelpertest.cpp
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"id": "option1",
|
"id": "option1",
|
||||||
"org.matrix.msc1767.text": "option1text"
|
"org.matrix.msc1767.text": "option1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "option2",
|
"id": "option2",
|
||||||
"org.matrix.msc1767.text": "option2text"
|
"org.matrix.msc1767.text": "option2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"kind": "org.matrix.msc3381.poll.undisclosed",
|
"kind": "org.matrix.msc3381.poll.disclosed",
|
||||||
"max_selections": 1,
|
"max_selections": 1,
|
||||||
"question": {
|
"question": {
|
||||||
"body": "test",
|
"body": "test",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQuickItem>
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
#include "delegatesizehelper.h"
|
#include "delegatesizehelper.h"
|
||||||
@@ -31,7 +30,7 @@ void DelegateSizeHelperTest::risingPercentage_data()
|
|||||||
QTest::addColumn<int>("currentPercentageWidth");
|
QTest::addColumn<int>("currentPercentageWidth");
|
||||||
QTest::addColumn<qreal>("currentWidth");
|
QTest::addColumn<qreal>("currentWidth");
|
||||||
|
|
||||||
QTest::newRow("zero") << qreal(0) << int(100) << qreal(0);
|
QTest::newRow("zero") << qreal(0) << int(0) << qreal(0);
|
||||||
QTest::newRow("one hundred") << qreal(100) << int(0) << qreal(0);
|
QTest::newRow("one hundred") << qreal(100) << int(0) << qreal(0);
|
||||||
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
||||||
QTest::newRow("two hundred") << qreal(200) << int(100) << qreal(200);
|
QTest::newRow("two hundred") << qreal(200) << int(100) << qreal(200);
|
||||||
@@ -44,18 +43,16 @@ void DelegateSizeHelperTest::risingPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(0);
|
delegateSizeHelper.setStartPercentWidth(0);
|
||||||
delegateSizeHelper.setEndPercentWidth(100);
|
delegateSizeHelper.setEndPercentWidth(100);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::fallingPercentage_data()
|
void DelegateSizeHelperTest::fallingPercentage_data()
|
||||||
@@ -77,18 +74,16 @@ void DelegateSizeHelperTest::fallingPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(100);
|
delegateSizeHelper.setStartPercentWidth(100);
|
||||||
delegateSizeHelper.setEndPercentWidth(0);
|
delegateSizeHelper.setEndPercentWidth(0);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::equalPercentage_data()
|
void DelegateSizeHelperTest::equalPercentage_data()
|
||||||
@@ -110,18 +105,16 @@ void DelegateSizeHelperTest::equalPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(50);
|
delegateSizeHelper.setStartPercentWidth(50);
|
||||||
delegateSizeHelper.setEndPercentWidth(50);
|
delegateSizeHelper.setEndPercentWidth(50);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::equalBreakpoint_data()
|
void DelegateSizeHelperTest::equalBreakpoint_data()
|
||||||
@@ -131,9 +124,9 @@ void DelegateSizeHelperTest::equalBreakpoint_data()
|
|||||||
QTest::addColumn<int>("currentPercentageWidth");
|
QTest::addColumn<int>("currentPercentageWidth");
|
||||||
QTest::addColumn<qreal>("currentWidth");
|
QTest::addColumn<qreal>("currentWidth");
|
||||||
|
|
||||||
QTest::newRow("start higher") << int(100) << int(0) << int(100) << qreal(1000);
|
QTest::newRow("start higher") << int(100) << int(0) << int(-1) << qreal(0);
|
||||||
QTest::newRow("equal") << int(50) << int(50) << int(50) << qreal(500);
|
QTest::newRow("equal") << int(50) << int(50) << int(50) << qreal(500);
|
||||||
QTest::newRow("end higher") << int(0) << int(100) << int(100) << qreal(1000);
|
QTest::newRow("end higher") << int(0) << int(100) << int(-1) << qreal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,18 +140,16 @@ void DelegateSizeHelperTest::equalBreakpoint()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(1000);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(100);
|
delegateSizeHelper.setEndBreakpoint(100);
|
||||||
delegateSizeHelper.setStartPercentWidth(startPercentageWidth);
|
delegateSizeHelper.setStartPercentWidth(startPercentageWidth);
|
||||||
delegateSizeHelper.setEndPercentWidth(endPercentageWidth);
|
delegateSizeHelper.setEndPercentWidth(endPercentageWidth);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(1000);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(DelegateSizeHelperTest)
|
QTEST_GUILESS_MAIN(DelegateSizeHelperTest)
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ private Q_SLOTS:
|
|||||||
void MediaSizeHelperTest::uninitialized()
|
void MediaSizeHelperTest::uninitialized()
|
||||||
{
|
{
|
||||||
MediaSizeHelper mediasizehelper;
|
MediaSizeHelper mediasizehelper;
|
||||||
mediasizehelper.setMaxSize(540, 540);
|
|
||||||
QCOMPARE(mediasizehelper.currentSize(), QSize(540, qRound(qreal(NeoChatConfig::self()->mediaMaxWidth()) / qreal(16.0) * qreal(9.0))));
|
QCOMPARE(mediasizehelper.currentSize(), QSize(540, qRound(qreal(NeoChatConfig::self()->mediaMaxWidth()) / qreal(16.0) * qreal(9.0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ void MediaSizeHelperTest::limits()
|
|||||||
QFETCH(QSize, currentSize);
|
QFETCH(QSize, currentSize);
|
||||||
|
|
||||||
MediaSizeHelper mediasizehelper;
|
MediaSizeHelper mediasizehelper;
|
||||||
mediasizehelper.setMaxSize(540, 540);
|
|
||||||
mediasizehelper.setMediaWidth(mediaWidth);
|
mediasizehelper.setMediaWidth(mediaWidth);
|
||||||
mediasizehelper.setMediaHeight(mediaHeight);
|
mediasizehelper.setMediaHeight(mediaHeight);
|
||||||
mediasizehelper.setContentMaxWidth(contentMaxWidth);
|
mediasizehelper.setContentMaxWidth(contentMaxWidth);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "models/messagecontentmodel.h"
|
#include "models/messagecontentmodel.h"
|
||||||
|
|
||||||
#include "neochatconnection.h"
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
@@ -33,7 +32,7 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void MessageContentModelTest::initTestCase()
|
void MessageContentModelTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = new NeoChatConnection;
|
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageContentModelTest::missingEvent()
|
void MessageContentModelTest::missingEvent()
|
||||||
|
|||||||
@@ -41,32 +41,29 @@ void PollHandlerTest::nullObject()
|
|||||||
auto pollHandler = PollHandler();
|
auto pollHandler = PollHandler();
|
||||||
|
|
||||||
QCOMPARE(pollHandler.hasEnded(), false);
|
QCOMPARE(pollHandler.hasEnded(), false);
|
||||||
QCOMPARE(pollHandler.numAnswers(), 0);
|
QCOMPARE(pollHandler.answerCount(), 0);
|
||||||
QCOMPARE(pollHandler.question(), QString());
|
QCOMPARE(pollHandler.question(), QString());
|
||||||
QCOMPARE(pollHandler.kind(), PollKind::Disclosed);
|
QCOMPARE(pollHandler.options(), QJsonArray());
|
||||||
|
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||||
|
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||||
|
QCOMPARE(pollHandler.kind(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollHandlerTest::poll()
|
void PollHandlerTest::poll()
|
||||||
{
|
{
|
||||||
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
||||||
auto pollHandler = PollHandler(room, startEvent->id());
|
auto pollHandler = PollHandler(room, startEvent);
|
||||||
|
|
||||||
QList<Quotient::EventContent::Answer> options = {EventContent::Answer{"option1"_L1, "option1"_L1}, EventContent::Answer{"option2"_L1, "option2"_L1}};
|
auto options = QJsonArray{QJsonObject{{"id"_L1, "option1"_L1}, {"org.matrix.msc1767.text"_L1, "option1"_L1}},
|
||||||
|
QJsonObject{{"id"_L1, "option2"_L1}, {"org.matrix.msc1767.text"_L1, "option2"_L1}}};
|
||||||
|
|
||||||
const auto answer0 = pollHandler.answerAtRow(0);
|
|
||||||
const auto answer1 = pollHandler.answerAtRow(1);
|
|
||||||
QCOMPARE(pollHandler.hasEnded(), false);
|
QCOMPARE(pollHandler.hasEnded(), false);
|
||||||
QCOMPARE(pollHandler.numAnswers(), 2);
|
QCOMPARE(pollHandler.answerCount(), 0);
|
||||||
QCOMPARE(pollHandler.question(), u"test"_s);
|
QCOMPARE(pollHandler.question(), u"test"_s);
|
||||||
QCOMPARE(answer0.id, "option1"_L1);
|
QCOMPARE(pollHandler.options(), options);
|
||||||
QCOMPARE(answer1.id, "option2"_L1);
|
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||||
QCOMPARE(answer0.text, "option1text"_L1);
|
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||||
QCOMPARE(answer1.text, "option2text"_L1);
|
QCOMPARE(pollHandler.kind(), u"org.matrix.msc3381.poll.disclosed"_s);
|
||||||
QCOMPARE(pollHandler.answerCountAtId(answer0.id), 0);
|
|
||||||
QCOMPARE(pollHandler.answerCountAtId(answer1.id), 0);
|
|
||||||
QCOMPARE(pollHandler.checkMemberSelectedId(connection->userId(), answer0.id), false);
|
|
||||||
QCOMPARE(pollHandler.checkMemberSelectedId(connection->userId(), answer1.id), false);
|
|
||||||
QCOMPARE(pollHandler.kind(), PollKind::Undisclosed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(PollHandlerTest)
|
QTEST_GUILESS_MAIN(PollHandlerTest)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <Quotient/events/roommessageevent.h>
|
#include <Quotient/events/roommessageevent.h>
|
||||||
|
|
||||||
#include "models/messagecontentmodel.h"
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#include <Quotient/quotient_common.h>
|
#include <Quotient/quotient_common.h>
|
||||||
#include <Quotient/syncdata.h>
|
#include <Quotient/syncdata.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
#include <Kirigami/Platform/PlatformTheme>
|
|
||||||
|
|
||||||
#include "enums/messagecomponenttype.h"
|
#include "enums/messagecomponenttype.h"
|
||||||
#include "models/customemojimodel.h"
|
#include "models/customemojimodel.h"
|
||||||
@@ -44,8 +43,6 @@ private Q_SLOTS:
|
|||||||
void sendCustomEmoji();
|
void sendCustomEmoji();
|
||||||
void sendCustomEmojiCode_data();
|
void sendCustomEmojiCode_data();
|
||||||
void sendCustomEmojiCode();
|
void sendCustomEmojiCode();
|
||||||
void sendCustomTags_data();
|
|
||||||
void sendCustomTags();
|
|
||||||
|
|
||||||
void receiveSpacelessSelfClosingTag();
|
void receiveSpacelessSelfClosingTag();
|
||||||
void receiveStripReply();
|
void receiveStripReply();
|
||||||
@@ -252,38 +249,6 @@ void TextHandlerTest::sendCustomEmojiCode()
|
|||||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::sendCustomTags_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("testInputString");
|
|
||||||
QTest::addColumn<QString>("testOutputString");
|
|
||||||
|
|
||||||
// spoiler
|
|
||||||
QTest::newRow("incomplete spoiler") << u"||test"_s << u"||test"_s;
|
|
||||||
QTest::newRow("complete spoiler") << u"||test||"_s << u"<span data-mx-spoiler>test</span>"_s;
|
|
||||||
QTest::newRow("multiple spoiler") << u"||apple||banana||pear||"_s << u"<span data-mx-spoiler>apple</span>banana<span data-mx-spoiler>pear</span>"_s;
|
|
||||||
QTest::newRow("inside code block spoiler") << u"```||apple||```"_s << u"<code>||apple||</code>"_s;
|
|
||||||
QTest::newRow("outside code block spoiler") << u"||apple|| ```||banana||``` ||pear||"_s
|
|
||||||
<< u"<span data-mx-spoiler>apple</span> <code>||banana||</code> <span data-mx-spoiler>pear</span>"_s;
|
|
||||||
|
|
||||||
// strikethrough
|
|
||||||
QTest::newRow("incomplete strikethrough") << u"~~test"_s << u"~~test"_s;
|
|
||||||
QTest::newRow("complete strikethrough") << u"~~test~~"_s << u"<del>test</del>"_s;
|
|
||||||
QTest::newRow("inside code block strikethrough") << u"```~~apple~~```"_s << u"<code>~~apple~~</code>"_s;
|
|
||||||
QTest::newRow("outside code block strikethrough") << u"~~apple~~ ```~~banana~~``` ~~pear~~"_s
|
|
||||||
<< u"<del>apple</del> <code>~~banana~~</code> <del>pear</del>"_s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextHandlerTest::sendCustomTags()
|
|
||||||
{
|
|
||||||
QFETCH(QString, testInputString);
|
|
||||||
QFETCH(QString, testOutputString);
|
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
|
||||||
testTextHandler.setData(testInputString);
|
|
||||||
|
|
||||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"Test...<br/>...ing"_s;
|
const QString testInputString = u"Test...<br/>...ing"_s;
|
||||||
@@ -503,12 +468,9 @@ void TextHandlerTest::receiveRichEdited_data()
|
|||||||
QTest::addColumn<QString>("testInputString");
|
QTest::addColumn<QString>("testInputString");
|
||||||
QTest::addColumn<QString>("testOutputString");
|
QTest::addColumn<QString>("testOutputString");
|
||||||
|
|
||||||
auto theme = static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
QTest::newRow("basic") << u"Edited"_s << u"Edited <span style=\"color:#000000\">(edited)</span>"_s;
|
||||||
|
|
||||||
QTest::newRow("basic") << u"Edited"_s << u"Edited <span style=\"color:%1\">(edited)</span>"_s.arg(theme ? theme->disabledTextColor().name() : u"#000000"_s);
|
|
||||||
QTest::newRow("multiple paragraphs") << u"<p>Edited</p>\n<p>Edited</p>"_s
|
QTest::newRow("multiple paragraphs") << u"<p>Edited</p>\n<p>Edited</p>"_s
|
||||||
<< u"<p>Edited</p>\n<p>Edited <span style=\"color:%1\">(edited)</span></p>"_s.arg(
|
<< u"<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>"_s;
|
||||||
theme ? theme->disabledTextColor().name() : u"#000000"_s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichEdited()
|
void TextHandlerTest::receiveRichEdited()
|
||||||
@@ -549,6 +511,8 @@ void TextHandlerTest::receiveRichColor()
|
|||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
|
|
||||||
|
qInfo() << testTextHandler.handleRecieveRichText();
|
||||||
|
|
||||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,9 +530,6 @@ void TextHandlerTest::componentOutput_data()
|
|||||||
QTest::newRow("quote") << u"<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>"_s
|
QTest::newRow("quote") << u"<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>"_s
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||||
MessageComponent{MessageComponentType::Quote, u"“blockquote”"_s, {}}};
|
MessageComponent{MessageComponentType::Quote, u"“blockquote”"_s, {}}};
|
||||||
QTest::newRow("multiple paragraph quote") << u"<blockquote>\n<p>blockquote</p>\n<p>next paragraph</p>\n</blockquote>"_s
|
|
||||||
<< QList<MessageComponent>{
|
|
||||||
MessageComponent{MessageComponentType::Quote, u"<p>“blockquote</p>\n<p>next paragraph”</p>"_s, {}}};
|
|
||||||
QTest::newRow("no tag first paragraph") << u"Text\n<p>Text</p>"_s
|
QTest::newRow("no tag first paragraph") << u"Text\n<p>Text</p>"_s
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
||||||
|
|||||||
@@ -7,19 +7,16 @@ qt_add_executable(timeline-memtest
|
|||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(timeline-memtest PRIVATE neochatplugin Timelineplugin)
|
target_link_libraries(timeline-memtest PRIVATE neochatplugin timelineplugin)
|
||||||
target_link_libraries(timeline-memtest PUBLIC
|
target_link_libraries(timeline-memtest PUBLIC
|
||||||
Qt::Core
|
Qt::Core
|
||||||
Qt::Quick
|
Qt::Quick
|
||||||
Qt::Qml
|
Qt::Qml
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
Qt::QuickControls2
|
Qt::QuickControls2
|
||||||
Qt::Widgets
|
|
||||||
KF6::I18nQml
|
|
||||||
KF6::Kirigami
|
KF6::Kirigami
|
||||||
QuotientQt6
|
QuotientQt6
|
||||||
LibNeoChat
|
neochat
|
||||||
Timeline
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_qml_module(timeline-memtest URI org.kde.neochat.timeline-memtest GENERATE_PLUGIN_SOURCE
|
ecm_add_qml_module(timeline-memtest URI org.kde.neochat.timeline-memtest GENERATE_PLUGIN_SOURCE
|
||||||
@@ -33,5 +30,5 @@ ecm_add_qml_module(timeline-memtest URI org.kde.neochat.timeline-memtest GENERAT
|
|||||||
QtCore
|
QtCore
|
||||||
QtQuick
|
QtQuick
|
||||||
IMPORTS
|
IMPORTS
|
||||||
org.kde.neochat.timeline
|
org.kde.neochat
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ QQC2.ApplicationWindow {
|
|||||||
height: root.height
|
height: root.height
|
||||||
|
|
||||||
contentItem: ListView {
|
contentItem: ListView {
|
||||||
cacheBuffer: 1000000
|
|
||||||
model: messageFilterModel
|
model: messageFilterModel
|
||||||
|
|
||||||
delegate: EventDelegate {
|
delegate: EventDelegate {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
|
||||||
#include <KLocalizedQmlContext>
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
#include "memtesttimelinemodel.h"
|
#include "memtesttimelinemodel.h"
|
||||||
@@ -20,15 +19,12 @@ int main(int argc, char **argv)
|
|||||||
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
|
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");
|
||||||
KLocalization::setupLocalizedContext(&engine);
|
|
||||||
|
|
||||||
MemTestTimelineModel *memTestTimelineModel = new MemTestTimelineModel;
|
MemTestTimelineModel *memTestTimelineModel = new MemTestTimelineModel;
|
||||||
MessageFilterModel *messageFilterModel = new MessageFilterModel(nullptr, memTestTimelineModel);
|
MessageFilterModel *messageFilterModel = new MessageFilterModel(nullptr, memTestTimelineModel);
|
||||||
engine.rootContext()->setContextProperty(u"memTestTimelineModel"_s, memTestTimelineModel);
|
engine.rootContext()->setContextProperty(u"memTestTimelineModel"_s, memTestTimelineModel);
|
||||||
engine.rootContext()->setContextProperty(u"messageFilterModel"_s, messageFilterModel);
|
engine.rootContext()->setContextProperty(u"messageFilterModel"_s, messageFilterModel);
|
||||||
|
|
||||||
engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,7 +241,7 @@
|
|||||||
"formatted_body": "This is an example<br>text message",
|
"formatted_body": "This is an example<br>text message",
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
},
|
},
|
||||||
"event_id": 0,
|
"event_id": "$1000000000000:example.org",
|
||||||
"origin_server_ts": 1000000000000,
|
"origin_server_ts": 1000000000000,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@example:example.org",
|
"sender": "@example:example.org",
|
||||||
@@ -255,7 +255,7 @@
|
|||||||
"body": "This is a highlight @bob:example.org",
|
"body": "This is a highlight @bob:example.org",
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
},
|
},
|
||||||
"event_id": 1,
|
"event_id": "$1000000000001:example.org",
|
||||||
"origin_server_ts": 1000000000001,
|
"origin_server_ts": 1000000000001,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@example:example.org",
|
"sender": "@example:example.org",
|
||||||
@@ -266,11 +266,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"content": {
|
"content": {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"event_id": 1,
|
"event_id": "$1000000000001:example.org",
|
||||||
"key": "👍",
|
"key": "👍",
|
||||||
"rel_type": "m.annotation"
|
"rel_type": "m.annotation"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"origin_server_ts": 1000000000002,
|
"origin_server_ts": 1000000000002,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
"unsigned": {
|
"unsigned": {
|
||||||
"age": 390159120
|
"age": 390159120
|
||||||
},
|
},
|
||||||
"event_id": 2,
|
"event_id": "$1000000000002:example.org",
|
||||||
"age": 390159120
|
"age": 390159120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -289,7 +289,7 @@
|
|||||||
"formatted_body": "reply",
|
"formatted_body": "reply",
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"m.in_reply_to": {
|
"m.in_reply_to": {
|
||||||
"event_id": 0
|
"event_id": "$1000000000000:example.org"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
@@ -300,7 +300,7 @@
|
|||||||
"unsigned": {
|
"unsigned": {
|
||||||
"age": 98
|
"age": 98
|
||||||
},
|
},
|
||||||
"event_id": 3,
|
"event_id": "$1000000000003:example.org",
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@
|
|||||||
"uri": "geo:51.7035,-1.14394"
|
"uri": "geo:51.7035,-1.14394"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"event_id": 4,
|
"event_id": "$1000000000004:example.org",
|
||||||
"origin_server_ts": 1000000000004,
|
"origin_server_ts": 1000000000004,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@example:example.org",
|
"sender": "@example:example.org",
|
||||||
@@ -333,7 +333,7 @@
|
|||||||
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");\n\n return app.exec();\n}\n</code></pre>",
|
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");\n\n return app.exec();\n}\n</code></pre>",
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
},
|
},
|
||||||
"event_id": 5,
|
"event_id": "$1000000000005:example.org",
|
||||||
"origin_server_ts": 1000000000005,
|
"origin_server_ts": 1000000000005,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@bob:example.org",
|
"sender": "@bob:example.org",
|
||||||
@@ -347,7 +347,7 @@
|
|||||||
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
},
|
},
|
||||||
"event_id": 6,
|
"event_id": "$1000000000006:example.org",
|
||||||
"origin_server_ts": 1000000000006,
|
"origin_server_ts": 1000000000006,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@example:example.org",
|
"sender": "@example:example.org",
|
||||||
@@ -363,7 +363,7 @@
|
|||||||
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
|
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
},
|
},
|
||||||
"event_id": 7,
|
"event_id": "$1000000000007:example.org",
|
||||||
"origin_server_ts": 1000000000007,
|
"origin_server_ts": 1000000000007,
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
"sender": "@example:example.org",
|
"sender": "@example:example.org",
|
||||||
@@ -371,6 +371,282 @@
|
|||||||
"unsigned": {
|
"unsigned": {
|
||||||
"age": 1232
|
"age": 1232
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "This is an example text message",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "This is an example<br>text message",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000008:example.org",
|
||||||
|
"origin_server_ts": 1000000000008,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "This is a highlight @bob:example.org",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000009:example.org",
|
||||||
|
"origin_server_ts": 1000000000009,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1233
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"m.relates_to": {
|
||||||
|
"event_id": "$1000000000009:example.org",
|
||||||
|
"key": "👍",
|
||||||
|
"rel_type": "m.annotation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1000000000010,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@alice:example.org",
|
||||||
|
"type": "m.reaction",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 390159120
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000010:example.org",
|
||||||
|
"age": 390159120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "reply",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "reply",
|
||||||
|
"m.relates_to": {
|
||||||
|
"m.in_reply_to": {
|
||||||
|
"event_id": "$1000000000008:example.org"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1000000000011,
|
||||||
|
"sender": "@alice:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 98
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000011:example.org",
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"age": 96845207,
|
||||||
|
"content": {
|
||||||
|
"body": "Lat: 51.7035, Lon: -1.14394",
|
||||||
|
"geo_uri": "geo:51.7035,-1.14394",
|
||||||
|
"msgtype": "m.location",
|
||||||
|
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
|
||||||
|
"org.matrix.msc3488.asset": {
|
||||||
|
"type": "m.pin"
|
||||||
|
},
|
||||||
|
"org.matrix.msc3488.location": {
|
||||||
|
"uri": "geo:51.7035,-1.14394"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000012:example.org",
|
||||||
|
"origin_server_ts": 1000000000012,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 96845207
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");\n\n return app.exec();\n}\n</code></pre>",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000013:example.org",
|
||||||
|
"origin_server_ts": 1000000000013,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@bob:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1233
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000014:example.org",
|
||||||
|
"origin_server_ts": 1000000000014,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000015:example.org",
|
||||||
|
"origin_server_ts": 1000000000015,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "This is an example text message",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "This is an example<br>text message",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000016:example.org",
|
||||||
|
"origin_server_ts": 1000000000016,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "This is a highlight @bob:example.org",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000017:example.org",
|
||||||
|
"origin_server_ts": 1000000000017,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1233
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"m.relates_to": {
|
||||||
|
"event_id": "$1000000000017:example.org",
|
||||||
|
"key": "👍",
|
||||||
|
"rel_type": "m.annotation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1000000000018,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@alice:example.org",
|
||||||
|
"type": "m.reaction",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 390159120
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000018:example.org",
|
||||||
|
"age": 390159120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "reply",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "reply",
|
||||||
|
"m.relates_to": {
|
||||||
|
"m.in_reply_to": {
|
||||||
|
"event_id": "$1000000000016:example.org"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1000000000019,
|
||||||
|
"sender": "@alice:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 98
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000019:example.org",
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"age": 96845207,
|
||||||
|
"content": {
|
||||||
|
"body": "Lat: 51.7035, Lon: -1.14394",
|
||||||
|
"geo_uri": "geo:51.7035,-1.14394",
|
||||||
|
"msgtype": "m.location",
|
||||||
|
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
|
||||||
|
"org.matrix.msc3488.asset": {
|
||||||
|
"type": "m.pin"
|
||||||
|
},
|
||||||
|
"org.matrix.msc3488.location": {
|
||||||
|
"uri": "geo:51.7035,-1.14394"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000020:example.org",
|
||||||
|
"origin_server_ts": 1000000000020,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 96845207
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");\n\n return app.exec();\n}\n</code></pre>",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000021:example.org",
|
||||||
|
"origin_server_ts": 1000000000021,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@bob:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1233
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000022:example.org",
|
||||||
|
"origin_server_ts": 1000000000022,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$1000000000023:example.org",
|
||||||
|
"origin_server_ts": 1000000000023,
|
||||||
|
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||||
|
"sender": "@example:example.org",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1232
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"limited": true,
|
"limited": true,
|
||||||
|
|||||||
@@ -39,52 +39,10 @@ public:
|
|||||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
|
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
|
||||||
testSyncFile.open(QIODevice::ReadOnly);
|
testSyncFile.open(QIODevice::ReadOnly);
|
||||||
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()).object();
|
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()).object();
|
||||||
auto timelineJson = testSyncJson["timeline"_L1].toObject();
|
|
||||||
timelineJson["events"_L1] = multiplyEvents(timelineJson["events"_L1].toArray(), 100);
|
|
||||||
testSyncJson["timeline"_L1] = timelineJson;
|
|
||||||
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson);
|
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson);
|
||||||
update(std::move(roomData));
|
update(std::move(roomData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray multiplyEvents(QJsonArray events, int factor)
|
|
||||||
{
|
|
||||||
QJsonArray newArray;
|
|
||||||
int eventNum = 0;
|
|
||||||
int ts = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < factor; ++i) {
|
|
||||||
for (const auto &event : events) {
|
|
||||||
auto eventObject = event.toObject();
|
|
||||||
auto contentJson = eventObject["content"_L1].toObject();
|
|
||||||
if (contentJson.contains("m.relates_to"_L1)) {
|
|
||||||
auto relatesToJson = contentJson["m.relates_to"_L1].toObject();
|
|
||||||
if (relatesToJson.contains("m.in_reply_to"_L1)) {
|
|
||||||
auto replyJson = relatesToJson["m.in_reply_to"_L1].toObject();
|
|
||||||
const auto currentId = eventObject["event_id"_L1].toInt();
|
|
||||||
const auto currentReplyId = replyJson["event_id"_L1].toInt();
|
|
||||||
replyJson["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum - (currentId - currentReplyId)));
|
|
||||||
relatesToJson["m.in_reply_to"_L1] = replyJson;
|
|
||||||
} else if (relatesToJson.contains("event_id"_L1)) {
|
|
||||||
const auto currentId = eventObject["event_id"_L1].toInt();
|
|
||||||
const auto currentRelationId = relatesToJson["event_id"_L1].toInt();
|
|
||||||
relatesToJson["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum - (currentId - currentRelationId)));
|
|
||||||
}
|
|
||||||
contentJson["m.relates_to"_L1] = relatesToJson;
|
|
||||||
eventObject["content"_L1] = contentJson;
|
|
||||||
}
|
|
||||||
eventObject["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum));
|
|
||||||
eventObject["origin_server_ts"_L1] = ts;
|
|
||||||
auto unsignedJson = eventObject["unsigned"_L1].toObject();
|
|
||||||
unsignedJson["age"_L1] = ts;
|
|
||||||
eventObject["unsigned"_L1] = unsignedJson;
|
|
||||||
newArray.append(eventObject);
|
|
||||||
++eventNum;
|
|
||||||
++ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newArray;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -70,12 +70,10 @@
|
|||||||
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
||||||
<summary xml:lang="it">Chat su Matrix</summary>
|
<summary xml:lang="it">Chat su Matrix</summary>
|
||||||
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
|
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
|
||||||
<summary xml:lang="ko">Matrix에서 대화하기</summary>
|
|
||||||
<summary xml:lang="lv">Tērzējiet „Matrix“ tīklā</summary>
|
<summary xml:lang="lv">Tērzējiet „Matrix“ tīklā</summary>
|
||||||
<summary xml:lang="nl">Chat op Matrix</summary>
|
<summary xml:lang="nl">Chat op Matrix</summary>
|
||||||
<summary xml:lang="nn">Prat med via Matrix</summary>
|
<summary xml:lang="nn">Prat med via Matrix</summary>
|
||||||
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
|
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
|
||||||
<summary xml:lang="ru">Общение в Matrix</summary>
|
|
||||||
<summary xml:lang="sa">Matrix इत्यत्र गपशपं कुर्वन्तु</summary>
|
<summary xml:lang="sa">Matrix इत्यत्र गपशपं कुर्वन्तु</summary>
|
||||||
<summary xml:lang="sl">Klepet na Matrixu</summary>
|
<summary xml:lang="sl">Klepet na Matrixu</summary>
|
||||||
<summary xml:lang="sv">Chatta på Matrix</summary>
|
<summary xml:lang="sv">Chatta på Matrix</summary>
|
||||||
@@ -104,7 +102,6 @@
|
|||||||
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
||||||
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
||||||
<p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p>
|
<p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p>
|
||||||
<p xml:lang="ko">NeoChat은 Matrix 네트워크를 사용하는 채팅 앱입니다. 텍스트 메시지, 동영상, 오디오 파일을 가족, 친구, 동료와 안전하게 공유할 수 있습니다.</p>
|
|
||||||
<p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p>
|
<p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p>
|
||||||
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
|
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
|
||||||
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
|
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
|
||||||
@@ -375,7 +372,6 @@
|
|||||||
<caption xml:lang="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
|
<caption xml:lang="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
|
||||||
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
|
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
|
||||||
<caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption>
|
<caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption>
|
||||||
<caption xml:lang="ko">Matrix 스페이스에서 새로운 커뮤니티 탐험</caption>
|
|
||||||
<caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption>
|
<caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption>
|
||||||
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
|
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
|
||||||
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
|
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
|
||||||
@@ -477,8 +473,6 @@
|
|||||||
<content_attribute id="social-chat">intense</content_attribute>
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
</content_rating>
|
</content_rating>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="25.04.1" date="2025-05-08"/>
|
|
||||||
<release version="25.04.0" date="2025-04-17"/>
|
|
||||||
<release version="24.12.3" date="2025-03-06"/>
|
<release version="24.12.3" date="2025-03-06"/>
|
||||||
<release version="24.12.2" date="2025-02-06"/>
|
<release version="24.12.2" date="2025-02-06"/>
|
||||||
<release version="24.12.1" date="2025-01-09"/>
|
<release version="24.12.1" date="2025-01-09"/>
|
||||||
|
|||||||
@@ -109,12 +109,10 @@ Comment[hu]=Csevegés Matrixon
|
|||||||
Comment[ia]=Conversation en ditecto sur Matrix
|
Comment[ia]=Conversation en ditecto sur Matrix
|
||||||
Comment[it]= su Matrix
|
Comment[it]= su Matrix
|
||||||
Comment[ka]=ჩატი Matrix-ზე
|
Comment[ka]=ჩატი Matrix-ზე
|
||||||
Comment[ko]=Matrix에서 대화하기
|
|
||||||
Comment[lv]=Tērzējiet „Matrix“ tīklā
|
Comment[lv]=Tērzējiet „Matrix“ tīklā
|
||||||
Comment[nl]=Chat op Matrix
|
Comment[nl]=Chat op Matrix
|
||||||
Comment[pl]=Rozmawiaj na Matriksie
|
Comment[pl]=Rozmawiaj na Matriksie
|
||||||
Comment[pt_BR]=Bate papo na Matrix
|
Comment[pt_BR]=Bate papo na Matrix
|
||||||
Comment[ru]=Общение в Matrix
|
|
||||||
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
||||||
Comment[sl]=Klepet na Matrixu
|
Comment[sl]=Klepet na Matrixu
|
||||||
Comment[sv]=Chatta på Matrix
|
Comment[sv]=Chatta på Matrix
|
||||||
|
|||||||
6846
po/ar/neochat.po
6846
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
6660
po/ast/neochat.po
6660
po/ast/neochat.po
File diff suppressed because it is too large
Load Diff
7451
po/az/neochat.po
7451
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
6889
po/ca/neochat.po
6889
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6738
po/cs/neochat.po
6738
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
7066
po/da/neochat.po
7066
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
7006
po/de/neochat.po
7006
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
7074
po/el/neochat.po
7074
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
6944
po/en_GB/neochat.po
6944
po/en_GB/neochat.po
File diff suppressed because it is too large
Load Diff
6846
po/eo/neochat.po
6846
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
6870
po/es/neochat.po
6870
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
6876
po/eu/neochat.po
6876
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
6853
po/fi/neochat.po
6853
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
6930
po/fr/neochat.po
6930
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
6907
po/gl/neochat.po
6907
po/gl/neochat.po
File diff suppressed because it is too large
Load Diff
6373
po/he/neochat.po
6373
po/he/neochat.po
File diff suppressed because it is too large
Load Diff
6872
po/hi/neochat.po
6872
po/hi/neochat.po
File diff suppressed because it is too large
Load Diff
6984
po/hu/neochat.po
6984
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
6900
po/ia/neochat.po
6900
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
7335
po/id/neochat.po
7335
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
7179
po/ie/neochat.po
7179
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
6910
po/it/neochat.po
6910
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
6642
po/ja/neochat.po
6642
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
6824
po/ka/neochat.po
6824
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
7876
po/ko/neochat.po
7876
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
6704
po/lt/neochat.po
6704
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
6876
po/lv/neochat.po
6876
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
6901
po/nl/neochat.po
6901
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
6834
po/nn/neochat.po
6834
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
7379
po/pa/neochat.po
7379
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
6930
po/pl/neochat.po
6930
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
7357
po/pt/neochat.po
7357
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
7418
po/pt_BR/neochat.po
7418
po/pt_BR/neochat.po
File diff suppressed because it is too large
Load Diff
7671
po/ru/neochat.po
7671
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
6840
po/sa/neochat.po
6840
po/sa/neochat.po
File diff suppressed because it is too large
Load Diff
7323
po/sk/neochat.po
7323
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
6872
po/sl/neochat.po
6872
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
6883
po/sv/neochat.po
6883
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
6856
po/ta/neochat.po
6856
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
7080
po/tok/neochat.po
7080
po/tok/neochat.po
File diff suppressed because it is too large
Load Diff
6901
po/tr/neochat.po
6901
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
6935
po/uk/neochat.po
6935
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
6698
po/zh_CN/neochat.po
6698
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
6760
po/zh_TW/neochat.po
6760
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2024-2025 Scarlett Moore <sgmoore@kde.org>
|
# SPDX-FileCopyrightText: 2024 Scarlett Moore <sgmoore@kde.org>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
---
|
---
|
||||||
@@ -24,9 +24,6 @@ apps:
|
|||||||
- network-manager-observe
|
- network-manager-observe
|
||||||
- password-manager-service
|
- password-manager-service
|
||||||
- accounts-service
|
- accounts-service
|
||||||
environment:
|
|
||||||
QT_PLUGIN_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/plugins/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/plugins"
|
|
||||||
QML_IMPORT_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml:/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml"
|
|
||||||
|
|
||||||
compression: lzo
|
compression: lzo
|
||||||
|
|
||||||
@@ -44,12 +41,11 @@ parts:
|
|||||||
olm:
|
olm:
|
||||||
source: https://gitlab.matrix.org/matrix-org/olm.git
|
source: https://gitlab.matrix.org/matrix-org/olm.git
|
||||||
source-depth: 1
|
source-depth: 1
|
||||||
source-tag: '3.2.16'
|
source-tag: '3.2.12'
|
||||||
plugin: cmake
|
plugin: cmake
|
||||||
cmake-parameters:
|
cmake-parameters:
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
|
||||||
prime:
|
prime:
|
||||||
- -usr/include
|
- -usr/include
|
||||||
- -usr/lib/*/pkgconfig
|
- -usr/lib/*/pkgconfig
|
||||||
@@ -85,7 +81,8 @@ parts:
|
|||||||
plugin: cmake
|
plugin: cmake
|
||||||
build-environment:
|
build-environment:
|
||||||
- PATH: /snap/bin:${PATH}
|
- PATH: /snap/bin:${PATH}
|
||||||
- PKG_CONFIG_PATH: "$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH"
|
- PKG_CONFIG_PATH: "$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET\
|
||||||
|
/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
cmake-parameters:
|
cmake-parameters:
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
@@ -101,7 +98,7 @@ parts:
|
|||||||
- olm
|
- olm
|
||||||
- qtkeychain
|
- qtkeychain
|
||||||
source: https://github.com/quotient-im/libQuotient.git
|
source: https://github.com/quotient-im/libQuotient.git
|
||||||
source-tag: 0.9.2
|
source-tag: 0.9.1
|
||||||
source-depth: 1
|
source-depth: 1
|
||||||
plugin: cmake
|
plugin: cmake
|
||||||
build-environment:
|
build-environment:
|
||||||
@@ -140,24 +137,11 @@ parts:
|
|||||||
- -usr/lib/*/pkgconfig
|
- -usr/lib/*/pkgconfig
|
||||||
- -usr/lib/*/cmake
|
- -usr/lib/*/cmake
|
||||||
|
|
||||||
kunifiedpush:
|
|
||||||
source: https://invent.kde.org/libraries/kunifiedpush.git
|
|
||||||
plugin: cmake
|
|
||||||
build-environment:
|
|
||||||
- PATH: /snap/bin:${PATH}
|
|
||||||
- PYTHONPATH: ${CRAFT_STAGE}/lib/python3.12/site-packages:${CRAFT_STAGE}/usr/lib/python3/dist-packages
|
|
||||||
- LD_LIBRARY_PATH: "/snap/mesa-2404/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/kde-qt6-core24-sdk/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$LD_LIBRARY_PATH"
|
|
||||||
cmake-parameters:
|
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
|
||||||
- -DBUILD_TESTING=OFF
|
|
||||||
|
|
||||||
neochat:
|
neochat:
|
||||||
after:
|
after:
|
||||||
- qtkeychain
|
- qtkeychain
|
||||||
- libquotient
|
- libquotient
|
||||||
- kquickimageeditor
|
- kquickimageeditor
|
||||||
- kunifiedpush
|
|
||||||
parse-info:
|
parse-info:
|
||||||
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
||||||
source: .
|
source: .
|
||||||
|
|||||||
@@ -1,16 +1,580 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
# SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carl@carlschwan.eu>
|
||||||
|
# SPDX-FileCopyrightText: 2020-2021 Nicolas Fella <nicolas.fella@gmx.de>
|
||||||
|
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
||||||
add_subdirectory(purpose)
|
add_subdirectory(purpose)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(libneochat)
|
add_library(neochat STATIC
|
||||||
add_subdirectory(login)
|
controller.cpp
|
||||||
add_subdirectory(rooms)
|
controller.h
|
||||||
add_subdirectory(timeline)
|
models/emojimodel.cpp
|
||||||
add_subdirectory(spaces)
|
models/emojimodel.h
|
||||||
add_subdirectory(chatbar)
|
emojitones.cpp
|
||||||
|
emojitones.h
|
||||||
|
models/customemojimodel.cpp
|
||||||
|
models/customemojimodel.h
|
||||||
|
clipboard.cpp
|
||||||
|
clipboard.h
|
||||||
|
models/timelinemessagemodel.cpp
|
||||||
|
models/timelinemessagemodel.h
|
||||||
|
models/messagefiltermodel.cpp
|
||||||
|
models/messagefiltermodel.h
|
||||||
|
models/roomlistmodel.cpp
|
||||||
|
models/roomlistmodel.h
|
||||||
|
models/sortfilterspacelistmodel.cpp
|
||||||
|
models/sortfilterspacelistmodel.h
|
||||||
|
models/accountemoticonmodel.cpp
|
||||||
|
models/accountemoticonmodel.h
|
||||||
|
spacehierarchycache.cpp
|
||||||
|
spacehierarchycache.h
|
||||||
|
roommanager.cpp
|
||||||
|
roommanager.h
|
||||||
|
neochatroom.cpp
|
||||||
|
neochatroom.h
|
||||||
|
models/userlistmodel.cpp
|
||||||
|
models/userlistmodel.h
|
||||||
|
models/userfiltermodel.cpp
|
||||||
|
models/userfiltermodel.h
|
||||||
|
models/publicroomlistmodel.cpp
|
||||||
|
models/publicroomlistmodel.h
|
||||||
|
models/spacechildrenmodel.cpp
|
||||||
|
models/spacechildrenmodel.h
|
||||||
|
models/spacechildsortfiltermodel.cpp
|
||||||
|
models/spacechildsortfiltermodel.h
|
||||||
|
models/spacetreeitem.cpp
|
||||||
|
models/spacetreeitem.h
|
||||||
|
models/userdirectorylistmodel.cpp
|
||||||
|
models/userdirectorylistmodel.h
|
||||||
|
models/pushrulemodel.cpp
|
||||||
|
models/pushrulemodel.h
|
||||||
|
models/emoticonfiltermodel.cpp
|
||||||
|
models/emoticonfiltermodel.h
|
||||||
|
notificationsmanager.cpp
|
||||||
|
notificationsmanager.h
|
||||||
|
models/sortfilterroomlistmodel.cpp
|
||||||
|
models/sortfilterroomlistmodel.h
|
||||||
|
models/roomtreemodel.cpp
|
||||||
|
models/roomtreemodel.h
|
||||||
|
chatdocumenthandler.cpp
|
||||||
|
chatdocumenthandler.h
|
||||||
|
models/devicesmodel.cpp
|
||||||
|
models/devicesmodel.h
|
||||||
|
models/devicesproxymodel.cpp
|
||||||
|
filetype.cpp
|
||||||
|
filetype.h
|
||||||
|
login.cpp
|
||||||
|
login.h
|
||||||
|
models/webshortcutmodel.cpp
|
||||||
|
models/webshortcutmodel.h
|
||||||
|
blurhash.cpp
|
||||||
|
blurhash.h
|
||||||
|
blurhashimageprovider.cpp
|
||||||
|
blurhashimageprovider.h
|
||||||
|
models/mediamessagefiltermodel.cpp
|
||||||
|
models/mediamessagefiltermodel.h
|
||||||
|
urlhelper.cpp
|
||||||
|
urlhelper.h
|
||||||
|
windowcontroller.cpp
|
||||||
|
windowcontroller.h
|
||||||
|
linkpreviewer.cpp
|
||||||
|
linkpreviewer.h
|
||||||
|
models/completionmodel.cpp
|
||||||
|
models/completionmodel.h
|
||||||
|
models/completionproxymodel.cpp
|
||||||
|
models/completionproxymodel.h
|
||||||
|
models/actionsmodel.cpp
|
||||||
|
models/actionsmodel.h
|
||||||
|
models/serverlistmodel.cpp
|
||||||
|
models/serverlistmodel.h
|
||||||
|
models/statemodel.cpp
|
||||||
|
models/statemodel.h
|
||||||
|
models/statefiltermodel.cpp
|
||||||
|
models/statefiltermodel.h
|
||||||
|
filetransferpseudojob.cpp
|
||||||
|
filetransferpseudojob.h
|
||||||
|
models/searchmodel.cpp
|
||||||
|
models/searchmodel.h
|
||||||
|
texthandler.cpp
|
||||||
|
texthandler.h
|
||||||
|
logger.cpp
|
||||||
|
logger.h
|
||||||
|
models/stickermodel.cpp
|
||||||
|
models/stickermodel.h
|
||||||
|
models/imagepacksmodel.cpp
|
||||||
|
models/imagepacksmodel.h
|
||||||
|
events/imagepackevent.cpp
|
||||||
|
events/imagepackevent.h
|
||||||
|
models/reactionmodel.cpp
|
||||||
|
models/reactionmodel.h
|
||||||
|
delegatesizehelper.cpp
|
||||||
|
delegatesizehelper.h
|
||||||
|
models/livelocationsmodel.cpp
|
||||||
|
models/livelocationsmodel.h
|
||||||
|
models/locationsmodel.cpp
|
||||||
|
models/locationsmodel.h
|
||||||
|
locationhelper.cpp
|
||||||
|
locationhelper.h
|
||||||
|
events/pollevent.cpp
|
||||||
|
pollhandler.cpp
|
||||||
|
utils.h
|
||||||
|
utils.cpp
|
||||||
|
registration.cpp
|
||||||
|
neochatconnection.cpp
|
||||||
|
neochatconnection.h
|
||||||
|
jobs/neochatgetcommonroomsjob.cpp
|
||||||
|
jobs/neochatgetcommonroomsjob.h
|
||||||
|
mediasizehelper.cpp
|
||||||
|
mediasizehelper.h
|
||||||
|
eventhandler.cpp
|
||||||
|
enums/delegatetype.h
|
||||||
|
roomlastmessageprovider.cpp
|
||||||
|
roomlastmessageprovider.h
|
||||||
|
chatbarcache.cpp
|
||||||
|
chatbarcache.h
|
||||||
|
colorschemer.cpp
|
||||||
|
colorschemer.h
|
||||||
|
models/notificationsmodel.cpp
|
||||||
|
models/notificationsmodel.h
|
||||||
|
models/timelinemodel.cpp
|
||||||
|
models/timelinemodel.h
|
||||||
|
enums/pushrule.h
|
||||||
|
models/itinerarymodel.cpp
|
||||||
|
models/itinerarymodel.h
|
||||||
|
proxycontroller.cpp
|
||||||
|
proxycontroller.h
|
||||||
|
models/linemodel.cpp
|
||||||
|
models/linemodel.h
|
||||||
|
events/locationbeaconevent.h
|
||||||
|
events/widgetevent.h
|
||||||
|
enums/messagecomponenttype.h
|
||||||
|
models/messagecontentmodel.cpp
|
||||||
|
models/messagecontentmodel.h
|
||||||
|
enums/neochatroomtype.h
|
||||||
|
models/sortfilterroomtreemodel.cpp
|
||||||
|
models/sortfilterroomtreemodel.h
|
||||||
|
mediamanager.cpp
|
||||||
|
mediamanager.h
|
||||||
|
models/statekeysmodel.cpp
|
||||||
|
models/statekeysmodel.h
|
||||||
|
sharehandler.cpp
|
||||||
|
sharehandler.h
|
||||||
|
models/roomtreeitem.cpp
|
||||||
|
models/roomtreeitem.h
|
||||||
|
foreigntypes.h
|
||||||
|
models/threepidmodel.cpp
|
||||||
|
models/threepidmodel.h
|
||||||
|
threepidaddhelper.cpp
|
||||||
|
threepidaddhelper.h
|
||||||
|
identityserverhelper.cpp
|
||||||
|
identityserverhelper.h
|
||||||
|
enums/powerlevel.cpp
|
||||||
|
enums/powerlevel.h
|
||||||
|
models/permissionsmodel.cpp
|
||||||
|
models/permissionsmodel.h
|
||||||
|
threepidbindhelper.cpp
|
||||||
|
threepidbindhelper.h
|
||||||
|
models/readmarkermodel.cpp
|
||||||
|
models/readmarkermodel.h
|
||||||
|
neochatroommember.cpp
|
||||||
|
neochatroommember.h
|
||||||
|
models/threadmodel.cpp
|
||||||
|
models/threadmodel.h
|
||||||
|
enums/messagetype.h
|
||||||
|
messagecomponent.h
|
||||||
|
enums/roomsortparameter.cpp
|
||||||
|
enums/roomsortparameter.h
|
||||||
|
models/roomsortparametermodel.cpp
|
||||||
|
models/roomsortparametermodel.h
|
||||||
|
models/messagemodel.cpp
|
||||||
|
models/messagemodel.h
|
||||||
|
models/messagecontentfiltermodel.cpp
|
||||||
|
models/messagecontentfiltermodel.h
|
||||||
|
models/pinnedmessagemodel.cpp
|
||||||
|
models/pinnedmessagemodel.h
|
||||||
|
models/commonroomsmodel.cpp
|
||||||
|
models/commonroomsmodel.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
||||||
|
QT_QML_SINGLETON_TYPE TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ANDROID OR WIN32)
|
||||||
|
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
|
||||||
|
QT_QML_SOURCE_TYPENAME ShareAction
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||||
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
|
||||||
|
QML_FILES
|
||||||
|
qml/Main.qml
|
||||||
|
qml/AccountMenu.qml
|
||||||
|
qml/ExploreComponent.qml
|
||||||
|
qml/ExploreComponentMobile.qml
|
||||||
|
qml/RoomContextMenu.qml
|
||||||
|
qml/CollapsedRoomDelegate.qml
|
||||||
|
qml/RoomDelegate.qml
|
||||||
|
qml/RoomListPage.qml
|
||||||
|
qml/SpaceListContextMenu.qml
|
||||||
|
qml/UserInfo.qml
|
||||||
|
qml/UserInfoDesktop.qml
|
||||||
|
qml/RoomPage.qml
|
||||||
|
qml/ExploreRoomsPage.qml
|
||||||
|
qml/ManualRoomDialog.qml
|
||||||
|
qml/ExplorerDelegate.qml
|
||||||
|
qml/InviteUserPage.qml
|
||||||
|
qml/ImageEditorPage.qml
|
||||||
|
qml/NeochatMaximizeComponent.qml
|
||||||
|
qml/TypingPane.qml
|
||||||
|
qml/QuickSwitcher.qml
|
||||||
|
qml/HoverActions.qml
|
||||||
|
qml/AttachmentPane.qml
|
||||||
|
qml/QuickFormatBar.qml
|
||||||
|
qml/UserDetailDialog.qml
|
||||||
|
qml/CreateRoomDialog.qml
|
||||||
|
qml/OpenFileDialog.qml
|
||||||
|
qml/KeyVerificationDialog.qml
|
||||||
|
qml/ConfirmLogoutDialog.qml
|
||||||
|
qml/PowerLevelDialog.qml
|
||||||
|
qml/Message.qml
|
||||||
|
qml/EmojiItem.qml
|
||||||
|
qml/EmojiRow.qml
|
||||||
|
qml/EmojiSas.qml
|
||||||
|
qml/ConfirmDeactivateAccountDialog.qml
|
||||||
|
qml/VerificationCanceled.qml
|
||||||
|
qml/MessageDelegateContextMenu.qml
|
||||||
|
qml/FileDelegateContextMenu.qml
|
||||||
|
qml/MessageSourceSheet.qml
|
||||||
|
qml/ConfirmEncryptionDialog.qml
|
||||||
|
qml/RoomSearchPage.qml
|
||||||
|
qml/RoomPinnedMessagesPage.qml
|
||||||
|
qml/LocationChooser.qml
|
||||||
|
qml/TimelineView.qml
|
||||||
|
qml/InvitationView.qml
|
||||||
|
qml/AvatarTabButton.qml
|
||||||
|
qml/SpaceDrawer.qml
|
||||||
|
qml/OsmLocationPlugin.qml
|
||||||
|
qml/FullScreenMap.qml
|
||||||
|
qml/LocationsPage.qml
|
||||||
|
qml/LocationMapItem.qml
|
||||||
|
qml/RoomDrawer.qml
|
||||||
|
qml/RoomDrawerPage.qml
|
||||||
|
qml/DirectChatDrawerHeader.qml
|
||||||
|
qml/GroupChatDrawerHeader.qml
|
||||||
|
qml/RoomInformation.qml
|
||||||
|
qml/RoomMedia.qml
|
||||||
|
qml/ChooseRoomDialog.qml
|
||||||
|
qml/SpaceHomePage.qml
|
||||||
|
qml/SpaceHierarchyDelegate.qml
|
||||||
|
qml/RemoveChildDialog.qml
|
||||||
|
qml/SelectParentDialog.qml
|
||||||
|
qml/QrCodeMaximizeComponent.qml
|
||||||
|
qml/SelectSpacesDialog.qml
|
||||||
|
qml/NotificationsView.qml
|
||||||
|
qml/SearchPage.qml
|
||||||
|
qml/ServerComboBox.qml
|
||||||
|
qml/UserSearchPage.qml
|
||||||
|
qml/ManualUserDialog.qml
|
||||||
|
qml/RecommendedSpaceDialog.qml
|
||||||
|
qml/RoomTreeSection.qml
|
||||||
|
qml/DelegateContextMenu.qml
|
||||||
|
qml/ShareDialog.qml
|
||||||
|
qml/UnlockSSSSDialog.qml
|
||||||
|
qml/QrScannerPage.qml
|
||||||
|
qml/JoinRoomDialog.qml
|
||||||
|
qml/ConfirmUrlDialog.qml
|
||||||
|
qml/AccountSwitchDialog.qml
|
||||||
|
qml/ConfirmLeaveDialog.qml
|
||||||
|
qml/CodeMaximizeComponent.qml
|
||||||
|
qml/EditStateDialog.qml
|
||||||
|
qml/ConsentDialog.qml
|
||||||
|
qml/AskDirectChatConfirmation.qml
|
||||||
|
qml/HoverLinkIndicator.qml
|
||||||
|
qml/AvatarNotification.qml
|
||||||
|
qml/ReasonDialog.qml
|
||||||
|
DEPENDENCIES
|
||||||
|
QtCore
|
||||||
|
QtQuick
|
||||||
|
IMPORTS
|
||||||
|
org.kde.neochat.timeline
|
||||||
|
org.kde.neochat.settings
|
||||||
|
org.kde.neochat.devtools
|
||||||
|
org.kde.neochat.login
|
||||||
|
org.kde.neochat.chatbar
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(settings)
|
add_subdirectory(settings)
|
||||||
|
add_subdirectory(timeline)
|
||||||
add_subdirectory(devtools)
|
add_subdirectory(devtools)
|
||||||
add_subdirectory(app)
|
add_subdirectory(login)
|
||||||
|
add_subdirectory(chatbar)
|
||||||
|
|
||||||
|
if(NOT ANDROID AND NOT WIN32)
|
||||||
|
qt_target_qml_sources(neochat QML_FILES
|
||||||
|
qml/ShareAction.qml
|
||||||
|
qml/GlobalMenu.qml
|
||||||
|
qml/EditMenu.qml
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
qt_target_qml_sources(neochat QML_FILES qml/ShareActionStub.qml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(config-neochat.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-neochat.h)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set_target_properties(neochat PROPERTIES OUTPUT_NAME "neochatlib")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "messagemodel_logging.h"
|
||||||
|
IDENTIFIER "Message"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.messagemodel"
|
||||||
|
DESCRIPTION "Neochat: messagemodel"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
EXPORT NEOCHAT
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "publicroomlist_logging.h"
|
||||||
|
IDENTIFIER "PublicRoomList"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.publicroomlistmodel"
|
||||||
|
DESCRIPTION "Neochat: publicroomlistmodel"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
EXPORT NEOCHAT
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "eventhandler_logging.h"
|
||||||
|
IDENTIFIER "EventHandling"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.eventhandler"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "chatdocumenthandler_logging.h"
|
||||||
|
IDENTIFIER "ChatDocumentHandling"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.chatdocumenthandler"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(neochat-app
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(TARGET Qt::WebView)
|
||||||
|
target_link_libraries(neochat-app PUBLIC Qt::WebView)
|
||||||
|
target_compile_definitions(neochat-app PUBLIC -DHAVE_WEBVIEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
target_link_libraries(neochat-app PRIVATE
|
||||||
|
neochat
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
||||||
|
|
||||||
|
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
|
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
|
||||||
|
target_link_libraries(neochat PRIVATE KF6::StatusNotifierItem)
|
||||||
|
else()
|
||||||
|
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::WindowSystem ICU::uc)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_ICU)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_X11=1)
|
||||||
|
target_sources(neochat PRIVATE runner.cpp)
|
||||||
|
|
||||||
|
if (TARGET KUnifiedPush)
|
||||||
|
target_sources(neochat PRIVATE fakerunner.cpp)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_X11=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums)
|
||||||
|
target_link_libraries(neochat PRIVATE settingsplugin timelineplugin devtoolsplugin loginplugin chatbarplugin)
|
||||||
|
target_link_libraries(neochat PUBLIC
|
||||||
|
Qt::Core
|
||||||
|
Qt::Quick
|
||||||
|
Qt::Qml
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Multimedia
|
||||||
|
Qt::Network
|
||||||
|
Qt::QuickControls2
|
||||||
|
KF6::I18n
|
||||||
|
KF6::Kirigami
|
||||||
|
KF6::Notifications
|
||||||
|
KF6::ConfigCore
|
||||||
|
KF6::ConfigGui
|
||||||
|
KF6::CoreAddons
|
||||||
|
KF6::SonnetCore
|
||||||
|
KF6::IconThemes
|
||||||
|
KF6::ColorScheme
|
||||||
|
KF6::ItemModels
|
||||||
|
QuotientQt6
|
||||||
|
cmark::cmark
|
||||||
|
QCoro::Core
|
||||||
|
QCoro::Network
|
||||||
|
)
|
||||||
|
|
||||||
|
if (TARGET KF6::Crash)
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::Crash)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
kconfig_target_kcfg_file(neochat FILE neochatconfig.kcfg CLASS_NAME NeoChatConfig MUTATORS GENERATE_PROPERTIES DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR SINGLETON GENERATE_MOC QML_REGISTRATION)
|
||||||
|
|
||||||
|
if(NEOCHAT_FLATPAK)
|
||||||
|
target_compile_definitions(neochat PUBLIC NEOCHAT_FLATPAK)
|
||||||
|
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
|
||||||
|
"arrow-down-symbolic"
|
||||||
|
"arrow-up-symbolic"
|
||||||
|
"arrow-up-double-symbolic"
|
||||||
|
"arrow-left-symbolic"
|
||||||
|
"arrow-right-symbolic"
|
||||||
|
"checkmark"
|
||||||
|
"help-about"
|
||||||
|
"im-user"
|
||||||
|
"im-invisible-user"
|
||||||
|
"im-kick-user"
|
||||||
|
"mail-attachment"
|
||||||
|
"dialog-cancel"
|
||||||
|
"preferences-desktop-emoticons"
|
||||||
|
"preferences-security"
|
||||||
|
"document-open"
|
||||||
|
"document-save"
|
||||||
|
"document-send"
|
||||||
|
"dialog-close"
|
||||||
|
"edit-delete-remove"
|
||||||
|
"code-context"
|
||||||
|
"document-edit"
|
||||||
|
"list-user-add"
|
||||||
|
"list-add-user"
|
||||||
|
"user-others"
|
||||||
|
"media-playback-pause"
|
||||||
|
"media-playback-start"
|
||||||
|
"media-playback-stop"
|
||||||
|
"go-previous"
|
||||||
|
"go-up"
|
||||||
|
"go-down"
|
||||||
|
"list-add"
|
||||||
|
"irc-join-channel"
|
||||||
|
"settings-configure"
|
||||||
|
"configure"
|
||||||
|
"rating"
|
||||||
|
"rating-unrated"
|
||||||
|
"search"
|
||||||
|
"mail-replied-symbolic"
|
||||||
|
"edit-clear"
|
||||||
|
"edit-copy"
|
||||||
|
"gtk-quit"
|
||||||
|
"compass"
|
||||||
|
"computer"
|
||||||
|
"network-connect"
|
||||||
|
"list-remove-user"
|
||||||
|
"org.kde.neochat"
|
||||||
|
"org.kde.neochat.tray"
|
||||||
|
"preferences-system-users"
|
||||||
|
"preferences-desktop-theme-global"
|
||||||
|
"notifications"
|
||||||
|
"notifications-disabled"
|
||||||
|
"audio-volume-high"
|
||||||
|
"audio-volume-muted"
|
||||||
|
"draw-highlight"
|
||||||
|
"zoom-in"
|
||||||
|
"zoom-out"
|
||||||
|
"image-rotate-left-symbolic"
|
||||||
|
"image-rotate-right-symbolic"
|
||||||
|
"channel-secure-symbolic"
|
||||||
|
"download"
|
||||||
|
"smiley"
|
||||||
|
"tools-check-spelling"
|
||||||
|
"username-copy"
|
||||||
|
"system-switch-user"
|
||||||
|
"bookmark-new"
|
||||||
|
"bookmark-remove"
|
||||||
|
"favorite"
|
||||||
|
"window-new"
|
||||||
|
"globe"
|
||||||
|
"visibility"
|
||||||
|
"home"
|
||||||
|
"preferences-desktop-notification"
|
||||||
|
"computer-symbolic"
|
||||||
|
"gps"
|
||||||
|
"system-users-symbolic"
|
||||||
|
"map-flat"
|
||||||
|
"documentinfo"
|
||||||
|
"view-list-details"
|
||||||
|
"go-previous"
|
||||||
|
"mail-forward-symbolic"
|
||||||
|
"dialog-warning-symbolic"
|
||||||
|
"object-rotate-left"
|
||||||
|
"object-rotate-right"
|
||||||
|
"add-subtitle"
|
||||||
|
"security-high"
|
||||||
|
"security-low"
|
||||||
|
"security-low-symbolic"
|
||||||
|
"kde"
|
||||||
|
"list-remove-symbolic"
|
||||||
|
"edit-delete"
|
||||||
|
"user-home-symbolic"
|
||||||
|
"pin-symbolic"
|
||||||
|
"kt-restore-defaults-symbolic"
|
||||||
|
"user-symbolic"
|
||||||
|
)
|
||||||
|
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
|
||||||
|
else()
|
||||||
|
target_link_libraries(neochat PUBLIC Qt::Widgets KF6::KIOWidgets KF6::SyntaxHighlighting)
|
||||||
|
install(FILES neochat.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
set_target_properties(neochat-app PROPERTIES OUTPUT_NAME "neochat")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TARGET KF6::DBusAddons AND NOT WIN32)
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::DBusAddons)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KDBUSADDONS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET KF6::KIOWidgets)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KIO)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET KUnifiedPush)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KUNIFIEDPUSH)
|
||||||
|
target_link_libraries(neochat PUBLIC KUnifiedPush)
|
||||||
|
|
||||||
|
if (NOT ANDROID)
|
||||||
|
configure_file(org.kde.neochat.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
||||||
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||||
|
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -1,370 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carl@carlschwan.eu>
|
|
||||||
# SPDX-FileCopyrightText: 2020-2021 Nicolas Fella <nicolas.fella@gmx.de>
|
|
||||||
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
|
|
||||||
add_library(neochat STATIC
|
|
||||||
controller.cpp
|
|
||||||
controller.h
|
|
||||||
roommanager.cpp
|
|
||||||
roommanager.h
|
|
||||||
models/userfiltermodel.cpp
|
|
||||||
models/userfiltermodel.h
|
|
||||||
models/userdirectorylistmodel.cpp
|
|
||||||
models/userdirectorylistmodel.h
|
|
||||||
notificationsmanager.cpp
|
|
||||||
notificationsmanager.h
|
|
||||||
blurhash.cpp
|
|
||||||
blurhash.h
|
|
||||||
blurhashimageprovider.cpp
|
|
||||||
blurhashimageprovider.h
|
|
||||||
windowcontroller.cpp
|
|
||||||
windowcontroller.h
|
|
||||||
models/serverlistmodel.cpp
|
|
||||||
models/serverlistmodel.h
|
|
||||||
logger.cpp
|
|
||||||
logger.h
|
|
||||||
models/notificationsmodel.cpp
|
|
||||||
models/notificationsmodel.h
|
|
||||||
proxycontroller.cpp
|
|
||||||
proxycontroller.h
|
|
||||||
mediamanager.cpp
|
|
||||||
mediamanager.h
|
|
||||||
sharehandler.cpp
|
|
||||||
sharehandler.h
|
|
||||||
foreigntypes.h
|
|
||||||
identityserverhelper.cpp
|
|
||||||
identityserverhelper.h
|
|
||||||
models/commonroomsmodel.cpp
|
|
||||||
models/commonroomsmodel.h
|
|
||||||
texttospeechhelper.h
|
|
||||||
texttospeechhelper.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
|
||||||
QT_QML_SINGLETON_TYPE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
if(ANDROID OR WIN32)
|
|
||||||
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
|
|
||||||
QT_QML_SOURCE_TYPENAME ShareAction
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
|
|
||||||
QML_FILES
|
|
||||||
qml/Main.qml
|
|
||||||
qml/AccountMenu.qml
|
|
||||||
qml/CollapsedRoomDelegate.qml
|
|
||||||
qml/RoomPage.qml
|
|
||||||
qml/ExploreRoomsPage.qml
|
|
||||||
qml/ManualRoomDialog.qml
|
|
||||||
qml/ExplorerDelegate.qml
|
|
||||||
qml/InviteUserPage.qml
|
|
||||||
qml/ImageEditorPage.qml
|
|
||||||
qml/NeochatMaximizeComponent.qml
|
|
||||||
qml/TypingPane.qml
|
|
||||||
qml/QuickSwitcher.qml
|
|
||||||
qml/AttachmentPane.qml
|
|
||||||
qml/QuickFormatBar.qml
|
|
||||||
qml/UserDetailDialog.qml
|
|
||||||
qml/CreateRoomDialog.qml
|
|
||||||
qml/OpenFileDialog.qml
|
|
||||||
qml/KeyVerificationDialog.qml
|
|
||||||
qml/ConfirmLogoutDialog.qml
|
|
||||||
qml/VerificationMessage.qml
|
|
||||||
qml/EmojiItem.qml
|
|
||||||
qml/EmojiRow.qml
|
|
||||||
qml/EmojiSas.qml
|
|
||||||
qml/VerificationCanceled.qml
|
|
||||||
qml/MessageSourceSheet.qml
|
|
||||||
qml/RoomSearchPage.qml
|
|
||||||
qml/RoomPinnedMessagesPage.qml
|
|
||||||
qml/LocationChooser.qml
|
|
||||||
qml/InvitationView.qml
|
|
||||||
qml/AvatarTabButton.qml
|
|
||||||
qml/OsmLocationPlugin.qml
|
|
||||||
qml/FullScreenMap.qml
|
|
||||||
qml/LocationsPage.qml
|
|
||||||
qml/LocationMapItem.qml
|
|
||||||
qml/RoomDrawer.qml
|
|
||||||
qml/RoomDrawerPage.qml
|
|
||||||
qml/DirectChatDrawerHeader.qml
|
|
||||||
qml/GroupChatDrawerHeader.qml
|
|
||||||
qml/RoomInformation.qml
|
|
||||||
qml/RoomMedia.qml
|
|
||||||
qml/ChooseRoomDialog.qml
|
|
||||||
qml/RemoveChildDialog.qml
|
|
||||||
qml/QrCodeMaximizeComponent.qml
|
|
||||||
qml/NotificationsView.qml
|
|
||||||
qml/SearchPage.qml
|
|
||||||
qml/ServerComboBox.qml
|
|
||||||
qml/UserSearchPage.qml
|
|
||||||
qml/ManualUserDialog.qml
|
|
||||||
qml/RecommendedSpaceDialog.qml
|
|
||||||
qml/ShareDialog.qml
|
|
||||||
qml/UnlockSSSSDialog.qml
|
|
||||||
qml/QrScannerPage.qml
|
|
||||||
qml/JoinRoomDialog.qml
|
|
||||||
qml/ConfirmUrlDialog.qml
|
|
||||||
qml/AccountSwitchDialog.qml
|
|
||||||
qml/ConfirmLeaveDialog.qml
|
|
||||||
qml/CodeMaximizeComponent.qml
|
|
||||||
qml/EditStateDialog.qml
|
|
||||||
qml/ConsentDialog.qml
|
|
||||||
qml/AskDirectChatConfirmation.qml
|
|
||||||
qml/HoverLinkIndicator.qml
|
|
||||||
qml/AvatarNotification.qml
|
|
||||||
qml/ReasonDialog.qml
|
|
||||||
qml/NewPollDialog.qml
|
|
||||||
DEPENDENCIES
|
|
||||||
QtCore
|
|
||||||
QtQuick
|
|
||||||
IMPORTS
|
|
||||||
org.kde.neochat.libneochat
|
|
||||||
org.kde.neochat.rooms
|
|
||||||
org.kde.neochat.timeline
|
|
||||||
org.kde.neochat.spaces
|
|
||||||
org.kde.neochat.settings
|
|
||||||
org.kde.neochat.devtools
|
|
||||||
org.kde.neochat.login
|
|
||||||
org.kde.neochat.chatbar
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT ANDROID AND NOT WIN32)
|
|
||||||
qt_target_qml_sources(neochat QML_FILES
|
|
||||||
qml/ShareAction.qml
|
|
||||||
qml/GlobalMenu.qml
|
|
||||||
qml/EditMenu.qml
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
qt_target_qml_sources(neochat QML_FILES qml/ShareActionStub.qml)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
set_target_properties(neochat PROPERTIES OUTPUT_NAME "neochatlib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(neochat-app
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(TARGET Qt::WebView)
|
|
||||||
target_link_libraries(neochat-app PUBLIC Qt::WebView)
|
|
||||||
target_compile_definitions(neochat-app PUBLIC -DHAVE_WEBVIEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
|
|
||||||
|
|
||||||
target_link_libraries(neochat-app PRIVATE
|
|
||||||
neochat
|
|
||||||
)
|
|
||||||
|
|
||||||
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
|
||||||
|
|
||||||
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
|
||||||
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
|
|
||||||
target_link_libraries(neochat PRIVATE KF6::StatusNotifierItem)
|
|
||||||
else()
|
|
||||||
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::WindowSystem)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_X11=1)
|
|
||||||
target_sources(neochat PRIVATE runner.cpp)
|
|
||||||
|
|
||||||
if (TARGET KUnifiedPush)
|
|
||||||
target_sources(neochat PRIVATE fakerunner.cpp)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_X11=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models)
|
|
||||||
target_link_libraries(neochat PRIVATE Loginplugin Roomsplugin Timelineplugin Spacesplugin Chatbarplugin Settingsplugin Devtoolsplugin)
|
|
||||||
target_link_libraries(neochat PUBLIC
|
|
||||||
LibNeoChat
|
|
||||||
Timeline
|
|
||||||
Settings
|
|
||||||
Qt::Core
|
|
||||||
Qt::Quick
|
|
||||||
Qt::Qml
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Multimedia
|
|
||||||
Qt::Network
|
|
||||||
Qt::QuickControls2
|
|
||||||
Qt::TextToSpeech
|
|
||||||
KF6::I18n
|
|
||||||
KF6::Kirigami
|
|
||||||
KF6::Notifications
|
|
||||||
KF6::ConfigCore
|
|
||||||
KF6::ConfigGui
|
|
||||||
KF6::CoreAddons
|
|
||||||
KF6::SonnetCore
|
|
||||||
KF6::IconThemes
|
|
||||||
KF6::ItemModels
|
|
||||||
QuotientQt6
|
|
||||||
Login
|
|
||||||
Rooms
|
|
||||||
Spaces
|
|
||||||
)
|
|
||||||
|
|
||||||
if (TARGET KF6::Crash)
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::Crash)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
kconfig_target_kcfg_file(neochat FILE neochatconfig.kcfg CLASS_NAME NeoChatConfig MUTATORS GENERATE_PROPERTIES DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR SINGLETON GENERATE_MOC QML_REGISTRATION)
|
|
||||||
|
|
||||||
if(NEOCHAT_FLATPAK)
|
|
||||||
target_compile_definitions(neochat PUBLIC NEOCHAT_FLATPAK)
|
|
||||||
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
|
|
||||||
"arrow-down-symbolic"
|
|
||||||
"arrow-up-symbolic"
|
|
||||||
"arrow-up-double-symbolic"
|
|
||||||
"arrow-left-symbolic"
|
|
||||||
"arrow-right-symbolic"
|
|
||||||
"checkmark"
|
|
||||||
"help-about"
|
|
||||||
"im-user"
|
|
||||||
"im-invisible-user"
|
|
||||||
"im-kick-user"
|
|
||||||
"mail-attachment"
|
|
||||||
"dialog-cancel"
|
|
||||||
"preferences-desktop-emoticons"
|
|
||||||
"preferences-security"
|
|
||||||
"document-open"
|
|
||||||
"document-save"
|
|
||||||
"document-send"
|
|
||||||
"dialog-close"
|
|
||||||
"edit-delete-remove"
|
|
||||||
"code-context"
|
|
||||||
"document-edit"
|
|
||||||
"list-user-add"
|
|
||||||
"list-add-user"
|
|
||||||
"user-others"
|
|
||||||
"media-playback-pause"
|
|
||||||
"media-playback-start"
|
|
||||||
"media-playback-stop"
|
|
||||||
"go-previous"
|
|
||||||
"go-up"
|
|
||||||
"go-down"
|
|
||||||
"list-add"
|
|
||||||
"irc-join-channel"
|
|
||||||
"settings-configure"
|
|
||||||
"configure"
|
|
||||||
"rating"
|
|
||||||
"rating-unrated"
|
|
||||||
"search"
|
|
||||||
"mail-replied-symbolic"
|
|
||||||
"edit-clear"
|
|
||||||
"edit-copy"
|
|
||||||
"gtk-quit"
|
|
||||||
"compass"
|
|
||||||
"computer"
|
|
||||||
"network-connect"
|
|
||||||
"list-remove-user"
|
|
||||||
"org.kde.neochat"
|
|
||||||
"org.kde.neochat.tray"
|
|
||||||
"preferences-system-users"
|
|
||||||
"preferences-desktop-theme-global"
|
|
||||||
"notifications"
|
|
||||||
"notifications-disabled"
|
|
||||||
"audio-volume-high"
|
|
||||||
"audio-volume-muted"
|
|
||||||
"draw-highlight"
|
|
||||||
"zoom-in"
|
|
||||||
"zoom-out"
|
|
||||||
"image-rotate-left-symbolic"
|
|
||||||
"image-rotate-right-symbolic"
|
|
||||||
"channel-secure-symbolic"
|
|
||||||
"download"
|
|
||||||
"smiley"
|
|
||||||
"tools-check-spelling"
|
|
||||||
"username-copy"
|
|
||||||
"system-switch-user"
|
|
||||||
"bookmark-new"
|
|
||||||
"bookmark-remove"
|
|
||||||
"favorite"
|
|
||||||
"window-new"
|
|
||||||
"globe"
|
|
||||||
"visibility"
|
|
||||||
"home"
|
|
||||||
"preferences-desktop-notification"
|
|
||||||
"computer-symbolic"
|
|
||||||
"gps"
|
|
||||||
"system-users-symbolic"
|
|
||||||
"map-flat"
|
|
||||||
"documentinfo"
|
|
||||||
"view-list-details"
|
|
||||||
"go-previous"
|
|
||||||
"mail-forward-symbolic"
|
|
||||||
"dialog-warning-symbolic"
|
|
||||||
"object-rotate-left"
|
|
||||||
"object-rotate-right"
|
|
||||||
"add-subtitle"
|
|
||||||
"security-high"
|
|
||||||
"security-low"
|
|
||||||
"security-low-symbolic"
|
|
||||||
"kde"
|
|
||||||
"list-remove-symbolic"
|
|
||||||
"edit-delete"
|
|
||||||
"user-home-symbolic"
|
|
||||||
"pin-symbolic"
|
|
||||||
"kt-restore-defaults-symbolic"
|
|
||||||
"user-symbolic"
|
|
||||||
"mark-location-symbolic"
|
|
||||||
|
|
||||||
${KIRIGAMI_ADDONS_ICONS}
|
|
||||||
)
|
|
||||||
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
|
|
||||||
else()
|
|
||||||
target_link_libraries(neochat PUBLIC Qt::Widgets KF6::KIOWidgets)
|
|
||||||
install(FILES neochat.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
set_target_properties(neochat-app PROPERTIES OUTPUT_NAME "neochat")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(TARGET KF6::DBusAddons AND NOT WIN32)
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::DBusAddons)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KDBUSADDONS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (TARGET KF6::KIOWidgets)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KIO)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (TARGET KUnifiedPush)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KUNIFIEDPUSH)
|
|
||||||
target_link_libraries(neochat PUBLIC KUnifiedPush)
|
|
||||||
|
|
||||||
if (NOT ANDROID)
|
|
||||||
configure_file(org.kde.neochat.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service)
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
|
||||||
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
|
|
||||||
endif()
|
|
||||||
@@ -1,407 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
|
|
||||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
|
|
||||||
#include "controller.h"
|
|
||||||
|
|
||||||
#include <Quotient/connection.h>
|
|
||||||
#include <qt6keychain/keychain.h>
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <Quotient/csapi/notifications.h>
|
|
||||||
#include <Quotient/events/roommemberevent.h>
|
|
||||||
#include <Quotient/qt_connection_util.h>
|
|
||||||
#include <Quotient/settings.h>
|
|
||||||
|
|
||||||
#include "accountmanager.h"
|
|
||||||
#include "enums/roomsortparameter.h"
|
|
||||||
#include "mediasizehelper.h"
|
|
||||||
#include "models/actionsmodel.h"
|
|
||||||
#include "models/messagemodel.h"
|
|
||||||
#include "models/pushrulemodel.h"
|
|
||||||
#include "models/roomlistmodel.h"
|
|
||||||
#include "models/roomtreemodel.h"
|
|
||||||
#include "neochatconfig.h"
|
|
||||||
#include "neochatconnection.h"
|
|
||||||
#include "neochatroom.h"
|
|
||||||
#include "notificationsmanager.h"
|
|
||||||
#include "proxycontroller.h"
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
|
||||||
#include "trayicon.h"
|
|
||||||
#elif !defined(Q_OS_ANDROID)
|
|
||||||
#include "trayicon_sni.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
#include <QDBusConnection>
|
|
||||||
#include <QDBusInterface>
|
|
||||||
#include <QDBusMessage>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
#include <kunifiedpush/connector.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Quotient;
|
|
||||||
|
|
||||||
static std::function<bool(const Quotient::RoomEvent *)> hiddenEventFilter = [](const RoomEvent *event) -> bool {
|
|
||||||
if (event->isStateEvent() && !NeoChatConfig::showStateEvent()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (auto roomMemberEvent = eventCast<const RoomMemberEvent>(event)) {
|
|
||||||
if ((roomMemberEvent->isJoin() || roomMemberEvent->isLeave()) && !NeoChatConfig::showLeaveJoinEvent()) {
|
|
||||||
return true;
|
|
||||||
} else if (roomMemberEvent->isRename() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::showRename()) {
|
|
||||||
return true;
|
|
||||||
} else if (roomMemberEvent->isAvatarUpdate() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::showAvatarUpdate()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Controller::Controller(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
Connection::setRoomType<NeoChatRoom>();
|
|
||||||
|
|
||||||
Connection::setDirectChatEncryptionDefault(NeoChatConfig::preferUsingEncryption());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::PreferUsingEncryptionChanged, this, [] {
|
|
||||||
Connection::setDirectChatEncryptionDefault(NeoChatConfig::preferUsingEncryption());
|
|
||||||
});
|
|
||||||
|
|
||||||
NeoChatConnection::setGlobalUrlPreviewDefault(NeoChatConfig::showLinkPreview());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLinkPreviewChanged, this, [this] {
|
|
||||||
NeoChatConnection::setGlobalUrlPreviewDefault(NeoChatConfig::showLinkPreview());
|
|
||||||
Q_EMIT globalUrlPreviewDefaultChanged();
|
|
||||||
});
|
|
||||||
|
|
||||||
NeoChatConnection::setKeywordPushRuleDefault(static_cast<PushRuleAction::Action>(NeoChatConfig::keywordPushRuleDefault()));
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::KeywordPushRuleDefaultChanged, this, [] {
|
|
||||||
NeoChatConnection::setKeywordPushRuleDefault(static_cast<PushRuleAction::Action>(NeoChatConfig::keywordPushRuleDefault()));
|
|
||||||
});
|
|
||||||
|
|
||||||
ActionsModel::setAllowQuickEdit(NeoChatConfig::allowQuickEdit());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::AllowQuickEditChanged, this, []() {
|
|
||||||
ActionsModel::setAllowQuickEdit(NeoChatConfig::allowQuickEdit());
|
|
||||||
});
|
|
||||||
|
|
||||||
MessageModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
RoomListModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
RoomTreeModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::MediaMaxWidthChanged, this, []() {
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
});
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::MediaMaxHeightChanged, this, []() {
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
});
|
|
||||||
|
|
||||||
RoomSortParameter::setSortOrder(static_cast<RoomSortOrder::Order>(NeoChatConfig::sortOrder()));
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::SortOrderChanged, this, []() {
|
|
||||||
RoomSortParameter::setSortOrder(static_cast<RoomSortOrder::Order>(NeoChatConfig::sortOrder()));
|
|
||||||
});
|
|
||||||
|
|
||||||
QList<RoomSortParameter::Parameter> configParamList;
|
|
||||||
const auto intList = NeoChatConfig::customSortOrder();
|
|
||||||
std::transform(intList.constBegin(), intList.constEnd(), std::back_inserter(configParamList), [](int param) {
|
|
||||||
return static_cast<RoomSortParameter::Parameter>(param);
|
|
||||||
});
|
|
||||||
RoomSortParameter::setCustomSortOrder(configParamList);
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::CustomSortOrderChanged, this, []() {
|
|
||||||
QList<RoomSortParameter::Parameter> configParamList;
|
|
||||||
const auto intList = NeoChatConfig::customSortOrder();
|
|
||||||
std::transform(intList.constBegin(), intList.constEnd(), std::back_inserter(configParamList), [](int param) {
|
|
||||||
return static_cast<RoomSortParameter::Parameter>(param);
|
|
||||||
});
|
|
||||||
RoomSortParameter::setCustomSortOrder(configParamList);
|
|
||||||
});
|
|
||||||
|
|
||||||
ProxyController::instance().setApplicationProxy();
|
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
setQuitOnLastWindowClosed();
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::SystemTrayChanged, this, &Controller::setQuitOnLastWindowClosed);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QObject::connect(QGuiApplication::instance(), &QCoreApplication::aboutToQuit, QGuiApplication::instance(), [this] {
|
|
||||||
delete m_trayIcon;
|
|
||||||
NeoChatConfig::self()->save();
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifndef Q_OS_WINDOWS
|
|
||||||
const auto unixExitHandler = [](int) -> void {
|
|
||||||
QCoreApplication::quit();
|
|
||||||
};
|
|
||||||
|
|
||||||
const int quitSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
|
||||||
|
|
||||||
sigset_t blockingMask;
|
|
||||||
sigemptyset(&blockingMask);
|
|
||||||
for (const auto sig : quitSignals) {
|
|
||||||
sigaddset(&blockingMask, sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigaction sa;
|
|
||||||
sa.sa_handler = unixExitHandler;
|
|
||||||
sa.sa_mask = blockingMask;
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
|
|
||||||
for (auto sig : quitSignals) {
|
|
||||||
sigaction(sig, &sa, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
|
||||||
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_endpoint = endpoint;
|
|
||||||
for (auto "ientConnection : m_accountManager->accounts()->accounts()) {
|
|
||||||
auto connection = dynamic_cast<NeoChatConnection *>(quotientConnection);
|
|
||||||
connection->setupPushNotifications(endpoint);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connector->registerClient(
|
|
||||||
i18nc("The reason for using push notifications, as in: '[Push notifications are used for] Receiving notifications for new messages'",
|
|
||||||
"Receiving notifications for new messages"));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller &Controller::instance()
|
|
||||||
{
|
|
||||||
static Controller _instance;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setAccountManager(AccountManager *manager)
|
|
||||||
{
|
|
||||||
if (manager == m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_accountManager) {
|
|
||||||
m_accountManager->disconnect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_accountManager = manager;
|
|
||||||
|
|
||||||
if (m_accountManager) {
|
|
||||||
connect(m_accountManager, &AccountManager::errorOccured, this, &Controller::errorOccured);
|
|
||||||
connect(m_accountManager, &AccountManager::accountsLoadingChanged, this, &Controller::accountsLoadingChanged);
|
|
||||||
connect(m_accountManager, &AccountManager::connectionAdded, this, &Controller::initConnection);
|
|
||||||
connect(m_accountManager, &AccountManager::connectionDropped, this, &Controller::teardownConnection);
|
|
||||||
connect(m_accountManager, &AccountManager::activeConnectionChanged, this, &Controller::initActiveConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::initConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!connection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(
|
|
||||||
connection,
|
|
||||||
&NeoChatConnection::syncDone,
|
|
||||||
this,
|
|
||||||
[this, connection] {
|
|
||||||
if (!m_endpoint.isEmpty()) {
|
|
||||||
connection->setupPushNotifications(m_endpoint);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Qt::SingleShotConnection);
|
|
||||||
connect(connection, &NeoChatConnection::syncDone, this, [this, connection]() {
|
|
||||||
m_notificationsManager.handleNotifications(connection);
|
|
||||||
});
|
|
||||||
connect(this, &Controller::globalUrlPreviewDefaultChanged, connection, &NeoChatConnection::globalUrlPreviewEnabledChanged);
|
|
||||||
Q_EMIT connectionAdded(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::teardownConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!connection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->disconnect(this);
|
|
||||||
Q_EMIT connectionDropped(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::initActiveConnection(NeoChatConnection *oldConnection, NeoChatConnection *newConnection)
|
|
||||||
{
|
|
||||||
if (oldConnection) {
|
|
||||||
oldConnection->disconnect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newConnection) {
|
|
||||||
connect(newConnection, &NeoChatConnection::errorOccured, this, &Controller::errorOccured);
|
|
||||||
connect(newConnection, &NeoChatConnection::badgeNotificationCountChanged, this, &Controller::updateBadgeNotificationCount);
|
|
||||||
newConnection->refreshBadgeNotificationCount();
|
|
||||||
}
|
|
||||||
Q_EMIT activeConnectionChanged(newConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::supportSystemTray() const
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
auto de = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP"));
|
|
||||||
return de != u"GNOME"_s && de != u"Pantheon"_s;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setQuitOnLastWindowClosed()
|
|
||||||
{
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
if (supportSystemTray() && NeoChatConfig::self()->systemTray()) {
|
|
||||||
m_trayIcon = new TrayIcon(this);
|
|
||||||
m_trayIcon->show();
|
|
||||||
} else {
|
|
||||||
if (m_trayIcon) {
|
|
||||||
delete m_trayIcon;
|
|
||||||
m_trayIcon = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
NeoChatConnection *Controller::activeConnection() const
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_accountManager->activeConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setActiveConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_accountManager->setActiveConnection(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Controller::accountsLoading() const
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return m_accountManager->accountsLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::listenForNotifications()
|
|
||||||
{
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
|
||||||
|
|
||||||
auto timer = new QTimer();
|
|
||||||
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
|
||||||
|
|
||||||
connect(connector, &KUnifiedPush::Connector::messageReceived, [timer](const QByteArray &data) {
|
|
||||||
instance().m_notificationsManager.postPushNotification(data);
|
|
||||||
timer->stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait five seconds to see if we received any messages or this happened to be an erroneous activation.
|
|
||||||
// Otherwise, messageReceived is never activated, and this daemon could stick around forever.
|
|
||||||
timer->start(5000);
|
|
||||||
|
|
||||||
connector->registerClient(i18n("Receiving push notifications"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::clearInvitationNotification(const QString &roomId)
|
|
||||||
{
|
|
||||||
m_notificationsManager.clearInvitationNotification(roomId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::updateBadgeNotificationCount(int count)
|
|
||||||
{
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
// copied from Telegram desktop
|
|
||||||
const auto launcherUrl = "application://org.kde.neochat.desktop"_L1;
|
|
||||||
// Gnome requires that count is a 64bit integer
|
|
||||||
const qint64 counterSlice = std::min(count, 9999);
|
|
||||||
QVariantMap dbusUnityProperties;
|
|
||||||
|
|
||||||
if (counterSlice > 0) {
|
|
||||||
dbusUnityProperties["count"_L1] = counterSlice;
|
|
||||||
dbusUnityProperties["count-visible"_L1] = true;
|
|
||||||
} else {
|
|
||||||
dbusUnityProperties["count-visible"_L1] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto signal = QDBusMessage::createSignal("/com/canonical/unity/launcherentry/neochat"_L1, "com.canonical.Unity.LauncherEntry"_L1, "Update"_L1);
|
|
||||||
|
|
||||||
signal.setArguments({launcherUrl, dbusUnityProperties});
|
|
||||||
|
|
||||||
QDBusConnection::sessionBus().send(signal);
|
|
||||||
#endif // Q_OS_ANDROID
|
|
||||||
#else
|
|
||||||
qGuiApp->setBadgeNumber(count);
|
|
||||||
#endif // QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::isFlatpak() const
|
|
||||||
{
|
|
||||||
#ifdef NEOCHAT_FLATPAK
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountRegistry *Controller::accounts()
|
|
||||||
{
|
|
||||||
return m_accountManager->accounts();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Controller::loadFileContent(const QString &path) const
|
|
||||||
{
|
|
||||||
QUrl url(path);
|
|
||||||
QFile file(url.isLocalFile() ? url.toLocalFile() : url.toString());
|
|
||||||
file.open(QFile::ReadOnly);
|
|
||||||
return QString::fromLatin1(file.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::removeConnection(const QString &userId)
|
|
||||||
{
|
|
||||||
m_accountManager->dropConnection(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::revertToDefaultConfig()
|
|
||||||
{
|
|
||||||
const auto config = NeoChatConfig::self();
|
|
||||||
config->setDefaults();
|
|
||||||
config->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::isImageShown(const QString &eventId)
|
|
||||||
{
|
|
||||||
return m_shownImages.contains(eventId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::markImageShown(const QString &eventId)
|
|
||||||
{
|
|
||||||
m_shownImages.append(eventId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_controller.cpp"
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls as QQC2
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property NeoChatRoom currentRoom
|
|
||||||
readonly property var invitingMember: currentRoom.member(currentRoom.invitingUserId)
|
|
||||||
readonly property string inviteTimestamp: root.currentRoom.inviteTimestamp.toLocaleString(Qt.locale(), Locale.ShortFormat)
|
|
||||||
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
id: avatar
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
name: root.invitingMember.displayName
|
|
||||||
source: root.invitingMember.avatarUrl
|
|
||||||
color: root.invitingMember.color
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: !root.currentRoom.isDirectChat()
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: i18nc("@info:label 'Username' has invited you to this room at 'timestamp'.", "%1 has invited you to this room at %2.", root.invitingMember.displayName, root.inviteTimestamp)
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
text: root.currentRoom.displayName
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: root.currentRoom.isDirectChat()
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
text: root.currentRoom.displayName
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: i18nc("@info:label This user invited you to chat at 'timestamp'", "This user invited you to chat at %1.", root.inviteTimestamp)
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing * 4
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
id: acceptInviteDelegate
|
|
||||||
|
|
||||||
icon.name: "dialog-ok-symbolic"
|
|
||||||
text: i18nc("@action:button Accept this invite", "Accept Invite")
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
onClicked: root.currentRoom.acceptInvitation()
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: acceptInviteDelegate
|
|
||||||
below: rejectInviteDelegate
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
id: rejectInviteDelegate
|
|
||||||
|
|
||||||
icon.name: "dialog-cancel-symbolic"
|
|
||||||
text: i18nc("@action:button Reject this invite", "Reject Invite")
|
|
||||||
|
|
||||||
onClicked: RoomManager.leaveRoom(root.currentRoom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
id: blockUserCard
|
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
icon.name: "list-remove-symbolic"
|
|
||||||
text: i18nc("@action:button Block the user", "Block %1", root.invitingMember.displayName)
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
RoomManager.leaveRoom(root.currentRoom);
|
|
||||||
root.currentRoom.connection.addToIgnoredUsers(root.currentRoom.invitingUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
visible: root.currentRoom.connection.canCheckMutualRooms
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing * 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.Icon {
|
|
||||||
source: "help-hint-symbolic"
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.small
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.small
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
text: i18nc("@info:label", "You can reject invitations from unknown users under Security settings.")
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
|
|
||||||
// + 5 to prevent it from wrapping unnecessarily
|
|
||||||
Layout.maximumWidth: implicitWidth + 5
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls as QQC2
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
|
||||||
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
|
||||||
import org.kde.kirigamiaddons.delegates as Delegates
|
|
||||||
|
|
||||||
import Quotient
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
QQC2.Dialog {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property NeoChatRoom room
|
|
||||||
|
|
||||||
title: i18nc("@title: create new poll in the room", "Create Poll")
|
|
||||||
|
|
||||||
width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24)
|
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
topPadding: 0
|
|
||||||
bottomPadding: 0
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
FormCard.FormComboBoxDelegate {
|
|
||||||
id: pollTypeCombo
|
|
||||||
|
|
||||||
text: i18n("Poll type:")
|
|
||||||
currentIndex: 0
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "value"
|
|
||||||
model: [
|
|
||||||
{ value: PollKind.Disclosed, text: i18n("Open poll") },
|
|
||||||
{ value: PollKind.Undisclosed, text: i18n("Closed poll") }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
FormCard.FormTextDelegate {
|
|
||||||
verticalPadding: 0
|
|
||||||
text: pollTypeCombo.currentValue == 0 ? i18n("Voters can see the result as soon as they have voted") : i18n("Results are revealed only after the poll has closed")
|
|
||||||
}
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: questionTextField
|
|
||||||
label: i18n("Question:")
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
id: optionRepeater
|
|
||||||
|
|
||||||
model: ListModel {
|
|
||||||
id: optionModel
|
|
||||||
|
|
||||||
readonly property bool allValuesSet: {
|
|
||||||
for( var i = 0; i < optionModel.rowCount(); i++ ) {
|
|
||||||
if (optionModel.get(i).optionText.length <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
optionText: ""
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
optionText: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function values() {
|
|
||||||
let textValues = []
|
|
||||||
for( var i = 0; i < optionModel.rowCount(); i++ ) {
|
|
||||||
textValues.push(optionModel.get(i).optionText);
|
|
||||||
}
|
|
||||||
return textValues;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate: FormCard.AbstractFormDelegate {
|
|
||||||
id: optionDelegate
|
|
||||||
|
|
||||||
required property int index
|
|
||||||
required property string optionText
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
QQC2.Label {
|
|
||||||
id: optionLabel
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: i18nc("As in first answer option to the poll", "Option %1:", optionDelegate.index + 1)
|
|
||||||
elide: Text.ElideRight
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
Accessible.ignored: true
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
QQC2.TextField {
|
|
||||||
id: textField
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Accessible.name: optionLabel.text
|
|
||||||
onTextChanged: {
|
|
||||||
optionModel.set(optionDelegate.index, {optionText: text})
|
|
||||||
optionModel.allValuesSetChanged()
|
|
||||||
}
|
|
||||||
placeholderText: i18n("Enter option")
|
|
||||||
}
|
|
||||||
QQC2.ToolButton {
|
|
||||||
display: QQC2.AbstractButton.IconOnly
|
|
||||||
action: Kirigami.Action {
|
|
||||||
id: removeOptionAction
|
|
||||||
text: i18nc("@action:button", "Remove option")
|
|
||||||
icon.name: "edit-delete-remove"
|
|
||||||
onTriggered: optionModel.remove(optionDelegate.index)
|
|
||||||
}
|
|
||||||
QQC2.ToolTip {
|
|
||||||
text: removeOptionAction.text
|
|
||||||
delay: Kirigami.Units.toolTipDelay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delegates.RoundedItemDelegate {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
horizontalPadding: Kirigami.Units.largeSpacing * 2
|
|
||||||
leftInset: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
|
||||||
rightInset: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
highlighted: true
|
|
||||||
|
|
||||||
icon.name: "list-add"
|
|
||||||
text: i18nc("@action:button", "Add option")
|
|
||||||
|
|
||||||
onClicked: optionModel.append({optionText: ""})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer: QQC2.DialogButtonBox {
|
|
||||||
standardButtons: QQC2.Dialog.Cancel
|
|
||||||
|
|
||||||
QQC2.Button {
|
|
||||||
enabled: optionModel.allValuesSet && questionTextField.text.length > 0
|
|
||||||
text: i18nc("@action:button", "Send")
|
|
||||||
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
|
|
||||||
icon.name: "document-send"
|
|
||||||
onClicked: {
|
|
||||||
root.room.postPoll(pollTypeCombo.currentValue, questionTextField.text, optionModel.values())
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Ritchie Frodomar <ritchie@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
#include "texttospeechhelper.h"
|
|
||||||
|
|
||||||
void TextToSpeechHelper::speak(const QString &textToSpeak)
|
|
||||||
{
|
|
||||||
if (!m_speech) {
|
|
||||||
m_speech = new QTextToSpeech();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_speech->say(textToSpeak);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_texttospeechhelper.cpp"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Ritchie Frodomar <ritchie@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
#include <QtTextToSpeech>
|
|
||||||
|
|
||||||
class TextToSpeechHelper : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
QML_SINGLETON
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void speak(const QString &textToSpeak);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QTextToSpeech *m_speech = nullptr;
|
|
||||||
};
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
# SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
qt_add_library(Chatbar STATIC)
|
qt_add_library(chatbar STATIC)
|
||||||
ecm_add_qml_module(Chatbar GENERATE_PLUGIN_SOURCE
|
ecm_add_qml_module(chatbar GENERATE_PLUGIN_SOURCE
|
||||||
URI org.kde.neochat.chatbar
|
URI org.kde.neochat.chatbar
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/chatbar
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/chatbar
|
||||||
QML_FILES
|
QML_FILES
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import QtQuick.Controls as QQC2
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
import org.kde.neochat.libneochat as LibNeoChat
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A component for typing and sending chat messages.
|
* @brief A component for typing and sending chat messages.
|
||||||
@@ -103,7 +101,7 @@ QQC2.Control {
|
|||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
id: mapButton
|
id: mapButton
|
||||||
icon.name: "mark-location-symbolic"
|
icon.name: "globe"
|
||||||
property bool isBusy: false
|
property bool isBusy: false
|
||||||
text: i18n("Send a Location")
|
text: i18n("Send a Location")
|
||||||
displayHint: QQC2.AbstractButton.IconOnly
|
displayHint: QQC2.AbstractButton.IconOnly
|
||||||
@@ -115,20 +113,6 @@ QQC2.Control {
|
|||||||
}
|
}
|
||||||
tooltip: text
|
tooltip: text
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
|
||||||
id: pollButton
|
|
||||||
icon.name: "amarok_playcount"
|
|
||||||
property bool isBusy: false
|
|
||||||
text: i18nc("@action:button", "Create a Poll")
|
|
||||||
displayHint: QQC2.AbstractButton.IconOnly
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
newPollDialog.createObject(root.QQC2.Overlay.overlay, {
|
|
||||||
room: root.currentRoom
|
|
||||||
}).open();
|
|
||||||
}
|
|
||||||
tooltip: text
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
id: sendAction
|
id: sendAction
|
||||||
|
|
||||||
@@ -167,7 +151,7 @@ QQC2.Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
leftPadding: rightPadding
|
leftPadding: rightPadding
|
||||||
rightPadding: (root.width - chatBarSizeHelper.availableWidth) / 2
|
rightPadding: (root.width - chatBarSizeHelper.currentWidth) / 2
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
|
|
||||||
@@ -179,26 +163,15 @@ QQC2.Control {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Loader {
|
Loader {
|
||||||
id: replyLoader
|
id: paneLoader
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: Kirigami.Units.largeSpacing
|
Layout.margins: Kirigami.Units.largeSpacing
|
||||||
Layout.preferredHeight: active ? item.implicitHeight : 0
|
Layout.preferredHeight: active ? item.implicitHeight : 0
|
||||||
|
|
||||||
active: visible
|
active: visible
|
||||||
visible: root.currentRoom.mainCache.replyId.length > 0
|
visible: root.currentRoom.mainCache.replyId.length > 0 || root.currentRoom.mainCache.attachmentPath.length > 0
|
||||||
sourceComponent: replyPane
|
sourceComponent: root.currentRoom.mainCache.replyId.length > 0 ? replyPane : attachmentPane
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
id: attachLoader
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.margins: Kirigami.Units.largeSpacing
|
|
||||||
Layout.preferredHeight: active ? item.implicitHeight : 0
|
|
||||||
|
|
||||||
active: visible
|
|
||||||
visible: root.currentRoom.mainCache.attachmentPath.length > 0
|
|
||||||
sourceComponent: attachmentPane
|
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
QQC2.ScrollView {
|
QQC2.ScrollView {
|
||||||
@@ -310,12 +283,12 @@ QQC2.Control {
|
|||||||
if (quickFormatBar.visible && selectedText.length > 0) {
|
if (quickFormatBar.visible && selectedText.length > 0) {
|
||||||
quickFormatBar.close();
|
quickFormatBar.close();
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_Escape && completionMenu.visible) {
|
|
||||||
completionMenu.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onShortcutOverride: event => {
|
Keys.onShortcutOverride: event => {
|
||||||
if ((_private.chatBarCache.isReplying || _private.chatBarCache.attachmentPath.length > 0) && event.key === Qt.Key_Escape) {
|
if (completionMenu.visible) {
|
||||||
|
completionMenu.close();
|
||||||
|
} else if ((_private.chatBarCache.isReplying || _private.chatBarCache.attachmentPath.length > 0) && event.key === Qt.Key_Escape) {
|
||||||
_private.chatBarCache.attachmentPath = "";
|
_private.chatBarCache.attachmentPath = "";
|
||||||
_private.chatBarCache.replyId = "";
|
_private.chatBarCache.replyId = "";
|
||||||
_private.chatBarCache.threadId = "";
|
_private.chatBarCache.threadId = "";
|
||||||
@@ -355,14 +328,15 @@ QQC2.Control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibNeoChat.DelegateSizeHelper {
|
DelegateSizeHelper {
|
||||||
id: chatBarSizeHelper
|
id: chatBarSizeHelper
|
||||||
parentItem: root
|
|
||||||
startBreakpoint: Kirigami.Units.gridUnit * 46
|
startBreakpoint: Kirigami.Units.gridUnit * 46
|
||||||
endBreakpoint: Kirigami.Units.gridUnit * 66
|
endBreakpoint: Kirigami.Units.gridUnit * 66
|
||||||
startPercentWidth: 100
|
startPercentWidth: 100
|
||||||
endPercentWidth: NeoChatConfig.compactLayout ? 100 : 85
|
endPercentWidth: NeoChatConfig.compactLayout ? 100 : 85
|
||||||
maxWidth: NeoChatConfig.compactLayout ? root.width - Kirigami.Units.largeSpacing * 2 : Kirigami.Units.gridUnit * 60
|
maxWidth: NeoChatConfig.compactLayout ? -1 : Kirigami.Units.gridUnit * 60
|
||||||
|
|
||||||
|
parentWidth: root.width
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
@@ -374,11 +348,8 @@ QQC2.Control {
|
|||||||
id: replyComponent
|
id: replyComponent
|
||||||
replyEventId: _private.chatBarCache.replyId
|
replyEventId: _private.chatBarCache.replyId
|
||||||
replyAuthor: _private.chatBarCache.relationAuthor
|
replyAuthor: _private.chatBarCache.relationAuthor
|
||||||
replyContentModel: ContentProvider.contentModelForEvent(root.currentRoom, _private.chatBarCache.replyId, true)
|
replyContentModel: _private.chatBarCache.relationEventContentModel
|
||||||
Message.maxContentWidth: replyLoader.item.width
|
maxContentWidth: paneLoader.item.width
|
||||||
|
|
||||||
// When the user replies to a message and the preview is loaded, make sure the text field is focused again
|
|
||||||
Component.onCompleted: textField.forceActiveFocus(Qt.OtherFocusReason)
|
|
||||||
}
|
}
|
||||||
QQC2.Button {
|
QQC2.Button {
|
||||||
id: cancelButton
|
id: cancelButton
|
||||||
@@ -510,11 +481,6 @@ QQC2.Control {
|
|||||||
LocationChooser {}
|
LocationChooser {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: newPollDialog
|
|
||||||
NewPollDialog {}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompletionMenu {
|
CompletionMenu {
|
||||||
id: completionMenu
|
id: completionMenu
|
||||||
chatDocumentHandler: documentHandler
|
chatDocumentHandler: documentHandler
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ QQC2.Popup {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
chatDocumentHandler.completionModel.roomListModel = RoomManager.roomListModel;
|
chatDocumentHandler.completionModel.roomListModel = RoomManager.roomListModel;
|
||||||
chatDocumentHandler.completionModel.userListModel = RoomManager.userListModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function incrementIndex() {
|
function incrementIndex() {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ QQC2.Popup {
|
|||||||
property bool includeCustom: false
|
property bool includeCustom: false
|
||||||
property bool closeOnChosen: true
|
property bool closeOnChosen: true
|
||||||
property bool showQuickReaction: false
|
property bool showQuickReaction: false
|
||||||
property bool showStickers: true
|
|
||||||
|
|
||||||
signal chosen(string emoji)
|
signal chosen(string emoji)
|
||||||
|
|
||||||
@@ -72,7 +71,6 @@ QQC2.Popup {
|
|||||||
currentRoom: root.currentRoom
|
currentRoom: root.currentRoom
|
||||||
includeCustom: root.includeCustom
|
includeCustom: root.includeCustom
|
||||||
showQuickReaction: root.showQuickReaction
|
showQuickReaction: root.showQuickReaction
|
||||||
showStickers: root.showStickers
|
|
||||||
onChosen: emoji => {
|
onChosen: emoji => {
|
||||||
root.chosen(emoji);
|
root.chosen(emoji);
|
||||||
if (root.closeOnChosen) {
|
if (root.closeOnChosen) {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ ColumnLayout {
|
|||||||
|
|
||||||
property bool includeCustom: false
|
property bool includeCustom: false
|
||||||
property bool showQuickReaction: false
|
property bool showQuickReaction: false
|
||||||
property bool showStickers: true
|
|
||||||
|
|
||||||
readonly property var currentEmojiModel: {
|
readonly property var currentEmojiModel: {
|
||||||
if (includeCustom) {
|
if (includeCustom) {
|
||||||
@@ -44,7 +43,6 @@ ColumnLayout {
|
|||||||
id: types
|
id: types
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||||
visible: root.showStickers
|
|
||||||
|
|
||||||
background: null
|
background: null
|
||||||
actions: [
|
actions: [
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <Quotient/roommember.h>
|
#include <Quotient/roommember.h>
|
||||||
|
|
||||||
|
#include "chatdocumenthandler.h"
|
||||||
#include "eventhandler.h"
|
#include "eventhandler.h"
|
||||||
#include "models/actionsmodel.h"
|
#include "models/actionsmodel.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
@@ -87,6 +88,7 @@ void ChatBarCache::setReplyId(const QString &replyId)
|
|||||||
m_relationType = Reply;
|
m_relationType = Reply;
|
||||||
}
|
}
|
||||||
m_attachmentPath = QString();
|
m_attachmentPath = QString();
|
||||||
|
delete m_relationContentModel;
|
||||||
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
||||||
Q_EMIT attachmentPathChanged();
|
Q_EMIT attachmentPathChanged();
|
||||||
}
|
}
|
||||||
@@ -116,6 +118,7 @@ void ChatBarCache::setEditId(const QString &editId)
|
|||||||
m_relationType = Edit;
|
m_relationType = Edit;
|
||||||
}
|
}
|
||||||
m_attachmentPath = QString();
|
m_attachmentPath = QString();
|
||||||
|
delete m_relationContentModel;
|
||||||
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
||||||
Q_EMIT attachmentPathChanged();
|
Q_EMIT attachmentPathChanged();
|
||||||
}
|
}
|
||||||
@@ -158,6 +161,28 @@ QString ChatBarCache::relationMessage() const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageContentModel *ChatBarCache::relationEventContentModel()
|
||||||
|
{
|
||||||
|
if (parent() == nullptr) {
|
||||||
|
qWarning() << "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (m_relationId.isEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (m_relationContentModel != nullptr) {
|
||||||
|
return m_relationContentModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto room = dynamic_cast<NeoChatRoom *>(parent());
|
||||||
|
if (room == nullptr) {
|
||||||
|
qWarning() << "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
m_relationContentModel = new MessageContentModel(room, m_relationId, true);
|
||||||
|
return m_relationContentModel;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatBarCache::isThreaded() const
|
bool ChatBarCache::isThreaded() const
|
||||||
{
|
{
|
||||||
return !m_threadId.isEmpty();
|
return !m_threadId.isEmpty();
|
||||||
@@ -188,18 +213,11 @@ void ChatBarCache::setAttachmentPath(const QString &attachmentPath)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_attachmentPath = attachmentPath;
|
m_attachmentPath = attachmentPath;
|
||||||
Q_EMIT attachmentPathChanged();
|
|
||||||
|
|
||||||
#if (Quotient_VERSION_MINOR < 10 && Quotient_VERSION_PATCH < 3) || Quotient_VERSION_MINOR < 9
|
|
||||||
m_relationType = None;
|
m_relationType = None;
|
||||||
const auto oldEventId = std::exchange(m_relationId, QString());
|
const auto oldEventId = std::exchange(m_relationId, QString());
|
||||||
|
delete m_relationContentModel;
|
||||||
|
Q_EMIT attachmentPathChanged();
|
||||||
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
||||||
#else
|
|
||||||
if (m_relationType == Edit) {
|
|
||||||
const auto oldEventId = std::exchange(m_relationId, QString());
|
|
||||||
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatBarCache::clearRelations()
|
void ChatBarCache::clearRelations()
|
||||||
@@ -207,6 +225,7 @@ void ChatBarCache::clearRelations()
|
|||||||
const auto oldEventId = std::exchange(m_relationId, QString());
|
const auto oldEventId = std::exchange(m_relationId, QString());
|
||||||
const auto oldThreadId = std::exchange(m_threadId, QString());
|
const auto oldThreadId = std::exchange(m_threadId, QString());
|
||||||
m_attachmentPath = QString();
|
m_attachmentPath = QString();
|
||||||
|
delete m_relationContentModel;
|
||||||
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
Q_EMIT relationIdChanged(oldEventId, m_relationId);
|
||||||
Q_EMIT threadIdChanged(oldThreadId, m_threadId);
|
Q_EMIT threadIdChanged(oldThreadId, m_threadId);
|
||||||
Q_EMIT attachmentPathChanged();
|
Q_EMIT attachmentPathChanged();
|
||||||
@@ -217,6 +236,54 @@ QList<Mention> *ChatBarCache::mentions()
|
|||||||
return &m_mentions;
|
return &m_mentions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatBarCache::updateMentions(QQuickTextDocument *document, ChatDocumentHandler *documentHandler)
|
||||||
|
{
|
||||||
|
documentHandler->setDocument(document);
|
||||||
|
|
||||||
|
if (parent() == nullptr) {
|
||||||
|
qWarning() << "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_relationId.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto room = dynamic_cast<NeoChatRoom *>(parent());
|
||||||
|
if (room == nullptr) {
|
||||||
|
qWarning() << "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto event = room->findInTimeline(m_relationId); event != room->historyEdge()) {
|
||||||
|
if (const auto &roomMessageEvent = &*event->viewAs<Quotient::RoomMessageEvent>()) {
|
||||||
|
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown
|
||||||
|
const QRegularExpression re(uR"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\S]*)<\/a>)lit"_s);
|
||||||
|
|
||||||
|
m_mentions.clear();
|
||||||
|
|
||||||
|
int linkSize = 0;
|
||||||
|
auto matches = re.globalMatch(EventHandler::rawMessageBody(*roomMessageEvent));
|
||||||
|
while (matches.hasNext()) {
|
||||||
|
const QRegularExpressionMatch match = matches.next();
|
||||||
|
if (match.hasMatch()) {
|
||||||
|
const QString id = match.captured(1);
|
||||||
|
const QString name = match.captured(2);
|
||||||
|
|
||||||
|
const int position = match.capturedStart(0) - linkSize;
|
||||||
|
const int end = position + name.length();
|
||||||
|
linkSize += match.capturedLength(0) - name.length();
|
||||||
|
|
||||||
|
QTextCursor cursor(documentHandler->document()->textDocument());
|
||||||
|
cursor.setPosition(position);
|
||||||
|
cursor.setPosition(end, QTextCursor::KeepAnchor);
|
||||||
|
cursor.setKeepPositionOnInsert(true);
|
||||||
|
|
||||||
|
m_mentions.push_back(Mention{.cursor = cursor, .text = name, .start = position, .position = end, .id = id});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString ChatBarCache::savedText() const
|
QString ChatBarCache::savedText() const
|
||||||
{
|
{
|
||||||
return m_savedText;
|
return m_savedText;
|
||||||
@@ -235,19 +302,8 @@ void ChatBarCache::postMessage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isReply = !replyId().isEmpty();
|
|
||||||
std::optional<Quotient::EventRelation> relatesTo = std::nullopt;
|
|
||||||
|
|
||||||
if (!threadId().isEmpty()) {
|
|
||||||
relatesTo = Quotient::EventRelation::replyInThread(threadId(), !isReply, isReply ? replyId() : threadId());
|
|
||||||
} else if (!editId().isEmpty()) {
|
|
||||||
relatesTo = Quotient::EventRelation::replace(editId());
|
|
||||||
} else if (isReply) {
|
|
||||||
relatesTo = Quotient::EventRelation::replyTo(replyId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!attachmentPath().isEmpty()) {
|
if (!attachmentPath().isEmpty()) {
|
||||||
room->uploadFile(QUrl(attachmentPath()), sendText(), relatesTo);
|
room->uploadFile(QUrl(attachmentPath()), sendText());
|
||||||
clearCache();
|
clearCache();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -265,12 +321,22 @@ void ChatBarCache::postMessage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isReply = !replyId().isEmpty();
|
||||||
const auto replyIt = room->findInTimeline(replyId());
|
const auto replyIt = room->findInTimeline(replyId());
|
||||||
if (replyIt == room->historyEdge()) {
|
if (replyIt == room->historyEdge()) {
|
||||||
isReply = false;
|
isReply = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto content = std::make_unique<Quotient::EventContent::TextContent>(sendText, u"text/html"_s);
|
auto content = std::make_unique<Quotient::EventContent::TextContent>(sendText, u"text/html"_s);
|
||||||
|
std::optional<Quotient::EventRelation> relatesTo = std::nullopt;
|
||||||
|
|
||||||
|
if (!threadId().isEmpty()) {
|
||||||
|
relatesTo = Quotient::EventRelation::replyInThread(threadId(), !isReply, isReply ? replyId() : threadId());
|
||||||
|
} else if (!editId().isEmpty()) {
|
||||||
|
relatesTo = Quotient::EventRelation::replace(editId());
|
||||||
|
} else if (isReply) {
|
||||||
|
relatesTo = Quotient::EventRelation::replyTo(replyId());
|
||||||
|
}
|
||||||
|
|
||||||
room->post<Quotient::RoomMessageEvent>(text(), *std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result), std::move(content), relatesTo);
|
room->post<Quotient::RoomMessageEvent>(text(), *std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result), std::move(content), relatesTo);
|
||||||
clearCache();
|
clearCache();
|
||||||
@@ -8,11 +8,16 @@
|
|||||||
#include <QQuickTextDocument>
|
#include <QQuickTextDocument>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
|
|
||||||
|
#include "models/messagecontentmodel.h"
|
||||||
|
|
||||||
|
class ChatDocumentHandler;
|
||||||
|
|
||||||
namespace Quotient
|
namespace Quotient
|
||||||
{
|
{
|
||||||
class RoomMember;
|
class RoomMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines a user mention in the current chat or edit text.
|
* @brief Defines a user mention in the current chat or edit text.
|
||||||
*/
|
*/
|
||||||
@@ -106,6 +111,13 @@ class ChatBarCache : public QObject
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(QString relationMessage READ relationMessage NOTIFY relationIdChanged)
|
Q_PROPERTY(QString relationMessage READ relationMessage NOTIFY relationIdChanged)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The MessageContentModel for the related message.
|
||||||
|
*
|
||||||
|
* Will be nullptr if no related message.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(MessageContentModel *relationEventContentModel READ relationEventContentModel NOTIFY relationIdChanged)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether the chat bar is replying in a thread.
|
* @brief Whether the chat bar is replying in a thread.
|
||||||
*/
|
*/
|
||||||
@@ -155,6 +167,7 @@ public:
|
|||||||
Quotient::RoomMember relationAuthor() const;
|
Quotient::RoomMember relationAuthor() const;
|
||||||
|
|
||||||
QString relationMessage() const;
|
QString relationMessage() const;
|
||||||
|
MessageContentModel *relationEventContentModel();
|
||||||
|
|
||||||
bool isThreaded() const;
|
bool isThreaded() const;
|
||||||
QString threadId() const;
|
QString threadId() const;
|
||||||
@@ -175,6 +188,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
QList<Mention> *mentions();
|
QList<Mention> *mentions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the mentions in @p document when editing a message.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void updateMentions(QQuickTextDocument *document, ChatDocumentHandler *documentHandler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the saved chat bar text.
|
* @brief Get the saved chat bar text.
|
||||||
*/
|
*/
|
||||||
@@ -207,5 +225,7 @@ private:
|
|||||||
QList<Mention> m_mentions;
|
QList<Mention> m_mentions;
|
||||||
QString m_savedText;
|
QString m_savedText;
|
||||||
|
|
||||||
|
QPointer<MessageContentModel> m_relationContentModel;
|
||||||
|
|
||||||
void clearCache();
|
void clearCache();
|
||||||
};
|
};
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <Sonnet/Settings>
|
#include <Sonnet/Settings>
|
||||||
|
|
||||||
#include "chatdocumenthandler_logging.h"
|
#include "chatdocumenthandler_logging.h"
|
||||||
#include "eventhandler.h"
|
|
||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
@@ -118,10 +117,6 @@ ChatDocumentHandler::ChatDocumentHandler(QObject *parent)
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
connect(this, &ChatDocumentHandler::documentChanged, this, [this]() {
|
connect(this, &ChatDocumentHandler::documentChanged, this, [this]() {
|
||||||
if (!m_document) {
|
|
||||||
m_highlighter->setDocument(nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_highlighter->setDocument(m_document->textDocument());
|
m_highlighter->setDocument(m_document->textDocument());
|
||||||
});
|
});
|
||||||
connect(this, &ChatDocumentHandler::cursorPositionChanged, this, [this]() {
|
connect(this, &ChatDocumentHandler::cursorPositionChanged, this, [this]() {
|
||||||
@@ -361,43 +356,4 @@ void ChatDocumentHandler::setErrorColor(const QColor &color)
|
|||||||
Q_EMIT errorColorChanged();
|
Q_EMIT errorColorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatDocumentHandler::updateMentions(QQuickTextDocument *document, const QString &editId)
|
|
||||||
{
|
|
||||||
setDocument(document);
|
|
||||||
|
|
||||||
if (editId.isEmpty() || !m_chatBarCache || !m_room) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto event = m_room->findInTimeline(editId); event != m_room->historyEdge()) {
|
|
||||||
if (const auto &roomMessageEvent = &*event->viewAs<Quotient::RoomMessageEvent>()) {
|
|
||||||
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown
|
|
||||||
const QRegularExpression re(uR"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\S]*)<\/a>)lit"_s);
|
|
||||||
|
|
||||||
m_chatBarCache->mentions()->clear();
|
|
||||||
|
|
||||||
int linkSize = 0;
|
|
||||||
auto matches = re.globalMatch(EventHandler::rawMessageBody(*roomMessageEvent));
|
|
||||||
while (matches.hasNext()) {
|
|
||||||
const QRegularExpressionMatch match = matches.next();
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
const QString id = match.captured(1);
|
|
||||||
const QString name = match.captured(2);
|
|
||||||
|
|
||||||
const int position = match.capturedStart(0) - linkSize;
|
|
||||||
const int end = position + name.length();
|
|
||||||
linkSize += match.capturedLength(0) - name.length();
|
|
||||||
|
|
||||||
QTextCursor cursor(this->document()->textDocument());
|
|
||||||
cursor.setPosition(position);
|
|
||||||
cursor.setPosition(end, QTextCursor::KeepAnchor);
|
|
||||||
cursor.setKeepPositionOnInsert(true);
|
|
||||||
|
|
||||||
pushMention(Mention{.cursor = cursor, .text = name, .start = position, .position = end, .id = id});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_chatdocumenthandler.cpp"
|
#include "moc_chatdocumenthandler.cpp"
|
||||||
@@ -141,11 +141,6 @@ public:
|
|||||||
[[nodiscard]] QColor errorColor() const;
|
[[nodiscard]] QColor errorColor() const;
|
||||||
void setErrorColor(const QColor &color);
|
void setErrorColor(const QColor &color);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update the mentions in @p document when editing a message.
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE void updateMentions(QQuickTextDocument *document, const QString &editId);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void documentChanged();
|
void documentChanged();
|
||||||
void cursorPositionChanged();
|
void cursorPositionChanged();
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
ColorSchemer::ColorSchemer(QObject *parent)
|
ColorSchemer::ColorSchemer(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
KColorSchemeManager::instance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorSchemer::~ColorSchemer()
|
ColorSchemer::~ColorSchemer()
|
||||||
459
src/controller.cpp
Normal file
459
src/controller.cpp
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
|
||||||
|
// SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
#include "controller.h"
|
||||||
|
|
||||||
|
#include <qt6keychain/keychain.h>
|
||||||
|
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <Quotient/csapi/notifications.h>
|
||||||
|
#include <Quotient/qt_connection_util.h>
|
||||||
|
#include <Quotient/settings.h>
|
||||||
|
|
||||||
|
#include "neochatconfig.h"
|
||||||
|
#include "neochatconnection.h"
|
||||||
|
#include "neochatroom.h"
|
||||||
|
#include "notificationsmanager.h"
|
||||||
|
#include "proxycontroller.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||||
|
#include "trayicon.h"
|
||||||
|
#elif !defined(Q_OS_ANDROID)
|
||||||
|
#include "trayicon_sni.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDBusMessage>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
|
#include <kunifiedpush/connector.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool testMode = false;
|
||||||
|
|
||||||
|
using namespace Quotient;
|
||||||
|
|
||||||
|
Controller::Controller(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
Connection::setRoomType<NeoChatRoom>();
|
||||||
|
|
||||||
|
ProxyController::instance().setApplicationProxy();
|
||||||
|
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
setQuitOnLastWindowClosed();
|
||||||
|
connect(NeoChatConfig::self(), &NeoChatConfig::SystemTrayChanged, this, &Controller::setQuitOnLastWindowClosed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!testMode) {
|
||||||
|
QTimer::singleShot(0, this, [this] {
|
||||||
|
invokeLogin();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
auto c = new NeoChatConnection(this);
|
||||||
|
c->assumeIdentity(u"@user:localhost:1234"_s, u"device_1234"_s, u"token_1234"_s);
|
||||||
|
connect(c, &Connection::connected, this, [c, this]() {
|
||||||
|
m_accountRegistry.add(c);
|
||||||
|
c->syncLoop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(QGuiApplication::instance(), &QCoreApplication::aboutToQuit, QGuiApplication::instance(), [this] {
|
||||||
|
delete m_trayIcon;
|
||||||
|
NeoChatConfig::self()->save();
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifndef Q_OS_WINDOWS
|
||||||
|
const auto unixExitHandler = [](int) -> void {
|
||||||
|
QCoreApplication::quit();
|
||||||
|
};
|
||||||
|
|
||||||
|
const int quitSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||||
|
|
||||||
|
sigset_t blockingMask;
|
||||||
|
sigemptyset(&blockingMask);
|
||||||
|
for (const auto sig : quitSignals) {
|
||||||
|
sigaddset(&blockingMask, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigaction sa;
|
||||||
|
sa.sa_handler = unixExitHandler;
|
||||||
|
sa.sa_mask = blockingMask;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
|
||||||
|
for (auto sig : quitSignals) {
|
||||||
|
sigaction(sig, &sa, nullptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int oldAccountCount = 0;
|
||||||
|
connect(&m_accountRegistry, &AccountRegistry::accountCountChanged, this, [this]() {
|
||||||
|
if (m_accountRegistry.size() > oldAccountCount) {
|
||||||
|
auto connection = dynamic_cast<NeoChatConnection *>(m_accountRegistry.accounts()[m_accountRegistry.size() - 1]);
|
||||||
|
connect(
|
||||||
|
connection,
|
||||||
|
&NeoChatConnection::syncDone,
|
||||||
|
this,
|
||||||
|
[this, connection] {
|
||||||
|
if (!m_endpoint.isEmpty()) {
|
||||||
|
connection->setupPushNotifications(m_endpoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
}
|
||||||
|
oldAccountCount = m_accountRegistry.size();
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
|
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
||||||
|
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
|
||||||
|
m_endpoint = endpoint;
|
||||||
|
for (auto "ientConnection : m_accountRegistry) {
|
||||||
|
auto connection = dynamic_cast<NeoChatConnection *>(quotientConnection);
|
||||||
|
connection->setupPushNotifications(endpoint);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connector->registerClient(
|
||||||
|
i18nc("The reason for using push notifications, as in: '[Push notifications are used for] Receiving notifications for new messages'",
|
||||||
|
"Receiving notifications for new messages"));
|
||||||
|
|
||||||
|
m_endpoint = connector->endpoint();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller &Controller::instance()
|
||||||
|
{
|
||||||
|
static Controller _instance;
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::addConnection(NeoChatConnection *c)
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(c, __FUNCTION__, "Attempt to add a null connection");
|
||||||
|
|
||||||
|
m_accountRegistry.add(c);
|
||||||
|
|
||||||
|
c->setLazyLoading(true);
|
||||||
|
|
||||||
|
connect(c, &NeoChatConnection::syncDone, this, [c] {
|
||||||
|
c->sync(30000);
|
||||||
|
c->saveState();
|
||||||
|
});
|
||||||
|
connect(c, &NeoChatConnection::loggedOut, this, [this, c] {
|
||||||
|
if (accounts().count() > 1) {
|
||||||
|
// Only set the connection if the account being logged out is currently active
|
||||||
|
if (c == activeConnection()) {
|
||||||
|
setActiveConnection(dynamic_cast<NeoChatConnection *>(accounts().accounts()[0]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setActiveConnection(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
dropConnection(c);
|
||||||
|
});
|
||||||
|
connect(c, &NeoChatConnection::badgeNotificationCountChanged, this, &Controller::updateBadgeNotificationCount);
|
||||||
|
connect(c, &NeoChatConnection::syncDone, this, [this, c]() {
|
||||||
|
m_notificationsManager.handleNotifications(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
c->sync();
|
||||||
|
|
||||||
|
Q_EMIT connectionAdded(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::dropConnection(NeoChatConnection *c)
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(c, __FUNCTION__, "Attempt to drop a null connection");
|
||||||
|
|
||||||
|
c->disconnect(this);
|
||||||
|
c->disconnect(&m_notificationsManager);
|
||||||
|
m_accountRegistry.drop(c);
|
||||||
|
Q_EMIT connectionDropped(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::invokeLogin()
|
||||||
|
{
|
||||||
|
const auto accounts = SettingsGroup("Accounts"_L1).childGroups();
|
||||||
|
for (const auto &accountId : accounts) {
|
||||||
|
AccountSettings account{accountId};
|
||||||
|
m_accountsLoading += accountId;
|
||||||
|
Q_EMIT accountsLoadingChanged();
|
||||||
|
if (!account.homeserver().isEmpty()) {
|
||||||
|
auto accessTokenLoadingJob = loadAccessTokenFromKeyChain(account.userId());
|
||||||
|
connect(accessTokenLoadingJob, &QKeychain::Job::finished, this, [accountId, this, accessTokenLoadingJob](QKeychain::Job *) {
|
||||||
|
AccountSettings account{accountId};
|
||||||
|
QString accessToken;
|
||||||
|
if (accessTokenLoadingJob->error() == QKeychain::Error::NoError) {
|
||||||
|
accessToken = QString::fromLatin1(accessTokenLoadingJob->binaryData());
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto connection = new NeoChatConnection(account.homeserver());
|
||||||
|
m_connectionsLoading[accountId] = connection;
|
||||||
|
connect(connection, &NeoChatConnection::connected, this, [this, connection, accountId] {
|
||||||
|
connection->loadState();
|
||||||
|
if (connection->allRooms().size() == 0 || connection->allRooms()[0]->currentState().get<RoomCreateEvent>()) {
|
||||||
|
addConnection(connection);
|
||||||
|
m_accountsLoading.removeAll(connection->userId());
|
||||||
|
m_connectionsLoading.remove(accountId);
|
||||||
|
Q_EMIT accountsLoadingChanged();
|
||||||
|
} else {
|
||||||
|
connect(
|
||||||
|
connection->allRooms()[0],
|
||||||
|
&Room::baseStateLoaded,
|
||||||
|
this,
|
||||||
|
[this, connection, accountId]() {
|
||||||
|
addConnection(connection);
|
||||||
|
m_accountsLoading.removeAll(connection->userId());
|
||||||
|
m_connectionsLoading.remove(accountId);
|
||||||
|
Q_EMIT accountsLoadingChanged();
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connection->assumeIdentity(account.userId(), account.deviceId(), accessToken);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const QString &userId)
|
||||||
|
{
|
||||||
|
qDebug() << "Reading access token from the keychain for" << userId;
|
||||||
|
auto job = new QKeychain::ReadPasswordJob(qAppName(), this);
|
||||||
|
job->setKey(userId);
|
||||||
|
|
||||||
|
// Handling of errors
|
||||||
|
connect(job, &QKeychain::Job::finished, this, [this, job]() {
|
||||||
|
if (job->error() == QKeychain::Error::NoError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (job->error()) {
|
||||||
|
case QKeychain::EntryNotFound:
|
||||||
|
Q_EMIT errorOccured(i18n("Access token wasn't found: Maybe it was deleted?"));
|
||||||
|
break;
|
||||||
|
case QKeychain::AccessDeniedByUser:
|
||||||
|
case QKeychain::AccessDenied:
|
||||||
|
Q_EMIT errorOccured(i18n("Access to keychain was denied: Please allow NeoChat to read the access token"));
|
||||||
|
break;
|
||||||
|
case QKeychain::NoBackendAvailable:
|
||||||
|
Q_EMIT errorOccured(i18n("No keychain available: Please install a keychain, e.g. KWallet or GNOME keyring on Linux"));
|
||||||
|
break;
|
||||||
|
case QKeychain::OtherError:
|
||||||
|
Q_EMIT errorOccured(i18n("Unable to read access token: %1", job->errorString()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
job->start();
|
||||||
|
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::saveAccessTokenToKeyChain(const QString &userId, const QByteArray &accessToken)
|
||||||
|
{
|
||||||
|
qDebug() << "Save the access token to the keychain for " << userId;
|
||||||
|
auto job = new QKeychain::WritePasswordJob(qAppName());
|
||||||
|
job->setAutoDelete(true);
|
||||||
|
job->setKey(userId);
|
||||||
|
job->setBinaryData(accessToken);
|
||||||
|
connect(job, &QKeychain::WritePasswordJob::finished, this, [job]() {
|
||||||
|
if (job->error()) {
|
||||||
|
qWarning() << "Could not save access token to the keychain: " << qPrintable(job->errorString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
job->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::supportSystemTray() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
auto de = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP"));
|
||||||
|
return de != u"GNOME"_s && de != u"Pantheon"_s;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::setQuitOnLastWindowClosed()
|
||||||
|
{
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
if (supportSystemTray() && NeoChatConfig::self()->systemTray()) {
|
||||||
|
m_trayIcon = new TrayIcon(this);
|
||||||
|
m_trayIcon->show();
|
||||||
|
} else {
|
||||||
|
if (m_trayIcon) {
|
||||||
|
delete m_trayIcon;
|
||||||
|
m_trayIcon = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
NeoChatConnection *Controller::activeConnection() const
|
||||||
|
{
|
||||||
|
if (m_connection.isNull()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::setActiveConnection(NeoChatConnection *connection)
|
||||||
|
{
|
||||||
|
if (connection == m_connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_connection != nullptr) {
|
||||||
|
m_connection->disconnect(this);
|
||||||
|
m_connection->disconnect(&m_notificationsManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connection = connection;
|
||||||
|
|
||||||
|
if (m_connection != nullptr) {
|
||||||
|
m_connection->refreshBadgeNotificationCount();
|
||||||
|
updateBadgeNotificationCount(m_connection, m_connection->badgeNotificationCount());
|
||||||
|
|
||||||
|
connect(m_connection, &NeoChatConnection::errorOccured, this, &Controller::errorOccured);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT activeConnectionChanged(m_connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::listenForNotifications()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
|
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
||||||
|
|
||||||
|
auto timer = new QTimer();
|
||||||
|
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
||||||
|
|
||||||
|
connect(connector, &KUnifiedPush::Connector::messageReceived, [timer](const QByteArray &data) {
|
||||||
|
instance().m_notificationsManager.postPushNotification(data);
|
||||||
|
timer->stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait five seconds to see if we received any messages or this happened to be an erroneous activation.
|
||||||
|
// Otherwise, messageReceived is never activated, and this daemon could stick around forever.
|
||||||
|
timer->start(5000);
|
||||||
|
|
||||||
|
connector->registerClient(i18n("Receiving push notifications"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::clearInvitationNotification(const QString &roomId)
|
||||||
|
{
|
||||||
|
m_notificationsManager.clearInvitationNotification(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::updateBadgeNotificationCount(NeoChatConnection *connection, int count)
|
||||||
|
{
|
||||||
|
if (connection == m_connection) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
// copied from Telegram desktop
|
||||||
|
const auto launcherUrl = "application://org.kde.neochat.desktop"_L1;
|
||||||
|
// Gnome requires that count is a 64bit integer
|
||||||
|
const qint64 counterSlice = std::min(count, 9999);
|
||||||
|
QVariantMap dbusUnityProperties;
|
||||||
|
|
||||||
|
if (counterSlice > 0) {
|
||||||
|
dbusUnityProperties["count"_L1] = counterSlice;
|
||||||
|
dbusUnityProperties["count-visible"_L1] = true;
|
||||||
|
} else {
|
||||||
|
dbusUnityProperties["count-visible"_L1] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto signal = QDBusMessage::createSignal("/com/canonical/unity/launcherentry/neochat"_L1, "com.canonical.Unity.LauncherEntry"_L1, "Update"_L1);
|
||||||
|
|
||||||
|
signal.setArguments({launcherUrl, dbusUnityProperties});
|
||||||
|
|
||||||
|
QDBusConnection::sessionBus().send(signal);
|
||||||
|
#endif // Q_OS_ANDROID
|
||||||
|
#else
|
||||||
|
qGuiApp->setBadgeNumber(count);
|
||||||
|
#endif // QT_VERSION_CHECK(6, 6, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isFlatpak() const
|
||||||
|
{
|
||||||
|
#ifdef NEOCHAT_FLATPAK
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountRegistry &Controller::accounts()
|
||||||
|
{
|
||||||
|
return m_accountRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Controller::loadFileContent(const QString &path) const
|
||||||
|
{
|
||||||
|
QUrl url(path);
|
||||||
|
QFile file(url.isLocalFile() ? url.toLocalFile() : url.toString());
|
||||||
|
file.open(QFile::ReadOnly);
|
||||||
|
return QString::fromLatin1(file.readAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::setTestMode(bool test)
|
||||||
|
{
|
||||||
|
testMode = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::removeConnection(const QString &userId)
|
||||||
|
{
|
||||||
|
// When loadAccessTokenFromKeyChain() fails m_connectionsLoading won't have an
|
||||||
|
// entry for it so we need to check both separately.
|
||||||
|
if (m_accountsLoading.contains(userId)) {
|
||||||
|
m_accountsLoading.removeAll(userId);
|
||||||
|
Q_EMIT accountsLoadingChanged();
|
||||||
|
}
|
||||||
|
if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) {
|
||||||
|
auto connection = m_connectionsLoading[userId];
|
||||||
|
SettingsGroup("Accounts"_L1).remove(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::csSupported() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::revertToDefaultConfig()
|
||||||
|
{
|
||||||
|
const auto config = NeoChatConfig::self();
|
||||||
|
config->setDefaults();
|
||||||
|
config->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isImageShown(const QString &eventId)
|
||||||
|
{
|
||||||
|
return m_shownImages.contains(eventId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::markImageShown(const QString &eventId)
|
||||||
|
{
|
||||||
|
m_shownImages.append(eventId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_controller.cpp"
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
#include "accountmanager.h"
|
|
||||||
#include "neochatconnection.h"
|
#include "neochatconnection.h"
|
||||||
#include "notificationsmanager.h"
|
#include "notificationsmanager.h"
|
||||||
#include <Quotient/accountregistry.h>
|
#include <Quotient/accountregistry.h>
|
||||||
@@ -49,7 +48,9 @@ class Controller : public QObject
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(bool isFlatpak READ isFlatpak CONSTANT)
|
Q_PROPERTY(bool isFlatpak READ isFlatpak CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(QStringList accountsLoading READ accountsLoading NOTIFY accountsLoadingChanged)
|
Q_PROPERTY(QStringList accountsLoading MEMBER m_accountsLoading NOTIFY accountsLoadingChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool csSupported READ csSupported CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Controller &instance();
|
static Controller &instance();
|
||||||
@@ -59,12 +60,23 @@ public:
|
|||||||
return &instance();
|
return &instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAccountManager(AccountManager *manager);
|
|
||||||
|
|
||||||
[[nodiscard]] NeoChatConnection *activeConnection() const;
|
|
||||||
void setActiveConnection(NeoChatConnection *connection);
|
void setActiveConnection(NeoChatConnection *connection);
|
||||||
|
[[nodiscard]] NeoChatConnection *activeConnection() const;
|
||||||
|
|
||||||
QStringList accountsLoading() const;
|
/**
|
||||||
|
* @brief Add a new connection to the account registry.
|
||||||
|
*/
|
||||||
|
void addConnection(NeoChatConnection *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drop a connection from the account registry.
|
||||||
|
*/
|
||||||
|
void dropConnection(NeoChatConnection *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save an access token to the keychain for the given account.
|
||||||
|
*/
|
||||||
|
void saveAccessTokenToKeyChain(const QString &userId, const QByteArray &accessToken);
|
||||||
|
|
||||||
[[nodiscard]] bool supportSystemTray() const;
|
[[nodiscard]] bool supportSystemTray() const;
|
||||||
|
|
||||||
@@ -85,10 +97,14 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE QString loadFileContent(const QString &path) const;
|
Q_INVOKABLE QString loadFileContent(const QString &path) const;
|
||||||
|
|
||||||
Quotient::AccountRegistry *accounts();
|
Quotient::AccountRegistry &accounts();
|
||||||
|
|
||||||
|
static void setTestMode(bool testMode);
|
||||||
|
|
||||||
Q_INVOKABLE void removeConnection(const QString &userId);
|
Q_INVOKABLE void removeConnection(const QString &userId);
|
||||||
|
|
||||||
|
bool csSupported() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Revert all configuration values to their default.
|
* @brief Revert all configuration values to their default.
|
||||||
*
|
*
|
||||||
@@ -103,22 +119,23 @@ public:
|
|||||||
private:
|
private:
|
||||||
explicit Controller(QObject *parent = nullptr);
|
explicit Controller(QObject *parent = nullptr);
|
||||||
|
|
||||||
QPointer<AccountManager> m_accountManager;
|
|
||||||
void initConnection(NeoChatConnection *connection);
|
|
||||||
void teardownConnection(NeoChatConnection *connection);
|
|
||||||
void initActiveConnection(NeoChatConnection *oldConnection, NeoChatConnection *newConnection);
|
|
||||||
|
|
||||||
QPointer<NeoChatConnection> m_connection;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
TrayIcon *m_trayIcon = nullptr;
|
TrayIcon *m_trayIcon = nullptr;
|
||||||
|
|
||||||
|
QKeychain::ReadPasswordJob *loadAccessTokenFromKeyChain(const QString &account);
|
||||||
|
|
||||||
|
Quotient::AccountRegistry m_accountRegistry;
|
||||||
|
QStringList m_accountsLoading;
|
||||||
|
QMap<QString, QPointer<NeoChatConnection>> m_connectionsLoading;
|
||||||
QString m_endpoint;
|
QString m_endpoint;
|
||||||
QStringList m_shownImages;
|
QStringList m_shownImages;
|
||||||
|
|
||||||
NotificationsManager m_notificationsManager;
|
NotificationsManager m_notificationsManager;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
void invokeLogin();
|
||||||
void setQuitOnLastWindowClosed();
|
void setQuitOnLastWindowClosed();
|
||||||
void updateBadgeNotificationCount(int count);
|
void updateBadgeNotificationCount(NeoChatConnection *connection, int count);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
@@ -129,6 +146,4 @@ Q_SIGNALS:
|
|||||||
void connectionDropped(NeoChatConnection *connection);
|
void connectionDropped(NeoChatConnection *connection);
|
||||||
void activeConnectionChanged(NeoChatConnection *connection);
|
void activeConnectionChanged(NeoChatConnection *connection);
|
||||||
void accountsLoadingChanged();
|
void accountsLoadingChanged();
|
||||||
|
|
||||||
void globalUrlPreviewDefaultChanged();
|
|
||||||
};
|
};
|
||||||
@@ -12,56 +12,20 @@ DelegateSizeHelper::DelegateSizeHelper(QObject *parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickItem *DelegateSizeHelper::parentItem() const
|
qreal DelegateSizeHelper::parentWidth() const
|
||||||
{
|
{
|
||||||
return m_parentItem;
|
return m_parentWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelper::setParentItem(QQuickItem *parentItem)
|
void DelegateSizeHelper::setParentWidth(qreal parentWidth)
|
||||||
{
|
{
|
||||||
if (parentItem == m_parentItem) {
|
if (parentWidth == m_parentWidth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_parentItem = parentItem;
|
m_parentWidth = parentWidth;
|
||||||
|
Q_EMIT parentWidthChanged();
|
||||||
if (m_parentItem) {
|
Q_EMIT currentPercentageWidthChanged();
|
||||||
connect(m_parentItem, &QQuickItem::widthChanged, this, [this]() {
|
Q_EMIT currentWidthChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT parentItemChanged();
|
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal DelegateSizeHelper::leftPadding() const
|
|
||||||
{
|
|
||||||
return m_leftPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelegateSizeHelper::setLeftPadding(qreal leftPadding)
|
|
||||||
{
|
|
||||||
if (qFuzzyCompare(leftPadding, m_leftPadding)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_leftPadding = leftPadding;
|
|
||||||
Q_EMIT leftPaddingChanged();
|
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal DelegateSizeHelper::rightPadding() const
|
|
||||||
{
|
|
||||||
return m_rightPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelegateSizeHelper::setRightPadding(qreal rightPadding)
|
|
||||||
{
|
|
||||||
if (qFuzzyCompare(rightPadding, m_rightPadding)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_rightPadding = rightPadding;
|
|
||||||
Q_EMIT rightPaddingChanged();
|
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::startBreakpoint() const
|
qreal DelegateSizeHelper::startBreakpoint() const
|
||||||
@@ -76,7 +40,6 @@ void DelegateSizeHelper::setStartBreakpoint(qreal startBreakpoint)
|
|||||||
}
|
}
|
||||||
m_startBreakpoint = startBreakpoint;
|
m_startBreakpoint = startBreakpoint;
|
||||||
Q_EMIT startBreakpointChanged();
|
Q_EMIT startBreakpointChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::endBreakpoint() const
|
qreal DelegateSizeHelper::endBreakpoint() const
|
||||||
@@ -91,7 +54,6 @@ void DelegateSizeHelper::setEndBreakpoint(qreal endBreakpoint)
|
|||||||
}
|
}
|
||||||
m_endBreakpoint = endBreakpoint;
|
m_endBreakpoint = endBreakpoint;
|
||||||
Q_EMIT endBreakpointChanged();
|
Q_EMIT endBreakpointChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelegateSizeHelper::startPercentWidth() const
|
int DelegateSizeHelper::startPercentWidth() const
|
||||||
@@ -106,7 +68,6 @@ void DelegateSizeHelper::setStartPercentWidth(int startPercentWidth)
|
|||||||
}
|
}
|
||||||
m_startPercentWidth = startPercentWidth;
|
m_startPercentWidth = startPercentWidth;
|
||||||
Q_EMIT startPercentWidthChanged();
|
Q_EMIT startPercentWidthChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelegateSizeHelper::endPercentWidth() const
|
int DelegateSizeHelper::endPercentWidth() const
|
||||||
@@ -121,19 +82,11 @@ void DelegateSizeHelper::setEndPercentWidth(int endPercentWidth)
|
|||||||
}
|
}
|
||||||
m_endPercentWidth = endPercentWidth;
|
m_endPercentWidth = endPercentWidth;
|
||||||
Q_EMIT endPercentWidthChanged();
|
Q_EMIT endPercentWidthChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::maxWidth() const
|
qreal DelegateSizeHelper::maxWidth() const
|
||||||
{
|
{
|
||||||
if (m_maxWidth == std::nullopt) {
|
return m_maxWidth;
|
||||||
if (m_parentItem) {
|
|
||||||
return m_parentItem->width();
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *m_maxWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelper::setMaxWidth(qreal maxWidth)
|
void DelegateSizeHelper::setMaxWidth(qreal maxWidth)
|
||||||
@@ -143,26 +96,23 @@ void DelegateSizeHelper::setMaxWidth(qreal maxWidth)
|
|||||||
}
|
}
|
||||||
m_maxWidth = maxWidth;
|
m_maxWidth = maxWidth;
|
||||||
Q_EMIT maxWidthChanged();
|
Q_EMIT maxWidthChanged();
|
||||||
calcWidthsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::maxAvailableWidth() const
|
int DelegateSizeHelper::calculateCurrentPercentageWidth() const
|
||||||
{
|
{
|
||||||
if (!m_parentItem || qFuzzyCompare(m_parentItem->width(), 0)) {
|
// Don't do anything if m_parentWidth hasn't been set yet.
|
||||||
return 0;
|
if (m_parentWidth < 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return std::max(m_parentItem->width() - m_leftPadding - m_rightPadding, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DelegateSizeHelper::calculateAvailablePercentageWidth() const
|
|
||||||
{
|
|
||||||
// Don't bother with calculations for a horizontal line.
|
// Don't bother with calculations for a horizontal line.
|
||||||
if (m_startPercentWidth == m_endPercentWidth) {
|
if (m_startPercentWidth == m_endPercentWidth) {
|
||||||
return m_startPercentWidth;
|
return m_startPercentWidth;
|
||||||
}
|
}
|
||||||
// Dividing by zero is a bad idea.
|
// Dividing by zero is a bad idea.
|
||||||
if (m_startBreakpoint == m_endBreakpoint || qFuzzyCompare(maxAvailableWidth(), 0)) {
|
if (m_startBreakpoint == m_endBreakpoint) {
|
||||||
return 100;
|
qWarning() << "DelegateSizeHelper::calculateCurrentPercentageWidth() - m_startBreakpoint is equal to m_endBreakpoint this would lead to divide by "
|
||||||
|
"zero, aborting";
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fit to y = mx + c
|
// Fit to y = mx + c
|
||||||
@@ -174,35 +124,32 @@ int DelegateSizeHelper::calculateAvailablePercentageWidth() const
|
|||||||
int maxPercentWidth = endPercentBigger ? m_endPercentWidth : m_startPercentWidth;
|
int maxPercentWidth = endPercentBigger ? m_endPercentWidth : m_startPercentWidth;
|
||||||
int minPercentWidth = endPercentBigger ? m_startPercentWidth : m_endPercentWidth;
|
int minPercentWidth = endPercentBigger ? m_startPercentWidth : m_endPercentWidth;
|
||||||
|
|
||||||
int calcPercentWidth = std::round(m * maxAvailableWidth() + c);
|
int calcPercentWidth = std::round(m * m_parentWidth + c);
|
||||||
return std::clamp(calcPercentWidth, minPercentWidth, maxPercentWidth);
|
return std::clamp(calcPercentWidth, minPercentWidth, maxPercentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelegateSizeHelper::availablePercentageWidth() const
|
int DelegateSizeHelper::currentPercentageWidth() const
|
||||||
{
|
{
|
||||||
return calculateAvailablePercentageWidth();
|
return calculateCurrentPercentageWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::availableWidth() const
|
qreal DelegateSizeHelper::currentWidth() const
|
||||||
{
|
{
|
||||||
qreal absoluteWidth = maxAvailableWidth() * availablePercentageWidth() * 0.01;
|
if (m_parentWidth < 0) {
|
||||||
return std::round(std::min(absoluteWidth, maxWidth()));
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
int percentWidth = calculateCurrentPercentageWidth();
|
||||||
|
// - 1 means bad input values so don't try to calculate.
|
||||||
|
if (percentWidth == -1) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
qreal DelegateSizeHelper::leftX() const
|
qreal absoluteWidth = m_parentWidth * percentWidth * 0.01;
|
||||||
{
|
if (m_maxWidth < 0.0) {
|
||||||
return m_leftPadding + (maxAvailableWidth() - availableWidth()) / 2;
|
return std::round(absoluteWidth);
|
||||||
}
|
} else {
|
||||||
|
return std::round(std::min(absoluteWidth, m_maxWidth));
|
||||||
qreal DelegateSizeHelper::rightX() const
|
}
|
||||||
{
|
|
||||||
return m_leftPadding + maxAvailableWidth() - (maxAvailableWidth() - availableWidth()) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelegateSizeHelper::calcWidthsChanged()
|
|
||||||
{
|
|
||||||
Q_EMIT availablePercentageWidthChanged();
|
|
||||||
Q_EMIT availableWidthChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_delegatesizehelper.cpp"
|
#include "moc_delegatesizehelper.cpp"
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QQuickItem>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class DelegateSizeHelper
|
* @class DelegateSizeHelper
|
||||||
@@ -28,25 +27,9 @@ class DelegateSizeHelper : public QObject
|
|||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The parent item that defines the available content area.
|
* @brief The width of the component's parent.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(QQuickItem *parentItem READ parentItem WRITE setParentItem NOTIFY parentItemChanged)
|
Q_PROPERTY(qreal parentWidth READ parentWidth WRITE setParentWidth NOTIFY parentWidthChanged)
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The amount of padding to be removed from the left of the available content area.
|
|
||||||
*
|
|
||||||
* The padding is removed before calculating the available width, i.e. max available width
|
|
||||||
* at 100% is equal to parent width minus padding.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding NOTIFY leftPaddingChanged)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The amount of padding to be removed from the right of the available content area.
|
|
||||||
*
|
|
||||||
* The padding is removed before calculating the available width, i.e. max available width
|
|
||||||
* at 100% is equal to parent width minus padding.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding NOTIFY rightPaddingChanged)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The width (in px) when the width percentage should start to transition.
|
* @brief The width (in px) when the width percentage should start to transition.
|
||||||
@@ -84,7 +67,7 @@ class DelegateSizeHelper : public QObject
|
|||||||
*
|
*
|
||||||
* @sa parentWidth, startBreakpoint, endBreakpoint
|
* @sa parentWidth, startBreakpoint, endBreakpoint
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(int availablePercentageWidth READ availablePercentageWidth NOTIFY availableWidthChanged)
|
Q_PROPERTY(int currentPercentageWidth READ currentPercentageWidth NOTIFY currentPercentageWidthChanged)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The width (in px) of the component at the current parentWidth.
|
* @brief The width (in px) of the component at the current parentWidth.
|
||||||
@@ -93,72 +76,50 @@ class DelegateSizeHelper : public QObject
|
|||||||
*
|
*
|
||||||
* @sa parentWidth
|
* @sa parentWidth
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(qreal availableWidth READ availableWidth NOTIFY availableWidthChanged)
|
Q_PROPERTY(qreal currentWidth READ currentWidth NOTIFY currentWidthChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DelegateSizeHelper(QObject *parent = nullptr);
|
explicit DelegateSizeHelper(QObject *parent = nullptr);
|
||||||
|
|
||||||
QQuickItem *parentItem() const;
|
qreal parentWidth() const;
|
||||||
void setParentItem(QQuickItem *parentItem);
|
void setParentWidth(qreal parentWidth);
|
||||||
|
|
||||||
qreal leftPadding() const;
|
|
||||||
void setLeftPadding(qreal leftPadding);
|
|
||||||
qreal rightPadding() const;
|
|
||||||
void setRightPadding(qreal rightPadding);
|
|
||||||
|
|
||||||
qreal startBreakpoint() const;
|
qreal startBreakpoint() const;
|
||||||
void setStartBreakpoint(qreal startBreakpoint);
|
void setStartBreakpoint(qreal startBreakpoint);
|
||||||
|
|
||||||
qreal endBreakpoint() const;
|
qreal endBreakpoint() const;
|
||||||
void setEndBreakpoint(qreal endBreakpoint);
|
void setEndBreakpoint(qreal endBreakpoint);
|
||||||
|
|
||||||
int startPercentWidth() const;
|
int startPercentWidth() const;
|
||||||
void setStartPercentWidth(int startPercentWidth);
|
void setStartPercentWidth(int startPercentWidth);
|
||||||
|
|
||||||
int endPercentWidth() const;
|
int endPercentWidth() const;
|
||||||
void setEndPercentWidth(int endPercentWidth);
|
void setEndPercentWidth(int endPercentWidth);
|
||||||
|
|
||||||
qreal maxWidth() const;
|
qreal maxWidth() const;
|
||||||
void setMaxWidth(qreal maxWidth);
|
void setMaxWidth(qreal maxWidth);
|
||||||
|
|
||||||
qreal maxAvailableWidth() const;
|
int currentPercentageWidth() const;
|
||||||
|
|
||||||
int availablePercentageWidth() const;
|
qreal currentWidth() const;
|
||||||
qreal availableWidth() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The left x position of the content column.
|
|
||||||
*/
|
|
||||||
qreal leftX() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The right x position of the content column.
|
|
||||||
*/
|
|
||||||
qreal rightX() const;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void parentItemChanged();
|
void parentWidthChanged();
|
||||||
void leftPaddingChanged();
|
|
||||||
void rightPaddingChanged();
|
|
||||||
void startBreakpointChanged();
|
void startBreakpointChanged();
|
||||||
void endBreakpointChanged();
|
void endBreakpointChanged();
|
||||||
void startPercentWidthChanged();
|
void startPercentWidthChanged();
|
||||||
void endPercentWidthChanged();
|
void endPercentWidthChanged();
|
||||||
void maxWidthChanged();
|
void maxWidthChanged();
|
||||||
void availablePercentageWidthChanged();
|
void currentPercentageWidthChanged();
|
||||||
void availableWidthChanged();
|
void currentWidthChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer<QQuickItem> m_parentItem;
|
qreal m_parentWidth = -1.0;
|
||||||
|
qreal m_startBreakpoint;
|
||||||
|
qreal m_endBreakpoint;
|
||||||
|
int m_startPercentWidth;
|
||||||
|
int m_endPercentWidth;
|
||||||
|
qreal m_maxWidth = -1.0;
|
||||||
|
|
||||||
qreal m_leftPadding = 0.0;
|
int calculateCurrentPercentageWidth() const;
|
||||||
qreal m_rightPadding = 0.0;
|
|
||||||
|
|
||||||
qreal m_startBreakpoint = 0.0;
|
|
||||||
qreal m_endBreakpoint = 0.0;
|
|
||||||
int m_startPercentWidth = 100;
|
|
||||||
int m_endPercentWidth = 85;
|
|
||||||
std::optional<qreal> m_maxWidth = std::nullopt;
|
|
||||||
|
|
||||||
void calcWidthsChanged();
|
|
||||||
|
|
||||||
int calculateAvailablePercentageWidth() const;
|
|
||||||
};
|
};
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
qt_add_library(Devtools STATIC)
|
qt_add_library(devtools STATIC)
|
||||||
ecm_add_qml_module(Devtools GENERATE_PLUGIN_SOURCE
|
ecm_add_qml_module(devtools GENERATE_PLUGIN_SOURCE
|
||||||
URI org.kde.neochat.devtools
|
URI org.kde.neochat.devtools
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/devtools
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/devtools
|
||||||
QML_FILES
|
QML_FILES
|
||||||
@@ -13,14 +13,4 @@ ecm_add_qml_module(Devtools GENERATE_PLUGIN_SOURCE
|
|||||||
RoomData.qml
|
RoomData.qml
|
||||||
ServerData.qml
|
ServerData.qml
|
||||||
StateKeys.qml
|
StateKeys.qml
|
||||||
SOURCES
|
|
||||||
models/statefiltermodel.cpp
|
|
||||||
models/statekeysmodel.cpp
|
|
||||||
models/statemodel.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(Devtools PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models)
|
|
||||||
target_link_libraries(Devtools PRIVATE
|
|
||||||
Qt::Core
|
|
||||||
LibNeoChat
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,32 +9,34 @@ import org.kde.kirigamiaddons.formcard as FormCard
|
|||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
|
||||||
FormCard.FormCard {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
FormCard.FormCard {
|
||||||
|
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
FormCard.FormCheckDelegate {
|
FormCard.FormCheckDelegate {
|
||||||
text: i18nc("@option:check", "Show hidden events in the timeline")
|
text: i18nc("@option:check", "Show hidden events in the timeline")
|
||||||
checked: NeoChatConfig.showAllEvents
|
checked: NeoChatConfig.showAllEvents
|
||||||
|
|
||||||
onToggled: NeoChatConfig.showAllEvents = checked
|
onToggled: NeoChatConfig.showAllEvents = checked
|
||||||
}
|
}
|
||||||
FormCard.FormCheckDelegate {
|
FormCard.FormCheckDelegate {
|
||||||
id: roomAccountDataVisibleCheck
|
id: roomAccountDataVisibleCheck
|
||||||
text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification")
|
text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification")
|
||||||
description: i18n("Allow the user to start a verification session with devices that were already verified")
|
description: i18n("Allow the user to start a verification session with devices that were already verified")
|
||||||
checked: NeoChatConfig.alwaysVerifyDevice
|
checked: NeoChatConfig.alwaysVerifyDevice
|
||||||
|
|
||||||
onToggled: NeoChatConfig.alwaysVerifyDevice = checked
|
onToggled: NeoChatConfig.alwaysVerifyDevice = checked
|
||||||
}
|
}
|
||||||
FormCard.FormCheckDelegate {
|
FormCard.FormCheckDelegate {
|
||||||
text: i18nc("@option:check", "Show focus in window header")
|
text: i18nc("@option:check", "Show focus in window header")
|
||||||
checked: NeoChatConfig.windowTitleFocus
|
checked: NeoChatConfig.windowTitleFocus
|
||||||
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
NeoChatConfig.windowTitleFocus = checked;
|
NeoChatConfig.windowTitleFocus = checked;
|
||||||
NeoChatConfig.save();
|
NeoChatConfig.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
import org.kde.kirigamiaddons.formcard as FormCard
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property NeoChatRoom room
|
property NeoChatRoom room
|
||||||
required property NeoChatConnection connection
|
required property NeoChatConnection connection
|
||||||
|
|
||||||
title: i18nc("@title", "Developer Tools")
|
title: i18n("Developer Tools")
|
||||||
|
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
rightPadding: 0
|
rightPadding: 0
|
||||||
@@ -55,45 +52,22 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
StackLayout {
|
||||||
sourceComponent: switch (tabBar.currentIndex) {
|
id: swipeView
|
||||||
case 0: return debugOptions;
|
|
||||||
case 1: return roomData;
|
currentIndex: tabBar.currentIndex
|
||||||
case 2: return serverData;
|
|
||||||
case 3: return accountData;
|
|
||||||
case 4: return featureFlags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: debugOptions
|
|
||||||
DebugOptions {}
|
DebugOptions {}
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: roomData
|
|
||||||
RoomData {
|
RoomData {
|
||||||
room: root.room
|
room: root.room
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: serverData
|
|
||||||
ServerData {
|
ServerData {
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: accountData
|
|
||||||
AccountData {
|
AccountData {
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: featureFlags
|
|
||||||
FeatureFlagPage {}
|
FeatureFlagPage {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user