Compare commits
22 Commits
work/inval
...
v22.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f8d2a11d0 | ||
|
|
eb38741486 | ||
|
|
f207f57bd5 | ||
|
|
74b9f5fa4f | ||
|
|
6347c02d8b | ||
|
|
8dbfc093fa | ||
|
|
6acb847843 | ||
|
|
e270a46a36 | ||
|
|
e010116232 | ||
|
|
9bcbdb78fd | ||
|
|
85b0ec1e96 | ||
|
|
e4f42e2c2b | ||
|
|
8b5910773c | ||
|
|
1366158b45 | ||
|
|
d0dd86e6e8 | ||
|
|
af40860315 | ||
|
|
f3d7fbc483 | ||
|
|
d07066e540 | ||
|
|
dfb569c0f6 | ||
|
|
fda433706b | ||
|
|
a734be5f9e | ||
|
|
7ebd82d441 |
@@ -136,8 +136,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.4.0.tar.gz",
|
||||
"sha256": "0e68b3f0ce7bf521ffbdd731464d2d60d8d7a39a749b551ed26855a1707d86d1",
|
||||
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.7.0.tar.gz",
|
||||
"sha256": "23ef0217926e67c8d2eb861cf91617da2f7d8d5a9ae6c62321b21448b1669210",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 236236,
|
||||
|
||||
@@ -7,7 +7,6 @@ include:
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
|
||||
# TODO enable once we can have qt6 libQuotient on the CI
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
|
||||
# TODO re-enable once cmark is in the CI again
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml
|
||||
|
||||
@@ -14,6 +14,7 @@ Dependencies:
|
||||
'frameworks/knotifications': '@stable'
|
||||
'libraries/kquickimageeditor': '@stable'
|
||||
'frameworks/sonnet': '@stable'
|
||||
'libraries/kirigami-addons': '@latest'
|
||||
- 'on': ['Windows', 'Linux', 'FreeBSD']
|
||||
'require':
|
||||
'frameworks/qqc2-desktop-style': '@stable'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(NeoChat)
|
||||
set(PROJECT_VERSION "22.09")
|
||||
set(PROJECT_VERSION "22.11")
|
||||
|
||||
set(KF5_MIN_VERSION "5.91.0")
|
||||
set(QT_MIN_VERSION "5.15.2")
|
||||
@@ -58,6 +58,7 @@ set_package_properties(KF5Kirigami2 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Kirigami application UI framework"
|
||||
)
|
||||
find_package(KF5KirigamiAddons 0.6 REQUIRED)
|
||||
|
||||
find_package(Qt${QT_MAJOR_VERSION}Keychain)
|
||||
set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
|
||||
@@ -80,8 +81,6 @@ else()
|
||||
ecm_find_qmlmodule(org.kde.syntaxhighlighting 1.0)
|
||||
endif()
|
||||
|
||||
ecm_find_qmlmodule(org.kde.kirigamiaddons.labs.mobileform 0.1)
|
||||
|
||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||
find_package(KF5DBusAddons ${KF5_MIN_VERSION} REQUIRED)
|
||||
endif()
|
||||
@@ -145,7 +144,7 @@ add_definitions(-DQT_NO_FOREACH)
|
||||
|
||||
add_subdirectory(src)
|
||||
if (BUILD_TESTING AND Quotient_VERSION_MINOR GREATER 6)
|
||||
find_package(Qt5 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||
add_subdirectory(autotests)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -218,6 +218,9 @@
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<releases>
|
||||
<release version="22.11" date="2022-11-30">
|
||||
<url>https://plasma-mobile.org/2022/11/30/plasma-mobile-gear-22-11/</url>
|
||||
</release>
|
||||
<release version="22.09" date="2022-09-27">
|
||||
<url>https://www.plasma-mobile.org/2022/09/27/plasma-mobile-gear-22-09/</url>
|
||||
</release>
|
||||
|
||||
552
po/ar/neochat.po
552
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/az/neochat.po
556
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/ca/neochat.po
556
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
551
po/cs/neochat.po
551
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
542
po/da/neochat.po
542
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/de/neochat.po
556
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
556
po/es/neochat.po
556
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/eu/neochat.po
556
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/fi/neochat.po
556
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
552
po/fr/neochat.po
552
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
554
po/hu/neochat.po
554
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
774
po/ia/neochat.po
774
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
552
po/id/neochat.po
552
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
552
po/ie/neochat.po
552
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/it/neochat.po
556
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
538
po/ja/neochat.po
538
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
621
po/ka/neochat.po
621
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/ko/neochat.po
556
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/nl/neochat.po
556
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
430
po/nn/neochat.po
430
po/nn/neochat.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neochat\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-11-23 00:47+0000\n"
|
||||
"POT-Creation-Date: 2022-11-27 00:46+0000\n"
|
||||
"PO-Revision-Date: 2021-12-15 11:17+0100\n"
|
||||
"Last-Translator: Øystein Steffensen-Alværvik <oysteins.omsetting@protonmail."
|
||||
"com>\n"
|
||||
@@ -53,7 +53,7 @@ msgid "Sends the given emote colored as a rainbow"
|
||||
msgstr ""
|
||||
|
||||
#: src/actionsmodel.cpp:111
|
||||
msgid "Sends the given given message as plain text"
|
||||
msgid "Sends the given message as plain text"
|
||||
msgstr ""
|
||||
|
||||
#: src/actionsmodel.cpp:127
|
||||
@@ -387,16 +387,106 @@ msgstr ""
|
||||
msgid "Unable to read access token"
|
||||
msgstr ""
|
||||
|
||||
#: src/controller.cpp:720
|
||||
#: src/controller.cpp:709
|
||||
#, kde-format
|
||||
msgid "Room creation failed: \"%1\""
|
||||
msgstr "Feil ved romregistrering: «%1»"
|
||||
|
||||
#: src/controller.cpp:733
|
||||
#: src/controller.cpp:722
|
||||
#, kde-format
|
||||
msgid "The room id you are trying to join is not valid"
|
||||
msgstr "Rom-ID-en du prøver å bruka, er ikkje gyldig"
|
||||
|
||||
#: src/emojimodel.cpp:133
|
||||
#, kde-format
|
||||
msgctxt "Previously used emojis"
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:138
|
||||
#, kde-format
|
||||
msgctxt "'Custom' is a category of emoji"
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:143
|
||||
#, kde-format
|
||||
msgctxt "'Smileys' is a category of emoji"
|
||||
msgid "Smileys"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:148
|
||||
#, kde-format
|
||||
msgctxt "'People' is a category of emoji"
|
||||
msgid "People"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:153
|
||||
#, kde-format
|
||||
msgctxt "'Nature' is a category of emoji"
|
||||
msgid "Nature"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:158
|
||||
#, kde-format
|
||||
msgctxt "'Food' is a category of emoji"
|
||||
msgid "Food"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:163
|
||||
#, kde-format
|
||||
msgctxt "'Activities' is a category of emoji"
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:168
|
||||
#, kde-format
|
||||
msgctxt "'Travel' is a category of emoji"
|
||||
msgid "Travel"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:173
|
||||
#, kde-format
|
||||
msgctxt "'Objects' is a category of emoji"
|
||||
msgid "Objects"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:178
|
||||
#, kde-format
|
||||
msgctxt "'Symbols' is a category of emoji"
|
||||
msgid "Symbols"
|
||||
msgstr ""
|
||||
|
||||
#: src/emojimodel.cpp:183
|
||||
#, kde-format
|
||||
msgctxt "'Flags' is a category of emoji"
|
||||
msgid "Flags"
|
||||
msgstr ""
|
||||
|
||||
#: src/filetransferpseudojob.cpp:47
|
||||
#, kde-format
|
||||
msgctxt "Job heading, like 'Copying'"
|
||||
msgid "Downloading"
|
||||
msgstr ""
|
||||
|
||||
#: src/filetransferpseudojob.cpp:47
|
||||
#, kde-format
|
||||
msgctxt "Job heading, like 'Copying'"
|
||||
msgid "Uploading"
|
||||
msgstr ""
|
||||
|
||||
#: src/filetransferpseudojob.cpp:48
|
||||
#, kde-format
|
||||
msgctxt "The URL being downloaded/uploaded"
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#: src/filetransferpseudojob.cpp:49
|
||||
#, kde-format
|
||||
msgctxt "The location being downloaded to"
|
||||
msgid "Destination"
|
||||
msgstr ""
|
||||
|
||||
#: src/login.cpp:88 src/login.cpp:99
|
||||
#, kde-format
|
||||
msgid "Network Error"
|
||||
@@ -480,12 +570,12 @@ msgctxt "<version number> (built against <possibly different version number>)"
|
||||
msgid "%1 (built against %2)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:270
|
||||
#: src/main.cpp:273
|
||||
#, kde-format
|
||||
msgid "Client for the matrix communication protocol"
|
||||
msgstr "Lynmeldingsklient for Matrix-protokollen"
|
||||
|
||||
#: src/main.cpp:271
|
||||
#: src/main.cpp:274
|
||||
#, kde-format
|
||||
msgid "Supports matrix: url scheme"
|
||||
msgstr ""
|
||||
@@ -536,232 +626,232 @@ msgstr "[TREKT TILBAKE]"
|
||||
msgid "[REDACTED: %1]"
|
||||
msgstr "[TREKT TILBAKE: %1]"
|
||||
|
||||
#: src/neochatroom.cpp:480
|
||||
#: src/neochatroom.cpp:493
|
||||
#, kde-format
|
||||
msgid "a file"
|
||||
msgstr "ei fil"
|
||||
|
||||
#: src/neochatroom.cpp:529
|
||||
#: src/neochatroom.cpp:542
|
||||
#, kde-format
|
||||
msgid "reinvited %1 to the room"
|
||||
msgstr "inviterte %1 på nytt til rommet"
|
||||
|
||||
#: src/neochatroom.cpp:531
|
||||
#: src/neochatroom.cpp:544
|
||||
#, kde-format
|
||||
msgctxt "Optional reason for an invitation"
|
||||
msgid ": %1"
|
||||
msgstr ": %1"
|
||||
|
||||
#: src/neochatroom.cpp:540
|
||||
#: src/neochatroom.cpp:553
|
||||
#, kde-format
|
||||
msgid "joined the room (repeated)"
|
||||
msgstr "kom inn i rommet (på nytt)"
|
||||
|
||||
#: src/neochatroom.cpp:542
|
||||
#: src/neochatroom.cpp:555
|
||||
#, kde-format
|
||||
msgid "invited %1 to the room"
|
||||
msgstr "inviterte %1 til rommet"
|
||||
|
||||
#: src/neochatroom.cpp:542
|
||||
#: src/neochatroom.cpp:555
|
||||
#, kde-format
|
||||
msgid "joined the room"
|
||||
msgstr "kom inn i rommet"
|
||||
|
||||
#: src/neochatroom.cpp:546
|
||||
#: src/neochatroom.cpp:559
|
||||
#, kde-format
|
||||
msgid ": %1"
|
||||
msgstr ": %1"
|
||||
|
||||
#: src/neochatroom.cpp:553
|
||||
#: src/neochatroom.cpp:566
|
||||
#, kde-format
|
||||
msgctxt "their refers to a singular user"
|
||||
msgid "cleared their display name"
|
||||
msgstr "fjerna visingsnamnet"
|
||||
|
||||
#: src/neochatroom.cpp:555
|
||||
#: src/neochatroom.cpp:568
|
||||
#, kde-format
|
||||
msgctxt "their refers to a singular user"
|
||||
msgid "changed their display name to %1"
|
||||
msgstr "endra visingsnamn til %1"
|
||||
|
||||
#: src/neochatroom.cpp:560
|
||||
#: src/neochatroom.cpp:573
|
||||
#, kde-format
|
||||
msgid " and "
|
||||
msgstr " og "
|
||||
|
||||
#: src/neochatroom.cpp:563
|
||||
#: src/neochatroom.cpp:576
|
||||
#, kde-format
|
||||
msgctxt "their refers to a singular user"
|
||||
msgid "cleared their avatar"
|
||||
msgstr "fjerna avataren"
|
||||
|
||||
#: src/neochatroom.cpp:569
|
||||
#: src/neochatroom.cpp:582
|
||||
#, kde-format
|
||||
msgid "set an avatar"
|
||||
msgstr "valde ein avatar"
|
||||
|
||||
#: src/neochatroom.cpp:571
|
||||
#: src/neochatroom.cpp:584
|
||||
#, kde-format
|
||||
msgctxt "their refers to a singular user"
|
||||
msgid "updated their avatar"
|
||||
msgstr "bytte avataren sin"
|
||||
|
||||
#: src/neochatroom.cpp:575
|
||||
#: src/neochatroom.cpp:588
|
||||
#, kde-format
|
||||
msgctxt "<user> changed nothing"
|
||||
msgid "changed nothing"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:581
|
||||
#: src/neochatroom.cpp:594
|
||||
#, kde-format
|
||||
msgid "withdrew %1's invitation"
|
||||
msgstr "trekte tilbake invitasjonen til %1"
|
||||
|
||||
#: src/neochatroom.cpp:581
|
||||
#: src/neochatroom.cpp:594
|
||||
#, kde-format
|
||||
msgid "rejected the invitation"
|
||||
msgstr "avviste invitasjonen"
|
||||
|
||||
#: src/neochatroom.cpp:585
|
||||
#: src/neochatroom.cpp:598
|
||||
#, kde-format
|
||||
msgid "unbanned %1"
|
||||
msgstr "oppheva utestenging av %1"
|
||||
|
||||
#: src/neochatroom.cpp:585
|
||||
#: src/neochatroom.cpp:598
|
||||
#, kde-format
|
||||
msgid "self-unbanned"
|
||||
msgstr "utestengde seg sjølv"
|
||||
|
||||
#: src/neochatroom.cpp:588
|
||||
#: src/neochatroom.cpp:601
|
||||
#, kde-format
|
||||
msgid "has put %1 out of the room: %2"
|
||||
msgstr "fjerna %1 frå rommet: %2"
|
||||
|
||||
#: src/neochatroom.cpp:589
|
||||
#: src/neochatroom.cpp:602
|
||||
#, kde-format
|
||||
msgid "left the room"
|
||||
msgstr "forlét rommet"
|
||||
|
||||
#: src/neochatroom.cpp:593
|
||||
#: src/neochatroom.cpp:606
|
||||
#, kde-format
|
||||
msgid "banned %1 from the room"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:595
|
||||
#: src/neochatroom.cpp:608
|
||||
#, kde-format
|
||||
msgid "banned %1 from the room: %2"
|
||||
msgstr "utestengde %1 frå rommet: %2"
|
||||
|
||||
#: src/neochatroom.cpp:598
|
||||
#: src/neochatroom.cpp:611
|
||||
#, kde-format
|
||||
msgid "self-banned from the room"
|
||||
msgstr "utestengde seg sjølv frå rommet"
|
||||
|
||||
#: src/neochatroom.cpp:601
|
||||
#: src/neochatroom.cpp:614
|
||||
#, kde-format
|
||||
msgid "requested an invite"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:604
|
||||
#: src/neochatroom.cpp:617
|
||||
#, kde-format
|
||||
msgid "made something unknown"
|
||||
msgstr "gjorde noko ukjend"
|
||||
|
||||
#: src/neochatroom.cpp:607
|
||||
#: src/neochatroom.cpp:620
|
||||
#, kde-format
|
||||
msgid "cleared the room main alias"
|
||||
msgstr "fjerna hovudaliaset til rommet"
|
||||
|
||||
#: src/neochatroom.cpp:607
|
||||
#: src/neochatroom.cpp:620
|
||||
#, kde-format
|
||||
msgid "set the room main alias to: %1"
|
||||
msgstr "bytte hovudalias for rommet til: %1"
|
||||
|
||||
#: src/neochatroom.cpp:610
|
||||
#: src/neochatroom.cpp:623
|
||||
#, kde-format
|
||||
msgid "cleared the room name"
|
||||
msgstr "fjerna romnamnet"
|
||||
|
||||
#: src/neochatroom.cpp:610
|
||||
#: src/neochatroom.cpp:623
|
||||
#, kde-format
|
||||
msgid "set the room name to: %1"
|
||||
msgstr "bytte romnamnet til: %1"
|
||||
|
||||
#: src/neochatroom.cpp:613
|
||||
#: src/neochatroom.cpp:626
|
||||
#, kde-format
|
||||
msgid "cleared the topic"
|
||||
msgstr "tømte emnefeltet"
|
||||
|
||||
#: src/neochatroom.cpp:613
|
||||
#: src/neochatroom.cpp:626
|
||||
#, kde-format
|
||||
msgid "set the topic to: %1"
|
||||
msgstr "bytte emnet til: %1"
|
||||
|
||||
#: src/neochatroom.cpp:616
|
||||
#: src/neochatroom.cpp:629
|
||||
#, kde-format
|
||||
msgid "changed the room avatar"
|
||||
msgstr "bytte ut romavataren"
|
||||
|
||||
#: src/neochatroom.cpp:619
|
||||
#: src/neochatroom.cpp:632
|
||||
#, kde-format
|
||||
msgid "activated End-to-End Encryption"
|
||||
msgstr "slå på ende-til-ende-kryptering"
|
||||
|
||||
#: src/neochatroom.cpp:622
|
||||
#: src/neochatroom.cpp:635
|
||||
#, kde-format
|
||||
msgid "upgraded the room to version %1"
|
||||
msgstr "oppgraderte rommet til versjon %1"
|
||||
|
||||
#: src/neochatroom.cpp:623
|
||||
#: src/neochatroom.cpp:636
|
||||
#, kde-format
|
||||
msgid "created the room, version %1"
|
||||
msgstr "oppretta rommet, versjon %1"
|
||||
|
||||
#: src/neochatroom.cpp:626
|
||||
#: src/neochatroom.cpp:639
|
||||
#, kde-format
|
||||
msgctxt "'power level' means permission level"
|
||||
msgid "changed the power levels for this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:630
|
||||
#: src/neochatroom.cpp:643
|
||||
#, kde-format
|
||||
msgid "changed the server access control lists for this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:634
|
||||
#: src/neochatroom.cpp:647
|
||||
#, kde-format
|
||||
msgctxt "[User] added <name> widget"
|
||||
msgid "added %1 widget"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:637
|
||||
#: src/neochatroom.cpp:650
|
||||
#, kde-format
|
||||
msgctxt "[User] removed <name> widget"
|
||||
msgid "removed %1 widget"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:639
|
||||
#: src/neochatroom.cpp:652
|
||||
#, kde-format
|
||||
msgctxt "[User] configured <name> widget"
|
||||
msgid "configured %1 widget"
|
||||
msgstr ""
|
||||
|
||||
#: src/neochatroom.cpp:641
|
||||
#: src/neochatroom.cpp:654
|
||||
#, kde-format
|
||||
msgid "updated %1 state"
|
||||
msgstr "oppdaterte %1-tilstand"
|
||||
|
||||
#: src/neochatroom.cpp:642
|
||||
#: src/neochatroom.cpp:655
|
||||
#, kde-format
|
||||
msgid "updated %1 state for %2"
|
||||
msgstr "oppdaterte %1-tilstand for %2"
|
||||
|
||||
#: src/neochatroom.cpp:649
|
||||
#: src/neochatroom.cpp:662
|
||||
#, kde-format
|
||||
msgid "Unknown event"
|
||||
msgstr "Ukjend hending"
|
||||
|
||||
#: src/neochatroom.cpp:1141 src/neochatroom.cpp:1142
|
||||
#: src/neochatroom.cpp:1188 src/neochatroom.cpp:1189
|
||||
#, kde-format
|
||||
msgid "Report sent successfully."
|
||||
msgstr ""
|
||||
@@ -779,7 +869,7 @@ msgstr "Opna NeoChat i dette rommet"
|
||||
#: src/notificationsmanager.cpp:77
|
||||
#: src/qml/Menu/Timeline/FileDelegateContextMenu.qml:50
|
||||
#: src/qml/Menu/Timeline/MessageDelegateContextMenu.qml:37
|
||||
#: src/qml/Page/RoomPage.qml:539
|
||||
#: src/qml/Page/RoomPage.qml:540
|
||||
#, kde-format
|
||||
msgid "Reply"
|
||||
msgstr "Svar"
|
||||
@@ -816,7 +906,7 @@ msgstr "Vedlegg:"
|
||||
|
||||
#: src/qml/Component/ChatBox/AttachmentPane.qml:159
|
||||
#: src/qml/Menu/Timeline/MessageDelegateContextMenu.qml:28
|
||||
#: src/qml/Page/ImageEditorPage.qml:20 src/qml/Page/RoomPage.qml:527
|
||||
#: src/qml/Page/ImageEditorPage.qml:20 src/qml/Page/RoomPage.qml:528
|
||||
#, kde-format
|
||||
msgid "Edit"
|
||||
msgstr "Rediger"
|
||||
@@ -826,38 +916,38 @@ msgstr "Rediger"
|
||||
msgid "Cancel sending Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:81
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:82
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"This room is encrypted. Sending encrypted messages is not yet supported."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:81
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:82
|
||||
#, kde-format
|
||||
msgid "Edit Message"
|
||||
msgstr "Rediger melding"
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:81
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:82
|
||||
#, kde-format
|
||||
msgid "Send an encrypted message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:81
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:82
|
||||
#, kde-format
|
||||
msgid "Send a message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:168
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:169
|
||||
#, kde-format
|
||||
msgid "Attach an image or file"
|
||||
msgstr "Legg ved bilete eller fil"
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:200
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:201
|
||||
#, kde-format
|
||||
msgid "Add an Emoji"
|
||||
msgstr "Legg til emoji"
|
||||
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:211
|
||||
#: src/qml/Component/ChatBox/ChatBar.qml:212
|
||||
#, kde-format
|
||||
msgid "Send message"
|
||||
msgstr "Send melding"
|
||||
@@ -883,7 +973,7 @@ msgctxt "@action:button"
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/Emoji/EmojiPicker.qml:61
|
||||
#: src/qml/Component/Emoji/EmojiPicker.qml:46
|
||||
#, kde-format
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
@@ -1117,7 +1207,7 @@ msgctxt "Relative time since the room was last read"
|
||||
msgid "Last read: %1"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Component/Timeline/RichLabel.qml:77
|
||||
#: src/qml/Component/Timeline/RichLabel.qml:82
|
||||
#, kde-format
|
||||
msgid " (edited)"
|
||||
msgstr ""
|
||||
@@ -1127,7 +1217,7 @@ msgstr ""
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/qml/Component/UserInfo.qml:58 src/qml/Settings/AccountsPage.qml:82
|
||||
#: src/qml/Component/UserInfo.qml:58 src/qml/Settings/AccountsPage.qml:83
|
||||
#, kde-format
|
||||
msgid "Add Account"
|
||||
msgstr ""
|
||||
@@ -1148,7 +1238,7 @@ msgstr ""
|
||||
msgid "Edit this account"
|
||||
msgstr "Rediger kontoen"
|
||||
|
||||
#: src/qml/Component/UserInfo.qml:145 src/qml/Settings/AccountsPage.qml:35
|
||||
#: src/qml/Component/UserInfo.qml:145 src/qml/Settings/AccountsPage.qml:36
|
||||
#, kde-format
|
||||
msgid "Account editor"
|
||||
msgstr ""
|
||||
@@ -1456,23 +1546,29 @@ msgstr "Kast ut brukaren"
|
||||
msgid "Ban this user"
|
||||
msgstr "Utesteng brukaren"
|
||||
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:124
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:116
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Ban User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:127
|
||||
#, kde-format
|
||||
msgid "Unban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:137
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:140
|
||||
#, kde-format
|
||||
msgid "Remove recent messages by this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:142
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:145
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:152
|
||||
#: src/qml/Dialog/UserDetailDialog.qml:155
|
||||
#, kde-format
|
||||
msgid "Open a private chat"
|
||||
msgstr "Start privat prat"
|
||||
@@ -1807,6 +1903,30 @@ msgctxt "'Space' is a matrix space"
|
||||
msgid "Leave Space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Menu/Timeline/BanSheet.qml:16
|
||||
#, kde-format
|
||||
msgid "Ban User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Menu/Timeline/BanSheet.qml:20
|
||||
#, kde-format
|
||||
msgid "Reason for banning this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Menu/Timeline/BanSheet.qml:32
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Ban' as in 'Ban this user'"
|
||||
msgid "Ban"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Menu/Timeline/BanSheet.qml:41
|
||||
#: src/qml/Menu/Timeline/RemoveSheet.qml:47
|
||||
#: src/qml/Menu/Timeline/ReportSheet.qml:41 src/qml/Page/InviteUserPage.qml:22
|
||||
#, kde-format
|
||||
msgctxt "@action"
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: src/qml/Menu/Timeline/FileDelegateContextMenu.qml:23
|
||||
#, kde-format
|
||||
msgid "Open Externally"
|
||||
@@ -1905,13 +2025,6 @@ msgctxt "@action:button 'Remove' as in 'Remove this message'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Menu/Timeline/RemoveSheet.qml:47
|
||||
#: src/qml/Menu/Timeline/ReportSheet.qml:41 src/qml/Page/InviteUserPage.qml:22
|
||||
#, kde-format
|
||||
msgctxt "@action"
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: src/qml/Menu/Timeline/ReportSheet.qml:16
|
||||
#, kde-format
|
||||
msgid "Report Message"
|
||||
@@ -2095,7 +2208,12 @@ msgstr "Søk i romkatalogen"
|
||||
msgid "No Name"
|
||||
msgstr "Namnlaus"
|
||||
|
||||
#: src/qml/Page/RoomListPage.qml:353
|
||||
#: src/qml/Page/RoomListPage.qml:342
|
||||
#, kde-format
|
||||
msgid "Muted room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Page/RoomListPage.qml:362
|
||||
#, kde-format
|
||||
msgid "Configure room"
|
||||
msgstr "Set opp rommet"
|
||||
@@ -2130,12 +2248,12 @@ msgstr "Gå til første ulesne melding"
|
||||
msgid "Jump to latest message"
|
||||
msgstr "Gå til nyaste melding"
|
||||
|
||||
#: src/qml/Page/RoomPage.qml:404
|
||||
#: src/qml/Page/RoomPage.qml:405
|
||||
#, kde-format
|
||||
msgid "Drag items here to share them"
|
||||
msgstr "Dra element her for å dela dei"
|
||||
|
||||
#: src/qml/Page/RoomPage.qml:436
|
||||
#: src/qml/Page/RoomPage.qml:437
|
||||
#, kde-format
|
||||
msgctxt "Message displayed when some users are typing"
|
||||
msgid "%2 is typing"
|
||||
@@ -2143,12 +2261,12 @@ msgid_plural "%2 are typing"
|
||||
msgstr[0] "%2 skriv"
|
||||
msgstr[1] "%2 skriv"
|
||||
|
||||
#: src/qml/Page/RoomPage.qml:507
|
||||
#: src/qml/Page/RoomPage.qml:508
|
||||
#, kde-format
|
||||
msgid "This message was sent from a verified device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Page/RoomPage.qml:513
|
||||
#: src/qml/Page/RoomPage.qml:514
|
||||
#, kde-format
|
||||
msgid "React"
|
||||
msgstr "Reager"
|
||||
@@ -2316,7 +2434,7 @@ msgstr "Rommet er bytt ut."
|
||||
msgid "See new room..."
|
||||
msgstr "Sjå det nye rommet …"
|
||||
|
||||
#: src/qml/RoomSettings/General.qml:186 src/qml/RoomSettings/Security.qml:71
|
||||
#: src/qml/RoomSettings/General.qml:186 src/qml/RoomSettings/Security.qml:118
|
||||
#: src/qml/Settings/NetworkProxyPage.qml:108
|
||||
#: src/qml/Settings/SonnetConfigPage.qml:326
|
||||
#, kde-format
|
||||
@@ -2379,6 +2497,64 @@ msgctxt "@option:check"
|
||||
msgid "Anyone can find and join."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:68
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Message history visibility"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:71
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Anyone"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:72
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Anyone, regardless of whether they have joined, can view history."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:80
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Members only"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:81
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid ""
|
||||
"All members can view the entire message history, even before they joined."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:89
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Members only (since invite)"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:90
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid ""
|
||||
"New members can view the message history from the point they were invited to "
|
||||
"the room."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:98
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid "Members only (since joining)"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomSettings/Security.qml:99
|
||||
#, kde-format
|
||||
msgctxt "@option:check"
|
||||
msgid ""
|
||||
"New members can view the message history from the point they joined the room."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/About.qml:11
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
@@ -2467,17 +2643,17 @@ msgstr ""
|
||||
msgid "Accounts"
|
||||
msgstr "Kontoar"
|
||||
|
||||
#: src/qml/Settings/AccountsPage.qml:99
|
||||
#: src/qml/Settings/AccountsPage.qml:100
|
||||
#, kde-format
|
||||
msgid "Password changed successfully"
|
||||
msgstr "Passordet er no endra"
|
||||
|
||||
#: src/qml/Settings/AccountsPage.qml:101
|
||||
#: src/qml/Settings/AccountsPage.qml:102
|
||||
#, kde-format
|
||||
msgid "Wrong password entered"
|
||||
msgstr "Du skreiv inn feil passord"
|
||||
|
||||
#: src/qml/Settings/AccountsPage.qml:103
|
||||
#: src/qml/Settings/AccountsPage.qml:104
|
||||
#, kde-format
|
||||
msgid "Unknown problem while trying to change password"
|
||||
msgstr "Ukjent problem ved endring av passord"
|
||||
@@ -2503,37 +2679,32 @@ msgstr ""
|
||||
msgid "Compact"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:210
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:221
|
||||
#, kde-format
|
||||
msgid "Timeline"
|
||||
msgid "Show fancy effects in chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:214
|
||||
#, kde-format
|
||||
msgid "Show Fancy Effects"
|
||||
msgstr "Vis fancy effektar"
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:241
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:235
|
||||
#, kde-format
|
||||
msgid "Use transparent chat page"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:259
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:254
|
||||
#, kde-format
|
||||
msgid "Transparency"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:276
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:271
|
||||
#, kde-format
|
||||
msgid "Only enabled if the transparent chat page is enabled."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:289
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:284
|
||||
#, kde-format
|
||||
msgid "Show your messages on the right"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:302
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:297
|
||||
#, kde-format
|
||||
msgid "Show links preview in the chat messages"
|
||||
msgstr ""
|
||||
@@ -2545,17 +2716,17 @@ msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:318
|
||||
#, kde-format
|
||||
msgid "In Chat"
|
||||
msgid "In chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/AppearanceSettingsPage.qml:328
|
||||
#, kde-format
|
||||
msgid "In Sidebar"
|
||||
msgid "In sidebar"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/ColorScheme.qml:15
|
||||
#, kde-format
|
||||
msgid "Themes"
|
||||
msgid "Color theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:14 src/qml/Settings/DevicesPage.qml:26
|
||||
@@ -2569,32 +2740,42 @@ msgstr "Einingar"
|
||||
msgid "New device name"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:114
|
||||
#: src/qml/Settings/DevicesPage.qml:95
|
||||
#, kde-format
|
||||
msgid "Cancel editing display name"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:102
|
||||
#, kde-format
|
||||
msgid "Confirm new display name"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:117
|
||||
#, kde-format
|
||||
msgid "Edit device name"
|
||||
msgstr "Rediger einingsnamn"
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:123
|
||||
#: src/qml/Settings/DevicesPage.qml:131
|
||||
#, kde-format
|
||||
msgid "Verify device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:133
|
||||
#: src/qml/Settings/DevicesPage.qml:146
|
||||
#, kde-format
|
||||
msgid "Logout device"
|
||||
msgstr "Logg ut av eininga"
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:153
|
||||
#: src/qml/Settings/DevicesPage.qml:170
|
||||
#, kde-format
|
||||
msgid "Remove device"
|
||||
msgstr "Fjern eininga"
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:157
|
||||
#: src/qml/Settings/DevicesPage.qml:174
|
||||
#, kde-format
|
||||
msgid "Password:"
|
||||
msgstr "Passord:"
|
||||
|
||||
#: src/qml/Settings/DevicesPage.qml:161
|
||||
#: src/qml/Settings/DevicesPage.qml:178
|
||||
#, kde-format
|
||||
msgid "Confirm"
|
||||
msgstr "Stadfest"
|
||||
@@ -2620,6 +2801,11 @@ msgstr ""
|
||||
msgid "Add Emoji..."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/Emoticons.qml:113
|
||||
#, kde-format
|
||||
msgid "Images (*.png *.gif *.webp)"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:15
|
||||
#: src/qml/Settings/NetworkProxyPage.qml:14
|
||||
#, kde-format
|
||||
@@ -2632,80 +2818,80 @@ msgstr ""
|
||||
msgid "General settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:30
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:31
|
||||
#, kde-format
|
||||
msgid "Close to system tray"
|
||||
msgstr "Minimer til systemtrauet"
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:44
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:45
|
||||
#, kde-format
|
||||
msgid "Minimize to system tray on startup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:58
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:59
|
||||
#, kde-format
|
||||
msgid "Automatically hide/unhide the room information when resizing the window"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:76
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:77
|
||||
#, kde-format
|
||||
msgid "Timeline Events"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:81
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:82
|
||||
#, kde-format
|
||||
msgid "Show leave and join events"
|
||||
msgstr "Vis når personar kjem eller går"
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:94
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:95
|
||||
#, kde-format
|
||||
msgid "Show name change events"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:107
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:108
|
||||
#, kde-format
|
||||
msgid "Show avatar update events"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:124
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:125
|
||||
#, kde-format
|
||||
msgid "Rooms and private chats"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:127
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:128
|
||||
#, kde-format
|
||||
msgid "Separated"
|
||||
msgstr "Skilde"
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:136
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:137
|
||||
#, kde-format
|
||||
msgid "Intermixed"
|
||||
msgstr "Blanda"
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:153
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:154
|
||||
#, kde-format
|
||||
msgctxt "Chat Editor"
|
||||
msgid "Editor:"
|
||||
msgid "Editor"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:157
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:158
|
||||
#, kde-format
|
||||
msgid "Use s/text/replacement syntax to edit your last message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:168
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:169
|
||||
#, kde-format
|
||||
msgid "Send Typing Notifications"
|
||||
msgid "Send typing notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:185
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:186
|
||||
#, kde-format
|
||||
msgid "Developer Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:188
|
||||
#: src/qml/Settings/GeneralSettingsPage.qml:189
|
||||
#, kde-format
|
||||
msgid "Enable Developer Tools"
|
||||
msgid "Enable developer tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/Settings/GlobalNotificationsPage.qml:14
|
||||
|
||||
545
po/pa/neochat.po
545
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/pl/neochat.po
556
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
768
po/pt/neochat.po
768
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
540
po/ru/neochat.po
540
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
549
po/sk/neochat.po
549
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
633
po/sl/neochat.po
633
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
556
po/sv/neochat.po
556
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
552
po/ta/neochat.po
552
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
556
po/tr/neochat.po
556
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
558
po/uk/neochat.po
558
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -165,6 +165,8 @@ if(ANDROID)
|
||||
"download"
|
||||
"smiley"
|
||||
"tools-check-spelling"
|
||||
"username-copy"
|
||||
"edit-copy"
|
||||
)
|
||||
else()
|
||||
target_link_libraries(neochat PUBLIC Qt::Widgets KF5::KIOWidgets)
|
||||
|
||||
@@ -139,6 +139,10 @@ void ActionsHandler::handleMessage()
|
||||
|
||||
handledText = CustomEmojiModel::instance().preprocessText(handledText);
|
||||
handledText = markdownToHTML(handledText);
|
||||
if (handledText.count("<p>") == 1 && handledText.count("</p>") == 1) {
|
||||
handledText.remove("<p>");
|
||||
handledText.remove("</p>");
|
||||
}
|
||||
|
||||
if (handledText.length() == 0) {
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
#include <events/roommessageevent.h>
|
||||
|
||||
class NeoChatRoom;
|
||||
#include "neochatroom.h"
|
||||
|
||||
class CustomEmojiModel;
|
||||
class NeoChatRoom;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "controller.h"
|
||||
#include "neochatroom.h"
|
||||
#include "neochatuser.h"
|
||||
#include "roommanager.h"
|
||||
#include <events/roommemberevent.h>
|
||||
#include <events/roompowerlevelsevent.h>
|
||||
|
||||
@@ -193,8 +194,9 @@ QVector<ActionsModel::Action> actions{
|
||||
i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
|
||||
return QString();
|
||||
}
|
||||
if (Controller::instance().activeConnection()->room(text) || Controller::instance().activeConnection()->roomByAlias(text)) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("You are already in room <roomname>.", "You are already in room %1.", text));
|
||||
auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text);
|
||||
if (targetRoom) {
|
||||
RoomManager::instance().enterRoom(dynamic_cast<NeoChatRoom *>(targetRoom));
|
||||
return QString();
|
||||
}
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text));
|
||||
|
||||
@@ -135,7 +135,11 @@ int ChatDocumentHandler::completionStartIndex() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto &cursor = cursorPosition();
|
||||
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
|
||||
const long long cursor = cursorPosition();
|
||||
#else
|
||||
const auto cursor = cursorPosition();
|
||||
#endif
|
||||
const auto &text = m_room->chatBoxText();
|
||||
auto start = std::min(cursor, text.size()) - 1;
|
||||
while (start > -1) {
|
||||
@@ -199,7 +203,7 @@ void ChatDocumentHandler::setRoom(NeoChatRoom *room)
|
||||
|
||||
void ChatDocumentHandler::complete(int index)
|
||||
{
|
||||
if (m_completionModel->autoCompletionType() == ChatDocumentHandler::User) {
|
||||
if (m_completionModel->autoCompletionType() == CompletionModel::User) {
|
||||
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString();
|
||||
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString();
|
||||
auto text = m_room->chatBoxText();
|
||||
@@ -213,7 +217,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
cursor.setKeepPositionOnInsert(true);
|
||||
m_room->mentions()->push_back({cursor, name, 0, 0, id});
|
||||
m_highlighter->rehighlight();
|
||||
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Command) {
|
||||
} else if (m_completionModel->autoCompletionType() == CompletionModel::Command) {
|
||||
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
|
||||
auto text = m_room->chatBoxText();
|
||||
auto at = text.lastIndexOf(QLatin1Char('/'));
|
||||
@@ -221,7 +225,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
|
||||
cursor.insertText(QStringLiteral("/%1 ").arg(command));
|
||||
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Room) {
|
||||
} else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
|
||||
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString();
|
||||
auto text = m_room->chatBoxText();
|
||||
auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1);
|
||||
@@ -234,7 +238,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
cursor.setKeepPositionOnInsert(true);
|
||||
m_room->mentions()->push_back({cursor, alias, 0, 0, alias});
|
||||
m_highlighter->rehighlight();
|
||||
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Emoji) {
|
||||
} else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) {
|
||||
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
|
||||
auto text = m_room->chatBoxText();
|
||||
auto at = text.lastIndexOf(QLatin1Char(':'));
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QQuickTextDocument>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include "completionmodel.h"
|
||||
#include "userlistmodel.h"
|
||||
|
||||
class QTextDocument;
|
||||
class QQuickTextDocument;
|
||||
class NeoChatRoom;
|
||||
class SyntaxHighlighter;
|
||||
class CompletionModel;
|
||||
|
||||
class ChatDocumentHandler : public QObject
|
||||
{
|
||||
@@ -28,15 +27,6 @@ class ChatDocumentHandler : public QObject
|
||||
Q_PROPERTY(NeoChatRoom *room READ room NOTIFY roomChanged)
|
||||
|
||||
public:
|
||||
enum AutoCompletionType {
|
||||
User,
|
||||
Room,
|
||||
Emoji,
|
||||
Command,
|
||||
None,
|
||||
};
|
||||
Q_ENUM(AutoCompletionType)
|
||||
|
||||
explicit ChatDocumentHandler(QObject *parent = nullptr);
|
||||
|
||||
[[nodiscard]] QQuickTextDocument *document() const;
|
||||
@@ -80,9 +70,7 @@ private:
|
||||
|
||||
SyntaxHighlighter *m_highlighter = nullptr;
|
||||
|
||||
AutoCompletionType m_completionType = None;
|
||||
CompletionModel::AutoCompletionType m_completionType = CompletionModel::None;
|
||||
|
||||
CompletionModel *m_completionModel = nullptr;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ChatDocumentHandler::AutoCompletionType);
|
||||
|
||||
@@ -42,7 +42,7 @@ void CompletionModel::setText(const QString &text, const QString &fullText)
|
||||
int CompletionModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if (m_autoCompletionType == ChatDocumentHandler::None) {
|
||||
if (m_autoCompletionType == None) {
|
||||
return 0;
|
||||
}
|
||||
return m_filterModel->rowCount();
|
||||
@@ -54,7 +54,7 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
return {};
|
||||
}
|
||||
auto filterIndex = m_filterModel->index(index.row(), 0);
|
||||
if (m_autoCompletionType == ChatDocumentHandler::User) {
|
||||
if (m_autoCompletionType == User) {
|
||||
if (role == Text) {
|
||||
return m_filterModel->data(filterIndex, UserListModel::NameRole);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
}
|
||||
|
||||
if (m_autoCompletionType == ChatDocumentHandler::Command) {
|
||||
if (m_autoCompletionType == Command) {
|
||||
if (role == Text) {
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ")
|
||||
+ m_filterModel->data(filterIndex, ActionsModel::Parameters).toString();
|
||||
@@ -81,7 +81,7 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Prefix);
|
||||
}
|
||||
}
|
||||
if (m_autoCompletionType == ChatDocumentHandler::Room) {
|
||||
if (m_autoCompletionType == Room) {
|
||||
if (role == Text) {
|
||||
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole);
|
||||
}
|
||||
}
|
||||
if (m_autoCompletionType == ChatDocumentHandler::Emoji) {
|
||||
if (m_autoCompletionType == Emoji) {
|
||||
if (role == Text) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||
}
|
||||
@@ -125,7 +125,7 @@ void CompletionModel::updateCompletion()
|
||||
m_filterModel->setSecondaryFilterRole(UserListModel::NameRole);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_autoCompletionType = ChatDocumentHandler::User;
|
||||
m_autoCompletionType = User;
|
||||
m_filterModel->invalidate();
|
||||
} else if (text().startsWith(QLatin1Char('/'))) {
|
||||
m_filterModel->setSourceModel(&ActionsModel::instance());
|
||||
@@ -133,10 +133,10 @@ void CompletionModel::updateCompletion()
|
||||
m_filterModel->setSecondaryFilterRole(-1);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text.mid(1));
|
||||
m_autoCompletionType = ChatDocumentHandler::Command;
|
||||
m_autoCompletionType = Command;
|
||||
m_filterModel->invalidate();
|
||||
} else if (text().startsWith(QLatin1Char('#'))) {
|
||||
m_autoCompletionType = ChatDocumentHandler::Room;
|
||||
m_autoCompletionType = Room;
|
||||
m_filterModel->setSourceModel(m_roomListModel);
|
||||
m_filterModel->setFilterRole(RoomListModel::CanonicalAliasRole);
|
||||
m_filterModel->setSecondaryFilterRole(RoomListModel::DisplayNameRole);
|
||||
@@ -146,15 +146,15 @@ void CompletionModel::updateCompletion()
|
||||
} else if (text().startsWith(QLatin1Char(':'))
|
||||
&& (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|
||||
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
||||
m_autoCompletionType = ChatDocumentHandler::Emoji;
|
||||
m_filterModel->setSourceModel(m_emojiModel);
|
||||
m_autoCompletionType = Emoji;
|
||||
m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||
m_filterModel->setSecondaryFilterRole(-1);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_filterModel->invalidate();
|
||||
} else {
|
||||
m_autoCompletionType = ChatDocumentHandler::None;
|
||||
m_autoCompletionType = None;
|
||||
}
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
@@ -171,12 +171,12 @@ void CompletionModel::setRoom(NeoChatRoom *room)
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
ChatDocumentHandler::AutoCompletionType CompletionModel::autoCompletionType() const
|
||||
CompletionModel::AutoCompletionType CompletionModel::autoCompletionType() const
|
||||
{
|
||||
return m_autoCompletionType;
|
||||
}
|
||||
|
||||
void CompletionModel::setAutoCompletionType(ChatDocumentHandler::AutoCompletionType autoCompletionType)
|
||||
void CompletionModel::setAutoCompletionType(AutoCompletionType autoCompletionType)
|
||||
{
|
||||
m_autoCompletionType = autoCompletionType;
|
||||
Q_EMIT autoCompletionTypeChanged();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <KConcatenateRowsProxyModel>
|
||||
|
||||
#include "chatdocumenthandler.h"
|
||||
#include "roomlistmodel.h"
|
||||
|
||||
class CompletionProxyModel;
|
||||
class UserListModel;
|
||||
@@ -19,10 +19,19 @@ class CompletionModel : public QAbstractListModel
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString text READ text NOTIFY textChanged)
|
||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
|
||||
Q_PROPERTY(ChatDocumentHandler::AutoCompletionType autoCompletionType READ autoCompletionType NOTIFY autoCompletionTypeChanged);
|
||||
Q_PROPERTY(AutoCompletionType autoCompletionType READ autoCompletionType NOTIFY autoCompletionTypeChanged);
|
||||
Q_PROPERTY(RoomListModel *roomListModel READ roomListModel WRITE setRoomListModel NOTIFY roomListModelChanged);
|
||||
|
||||
public:
|
||||
enum AutoCompletionType {
|
||||
User,
|
||||
Room,
|
||||
Emoji,
|
||||
Command,
|
||||
None,
|
||||
};
|
||||
Q_ENUM(AutoCompletionType)
|
||||
|
||||
enum Roles {
|
||||
Text = Qt::DisplayRole,
|
||||
Subtitle,
|
||||
@@ -47,7 +56,7 @@ public:
|
||||
RoomListModel *roomListModel() const;
|
||||
void setRoomListModel(RoomListModel *roomListModel);
|
||||
|
||||
ChatDocumentHandler::AutoCompletionType autoCompletionType() const;
|
||||
AutoCompletionType autoCompletionType() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void textChanged();
|
||||
@@ -60,11 +69,12 @@ private:
|
||||
QString m_fullText;
|
||||
CompletionProxyModel *m_filterModel;
|
||||
NeoChatRoom *m_room = nullptr;
|
||||
ChatDocumentHandler::AutoCompletionType m_autoCompletionType = ChatDocumentHandler::None;
|
||||
AutoCompletionType m_autoCompletionType = None;
|
||||
|
||||
void setAutoCompletionType(ChatDocumentHandler::AutoCompletionType autoCompletionType);
|
||||
void setAutoCompletionType(AutoCompletionType autoCompletionType);
|
||||
|
||||
UserListModel *m_userListModel;
|
||||
RoomListModel *m_roomListModel;
|
||||
KConcatenateRowsProxyModel *m_emojiModel;
|
||||
};
|
||||
Q_DECLARE_METATYPE(CompletionModel::AutoCompletionType);
|
||||
|
||||
@@ -18,7 +18,11 @@ bool CompletionProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &so
|
||||
&& sourceModel()
|
||||
->data(sourceModel()->index(sourceRow, 0), secondaryFilterRole())
|
||||
.toString()
|
||||
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
|
||||
.startsWith(QStringView(m_filterText).sliced(1), Qt::CaseInsensitive));
|
||||
#else
|
||||
.startsWith(m_filterText.midRef(1), Qt::CaseInsensitive));
|
||||
#endif
|
||||
}
|
||||
|
||||
int CompletionProxyModel::secondaryFilterRole() const
|
||||
|
||||
@@ -234,13 +234,6 @@ void Controller::showWindow()
|
||||
WindowController::instance().showAndRaiseWindow(QString());
|
||||
}
|
||||
|
||||
inline QString accessTokenFileName(const AccountSettings &account)
|
||||
{
|
||||
QString fileName = account.userId();
|
||||
fileName.replace(':', '_');
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + '/' + fileName;
|
||||
}
|
||||
|
||||
void Controller::loginWithAccessToken(const QString &serverAddr, const QString &user, const QString &token, const QString &deviceName)
|
||||
{
|
||||
if (user.isEmpty() || token.isEmpty()) {
|
||||
@@ -281,7 +274,6 @@ void Controller::logout(Connection *conn, bool serverSideLogout)
|
||||
}
|
||||
|
||||
SettingsGroup("Accounts").remove(conn->userId());
|
||||
QFile(accessTokenFileName(AccountSettings(conn->userId()))).remove();
|
||||
|
||||
QKeychain::DeletePasswordJob job(qAppName());
|
||||
job.setAutoDelete(true);
|
||||
@@ -374,15 +366,7 @@ void Controller::invokeLogin()
|
||||
if (accessTokenLoadingJob->error() == QKeychain::Error::NoError) {
|
||||
accessToken = accessTokenLoadingJob->binaryData();
|
||||
} else {
|
||||
// No access token from the keychain, try token file
|
||||
// TODO FIXME this code is racy since the file might have
|
||||
// already been removed. But since the other code do a blocking
|
||||
// dbus call, the probability are not high that it will happen.
|
||||
// loadAccessTokenFromFile is also mostly legacy nowadays
|
||||
accessToken = loadAccessTokenFromFile(account);
|
||||
if (accessToken.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto connection = new Connection(account.homeserver());
|
||||
@@ -416,21 +400,6 @@ void Controller::invokeLogin()
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray Controller::loadAccessTokenFromFile(const AccountSettings &account)
|
||||
{
|
||||
QFile accountTokenFile{accessTokenFileName(account)};
|
||||
if (accountTokenFile.open(QFile::ReadOnly)) {
|
||||
if (accountTokenFile.size() < 1024) {
|
||||
return accountTokenFile.readAll();
|
||||
}
|
||||
|
||||
qWarning() << "File" << accountTokenFile.fileName() << "is" << accountTokenFile.size() << "bytes long - too long for a token, ignoring it.";
|
||||
}
|
||||
qWarning() << "Could not open access token file" << accountTokenFile.fileName();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const AccountSettings &account)
|
||||
{
|
||||
qDebug() << "Reading access token from the keychain for" << account.userId();
|
||||
@@ -442,24 +411,6 @@ QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const Accoun
|
||||
if (job->error() == QKeychain::Error::NoError) {
|
||||
return;
|
||||
}
|
||||
if (job->error() == QKeychain::Error::EntryNotFound) {
|
||||
// no access token from the keychain, try token file
|
||||
auto accessToken = loadAccessTokenFromFile(account);
|
||||
if (!accessToken.isEmpty()) {
|
||||
qDebug() << "Migrating the access token from file to the keychain for " << account.userId();
|
||||
bool removed = false;
|
||||
bool saved = saveAccessTokenToKeyChain(account, accessToken);
|
||||
if (saved) {
|
||||
QFile accountTokenFile{accessTokenFileName(account)};
|
||||
removed = accountTokenFile.remove();
|
||||
}
|
||||
if (!(saved && removed)) {
|
||||
qDebug() << "Migrating the access token from the file to the keychain "
|
||||
"failed";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (job->error()) {
|
||||
case QKeychain::EntryNotFound:
|
||||
@@ -484,22 +435,6 @@ QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const Accoun
|
||||
return job;
|
||||
}
|
||||
|
||||
bool Controller::saveAccessTokenToFile(const AccountSettings &account, const QByteArray &accessToken)
|
||||
{
|
||||
// (Re-)Make a dedicated file for access_token.
|
||||
QFile accountTokenFile{accessTokenFileName(account)};
|
||||
accountTokenFile.remove(); // Just in case
|
||||
|
||||
auto fileDir = QFileInfo(accountTokenFile).dir();
|
||||
if (!((fileDir.exists() || fileDir.mkpath(".")) && accountTokenFile.open(QFile::WriteOnly))) {
|
||||
Q_EMIT errorOccured("I/O Denied: Cannot save access token.");
|
||||
} else {
|
||||
accountTokenFile.write(accessToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Controller::saveAccessTokenToKeyChain(const AccountSettings &account, const QByteArray &accessToken)
|
||||
{
|
||||
qDebug() << "Save the access token to the keychain for " << account.userId();
|
||||
@@ -514,7 +449,7 @@ bool Controller::saveAccessTokenToKeyChain(const AccountSettings &account, const
|
||||
|
||||
if (job.error()) {
|
||||
qWarning() << "Could not save access token to the keychain: " << qPrintable(job.errorString());
|
||||
return saveAccessTokenToFile(account, accessToken);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
|
||||
[[nodiscard]] bool supportSystemTray() const;
|
||||
|
||||
bool saveAccessTokenToFile(const Quotient::AccountSettings &account, const QByteArray &accessToken);
|
||||
bool saveAccessTokenToKeyChain(const Quotient::AccountSettings &account, const QByteArray &accessToken);
|
||||
|
||||
int activeConnectionIndex() const;
|
||||
@@ -111,7 +110,6 @@ private:
|
||||
bool m_busy = false;
|
||||
TrayIcon *m_trayIcon = nullptr;
|
||||
|
||||
static QByteArray loadAccessTokenFromFile(const Quotient::AccountSettings &account);
|
||||
QKeychain::ReadPasswordJob *loadAccessTokenFromKeyChain(const Quotient::AccountSettings &account);
|
||||
|
||||
void loadSettings();
|
||||
|
||||
@@ -158,8 +158,8 @@ void Login::login()
|
||||
|
||||
// Some servers do not have a .well_known file. So we login via the username part from the mxid,
|
||||
// rather than with the full mxid, as that would lead to an invalid user.
|
||||
QStringRef username(&m_matrixId, 1, m_matrixId.indexOf(":") - 1);
|
||||
m_connection->loginWithPassword(username.toString(), m_password, m_deviceName, QString());
|
||||
auto username = m_matrixId.mid(1, m_matrixId.indexOf(":") - 1);
|
||||
m_connection->loginWithPassword(username, m_password, m_deviceName, QString());
|
||||
}
|
||||
|
||||
bool Login::supportsPassword() const
|
||||
|
||||
@@ -66,6 +66,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
|
||||
roles[AuthorDisplayNameRole] = "authorDisplayName";
|
||||
roles[IsNameChangeRole] = "isNameChange";
|
||||
roles[IsAvatarChangeRole] = "isAvatarChange";
|
||||
roles[IsRedactedRole] = "isRedacted";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -894,6 +895,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (role == IsRedactedRole) {
|
||||
return evt.isRedacted();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
AuthorDisplayNameRole,
|
||||
IsNameChangeRole,
|
||||
IsAvatarChangeRole,
|
||||
IsRedactedRole,
|
||||
LastRole, // Keep this last
|
||||
};
|
||||
Q_ENUM(EventRoles)
|
||||
|
||||
@@ -25,6 +25,10 @@ MessageFilterModel::MessageFilterModel(QObject *parent)
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowDeletedMessagesChanged, this, [this] {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
});
|
||||
}
|
||||
|
||||
bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
@@ -39,12 +43,15 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
if (index.data(MessageEventModel::IsAvatarChangeRole).toBool() && !NeoChatConfig::self()->showAvatarUpdate()) {
|
||||
return false;
|
||||
}
|
||||
if (index.data(MessageEventModel::IsRedactedRole).toBool() && !NeoChatConfig::self()->showDeletedMessages()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (specialMarks == EventStatus::Hidden || specialMarks == EventStatus::Replaced) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString eventType = index.data(MessageEventModel::EventTypeRole).toString();
|
||||
const auto eventType = index.data(MessageEventModel::EventTypeRole).toInt();
|
||||
|
||||
if (eventType == MessageEventModel::Other) {
|
||||
return false;
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
<label>Enable developer tools</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="LastSaveDirectory" type="String">
|
||||
<label>Directory last used for saving a file</label>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Timeline">
|
||||
<entry name="ShowAvatarInTimeline" type="bool">
|
||||
@@ -80,6 +83,10 @@
|
||||
<label>Show avatar update events in the timeline</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowDeletedMessages" type="bool">
|
||||
<label>Show deleted messages in the timeline</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowLinkPreview" type="bool">
|
||||
<label>Show preview of the links in the chat messages</label>
|
||||
</entry>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <qcoro/task.h>
|
||||
|
||||
#include <connection.h>
|
||||
#include <csapi/directory.h>
|
||||
#include <csapi/pushrules.h>
|
||||
#include <csapi/redaction.h>
|
||||
#include <csapi/report_content.h>
|
||||
@@ -473,13 +474,6 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
auto base = url.scheme() + QStringLiteral("://") + url.host() + (url.port() != -1 ? ':' + QString::number(url.port()) : QString());
|
||||
htmlBody.replace(utils::mxcImageRegExp, QStringLiteral(R"(<img \1 src="%1/_matrix/media/r0/download/\2/\3" \4 > )").arg(base));
|
||||
|
||||
if (e.msgtype() == MessageEventType::Emote) {
|
||||
auto author = static_cast<NeoChatUser *>(user(e.senderId()));
|
||||
int firstPara = htmlBody.indexOf("<p>");
|
||||
htmlBody.insert(firstPara == -1 ? 0 : firstPara + 3,
|
||||
"* <a href='https://matrix.to/#/" + author->id() + "' style='color: " + author->color().name() + "'>"
|
||||
+ author->displayname(this) + "</a> ");
|
||||
}
|
||||
return htmlBody;
|
||||
}
|
||||
|
||||
@@ -501,18 +495,14 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
plainBody = e.plainBody();
|
||||
}
|
||||
|
||||
if (removeReply) {
|
||||
plainBody = plainBody.remove(utils::removeReplyRegex);
|
||||
}
|
||||
if (prettyPrint) {
|
||||
plainBody = Quotient::prettyPrint(plainBody);
|
||||
if (removeReply) {
|
||||
plainBody.remove(utils::removeReplyRegex);
|
||||
}
|
||||
return Quotient::prettyPrint(plainBody);
|
||||
}
|
||||
if (e.msgtype() == MessageEventType::Emote) {
|
||||
auto author = static_cast<NeoChatUser *>(user(e.senderId()));
|
||||
plainBody.remove("/me");
|
||||
plainBody.insert(0,
|
||||
"* <a href='https://matrix.to/#/" + author->id() + "' style='color: " + author->color().name() + "'>"
|
||||
+ author->displayname(this) + "</a> ");
|
||||
if (removeReply) {
|
||||
return plainBody.remove(utils::removeReplyRegex);
|
||||
}
|
||||
return plainBody;
|
||||
},
|
||||
@@ -1335,3 +1325,46 @@ void NeoChatRoom::download(const QString &eventId, const QUrl &localFilename)
|
||||
job->start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void NeoChatRoom::mapAlias(const QString &alias)
|
||||
{
|
||||
auto getLocalAliasesJob = connection()->callApi<GetLocalAliasesJob>(id());
|
||||
connect(getLocalAliasesJob, &BaseJob::success, this, [this, getLocalAliasesJob, alias] {
|
||||
if (getLocalAliasesJob->aliases().contains(alias)) {
|
||||
return;
|
||||
} else {
|
||||
auto setRoomAliasJob = connection()->callApi<SetRoomAliasJob>(alias, id());
|
||||
connect(setRoomAliasJob, &BaseJob::success, this, [this, alias] {
|
||||
auto newAltAliases = altAliases();
|
||||
newAltAliases.append(alias);
|
||||
setLocalAliases(newAltAliases);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NeoChatRoom::unmapAlias(const QString &alias)
|
||||
{
|
||||
connection()->callApi<DeleteRoomAliasJob>(alias);
|
||||
}
|
||||
|
||||
void NeoChatRoom::setCanonicalAlias(const QString &newAlias)
|
||||
{
|
||||
QString oldCanonicalAlias = canonicalAlias();
|
||||
Room::setCanonicalAlias(newAlias);
|
||||
|
||||
connect(this, &Room::namesChanged, this, [this, newAlias, oldCanonicalAlias] {
|
||||
if (canonicalAlias() == newAlias) {
|
||||
// If the new canonical alias is already a published alt alias remove it otherwise it will be in both lists.
|
||||
// The server doesn't prevent this so we need to handle it.
|
||||
auto newAltAliases = altAliases();
|
||||
if (!oldCanonicalAlias.isEmpty()) {
|
||||
newAltAliases.append(oldCanonicalAlias);
|
||||
}
|
||||
if (newAltAliases.contains(newAlias)) {
|
||||
newAltAliases.removeAll(newAlias);
|
||||
Room::setLocalAliases(newAltAliases);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qobjectdefs.h>
|
||||
#include <room.h>
|
||||
|
||||
#include <QCache>
|
||||
@@ -201,6 +202,16 @@ public:
|
||||
|
||||
Q_INVOKABLE bool downloadTempFile(const QString &eventId);
|
||||
|
||||
/*
|
||||
* Map an alias to the room
|
||||
*
|
||||
* Note: this is different to setLocalAliases as that can only
|
||||
* get the room to publish and alias that is already mapped.
|
||||
*/
|
||||
Q_INVOKABLE void mapAlias(const QString &alias);
|
||||
Q_INVOKABLE void unmapAlias(const QString &alias);
|
||||
Q_INVOKABLE void setCanonicalAlias(const QString &newAlias);
|
||||
|
||||
#ifdef QUOTIENT_07
|
||||
Q_INVOKABLE PollHandler *poll(const QString &eventId);
|
||||
#endif
|
||||
|
||||
@@ -137,6 +137,9 @@ QQC2.ToolBar {
|
||||
completionMenu.decrementIndex()
|
||||
} else if (event.key === Qt.Key_Down && completionMenu.visible) {
|
||||
completionMenu.incrementIndex()
|
||||
} else if (event.key === Qt.Key_Backspace && inputField.text.length <= 1) {
|
||||
currentRoom.sendTypingNotification(false)
|
||||
repeatTimer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,10 +150,10 @@ QQC2.ToolBar {
|
||||
|
||||
onTextChanged: {
|
||||
if (!repeatTimer.running && Config.typingNotifications) {
|
||||
currentRoom.sendTypingNotification(true)
|
||||
var textExists = text.length > 0
|
||||
currentRoom.sendTypingNotification(textExists)
|
||||
textExists ? repeatTimer.start() : repeatTimer.stop()
|
||||
}
|
||||
repeatTimer.start()
|
||||
|
||||
currentRoom.chatBoxText = text
|
||||
}
|
||||
}
|
||||
@@ -267,7 +270,7 @@ QQC2.ToolBar {
|
||||
|
||||
function postMessage() {
|
||||
actionsHandler.handleMessage();
|
||||
|
||||
repeatTimer.stop()
|
||||
currentRoom.markAllMessagesAsRead();
|
||||
inputField.clear();
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
|
||||
@@ -293,8 +293,10 @@ QQC2.Popup {
|
||||
id: saveAsDialog
|
||||
FileDialog {
|
||||
fileMode: FileDialog.SaveFile
|
||||
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
folder: Config.lastSaveDirectory.length > 0 ? Config.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
onAccepted: {
|
||||
Config.lastSaveDirectory = folder
|
||||
Config.save()
|
||||
if (!currentFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,23 +5,15 @@ import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
Kirigami.LoadingPlaceholder {
|
||||
property var showContinueButton: false
|
||||
property var showBackButton: false
|
||||
property string title: i18n("Loading…")
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
QQC2.Label {
|
||||
text: i18n("Please wait. This might take a little while.")
|
||||
}
|
||||
|
||||
QQC2.BusyIndicator {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
running: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,11 +159,15 @@ TimelineContainer {
|
||||
|
||||
FileDialog {
|
||||
fileMode: FileDialog.SaveFile
|
||||
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
onAccepted: if (autoOpenFile) {
|
||||
UrlHelper.copyTo(progressInfo.localPath, file)
|
||||
} else {
|
||||
currentRoom.download(eventId, file);
|
||||
folder: Config.lastSaveDirectory.length > 0 ? Config.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
onAccepted: {
|
||||
Config.lastSaveDirectory = folder
|
||||
Config.save()
|
||||
if (autoOpenFile) {
|
||||
UrlHelper.copyTo(progressInfo.localPath, file)
|
||||
} else {
|
||||
currentRoom.download(eventId, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ a{
|
||||
background: " + Kirigami.Theme.textColor + ";
|
||||
}
|
||||
" : "") + "
|
||||
</style>" + textMessage + (isEdited && !contentLabel.isReplyLabel ? (" <span style=\"color: " + Kirigami.Theme.disabledTextColor + "\">" + "<span style='font-size: " + Kirigami.Theme.defaultFont.pixelSize +"px'>" + i18n(" (edited)") + "</span>") : "")
|
||||
</style>" + (isEmote ? "* <a href='https://matrix.to/#/" + author.id + "' style='color: " + author.color + "'>" + author.displayName + "</a> " : "") + textMessage + (isEdited && !contentLabel.isReplyLabel ? (" <span style=\"color: " + Kirigami.Theme.disabledTextColor + "\">" + "<span style='font-size: " + Kirigami.Theme.defaultFont.pixelSize +"px'>" + i18n(" (edited)") + "</span>") : "")
|
||||
|
||||
color: Kirigami.Theme.textColor
|
||||
selectedTextColor: Kirigami.Theme.highlightedTextColor
|
||||
|
||||
@@ -160,6 +160,15 @@ Kirigami.OverlaySheet {
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.BasicListItem {
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Copy link")
|
||||
icon.name: "username-copy"
|
||||
onTriggered: {
|
||||
Clipboard.saveText("https://matrix.to/#/" + user.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: fullScreenImage
|
||||
|
||||
|
||||
@@ -113,11 +113,13 @@ MessageDelegateContextMenu {
|
||||
id: saveAsDialog
|
||||
FileDialog {
|
||||
fileMode: FileDialog.SaveFile
|
||||
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
folder: Config.lastSaveDirectory.length > 0 ? Config.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation)
|
||||
onAccepted: {
|
||||
if (!currentFile) {
|
||||
return;
|
||||
}
|
||||
Config.lastSaveDirectory = folder
|
||||
Config.save()
|
||||
currentRoom.downloadFile(eventId, currentFile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,13 @@ Loader {
|
||||
width: Kirigami.Units.gridUnit * 25
|
||||
});
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Copy Link")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: {
|
||||
Clipboard.saveText("https://matrix.to/#/" + currentRoom.id + "/" + loadRoot.eventId)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -143,6 +150,7 @@ Loader {
|
||||
QQC2.MenuItem {
|
||||
text: i18n("Configure Web Shortcuts...")
|
||||
icon.name: "configure"
|
||||
visible: !Controller.isFlatpak
|
||||
onTriggered: webshortcutmodel.configureWebShortcuts()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,6 +348,7 @@ Kirigami.ScrollablePage {
|
||||
visible: currentRoom && currentRoom.hasUnreadMessages && currentRoom.readMarkerLoaded
|
||||
action: Kirigami.Action {
|
||||
onTriggered: {
|
||||
chatBox.focusInputField();
|
||||
messageListView.goToEvent(currentRoom.readMarkerEventId)
|
||||
}
|
||||
icon.name: "go-up"
|
||||
@@ -360,7 +361,7 @@ Kirigami.ScrollablePage {
|
||||
QQC2.RoundButton {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Kirigami.Units.largeSpacing + messageListView.headerItem.height
|
||||
anchors.bottomMargin: Kirigami.Units.largeSpacing
|
||||
anchors.rightMargin: Kirigami.Units.largeSpacing
|
||||
implicitWidth: Kirigami.Units.gridUnit * 2
|
||||
implicitHeight: Kirigami.Units.gridUnit * 2
|
||||
@@ -371,6 +372,7 @@ Kirigami.ScrollablePage {
|
||||
visible: !messageListView.atYEnd
|
||||
action: Kirigami.Action {
|
||||
onTriggered: {
|
||||
chatBox.focusInputField();
|
||||
goToLastMessage();
|
||||
currentRoom.markAllMessagesAsRead();
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ Kirigami.OverlayDrawer {
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 3.5
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 3.5
|
||||
|
||||
name: room ? room.name : i18n("No name")
|
||||
name: room ? room.displayName : ""
|
||||
source: room ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
@@ -14,108 +16,202 @@ Kirigami.ScrollablePage {
|
||||
|
||||
property var room
|
||||
|
||||
readonly property bool canChangeAvatar: room.canSendState("m.room.avatar")
|
||||
readonly property bool canChangeName: room.canSendState("m.room.name")
|
||||
readonly property bool canChangeTopic: room.canSendState("m.room.topic")
|
||||
readonly property bool canChangeCanonicalAlias: room.canSendState("m.room.canonical_alias")
|
||||
|
||||
title: i18n("General")
|
||||
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
MobileForm.FormCard {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.Avatar {
|
||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
name: room.name
|
||||
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
|
||||
QQC2.RoundButton {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: Kirigami.Units.gridUnits
|
||||
width: Kirigami.Units.gridUnits
|
||||
icon.name: 'cloud-upload'
|
||||
Accessible.name: i18n("Update avatar")
|
||||
enabled: canChangeAvatar
|
||||
onClicked: {
|
||||
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
|
||||
|
||||
fileDialog.chosen.connect(function(path) {
|
||||
if (!path) return
|
||||
|
||||
room.changeAvatar(path)
|
||||
})
|
||||
|
||||
fileDialog.open()
|
||||
}
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
MobileForm.FormCardHeader {
|
||||
title: i18n("Room Information")
|
||||
}
|
||||
}
|
||||
QQC2.TextField {
|
||||
id: roomNameField
|
||||
text: room.name
|
||||
Kirigami.FormData.label: i18n("Room Name:")
|
||||
enabled: canChangeName
|
||||
}
|
||||
|
||||
QQC2.TextArea {
|
||||
id: roomTopicField
|
||||
Layout.fillWidth: true
|
||||
text: room.topic
|
||||
Kirigami.FormData.label: i18n("Room topic:")
|
||||
enabled: canChangeTopic
|
||||
}
|
||||
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: canonicalAliasComboBox.visible || altAlias.visible
|
||||
}
|
||||
|
||||
QQC2.ComboBox {
|
||||
id: canonicalAliasComboBox
|
||||
visible: room.aliases && room.aliases.length
|
||||
Kirigami.FormData.label: i18n("Canonical Alias:")
|
||||
popup.z: 999; // HACK This is an absolute hack, but combos inside OverlaySheets have their popups show up underneath, because of fun z ordering stuff
|
||||
|
||||
enabled: canChangeCanonicalAlias
|
||||
|
||||
model: room.aliases
|
||||
|
||||
currentIndex: room.aliases.indexOf(room.canonicalAlias)
|
||||
onCurrentIndexChanged: {
|
||||
if (room.canonicalAlias != room.aliases[currentIndex]) {
|
||||
room.setCanonicalAlias(room.aliases[currentIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: altAlias
|
||||
Kirigami.FormData.label: i18n("Other Aliases:")
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.altAliases && room.altAliases.length
|
||||
|
||||
ColumnLayout {
|
||||
MobileForm.AbstractFormDelegate {
|
||||
Layout.fillWidth: true
|
||||
background: Item {}
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.Avatar {
|
||||
id: avatar
|
||||
Layout.alignment: Qt.AlignRight
|
||||
name: room.name
|
||||
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
}
|
||||
QQC2.Button {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
enabled: room.canSendState("m.room.avatar")
|
||||
visible: enabled
|
||||
icon.name: "cloud-upload"
|
||||
text: i18n("Update avatar")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
|
||||
spacing: 0
|
||||
onClicked: {
|
||||
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
|
||||
|
||||
Repeater {
|
||||
model: room.altAliases
|
||||
fileDialog.chosen.connect(function(path) {
|
||||
if (!path) return
|
||||
|
||||
delegate: RowLayout {
|
||||
Layout.maximumWidth: parent.width
|
||||
room.changeAvatar(path)
|
||||
})
|
||||
|
||||
QQC2.Label {
|
||||
text: modelData
|
||||
fileDialog.open()
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
MobileForm.FormTextFieldDelegate {
|
||||
id: roomNameField
|
||||
label: i18n("Room name:")
|
||||
text: room.name
|
||||
enabled: room.canSendState("m.room.name")
|
||||
}
|
||||
MobileForm.AbstractFormDelegate {
|
||||
id: roomTopicField
|
||||
Layout.fillWidth: true
|
||||
enabled: room.canSendState("m.room.topic")
|
||||
background: Item {}
|
||||
contentItem: ColumnLayout {
|
||||
QQC2.Label {
|
||||
id: roomTopicLabel
|
||||
text: i18n("Room topic:")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
QQC2.TextArea {
|
||||
Accessible.description: roomTopicLabel.text
|
||||
Layout.fillWidth: true
|
||||
text: room.topic
|
||||
onTextChanged: roomTopicField.text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
MobileForm.AbstractFormDelegate {
|
||||
Layout.fillWidth: true
|
||||
background: Item {}
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
QQC2.Button {
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
|
||||
text: i18n("Save")
|
||||
onClicked: {
|
||||
if (room.name != roomNameField.text) {
|
||||
room.setName(roomNameField.text)
|
||||
}
|
||||
|
||||
if (room.topic != roomTopicField.text) {
|
||||
room.setTopic(roomTopicField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MobileForm.FormCard {
|
||||
Layout.fillWidth: true
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
MobileForm.FormCardHeader {
|
||||
title: i18n("Aliases")
|
||||
}
|
||||
MobileForm.FormTextDelegate {
|
||||
visible: room.aliases.length <= 0
|
||||
text: i18n("No canonical alias set")
|
||||
}
|
||||
Repeater {
|
||||
id: altAliasRepeater
|
||||
model: room.aliases.slice().reverse()
|
||||
|
||||
delegate: MobileForm.FormTextDelegate {
|
||||
text: modelData
|
||||
description: room.canonicalAlias.length > 0 && modelData === room.canonicalAlias ? "Canonical alias" : ""
|
||||
contentItem.children: [
|
||||
QQC2.ToolButton {
|
||||
icon.name: ""
|
||||
onClicked: room.removeLocalAlias(modelData)
|
||||
id: setCanonicalAliasButton
|
||||
visible: modelData !== room.canonicalAlias && room.canSendState("m.room.canonical_alias")
|
||||
text: i18n("Make this alias the room's canonical alias")
|
||||
icon.name: "checkmark"
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
|
||||
onClicked: {
|
||||
room.setCanonicalAlias(modelData)
|
||||
}
|
||||
QQC2.ToolTip {
|
||||
text: setCanonicalAliasButton.text
|
||||
delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
},
|
||||
QQC2.ToolButton {
|
||||
id: deleteButton
|
||||
visible: room.canSendState("m.room.canonical_alias")
|
||||
text: i18n("Delete alias")
|
||||
icon.name: "edit-delete-remove"
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
|
||||
onClicked: {
|
||||
room.unmapAlias(modelData)
|
||||
}
|
||||
QQC2.ToolTip {
|
||||
text: deleteButton.text
|
||||
delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
MobileForm.AbstractFormDelegate {
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem : RowLayout {
|
||||
Kirigami.ActionTextField {
|
||||
id: aliasAddField
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
placeholderText: i18n("#new_alias:server.org")
|
||||
|
||||
rightActions: Kirigami.Action {
|
||||
icon.name: "edit-clear"
|
||||
visible: aliasAddField.text.length > 0
|
||||
onTriggered: {
|
||||
aliasAddField.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
room.mapAlias(aliasAddField.text)
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
id: addButton
|
||||
|
||||
text: i18n("Add keyword")
|
||||
Accessible.name: text
|
||||
icon.name: "list-add"
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
|
||||
onClicked: {
|
||||
room.mapAlias(aliasAddField.text)
|
||||
}
|
||||
|
||||
QQC2.ToolTip {
|
||||
text: addButton.text
|
||||
delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,47 +219,33 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.InlineMessage {
|
||||
Layout.fillWidth: true
|
||||
visible: next.visible || prev.visible
|
||||
}
|
||||
|
||||
QQC2.Control {
|
||||
id: next
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("This room continues another conversation.")
|
||||
type: Kirigami.MessageType.Information
|
||||
visible: room.predecessorId && room.connection.room(room.predecessorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room continues another conversation.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See older messages...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.predecessorId)
|
||||
root.close()
|
||||
}
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See older messages…")
|
||||
onTriggered: {
|
||||
RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Control {
|
||||
id: prev
|
||||
Kirigami.InlineMessage {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("This room has been replaced.")
|
||||
type: Kirigami.MessageType.Information
|
||||
visible: room.successorId && room.connection.room(room.successorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room has been replaced.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See new room...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.successorId)
|
||||
root.close()
|
||||
}
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See new room…")
|
||||
onTriggered: {
|
||||
RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,27 +256,5 @@ Kirigami.ScrollablePage {
|
||||
OpenFileDialog {}
|
||||
}
|
||||
}
|
||||
|
||||
footer: QQC2.ToolBar {
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
QQC2.Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
|
||||
text: i18n("Apply")
|
||||
onClicked: {
|
||||
if (room.name != roomNameField.text) {
|
||||
room.setName(roomNameField.text)
|
||||
}
|
||||
|
||||
if (room.topic != roomTopicField.text) {
|
||||
room.setTopic(roomTopicField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,19 @@ Kirigami.ScrollablePage {
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator { above: showAvatarChangeDelegate; below: showDeletedMessages }
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showDeletedMessages
|
||||
text: i18n("Show deleted messages")
|
||||
checked: Config.showDeletedMessages
|
||||
enabled: !Config.isShowDeletedMessagesImmutable
|
||||
onToggled: {
|
||||
Config.showDeletedMessages = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,13 +238,13 @@ Kirigami.ApplicationWindow {
|
||||
text: i18n("Explore rooms")
|
||||
icon.name: "compass"
|
||||
onTriggered: pushReplaceLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Explore Rooms") && Controller.accountCount > 0
|
||||
enabled: pageStack.layers.depth === 1 && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Start a Chat")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: pushReplaceLayer("qrc:/StartChatPage.qml", {connection: Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0
|
||||
enabled: pageStack.layers.depth === 1 && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Create a Room")
|
||||
@@ -262,7 +262,7 @@ Kirigami.ApplicationWindow {
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
|
||||
title: i18n("Configure")
|
||||
})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Configure NeoChat...")
|
||||
enabled: pageStack.layers.depth === 1
|
||||
shortcut: StandardKey.Preferences
|
||||
},
|
||||
Kirigami.Action {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "sortfilterroomlistmodel.h"
|
||||
|
||||
#include "neochatconfig.h"
|
||||
#include "roomlistmodel.h"
|
||||
#include "spacehierarchycache.h"
|
||||
|
||||
@@ -15,15 +14,6 @@ SortFilterRoomListModel::SortFilterRoomListModel(QObject *parent)
|
||||
connect(this, &SortFilterRoomListModel::filterTextChanged, this, [this]() {
|
||||
invalidateFilter();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowRenameChanged, this, [this] {
|
||||
invalidate();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowAvatarUpdateChanged, this, [this] {
|
||||
invalidate();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLeaveJoinEventChanged, this, [this] {
|
||||
invalidate();
|
||||
});
|
||||
}
|
||||
|
||||
void SortFilterRoomListModel::setRoomSortOrder(SortFilterRoomListModel::RoomSortOrder sortOrder)
|
||||
|
||||
Reference in New Issue
Block a user