Compare commits
96 Commits
v23.08.5
...
work/nvrwh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41603e7aa2 | ||
|
|
65a1df4a75 | ||
|
|
d15157703a | ||
|
|
2d21330a36 | ||
|
|
fbc4611d02 | ||
|
|
e257865b19 | ||
|
|
018154f555 | ||
|
|
80a5daa1f7 | ||
|
|
bf5ce049d9 | ||
|
|
58213ee3e6 | ||
|
|
2d1862a637 | ||
|
|
67453d9fb8 | ||
|
|
3ab04583ae | ||
|
|
794683b5d2 | ||
|
|
9f7f5409bd | ||
|
|
7d7b9d7ae0 | ||
|
|
c7c892c51c | ||
|
|
97903a7cb0 | ||
|
|
0c8f488ac4 | ||
|
|
88368cefaa | ||
|
|
ab4bb41979 | ||
|
|
c2398b19dc | ||
|
|
4b3dac025f | ||
|
|
9eeff06328 | ||
|
|
657a8291d0 | ||
|
|
bc4431462a | ||
|
|
fdd8a62873 | ||
|
|
c164228894 | ||
|
|
7d418f0883 | ||
|
|
e90aecbead | ||
|
|
221c27fbbe | ||
|
|
1907404124 | ||
|
|
81e953dd8c | ||
|
|
9311052e39 | ||
|
|
648fff20f2 | ||
|
|
980211f36a | ||
|
|
25e0e3fa8e | ||
|
|
403c1ed391 | ||
|
|
c2f76612cf | ||
|
|
2a651b8946 | ||
|
|
00c0d1c276 | ||
|
|
0162d91b60 | ||
|
|
5f41b7b4c1 | ||
|
|
d9691bac7c | ||
|
|
719b916837 | ||
|
|
f9514fe925 | ||
|
|
399b9e6944 | ||
|
|
00cf5c8a5b | ||
|
|
02f26424e2 | ||
|
|
3bd639775a | ||
|
|
163c1ef407 | ||
|
|
9997b1074a | ||
|
|
f52a25717b | ||
|
|
5746c24b73 | ||
|
|
dca1b22521 | ||
|
|
b15f1461d8 | ||
|
|
24fd7a0f5b | ||
|
|
0ac3932303 | ||
|
|
807a9ee779 | ||
|
|
4f32a168cd | ||
|
|
45d2da56c7 | ||
|
|
d794e26d62 | ||
|
|
42cc42642d | ||
|
|
ffd6205bd1 | ||
|
|
9ba6b2f0a5 | ||
|
|
f8d3e25f8e | ||
|
|
75cd77facb | ||
|
|
8546d76a54 | ||
|
|
00b7f68a03 | ||
|
|
b486cb905c | ||
|
|
cdd5c9f484 | ||
|
|
3e6c426397 | ||
|
|
847f41e1ad | ||
|
|
ed5bb270ff | ||
|
|
c8b4da2b96 | ||
|
|
ba5445e135 | ||
|
|
1cca39e105 | ||
|
|
dbf67b984e | ||
|
|
c9126cf38e | ||
|
|
13988da4fc | ||
|
|
0847839abc | ||
|
|
6b55e502a0 | ||
|
|
8f81629ac1 | ||
|
|
7f459cb90f | ||
|
|
420e195313 | ||
|
|
3263a69880 | ||
|
|
b060881f06 | ||
|
|
701e786c1f | ||
|
|
646c8ba8fe | ||
|
|
9b31fdea10 | ||
|
|
ce5dfdee16 | ||
|
|
918e805718 | ||
|
|
7debf47833 | ||
|
|
2c142c36e6 | ||
|
|
3279142498 | ||
|
|
0e08a1aa7e |
@@ -1,5 +0,0 @@
|
||||
; SPDX-FileCopyrightText: None
|
||||
; SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
[BlueprintSettings]
|
||||
kde/applications/neochat.packageAppx = True
|
||||
@@ -26,7 +26,7 @@
|
||||
"name": "kirigamiaddons",
|
||||
"config-opts": [ "-DBUILD_TESTING=OFF" ],
|
||||
"buildsystem": "cmake-ninja",
|
||||
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git", "branch": "kf5" } ]
|
||||
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git" } ]
|
||||
},
|
||||
{
|
||||
"name": "kquickimageeditor",
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
include:
|
||||
- project: sysadmin/ci-utilities
|
||||
file:
|
||||
- /gitlab-templates/reuse-lint.yml
|
||||
- /gitlab-templates/android.yml
|
||||
# - /gitlab-templates/linux.yml
|
||||
- /gitlab-templates/linux-qt6.yml
|
||||
- /gitlab-templates/windows.yml
|
||||
# - /gitlab-templates/freebsd.yml
|
||||
- /gitlab-templates/flatpak.yml
|
||||
- /gitlab-templates/craft-android-apks.yml
|
||||
- /gitlab-templates/craft-windows-x86-64.yml
|
||||
- /gitlab-templates/craft-windows-appx-qt5.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml
|
||||
|
||||
@@ -58,5 +58,9 @@ Dependencies:
|
||||
'require':
|
||||
'frameworks/kdbusaddons': '@latest-kf6'
|
||||
|
||||
- 'on': ['Linux/Qt6', 'Linux/Qt5']
|
||||
'require':
|
||||
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
|
||||
|
||||
Options:
|
||||
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD' ]
|
||||
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
|
||||
|
||||
@@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# KDE Applications version, managed by release script.
|
||||
set(RELEASE_SERVICE_VERSION_MAJOR "23")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "08")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "5")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "11")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "70")
|
||||
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
|
||||
|
||||
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
|
||||
@@ -93,12 +93,6 @@ set_package_properties(KF${QT_MAJOR_VERSION}Kirigami2 PROPERTIES
|
||||
)
|
||||
find_package(KF${QT_MAJOR_VERSION}KirigamiAddons 0.7.2 REQUIRED)
|
||||
|
||||
find_package(Qt${QT_MAJOR_VERSION}Keychain)
|
||||
set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Secure storage of account secrets"
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
find_package(OpenSSL)
|
||||
set_package_properties(OpenSSL PROPERTIES
|
||||
@@ -130,6 +124,11 @@ set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES
|
||||
PURPOSE "Talk with matrix server"
|
||||
)
|
||||
|
||||
if (NOT TARGET Olm::Olm)
|
||||
message(FATAL_ERROR "NeoChat requires Quotient with the E2EE feature enabled")
|
||||
endif()
|
||||
|
||||
|
||||
find_package(cmark)
|
||||
set_package_properties(cmark PROPERTIES
|
||||
TYPE REQUIRED
|
||||
@@ -141,7 +140,6 @@ set_package_properties(cmark PROPERTIES
|
||||
ecm_find_qmlmodule(org.kde.kquickimageeditor 1.0)
|
||||
ecm_find_qmlmodule(org.kde.kitemmodels 1.0)
|
||||
ecm_find_qmlmodule(org.kde.quickcharts 1.0)
|
||||
ecm_find_qmlmodule(QtLocation ${QTLOCATION_MODULE_QML_VERSION})
|
||||
|
||||
find_package(KQuickImageEditor COMPONENTS)
|
||||
set_package_properties(KQuickImageEditor PROPERTIES
|
||||
@@ -161,10 +159,6 @@ set_package_properties(KF${QT_MAJOR_VERSION}DocTools PROPERTIES DESCRIPTION
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
|
||||
if(NOT Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
|
||||
cmake_policy(SET CMP0063 OLD)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
find_package(Sqlite3)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
|
||||
@@ -180,9 +174,11 @@ install(FILES org.kde.neochat.tray.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/h
|
||||
add_definitions(-DQT_NO_FOREACH)
|
||||
|
||||
add_subdirectory(src)
|
||||
if (BUILD_TESTING AND Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||
add_subdirectory(autotests)
|
||||
add_subdirectory(appiumtests)
|
||||
endif()
|
||||
|
||||
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)
|
||||
|
||||
23
appiumtests/CMakeLists.txt
Normal file
23
appiumtests/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
|
||||
|
||||
|
||||
if(NOT BUILD_TESTING OR NOT CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(SeleniumWebDriverATSPI)
|
||||
set_package_properties(SeleniumWebDriverATSPI PROPERTIES
|
||||
DESCRIPTION "Server component for selenium tests using Linux accessibility infrastructure"
|
||||
PURPOSE "Needed for GUI tests"
|
||||
URL "https://invent.kde.org/sdk/selenium-webdriver-at-spi"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(NOT SeleniumWebDriverATSPI_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME logintest
|
||||
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/logintest.py
|
||||
)
|
||||
42
appiumtests/login-server.py
Normal file
42
appiumtests/login-server.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
|
||||
|
||||
from flask import Flask, request, abort
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/_matrix/client/v3/login", methods=["GET"])
|
||||
def login_get():
|
||||
result = dict()
|
||||
result["flows"] = [dict()]
|
||||
result["flows"][0]["type"] = "m.login.password"
|
||||
return result
|
||||
|
||||
@app.route("/_matrix/client/v3/login", methods=["POST"])
|
||||
def login_post():
|
||||
data = request.get_json()
|
||||
if data["identifier"]["user"] != "user" or data["password"] != "1234":
|
||||
abort(403)
|
||||
print(data)
|
||||
result = dict()
|
||||
result["access_token"] = "token_1234"
|
||||
result["device_id"] = "device_1234"
|
||||
result["user_id"] = "@user:localhost:1234"
|
||||
return result
|
||||
|
||||
@app.route("/_matrix/client/r0/sync")
|
||||
def sync():
|
||||
result = dict()
|
||||
result["next_batch"] = "batch1234"
|
||||
return result
|
||||
|
||||
@app.route("/.well-known/matrix/client")
|
||||
def well_known():
|
||||
reply = dict()
|
||||
reply["m.homeserver"] = dict()
|
||||
reply["m.homeserver"]["base_url"] = "https://localhost:1234"
|
||||
return reply
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(ssl_context='adhoc', port=1234)
|
||||
44
appiumtests/logintest.py
Executable file
44
appiumtests/logintest.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
|
||||
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
|
||||
import unittest
|
||||
from appium import webdriver
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
class LoginTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
desired_caps = {}
|
||||
desired_caps["app"] = "neochat --ignore-ssl-errors"
|
||||
desired_caps["timeouts"] = {'implicit': 10000}
|
||||
self.driver = webdriver.Remote(
|
||||
command_executor='http://127.0.0.1:4723',
|
||||
desired_capabilities=desired_caps)
|
||||
subprocess.Popen(["python","login-server.py"])
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
if not self._outcome.result.wasSuccessful():
|
||||
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
self.driver.quit()
|
||||
|
||||
def test_login(self):
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Matrix ID").send_keys("@user:localhost:1234")
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Continue").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Password").send_keys("1234")
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Join some rooms to get started").click()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <Quotient/syncdata.h>
|
||||
#include <qnamespace.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class TestRoom : public NeoChatRoom
|
||||
@@ -555,10 +557,10 @@ void TextHandlerTest::receiveRichPlainUrl()
|
||||
void TextHandlerTest::receiveRichEmote()
|
||||
{
|
||||
auto event = room->messageEvents().at(1).get();
|
||||
auto author = static_cast<NeoChatUser *>(room->user(event->senderId()));
|
||||
auto author = room->user(event->senderId());
|
||||
const QString testInputString = QStringLiteral("This is an emote.");
|
||||
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:") + author->color().name()
|
||||
+ QStringLiteral("\">@example:example.org</a> This is an emote.");
|
||||
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:")
|
||||
+ Utils::getUserColor(author->hueF()).name() + QStringLiteral("\">@example:example.org</a> This is an emote.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -644,5 +646,5 @@ void TextHandlerTest::linkPreviewsReject()
|
||||
QCOMPARE(testTextHandler.getLinkPreviews(), testOutputLinks);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TextHandlerTest)
|
||||
QTEST_MAIN(TextHandlerTest)
|
||||
#include "texthandlertest.moc"
|
||||
|
||||
@@ -46,45 +46,22 @@
|
||||
<name xml:lang="uk">NeoChat</name>
|
||||
<name xml:lang="x-test">xxNeoChatxx</name>
|
||||
<name xml:lang="zh-CN">NeoChat</name>
|
||||
<name xml:lang="zh-TW">NeoChat</name>
|
||||
<summary>A client for matrix, the decentralized communication protocol</summary>
|
||||
<summary xml:lang="ar">عميل لماتركس، ميفاق الاتصال اللامركزي</summary>
|
||||
<summary xml:lang="az">Matrix üçün müştəri, mərkəzləşməmiş kommunikasiya protokolu</summary>
|
||||
<summary xml:lang="ca">Un client de Matrix, el protocol de comunicacions descentralitzat</summary>
|
||||
<summary xml:lang="ca-valencia">Un client de Matrix, el protocol de comunicacions descentralitzat</summary>
|
||||
<summary xml:lang="cs">Klient pro decentralizovaný komunikační protokol matrix</summary>
|
||||
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
|
||||
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
|
||||
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
|
||||
<summary xml:lang="eo">Kliento por matrix, la malcentra komunikprotokolo</summary>
|
||||
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
|
||||
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
|
||||
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
|
||||
<summary xml:lang="fr">Un client pour « Matrix », le protocole décentralisé de communications.</summary>
|
||||
<summary xml:lang="gl">Un cliente para Matrix, o protocolo de comunicación descentralizada.</summary>
|
||||
<summary xml:lang="hu">Kliens a matrixhoz, a decentralizált kommunikációs protokollhoz</summary>
|
||||
<summary xml:lang="ia">Un cliente per Matrix, le protocollo de communication decentralisate</summary>
|
||||
<summary xml:lang="id">Klien untuk matrix, protokol komunikasi terdesentralisasi</summary>
|
||||
<summary xml:lang="ie">Un cliente de Matrix, li protocol de communication decentralisat</summary>
|
||||
<summary xml:lang="it">Un client per matrix, il protocollo di comunicazione decentralizzato</summary>
|
||||
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
|
||||
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
|
||||
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</summary>
|
||||
<summary xml:lang="nn">Ein klient for Matrix – protokollen for desentralisert kommunikasjon</summary>
|
||||
<summary xml:lang="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
|
||||
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
|
||||
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
|
||||
<summary xml:lang="pt-BR">Um cliente do Matrix, o protocolo de comunicação descentralizado</summary>
|
||||
<summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary>
|
||||
<summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary>
|
||||
<summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary>
|
||||
<summary xml:lang="sv">En klient för Matrix, det decentraliserade kommunikationsprotokollet</summary>
|
||||
<summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary>
|
||||
<summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary>
|
||||
<summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary>
|
||||
<summary xml:lang="x-test">xxA client for matrix, the decentralized communication protocolxx</summary>
|
||||
<summary xml:lang="zh-CN">分布式通讯协议 Matrix 的客户端</summary>
|
||||
<summary xml:lang="zh-TW">去中心化通訊協定 Matrix 的用戶端</summary>
|
||||
<summary>Chat with your friends on matrix</summary>
|
||||
<summary xml:lang="ca">Xategeu amb els vostres amics a Matrix</summary>
|
||||
<summary xml:lang="ca-valencia">Xategeu amb els vostres amics a Matrix</summary>
|
||||
<summary xml:lang="eo">Babilu kun viaj amikoj sur matrix</summary>
|
||||
<summary xml:lang="eu">Berriketan jardun zure lagunekin «Matrix»en</summary>
|
||||
<summary xml:lang="gl">Charle coas súas amizades en Matrix.</summary>
|
||||
<summary xml:lang="it">Conversa con i tuoi contatti su matrix</summary>
|
||||
<summary xml:lang="ka">ესაუბრეთ მეგობრებს Matrix-ზე</summary>
|
||||
<summary xml:lang="nl">Met uw vrienden chatten op matrix</summary>
|
||||
<summary xml:lang="nn">Prat med vennar på Matrix</summary>
|
||||
<summary xml:lang="sl">Klepet z vašimi prijatelji na matrixu</summary>
|
||||
<summary xml:lang="sv">Chatta med dina vänner på Matrix</summary>
|
||||
<summary xml:lang="ta">மேட்ரிக்ஸு மூலம் உங்கள் நண்பர்களிடம் பேசலாம்</summary>
|
||||
<summary xml:lang="tr">Matrix'te arkadaşlarınızla sohbet edin</summary>
|
||||
<summary xml:lang="uk">Спілкуйтеся з вашими друзями у matrix</summary>
|
||||
<summary xml:lang="x-test">xxChat with your friends on matrixxx</summary>
|
||||
<description>
|
||||
<p>NeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami
|
||||
to provide a convergent experience across multiple platforms.</p>
|
||||
@@ -106,17 +83,15 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<p xml:lang="nn">NeoChat er ein klient for Matrix, ein protokoll for desentralisert kommunikasjon. Du kan utveksla tekst, lyd og videoar med kollegaar, vennar og familie. Programmet brukar KDE Frameworks og Kirigami for å gje ei brukarflate tilpassa ulike plattformer.</p>
|
||||
<p xml:lang="pl">NeoChat jest programem do Matriksa, protokołu rozproszonego porozumiewania się w czasie rzeczywistym. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół. Używa szkieletów KDE i głównie Kirigami, aby zapewnić spójne wrażenia na wielu platformach</p>
|
||||
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix. Usa as plataformas do KDE, e principalmente o Kirigami, para oferecer uma experiência convergente entre várias plataformas.</p>
|
||||
<p xml:lang="ru">NeoChat — клиент для Matrix, децентрализованного коммуникационного протокола для мгновенного обмена сообщениями. С его помощью возможно отправлять текстовые сообщения, видео- и звуковые файлы родственникам, коллегам и друзьям. В программе использованы библиотеки KDE, в частности Kirigami, для обеспечения единообразной работы на различных платформах.</p>
|
||||
<p xml:lang="sl">Neochat je odjemalec za Matrix, decentralizirani komunikacijski protokol za takojšnje sporočanje. Omogoča vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek svoji družini, sodelavcem in prijateljem. Uporablja okvire ogrodje KDE frameworks in predvsem Kirigami za zagotavljanje konvergentne izkušnje na več platformah.</p>
|
||||
<p xml:lang="sv">NeoChat är en klient för Matrix, det decentraliserade kommunikationsprotokollet för direktmeddelanden. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner. Den använder KDE Ramverk, i synnerhet Kirigami, för att tillhandahålla en konvergent upplevelse på flera plattformar.</p>
|
||||
<p xml:lang="tr">NeoChat, anlık iletileşme için merkezi olmayan iletişim protokolü olan Matrix için bir istemcidir. Ailenize, iş arkadaşlarınıza ve arkadaşlarınıza metin iletiler, videolar ve ses dosyaları göndermenize olanak tanır. Birden çok platformda yakınsak bir deneyim sağlamak için KDE Frameworks ve en önemlilerinden Kirigami'yi kullanır.</p>
|
||||
<p xml:lang="uk">NeoChat — клієнт Matrix, децентралізованого протоколу спілкування для миттєвого обміну повідомленнями. За його допомогою ви можете надсилати текстові повідомлення, відео та звукові файли вашій родин, колегами та друзям. У програмі використано бібліотеки KDE, зокрема Kirigami, для надання однорідного середовища на декількох програмних та апаратних платформах.</p>
|
||||
<p xml:lang="x-test">xxNeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.xx</p>
|
||||
<p xml:lang="zh-TW">NeoChat 是去中心化即時通訊協定 Matrix 的一個用戶端。它讓您可以傳送文字訊息、影片、音訊檔案給您的家人、同事或朋友。NeoChat 使用 KDE frameworks,尤其是 Kirigami,來提供跨平台的響應式體驗。</p>
|
||||
<p>NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
|
||||
<p xml:lang="ar">يهدف نيوتشات إلى أن يكون تطبيقًا كامل الميزات لمواصفات ماتركس. على هذا النحو يتم دعم كل شيء في المواصفات المستقرة الحالية مع الاستثناءات الملحوظة لـ VoIP والخيوط وبعض جوانب التشفير من طرف إلى طرف. هناك عدد قليل من الإغفالات الصغيرة الأخرى بسبب حقيقة أن مواصفات ماتركس تتطور باستمرار ، ولكن يبقى الهدف توفير الدعم النهائي للمواصفات بأكملها.</p>
|
||||
<p xml:lang="ca">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptatge d'extrem a extrem. Hi ha algunes altres omissions més petites a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu segueix sent proporcionar suport eventual per a tota l'especificació.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
|
||||
<p xml:lang="en-GB">NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
|
||||
<p xml:lang="eo">NeoChat celas esti plene kapabla aplikaĵo por la Matrix-specifo. Kiel tia, ĉio en la nuna stabila specifo kun la rimarkindaj esceptoj de VoIP, fadenoj kaj kelkaj aspektoj de Fin-al-Fina Ĉifrado estas subtenataj. Estas kelkaj aliaj pli malgrandaj preterlasoj pro la fakto, ke la Matrix-speco konstante evoluas, sed la celo restas provizi finfine subtenon por la tuta specifaĵo.</p>
|
||||
<p xml:lang="es">NeoChat pretende ser una aplicación con todas las funciones para la especificación de Matrix. Como tal, admite todo en la especificación estable actual, con las notables excepciones de VoIP, subprocesos y algunas funciones de cifrado de extremo a extremo. Existen algunas omisiones menos importantes debido al hecho de que la especificación de Matrix está en constante evolución, pero el objetivo sigue siendo brindar compatibilidad final con toda la especificación.</p>
|
||||
@@ -132,13 +107,11 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
|
||||
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
|
||||
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
|
||||
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
|
||||
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
|
||||
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
|
||||
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme'nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
|
||||
<p xml:lang="uk">Метою створення NeoChat є повноцінна реалізація програми для специфікації Matrix. Як наслідок, реалізовано усе у поточній стабільній специфікації, окрім голосового інтернет-зв'язку, потоків та деяких аспектів міжвузлового шифрування. Є також декілька інших незначних прогалин через те, що специфікація Matrix постійно змінюється, але метою лишається повна підтримка специфікації.</p>
|
||||
<p xml:lang="x-test">xxNeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.xx</p>
|
||||
<p xml:lang="zh-TW">NeoChat 以完整支援 Matrix 標準為目標,因此目前穩定版標準除了 VoIP、對話串與端對端加密的某些部分以外的所有部分都有支援。其他部分還有一些較小的不支援的部分,這是因為 Matrix 標準隨時都在改進,但目標仍然時最終提供整個標準的完整支援。</p>
|
||||
<p>Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:</p>
|
||||
<p xml:lang="ar">نظرًا لطبيعة تطوير مواصفات ماتركس، يدعم نيوتشات أيضًا العديد من الميزات غير المستقرة وهي:</p>
|
||||
<p xml:lang="ca">A causa de la naturalesa del desenvolupament de l'especificació de Matrix, el NeoChat també implementa nombroses característiques inestables. Actualment són:</p>
|
||||
@@ -158,14 +131,12 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
|
||||
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
|
||||
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
|
||||
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
|
||||
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
|
||||
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
|
||||
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் விதத்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
|
||||
<p xml:lang="tr">NeoChat, Matrix belirtimi geliştirmesinin doğası gereği çok sayıda kararsız özelliği de destekler. Şu anda bunlar:</p>
|
||||
<p xml:lang="uk">Через природу розробки специфікації Matrix, у NeoChat також передбачено підтримку численних нестабільних можливостей. У поточній версії цими можливостями є:</p>
|
||||
<p xml:lang="x-test">xxDue to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:xx</p>
|
||||
<p xml:lang="zh-TW">由於 Matrix 標準的開發流程的緣故,NeoChat 也支援數個非穩定版的功能。目前這些功能是:</p>
|
||||
<ul>
|
||||
<li>Polls - MSC3381</li>
|
||||
<li xml:lang="ar">التصويت - MSC3381</li>
|
||||
@@ -184,16 +155,13 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<li xml:lang="ko">투표 - MSC3381</li>
|
||||
<li xml:lang="nl">Polls - MSC3381</li>
|
||||
<li xml:lang="nn">Avstemmingar – MSC3381</li>
|
||||
<li xml:lang="pl">Ankiety - MSC3381</li>
|
||||
<li xml:lang="pt">Inquéritos - MSC3381</li>
|
||||
<li xml:lang="ru">Голосования — MSC3381</li>
|
||||
<li xml:lang="sl">Polls - MSC3381</li>
|
||||
<li xml:lang="sv">Polls - MSC3381</li>
|
||||
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
|
||||
<li xml:lang="tr">Anketler - MSC3381</li>
|
||||
<li xml:lang="uk">Опитування - MSC3381</li>
|
||||
<li xml:lang="x-test">xxPolls - MSC3381xx</li>
|
||||
<li xml:lang="zh-TW">投票 - MSC3381</li>
|
||||
<li>Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ar">حزم الملصقات - MSC2545</li>
|
||||
<li xml:lang="ca">Paquets d'adhesius - MSC2545</li>
|
||||
@@ -211,16 +179,13 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<li xml:lang="ko">스티커 팩 - MSC2545</li>
|
||||
<li xml:lang="nl">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="nn">Klistremerke-pakkar – MSC2545</li>
|
||||
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
|
||||
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
|
||||
<li xml:lang="ru">Наборы наклеек — MSC2545</li>
|
||||
<li xml:lang="sl">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="sv">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
||||
<li xml:lang="tr">Yapışkan Paketleri - MSC2545</li>
|
||||
<li xml:lang="uk">Пакунки наліпок - MSC2545</li>
|
||||
<li xml:lang="x-test">xxSticker Packs - MSC2545xx</li>
|
||||
<li xml:lang="zh-TW">貼圖包 - MSC2545</li>
|
||||
<li>Location Events - MSC3488</li>
|
||||
<li xml:lang="ar">موقع الأحداث - MSC3488</li>
|
||||
<li xml:lang="ca">Esdeveniments d'ubicació - MSC3488</li>
|
||||
@@ -238,16 +203,13 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
|
||||
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
|
||||
<li xml:lang="nn">Posisjonshendingar – MSC3488</li>
|
||||
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
|
||||
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
|
||||
<li xml:lang="ru">События местоположения — MSC3488</li>
|
||||
<li xml:lang="sl">Location Events - MSC3488</li>
|
||||
<li xml:lang="sv">Location Events - MSC3488</li>
|
||||
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
||||
<li xml:lang="tr">Konum Etkinlikleri - MSC3488</li>
|
||||
<li xml:lang="uk">Місцеві зустрічі - MSC3488</li>
|
||||
<li xml:lang="x-test">xxLocation Events - MSC3488xx</li>
|
||||
<li xml:lang="zh-TW">位置事件 - MSC3488</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url type="homepage">https://apps.kde.org/neochat/</url>
|
||||
@@ -292,7 +254,6 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<developer_name xml:lang="uk">Спільнота KDE</developer_name>
|
||||
<developer_name xml:lang="x-test">xxThe KDE Communityxx</developer_name>
|
||||
<developer_name xml:lang="zh-CN">KDE 社区</developer_name>
|
||||
<developer_name xml:lang="zh-TW">KDE 社群</developer_name>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
<custom>
|
||||
@@ -303,6 +264,50 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
|
||||
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
|
||||
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
|
||||
<value key="KDE::windows_store::screenshots::1::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption">Main view with room list, chat, and room information</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="eo">Ĉefa vido kun ĉambra listo, babilejo kaj ĉambra informo</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</value>
|
||||
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
|
||||
<value key="KDE::windows_store::screenshots::2::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption">Login screen</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca">Pantalla d'inici de sessió</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca-valencia">Pantalla d'inici de sessió</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="eo">Ensaluta ekrano</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="es">Pantalla de inicio de sesión</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="eu">Saio-hasteko pantaila</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fi">Kirjautumisnäkymä</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="gl">Pantalla de identificación.</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="it">Schermata di accesso</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ko">로그인 화면</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nn">Innloggingsbilete</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="pt">Ecrã de autenticação</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sl">Prijavni zaslon</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sv">Inloggningsfönster</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ta">நுழைவுத் திரை</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="tr">Oturum açma ekranı</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="uk">Вікно входу</value>
|
||||
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>
|
||||
</custom>
|
||||
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
|
||||
<screenshots>
|
||||
@@ -312,90 +317,15 @@ to provide a convergent experience across multiple platforms.</p>
|
||||
<screenshot type="default">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/application.png</image>
|
||||
</screenshot>
|
||||
<screenshot x-kde-os="windows">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</image>
|
||||
<caption>Main view with room list, chat, and room information</caption>
|
||||
<caption xml:lang="ar">العرض الرئيسة مع قائمة الغرف والدردشات و معلومات الغرفة</caption>
|
||||
<caption xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</caption>
|
||||
<caption xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</caption>
|
||||
<caption xml:lang="eo">Ĉefa vido kun ĉambra listo, babilejo kaj ĉambra informo</caption>
|
||||
<caption xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</caption>
|
||||
<caption xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</caption>
|
||||
<caption xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</caption>
|
||||
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
||||
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
||||
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
||||
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
||||
<caption xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</caption>
|
||||
<caption xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</caption>
|
||||
<caption xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</caption>
|
||||
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
|
||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
<caption xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</caption>
|
||||
<caption xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</caption>
|
||||
<caption xml:lang="x-test">xxMain view with room list, chat, and room informationxx</caption>
|
||||
<caption xml:lang="zh-TW">主頁面,包含聊天室列表、聊天內容,與聊天室資訊</caption>
|
||||
</screenshot>
|
||||
<screenshot x-kde-os="windows">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</image>
|
||||
<caption>Login screen</caption>
|
||||
<caption xml:lang="ar">شاشة الدخول</caption>
|
||||
<caption xml:lang="ca">Pantalla d'inici de sessió</caption>
|
||||
<caption xml:lang="ca-valencia">Pantalla d'inici de sessió</caption>
|
||||
<caption xml:lang="cs">Přihlašovací obrazovka</caption>
|
||||
<caption xml:lang="eo">Ensaluta ekrano</caption>
|
||||
<caption xml:lang="es">Pantalla de inicio de sesión</caption>
|
||||
<caption xml:lang="eu">Saio-hasteko pantaila</caption>
|
||||
<caption xml:lang="fi">Kirjautumisnäkymä</caption>
|
||||
<caption xml:lang="fr">Écran de connexion</caption>
|
||||
<caption xml:lang="gl">Pantalla de identificación.</caption>
|
||||
<caption xml:lang="ia">Schermo de accesso</caption>
|
||||
<caption xml:lang="it">Schermata di accesso</caption>
|
||||
<caption xml:lang="ka">შესვლის ეკრანი</caption>
|
||||
<caption xml:lang="ko">로그인 화면</caption>
|
||||
<caption xml:lang="nl">Aanmeldscherm</caption>
|
||||
<caption xml:lang="nn">Innloggingsbilete</caption>
|
||||
<caption xml:lang="pl">Ekran logowania</caption>
|
||||
<caption xml:lang="pt">Ecrã de autenticação</caption>
|
||||
<caption xml:lang="ru">Окно входа</caption>
|
||||
<caption xml:lang="sl">Prijavni zaslon</caption>
|
||||
<caption xml:lang="sv">Inloggningsfönster</caption>
|
||||
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
||||
<caption xml:lang="tr">Oturum açma ekranı</caption>
|
||||
<caption xml:lang="uk">Вікно входу</caption>
|
||||
<caption xml:lang="x-test">xxLogin screenxx</caption>
|
||||
<caption xml:lang="zh-TW">登入畫面</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<releases>
|
||||
<release version="23.08.5" date="2024-02-15"/>
|
||||
<release version="23.08.4" date="2023-12-07"/>
|
||||
<release version="23.08.3" date="2023-11-09"/>
|
||||
<release version="23.08.2" date="2023-10-12"/>
|
||||
<release version="23.08.0" date="2023-08-24">
|
||||
<url>https://kde.org/announcements/gear/23.08.0/#neochathttpsappskdeorgneochat</url>
|
||||
<description>
|
||||
<p>Apart from a visual overhaul, NeoChat can now display location events and also a map with the location of all the users currently broadcasting their location using Itineray's Matrix integration. Great for locating where your friends are.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="23.04.3" date="2023-07-06"/>
|
||||
<release version="23.04.2" date="2023-06-08"/>
|
||||
<release version="23.04.1" date="2023-05-11"/>
|
||||
<release version="23.04.0" date="2023-04-20">
|
||||
<url>https://kde.org/announcements/gear/23.04.0/#neochathttpsappskdeorgneochat</url>
|
||||
<description>
|
||||
<p>NeoChat improves its design with tweaks that provide a more compact layout and a simpler menu which works better for the collapsed room list.</p>
|
||||
<p>We have also improved the video controls, added a new command /knock <room-id> to send a knock event to a room, and you can now edit a prior message inline, within the chat pane.</p>
|
||||
<p>Other usability improvements include an overhaul of the keyboard navigation and shortcuts like Ctrl+PgUp/PgDn that allow you to skip from room to room.</p>
|
||||
</description>
|
||||
<artifacts>
|
||||
<artifact type="binary" platform="x86_64-windows-msvc">
|
||||
<location>https://download.kde.org/stable/release-service/23.04.0/windows/neochat-23.04.0-512-windows-cl-msvc2019-x86_64.exe</location>
|
||||
|
||||
@@ -41,7 +41,6 @@ Name[tr]=NeoChat
|
||||
Name[uk]=NeoChat
|
||||
Name[x-test]=xxNeoChatxx
|
||||
Name[zh_CN]=NeoChat
|
||||
Name[zh_TW]=NeoChat
|
||||
GenericName=Matrix Client
|
||||
GenericName[ar]=عميل ماتركس
|
||||
GenericName[az]=Matrix Müştərisi
|
||||
@@ -81,7 +80,6 @@ GenericName[tr]=Matrix İstemcisi
|
||||
GenericName[uk]=Клієнт Matrix
|
||||
GenericName[x-test]=xxMatrix Clientxx
|
||||
GenericName[zh_CN]=Matrix 客户端
|
||||
GenericName[zh_TW]=Matrix 用戶端
|
||||
Comment=Client for the Matrix protocol
|
||||
Comment[ar]=عميل لميفاق ماتركس
|
||||
Comment[az]=Matrix protokolu üçün müştəri
|
||||
@@ -120,7 +118,6 @@ Comment[tr]=Matrix protokolü için istemci
|
||||
Comment[uk]=Клієнт протоколу Matrix
|
||||
Comment[x-test]=xxClient for the Matrix protocolxx
|
||||
Comment[zh_CN]=为 Matrix 协议打造的客户端
|
||||
Comment[zh_TW]=Matrix 通訊協定的用戶端
|
||||
MimeType=x-scheme-handler/matrix;
|
||||
Exec=neochat %u
|
||||
Terminal=false
|
||||
|
||||
552
po/ar/neochat.po
552
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
513
po/az/neochat.po
513
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
514
po/ca/neochat.po
514
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
522
po/cs/neochat.po
522
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
506
po/da/neochat.po
506
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
509
po/de/neochat.po
509
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
509
po/el/neochat.po
509
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
521
po/es/neochat.po
521
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
558
po/eu/neochat.po
558
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
526
po/fi/neochat.po
526
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
580
po/fr/neochat.po
580
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
518
po/hu/neochat.po
518
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
710
po/ia/neochat.po
710
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
518
po/id/neochat.po
518
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
510
po/ie/neochat.po
510
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
524
po/it/neochat.po
524
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
503
po/ja/neochat.po
503
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
516
po/ka/neochat.po
516
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
1776
po/ko/neochat.po
1776
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
503
po/lt/neochat.po
503
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
518
po/nl/neochat.po
518
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
507
po/nn/neochat.po
507
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
515
po/pa/neochat.po
515
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
759
po/pl/neochat.po
759
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
518
po/pt/neochat.po
518
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
814
po/ru/neochat.po
814
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
513
po/sk/neochat.po
513
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
520
po/sl/neochat.po
520
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
533
po/sv/neochat.po
533
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
524
po/ta/neochat.po
524
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
612
po/tr/neochat.po
612
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
514
po/uk/neochat.po
514
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
1121
po/zh_CN/neochat.po
1121
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
1987
po/zh_TW/neochat.po
1987
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
225
snapcraft.yaml
225
snapcraft.yaml
@@ -1,225 +0,0 @@
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Scarlett Moore <sgmoore@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
name: neochat
|
||||
base: core22
|
||||
adopt-info: neochat
|
||||
grade: stable
|
||||
confinement: strict
|
||||
apps:
|
||||
neochat:
|
||||
# extensions:
|
||||
# - kde-neon
|
||||
command: usr/bin/neochat
|
||||
common-id: org.kde.neochat
|
||||
desktop: usr/share/applications/org.kde.neochat.desktop
|
||||
plugs:
|
||||
- home
|
||||
- removable-media
|
||||
- desktop
|
||||
- desktop-legacy
|
||||
- opengl
|
||||
- wayland
|
||||
- x11
|
||||
- audio-playback
|
||||
- unity7
|
||||
- network
|
||||
- network-bind
|
||||
- network-manager-observe
|
||||
- password-manager-service
|
||||
- accounts-service
|
||||
command-chain:
|
||||
- snap/command-chain/desktop-launch
|
||||
assumes:
|
||||
- snapd2.58.3
|
||||
compression: lzo
|
||||
plugs:
|
||||
desktop:
|
||||
mount-host-font-cache: false
|
||||
icon-themes:
|
||||
interface: content
|
||||
target: $SNAP/data-dir/icons
|
||||
default-provider: gtk-common-themes
|
||||
sound-themes:
|
||||
interface: content
|
||||
target: $SNAP/data-dir/sounds
|
||||
default-provider: gtk-common-themes
|
||||
kf5-5-111-qt-5-15-11-core22:
|
||||
content: kf5-5-111-qt-5-15-11-core22-all
|
||||
interface: content
|
||||
default-provider: kf5-5-111-qt-5-15-11-core22
|
||||
target: $SNAP/kf5
|
||||
environment:
|
||||
SNAP_DESKTOP_RUNTIME: $SNAP/kf5
|
||||
QML2_IMPORT_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/qml:$SNAP/kf5/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/qml:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/qml"
|
||||
QT_QUICK_CONTROLS_STYLE: org.kde.desktop
|
||||
XDG_DATA_DIRS: "$SNAP/.local"
|
||||
XDG_CONFIG_DIRS: "$SNAP/etc/xdg"
|
||||
hooks:
|
||||
configure:
|
||||
plugs:
|
||||
- desktop
|
||||
command-chain:
|
||||
- snap/command-chain/hooks-configure-desktop
|
||||
layout:
|
||||
/usr/share/X11:
|
||||
symlink: $SNAP/kf5/usr/share/X11
|
||||
slots:
|
||||
session-dbus-interface:
|
||||
interface: dbus
|
||||
name: org.kde.neochat
|
||||
bus: session
|
||||
package-repositories:
|
||||
- type: apt
|
||||
components:
|
||||
- main
|
||||
suites:
|
||||
- jammy
|
||||
key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
|
||||
url: http://origin.archive.neon.kde.org/user
|
||||
key-server: keyserver.ubuntu.com
|
||||
parts:
|
||||
kde-neon:
|
||||
source: /snap/snapcraft/current/share/snapcraft/extensions/desktop/kde-neon
|
||||
source-type: local
|
||||
plugin: make
|
||||
make-parameters:
|
||||
- PLATFORM_PLUG=kf5-5-111-qt-5-15-11-core22
|
||||
build-snaps:
|
||||
- kf5-5-111-qt-5-15-11-core22-sdk
|
||||
build-environment:
|
||||
- &id001
|
||||
PATH: /snap/kf5-5-111-qt-5-15-11-core22-sdk/current/usr/bin${PATH:+:$PATH}
|
||||
- &id002
|
||||
XDG_DATA_DIRS: $CRAFT_STAGE/usr/share:/snap/kf5-5-111-qt-5-15-11-core22-sdk/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}
|
||||
- &id003
|
||||
XDG_CONFIG_HOME: $CRAFT_STAGE/etc/xdg:/snap/kf5-5-111-qt-5-15-11-core22-sdk/current/etc/xdg:/etc/xdg${XDG_CONFIG_HOME:+:$XDG_CONFIG_HOME}
|
||||
- &id004
|
||||
CRAFT_CMAKE_ARGS: -DCMAKE_FIND_ROOT_PATH=/snap/kf5-5-111-qt-5-15-11-core22-sdk/current${CRAFT_CMAKE_ARGS:+:$CRAFT_CMAKE_ARGS}
|
||||
qtkeychain:
|
||||
after:
|
||||
- kde-neon
|
||||
source: https://github.com/frankosterfeld/qtkeychain.git
|
||||
source-tag: v0.14.0
|
||||
source-depth: 0
|
||||
plugin: cmake
|
||||
build-packages:
|
||||
- libsecret-1-dev
|
||||
stage-packages:
|
||||
- libsecret-1-0
|
||||
- gnome-keyring
|
||||
cmake-parameters:
|
||||
- "-DKDE_INSTALL_USE_QT_SYS_PATHS=FALSE"
|
||||
- "-DCMAKE_INSTALL_PREFIX=/usr"
|
||||
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
||||
- "-DENABLE_TESTING=OFF"
|
||||
- "-DBUILD_TESTING=OFF"
|
||||
- "-DKDE_SKIP_TEST_SETTINGS=ON"
|
||||
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22/current"
|
||||
- "-DBUILD_TRANSLATIONS=OFF"
|
||||
- "-DLIBSECRET_SUPPORT=ON"
|
||||
- "-DKEYCHAIN_DBUS=1"
|
||||
prime:
|
||||
- "-usr/include/qt5keychain"
|
||||
- "-usr/lib/$CRAFT_ARCH_TRIPLET/libqt5keychain.so"
|
||||
- "-usr/mkspecs"
|
||||
- "-usr/lib/$CRAFT_ARCH_TRIPLET/cmake"
|
||||
libmatrixclient:
|
||||
after:
|
||||
- kde-neon
|
||||
- qtkeychain
|
||||
source: https://github.com/quotient-im/libQuotient.git
|
||||
source-tag: 0.8.1.2
|
||||
source-depth: 0
|
||||
plugin: cmake
|
||||
build-packages:
|
||||
- qtmultimedia5-dev
|
||||
- libolm-dev
|
||||
- libssl-dev
|
||||
cmake-parameters:
|
||||
- "-DCMAKE_INSTALL_PREFIX=/usr"
|
||||
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
||||
- "-DENABLE_TESTING=OFF"
|
||||
- "-DBUILD_TESTING=OFF"
|
||||
- "-DKDE_SKIP_TEST_SETTINGS=ON"
|
||||
- "-DQuotient_ENABLE_E2EE=ON"
|
||||
- "-DBUILDING_SHARED_QUOTIENT=ON"
|
||||
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22/current"
|
||||
neochat:
|
||||
after:
|
||||
- kde-neon
|
||||
- qtkeychain
|
||||
- libmatrixclient
|
||||
parse-info:
|
||||
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
||||
source: .
|
||||
source-type: local
|
||||
plugin: cmake
|
||||
build-packages:
|
||||
- cmark
|
||||
- gcc-10
|
||||
- g++-10
|
||||
- libcmark-dev
|
||||
- kquickimageeditor-dev
|
||||
- libkf5qqc2desktopstyle-dev
|
||||
- qcoro-qt5-dev
|
||||
- kirigami-addons-dev
|
||||
- reuse
|
||||
- libkf5doctools-dev
|
||||
- qtbase5-private-dev
|
||||
- qml-module-org-kde-kquickimageeditor
|
||||
- qml-module-org-kde-qqc2desktopstyle
|
||||
- kirigami-addons-data
|
||||
- qml-module-org-kde-kirigamiaddons
|
||||
- qml-module-org-kde-quickcharts
|
||||
- libsqlite3-dev
|
||||
- libolm-dev
|
||||
stage-packages:
|
||||
- libcmark0.30.2
|
||||
- qml-module-org-kde-kquickimageeditor
|
||||
- qml-module-org-kde-qqc2desktopstyle
|
||||
- kirigami-addons-data
|
||||
- qml-module-org-kde-kirigamiaddons
|
||||
- qml-module-org-kde-quickcharts
|
||||
- qml-module-org-kde-kirigami2
|
||||
- reuse
|
||||
- libsqlite3-0
|
||||
- libolm3
|
||||
cmake-parameters:
|
||||
- "-DKDE_INSTALL_USE_QT_SYS_PATHS=FALSE"
|
||||
- "-DCMAKE_INSTALL_PREFIX=/usr"
|
||||
- "-DCMAKE_BUILD_TYPE=Release"
|
||||
- "-DENABLE_TESTING=OFF"
|
||||
- "-DBUILD_TESTING=OFF"
|
||||
- "-DKDE_SKIP_TEST_SETTINGS=ON"
|
||||
- "-DNEOCHAT_FLATPAK=ON"
|
||||
- "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kf5-5-111-qt-5-15-11-core22-sdk/current"
|
||||
- "-DKDE_INSTALL_PLUGINDIR=/usr/lib/$CRAFT_ARCH_TRIPLET/qt5/plugins/"
|
||||
prime:
|
||||
- "-usr/lib/*/cmake/*"
|
||||
- "-usr/include/*"
|
||||
- "-usr/share/ECM/*"
|
||||
- "-usr/share/doc/*"
|
||||
- "-usr/share/man/*"
|
||||
- "-usr/share/icons/breeze-dark*"
|
||||
- "-usr/bin/X11"
|
||||
- "-usr/lib/gcc/$CRAFT_ARCH_TRIPLET/6.0.0"
|
||||
- "-usr/lib/aspell/*"
|
||||
- "-usr/share/lintian"
|
||||
build-environment: &id005
|
||||
- *id001
|
||||
- *id002
|
||||
- *id003
|
||||
- *id004
|
||||
cleanup:
|
||||
after:
|
||||
- kde-neon
|
||||
- neochat
|
||||
plugin: nil
|
||||
override-prime: |
|
||||
set -eux
|
||||
# find $CRAFT_PRIME/usr/share/doc/ -type f -not -name 'copyright' -delete
|
||||
# find $CRAFT_PRIME/usr/share -type d -empty -delete | /bin/true
|
||||
# # Unused libraries found by linter
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
configure_file(qml/Page/RoomList/RoomDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Page/RoomList/RoomDelegate.qml)
|
||||
configure_file(qml/Component/QuickSwitcher.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/QuickSwitcher.qml)
|
||||
configure_file(qml/Dialog/UserDetailDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/UserDetailDialog.qml)
|
||||
configure_file(qml/Dialog/PowerLevelDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/PowerLevelDialog.qml)
|
||||
configure_file(qml/Component/Timeline/AudioDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/AudioDelegate.qml)
|
||||
configure_file(qml/Component/Timeline/VideoDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/VideoDelegate.qml)
|
||||
@@ -44,8 +43,6 @@ add_library(neochat STATIC
|
||||
roommanager.h
|
||||
neochatroom.cpp
|
||||
neochatroom.h
|
||||
neochatuser.cpp
|
||||
neochatuser.h
|
||||
models/userlistmodel.cpp
|
||||
models/userlistmodel.h
|
||||
models/userfiltermodel.cpp
|
||||
@@ -127,6 +124,7 @@ add_library(neochat STATIC
|
||||
locationhelper.h
|
||||
events/pollevent.cpp
|
||||
pollhandler.cpp
|
||||
utils.h
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(neochat
|
||||
@@ -175,7 +173,7 @@ else()
|
||||
endif()
|
||||
|
||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
|
||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark QCoro::Core)
|
||||
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
||||
|
||||
if(NEOCHAT_FLATPAK)
|
||||
|
||||
@@ -35,15 +35,15 @@
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/csapi/content-repo.h>
|
||||
#include <Quotient/csapi/logout.h>
|
||||
#include <Quotient/csapi/notifications.h>
|
||||
#include <Quotient/csapi/profile.h>
|
||||
#include <Quotient/eventstats.h>
|
||||
#include <Quotient/jobs/downloadfilejob.h>
|
||||
#include <Quotient/qt_connection_util.h>
|
||||
#include <Quotient/csapi/notifications.h>
|
||||
#include <Quotient/eventstats.h>
|
||||
#include <Quotient/user.h>
|
||||
|
||||
#include "neochatconfig.h"
|
||||
#include "neochatroom.h"
|
||||
#include "neochatuser.h"
|
||||
#include "notificationsmanager.h"
|
||||
#include "roommanager.h"
|
||||
#include "windowcontroller.h"
|
||||
@@ -60,7 +60,6 @@ Controller::Controller(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
Connection::setRoomType<NeoChatRoom>();
|
||||
Connection::setUserType<NeoChatUser>();
|
||||
|
||||
setApplicationProxy();
|
||||
|
||||
@@ -532,7 +531,7 @@ void Controller::joinRoom(const QString &alias)
|
||||
RoomManager::instance().joinRoom(m_connection, alias, QStringList{knownServer});
|
||||
}
|
||||
|
||||
void Controller::openOrCreateDirectChat(NeoChatUser *user)
|
||||
void Controller::openOrCreateDirectChat(User *user)
|
||||
{
|
||||
const auto existing = activeConnection()->directChats();
|
||||
|
||||
@@ -582,11 +581,6 @@ bool Controller::hasWindowSystem() const
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Controller::encryptionSupported() const
|
||||
{
|
||||
return Quotient::encryptionSupported();
|
||||
}
|
||||
|
||||
void Controller::forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item)
|
||||
{
|
||||
// HACK: Workaround bug QTBUG 93281
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <Quotient/settings.h>
|
||||
|
||||
class NeoChatRoom;
|
||||
class NeoChatUser;
|
||||
class TrayIcon;
|
||||
class QWindow;
|
||||
class QQuickTextDocument;
|
||||
@@ -23,6 +22,7 @@ namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
class Room;
|
||||
class User;
|
||||
}
|
||||
|
||||
namespace QKeychain
|
||||
@@ -87,11 +87,6 @@ class Controller : public QObject
|
||||
*/
|
||||
Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged)
|
||||
|
||||
/**
|
||||
* @brief Whether the ecryption support has been enabled.
|
||||
*/
|
||||
Q_PROPERTY(bool encryptionSupported READ encryptionSupported CONSTANT)
|
||||
|
||||
/**
|
||||
* @brief The current minor version number of libQuotient being used.
|
||||
*
|
||||
@@ -183,7 +178,7 @@ public:
|
||||
*
|
||||
* If a direct chat with the user doesn't exist one is created and then joined.
|
||||
*/
|
||||
Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user);
|
||||
Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
|
||||
|
||||
[[nodiscard]] bool supportSystemTray() const;
|
||||
|
||||
@@ -194,8 +189,6 @@ public:
|
||||
|
||||
bool isOnline() const;
|
||||
|
||||
bool encryptionSupported() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the QNetworkProxy for the application.
|
||||
*
|
||||
|
||||
22
src/main.cpp
22
src/main.cpp
@@ -4,6 +4,7 @@
|
||||
#include <QCommandLineParser>
|
||||
#include <QIcon>
|
||||
#include <QNetworkProxyFactory>
|
||||
#include <QObject>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlNetworkAccessManagerFactory>
|
||||
@@ -28,10 +29,11 @@
|
||||
|
||||
#include "neochat-version.h"
|
||||
|
||||
#include <Quotient/keyverificationsession.h>
|
||||
#include <Quotient/accountregistry.h>
|
||||
#include <Quotient/keyverificationsession.h>
|
||||
#include <Quotient/networkaccessmanager.h>
|
||||
#include <Quotient/room.h>
|
||||
#include <Quotient/user.h>
|
||||
#include <Quotient/util.h>
|
||||
|
||||
#include "actionshandler.h"
|
||||
@@ -75,7 +77,6 @@
|
||||
#include "models/webshortcutmodel.h"
|
||||
#include "neochatconfig.h"
|
||||
#include "neochatroom.h"
|
||||
#include "neochatuser.h"
|
||||
#include "notificationsmanager.h"
|
||||
#include "pollhandler.h"
|
||||
#include "roommanager.h"
|
||||
@@ -88,7 +89,6 @@
|
||||
#endif
|
||||
#include "models/completionmodel.h"
|
||||
#include "models/statemodel.h"
|
||||
#include "neochatuser.h"
|
||||
|
||||
#ifdef HAVE_RUNNER
|
||||
#include "runner.h"
|
||||
@@ -185,10 +185,8 @@ int main(int argc, char *argv[])
|
||||
initLogging();
|
||||
|
||||
#if Quotient_VERSION_MINOR == 8
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
Connection::setEncryptionDefault(true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NEOCHAT_FLATPAK
|
||||
// Copy over the included FontConfig configuration to the
|
||||
@@ -261,24 +259,23 @@ int main(int argc, char *argv[])
|
||||
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM");
|
||||
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM");
|
||||
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
|
||||
qmlRegisterUncreatableType<NeoChatUser>("org.kde.neochat", 1, 0, "NeoChatUser", {});
|
||||
qmlRegisterUncreatableType<User>("org.kde.neochat", 1, 0, "User", {});
|
||||
qmlRegisterUncreatableType<NeoChatRoom>("org.kde.neochat", 1, 0, "NeoChatRoom", {});
|
||||
|
||||
qRegisterMetaType<User *>("User*");
|
||||
qRegisterMetaType<User *>("const User*");
|
||||
qRegisterMetaType<User *>("const Quotient::User*");
|
||||
qRegisterMetaType<RoomMember *>("RoomMember*");
|
||||
qRegisterMetaType<Room *>("Room*");
|
||||
qRegisterMetaType<Connection *>("Connection*");
|
||||
qRegisterMetaType<MessageEventType>("MessageEventType");
|
||||
qRegisterMetaType<NeoChatRoom *>("NeoChatRoom*");
|
||||
qRegisterMetaType<NeoChatUser *>("NeoChatUser*");
|
||||
qRegisterMetaType<User *>("User*");
|
||||
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
|
||||
qRegisterMetaType<QMimeType>("QMimeType");
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
qRegisterMetaType<KeyVerificationSession *>("KeyVerificationSession*");
|
||||
qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
|
||||
qRegisterMetaType<QVector<EmojiEntry>>("QVector<EmojiEntry>");
|
||||
#endif
|
||||
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
|
||||
return engine->toScriptValue(KAboutData::applicationData());
|
||||
});
|
||||
@@ -325,11 +322,18 @@ int main(int argc, char *argv[])
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
|
||||
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
|
||||
parser.addOption(QCommandLineOption("ignore-ssl-errors", i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
|
||||
|
||||
about.setupCommandLine(&parser);
|
||||
parser.process(app);
|
||||
about.processCommandLine(&parser);
|
||||
|
||||
if (parser.isSet("ignore-ssl-errors")) {
|
||||
QObject::connect(NetworkAccessManager::instance(), &QNetworkAccessManager::sslErrors, NetworkAccessManager::instance(), [](QNetworkReply *reply) {
|
||||
reply->ignoreSslErrors();
|
||||
});
|
||||
}
|
||||
|
||||
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
|
||||
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
|
||||
if (device.deviceId == m_connection->deviceId()) {
|
||||
return This;
|
||||
}
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
if (!m_connection->isKnownE2eeCapableDevice(m_connection->userId(), device.deviceId)) {
|
||||
return Unencrypted;
|
||||
}
|
||||
@@ -74,9 +73,6 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
|
||||
} else {
|
||||
return Unverified;
|
||||
}
|
||||
#else
|
||||
return Unverified;
|
||||
#endif
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -161,7 +157,6 @@ void DevicesModel::setConnection(Connection *connection)
|
||||
Q_EMIT connectionChanged();
|
||||
fetchDevices();
|
||||
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &userId, const QString &deviceId) {
|
||||
Q_UNUSED(deviceId);
|
||||
if (userId == Controller::instance().activeConnection()->userId()) {
|
||||
@@ -171,7 +166,6 @@ void DevicesModel::setConnection(Connection *connection)
|
||||
connect(m_connection, &Connection::finishedQueryingKeys, this, [this]() {
|
||||
fetchDevices();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "moc_devicesmodel.cpp"
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
bool operator<(const LiveLocationData &lhs, const LiveLocationData &rhs)
|
||||
@@ -88,6 +90,11 @@ QVariant LiveLocationsModel::data(const QModelIndex &index, int roleName) const
|
||||
const auto timeout = data.beaconInfo.value("timeout"_ls).toDouble(600000);
|
||||
return lastTs + timeout >= QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
}
|
||||
case HeadingRole: {
|
||||
bool success = false;
|
||||
const auto heading = data.beacon["org.matrix.msc3488.location"_ls].toObject()["org.kde.itinerary.heading"_ls].toString().toDouble(&success);
|
||||
return success ? heading : NAN;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -101,6 +108,7 @@ QHash<int, QByteArray> LiveLocationsModel::roleNames() const
|
||||
r.insert(AssetRole, "asset");
|
||||
r.insert(AuthorRole, "author");
|
||||
r.insert(IsLiveRole, "isLive");
|
||||
r.insert(HeadingRole, "heading");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
AssetRole, /**< Type of location event, e.g. self pin of the user location. */
|
||||
AuthorRole, /**< The author of the event. */
|
||||
IsLiveRole, /**< Boolean that indicates whether a live location beacon is still live. */
|
||||
HeadingRole, /**< Heading in degree (not part of any MSC yet, using an Itinerary extension). */
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "locationsmodel.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
LocationsModel::LocationsModel(QObject *parent)
|
||||
@@ -43,6 +45,10 @@ LocationsModel::LocationsModel(QObject *parent)
|
||||
});
|
||||
|
||||
connect(this, &LocationsModel::rowsInserted, this, &LocationsModel::boundingBoxChanged);
|
||||
|
||||
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
|
||||
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole});
|
||||
});
|
||||
}
|
||||
|
||||
void LocationsModel::addLocation(const RoomMessageEvent *event)
|
||||
@@ -61,7 +67,7 @@ void LocationsModel::addLocation(const RoomMessageEvent *event)
|
||||
.latitude = latitude,
|
||||
.longitude = longitude,
|
||||
.content = event->contentJson(),
|
||||
.author = dynamic_cast<NeoChatUser *>(m_room->user(event->senderId())),
|
||||
.author = m_room->user(event->senderId()),
|
||||
};
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include <Quotient/events/roommessageevent.h>
|
||||
#include <Quotient/user.h>
|
||||
|
||||
class LocationsModel : public QAbstractListModel
|
||||
{
|
||||
@@ -51,7 +52,7 @@ private:
|
||||
float latitude;
|
||||
float longitude;
|
||||
QJsonObject content;
|
||||
NeoChatUser *author;
|
||||
Quotient::User *author;
|
||||
};
|
||||
QList<LocationData> m_locations;
|
||||
void addLocation(const Quotient::RoomMessageEvent *event);
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include "models/reactionmodel.h"
|
||||
#include "neochatuser.h"
|
||||
#include "texthandler.h"
|
||||
|
||||
using namespace Quotient;
|
||||
@@ -78,7 +77,7 @@ MessageEventModel::MessageEventModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
|
||||
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReplyRole});
|
||||
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReplyAuthor, ReadMarkersRole});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -531,7 +530,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
|
||||
if (role == AuthorRole) {
|
||||
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
|
||||
auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
|
||||
return m_currentRoom->getUser(author);
|
||||
}
|
||||
|
||||
@@ -679,7 +678,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
auto replyPtr = m_currentRoom->getReplyForEvent(evt);
|
||||
|
||||
if (replyPtr) {
|
||||
auto replyUser = static_cast<NeoChatUser *>(m_currentRoom->user(replyPtr->senderId()));
|
||||
auto replyUser = m_currentRoom->user(replyPtr->senderId());
|
||||
return m_currentRoom->getUser(replyUser);
|
||||
} else {
|
||||
return m_currentRoom->getUser(nullptr);
|
||||
@@ -808,7 +807,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
QVariantList users;
|
||||
users.reserve(userIds.size());
|
||||
for (const auto &userId : userIds) {
|
||||
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
|
||||
auto user = m_currentRoom->user(userId);
|
||||
users += m_currentRoom->getUser(user);
|
||||
}
|
||||
|
||||
@@ -836,7 +835,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
*/
|
||||
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
|
||||
for (const auto &userId : userIds) {
|
||||
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
|
||||
auto user = m_currentRoom->user(userId);
|
||||
readMarkersString += user->displayname(m_currentRoom) + i18nc("list separator", ", ");
|
||||
}
|
||||
readMarkersString.chop(2);
|
||||
@@ -866,18 +865,16 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
|
||||
if (role == VerifiedRole) {
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
if (evt.originalEvent()) {
|
||||
auto encrypted = dynamic_cast<const EncryptedEvent *>(evt.originalEvent());
|
||||
Q_ASSERT(encrypted);
|
||||
return m_currentRoom->connection()->isVerifiedSession(encrypted->sessionId().toLatin1());
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (role == DisplayNameForInitialsRole) {
|
||||
auto user = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
|
||||
auto user = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
|
||||
return user->displayname(m_currentRoom).remove(QStringLiteral(" (%1)").arg(user->id()));
|
||||
}
|
||||
|
||||
@@ -889,7 +886,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
return previousDisplayName;
|
||||
} else {
|
||||
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
|
||||
auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
|
||||
return m_currentRoom->htmlSafeMemberName(author->id());
|
||||
}
|
||||
}
|
||||
@@ -944,12 +941,12 @@ QVariantMap MessageEventModel::getMediaInfoFromFileInfo(const EventContent::File
|
||||
QVariantMap mediaInfo;
|
||||
|
||||
// Get the mxc URL for the media.
|
||||
if (!fileInfo->url().isValid() || fileInfo->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
|
||||
if (!fileInfo->url().isValid() || eventId.isEmpty()) {
|
||||
mediaInfo["source"] = QUrl();
|
||||
} else {
|
||||
QUrl source = m_currentRoom->makeMediaUrl(eventId, fileInfo->url());
|
||||
|
||||
if (source.isValid()) {
|
||||
if (source.isValid() && source.scheme() == QStringLiteral("mxc")) {
|
||||
mediaInfo["source"] = source;
|
||||
} else {
|
||||
mediaInfo["source"] = QUrl();
|
||||
@@ -1062,13 +1059,13 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
|
||||
return;
|
||||
};
|
||||
|
||||
QMap<QString, QList<NeoChatUser *>> reactions = {};
|
||||
QMap<QString, QList<Quotient::User *>> reactions = {};
|
||||
for (const auto &a : annotations) {
|
||||
if (a->isRedacted()) { // Just in case?
|
||||
continue;
|
||||
}
|
||||
if (const auto &e = eventCast<const ReactionEvent>(a)) {
|
||||
reactions[e->key()].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId())));
|
||||
reactions[e->key()].append(m_currentRoom->user(e->senderId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1095,7 +1092,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
|
||||
if (m_reactionModels.contains(eventId)) {
|
||||
m_reactionModels[eventId]->setReactions(res);
|
||||
} else if (res.size() > 0) {
|
||||
m_reactionModels[eventId] = new ReactionModel(this, res, static_cast<NeoChatUser *>(m_currentRoom->localUser()));
|
||||
m_reactionModels[eventId] = new ReactionModel(this, res, m_currentRoom->localUser());
|
||||
} else {
|
||||
if (m_reactionModels.contains(eventId)) {
|
||||
delete m_reactionModels[eventId];
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include "neochatuser.h"
|
||||
#include <Quotient/user.h>
|
||||
|
||||
ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, NeoChatUser *localUser)
|
||||
ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, Quotient::User *localUser)
|
||||
: QAbstractListModel(parent)
|
||||
, m_localUser(localUser)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
class NeoChatUser;
|
||||
namespace Quotient
|
||||
{
|
||||
class User;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class ReactionModel
|
||||
@@ -36,7 +39,7 @@ public:
|
||||
HasLocalUser, /**< Whether the local user is in the list of authors. */
|
||||
};
|
||||
|
||||
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, NeoChatUser *localUser = nullptr);
|
||||
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, Quotient::User *localUser = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
@@ -67,6 +70,6 @@ public:
|
||||
private:
|
||||
QList<Reaction> m_reactions;
|
||||
|
||||
NeoChatUser *m_localUser;
|
||||
Quotient::User *m_localUser;
|
||||
};
|
||||
Q_DECLARE_METATYPE(ReactionModel *)
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
|
||||
#include "messageeventmodel.h"
|
||||
#include "neochatroom.h"
|
||||
#include "neochatuser.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/stickerevent.h>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
// TODO search only in the current room
|
||||
@@ -19,6 +20,9 @@ using namespace Quotient;
|
||||
SearchModel::SearchModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this] {
|
||||
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReadMarkersRole});
|
||||
});
|
||||
}
|
||||
|
||||
QString SearchModel::searchText() const
|
||||
@@ -109,7 +113,7 @@ QVariant SearchModel::data(const QModelIndex &index, int role) const
|
||||
return false;
|
||||
case ReplyAuthorRole:
|
||||
if (const auto &replyPtr = m_room->getReplyForEvent(event)) {
|
||||
return m_room->getUser(static_cast<NeoChatUser *>(m_room->user(replyPtr->senderId())));
|
||||
return m_room->getUser(m_room->user(replyPtr->senderId()));
|
||||
} else {
|
||||
return m_room->getUser(nullptr);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ void StickerModel::setRoom(NeoChatRoom *room)
|
||||
void StickerModel::postSticker(int index)
|
||||
{
|
||||
const auto &image = m_images[index];
|
||||
const auto &body = image.body ? *image.body : image.shortcode;
|
||||
const auto &body = image.body ? *image.body : QString();
|
||||
QJsonObject infoJson;
|
||||
if (image.info) {
|
||||
infoJson["w"] = image.info->imageSize.width();
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "userlistmodel.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/roompowerlevelsevent.h>
|
||||
|
||||
@@ -14,6 +16,9 @@ UserListModel::UserListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_currentRoom(nullptr)
|
||||
{
|
||||
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, [this]() {
|
||||
refreshAllUsers();
|
||||
});
|
||||
}
|
||||
|
||||
void UserListModel::setRoom(NeoChatRoom *room)
|
||||
@@ -28,11 +33,9 @@ void UserListModel::setRoom(NeoChatRoom *room)
|
||||
m_currentRoom = room;
|
||||
|
||||
if (m_currentRoom) {
|
||||
connect(m_currentRoom, &Room::userAdded, this, &UserListModel::userAdded);
|
||||
connect(m_currentRoom, &Room::userRemoved, this, &UserListModel::userRemoved);
|
||||
connect(m_currentRoom, &Room::memberAboutToRename, this, &UserListModel::userRemoved);
|
||||
connect(m_currentRoom, &Room::memberRenamed, this, &UserListModel::userAdded);
|
||||
connect(m_currentRoom, &Room::changed, this, &UserListModel::refreshAllUsers);
|
||||
connect(m_currentRoom, &Room::memberAdded, this, &UserListModel::memberAdded);
|
||||
connect(m_currentRoom, &Room::memberRemoved, this, &UserListModel::memberRemoved);
|
||||
connect(m_currentRoom, &Room::memberUpdated, this, &UserListModel::memberUpdated);
|
||||
}
|
||||
|
||||
refreshAllUsers();
|
||||
@@ -44,38 +47,29 @@ NeoChatRoom *UserListModel::room() const
|
||||
return m_currentRoom;
|
||||
}
|
||||
|
||||
Quotient::User *UserListModel::userAt(QModelIndex index) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= m_users.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_users.at(index.row());
|
||||
}
|
||||
|
||||
QVariant UserListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (index.row() >= m_users.count()) {
|
||||
if (index.row() >= rowCount()) {
|
||||
qDebug() << "UserListModel, something's wrong: index.row() >= "
|
||||
"users.count()";
|
||||
return {};
|
||||
}
|
||||
auto user = m_users.at(index.row());
|
||||
auto user = m_members.at(index.row());
|
||||
if (role == DisplayNameRole) {
|
||||
return user->displayname(m_currentRoom);
|
||||
return user->displayName();
|
||||
}
|
||||
if (role == UserIdRole) {
|
||||
return user->id();
|
||||
}
|
||||
if (role == AvatarRole) {
|
||||
auto neoChatUser = static_cast<NeoChatUser *>(user);
|
||||
return m_currentRoom->avatarForMember(neoChatUser);
|
||||
return user->avatarUrl();
|
||||
}
|
||||
if (role == ObjectRole) {
|
||||
return QVariant::fromValue(user);
|
||||
return QVariant::fromValue<RoomMember *>(user.get());
|
||||
}
|
||||
if (role == PowerLevelRole) {
|
||||
auto plEvent = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
|
||||
@@ -114,59 +108,47 @@ int UserListModel::rowCount(const QModelIndex &parent) const
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return m_users.count();
|
||||
return m_members.count();
|
||||
}
|
||||
|
||||
void UserListModel::userAdded(Quotient::User *user)
|
||||
void UserListModel::memberAdded(QString memberId)
|
||||
{
|
||||
auto pos = findUserPos(user);
|
||||
beginInsertRows(QModelIndex(), pos, pos);
|
||||
m_users.insert(pos, user);
|
||||
if (m_currentRoom->memberIds().contains(memberId)) {
|
||||
return;
|
||||
}
|
||||
beginInsertRows(QModelIndex(), m_currentRoom->memberIds().size(), m_currentRoom->memberIds().size());
|
||||
endInsertRows();
|
||||
connect(user, &User::defaultAvatarChanged, this, [this, user]() {
|
||||
refreshUser(user, {AvatarRole});
|
||||
});
|
||||
}
|
||||
|
||||
void UserListModel::userRemoved(Quotient::User *user)
|
||||
void UserListModel::memberUpdated(QString memberId)
|
||||
{
|
||||
auto pos = findUserPos(user);
|
||||
if (pos != m_users.size()) {
|
||||
beginRemoveRows(QModelIndex(), pos, pos);
|
||||
m_users.removeAt(pos);
|
||||
endRemoveRows();
|
||||
user->disconnect(this);
|
||||
} else {
|
||||
qWarning() << "Trying to remove a room member not in the user list";
|
||||
if (!m_currentRoom->memberIds().contains(memberId)) {
|
||||
return;
|
||||
}
|
||||
auto row = m_currentRoom->memberIds().indexOf(memberId);
|
||||
if (row >= 0 && row < m_currentRoom->memberIds().size()) {
|
||||
Q_EMIT dataChanged(index(row), index(row));
|
||||
}
|
||||
}
|
||||
|
||||
void UserListModel::refreshUser(Quotient::User *user, const QVector<int> &roles)
|
||||
void UserListModel::memberRemoved(QString memberId)
|
||||
{
|
||||
auto pos = findUserPos(user);
|
||||
if (pos != m_users.size()) {
|
||||
Q_EMIT dataChanged(index(pos), index(pos), roles);
|
||||
} else {
|
||||
qWarning() << "Trying to access a room member not in the user list";
|
||||
if (!m_currentRoom->memberIds().contains(memberId)) {
|
||||
return;
|
||||
}
|
||||
auto row = m_currentRoom->memberIds().indexOf(memberId);
|
||||
if (row >= 0 && row < m_currentRoom->memberIds().size()) {
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
void UserListModel::refreshAllUsers()
|
||||
{
|
||||
beginResetModel();
|
||||
for (User *user : std::as_const(m_users)) {
|
||||
user->disconnect(this);
|
||||
}
|
||||
m_users.clear();
|
||||
m_members.clear();
|
||||
m_members = m_currentRoom->members();
|
||||
|
||||
m_users = m_currentRoom->users();
|
||||
std::sort(m_users.begin(), m_users.end(), m_currentRoom->memberSorter());
|
||||
|
||||
for (User *user : std::as_const(m_users)) {
|
||||
connect(user, &User::defaultAvatarChanged, this, [this, user]() {
|
||||
refreshUser(user, {AvatarRole});
|
||||
});
|
||||
}
|
||||
connect(m_currentRoom->connection(), &Connection::loggedOut, this, [this]() {
|
||||
setRoom(nullptr);
|
||||
});
|
||||
@@ -174,19 +156,6 @@ void UserListModel::refreshAllUsers()
|
||||
Q_EMIT usersRefreshed();
|
||||
}
|
||||
|
||||
int UserListModel::findUserPos(Quotient::User *user) const
|
||||
{
|
||||
return findUserPos(m_currentRoom->safeMemberName(user->id()));
|
||||
}
|
||||
|
||||
int UserListModel::findUserPos(const QString &username) const
|
||||
{
|
||||
if (!m_currentRoom) {
|
||||
return 0;
|
||||
}
|
||||
return m_currentRoom->memberSorter().lowerBoundIndex(m_users, username);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> UserListModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
@@ -54,11 +54,6 @@ public:
|
||||
[[nodiscard]] NeoChatRoom *room() const;
|
||||
void setRoom(NeoChatRoom *room);
|
||||
|
||||
/**
|
||||
* @brief The user at the given index of the model.
|
||||
*/
|
||||
[[nodiscard]] Quotient::User *userAt(QModelIndex index) const;
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
*
|
||||
@@ -85,15 +80,12 @@ Q_SIGNALS:
|
||||
void usersRefreshed();
|
||||
|
||||
private Q_SLOTS:
|
||||
void userAdded(Quotient::User *user);
|
||||
void userRemoved(Quotient::User *user);
|
||||
void refreshUser(Quotient::User *user, const QVector<int> &roles = {});
|
||||
void memberAdded(QString memberId);
|
||||
void memberUpdated(QString memberId);
|
||||
void memberRemoved(QString memberId);
|
||||
void refreshAllUsers();
|
||||
|
||||
private:
|
||||
QPointer<NeoChatRoom> m_currentRoom;
|
||||
QList<Quotient::User *> m_users;
|
||||
|
||||
int findUserPos(Quotient::User *user) const;
|
||||
[[nodiscard]] int findUserPos(const QString &username) const;
|
||||
QList<QSharedPointer<Quotient::RoomMember>> m_members;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,6 @@ Name[tr]=NeoChat
|
||||
Name[uk]=NeoChat
|
||||
Name[x-test]=xxNeoChatxx
|
||||
Name[zh_CN]=NeoChat
|
||||
Name[zh_TW]=NeoChat
|
||||
DesktopEntry=org.kde.neochat
|
||||
Comment=A client for matrix, the decentralized communication protocol
|
||||
Comment[ar]=عميل لماتركس، ميفاق الاتصال اللامركزي
|
||||
@@ -79,7 +78,6 @@ Comment[tr]=Merkezi olmayan iletişim protokolü Matrix için bir istemci
|
||||
Comment[uk]=Клієнт matrix, децентралізованого протоколу обміну даними
|
||||
Comment[x-test]=xxA client for matrix, the decentralized communication protocolxx
|
||||
Comment[zh_CN]=分布式通讯协议 Matrix 的客户端
|
||||
Comment[zh_TW]=去中心化通訊協定 Matrix 的用戶端
|
||||
|
||||
|
||||
[Event/message]
|
||||
@@ -118,11 +116,10 @@ Name[sk]=Nová správa
|
||||
Name[sl]=Novo sporočilo
|
||||
Name[sv]=Nytt meddelande
|
||||
Name[ta]=புதிய செய்தி
|
||||
Name[tr]=Yeni İleti
|
||||
Name[tr]=Yeni ileti
|
||||
Name[uk]=Нове повідомлення
|
||||
Name[x-test]=xxNew messagexx
|
||||
Name[zh_CN]=新消息
|
||||
Name[zh_TW]=新訊息
|
||||
Comment=There is a new message
|
||||
Comment[ar]=توجد رسالة جديدة
|
||||
Comment[az]=Yeni ismarıc var
|
||||
@@ -161,7 +158,6 @@ Comment[tr]=Yeni bir ileti var
|
||||
Comment[uk]=Надійшло нове повідомлення
|
||||
Comment[x-test]=xxThere is a new messagexx
|
||||
Comment[zh_CN]=有新消息
|
||||
Comment[zh_TW]=有新的訊息
|
||||
Action=Popup
|
||||
|
||||
[Event/invite]
|
||||
@@ -199,8 +195,6 @@ Name[ta]=புதிய அழைப்பிதழ்
|
||||
Name[tr]=Yeni Davet
|
||||
Name[uk]=Нове запрошення
|
||||
Name[x-test]=xxNew Invitationxx
|
||||
Name[zh_CN]=新邀请
|
||||
Name[zh_TW]=新邀請
|
||||
Comment=There is a new invitation to a room
|
||||
Comment[ar]=توجد دعوة جديدة
|
||||
Comment[az]=Otağa bir yeni dəvət var
|
||||
@@ -235,6 +229,4 @@ Comment[ta]=ஓர் அரங்கிற்கான புதிய அழ
|
||||
Comment[tr]=Bir odaya yeni bir davetiye var
|
||||
Comment[uk]=У кімнаті нове запрошення
|
||||
Comment[x-test]=xxThere is a new invitation to a roomxx
|
||||
Comment[zh_CN]=有新的聊天室邀请
|
||||
Comment[zh_TW]=有新的加入聊天室邀請
|
||||
Action=Popup
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QGuiApplication>
|
||||
#include <QMetaObject>
|
||||
#include <QMimeDatabase>
|
||||
#include <QPalette>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextDocument>
|
||||
|
||||
@@ -13,6 +15,7 @@
|
||||
#include <QMediaPlayer>
|
||||
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
#include <Quotient/user.h>
|
||||
#include <qcoro/qcorosignal.h>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
@@ -43,6 +46,7 @@
|
||||
#include "neochatconfig.h"
|
||||
#include "notificationsmanager.h"
|
||||
#include "texthandler.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
@@ -412,11 +416,11 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const
|
||||
int count = 0;
|
||||
for (const auto u : userList) {
|
||||
if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) {
|
||||
NeoChatUser user(u->id(), u->connection());
|
||||
Quotient::User user(u->id(), u->connection());
|
||||
QVariantMap userVariant{{QStringLiteral("id"), user.id()},
|
||||
{QStringLiteral("displayName"), user.displayname(this)},
|
||||
{QStringLiteral("avatarMediaId"), user.avatarMediaId(this)},
|
||||
{QStringLiteral("color"), user.color()}};
|
||||
{QStringLiteral("color"), Utils::getUserColor(user.hueF())}};
|
||||
|
||||
matchedList.append(QVariant::fromValue(userVariant));
|
||||
count++;
|
||||
@@ -442,11 +446,10 @@ static const QVariantMap emptyUser = {
|
||||
|
||||
QVariantMap NeoChatRoom::getUser(const QString &userID) const
|
||||
{
|
||||
NeoChatUser *userObject = static_cast<NeoChatUser *>(user(userID));
|
||||
return getUser(userObject);
|
||||
return getUser(user(userID));
|
||||
}
|
||||
|
||||
QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const
|
||||
QVariantMap NeoChatRoom::getUser(User *user) const
|
||||
{
|
||||
if (user == nullptr) {
|
||||
return emptyUser;
|
||||
@@ -458,7 +461,7 @@ QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const
|
||||
{QStringLiteral("displayName"), user->displayname(this)},
|
||||
{QStringLiteral("avatarSource"), avatarForMember(user)},
|
||||
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)},
|
||||
{QStringLiteral("color"), user->color()},
|
||||
{QStringLiteral("color"), Utils::getUserColor(user->hueF())},
|
||||
{QStringLiteral("object"), QVariant::fromValue(user)},
|
||||
};
|
||||
}
|
||||
@@ -539,7 +542,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
|
||||
if (prettyPrint) {
|
||||
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
|
||||
.arg(e.userId(), static_cast<NeoChatUser *>(user(e.userId()))->color().name(), subjectName);
|
||||
.arg(e.userId(), Utils::getUserColor(user(e.userId())->hueF()).name(), subjectName);
|
||||
}
|
||||
|
||||
// The below code assumes senderName output in AuthorRole
|
||||
@@ -1682,7 +1685,7 @@ QVariantMap NeoChatRoom::chatBoxReplyUser() const
|
||||
if (m_chatBoxReplyId.isEmpty()) {
|
||||
return emptyUser;
|
||||
}
|
||||
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxReplyId))->senderId())));
|
||||
return getUser(user((*findInTimeline(m_chatBoxReplyId))->senderId()));
|
||||
}
|
||||
|
||||
QString NeoChatRoom::chatBoxReplyMessage() const
|
||||
@@ -1698,7 +1701,7 @@ QVariantMap NeoChatRoom::chatBoxEditUser() const
|
||||
if (m_chatBoxEditId.isEmpty()) {
|
||||
return emptyUser;
|
||||
}
|
||||
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxEditId))->senderId())));
|
||||
return getUser(user((*findInTimeline(m_chatBoxEditId))->senderId()));
|
||||
}
|
||||
|
||||
QString NeoChatRoom::chatBoxEditMessage() const
|
||||
@@ -1809,10 +1812,7 @@ void NeoChatRoom::editLastMessage()
|
||||
|
||||
bool NeoChatRoom::canEncryptRoom() const
|
||||
{
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
return !usesEncryption() && canSendState("m.room.encryption");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
PollHandler *NeoChatRoom::poll(const QString &eventId)
|
||||
@@ -1904,9 +1904,10 @@ int NeoChatRoom::maxRoomVersion() const
|
||||
}
|
||||
return maxVersion;
|
||||
}
|
||||
NeoChatUser *NeoChatRoom::directChatRemoteUser() const
|
||||
|
||||
Quotient::User *NeoChatRoom::directChatRemoteUser() const
|
||||
{
|
||||
return dynamic_cast<NeoChatUser *>(connection()->directChatUsers(this)[0]);
|
||||
return connection()->directChatUsers(this)[0];
|
||||
}
|
||||
|
||||
void NeoChatRoom::sendLocation(float lat, float lon, const QString &description)
|
||||
@@ -1938,7 +1939,7 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
|
||||
return QJsonDocument(accountData(eventType)->fullJson()).toJson();
|
||||
}
|
||||
|
||||
QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const
|
||||
QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const
|
||||
{
|
||||
const auto &url = memberAvatarUrl(user->id());
|
||||
if (url.isEmpty() || url.scheme() != "mxc"_ls) {
|
||||
|
||||
@@ -10,10 +10,15 @@
|
||||
#include <QTextCursor>
|
||||
|
||||
#include <QCoroTask>
|
||||
#include <Quotient/user.h>
|
||||
|
||||
#include "neochatuser.h"
|
||||
#include "pollhandler.h"
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class User;
|
||||
}
|
||||
|
||||
class PushNotificationState : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -64,7 +69,7 @@ class NeoChatRoom : public Quotient::Room
|
||||
*
|
||||
* The list does not include the local user.
|
||||
*
|
||||
* This is different to getting a list of NeoChatUser objects or Quotient::User objects
|
||||
* This is different to getting a list of Quotient::User objects
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room. This function
|
||||
* provides the room context and puts the result as a list of QVariantMap objects.
|
||||
@@ -76,7 +81,7 @@ class NeoChatRoom : public Quotient::Room
|
||||
* - displayName - Display name in the context of this room.
|
||||
* - display - Name in the context of this room.
|
||||
*
|
||||
* @sa Quotient::User, NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged)
|
||||
|
||||
@@ -119,7 +124,7 @@ class NeoChatRoom : public Quotient::Room
|
||||
/**
|
||||
* @brief Get a user object for the other person in a direct chat.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatUser *directChatRemoteUser READ directChatRemoteUser CONSTANT)
|
||||
Q_PROPERTY(Quotient::User *directChatRemoteUser READ directChatRemoteUser CONSTANT)
|
||||
|
||||
/**
|
||||
* @brief If the room is a space.
|
||||
@@ -181,9 +186,6 @@ class NeoChatRoom : public Quotient::Room
|
||||
/**
|
||||
* @brief Whether the local user can encrypt the room.
|
||||
*
|
||||
* Requires libQuotient 0.7 compiled with the Quotient_E2EE_ENABLED parameter to
|
||||
* be able to return true.
|
||||
*
|
||||
* A local user can encrypt a room if they have permission to send the m.room.encryption
|
||||
* state event.
|
||||
*
|
||||
@@ -316,7 +318,7 @@ class NeoChatRoom : public Quotient::Room
|
||||
/**
|
||||
* @brief Get the user for the message being replied to.
|
||||
*
|
||||
* This is different to getting a NeoChatUser object or Quotient::User object
|
||||
* This is different to getting a Quotient::User object
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room.
|
||||
*
|
||||
@@ -329,9 +331,9 @@ class NeoChatRoom : public Quotient::Room
|
||||
* - avatarSource - The mxc URL for the user's avatar in the current room.
|
||||
* - avatarMediaId - Avatar id in the context of this room.
|
||||
* - color - Color for the user.
|
||||
* - object - The NeoChatUser object for the user.
|
||||
* - object - The Quotient::User object for the user.
|
||||
*
|
||||
* @sa getUser, Quotient::User, NeoChatUser
|
||||
* @sa getUser, Quotient::User
|
||||
*/
|
||||
Q_PROPERTY(QVariantMap chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged)
|
||||
|
||||
@@ -345,7 +347,7 @@ class NeoChatRoom : public Quotient::Room
|
||||
/**
|
||||
* @brief Get the user for the message being edited.
|
||||
*
|
||||
* This is different to getting a NeoChatUser object or Quotient::User object
|
||||
* This is different to getting a Quotient::User object
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room.
|
||||
*
|
||||
@@ -358,9 +360,9 @@ class NeoChatRoom : public Quotient::Room
|
||||
* - avatarSource - The mxc URL for the user's avatar in the current room.
|
||||
* - avatarMediaId - Avatar id in the context of this room.
|
||||
* - color - Color for the user.
|
||||
* - object - The NeoChatUser object for the user.
|
||||
* - object - The Quotient::User object for the user.
|
||||
*
|
||||
* @sa getUser, Quotient::User, NeoChatUser
|
||||
* @sa getUser, Quotient::User
|
||||
*/
|
||||
Q_PROPERTY(QVariantMap chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged)
|
||||
|
||||
@@ -392,7 +394,7 @@ public:
|
||||
/**
|
||||
* @brief Get a list of users in the context of this room.
|
||||
*
|
||||
* This is different to getting a list of NeoChatUser objects or Quotient::User objects
|
||||
* This is different to getting a list of Quotient::User objects
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room. This function
|
||||
* provides the room context and returns the result as a list of QVariantMap objects.
|
||||
@@ -407,14 +409,14 @@ public:
|
||||
* - avatarMediaId - Avatar id in the context of this room.
|
||||
* - color - Color for the user.
|
||||
*
|
||||
* @sa Quotient::User, NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword, int limit = -1) const;
|
||||
|
||||
/**
|
||||
* @brief Get a user in the context of this room.
|
||||
*
|
||||
* This is different to getting a NeoChatUser object or Quotient::User object
|
||||
* This is different to getting a Quotient::User object
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room. This function
|
||||
* provides the room context and outputs the result as QVariantMap.
|
||||
@@ -431,16 +433,16 @@ public:
|
||||
* - avatarSource - The mxc URL for the user's avatar in the current room.
|
||||
* - avatarMediaId - Avatar id in the context of this room.
|
||||
* - color - Color for the user.
|
||||
* - object - The NeoChatUser object for the user.
|
||||
* - object - The Quotient::User object for the user.
|
||||
*
|
||||
* @sa Quotient::User, NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const;
|
||||
|
||||
/**
|
||||
* @brief Get a user in the context of this room.
|
||||
*
|
||||
* This is different to getting a NeoChatUser object or Quotient::User object
|
||||
* This is different to getting a Quotient::User object
|
||||
* as neither of those can provide details like the displayName or avatarMediaId
|
||||
* without the room context as these can vary from room to room. This function
|
||||
* provides the room context and outputs the result as QVariantMap.
|
||||
@@ -457,11 +459,11 @@ public:
|
||||
* - avatarSource - The mxc URL for the user's avatar in the current room.
|
||||
* - avatarMediaId - Avatar id in the context of this room.
|
||||
* - color - Color for the user.
|
||||
* - object - The NeoChatUser object for the user.
|
||||
* - object - The Quotient::User object for the user.
|
||||
*
|
||||
* @sa Quotient::User, NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(NeoChatUser *user) const;
|
||||
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(Quotient::User *user) const;
|
||||
|
||||
[[nodiscard]] QVariantList getUsersTyping() const;
|
||||
|
||||
@@ -602,7 +604,7 @@ public:
|
||||
|
||||
[[nodiscard]] QString avatarMediaId() const;
|
||||
|
||||
NeoChatUser *directChatRemoteUser() const;
|
||||
Quotient::User *directChatRemoteUser() const;
|
||||
|
||||
[[nodiscard]] bool isSpace();
|
||||
|
||||
@@ -818,7 +820,7 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE QByteArray roomAcountDataJson(const QString &eventType);
|
||||
|
||||
Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(NeoChatUser *user) const;
|
||||
Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(Quotient::User *user) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply.
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include "neochatuser.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QJsonObject>
|
||||
#include <QPalette>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
NeoChatUser::NeoChatUser(QString userId, Connection *connection)
|
||||
: User(std::move(userId), connection)
|
||||
{
|
||||
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, &NeoChatUser::polishColor);
|
||||
polishColor();
|
||||
}
|
||||
|
||||
QColor NeoChatUser::color()
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void NeoChatUser::setColor(const QColor &color)
|
||||
{
|
||||
if (m_color == color) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_color = color;
|
||||
Q_EMIT colorChanged(m_color);
|
||||
}
|
||||
|
||||
void NeoChatUser::polishColor()
|
||||
{
|
||||
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
|
||||
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
|
||||
setColor(QColor::fromHslF(hueF(), 1, -0.7 * lightness + 0.9, 1));
|
||||
}
|
||||
|
||||
#include "moc_neochatuser.cpp"
|
||||
@@ -1,39 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <Quotient/user.h>
|
||||
|
||||
/**
|
||||
* @class NeoChatUser
|
||||
*
|
||||
* A class inherited from Quotient::User to add a user color function.
|
||||
*
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
class NeoChatUser : public Quotient::User
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* @brief The color to use for the user.
|
||||
*/
|
||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
||||
public:
|
||||
explicit NeoChatUser(QString userId, Quotient::Connection *connection);
|
||||
|
||||
public Q_SLOTS:
|
||||
QColor color();
|
||||
void setColor(const QColor &color);
|
||||
|
||||
Q_SIGNALS:
|
||||
void colorChanged(QColor _t1);
|
||||
|
||||
private:
|
||||
QColor m_color;
|
||||
|
||||
void polishColor();
|
||||
};
|
||||
@@ -122,10 +122,8 @@ void NotificationsManager::processNotificationJob(QPointer<Quotient::Connection>
|
||||
}
|
||||
|
||||
if (notification["event"]["type"] == "m.room.encrypted") {
|
||||
#ifdef Quotient_E2EE_ENABLED
|
||||
auto decrypted = connection->decryptNotification(notification);
|
||||
body = decrypted["content"].toObject()["body"].toString();
|
||||
#endif
|
||||
if (body.isEmpty()) {
|
||||
body = i18n("Encrypted Message");
|
||||
}
|
||||
@@ -293,12 +291,7 @@ QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoCha
|
||||
roundedImage.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&roundedImage);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.setPen(Qt::NoPen);
|
||||
|
||||
// Fill background for transparent avatars
|
||||
painter.setBrush(Qt::white);
|
||||
painter.drawRoundedRect(imageRect, imageRect.width(), imageRect.height());
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QBrush brush(icon.scaledToHeight(biggestDimension));
|
||||
painter.setBrush(brush);
|
||||
@@ -309,9 +302,6 @@ QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoCha
|
||||
if (icon != roomAvatar) {
|
||||
const QRect lowerQuarter{imageRect.center(), imageRect.size() / 2};
|
||||
|
||||
painter.setBrush(Qt::white);
|
||||
painter.drawRoundedRect(lowerQuarter, lowerQuarter.width(), lowerQuarter.height());
|
||||
|
||||
painter.setBrush(roomAvatar.scaled(lowerQuarter.size()));
|
||||
painter.drawRoundedRect(lowerQuarter, lowerQuarter.width(), lowerQuarter.height());
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ Name[tr]=NeoChat
|
||||
Name[uk]=NeoChat
|
||||
Name[x-test]=xxNeoChatxx
|
||||
Name[zh_CN]=NeoChat
|
||||
Name[zh_TW]=NeoChat
|
||||
Comment=Find rooms in NeoChat
|
||||
Comment[ar]=اعثر على غرف في نيوتشات
|
||||
Comment[az]=NeoChat-da otaqları tapın
|
||||
@@ -73,8 +72,6 @@ Comment[ta]=நியோச்சாட்டில் அரங்குகள
|
||||
Comment[tr]=NeoChat'te odalar bulun
|
||||
Comment[uk]=Пошук кімнат у NeoChat
|
||||
Comment[x-test]=xxFind rooms in NeoChatxx
|
||||
Comment[zh_CN]=在 NeoChat 查找聊天室
|
||||
Comment[zh_TW]=在 NeoChat 尋找聊天室
|
||||
X-KDE-ServiceTypes=Plasma/Runner
|
||||
Type=Service
|
||||
Icon=org.kde.neochat
|
||||
|
||||
@@ -28,8 +28,6 @@ Delegates.RoundedItemDelegate {
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
acceptedDevices: PointerDevice.Mouse
|
||||
grabPermissions: PointerHandler.TakeOverForbidden
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
onTapped: root.contextMenuRequested()
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ QQC2.Control {
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
required property NeoChatRoom currentRoom
|
||||
|
||||
/**
|
||||
* @brief The QQC2.TextArea object.
|
||||
@@ -55,10 +55,10 @@ QQC2.Control {
|
||||
Kirigami.Action {
|
||||
id: attachmentAction
|
||||
|
||||
property bool isBusy: currentRoom && currentRoom.hasFileUploading
|
||||
property bool isBusy: root.currentRoom && root.currentRoom.hasFileUploading
|
||||
|
||||
// Matrix does not allow sending attachments in replies
|
||||
visible: currentRoom.chatBoxReplyId.length === 0 && currentRoom.chatBoxAttachmentPath.length === 0
|
||||
visible: root.currentRoom.chatBoxReplyId.length === 0 && root.currentRoom.chatBoxAttachmentPath.length === 0
|
||||
icon.name: "mail-attachment"
|
||||
text: i18n("Attach an image or file")
|
||||
displayHint: Kirigami.DisplayHint.IconOnly
|
||||
@@ -72,7 +72,7 @@ QQC2.Control {
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
currentRoom.chatBoxAttachmentPath = path;
|
||||
root.currentRoom.chatBoxAttachmentPath = path;
|
||||
})
|
||||
fileDialog.open()
|
||||
}
|
||||
@@ -85,19 +85,19 @@ QQC2.Control {
|
||||
|
||||
property bool isBusy: false
|
||||
|
||||
visible: !Kirigami.Settings.isMobile
|
||||
icon.name: "smiley"
|
||||
text: i18n("Emojis & Stickers")
|
||||
displayHint: Kirigami.DisplayHint.IconOnly
|
||||
checkable: true
|
||||
|
||||
onTriggered: {
|
||||
if (emojiDialog.visible) {
|
||||
emojiDialog.close()
|
||||
if (emojiDialog.item.visible) {
|
||||
emojiDialog.item.close()
|
||||
} else {
|
||||
emojiDialog.open()
|
||||
emojiDialog.item.open()
|
||||
}
|
||||
}
|
||||
tooltip: text
|
||||
},
|
||||
Kirigami.Action {
|
||||
id: mapButton
|
||||
@@ -107,9 +107,8 @@ QQC2.Control {
|
||||
displayHint: QQC2.AbstractButton.IconOnly
|
||||
|
||||
onTriggered: {
|
||||
locationChooserComponent.createObject(QQC2.ApplicationWindow.overlay, {room: currentRoom}).open()
|
||||
locationChooserComponent.createObject(QQC2.ApplicationWindow.overlay, {room: root.currentRoom}).open()
|
||||
}
|
||||
tooltip: text
|
||||
},
|
||||
Kirigami.Action {
|
||||
id: sendAction
|
||||
@@ -164,10 +163,11 @@ QQC2.Control {
|
||||
leftPadding: LayoutMirroring.enabled ? actionsRow.width : Kirigami.Units.largeSpacing
|
||||
rightPadding: LayoutMirroring.enabled ? Kirigami.Units.largeSpacing : actionsRow.width + x * 2 + Kirigami.Units.largeSpacing * 2
|
||||
|
||||
placeholderText: readOnly ? i18n("This room is encrypted. Build libQuotient with encryption enabled to send encrypted messages.") : currentRoom.usesEncryption ? i18n("Send an encrypted message…") : currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
|
||||
placeholderText: root.currentRoom.usesEncryption ? i18n("Send an encrypted message…") : root.currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
readOnly: (currentRoom.usesEncryption && !Controller.encryptionSupported)
|
||||
|
||||
Accessible.description: placeholderText
|
||||
|
||||
Timer {
|
||||
id: repeatTimer
|
||||
@@ -177,10 +177,10 @@ QQC2.Control {
|
||||
onTextChanged: {
|
||||
if (!repeatTimer.running && Config.typingNotifications) {
|
||||
var textExists = text.length > 0
|
||||
currentRoom.sendTypingNotification(textExists)
|
||||
root.currentRoom.sendTypingNotification(textExists)
|
||||
textExists ? repeatTimer.start() : repeatTimer.stop()
|
||||
}
|
||||
currentRoom.chatBoxText = text
|
||||
root.currentRoom.chatBoxText = text
|
||||
}
|
||||
onCursorRectangleChanged: chatBarScrollView.ensureVisible(cursorRectangle)
|
||||
onSelectedTextChanged: {
|
||||
@@ -207,7 +207,7 @@ QQC2.Control {
|
||||
remove(cursorPosition, cursorPosition + 1)
|
||||
}
|
||||
if (textField.text == selectedText || textField.text.length <= 1) {
|
||||
currentRoom.sendTypingNotification(false)
|
||||
root.currentRoom.sendTypingNotification(false)
|
||||
repeatTimer.stop()
|
||||
}
|
||||
if (quickFormatBar.visible) {
|
||||
@@ -237,20 +237,20 @@ QQC2.Control {
|
||||
completionMenu.complete()
|
||||
}
|
||||
}
|
||||
Keys.onPressed: (event) => {
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_V && event.modifiers & Qt.ControlModifier) {
|
||||
event.accepted = root.pasteImage();
|
||||
root.pasteImage();
|
||||
} else if (event.key === Qt.Key_Up && event.modifiers & Qt.ControlModifier) {
|
||||
currentRoom.replyLastMessage();
|
||||
root.currentRoom.replyLastMessage();
|
||||
} else if (event.key === Qt.Key_Up && textField.text.length === 0) {
|
||||
currentRoom.editLastMessage();
|
||||
root.currentRoom.editLastMessage();
|
||||
} else if (event.key === Qt.Key_Up && completionMenu.visible) {
|
||||
completionMenu.decrementIndex()
|
||||
} else if (event.key === Qt.Key_Down && completionMenu.visible) {
|
||||
completionMenu.incrementIndex()
|
||||
} else if (event.key === Qt.Key_Backspace) {
|
||||
if (textField.text == selectedText || textField.text.length <= 1) {
|
||||
currentRoom.sendTypingNotification(false)
|
||||
root.currentRoom.sendTypingNotification(false)
|
||||
repeatTimer.stop()
|
||||
}
|
||||
if (quickFormatBar.visible && selectedText.length > 0) {
|
||||
@@ -282,19 +282,19 @@ QQC2.Control {
|
||||
Component {
|
||||
id: replyPane
|
||||
ReplyPane {
|
||||
userName: currentRoom.chatBoxReplyUser.displayName
|
||||
userColor: currentRoom.chatBoxReplyUser.color
|
||||
userAvatar: currentRoom.chatBoxReplyUser.avatarSource
|
||||
text: currentRoom.chatBoxReplyMessage
|
||||
userName: root.currentRoom.chatBoxReplyUser.displayName
|
||||
userColor: root.currentRoom.chatBoxReplyUser.color
|
||||
userAvatar: root.currentRoom.chatBoxReplyUser.avatarSource
|
||||
text: root.currentRoom.chatBoxReplyMessage
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: attachmentPane
|
||||
AttachmentPane {
|
||||
attachmentPath: currentRoom.chatBoxAttachmentPath
|
||||
attachmentPath: root.currentRoom.chatBoxAttachmentPath
|
||||
|
||||
onAttachmentCancelled: {
|
||||
currentRoom.chatBoxAttachmentPath = "";
|
||||
root.currentRoom.chatBoxAttachmentPath = "";
|
||||
root.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
@@ -346,8 +346,8 @@ QQC2.Control {
|
||||
text: i18nc("@action:button", "Cancel reply")
|
||||
icon.name: "dialog-close"
|
||||
onTriggered: {
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
currentRoom.chatBoxAttachmentPath = "";
|
||||
root.currentRoom.chatBoxReplyId = "";
|
||||
root.currentRoom.chatBoxAttachmentPath = "";
|
||||
root.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
@@ -384,28 +384,32 @@ QQC2.Control {
|
||||
|
||||
QQC2.ToolTip.visible: modelData.tooltip !== "" && hoverHandler.hovered
|
||||
QQC2.ToolTip.text: modelData.tooltip
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
HoverHandler { id: hoverHandler }
|
||||
|
||||
PieProgressBar {
|
||||
visible: modelData.isBusy
|
||||
progress: currentRoom.fileUploadingProgress
|
||||
progress: root.currentRoom.fileUploadingProgress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmojiDialog {
|
||||
Loader {
|
||||
id: emojiDialog
|
||||
x: parent.width - width
|
||||
y: -implicitHeight // - Kirigami.Units.smallSpacing
|
||||
active: !Kirigami.Settings.isMobile
|
||||
sourceComponent: EmojiDialog {
|
||||
x: root.width - width
|
||||
y: -implicitHeight // - Kirigami.Units.smallSpacing
|
||||
|
||||
modal: false
|
||||
includeCustom: true
|
||||
closeOnChosen: false
|
||||
modal: false
|
||||
includeCustom: true
|
||||
closeOnChosen: false
|
||||
|
||||
onChosen: insertText(emoji)
|
||||
onClosed: if (emojiButton.checked) emojiButton.checked = false
|
||||
currentRoom: root.currentRoom
|
||||
|
||||
onChosen: insertText(emoji)
|
||||
onClosed: if (emojiAction.checked) emojiAction.checked = false
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
@@ -467,18 +471,17 @@ QQC2.Control {
|
||||
function pasteImage() {
|
||||
let localPath = Clipboard.saveImage();
|
||||
if (localPath.length === 0) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
root.currentRoom.chatBoxAttachmentPath = localPath;
|
||||
return true;
|
||||
root.currentRoom.chatBoxAttachmentPath = localPath
|
||||
}
|
||||
|
||||
function postMessage() {
|
||||
actionsHandler.handleNewMessage();
|
||||
repeatTimer.stop()
|
||||
currentRoom.markAllMessagesAsRead();
|
||||
root.currentRoom.markAllMessagesAsRead();
|
||||
textField.clear();
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
root.currentRoom.chatBoxReplyId = "";
|
||||
messageSent()
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ import org.kde.neochat 1.0
|
||||
* @sa ChatBar
|
||||
*/
|
||||
ColumnLayout {
|
||||
id: chatBox
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
required property NeoChatRoom currentRoom
|
||||
|
||||
/**
|
||||
* @brief A message has been sent from the chat bar.
|
||||
@@ -63,7 +63,7 @@ ColumnLayout {
|
||||
ChatBar {
|
||||
id: chatBar
|
||||
|
||||
visible: currentRoom.canSendEvent("m.room.message")
|
||||
visible: root.currentRoom.canSendEvent("m.room.message")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: Math.max(Kirigami.Units.gridUnit * 2, implicitHeight + Kirigami.Units.largeSpacing)
|
||||
@@ -78,7 +78,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
onMessageSent: {
|
||||
chatBox.messageSent();
|
||||
root.messageSent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ import org.kde.neochat 1.0
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
|
||||
property bool includeCustom: false
|
||||
property bool showQuickReaction: false
|
||||
|
||||
@@ -151,7 +156,7 @@ ColumnLayout {
|
||||
|
||||
ImagePacksModel {
|
||||
id: stickerPackModel
|
||||
room: currentRoom
|
||||
room: root.currentRoom
|
||||
showStickers: true
|
||||
showEmoticons: false
|
||||
}
|
||||
@@ -160,7 +165,7 @@ ColumnLayout {
|
||||
id: stickerModel
|
||||
model: stickerPackModel
|
||||
packIndex: 0
|
||||
room: currentRoom
|
||||
room: root.currentRoom
|
||||
}
|
||||
|
||||
EmoticonFilterModel {
|
||||
|
||||
@@ -26,20 +26,14 @@ QQC2.Popup {
|
||||
padding: 2
|
||||
modal: true
|
||||
dim: true
|
||||
clip: false
|
||||
onOpened: x = Math.min(parent.mapFromGlobal(QQC2.Overlay.overlay.width - tones.width, 0).x, -(width - parent.width) / 2)
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.mediumSpacing
|
||||
shadow {
|
||||
size: Kirigami.Units.largeSpacing
|
||||
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
|
||||
yOffset: 2
|
||||
}
|
||||
border {
|
||||
color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
width: 1
|
||||
}
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
shadow.size: Kirigami.Units.smallSpacing
|
||||
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
|
||||
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
ListView {
|
||||
|
||||
@@ -46,6 +46,7 @@ ApplicationWindow {
|
||||
asset: root.asset
|
||||
author: root.author
|
||||
isLive: true
|
||||
heading: NaN
|
||||
visible: !isNaN(root.latitude) && !isNaN(root.longitude)
|
||||
}
|
||||
MapItemView {
|
||||
|
||||
@@ -6,6 +6,7 @@ import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
/**
|
||||
* @brief A component that provides a set of actions when a message is hovered in the timeline.
|
||||
@@ -16,6 +17,11 @@ import org.kde.kirigami 2.15 as Kirigami
|
||||
QQC2.Control {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
required property NeoChatRoom currentRoom
|
||||
|
||||
/**
|
||||
* @brief Whether the actions should be shown.
|
||||
*/
|
||||
@@ -108,6 +114,7 @@ QQC2.Control {
|
||||
|
||||
EmojiDialog {
|
||||
id: emojiDialog
|
||||
currentRoom: root.currentRoom
|
||||
showQuickReaction: true
|
||||
onChosen: (emoji) => root.reactClicked(emoji)
|
||||
}
|
||||
|
||||
@@ -24,11 +24,14 @@ MapQuickItem {
|
||||
|
||||
required property bool isLive
|
||||
|
||||
required property real heading
|
||||
|
||||
anchorPoint.x: sourceItem.width / 2
|
||||
anchorPoint.y: sourceItem.height
|
||||
coordinate: QtPositioning.coordinate(root.latitude, root.longitude)
|
||||
autoFadeIn: false
|
||||
sourceItem: Kirigami.Icon {
|
||||
id: mainIcon
|
||||
width: height
|
||||
height: Kirigami.Units.iconSizes.huge
|
||||
source: "gps"
|
||||
@@ -55,5 +58,19 @@ MapQuickItem {
|
||||
source: root.author.avatarSource
|
||||
color: root.author.color
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: headingIcon
|
||||
source: "go-up-symbolic"
|
||||
color: parent.color
|
||||
visible: !isNaN(root.heading) && root.isLive
|
||||
anchors.bottom: mainIcon.top
|
||||
anchors.horizontalCenter: mainIcon.horizontalCenter
|
||||
transform: Rotation {
|
||||
origin.x: headingIcon.width/2
|
||||
origin.y: headingIcon.height + mainIcon.height/2
|
||||
angle: root.heading
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ Kirigami.Page {
|
||||
}
|
||||
delegate: LocationMapItem {
|
||||
isLive: true
|
||||
heading: NaN
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ LoginStep {
|
||||
id: matrixIdField
|
||||
Kirigami.FormData.label: i18n("Matrix ID:")
|
||||
placeholderText: "@user:matrix.org"
|
||||
Accessible.name: i18n("Matrix ID")
|
||||
onTextChanged: {
|
||||
LoginHelper.matrixId = text
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ LoginStep {
|
||||
id: passwordField
|
||||
onTextChanged: LoginHelper.password = text
|
||||
enabled: !LoginHelper.isLoggingIn
|
||||
Accessible.name: i18n("Password")
|
||||
|
||||
Component.onCompleted: {
|
||||
passwordField.forceActiveFocus()
|
||||
|
||||
@@ -105,7 +105,7 @@ Components.AlbumMaximizeComponent {
|
||||
Component {
|
||||
id: saveAsDialog
|
||||
Platform.FileDialog {
|
||||
fileMode: Platform.FileDialog.SaveFile
|
||||
fileMode: FileDialog.SaveFile
|
||||
folder: root.saveFolder
|
||||
onAccepted: {
|
||||
Config.lastSaveDirectory = folder
|
||||
@@ -113,7 +113,7 @@ Components.AlbumMaximizeComponent {
|
||||
if (!currentFile) {
|
||||
return;
|
||||
}
|
||||
currentRoom.downloadFile(root.currentEventId, currentFile)
|
||||
currentRoom.downloadFile(rooteventId, currentFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ TimelineContainer {
|
||||
asset: root.asset
|
||||
author: root.author
|
||||
isLive: true
|
||||
heading: NaN
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
|
||||
@@ -50,6 +50,12 @@ TimelineContainer {
|
||||
isReply: root.isReply
|
||||
|
||||
textMessage: root.display
|
||||
|
||||
TapHandler {
|
||||
enabled: !label.hoveredLink
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: root.openContextMenu()
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -34,9 +34,9 @@ Item {
|
||||
* - displayName - The display name of the reply author.
|
||||
* - display - The name of the reply author.
|
||||
* - color - The color for the reply author.
|
||||
* - object - The NeoChatUser object for the reply author.
|
||||
* - object - The Quotient::User object for the reply author.
|
||||
*
|
||||
* @sa NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
required property var author
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ ColumnLayout {
|
||||
* - displayName - The display name of the author.
|
||||
* - display - The name of the author.
|
||||
* - color - The color for the author.
|
||||
* - object - The NeoChatUser object for the author.
|
||||
* - object - The Quotient::User object for the author.
|
||||
*
|
||||
* @sa NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
required property var author
|
||||
|
||||
@@ -137,9 +137,9 @@ ColumnLayout {
|
||||
* - displayName - The display name of the reply author.
|
||||
* - display - The name of the reply author.
|
||||
* - color - The color for the reply author.
|
||||
* - object - The NeoChatUser object for the reply author.
|
||||
* - object - The Quotient::User object for the reply author.
|
||||
*
|
||||
* @sa NeoChatUser
|
||||
* @sa Quotient::User
|
||||
*/
|
||||
required property var replyAuthor
|
||||
|
||||
@@ -485,7 +485,7 @@ ColumnLayout {
|
||||
|
||||
Layout.maximumWidth: contentMaxWidth
|
||||
|
||||
active: root.isReply
|
||||
active: root.isReply && root.reply
|
||||
visible: active
|
||||
|
||||
sourceComponent: ReplyComponent {
|
||||
@@ -518,8 +518,7 @@ ColumnLayout {
|
||||
visible: cardBackground && !Config.compactLayout
|
||||
anchors.fill: parent
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Kirigami.Theme.inherit: false
|
||||
color: if (root.author.isLocalUser) {
|
||||
color: if (root.author.isLocalUser) {
|
||||
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15)
|
||||
} else if (root.showHighlight) {
|
||||
return Kirigami.Theme.positiveBackgroundColor
|
||||
|
||||
@@ -16,9 +16,19 @@ import org.kde.neochat 1.0
|
||||
QQC2.ScrollView {
|
||||
id: root
|
||||
required property NeoChatRoom currentRoom
|
||||
readonly property bool isLoaded: root.width * root.height > 10
|
||||
onCurrentRoomChanged: {
|
||||
roomChanging = true;
|
||||
applicationWindow().hoverLinkIndicator.text = "";
|
||||
messageListView.positionViewAtBeginning();
|
||||
hasScrolledUpBefore = false;
|
||||
roomChanging = true;
|
||||
}
|
||||
property bool roomChanging: false
|
||||
readonly property bool atYEnd: messageListView.atYEnd
|
||||
|
||||
/// Used to determine if scrolling to the bottom should mark the message as unread
|
||||
property bool hasScrolledUpBefore: false;
|
||||
|
||||
signal focusChatBox()
|
||||
|
||||
ListView {
|
||||
@@ -38,7 +48,7 @@ QQC2.ScrollView {
|
||||
interactive: Kirigami.Settings.isMobile
|
||||
bottomMargin: Kirigami.Units.largeSpacing + Math.round(Kirigami.Theme.defaultFont.pointSize * 2)
|
||||
|
||||
model: !isLoaded ? undefined : collapseStateProxyModel
|
||||
model: collapseStateProxyModel
|
||||
|
||||
MessageEventModel {
|
||||
id: messageEventModel
|
||||
@@ -70,13 +80,15 @@ QQC2.ScrollView {
|
||||
messageEventModel.fetchMore(messageEventModel.index(0, 0));
|
||||
}
|
||||
|
||||
onAtYEndChanged: if (atYEnd && hasScrolledUpBefore) {
|
||||
if (QQC2.ApplicationWindow.window && (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden)) {
|
||||
root.currentRoom.markAllMessagesAsRead();
|
||||
onAtYEndChanged: if (!root.roomChanging) {
|
||||
if (atYEnd && root.hasScrolledUpBefore) {
|
||||
if (QQC2.ApplicationWindow.window && (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden)) {
|
||||
root.currentRoom.markAllMessagesAsRead();
|
||||
}
|
||||
root.hasScrolledUpBefore = false;
|
||||
} else if (!atYEnd) {
|
||||
root.hasScrolledUpBefore = true;
|
||||
}
|
||||
hasScrolledUpBefore = false;
|
||||
} else if (!atYEnd) {
|
||||
hasScrolledUpBefore = true;
|
||||
}
|
||||
|
||||
// Not rendered because the sections are part of the TimelineContainer.qml, this is only so that items have the section property available for use by sectionBanner.
|
||||
@@ -310,6 +322,7 @@ QQC2.ScrollView {
|
||||
y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0
|
||||
width: delegate ? delegate.bubbleWidth : Kirigami.Units.gridUnit * 4
|
||||
|
||||
currentRoom: root.currentRoom
|
||||
showActions: delegate && delegate.hovered
|
||||
verified: delegate && delegate.verified
|
||||
editable: delegate && delegate.author.isLocalUser && (delegate.delegateType === MessageEventModel.Emote || delegate.delegateType === MessageEventModel.Message)
|
||||
|
||||
@@ -11,6 +11,11 @@ import org.kde.neochat 1.0
|
||||
QQC2.Popup {
|
||||
id: emojiPopup
|
||||
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
|
||||
property bool includeCustom: false
|
||||
property bool closeOnChosen: true
|
||||
property bool showQuickReaction: false
|
||||
@@ -34,21 +39,15 @@ QQC2.Popup {
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.mediumSpacing
|
||||
shadow {
|
||||
size: Kirigami.Units.largeSpacing
|
||||
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
|
||||
yOffset: 2
|
||||
}
|
||||
border {
|
||||
color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
width: 2
|
||||
}
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
shadow.size: Kirigami.Units.smallSpacing
|
||||
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
|
||||
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
modal: true
|
||||
focus: true
|
||||
clip: false
|
||||
closePolicy: QQC2.Popup.CloseOnEscape | QQC2.Popup.CloseOnPressOutsideParent
|
||||
margins: 0
|
||||
padding: 2
|
||||
@@ -58,6 +57,7 @@ QQC2.Popup {
|
||||
contentItem: EmojiPicker {
|
||||
id: emojiPicker
|
||||
height: 400
|
||||
currentRoom: root.currentRoom
|
||||
includeCustom: emojiPopup.includeCustom
|
||||
showQuickReaction: emojiPopup.showQuickReaction
|
||||
onChosen: {
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
Kirigami.Dialog {
|
||||
id: root
|
||||
|
||||
signal closed()
|
||||
@@ -26,6 +26,9 @@ Kirigami.OverlaySheet {
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
standardButtons: Kirigami.Dialog.NoButton
|
||||
|
||||
width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24)
|
||||
title: i18nc("@title:menu Account detail dialog", "Account detail")
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
@@ -58,7 +61,6 @@ Kirigami.OverlaySheet {
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
text: user.displayName
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Kirigami.SelectableLabel {
|
||||
@@ -197,10 +199,5 @@ Kirigami.OverlaySheet {
|
||||
}
|
||||
}
|
||||
}
|
||||
@OVERLAYSHEET_OPEN@: {
|
||||
if (!sheetOpen) {
|
||||
closed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,7 @@ Labs.MenuBar {
|
||||
text: i18nc("menu", "Configure NeoChat...")
|
||||
|
||||
shortcut: StandardKey.Preferences
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {
|
||||
connection: Controller.activeConnection
|
||||
}, {
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
|
||||
title: i18n("Configure")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.Page {
|
||||
id: banSheet
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.Page {
|
||||
id: reportSheet
|
||||
|
||||
|
||||
@@ -193,6 +193,12 @@ Kirigami.Page {
|
||||
width: Kirigami.Units.iconSizes.small
|
||||
height: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
text: roomListModel.categoryVisible(section) ? i18nc("Collapse <section name>", "Collapse %1", roomListModel.categoryName(section)) : i18nc("Expand <section name", "Expand %1", roomListModel.categoryName(section))
|
||||
display: QQC2.Button.IconOnly
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
|
||||
onClicked: roomListModel.setCategoryVisible(section, !roomListModel.categoryVisible(section))
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ Delegates.RoundedItemDelegate {
|
||||
|
||||
readonly property bool hasNotifications: notificationCount > 0
|
||||
|
||||
Accessible.name: root.displayName
|
||||
|
||||
onPressAndHold: createRoomListContextMenu()
|
||||
|
||||
TapHandler {
|
||||
|
||||
@@ -72,12 +72,7 @@ QQC2.Control {
|
||||
connection: Controller.activeConnection
|
||||
}
|
||||
}
|
||||
onCountChanged: {
|
||||
root.enabled = count > 0
|
||||
if (!Controller.activeConnection.room(root.selectedSpaceId)) {
|
||||
root.selectedSpaceId = ""
|
||||
}
|
||||
}
|
||||
onCountChanged: root.enabled = count > 0
|
||||
Component.onCompleted: root.enabled = count > 0
|
||||
|
||||
delegate: AvatarTabButton {
|
||||
|
||||
@@ -24,13 +24,11 @@ Loader {
|
||||
QQC2.Menu {
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("'Space' is a matrix space", "View Space")
|
||||
icon.name: "view-list-details"
|
||||
onTriggered: RoomManager.enterRoom(room);
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@action:inmenu", "Copy Address to Clipboard")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: if (room.canonicalAlias.length === 0) {
|
||||
Clipboard.saveText(room.id)
|
||||
} else {
|
||||
@@ -40,7 +38,6 @@ Loader {
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("'Space' is a matrix space", "Space Settings")
|
||||
icon.name: 'settings-configure'
|
||||
onTriggered: QQC2.ApplicationWindow.window.pageStack.pushDialogLayer('qrc:/Categories.qml', {room: room}, { title: i18n("Space Settings") })
|
||||
}
|
||||
|
||||
@@ -48,13 +45,12 @@ Loader {
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("'Space' is a matrix space", "Leave Space")
|
||||
icon.name: "go-previous"
|
||||
onTriggered: RoomManager.leaveRoom(room)
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
root.closed()
|
||||
regularMenu.destroy()
|
||||
destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ QQC2.ToolBar {
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
width: parent.width
|
||||
Layout.preferredHeight: contentHeight
|
||||
delegate: Delegates.RoundedItemDelegate {
|
||||
id: userDelegate
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user