Compare commits
1 Commits
release/25
...
work/tobia
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
658551e64d |
@@ -147,7 +147,7 @@
|
|||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/quotient-im/libQuotient.git",
|
"url": "https://github.com/quotient-im/libQuotient.git",
|
||||||
"branch": "0.9.6.1",
|
"branch": "dev",
|
||||||
"disable-submodules": true
|
"disable-submodules": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -206,6 +206,14 @@
|
|||||||
{
|
{
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"path": "."
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patch",
|
||||||
|
"path": "patches/0001-Revert-Bump-KF6-dependency-version.patch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patch",
|
||||||
|
"path": "patches/0001-Revert-Use-new-Kirigami-builtin-column-resize-handle.patch"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ Dependencies:
|
|||||||
'frameworks/ki18n': '@latest-kf6'
|
'frameworks/ki18n': '@latest-kf6'
|
||||||
'frameworks/kconfig': '@latest-kf6'
|
'frameworks/kconfig': '@latest-kf6'
|
||||||
'frameworks/syntax-highlighting': '@latest-kf6'
|
'frameworks/syntax-highlighting': '@latest-kf6'
|
||||||
'frameworks/kiconthemes': '@latest-kf6'
|
|
||||||
'frameworks/kitemmodels': '@latest-kf6'
|
'frameworks/kitemmodels': '@latest-kf6'
|
||||||
'frameworks/kquickcharts': '@latest-kf6'
|
'frameworks/kquickcharts': '@latest-kf6'
|
||||||
'frameworks/knotifications': '@latest-kf6'
|
'frameworks/knotifications': '@latest-kf6'
|
||||||
'frameworks/kcolorscheme': '@latest-kf6'
|
'frameworks/kcolorscheme': '@latest-kf6'
|
||||||
|
'frameworks/kiconthemes': '@latest-kf6'
|
||||||
'libraries/kquickimageeditor': '@latest-kf6'
|
'libraries/kquickimageeditor': '@latest-kf6'
|
||||||
'frameworks/sonnet': '@latest-kf6'
|
'frameworks/sonnet': '@latest-kf6'
|
||||||
'frameworks/prison': '@latest-kf6'
|
'frameworks/prison': '@latest-kf6'
|
||||||
@@ -29,6 +29,7 @@ Dependencies:
|
|||||||
'frameworks/kio': '@latest-kf6'
|
'frameworks/kio': '@latest-kf6'
|
||||||
'frameworks/kwindowsystem': '@latest-kf6'
|
'frameworks/kwindowsystem': '@latest-kf6'
|
||||||
'frameworks/kstatusnotifieritem': '@latest-kf6'
|
'frameworks/kstatusnotifieritem': '@latest-kf6'
|
||||||
|
'frameworks/kcrash': '@latest-kf6'
|
||||||
- 'on': ['Linux', 'FreeBSD']
|
- 'on': ['Linux', 'FreeBSD']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/kdbusaddons': '@latest-kf6'
|
'frameworks/kdbusaddons': '@latest-kf6'
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ 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 "12")
|
set(RELEASE_SERVICE_VERSION_MINOR "11")
|
||||||
set(RELEASE_SERVICE_VERSION_MICRO "3")
|
set(RELEASE_SERVICE_VERSION_MICRO "70")
|
||||||
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.17")
|
set(KF_MIN_VERSION "6.17")
|
||||||
set(QT_MIN_VERSION "6.9")
|
set(QT_MIN_VERSION "6.8")
|
||||||
|
|
||||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
|||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(KDE_COMPILERSETTINGS_LEVEL 6.17)
|
set(KDE_COMPILERSETTINGS_LEVEL 6.0)
|
||||||
|
|
||||||
include(FeatureSummary)
|
include(FeatureSummary)
|
||||||
include(ECMSetupVersion)
|
include(ECMSetupVersion)
|
||||||
@@ -39,7 +39,6 @@ include(ECMCheckOutboundLicense)
|
|||||||
include(ECMQtDeclareLoggingCategory)
|
include(ECMQtDeclareLoggingCategory)
|
||||||
include(ECMAddAndroidApk)
|
include(ECMAddAndroidApk)
|
||||||
include(ECMQmlModule)
|
include(ECMQmlModule)
|
||||||
include(ECMDeprecationSettings)
|
|
||||||
include(GenerateExportHeader)
|
include(GenerateExportHeader)
|
||||||
include(ECMGenerateHeaders)
|
include(ECMGenerateHeaders)
|
||||||
if (NOT ANDROID)
|
if (NOT ANDROID)
|
||||||
@@ -52,8 +51,6 @@ endif()
|
|||||||
|
|
||||||
set(QUOTIENT_FORCE_NAMESPACED_INCLUDES TRUE)
|
set(QUOTIENT_FORCE_NAMESPACED_INCLUDES TRUE)
|
||||||
|
|
||||||
ecm_set_disabled_deprecation_versions(Qt 6.9.0 KF 6.17.0)
|
|
||||||
|
|
||||||
ecm_setup_version(${PROJECT_VERSION}
|
ecm_setup_version(${PROJECT_VERSION}
|
||||||
VARIABLE_PREFIX NEOCHAT
|
VARIABLE_PREFIX NEOCHAT
|
||||||
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
||||||
@@ -69,7 +66,7 @@ if (QT_KNOWN_POLICY_QTP0004)
|
|||||||
qt_policy(SET QTP0004 NEW)
|
qt_policy(SET QTP0004 NEW)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
find_package(KF6 ${KF_MIN_VERSION} COMPONENTS Kirigami I18n Notifications Config CoreAddons Sonnet ItemModels ColorScheme IconThemes)
|
find_package(KF6 ${KF_MIN_VERSION} COMPONENTS Kirigami I18n Notifications Config CoreAddons Sonnet ItemModels IconThemes ColorScheme)
|
||||||
set_package_properties(KF6 PROPERTIES
|
set_package_properties(KF6 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Basic application components"
|
PURPOSE "Basic application components"
|
||||||
@@ -78,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.10.0 REQUIRED)
|
find_package(KF6KirigamiAddons 1.6.0 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)
|
||||||
@@ -92,7 +89,7 @@ if(ANDROID)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} COMPONENTS Widgets)
|
find_package(Qt6 ${QT_MIN_VERSION} COMPONENTS Widgets)
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem StatusNotifierItem)
|
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem StatusNotifierItem Crash)
|
||||||
find_package(KF6SyntaxHighlighting ${KF_MIN_VERSION} REQUIRED)
|
find_package(KF6SyntaxHighlighting ${KF_MIN_VERSION} REQUIRED)
|
||||||
set_package_properties(KF6QQC2DesktopStyle PROPERTIES
|
set_package_properties(KF6QQC2DesktopStyle PROPERTIES
|
||||||
TYPE RUNTIME
|
TYPE RUNTIME
|
||||||
@@ -110,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.3)
|
find_package(QuotientQt6 0.9.1)
|
||||||
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"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void ActionsTest::testActions_data()
|
|||||||
QTest::addColumn<std::optional<QString>>("resultText");
|
QTest::addColumn<std::optional<QString>>("resultText");
|
||||||
QTest::addColumn<std::optional<Quotient::RoomMessageEvent::MsgType>>("type");
|
QTest::addColumn<std::optional<Quotient::RoomMessageEvent::MsgType>>("type");
|
||||||
|
|
||||||
QTest::newRow("shrug") << u"/shrug Hello"_s << std::make_optional(u"¯\\\\\\_(ツ)\\_/¯ Hello"_s)
|
QTest::newRow("shrug") << u"/shrug Hello"_s << std::make_optional(u"¯\\\\_(ツ)_/¯ Hello"_s)
|
||||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||||
QTest::newRow("lenny") << u"/lenny Hello"_s << std::make_optional(u"( ͡° ͜ʖ ͡°) Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
QTest::newRow("lenny") << u"/lenny Hello"_s << std::make_optional(u"( ͡° ͜ʖ ͡°) Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||||
QTest::newRow("tableflip") << u"/tableflip Hello"_s << std::make_optional(u"(╯°□°)╯︵ ┻━┻ Hello"_s)
|
QTest::newRow("tableflip") << u"/tableflip Hello"_s << std::make_optional(u"(╯°□°)╯︵ ┻━┻ Hello"_s)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ private:
|
|||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
void testMaximizeMedia();
|
void testMaximizeMedia();
|
||||||
void testResolveMatrixLinks();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void RoomManagerTest::initTestCase()
|
void RoomManagerTest::initTestCase()
|
||||||
@@ -129,13 +128,5 @@ void RoomManagerTest::testMaximizeMedia()
|
|||||||
QVERIFY(spy[1][0] == 0);
|
QVERIFY(spy[1][0] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManagerTest::testResolveMatrixLinks()
|
|
||||||
{
|
|
||||||
// Test if resolving a non-joined room will bring up the confirmation dialog.
|
|
||||||
const QSignalSpy askToJoinSpy(&RoomManager::instance(), &RoomManager::askJoinRoom);
|
|
||||||
RoomManager::instance().resolveResource(QStringLiteral("matrix:r/testbuild:matrix.org"), QStringLiteral("join"));
|
|
||||||
QTRY_COMPARE(askToJoinSpy.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(RoomManagerTest)
|
QTEST_MAIN(RoomManagerTest)
|
||||||
#include "roommanagertest.moc"
|
#include "roommanagertest.moc"
|
||||||
|
|||||||
@@ -4,12 +4,15 @@
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QHttpServer>
|
||||||
#include <QHttpServerResponder>
|
#include <QHttpServerResponder>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QSslCertificate>
|
#include <QSslCertificate>
|
||||||
#include <QSslKey>
|
#include <QSslKey>
|
||||||
|
#include <QSslServer>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include <Quotient/networkaccessmanager.h>
|
#include <Quotient/networkaccessmanager.h>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,7 @@ Name[sv]=NeoChat
|
|||||||
Name[ta]=நியோச்சாட்
|
Name[ta]=நியோச்சாட்
|
||||||
Name[tr]=NeoChat
|
Name[tr]=NeoChat
|
||||||
Name[uk]=NeoChat
|
Name[uk]=NeoChat
|
||||||
|
Name[x-test]=xxNeoChatxx
|
||||||
Name[zh_CN]=NeoChat
|
Name[zh_CN]=NeoChat
|
||||||
Name[zh_TW]=NeoChat
|
Name[zh_TW]=NeoChat
|
||||||
GenericName=Matrix Client
|
GenericName=Matrix Client
|
||||||
@@ -87,6 +88,7 @@ GenericName[sv]=Matrix-klient
|
|||||||
GenericName[ta]=Matrix வாங்கி
|
GenericName[ta]=Matrix வாங்கி
|
||||||
GenericName[tr]=Matrix İstemcisi
|
GenericName[tr]=Matrix İstemcisi
|
||||||
GenericName[uk]=Клієнт Matrix
|
GenericName[uk]=Клієнт Matrix
|
||||||
|
GenericName[x-test]=xxMatrix Clientxx
|
||||||
GenericName[zh_CN]=Matrix 客户端
|
GenericName[zh_CN]=Matrix 客户端
|
||||||
GenericName[zh_TW]=Matrix 用戶端
|
GenericName[zh_TW]=Matrix 用戶端
|
||||||
Comment=Chat on Matrix
|
Comment=Chat on Matrix
|
||||||
@@ -112,7 +114,6 @@ 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[ro]=Discutați pe Matrix
|
|
||||||
Comment[ru]=Общение в Matrix
|
Comment[ru]=Общение в Matrix
|
||||||
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
||||||
Comment[sl]=Klepet na Matrixu
|
Comment[sl]=Klepet na Matrixu
|
||||||
@@ -120,6 +121,7 @@ Comment[sv]=Chatta på Matrix
|
|||||||
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
||||||
Comment[tr]=Matrix üzerinde sohbet edin
|
Comment[tr]=Matrix üzerinde sohbet edin
|
||||||
Comment[uk]=Спілкування у Matrix
|
Comment[uk]=Спілкування у Matrix
|
||||||
|
Comment[x-test]=xxChat on Matrixxx
|
||||||
Comment[zh_CN]=在 Matrix 上聊天
|
Comment[zh_CN]=在 Matrix 上聊天
|
||||||
Comment[zh_TW]=在 Matrix 上聊天
|
Comment[zh_TW]=在 Matrix 上聊天
|
||||||
MimeType=x-scheme-handler/matrix;
|
MimeType=x-scheme-handler/matrix;
|
||||||
|
|||||||
28
patches/0001-Revert-Bump-KF6-dependency-version.patch
Normal file
28
patches/0001-Revert-Bump-KF6-dependency-version.patch
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
SPDX-FileCopyrightText: 2025 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
From dbd1cefd0f07a6942aef450f8f3e082aa3b1cc25 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tobias Fella <tobias.fella@kde.org>
|
||||||
|
Date: Sun, 17 Aug 2025 20:04:04 +0200
|
||||||
|
Subject: [PATCH] Revert "Bump KF6 dependency version"
|
||||||
|
|
||||||
|
This reverts commit 18a6ea98232b3a734905fb18eebba9cf39bf5325.
|
||||||
|
---
|
||||||
|
CMakeLists.txt | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 10fe66daa..cd063113d 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -14,7 +14,7 @@ set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_
|
||||||
|
|
||||||
|
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
|
||||||
|
|
||||||
|
-set(KF_MIN_VERSION "6.17")
|
||||||
|
+set(KF_MIN_VERSION "6.12")
|
||||||
|
set(QT_MIN_VERSION "6.8")
|
||||||
|
|
||||||
|
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
SPDX-FileCopyrightText: 2025 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
From ca72345b8ee550be2172d8ac5e5dc9e4c2b508c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tobias Fella <tobias.fella@kde.org>
|
||||||
|
Date: Sun, 17 Aug 2025 20:00:08 +0200
|
||||||
|
Subject: [PATCH] Revert "Use new Kirigami builtin column resize handle"
|
||||||
|
|
||||||
|
This reverts commit de97275a387abcbca6fcb185bcbd1b69c30f5c66.
|
||||||
|
---
|
||||||
|
src/app/qml/Main.qml | 1 -
|
||||||
|
src/rooms/RoomListPage.qml | 70 +++++++++++++++++++++++++++++---------
|
||||||
|
2 files changed, 54 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/app/qml/Main.qml b/src/app/qml/Main.qml
|
||||||
|
index ea8955674..6eed271c1 100644
|
||||||
|
--- a/src/app/qml/Main.qml
|
||||||
|
+++ b/src/app/qml/Main.qml
|
||||||
|
@@ -45,7 +45,6 @@ Kirigami.ApplicationWindow {
|
||||||
|
showExisting: true
|
||||||
|
onConnectionChosen: root.load()
|
||||||
|
}
|
||||||
|
- columnView.columnResizeMode: pageStack.wideMode ? Kirigami.ColumnView.DynamicColumns : Kirigami.ColumnView.SingleColumn
|
||||||
|
globalToolBar.canContainHandles: true
|
||||||
|
globalToolBar {
|
||||||
|
style: Kirigami.ApplicationHeaderStyle.ToolBar
|
||||||
|
diff --git a/src/rooms/RoomListPage.qml b/src/rooms/RoomListPage.qml
|
||||||
|
index 2ac211fd5..f5586d789 100644
|
||||||
|
--- a/src/rooms/RoomListPage.qml
|
||||||
|
+++ b/src/rooms/RoomListPage.qml
|
||||||
|
@@ -17,22 +17,13 @@ import org.kde.neochat
|
||||||
|
Kirigami.Page {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
- Kirigami.ColumnView.interactiveResizeEnabled: true
|
||||||
|
- Kirigami.ColumnView.minimumWidth: _private.collapsedSize + spaceDrawer.width + 1
|
||||||
|
- Kirigami.ColumnView.maximumWidth: _private.defaultWidth + spaceDrawer.width + 1
|
||||||
|
- Kirigami.ColumnView.onInteractiveResizingChanged: {
|
||||||
|
- if (!Kirigami.ColumnView.interactiveResizing && collapsed) {
|
||||||
|
- Kirigami.ColumnView.preferredWidth = root.Kirigami.ColumnView.minimumWidth;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- Kirigami.ColumnView.preferredWidth: _private.currentWidth + spaceDrawer.width + 1
|
||||||
|
- Kirigami.ColumnView.onPreferredWidthChanged: {
|
||||||
|
- if (width > _private.collapseWidth) {
|
||||||
|
- NeoChatConfig.collapsed = false;
|
||||||
|
- } else if (Kirigami.ColumnView.interactiveResizing) {
|
||||||
|
- NeoChatConfig.collapsed = true;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ /**
|
||||||
|
+ * @brief The current width of the room list.
|
||||||
|
+ *
|
||||||
|
+ * @note Other objects can access the value but the private function makes sure
|
||||||
|
+ * that only the internal members can modify it.
|
||||||
|
+ */
|
||||||
|
+ readonly property int currentWidth: _private.currentWidth + spaceDrawer.width + 1
|
||||||
|
|
||||||
|
required property NeoChatConnection connection
|
||||||
|
|
||||||
|
@@ -40,6 +31,10 @@ Kirigami.Page {
|
||||||
|
|
||||||
|
signal search
|
||||||
|
|
||||||
|
+ onCurrentWidthChanged: pageStack.defaultColumnWidth = root.currentWidth
|
||||||
|
+ Component.onCompleted: pageStack.defaultColumnWidth = root.currentWidth
|
||||||
|
+
|
||||||
|
+
|
||||||
|
onCollapsedChanged: {
|
||||||
|
if (collapsed) {
|
||||||
|
RoomManager.sortFilterRoomTreeModel.filterText = "";
|
||||||
|
@@ -252,6 +247,49 @@ Kirigami.Page {
|
||||||
|
sourceComponent: Kirigami.Settings.isMobile ? exploreComponentMobile : userInfoDesktop
|
||||||
|
}
|
||||||
|
|
||||||
|
+ MouseArea {
|
||||||
|
+ anchors.top: parent.top
|
||||||
|
+ anchors.bottom: parent.bottom
|
||||||
|
+ parent: applicationWindow().overlay.parent
|
||||||
|
+
|
||||||
|
+ x: root.currentWidth - width / 2
|
||||||
|
+ width: Kirigami.Units.smallSpacing * 2
|
||||||
|
+ z: root.z + 1
|
||||||
|
+ enabled: RoomManager.hasOpenRoom && applicationWindow().width >= Kirigami.Units.gridUnit * 35
|
||||||
|
+ visible: enabled
|
||||||
|
+ cursorShape: Qt.SplitHCursor
|
||||||
|
+
|
||||||
|
+ property int _lastX
|
||||||
|
+
|
||||||
|
+ onPressed: mouse => {
|
||||||
|
+ _lastX = mouse.x;
|
||||||
|
+ }
|
||||||
|
+ onPositionChanged: mouse => {
|
||||||
|
+ if (_lastX == -1) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (mouse.x > _lastX) {
|
||||||
|
+ // we moved to the right
|
||||||
|
+ if (_private.currentWidth < _private.collapseWidth && _private.currentWidth + (mouse.x - _lastX) >= _private.collapseWidth) {
|
||||||
|
+ // Here we get back directly to a more wide mode.
|
||||||
|
+ _private.currentWidth = _private.defaultWidth;
|
||||||
|
+ NeoChatConfig.collapsed = false;
|
||||||
|
+ } else if (_private.currentWidth >= _private.collapseWidth) {
|
||||||
|
+ // Increase page width
|
||||||
|
+ _private.currentWidth = Math.min(_private.defaultWidth, _private.currentWidth + (mouse.x - _lastX));
|
||||||
|
+ }
|
||||||
|
+ } else if (mouse.x < _lastX) {
|
||||||
|
+ const tmpWidth = _private.currentWidth - (_lastX - mouse.x);
|
||||||
|
+ if (tmpWidth < _private.collapseWidth) {
|
||||||
|
+ _private.currentWidth = Qt.binding(() => _private.collapsedSize);
|
||||||
|
+ NeoChatConfig.collapsed = true;
|
||||||
|
+ } else {
|
||||||
|
+ _private.currentWidth = tmpWidth;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
Component {
|
||||||
|
id: userInfo
|
||||||
|
UserInfo {
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
1706
po/ar/neochat.po
1706
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
1484
po/ast/neochat.po
1484
po/ast/neochat.po
File diff suppressed because it is too large
Load Diff
1673
po/az/neochat.po
1673
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
1671
po/ca/neochat.po
1671
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1669
po/cs/neochat.po
1669
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
1628
po/da/neochat.po
1628
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
2819
po/de/neochat.po
2819
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
1725
po/el/neochat.po
1725
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
1764
po/en_GB/neochat.po
1764
po/en_GB/neochat.po
File diff suppressed because it is too large
Load Diff
1753
po/eo/neochat.po
1753
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
1598
po/es/neochat.po
1598
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
1763
po/eu/neochat.po
1763
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
2054
po/fi/neochat.po
2054
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
1802
po/fr/neochat.po
1802
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
7002
po/ga/neochat.po
7002
po/ga/neochat.po
File diff suppressed because it is too large
Load Diff
1768
po/gl/neochat.po
1768
po/gl/neochat.po
File diff suppressed because it is too large
Load Diff
1685
po/he/neochat.po
1685
po/he/neochat.po
File diff suppressed because it is too large
Load Diff
1751
po/hi/neochat.po
1751
po/hi/neochat.po
File diff suppressed because it is too large
Load Diff
2063
po/hu/neochat.po
2063
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
2246
po/ia/neochat.po
2246
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
1719
po/id/neochat.po
1719
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
1650
po/ie/neochat.po
1650
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
1728
po/it/neochat.po
1728
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
1483
po/ja/neochat.po
1483
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
1688
po/ka/neochat.po
1688
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
2149
po/ko/neochat.po
2149
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
2460
po/lt/neochat.po
2460
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
1987
po/lv/neochat.po
1987
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
1693
po/nl/neochat.po
1693
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
1626
po/nn/neochat.po
1626
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
1670
po/pa/neochat.po
1670
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
2614
po/pl/neochat.po
2614
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
1708
po/pt/neochat.po
1708
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<!DOCTYPE refentry PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
|
|
||||||
<!ENTITY % Brazilian-Portuguese "INCLUDE">
|
|
||||||
]>
|
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
|
|
||||||
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
||||||
-->
|
|
||||||
|
|
||||||
<refentry lang="&language;">
|
|
||||||
<refentryinfo>
|
|
||||||
<title
|
|
||||||
>Manual do Usuário do NeoChat</title>
|
|
||||||
<author
|
|
||||||
><firstname
|
|
||||||
>Carl</firstname
|
|
||||||
><surname
|
|
||||||
>Schwan</surname
|
|
||||||
> <contrib
|
|
||||||
>NeoChat man page.</contrib
|
|
||||||
> <email
|
|
||||||
>carl@carlschwan.eu</email
|
|
||||||
></author>
|
|
||||||
<date
|
|
||||||
>01/11/2022</date>
|
|
||||||
<releaseinfo
|
|
||||||
>22.09</releaseinfo>
|
|
||||||
<productname
|
|
||||||
>NeoChat</productname>
|
|
||||||
</refentryinfo>
|
|
||||||
|
|
||||||
<refmeta>
|
|
||||||
<refentrytitle>
|
|
||||||
<command
|
|
||||||
>neochat</command>
|
|
||||||
</refentrytitle>
|
|
||||||
<manvolnum
|
|
||||||
>1</manvolnum>
|
|
||||||
</refmeta>
|
|
||||||
|
|
||||||
<refnamediv>
|
|
||||||
<refname
|
|
||||||
>neochat</refname>
|
|
||||||
<refpurpose
|
|
||||||
>Cliente para interação com o protocolo de mensagens Matrix.</refpurpose>
|
|
||||||
</refnamediv>
|
|
||||||
<!-- body begins here -->
|
|
||||||
<refsynopsisdiv id='synopsis'>
|
|
||||||
<cmdsynopsis
|
|
||||||
><command
|
|
||||||
>neochat</command
|
|
||||||
> <arg choice="opt"
|
|
||||||
><replaceable
|
|
||||||
>URI</replaceable
|
|
||||||
></arg
|
|
||||||
> </cmdsynopsis>
|
|
||||||
</refsynopsisdiv>
|
|
||||||
|
|
||||||
|
|
||||||
<refsect1 id="description">
|
|
||||||
<title
|
|
||||||
>Descrição</title>
|
|
||||||
<para
|
|
||||||
>O <command
|
|
||||||
>neochat</command
|
|
||||||
> é um aplicativo de bate-papo para o protocolo Matrix. Ele funciona tanto em computadores quanto em dispositivos móveis. </para>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1 id="options"
|
|
||||||
><title
|
|
||||||
>Opções</title>
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term
|
|
||||||
><option
|
|
||||||
>URI</option
|
|
||||||
></term>
|
|
||||||
<listitem>
|
|
||||||
<para
|
|
||||||
>O URI da matriz para um usuário ou uma sala. Por exemplo, matrix:u/usuário:exemplo.org e matrix:r/root:exemplo.org. Isso fará com que o NeoChat tente abrir a sala ou conversa especificada. </para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1 id="bug">
|
|
||||||
<title
|
|
||||||
>Relatar bugs</title>
|
|
||||||
<para
|
|
||||||
>Você pode reportar erros e solicitar novas funcionalidades em <ulink url="https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General"
|
|
||||||
>https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General</ulink
|
|
||||||
></para>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1>
|
|
||||||
<title
|
|
||||||
>Veja também</title>
|
|
||||||
<simplelist>
|
|
||||||
<member
|
|
||||||
>Lista de perguntas frequentes sobre o Matrix <ulink url="https://matrix.org/faq/"
|
|
||||||
>https://matrix.org/faq/</ulink
|
|
||||||
> </member>
|
|
||||||
<member
|
|
||||||
>kf5options(7)</member>
|
|
||||||
<member
|
|
||||||
>qt5options(7)</member>
|
|
||||||
</simplelist>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1 id="copyright"
|
|
||||||
><title
|
|
||||||
>Direitos autorais</title>
|
|
||||||
<para
|
|
||||||
>Direitos autorais © 2020-2022 Tobias Fella </para>
|
|
||||||
<para
|
|
||||||
>Direitos autorais © 2020-2022 Carl Schwan </para>
|
|
||||||
<para
|
|
||||||
>Licença: GNU General Public Versão 3 ou posterior <ulink url="https://www.gnu.org/licenses/gpl-3.0.html"
|
|
||||||
>https://www.gnu.org/licenses/gpl-3.0.html</ulink
|
|
||||||
>></para>
|
|
||||||
</refsect1>
|
|
||||||
</refentry>
|
|
||||||
1752
po/pt_BR/neochat.po
1752
po/pt_BR/neochat.po
File diff suppressed because it is too large
Load Diff
7049
po/ro/neochat.po
7049
po/ro/neochat.po
File diff suppressed because it is too large
Load Diff
2184
po/ru/neochat.po
2184
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
1751
po/sa/neochat.po
1751
po/sa/neochat.po
File diff suppressed because it is too large
Load Diff
1689
po/sk/neochat.po
1689
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
1699
po/sl/neochat.po
1699
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
1696
po/sv/neochat.po
1696
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
2180
po/ta/neochat.po
2180
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
1639
po/tok/neochat.po
1639
po/tok/neochat.po
File diff suppressed because it is too large
Load Diff
1715
po/tr/neochat.po
1715
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
1709
po/uk/neochat.po
1709
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
1677
po/zh_CN/neochat.po
1677
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
2012
po/zh_TW/neochat.po
2012
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -48,8 +48,6 @@ if(ANDROID OR WIN32)
|
|||||||
set_source_files_properties(qml/GlobalMenuStub.qml PROPERTIES
|
set_source_files_properties(qml/GlobalMenuStub.qml PROPERTIES
|
||||||
QT_QML_SOURCE_TYPENAME GlobalMenu
|
QT_QML_SOURCE_TYPENAME GlobalMenu
|
||||||
)
|
)
|
||||||
else()
|
|
||||||
set(EXTRA_IMPORTS org.kde.purpose)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||||
@@ -103,7 +101,6 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
|||||||
qml/ReasonDialog.qml
|
qml/ReasonDialog.qml
|
||||||
qml/NewPollDialog.qml
|
qml/NewPollDialog.qml
|
||||||
qml/UserMenu.qml
|
qml/UserMenu.qml
|
||||||
qml/MeetingDialog.qml
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
QtCore
|
QtCore
|
||||||
QtQuick
|
QtQuick
|
||||||
@@ -120,8 +117,8 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
|||||||
org.kde.neochat.login
|
org.kde.neochat.login
|
||||||
org.kde.neochat.chatbar
|
org.kde.neochat.chatbar
|
||||||
org.kde.config
|
org.kde.config
|
||||||
|
org.kde.purpose
|
||||||
org.kde.syntaxhighlighting
|
org.kde.syntaxhighlighting
|
||||||
${EXTRA_IMPORTS}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT ANDROID AND NOT WIN32)
|
if(NOT ANDROID AND NOT WIN32)
|
||||||
@@ -153,7 +150,6 @@ target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
|
|||||||
|
|
||||||
target_link_libraries(neochat-app PRIVATE
|
target_link_libraries(neochat-app PRIVATE
|
||||||
neochat
|
neochat
|
||||||
KF6::IconThemes
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
||||||
@@ -204,9 +200,8 @@ target_link_libraries(neochat PUBLIC
|
|||||||
KF6::ConfigGui
|
KF6::ConfigGui
|
||||||
KF6::CoreAddons
|
KF6::CoreAddons
|
||||||
KF6::SonnetCore
|
KF6::SonnetCore
|
||||||
|
KF6::IconThemes
|
||||||
KF6::ItemModels
|
KF6::ItemModels
|
||||||
KF6::I18nQml
|
|
||||||
KirigamiApp
|
|
||||||
QuotientQt6
|
QuotientQt6
|
||||||
Login
|
Login
|
||||||
Rooms
|
Rooms
|
||||||
@@ -214,6 +209,10 @@ target_link_libraries(neochat PUBLIC
|
|||||||
Spaces
|
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)
|
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)
|
if(NEOCHAT_FLATPAK)
|
||||||
@@ -324,7 +323,6 @@ if(ANDROID)
|
|||||||
"kt-restore-defaults-symbolic"
|
"kt-restore-defaults-symbolic"
|
||||||
"user-symbolic"
|
"user-symbolic"
|
||||||
"mark-location-symbolic"
|
"mark-location-symbolic"
|
||||||
"amarok_playcount"
|
|
||||||
|
|
||||||
${KIRIGAMI_ADDONS_ICONS}
|
${KIRIGAMI_ADDONS_ICONS}
|
||||||
)
|
)
|
||||||
@@ -353,8 +351,7 @@ endif()
|
|||||||
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||||
# krunner plugin must be the same as the app id for flatpak to export it
|
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
|
||||||
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins RENAME org.kde.neochat.desktop)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <Quotient/qt_connection_util.h>
|
#include <Quotient/qt_connection_util.h>
|
||||||
#include <Quotient/settings.h>
|
#include <Quotient/settings.h>
|
||||||
|
|
||||||
|
#include "accountmanager.h"
|
||||||
#include "enums/roomsortparameter.h"
|
#include "enums/roomsortparameter.h"
|
||||||
#include "general_logging.h"
|
#include "general_logging.h"
|
||||||
#include "mediasizehelper.h"
|
#include "mediasizehelper.h"
|
||||||
@@ -25,7 +26,9 @@
|
|||||||
#include "models/roomlistmodel.h"
|
#include "models/roomlistmodel.h"
|
||||||
#include "models/roomtreemodel.h"
|
#include "models/roomtreemodel.h"
|
||||||
#include "neochatconfig.h"
|
#include "neochatconfig.h"
|
||||||
|
#include "neochatconnection.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
|
#include "notificationsmanager.h"
|
||||||
#include "proxycontroller.h"
|
#include "proxycontroller.h"
|
||||||
#include "roommanager.h"
|
#include "roommanager.h"
|
||||||
|
|
||||||
@@ -306,7 +309,8 @@ void Controller::listenForNotifications()
|
|||||||
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
||||||
|
|
||||||
connect(connector, &KUnifiedPush::Connector::messageReceived, [timer](const QByteArray &data) {
|
connect(connector, &KUnifiedPush::Connector::messageReceived, [timer](const QByteArray &data) {
|
||||||
NotificationsManager::postPushNotification(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.
|
// Wait five seconds to see if we received any messages or this happened to be an erroneous activation.
|
||||||
|
|||||||
@@ -33,10 +33,13 @@
|
|||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_include("KCrash")
|
||||||
|
#include <KCrash>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <KIconTheme>
|
#include <KIconTheme>
|
||||||
#include <KLocalizedQmlContext>
|
#include <KLocalizedContext>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KirigamiApp>
|
|
||||||
|
|
||||||
#include "neochat-version.h"
|
#include "neochat-version.h"
|
||||||
|
|
||||||
@@ -101,11 +104,8 @@ Q_DECL_EXPORT
|
|||||||
#endif
|
#endif
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
|
||||||
|
|
||||||
// We currently need to do this ourselves,
|
|
||||||
// KirigamiApp currently called this after constructing the app which breaks icons on Windows.
|
|
||||||
KIconTheme::initTheme();
|
KIconTheme::initTheme();
|
||||||
|
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||||
|
|
||||||
#ifdef HAVE_WEBVIEW
|
#ifdef HAVE_WEBVIEW
|
||||||
QtWebView::initialize();
|
QtWebView::initialize();
|
||||||
@@ -113,10 +113,24 @@ int main(int argc, char *argv[])
|
|||||||
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
|
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KirigamiApp::App app(argc, argv);
|
#ifdef Q_OS_ANDROID
|
||||||
KirigamiApp kirigamiApp;
|
QGuiApplication app(argc, argv);
|
||||||
|
QQuickStyle::setStyle(u"org.kde.breeze"_s);
|
||||||
|
#else
|
||||||
|
QIcon::setFallbackThemeName("breeze"_L1);
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
// Default to org.kde.desktop style unless the user forces another style
|
||||||
|
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
|
||||||
|
QQuickStyle::setStyle(u"org.kde.desktop"_s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
freopen("CONOUT$", "w", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
QApplication::setStyle(u"breeze"_s);
|
QApplication::setStyle(u"breeze"_s);
|
||||||
QFont font(u"Segoe UI Emoji"_s);
|
QFont font(u"Segoe UI Emoji"_s);
|
||||||
font.setPointSize(10);
|
font.setPointSize(10);
|
||||||
@@ -163,6 +177,10 @@ int main(int argc, char *argv[])
|
|||||||
KAboutData::setApplicationData(about);
|
KAboutData::setApplicationData(about);
|
||||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(u"org.kde.neochat"_s));
|
QGuiApplication::setWindowIcon(QIcon::fromTheme(u"org.kde.neochat"_s));
|
||||||
|
|
||||||
|
#if __has_include("KCrash")
|
||||||
|
KCrash::initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
Connection::setEncryptionDefault(true);
|
Connection::setEncryptionDefault(true);
|
||||||
Connection::setDirectChatEncryptionDefault(true);
|
Connection::setDirectChatEncryptionDefault(true);
|
||||||
|
|
||||||
@@ -187,7 +205,7 @@ int main(int argc, char *argv[])
|
|||||||
parser.addOption(testOption);
|
parser.addOption(testOption);
|
||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
QCommandLineOption dbusActivatedOption(u"dbus-activated"_s);
|
QCommandLineOption dbusActivatedOption(u"dbus-activated"_s, i18n("Internal usage only."));
|
||||||
dbusActivatedOption.setFlags(QCommandLineOption::Flag::HiddenFromHelp);
|
dbusActivatedOption.setFlags(QCommandLineOption::Flag::HiddenFromHelp);
|
||||||
parser.addOption(dbusActivatedOption);
|
parser.addOption(dbusActivatedOption);
|
||||||
#endif
|
#endif
|
||||||
@@ -201,14 +219,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
if (parser.isSet(dbusActivatedOption)) {
|
if (parser.isSet(dbusActivatedOption)) {
|
||||||
#ifdef HAVE_KDBUSADDONS
|
// We want to be replaceable by the main client
|
||||||
// We *don't* want to use KDBusService here. I don't know why, but it makes activation super unreliable. We don't really need it anyway.
|
KDBusService service(KDBusService::Replace);
|
||||||
if (!QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.neochat"))) {
|
|
||||||
// Gracefully fail if NeoChat is already running
|
|
||||||
qWarning() << "NeoChat already running, not sending push notifications.";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_RUNNER
|
#ifdef HAVE_RUNNER
|
||||||
// If we are built with KRunner and KUnifiedPush support, we need to do something special.
|
// If we are built with KRunner and KUnifiedPush support, we need to do something special.
|
||||||
@@ -267,7 +279,7 @@ int main(int argc, char *argv[])
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KLocalization::setupLocalizedContext(&engine);
|
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
|
||||||
engine.setNetworkAccessManagerFactory(new NetworkAccessManagerFactory());
|
engine.setNetworkAccessManagerFactory(new NetworkAccessManagerFactory());
|
||||||
|
|
||||||
if (parser.isSet("ignore-ssl-errors"_L1)) {
|
if (parser.isSet("ignore-ssl-errors"_L1)) {
|
||||||
@@ -282,9 +294,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
engine.addImageProvider(u"blurhash"_s, new BlurhashImageProvider);
|
engine.addImageProvider(u"blurhash"_s, new BlurhashImageProvider);
|
||||||
|
|
||||||
if (!kirigamiApp.start("org.kde.neochat", "Main", &engine)) {
|
engine.loadFromModule("org.kde.neochat", "Main");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parser.positionalArguments().isEmpty() && !parser.isSet("share"_L1)) {
|
if (!parser.positionalArguments().isEmpty() && !parser.isSet("share"_L1)) {
|
||||||
RoomManager::instance().setUrlArgument(parser.positionalArguments()[0]);
|
RoomManager::instance().setUrlArgument(parser.positionalArguments()[0]);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ QVariant NotificationsModel::data(const QModelIndex &index, int role) const
|
|||||||
QHash<int, QByteArray> NotificationsModel::roleNames() const
|
QHash<int, QByteArray> NotificationsModel::roleNames() const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{TextRole, "notificationText"},
|
{TextRole, "text"},
|
||||||
{RoomIdRole, "roomId"},
|
{RoomIdRole, "roomId"},
|
||||||
{AuthorName, "authorName"},
|
{AuthorName, "authorName"},
|
||||||
{AuthorAvatar, "authorAvatar"},
|
{AuthorAvatar, "authorAvatar"},
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ Name[sv]=NeoChat
|
|||||||
Name[ta]=நியோச்சாட்
|
Name[ta]=நியோச்சாட்
|
||||||
Name[tr]=NeoChat
|
Name[tr]=NeoChat
|
||||||
Name[uk]=NeoChat
|
Name[uk]=NeoChat
|
||||||
|
Name[x-test]=xxNeoChatxx
|
||||||
Name[zh_CN]=NeoChat
|
Name[zh_CN]=NeoChat
|
||||||
Name[zh_TW]=NeoChat
|
Name[zh_TW]=NeoChat
|
||||||
DesktopEntry=org.kde.neochat
|
DesktopEntry=org.kde.neochat
|
||||||
@@ -86,6 +87,7 @@ Comment[sv]=En klient för matrix, det decentraliserade kommunikationsprotokolle
|
|||||||
Comment[ta]=மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி
|
Comment[ta]=மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி
|
||||||
Comment[tr]=Merkezi olmayan iletişim protokolü Matrix için bir istemci
|
Comment[tr]=Merkezi olmayan iletişim protokolü Matrix için bir istemci
|
||||||
Comment[uk]=Клієнт matrix, децентралізованого протоколу обміну даними
|
Comment[uk]=Клієнт matrix, децентралізованого протоколу обміну даними
|
||||||
|
Comment[x-test]=xxA client for matrix, the decentralized communication protocolxx
|
||||||
Comment[zh_CN]=分布式通讯协议 Matrix 的客户端
|
Comment[zh_CN]=分布式通讯协议 Matrix 的客户端
|
||||||
Comment[zh_TW]=去中心化通訊協定 Matrix 的用戶端
|
Comment[zh_TW]=去中心化通訊協定 Matrix 的用戶端
|
||||||
|
|
||||||
@@ -132,6 +134,7 @@ Name[sv]=Nytt meddelande
|
|||||||
Name[ta]=புதிய செய்தி
|
Name[ta]=புதிய செய்தி
|
||||||
Name[tr]=Yeni İleti
|
Name[tr]=Yeni İleti
|
||||||
Name[uk]=Нове повідомлення
|
Name[uk]=Нове повідомлення
|
||||||
|
Name[x-test]=xxNew messagexx
|
||||||
Name[zh_CN]=新消息
|
Name[zh_CN]=新消息
|
||||||
Name[zh_TW]=新訊息
|
Name[zh_TW]=新訊息
|
||||||
Comment=There is a new message
|
Comment=There is a new message
|
||||||
@@ -174,6 +177,7 @@ Comment[sv]=Det finns ett nytt meddelande
|
|||||||
Comment[ta]=ஒரு புதிய செய்தி உள்ளது
|
Comment[ta]=ஒரு புதிய செய்தி உள்ளது
|
||||||
Comment[tr]=Yeni bir ileti var
|
Comment[tr]=Yeni bir ileti var
|
||||||
Comment[uk]=Надійшло нове повідомлення
|
Comment[uk]=Надійшло нове повідомлення
|
||||||
|
Comment[x-test]=xxThere is a new messagexx
|
||||||
Comment[zh_CN]=有新消息
|
Comment[zh_CN]=有新消息
|
||||||
Comment[zh_TW]=有新的訊息
|
Comment[zh_TW]=有新的訊息
|
||||||
Action=Popup
|
Action=Popup
|
||||||
@@ -211,7 +215,6 @@ Name[pa]=ਨਵਾਂ ਸੱਦਾ
|
|||||||
Name[pl]=Nowe zaproszenie
|
Name[pl]=Nowe zaproszenie
|
||||||
Name[pt]=Novo Convite
|
Name[pt]=Novo Convite
|
||||||
Name[pt_BR]=Novo convite
|
Name[pt_BR]=Novo convite
|
||||||
Name[ro]=Invitație nouă
|
|
||||||
Name[ru]=Новое приглашение
|
Name[ru]=Новое приглашение
|
||||||
Name[sa]=नवीन आमन्त्रणम्
|
Name[sa]=नवीन आमन्त्रणम्
|
||||||
Name[sl]=Novo povabilo
|
Name[sl]=Novo povabilo
|
||||||
@@ -219,6 +222,7 @@ Name[sv]=Ny inbjudan
|
|||||||
Name[ta]=புதிய அழைப்பிதழ்
|
Name[ta]=புதிய அழைப்பிதழ்
|
||||||
Name[tr]=Yeni Davet
|
Name[tr]=Yeni Davet
|
||||||
Name[uk]=Нове запрошення
|
Name[uk]=Нове запрошення
|
||||||
|
Name[x-test]=xxNew Invitationxx
|
||||||
Name[zh_CN]=新邀请
|
Name[zh_CN]=新邀请
|
||||||
Name[zh_TW]=新邀請
|
Name[zh_TW]=新邀請
|
||||||
Comment=There is a new invitation to a room
|
Comment=There is a new invitation to a room
|
||||||
@@ -253,14 +257,14 @@ Comment[pa]=ਰੂਮ ਲਈ ਨਵਾਂ ਸੱਦਾ ਹੈ
|
|||||||
Comment[pl]=Dostępna jest nowe zaproszenie do pokoju
|
Comment[pl]=Dostępna jest nowe zaproszenie do pokoju
|
||||||
Comment[pt]=Existe um novo convite para uma sala
|
Comment[pt]=Existe um novo convite para uma sala
|
||||||
Comment[pt_BR]=Existe um novo convite para uma sala
|
Comment[pt_BR]=Existe um novo convite para uma sala
|
||||||
Comment[ro]=E o nouă invitație la o cameră
|
|
||||||
Comment[ru]=Доступно новое приглашение в комнату
|
Comment[ru]=Доступно новое приглашение в комнату
|
||||||
Comment[sa]=कक्षस्य नूतनं निमन्त्रणम् अस्ति
|
Comment[sa]=कक्षस्य नूतनं निमन्त्रणम् अस्ति
|
||||||
Comment[sl]=Tam je novo povabilo v sobo
|
Comment[sl]=Tam je novo povabilo v sobo
|
||||||
Comment[sv]=Det finns en ny inbjudan till ett rum
|
Comment[sv]=Det finns en ny inbjudan till ett rum
|
||||||
Comment[ta]=ஓர் அரங்கிற்கான புதிய அழைப்பிதழ் உள்ளது
|
Comment[ta]=ஓர் அரங்கிற்கான புதிய அழைப்பிதழ் உள்ளது
|
||||||
Comment[tr]=Bir odaya yeni bir davet var
|
Comment[tr]=Bir odaya yeni bir davetiye var
|
||||||
Comment[uk]=У кімнаті нове запрошення
|
Comment[uk]=У кімнаті нове запрошення
|
||||||
|
Comment[x-test]=xxThere is a new invitation to a roomxx
|
||||||
Comment[zh_CN]=有新的聊天室邀请
|
Comment[zh_CN]=有新的聊天室邀请
|
||||||
Comment[zh_TW]=有新的加入聊天室邀請
|
Comment[zh_TW]=有新的加入聊天室邀請
|
||||||
Action=Popup
|
Action=Popup
|
||||||
@@ -292,7 +296,6 @@ Name[nl]=Gedeelde
|
|||||||
Name[nn]=Del
|
Name[nn]=Del
|
||||||
Name[pl]=Udostępnij
|
Name[pl]=Udostępnij
|
||||||
Name[pt_BR]=Compartilhar
|
Name[pt_BR]=Compartilhar
|
||||||
Name[ro]=Partajare
|
|
||||||
Name[ru]=Публикация
|
Name[ru]=Публикация
|
||||||
Name[sa]=संविभागः
|
Name[sa]=संविभागः
|
||||||
Name[sl]=Deli
|
Name[sl]=Deli
|
||||||
@@ -300,6 +303,7 @@ Name[sv]=Dela
|
|||||||
Name[ta]=பகிர்
|
Name[ta]=பகிர்
|
||||||
Name[tr]=Paylaş
|
Name[tr]=Paylaş
|
||||||
Name[uk]=Оприлюднення
|
Name[uk]=Оприлюднення
|
||||||
|
Name[x-test]=xxSharexx
|
||||||
Name[zh_CN]=分享
|
Name[zh_CN]=分享
|
||||||
Name[zh_TW]=分享
|
Name[zh_TW]=分享
|
||||||
Comment=The result of sharing a piece of content
|
Comment=The result of sharing a piece of content
|
||||||
@@ -327,7 +331,6 @@ Comment[nl]=Het resultaat van het delen van een stukje inhoud
|
|||||||
Comment[nn]=Resultatet av deling av innhald
|
Comment[nn]=Resultatet av deling av innhald
|
||||||
Comment[pl]=Wynik udostępniania kawałka treści
|
Comment[pl]=Wynik udostępniania kawałka treści
|
||||||
Comment[pt_BR]=O resultado de compartilhar um conteúdo
|
Comment[pt_BR]=O resultado de compartilhar um conteúdo
|
||||||
Comment[ro]=Rezultatul partajării unei bucăți de conținut
|
|
||||||
Comment[ru]=Результат публикации данных
|
Comment[ru]=Результат публикации данных
|
||||||
Comment[sa]=सामग्रीखण्डस्य साझाकरणस्य परिणामः
|
Comment[sa]=सामग्रीखण्डस्य साझाकरणस्य परिणामः
|
||||||
Comment[sl]=Rezultat deljenega kosa vsebine
|
Comment[sl]=Rezultat deljenega kosa vsebine
|
||||||
@@ -335,6 +338,7 @@ Comment[sv]=Resultatet av att dela innehåll
|
|||||||
Comment[ta]=எதையோ பகிர்ந்ததன் விளைவு
|
Comment[ta]=எதையோ பகிர்ந்ததன் விளைவு
|
||||||
Comment[tr]=Bir parça içerik paylaşımının sonucu
|
Comment[tr]=Bir parça içerik paylaşımının sonucu
|
||||||
Comment[uk]=Результат оприлюднення даних
|
Comment[uk]=Результат оприлюднення даних
|
||||||
|
Comment[x-test]=xxThe result of sharing a piece of contentxx
|
||||||
Comment[zh_CN]=分享一个内容得到的结果
|
Comment[zh_CN]=分享一个内容得到的结果
|
||||||
Comment[zh_TW]=分享一份內容之後的結果
|
Comment[zh_TW]=分享一份內容之後的結果
|
||||||
Action=Popup
|
Action=Popup
|
||||||
|
|||||||
@@ -66,10 +66,6 @@
|
|||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
<group name="Timeline">
|
<group name="Timeline">
|
||||||
<entry name="FontScale" type="double">
|
|
||||||
<label>Scaling factor for font sizes</label>
|
|
||||||
<default>1.0</default>
|
|
||||||
</entry>
|
|
||||||
<entry name="ShowAvatarInTimeline" type="bool">
|
<entry name="ShowAvatarInTimeline" type="bool">
|
||||||
<label>Show avatar in the timeline</label>
|
<label>Show avatar in the timeline</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
|
|||||||
@@ -216,12 +216,12 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
notification->setTitle(room->displayName());
|
|
||||||
|
|
||||||
QString entry;
|
QString entry;
|
||||||
if (room->isDirectChat()) {
|
if (sender == room->displayName()) {
|
||||||
|
notification->setTitle(sender);
|
||||||
entry = text.toHtmlEscaped();
|
entry = text.toHtmlEscaped();
|
||||||
} else {
|
} else {
|
||||||
|
notification->setTitle(room->displayName());
|
||||||
entry = i18n("%1: %2", sender, text.toHtmlEscaped());
|
entry = i18n("%1: %2", sender, text.toHtmlEscaped());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,9 +253,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
|
|||||||
notification->setReplyAction(std::move(replyAction));
|
notification->setReplyAction(std::move(replyAction));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Controller::instance().accounts()->rowCount() > 1) {
|
notification->setHint(u"x-kde-origin-name"_s, room->localMember().id());
|
||||||
notification->setHint(u"x-kde-origin-name"_s, room->localMember().id());
|
|
||||||
}
|
|
||||||
notification->sendEvent();
|
notification->sendEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,9 +347,7 @@ void NotificationsManager::doPostInviteNotification(QPointer<NeoChatRoom> room)
|
|||||||
m_invitations.remove(room->id());
|
m_invitations.remove(room->id());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Controller::instance().accounts()->rowCount() > 1) {
|
notification->setHint(u"x-kde-origin-name"_s, room->localMember().id());
|
||||||
notification->setHint(u"x-kde-origin-name"_s, room->localMember().id());
|
|
||||||
}
|
|
||||||
|
|
||||||
notification->sendEvent();
|
notification->sendEvent();
|
||||||
}
|
}
|
||||||
@@ -392,7 +388,7 @@ void NotificationsManager::postPushNotification(const QByteArray &message)
|
|||||||
|
|
||||||
#ifdef HAVE_KIO
|
#ifdef HAVE_KIO
|
||||||
auto openAction = notification->addAction(i18n("Open NeoChat"));
|
auto openAction = notification->addAction(i18n("Open NeoChat"));
|
||||||
connect(openAction, &KNotificationAction::activated, notification, [=]() {
|
connect(openAction, &KNotificationAction::activated, this, [=]() {
|
||||||
QString properId = roomId;
|
QString properId = roomId;
|
||||||
properId = properId.replace(u"#"_s, QString());
|
properId = properId.replace(u"#"_s, QString());
|
||||||
properId = properId.replace(u"!"_s, QString());
|
properId = properId.replace(u"!"_s, QString());
|
||||||
@@ -406,6 +402,8 @@ void NotificationsManager::postPushNotification(const QByteArray &message)
|
|||||||
connect(notification, &KNotification::closed, qGuiApp, &QGuiApplication::quit);
|
connect(notification, &KNotification::closed, qGuiApp, &QGuiApplication::quit);
|
||||||
|
|
||||||
notification->sendEvent();
|
notification->sendEvent();
|
||||||
|
|
||||||
|
m_notifications.insert(roomId, {json["ts"_L1].toVariant().toLongLong(), notification});
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Skipping unsupported push notification" << type;
|
qWarning() << "Skipping unsupported push notification" << type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Display a native notification for the given push notification.
|
* @brief Display a native notification for the given push notification.
|
||||||
*/
|
*/
|
||||||
static void postPushNotification(const QByteArray &message);
|
void postPushNotification(const QByteArray &message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle the notifications for the given connection.
|
* @brief Handle the notifications for the given connection.
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ Name[sv]=NeoChat
|
|||||||
Name[ta]=நியோச்சாட்
|
Name[ta]=நியோச்சாட்
|
||||||
Name[tr]=NeoChat
|
Name[tr]=NeoChat
|
||||||
Name[uk]=NeoChat
|
Name[uk]=NeoChat
|
||||||
|
Name[x-test]=xxNeoChatxx
|
||||||
Name[zh_CN]=NeoChat
|
Name[zh_CN]=NeoChat
|
||||||
Name[zh_TW]=NeoChat
|
Name[zh_TW]=NeoChat
|
||||||
Comment=Find rooms in NeoChat
|
Comment=Find rooms in NeoChat
|
||||||
@@ -75,7 +76,6 @@ Comment[nn]=Finn rom i NeoChat
|
|||||||
Comment[pl]=Znajdź pokoje w NeoChat
|
Comment[pl]=Znajdź pokoje w NeoChat
|
||||||
Comment[pt]=Procurar salas no NeoChat
|
Comment[pt]=Procurar salas no NeoChat
|
||||||
Comment[pt_BR]=Encontrar salas no NeoChat
|
Comment[pt_BR]=Encontrar salas no NeoChat
|
||||||
Comment[ro]=Găsește camere în NeoChat
|
|
||||||
Comment[ru]=Поиск комнат NeoChat
|
Comment[ru]=Поиск комнат NeoChat
|
||||||
Comment[sa]=NeoChat इत्यत्र कक्ष्याः अन्वेषणं कुर्वन्तु
|
Comment[sa]=NeoChat इत्यत्र कक्ष्याः अन्वेषणं कुर्वन्तु
|
||||||
Comment[sl]=Najdi sobe v NeoChatu
|
Comment[sl]=Najdi sobe v NeoChatu
|
||||||
@@ -83,6 +83,7 @@ Comment[sv]=Sök efter rum i NeoChat
|
|||||||
Comment[ta]=நியோச்சாட்டில் அரங்குகளை கண்டுபிடிக்கும்
|
Comment[ta]=நியோச்சாட்டில் அரங்குகளை கண்டுபிடிக்கும்
|
||||||
Comment[tr]=NeoChat’te odalar bulun
|
Comment[tr]=NeoChat’te odalar bulun
|
||||||
Comment[uk]=Пошук кімнат у NeoChat
|
Comment[uk]=Пошук кімнат у NeoChat
|
||||||
|
Comment[x-test]=xxFind rooms in NeoChatxx
|
||||||
Comment[zh_CN]=在 NeoChat 查找聊天室
|
Comment[zh_CN]=在 NeoChat 查找聊天室
|
||||||
Comment[zh_TW]=在 NeoChat 尋找聊天室
|
Comment[zh_TW]=在 NeoChat 尋找聊天室
|
||||||
X-KDE-ServiceTypes=Plasma/Runner
|
X-KDE-ServiceTypes=Plasma/Runner
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ KirigamiComponents.ConvergentContextMenu {
|
|||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
text: i18nc("@action:inmenu", "Verify This Device")
|
text: i18nc("@action:inmenu", "Verify This Device")
|
||||||
icon.name: "security-low"
|
icon.name: "security-low"
|
||||||
visible: !root.connection.isVerifiedSession
|
visible: !root.connection.isVerifiedSession()
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.connection.startSelfVerification();
|
root.connection.startSelfVerification();
|
||||||
const dialog = Qt.createComponent("org.kde.kirigami", "PromptDialog").createObject(QQC2.Overlay.overlay, {
|
const dialog = Qt.createComponent("org.kde.kirigami", "PromptDialog").createObject(QQC2.Overlay.overlay, {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
((root.QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow).pageStack as Kirigami.PageRow).pushDialogLayer(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'), {}, {
|
pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'), {}, {
|
||||||
title: i18nc("@title:window", "Login")
|
title: i18nc("@title:window", "Login")
|
||||||
});
|
});
|
||||||
root.close();
|
root.close();
|
||||||
@@ -95,8 +95,8 @@ Kirigami.Dialog {
|
|||||||
accountView.decrementCurrentIndex();
|
accountView.decrementCurrentIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onEnterPressed: ((accountView.currentItem ?? accountView.footerItem) as Delegates.RoundedItemDelegate).clicked()
|
Keys.onEnterPressed: (accountView.currentItem as Delegates.RoundedItemDelegate).clicked()
|
||||||
Keys.onReturnPressed: ((accountView.currentItem ?? accountView.footerItem) as Delegates.RoundedItemDelegate).clicked()
|
Keys.onReturnPressed: (accountView.currentItem as Delegates.RoundedItemDelegate).clicked()
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
for (let i = 0; i < accountView.count; i++) {
|
for (let i = 0; i < accountView.count; i++) {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ Delegates.RoundedItemDelegate {
|
|||||||
signal contextMenuRequested
|
signal contextMenuRequested
|
||||||
signal selected
|
signal selected
|
||||||
|
|
||||||
activeFocusOnTab: true
|
|
||||||
padding: Kirigami.Units.largeSpacing
|
padding: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
QQC2.ToolTip.visible: hovered
|
QQC2.ToolTip.visible: hovered
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ Components.AbstractMaximizeComponent {
|
|||||||
implicitWidth: Kirigami.Units.iconSizes.medium
|
implicitWidth: Kirigami.Units.iconSizes.medium
|
||||||
implicitHeight: Kirigami.Units.iconSizes.medium
|
implicitHeight: Kirigami.Units.iconSizes.medium
|
||||||
|
|
||||||
name: root.author.displayName
|
name: root.author.name ?? root.author.displayName
|
||||||
source: root.author.avatarUrl
|
source: root.author.avatarUrl
|
||||||
color: root.author.color
|
color: root.author.color
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ Components.AbstractMaximizeComponent {
|
|||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
id: userLabel
|
id: userLabel
|
||||||
|
|
||||||
text: root.author.displayName
|
text: root.author.name ?? root.author.displayName
|
||||||
color: root.author.color
|
color: root.author.color
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
@@ -91,7 +91,6 @@ Components.AbstractMaximizeComponent {
|
|||||||
color: Kirigami.Theme.textColor
|
color: Kirigami.Theme.textColor
|
||||||
|
|
||||||
font.family: "monospace"
|
font.family: "monospace"
|
||||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * NeoChatConfig.fontScale
|
|
||||||
|
|
||||||
Kirigami.SpellCheck.enabled: false
|
Kirigami.SpellCheck.enabled: false
|
||||||
|
|
||||||
@@ -150,6 +149,4 @@ Components.AbstractMaximizeComponent {
|
|||||||
color: Kirigami.Theme.backgroundColor
|
color: Kirigami.Theme.backgroundColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpened: forceActiveFocus()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ 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
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property string emoji
|
property alias emoji: emojiLabel.text
|
||||||
required property string description
|
property alias description: descriptionLabel.text
|
||||||
|
|
||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
text: root.emoji
|
id: emojiLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
|
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
||||||
@@ -24,7 +25,7 @@ ColumnLayout {
|
|||||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 4
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 4
|
||||||
}
|
}
|
||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
text: root.description
|
id: descriptionLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ RowLayout {
|
|||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
delegate: EmojiItem {}
|
delegate: EmojiItem {
|
||||||
|
emoji: modelData.emoji
|
||||||
|
description: modelData.description
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ ApplicationWindow {
|
|||||||
property real longitude: NaN
|
property real longitude: NaN
|
||||||
property string asset
|
property string asset
|
||||||
property var author
|
property var author
|
||||||
property LiveLocationsModel liveLocationModel: null
|
property QtObject liveLocationModel: null
|
||||||
|
|
||||||
flags: Qt.FramelessWindowHint | Qt.WA_TranslucentBackground
|
flags: Qt.FramelessWindowHint | Qt.WA_TranslucentBackground
|
||||||
visibility: Qt.WindowFullScreen
|
visibility: Qt.WindowFullScreen
|
||||||
@@ -59,7 +59,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: mapView.map
|
target: mapView.map
|
||||||
function onCopyrightLinkActivated(link: string) {
|
function onCopyrightLinkActivated() {
|
||||||
Qt.openUrlExternally(link);
|
Qt.openUrlExternally(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ Labs.MenuBar {
|
|||||||
|
|
||||||
Labs.MenuItem {
|
Labs.MenuItem {
|
||||||
icon.name: "list-add-user"
|
icon.name: "list-add-user"
|
||||||
text: i18nc("@action:inmenu", "Find User")
|
text: i18nc("@action:inmenu", "Find your Friends")
|
||||||
enabled: root.connection
|
enabled: root.connection
|
||||||
onTriggered: root.appWindow.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'UserSearchPage'), {
|
onTriggered: root.appWindow.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'UserSearchPage'), {
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
}, {
|
}, {
|
||||||
title: i18nc("@title", "Find User")
|
title: i18nc("@title", "Find your friends")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Labs.MenuItem {
|
Labs.MenuItem {
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
required property NeoChatConnection connection
|
required property NeoChatConnection connection
|
||||||
required property Kirigami.ApplicationWindow appWindow
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ Kirigami.Dialog {
|
|||||||
text: i18nc("@action:button", "Join room")
|
text: i18nc("@action:button", "Join room")
|
||||||
icon.name: "irc-join-channel"
|
icon.name: "irc-join-channel"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
RoomManager.resolveResource(root.room, "join_confirmed");
|
RoomManager.resolveResource(root.room, "join");
|
||||||
root.close();
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Window
|
|
||||||
import QtQml
|
import QtQml
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
@@ -171,8 +170,6 @@ Kirigami.Page {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isDone: root.session.state === KeyVerificationSession.DONE
|
|
||||||
onDone: root.closeDialog()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ Components.AbstractMaximizeComponent {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
onOpened: forceActiveFocus()
|
|
||||||
|
|
||||||
PositionSource {
|
PositionSource {
|
||||||
id: positionSource
|
id: positionSource
|
||||||
|
|
||||||
|
|||||||
@@ -100,8 +100,7 @@ Kirigami.ApplicationWindow {
|
|||||||
|
|
||||||
function onCurrentRoomChanged() {
|
function onCurrentRoomChanged() {
|
||||||
if (RoomManager.currentRoom && root.pageStack.depth <= 1 && root.initialized && Kirigami.Settings.isMobile) {
|
if (RoomManager.currentRoom && root.pageStack.depth <= 1 && root.initialized && Kirigami.Settings.isMobile) {
|
||||||
let roomPage = pageStack.push(Qt.createComponent('org.kde.neochat', 'RoomPage'));
|
let roomPage = root.pageStack.layers.push(Qt.createComponent('org.kde.neochat', 'RoomPage'));
|
||||||
roomPage.forceActiveFocus();
|
|
||||||
roomPage.backRequested.connect(event => {
|
roomPage.backRequested.connect(event => {
|
||||||
RoomManager.clearCurrentRoom();
|
RoomManager.clearCurrentRoom();
|
||||||
});
|
});
|
||||||
@@ -234,7 +233,7 @@ Kirigami.ApplicationWindow {
|
|||||||
RoomListPage {
|
RoomListPage {
|
||||||
id: roomList
|
id: roomList
|
||||||
|
|
||||||
onSearch: root.quickSwitcher.open()
|
onSearch: quickSwitcher.open()
|
||||||
|
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
|
|
||||||
@@ -268,17 +267,6 @@ Kirigami.ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.connection
|
|
||||||
function onLoggedOut(): void {
|
|
||||||
root.pageStack.clear();
|
|
||||||
let page = root.pageStack.push(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'), {
|
|
||||||
showExisting: true,
|
|
||||||
}) as WelcomePage;
|
|
||||||
page.connectionChosen.connect(() => root.load())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: AccountRegistry
|
target: AccountRegistry
|
||||||
function onRowsRemoved() {
|
function onRowsRemoved() {
|
||||||
@@ -359,11 +347,7 @@ Kirigami.ApplicationWindow {
|
|||||||
user: user,
|
user: user,
|
||||||
connection: root.connection,
|
connection: root.connection,
|
||||||
}) as UserDetailDialog;
|
}) as UserDetailDialog;
|
||||||
// FIXME: The reason why we don't want the focusedWindowItem for the room null case (aka QR codes) is because it will parent it to the soon-to-be-destroyed window item.
|
dialog.parent = QmlUtils.focusedWindowItem(); // Kirigami Dialogs overwrite the parent, so we need to set it again
|
||||||
// But this won't be a problem if we turn it into a Kirigami.Dialog or some other in-scene item, which it really should be.
|
|
||||||
if (room != null) {
|
|
||||||
dialog.parent = QmlUtils.focusedWindowItem(); // Kirigami Dialogs overwrite the parent, so we need to set it again
|
|
||||||
}
|
|
||||||
dialog.open();
|
dialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
Kirigami.PromptDialog {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property bool hasExistingMeeting
|
|
||||||
|
|
||||||
title: hasExistingMeeting ? i18nc("@title", "Join Meeting") : i18nc("@title", "Start Meeting")
|
|
||||||
subtitle: hasExistingMeeting ? i18nc("@info:label", "You are about to join a Jitsi meeting in your web browser.") : i18nc("@info:label", "You are about to start a new Jitsi meeting in your web browser.")
|
|
||||||
standardButtons: Kirigami.Dialog.Cancel
|
|
||||||
|
|
||||||
customFooterActions: Kirigami.Action {
|
|
||||||
icon.name: "camera-video-symbolic"
|
|
||||||
text: hasExistingMeeting ? i18nc("@action:button Join the Jitsi meeting", "Join") : i18nc("@action:button Start a new Jitsi meeting", "Start")
|
|
||||||
onTriggered: root.accept()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,8 +34,8 @@ Kirigami.Page {
|
|||||||
enabled: root.model
|
enabled: root.model
|
||||||
target: root.room
|
target: root.room
|
||||||
function onChanged(): void {
|
function onChanged(): void {
|
||||||
root.contentJson = root.model.stateEventContentJson(root.type, root.stateKey);
|
root.contentJson = model.stateEventContentJson(root.type, root.stateKey);
|
||||||
root.sourceText = root.model.stateEventJson(root.type, root.stateKey);
|
root.sourceText = model.stateEventJson(root.type, root.stateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,8 +46,8 @@ Kirigami.Page {
|
|||||||
text: i18nc("@action As in 'edit the state of this room'", "Edit state")
|
text: i18nc("@action As in 'edit the state of this room'", "Edit state")
|
||||||
icon.name: "document-edit"
|
icon.name: "document-edit"
|
||||||
visible: root.allowEdit
|
visible: root.allowEdit
|
||||||
enabled: root.room.canSendState(root.type) && (!root.stateKey.startsWith("@") || root.stateKey === root.room.connection.localUserId) && root.type !== "m.room.create"
|
enabled: room.canSendState(root.type) && (!root.stateKey.startsWith("@") || root.stateKey === root.room.connection.localUserId) && root.type !== "m.room.create"
|
||||||
onTriggered: (root.Kirigami.PageStack.pageStack as Kirigami.PageRow).pushDialogLayer(Qt.createComponent("org.kde.neochat", "EditStateDialog"), {
|
onTriggered: pageStack.pushDialogLayer(Qt.createComponent("org.kde.neochat", "EditStateDialog"), {
|
||||||
room: root.room,
|
room: root.room,
|
||||||
type: root.type,
|
type: root.type,
|
||||||
stateKey: root.stateKey,
|
stateKey: root.stateKey,
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtCore as Core
|
import QtCore as Core
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
@@ -23,13 +21,13 @@ Components.AlbumMaximizeComponent {
|
|||||||
*/
|
*/
|
||||||
required property NeoChatRoom currentRoom
|
required property NeoChatRoom currentRoom
|
||||||
|
|
||||||
readonly property string currentEventId: model.data(model.index((content as ListView).currentIndex, 0), TimelineMessageModel.EventIdRole)
|
readonly property string currentEventId: model.data(model.index(content.currentIndex, 0), TimelineMessageModel.EventIdRole)
|
||||||
|
|
||||||
readonly property var currentAuthor: model.data(model.index((content as ListView).currentIndex, 0), TimelineMessageModel.AuthorRole)
|
readonly property var currentAuthor: model.data(model.index(content.currentIndex, 0), TimelineMessageModel.AuthorRole)
|
||||||
|
|
||||||
readonly property var currentTime: model.data(model.index((content as ListView).currentIndex, 0), TimelineMessageModel.TimeRole)
|
readonly property var currentTime: model.data(model.index(content.currentIndex, 0), TimelineMessageModel.TimeRole)
|
||||||
|
|
||||||
readonly property var currentProgressInfo: model.data(model.index((content as ListView).currentIndex, 0), TimelineMessageModel.ProgressInfoRole)
|
readonly property var currentProgressInfo: model.data(model.index(content.currentIndex, 0), TimelineMessageModel.ProgressInfoRole)
|
||||||
|
|
||||||
actions: [
|
actions: [
|
||||||
ShareAction {
|
ShareAction {
|
||||||
@@ -61,28 +59,28 @@ Components.AlbumMaximizeComponent {
|
|||||||
|
|
||||||
downloadAction: Components.DownloadAction {
|
downloadAction: Components.DownloadAction {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.currentRoom.downloadFile(root.currentEventId, Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + root.currentEventId.replace(":", "_").replace("/", "_").replace("+", "_") + root.currentRoom.fileNameToDownload(root.currentEventId));
|
currentRoom.downloadFile(root.currentEventId, Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + root.currentEventId.replace(":", "_").replace("/", "_").replace("+", "_") + currentRoom.fileNameToDownload(root.currentEventId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playAction: Kirigami.Action {
|
playAction: Kirigami.Action {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
MediaManager.startPlayback();
|
MediaManager.startPlayback();
|
||||||
(root.currentItem as Components.VideoMaximizeDelegate).play();
|
currentItem.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: MediaManager
|
target: MediaManager
|
||||||
function onPlaybackStarted() {
|
function onPlaybackStarted() {
|
||||||
if ((root.currentItem as Components.VideoMaximizeDelegate).playbackState === MediaPlayer.PlayingState) {
|
if (currentItem.playbackState === MediaPlayer.PlayingState) {
|
||||||
(root.currentItem as Components.VideoMaximizeDelegate).pause();
|
currentItem.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.currentRoom
|
target: currentRoom
|
||||||
|
|
||||||
function onFileTransferProgress(id, progress, total) {
|
function onFileTransferProgress(id, progress, total) {
|
||||||
if (id == root.currentEventId) {
|
if (id == root.currentEventId) {
|
||||||
@@ -125,7 +123,7 @@ Components.AlbumMaximizeComponent {
|
|||||||
onItemRightClicked: RoomManager.viewEventMenu(root.currentEventId, root.currentRoom)
|
onItemRightClicked: RoomManager.viewEventMenu(root.currentEventId, root.currentRoom)
|
||||||
|
|
||||||
onSaveItem: {
|
onSaveItem: {
|
||||||
var dialog = saveAsDialog.createObject(QQC2.Overlay.overlay) as Dialogs.FileDialog;
|
var dialog = saveAsDialog.createObject(QQC2.Overlay.overlay);
|
||||||
dialog.selectedFile = currentRoom.fileNameToDownload(root.currentEventId);
|
dialog.selectedFile = currentRoom.fileNameToDownload(root.currentEventId);
|
||||||
dialog.open();
|
dialog.open();
|
||||||
}
|
}
|
||||||
@@ -148,7 +146,7 @@ Components.AlbumMaximizeComponent {
|
|||||||
if (!selectedFile) {
|
if (!selectedFile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
root.currentRoom.downloadFile(root.currentEventId, selectedFile);
|
currentRoom.downloadFile(root.currentEventId, selectedFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
pragma 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.kirigami as Kirigami
|
||||||
|
import org.kde.kirigami.delegates as KD
|
||||||
import org.kde.kirigamiaddons.components as Components
|
import org.kde.kirigamiaddons.components as Components
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
@@ -42,23 +41,15 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delegate: QQC2.ItemDelegate {
|
delegate: QQC2.ItemDelegate {
|
||||||
id: notificationDelegate
|
|
||||||
|
|
||||||
required property string uri
|
|
||||||
required property string authorAvatar
|
|
||||||
required property string authorName
|
|
||||||
required property string roomDisplayName
|
|
||||||
required property string notificationText
|
|
||||||
|
|
||||||
width: parent?.width ?? 0
|
width: parent?.width ?? 0
|
||||||
|
|
||||||
onClicked: RoomManager.resolveResource(uri)
|
onClicked: RoomManager.resolveResource(model.uri)
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
spacing: Kirigami.Units.largeSpacing
|
spacing: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
Components.Avatar {
|
Components.Avatar {
|
||||||
source: notificationDelegate.authorAvatar
|
source: model.authorAvatar
|
||||||
name: notificationDelegate.authorName
|
name: model.authorName
|
||||||
implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
|
|
||||||
@@ -75,7 +66,7 @@ Kirigami.ScrollablePage {
|
|||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
text: notificationDelegate.roomDisplayName
|
text: model.roomDisplayName
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
textFormat: Text.PlainText
|
textFormat: Text.PlainText
|
||||||
@@ -87,9 +78,10 @@ Kirigami.ScrollablePage {
|
|||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
id: subtitle
|
id: subtitle
|
||||||
|
|
||||||
text: notificationDelegate.notificationText
|
text: model.text
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font: Kirigami.Theme.smallFont
|
font: Kirigami.Theme.smallFont
|
||||||
|
opacity: root.hasNotifications ? 0.9 : 0.7
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||||
|
|||||||
@@ -27,26 +27,9 @@ Kirigami.Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaDevices {
|
|
||||||
id: devices
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
visible: devices.videoInputs.length === 0
|
|
||||||
|
|
||||||
Kirigami.PlaceholderMessage {
|
|
||||||
text: i18nc("@info", "No Camera Connected")
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoOutput {
|
VideoOutput {
|
||||||
id: viewFinder
|
id: viewFinder
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: devices.videoInputs.length > 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Prison.VideoScanner {
|
Prison.VideoScanner {
|
||||||
@@ -64,8 +47,6 @@ Kirigami.Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CaptureSession {
|
CaptureSession {
|
||||||
id: session
|
|
||||||
|
|
||||||
camera: Camera {
|
camera: Camera {
|
||||||
id: camera
|
id: camera
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Kirigami.SearchDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAccepted: if (currentItem) {
|
onAccepted: if (currentItem) {
|
||||||
(root.currentItem as RoomDelegate).clicked();
|
(currentItem as QQC2.ItemDelegate).clicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextChanged: RoomManager.sortFilterRoomListModel.filterText = text
|
onTextChanged: RoomManager.sortFilterRoomListModel.filterText = text
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Kirigami.Page {
|
|||||||
Keys.onReturnPressed: event => {
|
Keys.onReturnPressed: event => {
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
if (event.modifiers & Qt.ControlModifier) {
|
||||||
root.accepted(reason.text);
|
root.accepted(reason.text);
|
||||||
root.Kirigami.PageStack.closeDialog();
|
root.closeDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,14 +52,14 @@ Kirigami.Page {
|
|||||||
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
|
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.accepted(reason.text);
|
root.accepted(reason.text);
|
||||||
root.Kirigami.PageStack.closeDialog();
|
root.closeDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QQC2.Button {
|
QQC2.Button {
|
||||||
icon.name: "dialog-cancel-symbolic"
|
icon.name: "dialog-cancel-symbolic"
|
||||||
text: i18nc("@action", "Cancel")
|
text: i18nc("@action", "Cancel")
|
||||||
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
|
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
|
||||||
onClicked: root.Kirigami.PageStack.closeDialog()
|
onClicked: root.closeDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,9 @@
|
|||||||
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Window
|
import QtQuick.Window
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
|
|
||||||
@@ -59,92 +56,18 @@ Kirigami.Page {
|
|||||||
*/
|
*/
|
||||||
property MediaMessageFilterModel mediaMessageFilterModel: RoomManager.mediaMessageFilterModel
|
property MediaMessageFilterModel mediaMessageFilterModel: RoomManager.mediaMessageFilterModel
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The WidgetModel to use.
|
|
||||||
*
|
|
||||||
* This model has the list of widgets available in the current room.
|
|
||||||
*
|
|
||||||
* @note For loading a room in a different window, override this with a new
|
|
||||||
* WidgetModel.
|
|
||||||
*
|
|
||||||
* @sa WidgetModel
|
|
||||||
*/
|
|
||||||
property WidgetModel widgetModel: RoomManager.widgetModel
|
|
||||||
|
|
||||||
title: root.currentRoom ? root.currentRoom.displayName : ""
|
title: root.currentRoom ? root.currentRoom.displayName : ""
|
||||||
focus: true
|
focus: true
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
background: null // This needs to stay null, because of transparency blur
|
|
||||||
|
|
||||||
onHeightChanged: {
|
|
||||||
// HACK: See TimelineView for the hack details.
|
|
||||||
// We get the height change here *first* so we are informed this is because of a window resize and not due to the pinned message.
|
|
||||||
resetViewSettling();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resets the view settling of the timeline.
|
|
||||||
// This should be called whenever the apparent height of the timeline changes, or else the view will scroll on its own!
|
|
||||||
function resetViewSettling(): void {
|
|
||||||
(timelineViewLoader.item as TimelineView).resetViewSettling();
|
|
||||||
}
|
|
||||||
|
|
||||||
actions: [
|
actions: [
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
id: jitsiMeetingAction
|
visible: Kirigami.Settings.isMobile || !(root.Kirigami.PageStack.pageStack as Kirigami.PageRow).wideMode
|
||||||
|
|
||||||
readonly property bool hasExistingMeeting: root.widgetModel.jitsiIndex >= 0
|
|
||||||
readonly property bool canStartNewMeeting: root.currentRoom.canSendState("im.vector.modular.widgets")
|
|
||||||
|
|
||||||
tooltip: {
|
|
||||||
if (hasExistingMeeting) {
|
|
||||||
return i18nc("@action:button", "Join Jitsi meeting…");
|
|
||||||
}
|
|
||||||
|
|
||||||
return canStartNewMeeting ? i18nc("@action:button", "Start Jitsi meeting…") : i18nc("@action:button", "You do not have permissions to start Jitsi meetings")
|
|
||||||
}
|
|
||||||
icon {
|
|
||||||
name: "camera-video-symbolic"
|
|
||||||
color: hasExistingMeeting ? Kirigami.Theme.highlightColor : "transparent"
|
|
||||||
}
|
|
||||||
enabled: hasExistingMeeting || canStartNewMeeting
|
|
||||||
visible: root.currentRoom && !root.currentRoom.isSpace
|
|
||||||
onTriggered: {
|
|
||||||
const dialog = Qt.createComponent("org.kde.neochat", "MeetingDialog").createObject(QQC2.Overlay.overlay, { hasExistingMeeting });
|
|
||||||
dialog.onAccepted.connect(doAction);
|
|
||||||
dialog.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
function doAction(): void {
|
|
||||||
let url;
|
|
||||||
if (!hasExistingMeeting) {
|
|
||||||
url = root.widgetModel.addJitsiConference();
|
|
||||||
} else {
|
|
||||||
let idx = root.widgetModel.index(root.widgetModel.jitsiIndex, 0);
|
|
||||||
url = root.widgetModel.data(idx, WidgetModel.UrlRole);
|
|
||||||
}
|
|
||||||
Qt.openUrlExternally(url);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
|
||||||
visible: Kirigami.Settings.isMobile || !(root.Kirigami.PageStack.pageStack as Kirigami.PageRow)?.wideMode
|
|
||||||
icon.name: "view-right-new"
|
icon.name: "view-right-new"
|
||||||
onTriggered: (root.QQC2.ApplicationWindow.window as Main).openRoomDrawer()
|
onTriggered: (root.QQC2.ApplicationWindow.window as Main).openRoomDrawer()
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
Kirigami.Action {
|
|
||||||
enabled: root.currentRoom && !root.currentRoom.isSpace
|
|
||||||
shortcut: "Ctrl+F"
|
|
||||||
onTriggered: {
|
|
||||||
((root.QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow).pageStack as Kirigami.PageRow).pushDialogLayer(Qt.createComponent('org.kde.neochat', 'RoomSearchPage'), {
|
|
||||||
room: root.currentRoom
|
|
||||||
}, {
|
|
||||||
title: i18nc("@action:title", "Search")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyNavigation.left: (root.Kirigami.PageStack.pageStack as Kirigami.PageRow).get(0)
|
KeyNavigation.left: (root.Kirigami.PageStack.pageStack as Kirigami.PageRow).get(0)
|
||||||
|
|
||||||
onCurrentRoomChanged: {
|
onCurrentRoomChanged: {
|
||||||
@@ -154,9 +77,9 @@ Kirigami.Page {
|
|||||||
|
|
||||||
if (root.currentRoom.tagNames.includes("m.server_notice")) {
|
if (root.currentRoom.tagNames.includes("m.server_notice")) {
|
||||||
banner.text = i18nc("@info", "This room contains official messages from your homeserver.")
|
banner.text = i18nc("@info", "This room contains official messages from your homeserver.")
|
||||||
banner.show("message");
|
banner.visible = true;
|
||||||
} else {
|
} else {
|
||||||
banner.hideIf("message");
|
banner.visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,106 +88,28 @@ Kirigami.Page {
|
|||||||
function onIsOnlineChanged() {
|
function onIsOnlineChanged() {
|
||||||
if (!root.currentRoom.connection.isOnline) {
|
if (!root.currentRoom.connection.isOnline) {
|
||||||
banner.text = i18nc("@info:status", "NeoChat is offline. Please check your network connection.");
|
banner.text = i18nc("@info:status", "NeoChat is offline. Please check your network connection.");
|
||||||
|
banner.visible = true;
|
||||||
banner.type = Kirigami.MessageType.Error;
|
banner.type = Kirigami.MessageType.Error;
|
||||||
banner.show("offline");
|
|
||||||
} else {
|
} else {
|
||||||
banner.hideIf("offline");
|
banner.visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header: ColumnLayout {
|
header: Kirigami.InlineMessage {
|
||||||
id: headerLayout
|
id: banner
|
||||||
|
|
||||||
spacing: 0
|
showCloseButton: true
|
||||||
|
visible: false
|
||||||
readonly property bool shouldShowPins: root.currentRoom.pinnedMessage.length > 0 && !Kirigami.Settings.isMobile
|
position: Kirigami.InlineMessage.Position.Header
|
||||||
|
|
||||||
QQC2.Control {
|
|
||||||
id: pinControl
|
|
||||||
|
|
||||||
visible: headerLayout.shouldShowPins
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
|
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
|
||||||
Kirigami.Theme.inherit: false
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Kirigami.Icon {
|
|
||||||
source: "pin-symbolic"
|
|
||||||
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: root.currentRoom.pinnedMessage
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
|
|
||||||
onLinkActivated: link => UrlHelper.openUrl(link)
|
|
||||||
onHoveredLinkChanged: if (hoveredLink.length > 0 && hoveredLink !== "1") {
|
|
||||||
(QQC2.ApplicationWindow.window as Main).hoverLinkIndicator.text = hoveredLink;
|
|
||||||
} else {
|
|
||||||
(QQC2.ApplicationWindow.window as Main).hoverLinkIndicator.text = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'RoomPinnedMessagesPage'), {
|
|
||||||
room: root.currentRoom
|
|
||||||
}, {
|
|
||||||
title: i18nc("@title", "Pinned Messages")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.Separator {
|
|
||||||
visible: headerLayout.shouldShowPins
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.InlineMessage {
|
|
||||||
id: banner
|
|
||||||
|
|
||||||
// Used to keep track of messages so we can hide the right one at the right time
|
|
||||||
property string messageId
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
showCloseButton: true
|
|
||||||
visible: false
|
|
||||||
position: Kirigami.InlineMessage.Position.Header
|
|
||||||
|
|
||||||
function show(msgid: string): void {
|
|
||||||
messageId = msgid;
|
|
||||||
visible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideIf(msgid: string): void {
|
|
||||||
if (messageId == msgid) {
|
|
||||||
visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: timelineViewLoader
|
id: timelineViewLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
// We need the loader to be active but invisible while the room is loading messages so signals in TimelineView work.
|
|
||||||
active: root.currentRoom && !root.currentRoom.isInvite && !root.currentRoom.isSpace
|
active: root.currentRoom && !root.currentRoom.isInvite && !root.currentRoom.isSpace
|
||||||
|
// We need the loader to be active but invisible while the room is loading messages so signals in TimelineView work.
|
||||||
|
visible: !root.loading
|
||||||
sourceComponent: TimelineView {
|
sourceComponent: TimelineView {
|
||||||
id: timelineView
|
id: timelineView
|
||||||
messageFilterModel: root.messageFilterModel
|
messageFilterModel: root.messageFilterModel
|
||||||
@@ -302,18 +147,21 @@ Kirigami.Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||||
|
Kirigami.Theme.inherit: false
|
||||||
|
color: NeoChatConfig.compactLayout ? Kirigami.Theme.backgroundColor : "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
footer: Loader {
|
footer: Loader {
|
||||||
id: chatBarLoader
|
id: chatBarLoader
|
||||||
height: active ? (item as ChatBar)?.implicitHeight : 0
|
height: active ? item.implicitHeight : 0
|
||||||
active: timelineViewLoader.active && !root.currentRoom.readOnly
|
active: timelineViewLoader.active && !root.currentRoom.readOnly
|
||||||
sourceComponent: ChatBar {
|
sourceComponent: ChatBar {
|
||||||
id: chatBar
|
id: chatBar
|
||||||
width: parent.width
|
width: parent.width
|
||||||
currentRoom: root.currentRoom
|
currentRoom: root.currentRoom
|
||||||
connection: root.currentRoom.connection as NeoChatConnection
|
connection: root.currentRoom.connection
|
||||||
|
|
||||||
// Creating a reply (or doing anything in the chat bar) can change the height, but this isn't picked up on the root's onHeightChanged.
|
|
||||||
onHeightChanged: root.resetViewSettling()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +203,7 @@ Kirigami.Page {
|
|||||||
function onShowMessage(messageType, message) {
|
function onShowMessage(messageType, message) {
|
||||||
banner.text = message;
|
banner.text = message;
|
||||||
banner.type = messageType;
|
banner.type = messageType;
|
||||||
banner.show("generic");
|
banner.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onShowEventSource(eventId) {
|
function onShowEventSource(eventId) {
|
||||||
@@ -367,17 +215,16 @@ Kirigami.Page {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onShowDelegateMenu(eventId: string, author, messageComponentType, plainText: string, richText: string, mimeType: string, progressInfo, selectedText: string, hoveredLink: string) {
|
function onShowDelegateMenu(eventId: string, author, messageComponentType, plainText: string, richText: string, mimeType: string, progressInfo, isThread: bool, selectedText: string, hoveredLink: string) {
|
||||||
(delegateContextMenu.createObject(root, {
|
const contextMenu = delegateContextMenu.createObject(root, {
|
||||||
author: author,
|
author: author,
|
||||||
eventId: eventId,
|
eventId: eventId,
|
||||||
plainText: plainText,
|
plainText: plainText,
|
||||||
mimeType: mimeType,
|
mimeType: mimeType,
|
||||||
progressInfo: progressInfo,
|
progressInfo: progressInfo,
|
||||||
messageComponentType: messageComponentType,
|
messageComponentType: messageComponentType,
|
||||||
selectedText,
|
});
|
||||||
hoveredLink,
|
contextMenu.popup();
|
||||||
}) as DelegateContextMenu).popup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onShowMaximizedMedia(index) {
|
function onShowMaximizedMedia(index) {
|
||||||
@@ -392,12 +239,12 @@ Kirigami.Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onShowMaximizedCode(author, time, codeText, language) {
|
function onShowMaximizedCode(author, time, codeText, language) {
|
||||||
(Qt.createComponent('org.kde.neochat', 'CodeMaximizeComponent').createObject(QQC2.Overlay.overlay, {
|
let popup = Qt.createComponent('org.kde.neochat', 'CodeMaximizeComponent').createObject(QQC2.Overlay.overlay, {
|
||||||
author: author,
|
author: author,
|
||||||
time: time,
|
time: time,
|
||||||
codeText: codeText,
|
codeText: codeText,
|
||||||
language: language
|
language: language
|
||||||
}) as CodeMaximizeComponent).open();
|
}).open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +252,7 @@ Kirigami.Page {
|
|||||||
id: delegateContextMenu
|
id: delegateContextMenu
|
||||||
DelegateContextMenu {
|
DelegateContextMenu {
|
||||||
room: root.currentRoom
|
room: root.currentRoom
|
||||||
connection: root.currentRoom.connection as NeoChatConnection
|
connection: root.currentRoom.connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,15 +110,15 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
let qrCode = Qt.createComponent('org.kde.neochat', 'QrCodeMaximizeComponent').createObject(QQC2.Overlay.overlay, {
|
let map = Qt.createComponent('org.kde.neochat', 'QrCodeMaximizeComponent').createObject(QQC2.Overlay.overlay, {
|
||||||
text: barcode.content,
|
text: barcode.content,
|
||||||
title: root.room ? root.room.member(root.user.id).displayName : root.user.displayName,
|
title: root.room ? root.room.member(root.user.id).displayName : root.user.displayName,
|
||||||
subtitle: root.user.id,
|
subtitle: root.user.id,
|
||||||
avatarColor: root.room?.member(root.user.id).color,
|
avatarColor: root.room?.member(root.user.id).color,
|
||||||
avatarSource: root.room? root.room.member(root.user.id).avatarUrl : root.user.avatarUrl
|
avatarSource: root.room? root.room.member(root.user.id).avatarUrl : root.user.avatarUrl
|
||||||
}) as QrCodeMaximizeComponent;
|
});
|
||||||
root.close();
|
root.close();
|
||||||
qrCode.open();
|
map.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.ToolTip.visible: hovered
|
QQC2.ToolTip.visible: hovered
|
||||||
@@ -152,7 +152,7 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: root.room && root.user.id !== root.connection.localUserId && root.room.canSendState("kick") && root.room.containsUser(root.user.id) && root.room.memberEffectivePowerLevel(root.user.id) < root.room.memberEffectivePowerLevel(root.connection.localUserId)
|
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("kick") && room.containsUser(root.user.id) && room.memberEffectivePowerLevel(root.user.id) < room.memberEffectivePowerLevel(root.connection.localUserId)
|
||||||
|
|
||||||
text: i18nc("@action:button", "Kick this user")
|
text: i18nc("@action:button", "Kick this user")
|
||||||
icon.name: "im-kick-user"
|
icon.name: "im-kick-user"
|
||||||
@@ -174,7 +174,7 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: root.room && root.user.id !== root.connection.localUserId && root.room.canSendState("invite") && !root.room.containsUser(root.user.id)
|
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("invite") && !room.containsUser(root.user.id)
|
||||||
|
|
||||||
enabled: root.room && !root.room.isUserBanned(root.user.id)
|
enabled: root.room && !root.room.isUserBanned(root.user.id)
|
||||||
text: i18nc("@action:button", "Invite this user")
|
text: i18nc("@action:button", "Invite this user")
|
||||||
@@ -186,7 +186,7 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: root.room && root.user.id !== root.connection.localUserId && root.room.canSendState("ban") && !root.room.isUserBanned(root.user.id) && root.room.memberEffectivePowerLevel(root.user.id) < root.room.memberEffectivePowerLevel(root.connection.localUserId)
|
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("ban") && !room.isUserBanned(root.user.id) && room.memberEffectivePowerLevel(root.user.id) < room.memberEffectivePowerLevel(root.connection.localUserId)
|
||||||
|
|
||||||
text: i18nc("@action:button", "Ban this user")
|
text: i18nc("@action:button", "Ban this user")
|
||||||
icon.name: "im-ban-user"
|
icon.name: "im-ban-user"
|
||||||
@@ -209,7 +209,7 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: root.room && root.user.id !== root.connection.localUserId && root.room.canSendState("ban") && root.room.isUserBanned(root.user.id)
|
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("ban") && room.isUserBanned(root.user.id)
|
||||||
|
|
||||||
text: i18nc("@action:button", "Unban this user")
|
text: i18nc("@action:button", "Unban this user")
|
||||||
icon.name: "im-irc"
|
icon.name: "im-irc"
|
||||||
@@ -225,11 +225,12 @@ Kirigami.Dialog {
|
|||||||
text: i18nc("@action:button", "Set user power level")
|
text: i18nc("@action:button", "Set user power level")
|
||||||
icon.name: "visibility"
|
icon.name: "visibility"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
(powerLevelDialog.createObject(this, {
|
let dialog = powerLevelDialog.createObject(this, {
|
||||||
room: root.room,
|
room: root.room,
|
||||||
userId: root.user.id,
|
userId: root.user.id,
|
||||||
powerLevel: root.room.memberEffectivePowerLevel(root.user.id)
|
powerLevel: root.room.memberEffectivePowerLevel(root.user.id)
|
||||||
}) as PowerLevelDialog).open();
|
});
|
||||||
|
dialog.open();
|
||||||
root.close();
|
root.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,13 +243,13 @@ Kirigami.Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: root.room && (root.user.id === root.connection.localUserId || root.room.canSendState("redact"))
|
visible: root.room && (root.user.id === root.connection.localUserId || room.canSendState("redact"))
|
||||||
|
|
||||||
text: i18nc("@action:button", "Remove recent messages by this user")
|
text: i18nc("@action:button", "Remove recent messages by this user")
|
||||||
icon.name: "delete"
|
icon.name: "delete"
|
||||||
icon.color: Kirigami.Theme.negativeTextColor
|
icon.color: Kirigami.Theme.negativeTextColor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
let dialog = ((QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow).pageStack as Kirigami.PageRow).pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ReasonDialog'), {
|
let dialog = pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ReasonDialog'), {
|
||||||
title: i18nc("@title:dialog", "Remove Messages"),
|
title: i18nc("@title:dialog", "Remove Messages"),
|
||||||
placeholder: i18nc("@info:placeholder", "Reason for removing this user's recent messages"),
|
placeholder: i18nc("@info:placeholder", "Reason for removing this user's recent messages"),
|
||||||
actionText: i18nc("@action:button 'Remove' as in 'Remove these messages'", "Remove"),
|
actionText: i18nc("@action:button 'Remove' as in 'Remove these messages'", "Remove"),
|
||||||
@@ -278,7 +279,7 @@ Kirigami.Dialog {
|
|||||||
text: i18nc("@action:button %1 is the name of the user.", "Search room for %1's messages", root.room ? root.room.member(root.user.id).htmlSafeDisplayName : QmlUtils.escapeString(root.user.displayName))
|
text: i18nc("@action:button %1 is the name of the user.", "Search room for %1's messages", root.room ? root.room.member(root.user.id).htmlSafeDisplayName : QmlUtils.escapeString(root.user.displayName))
|
||||||
icon.name: "search-symbolic"
|
icon.name: "search-symbolic"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
((QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow).pageStack as Kirigami.PageRow).pushDialogLayer(Qt.createComponent('org.kde.neochat', 'RoomSearchPage'), {
|
pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'RoomSearchPage'), {
|
||||||
room: root.room,
|
room: root.room,
|
||||||
senderId: root.user.id
|
senderId: root.user.id
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ SearchPage {
|
|||||||
*/
|
*/
|
||||||
required property NeoChatConnection connection
|
required property NeoChatConnection connection
|
||||||
|
|
||||||
title: i18nc("@action:title", "Find User")
|
title: i18nc("@action:title", "Find Your Friends")
|
||||||
|
|
||||||
Component.onCompleted: focusSearch()
|
Component.onCompleted: focusSearch()
|
||||||
|
|
||||||
@@ -53,16 +53,6 @@ SearchPage {
|
|||||||
root.closeDialog();
|
root.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.ContextMenu.menu: QQC2.Menu {
|
|
||||||
QQC2.MenuItem {
|
|
||||||
text: i18nc("@action:inmenu", "Copy User ID")
|
|
||||||
icon.name: "username-copy"
|
|
||||||
onTriggered: {
|
|
||||||
Clipboard.saveText(userDelegate.userId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
spacing: Kirigami.Units.smallSpacing
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
@@ -81,7 +71,7 @@ SearchPage {
|
|||||||
}
|
}
|
||||||
QQC2.Label {
|
QQC2.Label {
|
||||||
visible: userDelegate.directChatExists
|
visible: userDelegate.directChatExists
|
||||||
text: i18nc("@info", "Direct Messages")
|
text: i18nc("@info", "Friends")
|
||||||
textFormat: Text.PlainText
|
textFormat: Text.PlainText
|
||||||
color: Kirigami.Theme.positiveTextColor
|
color: Kirigami.Theme.positiveTextColor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,7 @@ VerificationMessage {
|
|||||||
|
|
||||||
required property int reason
|
required property int reason
|
||||||
|
|
||||||
icon: {
|
icon: "security-low"
|
||||||
switch (root.reason) {
|
|
||||||
case KeyVerificationSession.TIMEOUT:
|
|
||||||
case KeyVerificationSession.REMOTE_TIMEOUT:
|
|
||||||
case KeyVerificationSession.USER:
|
|
||||||
case KeyVerificationSession.REMOTE_USER:
|
|
||||||
case KeyVerificationSession.SESSION_ACCEPTED:
|
|
||||||
case KeyVerificationSession.REMOTE_SESSION_ACCEPTED:
|
|
||||||
return "dialog-information";
|
|
||||||
default:
|
|
||||||
return "security-low";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text: {
|
text: {
|
||||||
switch (root.reason) {
|
switch (root.reason) {
|
||||||
case KeyVerificationSession.NONE:
|
case KeyVerificationSession.NONE:
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ ColumnLayout {
|
|||||||
|
|
||||||
required property string icon
|
required property string icon
|
||||||
required property string text
|
required property string text
|
||||||
required property bool isDone
|
|
||||||
|
|
||||||
signal done
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
@@ -35,14 +32,6 @@ ColumnLayout {
|
|||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
QQC2.Button {
|
|
||||||
text: i18nc("@action:button Done, we are finished with verification", "Done")
|
|
||||||
visible: root.isDone
|
|
||||||
onClicked: root.done()
|
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "eventhandler.h"
|
#include "eventhandler.h"
|
||||||
#include "models/actionsmodel.h"
|
#include "models/actionsmodel.h"
|
||||||
|
#include "models/messagefiltermodel.h"
|
||||||
|
#include "models/sortfilterroomtreemodel.h"
|
||||||
#include "neochatconfig.h"
|
#include "neochatconfig.h"
|
||||||
#include "neochatconnection.h"
|
#include "neochatconnection.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
@@ -29,28 +31,6 @@
|
|||||||
#include <KIO/OpenUrlJob>
|
#include <KIO/OpenUrlJob>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stops RoomManager from updating the last room and space config.
|
|
||||||
*/
|
|
||||||
class LastRoomBlocker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit LastRoomBlocker(RoomManager *manager)
|
|
||||||
: m_manager(manager)
|
|
||||||
{
|
|
||||||
Q_ASSERT(manager);
|
|
||||||
|
|
||||||
m_manager->m_dontUpdateLastRoom = true;
|
|
||||||
}
|
|
||||||
~LastRoomBlocker()
|
|
||||||
{
|
|
||||||
m_manager->m_dontUpdateLastRoom = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RoomManager *m_manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
RoomManager::RoomManager(QObject *parent)
|
RoomManager::RoomManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_config(KSharedConfig::openStateConfig())
|
, m_config(KSharedConfig::openStateConfig())
|
||||||
@@ -63,7 +43,6 @@ RoomManager::RoomManager(QObject *parent)
|
|||||||
, m_messageFilterModel(new MessageFilterModel(this, m_timelineModel))
|
, m_messageFilterModel(new MessageFilterModel(this, m_timelineModel))
|
||||||
, m_mediaMessageFilterModel(new MediaMessageFilterModel(this, m_messageFilterModel))
|
, m_mediaMessageFilterModel(new MediaMessageFilterModel(this, m_messageFilterModel))
|
||||||
, m_userListModel(new UserListModel(this))
|
, m_userListModel(new UserListModel(this))
|
||||||
, m_widgetModel(new WidgetModel(this))
|
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(UBUNTU_TOUCH)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(UBUNTU_TOUCH)
|
||||||
m_isMobile = true;
|
m_isMobile = true;
|
||||||
@@ -76,7 +55,6 @@ RoomManager::RoomManager(QObject *parent)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(this, &RoomManager::currentRoomChanged, this, [this]() {
|
connect(this, &RoomManager::currentRoomChanged, this, [this]() {
|
||||||
m_widgetModel->setRoom(m_currentRoom);
|
|
||||||
m_userListModel->setRoom(m_currentRoom);
|
m_userListModel->setRoom(m_currentRoom);
|
||||||
m_timelineModel->setRoom(m_currentRoom);
|
m_timelineModel->setRoom(m_currentRoom);
|
||||||
m_sortFilterRoomTreeModel->setCurrentRoom(m_currentRoom);
|
m_sortFilterRoomTreeModel->setCurrentRoom(m_currentRoom);
|
||||||
@@ -219,11 +197,6 @@ void RoomManager::activateUserModel()
|
|||||||
m_userListModel->activate();
|
m_userListModel->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetModel *RoomManager::widgetModel() const
|
|
||||||
{
|
|
||||||
return m_widgetModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RoomManager::resolveResource(const QString &idOrUri, const QString &action)
|
void RoomManager::resolveResource(const QString &idOrUri, const QString &action)
|
||||||
{
|
{
|
||||||
resolveResource(Uri{idOrUri}, action);
|
resolveResource(Uri{idOrUri}, action);
|
||||||
@@ -236,35 +209,24 @@ void RoomManager::resolveResource(Uri uri, const QString &action)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == "qr"_L1) {
|
if (uri.type() == Uri::NonMatrix && action == "qr"_L1) {
|
||||||
if (uri.type() == Uri::NonMatrix) {
|
Q_EMIT externalUrl(uri.toUrl());
|
||||||
Q_EMIT externalUrl(uri.toUrl());
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (uri.type() != Uri::UserId) {
|
|
||||||
uri.setAction(QStringLiteral("join"));
|
|
||||||
} else {
|
|
||||||
uri.setAction(action);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For matrix URIs:
|
|
||||||
if (uri.type() != Uri::NonMatrix) {
|
if (uri.type() != Uri::NonMatrix) {
|
||||||
if (!m_connection) {
|
if (!m_connection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Once a join is confirmed, set the action to "join" so it skips the confirmation check.
|
if (!action.isEmpty() && (uri.type() != Uri::UserId || action != "join"_L1)) {
|
||||||
if (action == "join_confirmed"_L1) {
|
uri.setAction(action);
|
||||||
uri.setAction(QStringLiteral("join"));
|
|
||||||
}
|
}
|
||||||
// TODO we should allow the user to select a connection.
|
// TODO we should allow the user to select a connection.
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto result = visitResource(m_connection, uri);
|
const auto result = visitResource(m_connection, uri);
|
||||||
|
|
||||||
// If we are not already in the room:
|
|
||||||
if (result == Quotient::CouldNotResolve) {
|
if (result == Quotient::CouldNotResolve) {
|
||||||
if ((uri.type() == Uri::RoomAlias || uri.type() == Uri::RoomId) && action == "join"_L1) {
|
if ((uri.type() == Uri::RoomAlias || uri.type() == Uri::RoomId) && action != "no_join"_L1) {
|
||||||
Q_EMIT askJoinRoom(uri.primaryId());
|
Q_EMIT askJoinRoom(uri.primaryId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,6 +308,17 @@ void RoomManager::loadInitialRoom()
|
|||||||
resolveResource(m_arg);
|
resolveResource(m_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_isMobile) {
|
||||||
|
QString lastSpace = m_lastRoomConfig.readEntry(u"lastSpace"_s, QString());
|
||||||
|
// We can't have empty keys in KConfig, so we stored it as "Home"
|
||||||
|
if (lastSpace == u"Home"_s) {
|
||||||
|
lastSpace.clear();
|
||||||
|
}
|
||||||
|
setCurrentSpace(lastSpace, false);
|
||||||
|
// We don't want to open a room on startup on mobile
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_currentRoom) {
|
if (m_currentRoom) {
|
||||||
// we opened a room with the arg parsing already
|
// we opened a room with the arg parsing already
|
||||||
return;
|
return;
|
||||||
@@ -358,14 +331,16 @@ void RoomManager::loadInitialRoom()
|
|||||||
|
|
||||||
void RoomManager::openRoomForActiveConnection()
|
void RoomManager::openRoomForActiveConnection()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_connection);
|
if (!m_connection) {
|
||||||
|
setCurrentRoom({});
|
||||||
|
setCurrentSpace({}, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto lastSpace = m_lastRoomConfig.readEntry(u"lastSpace"_s, QString());
|
auto lastSpace = m_lastRoomConfig.readEntry(u"lastSpace"_s, QString());
|
||||||
if (lastSpace == u"Home"_s) {
|
if (lastSpace == u"Home"_s) {
|
||||||
lastSpace.clear();
|
lastSpace.clear();
|
||||||
}
|
}
|
||||||
// We don't want to open a room on startup on mobile
|
setCurrentSpace(lastSpace, true);
|
||||||
setCurrentSpace(lastSpace, !m_isMobile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UriResolveResult RoomManager::visitUser(User *user, const QString &action)
|
UriResolveResult RoomManager::visitUser(User *user, const QString &action)
|
||||||
@@ -425,7 +400,7 @@ void RoomManager::joinRoom(Quotient::Connection *account, const QString &roomAli
|
|||||||
job.get(),
|
job.get(),
|
||||||
&Quotient::BaseJob::finished,
|
&Quotient::BaseJob::finished,
|
||||||
this,
|
this,
|
||||||
[this, account, roomAliasOrId](Quotient::BaseJob *finish) {
|
[this, account](Quotient::BaseJob *finish) {
|
||||||
if (finish->status() == Quotient::BaseJob::Success) {
|
if (finish->status() == Quotient::BaseJob::Success) {
|
||||||
connect(
|
connect(
|
||||||
account,
|
account,
|
||||||
@@ -436,7 +411,7 @@ void RoomManager::joinRoom(Quotient::Connection *account, const QString &roomAli
|
|||||||
},
|
},
|
||||||
Qt::SingleShotConnection);
|
Qt::SingleShotConnection);
|
||||||
} else {
|
} else {
|
||||||
Q_EMIT showMessage(MessageType::Warning, i18n("Failed to join %1:<br />%2", roomAliasOrId, finish->errorString()));
|
Q_EMIT showMessage(MessageType::Warning, i18n("Failed to join room<br />%1", finish->errorString()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Qt::SingleShotConnection);
|
Qt::SingleShotConnection);
|
||||||
@@ -503,8 +478,9 @@ void RoomManager::setConnection(NeoChatConnection *connection)
|
|||||||
|
|
||||||
m_connection = connection;
|
m_connection = connection;
|
||||||
|
|
||||||
|
m_lastRoomConfig = m_config->group(m_connection->userId()).group(u"LastOpenRoom"_s);
|
||||||
|
|
||||||
if (m_connection != nullptr) {
|
if (m_connection != nullptr) {
|
||||||
m_lastRoomConfig = m_config->group(m_connection->userId()).group(u"LastOpenRoom"_s);
|
|
||||||
connect(m_connection, &NeoChatConnection::showMessage, this, &RoomManager::showMessage);
|
connect(m_connection, &NeoChatConnection::showMessage, this, &RoomManager::showMessage);
|
||||||
connect(m_connection, &NeoChatConnection::createdRoom, this, [this](Quotient::Room *room) {
|
connect(m_connection, &NeoChatConnection::createdRoom, this, [this](Quotient::Room *room) {
|
||||||
resolveResource(room->id());
|
resolveResource(room->id());
|
||||||
@@ -522,85 +498,38 @@ void RoomManager::setConnection(NeoChatConnection *connection)
|
|||||||
Q_EMIT connectionChanged();
|
Q_EMIT connectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::setCurrentSpace(const QString &spaceId, bool goToLastUsedRoom)
|
void RoomManager::setCurrentSpace(const QString &spaceId, bool setRoom)
|
||||||
{
|
{
|
||||||
m_currentSpaceId = spaceId;
|
m_currentSpaceId = spaceId;
|
||||||
|
|
||||||
// This need to happen before the signal so TreeView.expandRecursively() can work nicely.
|
// This need to happen before the signal so TreeView.expandRecursively() can work nicely.
|
||||||
m_sortFilterRoomTreeModel->setActiveSpaceId(m_currentSpaceId);
|
m_sortFilterRoomTreeModel->setActiveSpaceId(m_currentSpaceId);
|
||||||
|
m_sortFilterRoomTreeModel->setMode(m_currentSpaceId == u"DM"_s ? SortFilterRoomTreeModel::DirectChats : SortFilterRoomTreeModel::Rooms);
|
||||||
if (m_currentSpaceId == u"DM") {
|
|
||||||
m_sortFilterRoomTreeModel->setMode(SortFilterRoomTreeModel::DirectChats);
|
|
||||||
} else if (m_currentSpaceId.isEmpty()) {
|
|
||||||
m_sortFilterRoomTreeModel->setMode(SortFilterRoomTreeModel::Rooms);
|
|
||||||
} else {
|
|
||||||
m_sortFilterRoomTreeModel->setMode(SortFilterRoomTreeModel::All);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT currentSpaceChanged();
|
Q_EMIT currentSpaceChanged();
|
||||||
if (m_connection) {
|
if (m_connection) {
|
||||||
m_lastRoomConfig.writeEntry(u"lastSpace"_s, spaceId.isEmpty() ? u"Home"_s : spaceId);
|
m_lastRoomConfig.writeEntry(u"lastSpace"_s, spaceId.isEmpty() ? u"Home"_s : spaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we requested to change to the last opened room, do so:
|
if (!setRoom) {
|
||||||
if (goToLastUsedRoom) {
|
return;
|
||||||
// We don't want to needlessly update the last room config here, that should only be done during explicit user action.
|
}
|
||||||
LastRoomBlocker blocker(this);
|
|
||||||
|
|
||||||
// We can't have empty keys in KConfig, so it's stored as "Home":
|
// We intentionally don't want to open the last room on mobile
|
||||||
if (const auto &lastRoom = m_lastRoomConfig.readEntry(spaceId.isEmpty() ? u"Home"_s : spaceId, QString()); !lastRoom.isEmpty()) {
|
if (m_isMobile) {
|
||||||
resolveResource(lastRoom, "no_join"_L1);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If no last room was opened, go to the space home:
|
// We can't have empty keys in KConfig, so it's stored as "Home"
|
||||||
if (!spaceId.isEmpty() && spaceId != u"DM"_s) {
|
if (const auto &lastRoom = m_lastRoomConfig.readEntry(spaceId.isEmpty() ? u"Home"_s : spaceId, QString()); !lastRoom.isEmpty()) {
|
||||||
resolveResource(spaceId, "no_join"_L1);
|
resolveResource(lastRoom, "no_join"_L1);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to no room opened:
|
|
||||||
setCurrentRoom({});
|
|
||||||
}
|
}
|
||||||
}
|
if (!spaceId.isEmpty() && spaceId != u"DM"_s) {
|
||||||
|
resolveResource(spaceId, "no_join"_L1);
|
||||||
QString RoomManager::findSpaceIdForCurrentRoom() const
|
return;
|
||||||
{
|
|
||||||
if (!m_currentRoom) {
|
|
||||||
return m_currentSpaceId;
|
|
||||||
}
|
}
|
||||||
if (m_currentRoom->isDirectChat()) {
|
setCurrentRoom({});
|
||||||
const auto roomsInSpace = SpaceHierarchyCache::instance().getRoomListForSpace(m_currentSpaceId, false);
|
|
||||||
if (roomsInSpace.contains(m_currentRoom->id())) {
|
|
||||||
return m_currentSpaceId;
|
|
||||||
}
|
|
||||||
return "DM"_L1;
|
|
||||||
}
|
|
||||||
const auto &parentSpaces = SpaceHierarchyCache::instance().parentSpaces(m_currentRoom->id());
|
|
||||||
if (parentSpaces.contains(m_currentSpaceId)) {
|
|
||||||
return m_currentSpaceId;
|
|
||||||
}
|
|
||||||
static auto config = NeoChatConfig::self();
|
|
||||||
if (config->allRoomsInHome()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (const auto &parent = m_connection->room(m_currentRoom->canonicalParent())) {
|
|
||||||
for (const auto &parentParent : SpaceHierarchyCache::instance().parentSpaces(parent->id())) {
|
|
||||||
if (SpaceHierarchyCache::instance().parentSpaces(parentParent).isEmpty()) {
|
|
||||||
return parentParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parent->id();
|
|
||||||
}
|
|
||||||
for (const auto &space : parentSpaces) {
|
|
||||||
if (SpaceHierarchyCache::instance().parentSpaces(space).isEmpty()) {
|
|
||||||
return space;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_currentRoom->isSpace()) {
|
|
||||||
return m_currentSpaceId;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::setCurrentRoom(const QString &roomId)
|
void RoomManager::setCurrentRoom(const QString &roomId)
|
||||||
@@ -620,25 +549,56 @@ void RoomManager::setCurrentRoom(const QString &roomId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_EMIT currentRoomChanged();
|
Q_EMIT currentRoomChanged();
|
||||||
|
if (m_connection) {
|
||||||
if (!m_dontUpdateLastRoom) {
|
|
||||||
if (roomId.isEmpty()) {
|
if (roomId.isEmpty()) {
|
||||||
m_lastRoomConfig.deleteEntry(m_currentSpaceId);
|
m_lastRoomConfig.deleteEntry(m_currentSpaceId);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto spaceIdForRoom = findSpaceIdForCurrentRoom();
|
|
||||||
// We can't have empty keys in KConfig, so name it "Home"
|
|
||||||
if (spaceIdForRoom.isEmpty()) {
|
|
||||||
m_lastRoomConfig.writeEntry(u"Home"_s, roomId);
|
|
||||||
} else {
|
} else {
|
||||||
m_lastRoomConfig.writeEntry(spaceIdForRoom, roomId);
|
// We can't have empty keys in KConfig, so name it "Home"
|
||||||
}
|
if (m_currentSpaceId.isEmpty()) {
|
||||||
|
m_lastRoomConfig.writeEntry(u"Home"_s, roomId);
|
||||||
if (m_currentSpaceId != spaceIdForRoom) {
|
} else {
|
||||||
setCurrentSpace(spaceIdForRoom, false);
|
m_lastRoomConfig.writeEntry(m_currentSpaceId, roomId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (roomId.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_currentRoom->isSpace()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_currentRoom->isDirectChat()) {
|
||||||
|
if (m_currentSpaceId != "DM"_L1) {
|
||||||
|
setCurrentSpace("DM"_L1, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto &parentSpaces = SpaceHierarchyCache::instance().parentSpaces(roomId);
|
||||||
|
if (parentSpaces.contains(m_currentSpaceId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static auto config = NeoChatConfig::self();
|
||||||
|
if (config->allRoomsInHome()) {
|
||||||
|
setCurrentSpace({}, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (const auto &parent = m_connection->room(m_currentRoom->canonicalParent())) {
|
||||||
|
for (const auto &parentParent : SpaceHierarchyCache::instance().parentSpaces(parent->id())) {
|
||||||
|
if (SpaceHierarchyCache::instance().parentSpaces(parentParent).isEmpty()) {
|
||||||
|
setCurrentSpace(parentParent, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentSpace(parent->id(), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const auto &space : parentSpaces) {
|
||||||
|
if (SpaceHierarchyCache::instance().parentSpaces(space).isEmpty()) {
|
||||||
|
setCurrentSpace(space, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentSpace({}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::clearCurrentRoom()
|
void RoomManager::clearCurrentRoom()
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "models/sortfilterspacelistmodel.h"
|
#include "models/sortfilterspacelistmodel.h"
|
||||||
#include "models/timelinemodel.h"
|
#include "models/timelinemodel.h"
|
||||||
#include "models/userlistmodel.h"
|
#include "models/userlistmodel.h"
|
||||||
#include "models/widgetmodel.h"
|
|
||||||
#include "neochatroommember.h"
|
#include "neochatroommember.h"
|
||||||
|
|
||||||
class NeoChatRoom;
|
class NeoChatRoom;
|
||||||
@@ -130,14 +129,6 @@ class RoomManager : public QObject, public UriResolverBase
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(UserListModel *userListModel READ userListModel CONSTANT)
|
Q_PROPERTY(UserListModel *userListModel READ userListModel CONSTANT)
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The WidgetModel that should be used for room widget visualisation.
|
|
||||||
*
|
|
||||||
* @note Available here so that the room page and drawer both have access to the
|
|
||||||
* same model.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(WidgetModel *widgetModel READ widgetModel CONSTANT)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether a room is currently open in NeoChat.
|
* @brief Whether a room is currently open in NeoChat.
|
||||||
*
|
*
|
||||||
@@ -169,8 +160,6 @@ public:
|
|||||||
UserListModel *userListModel() const;
|
UserListModel *userListModel() const;
|
||||||
Q_INVOKABLE void activateUserModel();
|
Q_INVOKABLE void activateUserModel();
|
||||||
|
|
||||||
WidgetModel *widgetModel() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resolve the given resource.
|
* @brief Resolve the given resource.
|
||||||
*
|
*
|
||||||
@@ -337,11 +326,6 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
void currentSpaceChanged();
|
void currentSpaceChanged();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool m_dontUpdateLastRoom = false; // Don't set directly, use LastRoomBlocker.
|
|
||||||
|
|
||||||
friend class LastRoomBlocker;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_isMobile = false;
|
bool m_isMobile = false;
|
||||||
|
|
||||||
@@ -372,28 +356,13 @@ private:
|
|||||||
MediaMessageFilterModel *m_mediaMessageFilterModel;
|
MediaMessageFilterModel *m_mediaMessageFilterModel;
|
||||||
|
|
||||||
UserListModel *m_userListModel;
|
UserListModel *m_userListModel;
|
||||||
WidgetModel *m_widgetModel;
|
|
||||||
|
|
||||||
QPointer<NeoChatConnection> m_connection;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
|
|
||||||
void setCurrentRoom(const QString &roomId);
|
void setCurrentRoom(const QString &roomId);
|
||||||
|
|
||||||
/**
|
// Space ID, "DM", or empty string
|
||||||
* @brief Find the most appropriate space for the currently selected room
|
void setCurrentSpace(const QString &spaceId, bool setRoom = true);
|
||||||
*
|
|
||||||
* Should be used to figure out what space to switch to after a room change.
|
|
||||||
*
|
|
||||||
* @return The Space ID that the currently set room should be displayed as part of. (or "DM" for DM and "" for Home)
|
|
||||||
*/
|
|
||||||
QString findSpaceIdForCurrentRoom() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the current space.
|
|
||||||
*
|
|
||||||
* @param spaceId The ID of the space, "DM" for direct messages or an empty string for Home.
|
|
||||||
* @param goToLastUsedRoom If true, we will navigate to the last opened room in this space.
|
|
||||||
*/
|
|
||||||
void setCurrentSpace(const QString &spaceId, bool goToLastUsedRoom = true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resolve a user URI.
|
* @brief Resolve a user URI.
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
|
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
#include "models/roomlistmodel.h"
|
||||||
|
#include "models/sortfilterroomlistmodel.h"
|
||||||
#include "roommanager.h"
|
#include "roommanager.h"
|
||||||
#include "windowcontroller.h"
|
#include "windowcontroller.h"
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
// SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
// SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtCore
|
import QtCore
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
@@ -89,15 +87,9 @@ QQC2.Control {
|
|||||||
displayHint: Kirigami.DisplayHint.IconOnly
|
displayHint: Kirigami.DisplayHint.IconOnly
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (Clipboard.hasImage) {
|
let dialog = (Clipboard.hasImage ? attachDialog : openFileDialog).createObject(root.QQC2.Overlay.overlay);
|
||||||
let dialog = attachDialog.createObject(root.QQC2.Overlay.overlay) as AttachDialog;
|
dialog.chosen.connect(path => _private.chatBarCache.attachmentPath = path);
|
||||||
dialog.chosen.connect(path => _private.chatBarCache.attachmentPath = path);
|
dialog.open();
|
||||||
dialog.open();
|
|
||||||
} else {
|
|
||||||
let dialog = openFileDialog.createObject(root.QQC2.Overlay.overlay) as OpenFileDialog;
|
|
||||||
dialog.chosen.connect(path => _private.chatBarCache.attachmentPath = path);
|
|
||||||
dialog.open();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tooltip: text
|
tooltip: text
|
||||||
@@ -130,9 +122,9 @@ QQC2.Control {
|
|||||||
displayHint: QQC2.AbstractButton.IconOnly
|
displayHint: QQC2.AbstractButton.IconOnly
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
(locationChooser.createObject(QQC2.Overlay.overlay, {
|
locationChooser.createObject(QQC2.Overlay.overlay, {
|
||||||
room: root.currentRoom
|
room: root.currentRoom
|
||||||
}) as LocationChooser).open();
|
}).open();
|
||||||
}
|
}
|
||||||
tooltip: text
|
tooltip: text
|
||||||
},
|
},
|
||||||
@@ -144,9 +136,9 @@ QQC2.Control {
|
|||||||
displayHint: QQC2.AbstractButton.IconOnly
|
displayHint: QQC2.AbstractButton.IconOnly
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
(newPollDialog.createObject(QQC2.Overlay.overlay, {
|
newPollDialog.createObject(QQC2.Overlay.overlay, {
|
||||||
room: root.currentRoom
|
room: root.currentRoom
|
||||||
}) as NewPollDialog).open();
|
}).open();
|
||||||
}
|
}
|
||||||
tooltip: text
|
tooltip: text
|
||||||
},
|
},
|
||||||
@@ -263,7 +255,6 @@ QQC2.Control {
|
|||||||
wrapMode: TextEdit.Wrap
|
wrapMode: TextEdit.Wrap
|
||||||
// This has to stay PlainText or else formatting starts breaking in strange ways
|
// This has to stay PlainText or else formatting starts breaking in strange ways
|
||||||
textFormat: TextEdit.PlainText
|
textFormat: TextEdit.PlainText
|
||||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * NeoChatConfig.fontScale
|
|
||||||
|
|
||||||
Accessible.description: placeholderText
|
Accessible.description: placeholderText
|
||||||
|
|
||||||
@@ -376,9 +367,7 @@ QQC2.Control {
|
|||||||
id: actionDelegate
|
id: actionDelegate
|
||||||
required property BusyAction modelData
|
required property BusyAction modelData
|
||||||
icon.name: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
|
icon.name: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
|
||||||
onClicked: if (!pieProgress.visible) {
|
onClicked: modelData.trigger()
|
||||||
modelData.trigger()
|
|
||||||
}
|
|
||||||
|
|
||||||
padding: Kirigami.Units.smallSpacing
|
padding: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
@@ -386,9 +375,7 @@ QQC2.Control {
|
|||||||
QQC2.ToolTip.text: modelData.tooltip
|
QQC2.ToolTip.text: modelData.tooltip
|
||||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
|
|
||||||
PieProgressBar {
|
contentItem: PieProgressBar {
|
||||||
id: pieProgress
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: actionDelegate.modelData.isBusy
|
visible: actionDelegate.modelData.isBusy
|
||||||
progress: root.currentRoom.fileUploadingProgress
|
progress: root.currentRoom.fileUploadingProgress
|
||||||
}
|
}
|
||||||
@@ -415,7 +402,7 @@ QQC2.Control {
|
|||||||
ReplyComponent {
|
ReplyComponent {
|
||||||
id: replyComponent
|
id: replyComponent
|
||||||
replyContentModel: ContentProvider.contentModelForEvent(root.currentRoom, _private.chatBarCache.replyId, true)
|
replyContentModel: ContentProvider.contentModelForEvent(root.currentRoom, _private.chatBarCache.replyId, true)
|
||||||
Message.maxContentWidth: (replyLoader.item as Item).width
|
Message.maxContentWidth: replyLoader.item.width
|
||||||
|
|
||||||
// When the user replies to a message and the preview is loaded, make sure the text field is focused again
|
// 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)
|
Component.onCompleted: textField.forceActiveFocus(Qt.OtherFocusReason)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
QQC2.ItemDelegate {
|
QQC2.ItemDelegate {
|
||||||
id: root
|
id: root
|
||||||
@@ -30,7 +29,6 @@ QQC2.ItemDelegate {
|
|||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.family: "emoji"
|
font.family: "emoji"
|
||||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * NeoChatConfig.fontScale
|
|
||||||
|
|
||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
width: Kirigami.Units.gridUnit * 0.5
|
width: Kirigami.Units.gridUnit * 0.5
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ QQC2.Popup {
|
|||||||
padding: 2
|
padding: 2
|
||||||
|
|
||||||
implicitHeight: Kirigami.Units.gridUnit * 20 + 2 * padding
|
implicitHeight: Kirigami.Units.gridUnit * 20 + 2 * padding
|
||||||
width: Math.min(contentItem.categoryIconSize * 11 + 2 * padding, QQC2.ApplicationWindow.window?.width)
|
width: Math.min(contentItem.categoryIconSize * 11 + 2 * padding, QQC2.ApplicationWindow.window.width)
|
||||||
contentItem: EmojiPicker {
|
contentItem: EmojiPicker {
|
||||||
id: emojiPicker
|
id: emojiPicker
|
||||||
height: 400
|
height: 400
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ ColumnLayout {
|
|||||||
id: quickReactions
|
id: quickReactions
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
model: ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"]
|
model: ["👍", "👎", "😄", "🎉", "😕", "❤", "🚀", "👀"]
|
||||||
|
|
||||||
delegate: EmojiDelegate {
|
delegate: EmojiDelegate {
|
||||||
required property string modelData
|
required property string modelData
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
|
import QtQuick.Layouts
|
||||||
import QtCore as Core
|
import QtCore as Core
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.kquickimageeditor as KQuickImageEditor
|
import org.kde.kquickimageeditor as KQuickImageEditor
|
||||||
|
|
||||||
Kirigami.Page {
|
Kirigami.Page {
|
||||||
id: root
|
id: rootEditorView
|
||||||
|
|
||||||
property bool resizing: false
|
property bool resizing: false
|
||||||
required property string imagePath
|
required property string imagePath
|
||||||
@@ -25,7 +26,7 @@ Kirigami.Page {
|
|||||||
function crop() {
|
function crop() {
|
||||||
const ratioX = editImage.paintedWidth / editImage.nativeWidth;
|
const ratioX = editImage.paintedWidth / editImage.nativeWidth;
|
||||||
const ratioY = editImage.paintedHeight / editImage.nativeHeight;
|
const ratioY = editImage.paintedHeight / editImage.nativeHeight;
|
||||||
root.resizing = false;
|
rootEditorView.resizing = false;
|
||||||
imageDoc.crop(selectionTool.selectionX / ratioX, selectionTool.selectionY / ratioY, selectionTool.selectionWidth / ratioX, selectionTool.selectionHeight / ratioY);
|
imageDoc.crop(selectionTool.selectionX / ratioX, selectionTool.selectionY / ratioY, selectionTool.selectionWidth / ratioX, selectionTool.selectionHeight / ratioY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,9 +43,9 @@ Kirigami.Page {
|
|||||||
text: i18nc("@action:button Accept image modification", "Accept")
|
text: i18nc("@action:button Accept image modification", "Accept")
|
||||||
icon.name: "dialog-ok"
|
icon.name: "dialog-ok"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
let newPath = Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + (new Date()).getTime() + "." + root.imagePath.split('.').pop();
|
let newPath = Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + (new Date()).getTime() + "." + imagePath.split('.').pop();
|
||||||
if (imageDoc.saveAs(newPath)) {
|
if (imageDoc.saveAs(newPath)) {
|
||||||
root.newPathChanged(newPath);
|
newPathChanged(newPath);
|
||||||
} else {
|
} else {
|
||||||
msg.type = Kirigami.MessageType.Error;
|
msg.type = Kirigami.MessageType.Error;
|
||||||
msg.text = i18n("Unable to save file. Check if you have the correct permission to edit the cache directory.");
|
msg.text = i18n("Unable to save file. Check if you have the correct permission to edit the cache directory.");
|
||||||
@@ -79,12 +80,12 @@ Kirigami.Page {
|
|||||||
|
|
||||||
KQuickImageEditor.ImageDocument {
|
KQuickImageEditor.ImageDocument {
|
||||||
id: imageDoc
|
id: imageDoc
|
||||||
path: root.imagePath
|
path: rootEditorView.imagePath
|
||||||
}
|
}
|
||||||
|
|
||||||
KQuickImageEditor.SelectionTool {
|
KQuickImageEditor.SelectionTool {
|
||||||
id: selectionTool
|
id: selectionTool
|
||||||
visible: root.resizing
|
visible: rootEditorView.resizing
|
||||||
width: editImage.paintedWidth
|
width: editImage.paintedWidth
|
||||||
height: editImage.paintedHeight
|
height: editImage.paintedHeight
|
||||||
x: editImage.horizontalPadding
|
x: editImage.horizontalPadding
|
||||||
@@ -100,7 +101,7 @@ Kirigami.Page {
|
|||||||
Connections {
|
Connections {
|
||||||
target: selectionTool.selectionArea
|
target: selectionTool.selectionArea
|
||||||
function onDoubleClicked() {
|
function onDoubleClicked() {
|
||||||
root.crop();
|
rootEditorView.crop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,8 +119,8 @@ Kirigami.Page {
|
|||||||
display: QQC2.Button.TextBesideIcon
|
display: QQC2.Button.TextBesideIcon
|
||||||
actions: [
|
actions: [
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: root.resizing ? "dialog-cancel" : "transform-crop"
|
icon.name: rootEditorView.resizing ? "dialog-cancel" : "transform-crop"
|
||||||
text: root.resizing ? i18n("Cancel") : i18nc("@action:button Crop an image", "Crop")
|
text: rootEditorView.resizing ? i18n("Cancel") : i18nc("@action:button Crop an image", "Crop")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
resizeRectangle.width = editImage.paintedWidth;
|
resizeRectangle.width = editImage.paintedWidth;
|
||||||
resizeRectangle.height = editImage.paintedHeight;
|
resizeRectangle.height = editImage.paintedHeight;
|
||||||
@@ -129,38 +130,38 @@ Kirigami.Page {
|
|||||||
resizeRectangle.insideY = 100;
|
resizeRectangle.insideY = 100;
|
||||||
resizeRectangle.insideWidth = 100;
|
resizeRectangle.insideWidth = 100;
|
||||||
resizeRectangle.insideHeight = 100;
|
resizeRectangle.insideHeight = 100;
|
||||||
root.resizing = !root.resizing;
|
rootEditorView.resizing = !rootEditorView.resizing;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: "dialog-ok"
|
icon.name: "dialog-ok"
|
||||||
visible: root.resizing
|
visible: rootEditorView.resizing
|
||||||
text: i18nc("@action:button Crop an image", "Crop")
|
text: i18nc("@action:button Crop an image", "Crop")
|
||||||
onTriggered: root.crop()
|
onTriggered: rootEditorView.crop()
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: "object-rotate-left"
|
icon.name: "object-rotate-left"
|
||||||
text: i18nc("@action:button Rotate an image to the left", "Rotate left")
|
text: i18nc("@action:button Rotate an image to the left", "Rotate left")
|
||||||
onTriggered: imageDoc.rotate(-90)
|
onTriggered: imageDoc.rotate(-90)
|
||||||
visible: !root.resizing
|
visible: !rootEditorView.resizing
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: "object-rotate-right"
|
icon.name: "object-rotate-right"
|
||||||
text: i18nc("@action:button Rotate an image to the right", "Rotate right")
|
text: i18nc("@action:button Rotate an image to the right", "Rotate right")
|
||||||
onTriggered: imageDoc.rotate(90)
|
onTriggered: imageDoc.rotate(90)
|
||||||
visible: !root.resizing
|
visible: !rootEditorView.resizing
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: "object-flip-vertical"
|
icon.name: "object-flip-vertical"
|
||||||
text: i18nc("@action:button Mirror an image vertically", "Flip")
|
text: i18nc("@action:button Mirror an image vertically", "Flip")
|
||||||
onTriggered: imageDoc.mirror(false, true)
|
onTriggered: imageDoc.mirror(false, true)
|
||||||
visible: !root.resizing
|
visible: !rootEditorView.resizing
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
icon.name: "object-flip-horizontal"
|
icon.name: "object-flip-horizontal"
|
||||||
text: i18nc("@action:button Mirror an image horizontally", "Mirror")
|
text: i18nc("@action:button Mirror an image horizontally", "Mirror")
|
||||||
onTriggered: imageDoc.mirror(true, false)
|
onTriggered: imageDoc.mirror(true, false)
|
||||||
visible: !root.resizing
|
visible: !rootEditorView.resizing
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user