Compare commits

..

1 Commits

Author SHA1 Message Date
Tobias Fella
739c96711c Invalidate room list sorting when changing event visibility settings
BUG: 455030
2022-11-27 19:16:51 +01:00
73 changed files with 9749 additions and 11599 deletions

View File

@@ -136,8 +136,8 @@
"sources": [
{
"type": "archive",
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.7.0.tar.gz",
"sha256": "23ef0217926e67c8d2eb861cf91617da2f7d8d5a9ae6c62321b21448b1669210",
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.4.0.tar.gz",
"sha256": "0e68b3f0ce7bf521ffbdd731464d2d60d8d7a39a749b551ed26855a1707d86d1",
"x-checker-data": {
"type": "anitya",
"project-id": 236236,

View File

@@ -7,6 +7,7 @@ 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
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.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/freebsd.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml

View File

@@ -14,7 +14,6 @@ Dependencies:
'frameworks/knotifications': '@stable'
'libraries/kquickimageeditor': '@stable'
'frameworks/sonnet': '@stable'
'libraries/kirigami-addons': '@latest'
- 'on': ['Windows', 'Linux', 'FreeBSD']
'require':
'frameworks/qqc2-desktop-style': '@stable'

View File

@@ -7,7 +7,7 @@
cmake_minimum_required(VERSION 3.16)
project(NeoChat)
set(PROJECT_VERSION "22.11")
set(PROJECT_VERSION "22.09")
set(KF5_MIN_VERSION "5.91.0")
set(QT_MIN_VERSION "5.15.2")
@@ -58,7 +58,6 @@ 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
@@ -81,6 +80,8 @@ 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()
@@ -144,7 +145,7 @@ add_definitions(-DQT_NO_FOREACH)
add_subdirectory(src)
if (BUILD_TESTING AND Quotient_VERSION_MINOR GREATER 6)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
find_package(Qt5 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
add_subdirectory(autotests)
endif()

View File

@@ -218,9 +218,6 @@
<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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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-27 00:46+0000\n"
"POT-Creation-Date: 2022-11-23 00:47+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 message as plain text"
msgid "Sends the given given message as plain text"
msgstr ""
#: src/actionsmodel.cpp:127
@@ -387,106 +387,16 @@ msgstr ""
msgid "Unable to read access token"
msgstr ""
#: src/controller.cpp:709
#: src/controller.cpp:720
#, kde-format
msgid "Room creation failed: \"%1\""
msgstr "Feil ved romregistrering: «%1»"
#: src/controller.cpp:722
#: src/controller.cpp:733
#, 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"
@@ -570,12 +480,12 @@ msgctxt "<version number> (built against <possibly different version number>)"
msgid "%1 (built against %2)"
msgstr ""
#: src/main.cpp:273
#: src/main.cpp:270
#, kde-format
msgid "Client for the matrix communication protocol"
msgstr "Lynmeldings­klient for Matrix-protokollen"
#: src/main.cpp:274
#: src/main.cpp:271
#, kde-format
msgid "Supports matrix: url scheme"
msgstr ""
@@ -626,232 +536,232 @@ msgstr "[TREKT TILBAKE]"
msgid "[REDACTED: %1]"
msgstr "[TREKT TILBAKE: %1]"
#: src/neochatroom.cpp:493
#: src/neochatroom.cpp:480
#, kde-format
msgid "a file"
msgstr "ei fil"
#: src/neochatroom.cpp:542
#: src/neochatroom.cpp:529
#, kde-format
msgid "reinvited %1 to the room"
msgstr "inviterte %1 på nytt til rommet"
#: src/neochatroom.cpp:544
#: src/neochatroom.cpp:531
#, kde-format
msgctxt "Optional reason for an invitation"
msgid ": %1"
msgstr ": %1"
#: src/neochatroom.cpp:553
#: src/neochatroom.cpp:540
#, kde-format
msgid "joined the room (repeated)"
msgstr "kom inn i rommet (på nytt)"
#: src/neochatroom.cpp:555
#: src/neochatroom.cpp:542
#, kde-format
msgid "invited %1 to the room"
msgstr "inviterte %1 til rommet"
#: src/neochatroom.cpp:555
#: src/neochatroom.cpp:542
#, kde-format
msgid "joined the room"
msgstr "kom inn i rommet"
#: src/neochatroom.cpp:559
#: src/neochatroom.cpp:546
#, kde-format
msgid ": %1"
msgstr ": %1"
#: src/neochatroom.cpp:566
#: src/neochatroom.cpp:553
#, kde-format
msgctxt "their refers to a singular user"
msgid "cleared their display name"
msgstr "fjerna visingsnamnet"
#: src/neochatroom.cpp:568
#: src/neochatroom.cpp:555
#, kde-format
msgctxt "their refers to a singular user"
msgid "changed their display name to %1"
msgstr "endra visingsnamn til %1"
#: src/neochatroom.cpp:573
#: src/neochatroom.cpp:560
#, kde-format
msgid " and "
msgstr " og "
#: src/neochatroom.cpp:576
#: src/neochatroom.cpp:563
#, kde-format
msgctxt "their refers to a singular user"
msgid "cleared their avatar"
msgstr "fjerna avataren"
#: src/neochatroom.cpp:582
#: src/neochatroom.cpp:569
#, kde-format
msgid "set an avatar"
msgstr "valde ein avatar"
#: src/neochatroom.cpp:584
#: src/neochatroom.cpp:571
#, kde-format
msgctxt "their refers to a singular user"
msgid "updated their avatar"
msgstr "bytte avataren sin"
#: src/neochatroom.cpp:588
#: src/neochatroom.cpp:575
#, kde-format
msgctxt "<user> changed nothing"
msgid "changed nothing"
msgstr ""
#: src/neochatroom.cpp:594
#: src/neochatroom.cpp:581
#, kde-format
msgid "withdrew %1's invitation"
msgstr "trekte tilbake invitasjonen til %1"
#: src/neochatroom.cpp:594
#: src/neochatroom.cpp:581
#, kde-format
msgid "rejected the invitation"
msgstr "avviste invitasjonen"
#: src/neochatroom.cpp:598
#: src/neochatroom.cpp:585
#, kde-format
msgid "unbanned %1"
msgstr "oppheva utestenging av %1"
#: src/neochatroom.cpp:598
#: src/neochatroom.cpp:585
#, kde-format
msgid "self-unbanned"
msgstr "utestengde seg sjølv"
#: src/neochatroom.cpp:601
#: src/neochatroom.cpp:588
#, kde-format
msgid "has put %1 out of the room: %2"
msgstr "fjerna %1 frå rommet: %2"
#: src/neochatroom.cpp:602
#: src/neochatroom.cpp:589
#, kde-format
msgid "left the room"
msgstr "forlét rommet"
#: src/neochatroom.cpp:606
#: src/neochatroom.cpp:593
#, kde-format
msgid "banned %1 from the room"
msgstr ""
#: src/neochatroom.cpp:608
#: src/neochatroom.cpp:595
#, kde-format
msgid "banned %1 from the room: %2"
msgstr "utestengde %1 frå rommet: %2"
#: src/neochatroom.cpp:611
#: src/neochatroom.cpp:598
#, kde-format
msgid "self-banned from the room"
msgstr "utestengde seg sjølv frå rommet"
#: src/neochatroom.cpp:614
#: src/neochatroom.cpp:601
#, kde-format
msgid "requested an invite"
msgstr ""
#: src/neochatroom.cpp:617
#: src/neochatroom.cpp:604
#, kde-format
msgid "made something unknown"
msgstr "gjorde noko ukjend"
#: src/neochatroom.cpp:620
#: src/neochatroom.cpp:607
#, kde-format
msgid "cleared the room main alias"
msgstr "fjerna hovudaliaset til rommet"
#: src/neochatroom.cpp:620
#: src/neochatroom.cpp:607
#, kde-format
msgid "set the room main alias to: %1"
msgstr "bytte hovudalias for rommet til: %1"
#: src/neochatroom.cpp:623
#: src/neochatroom.cpp:610
#, kde-format
msgid "cleared the room name"
msgstr "fjerna romnamnet"
#: src/neochatroom.cpp:623
#: src/neochatroom.cpp:610
#, kde-format
msgid "set the room name to: %1"
msgstr "bytte romnamnet til: %1"
#: src/neochatroom.cpp:626
#: src/neochatroom.cpp:613
#, kde-format
msgid "cleared the topic"
msgstr "tømte emnefeltet"
#: src/neochatroom.cpp:626
#: src/neochatroom.cpp:613
#, kde-format
msgid "set the topic to: %1"
msgstr "bytte emnet til: %1"
#: src/neochatroom.cpp:629
#: src/neochatroom.cpp:616
#, kde-format
msgid "changed the room avatar"
msgstr "bytte ut romavataren"
#: src/neochatroom.cpp:632
#: src/neochatroom.cpp:619
#, kde-format
msgid "activated End-to-End Encryption"
msgstr "slå på ende-til-ende-kryptering"
#: src/neochatroom.cpp:635
#: src/neochatroom.cpp:622
#, kde-format
msgid "upgraded the room to version %1"
msgstr "oppgraderte rommet til versjon %1"
#: src/neochatroom.cpp:636
#: src/neochatroom.cpp:623
#, kde-format
msgid "created the room, version %1"
msgstr "oppretta rommet, versjon %1"
#: src/neochatroom.cpp:639
#: src/neochatroom.cpp:626
#, kde-format
msgctxt "'power level' means permission level"
msgid "changed the power levels for this room"
msgstr ""
#: src/neochatroom.cpp:643
#: src/neochatroom.cpp:630
#, kde-format
msgid "changed the server access control lists for this room"
msgstr ""
#: src/neochatroom.cpp:647
#: src/neochatroom.cpp:634
#, kde-format
msgctxt "[User] added <name> widget"
msgid "added %1 widget"
msgstr ""
#: src/neochatroom.cpp:650
#: src/neochatroom.cpp:637
#, kde-format
msgctxt "[User] removed <name> widget"
msgid "removed %1 widget"
msgstr ""
#: src/neochatroom.cpp:652
#: src/neochatroom.cpp:639
#, kde-format
msgctxt "[User] configured <name> widget"
msgid "configured %1 widget"
msgstr ""
#: src/neochatroom.cpp:654
#: src/neochatroom.cpp:641
#, kde-format
msgid "updated %1 state"
msgstr "oppdaterte %1-tilstand"
#: src/neochatroom.cpp:655
#: src/neochatroom.cpp:642
#, kde-format
msgid "updated %1 state for %2"
msgstr "oppdaterte %1-tilstand for %2"
#: src/neochatroom.cpp:662
#: src/neochatroom.cpp:649
#, kde-format
msgid "Unknown event"
msgstr "Ukjend hending"
#: src/neochatroom.cpp:1188 src/neochatroom.cpp:1189
#: src/neochatroom.cpp:1141 src/neochatroom.cpp:1142
#, kde-format
msgid "Report sent successfully."
msgstr ""
@@ -869,7 +779,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:540
#: src/qml/Page/RoomPage.qml:539
#, kde-format
msgid "Reply"
msgstr "Svar"
@@ -906,7 +816,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:528
#: src/qml/Page/ImageEditorPage.qml:20 src/qml/Page/RoomPage.qml:527
#, kde-format
msgid "Edit"
msgstr "Rediger"
@@ -916,38 +826,38 @@ msgstr "Rediger"
msgid "Cancel sending Image"
msgstr ""
#: src/qml/Component/ChatBox/ChatBar.qml:82
#: src/qml/Component/ChatBox/ChatBar.qml:81
#, kde-format
msgid ""
"This room is encrypted. Sending encrypted messages is not yet supported."
msgstr ""
#: src/qml/Component/ChatBox/ChatBar.qml:82
#: src/qml/Component/ChatBox/ChatBar.qml:81
#, kde-format
msgid "Edit Message"
msgstr "Rediger melding"
#: src/qml/Component/ChatBox/ChatBar.qml:82
#: src/qml/Component/ChatBox/ChatBar.qml:81
#, kde-format
msgid "Send an encrypted message…"
msgstr ""
#: src/qml/Component/ChatBox/ChatBar.qml:82
#: src/qml/Component/ChatBox/ChatBar.qml:81
#, kde-format
msgid "Send a message…"
msgstr ""
#: src/qml/Component/ChatBox/ChatBar.qml:169
#: src/qml/Component/ChatBox/ChatBar.qml:168
#, kde-format
msgid "Attach an image or file"
msgstr "Legg ved bilete eller fil"
#: src/qml/Component/ChatBox/ChatBar.qml:201
#: src/qml/Component/ChatBox/ChatBar.qml:200
#, kde-format
msgid "Add an Emoji"
msgstr "Legg til emoji"
#: src/qml/Component/ChatBox/ChatBar.qml:212
#: src/qml/Component/ChatBox/ChatBar.qml:211
#, kde-format
msgid "Send message"
msgstr "Send melding"
@@ -973,7 +883,7 @@ msgctxt "@action:button"
msgid "Cancel reply"
msgstr ""
#: src/qml/Component/Emoji/EmojiPicker.qml:46
#: src/qml/Component/Emoji/EmojiPicker.qml:61
#, kde-format
msgid "Custom"
msgstr ""
@@ -1207,7 +1117,7 @@ msgctxt "Relative time since the room was last read"
msgid "Last read: %1"
msgstr ""
#: src/qml/Component/Timeline/RichLabel.qml:82
#: src/qml/Component/Timeline/RichLabel.qml:77
#, kde-format
msgid " (edited)"
msgstr ""
@@ -1217,7 +1127,7 @@ msgstr ""
msgid "Video"
msgstr "Video"
#: src/qml/Component/UserInfo.qml:58 src/qml/Settings/AccountsPage.qml:83
#: src/qml/Component/UserInfo.qml:58 src/qml/Settings/AccountsPage.qml:82
#, kde-format
msgid "Add Account"
msgstr ""
@@ -1238,7 +1148,7 @@ msgstr ""
msgid "Edit this account"
msgstr "Rediger kontoen"
#: src/qml/Component/UserInfo.qml:145 src/qml/Settings/AccountsPage.qml:36
#: src/qml/Component/UserInfo.qml:145 src/qml/Settings/AccountsPage.qml:35
#, kde-format
msgid "Account editor"
msgstr ""
@@ -1546,29 +1456,23 @@ msgstr "Kast ut brukaren"
msgid "Ban this user"
msgstr "Utesteng brukaren"
#: src/qml/Dialog/UserDetailDialog.qml:116
#, kde-format
msgctxt "@title"
msgid "Ban User"
msgstr ""
#: src/qml/Dialog/UserDetailDialog.qml:127
#: src/qml/Dialog/UserDetailDialog.qml:124
#, kde-format
msgid "Unban this user"
msgstr ""
#: src/qml/Dialog/UserDetailDialog.qml:140
#: src/qml/Dialog/UserDetailDialog.qml:137
#, kde-format
msgid "Remove recent messages by this user"
msgstr ""
#: src/qml/Dialog/UserDetailDialog.qml:145
#: src/qml/Dialog/UserDetailDialog.qml:142
#, kde-format
msgctxt "@title"
msgid "Remove Messages"
msgstr ""
#: src/qml/Dialog/UserDetailDialog.qml:155
#: src/qml/Dialog/UserDetailDialog.qml:152
#, kde-format
msgid "Open a private chat"
msgstr "Start privat prat"
@@ -1903,30 +1807,6 @@ 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"
@@ -2025,6 +1905,13 @@ 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"
@@ -2208,12 +2095,7 @@ msgstr "Søk i romkatalogen"
msgid "No Name"
msgstr "Namnlaus"
#: src/qml/Page/RoomListPage.qml:342
#, kde-format
msgid "Muted room"
msgstr ""
#: src/qml/Page/RoomListPage.qml:362
#: src/qml/Page/RoomListPage.qml:353
#, kde-format
msgid "Configure room"
msgstr "Set opp rommet"
@@ -2248,12 +2130,12 @@ msgstr "Gå til første ulesne melding"
msgid "Jump to latest message"
msgstr "Gå til nyaste melding"
#: src/qml/Page/RoomPage.qml:405
#: src/qml/Page/RoomPage.qml:404
#, kde-format
msgid "Drag items here to share them"
msgstr "Dra element her for å dela dei"
#: src/qml/Page/RoomPage.qml:437
#: src/qml/Page/RoomPage.qml:436
#, kde-format
msgctxt "Message displayed when some users are typing"
msgid "%2 is typing"
@@ -2261,12 +2143,12 @@ msgid_plural "%2 are typing"
msgstr[0] "%2 skriv"
msgstr[1] "%2 skriv"
#: src/qml/Page/RoomPage.qml:508
#: src/qml/Page/RoomPage.qml:507
#, kde-format
msgid "This message was sent from a verified device"
msgstr ""
#: src/qml/Page/RoomPage.qml:514
#: src/qml/Page/RoomPage.qml:513
#, kde-format
msgid "React"
msgstr "Reager"
@@ -2434,7 +2316,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:118
#: src/qml/RoomSettings/General.qml:186 src/qml/RoomSettings/Security.qml:71
#: src/qml/Settings/NetworkProxyPage.qml:108
#: src/qml/Settings/SonnetConfigPage.qml:326
#, kde-format
@@ -2497,64 +2379,6 @@ 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"
@@ -2643,17 +2467,17 @@ msgstr ""
msgid "Accounts"
msgstr "Kontoar"
#: src/qml/Settings/AccountsPage.qml:100
#: src/qml/Settings/AccountsPage.qml:99
#, kde-format
msgid "Password changed successfully"
msgstr "Passordet er no endra"
#: src/qml/Settings/AccountsPage.qml:102
#: src/qml/Settings/AccountsPage.qml:101
#, kde-format
msgid "Wrong password entered"
msgstr "Du skreiv inn feil passord"
#: src/qml/Settings/AccountsPage.qml:104
#: src/qml/Settings/AccountsPage.qml:103
#, kde-format
msgid "Unknown problem while trying to change password"
msgstr "Ukjent problem ved endring av passord"
@@ -2679,32 +2503,37 @@ msgstr ""
msgid "Compact"
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:221
#: src/qml/Settings/AppearanceSettingsPage.qml:210
#, kde-format
msgid "Show fancy effects in chat"
msgid "Timeline"
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:235
#: src/qml/Settings/AppearanceSettingsPage.qml:214
#, kde-format
msgid "Show Fancy Effects"
msgstr "Vis fancy effektar"
#: src/qml/Settings/AppearanceSettingsPage.qml:241
#, kde-format
msgid "Use transparent chat page"
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:254
#: src/qml/Settings/AppearanceSettingsPage.qml:259
#, kde-format
msgid "Transparency"
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:271
#: src/qml/Settings/AppearanceSettingsPage.qml:276
#, kde-format
msgid "Only enabled if the transparent chat page is enabled."
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:284
#: src/qml/Settings/AppearanceSettingsPage.qml:289
#, kde-format
msgid "Show your messages on the right"
msgstr ""
#: src/qml/Settings/AppearanceSettingsPage.qml:297
#: src/qml/Settings/AppearanceSettingsPage.qml:302
#, kde-format
msgid "Show links preview in the chat messages"
msgstr ""
@@ -2716,17 +2545,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 "Color theme"
msgid "Themes"
msgstr ""
#: src/qml/Settings/DevicesPage.qml:14 src/qml/Settings/DevicesPage.qml:26
@@ -2740,42 +2569,32 @@ msgstr "Einingar"
msgid "New device name"
msgstr ""
#: 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
#: src/qml/Settings/DevicesPage.qml:114
#, kde-format
msgid "Edit device name"
msgstr "Rediger einingsnamn"
#: src/qml/Settings/DevicesPage.qml:131
#: src/qml/Settings/DevicesPage.qml:123
#, kde-format
msgid "Verify device"
msgstr ""
#: src/qml/Settings/DevicesPage.qml:146
#: src/qml/Settings/DevicesPage.qml:133
#, kde-format
msgid "Logout device"
msgstr "Logg ut av eininga"
#: src/qml/Settings/DevicesPage.qml:170
#: src/qml/Settings/DevicesPage.qml:153
#, kde-format
msgid "Remove device"
msgstr "Fjern eininga"
#: src/qml/Settings/DevicesPage.qml:174
#: src/qml/Settings/DevicesPage.qml:157
#, kde-format
msgid "Password:"
msgstr "Passord:"
#: src/qml/Settings/DevicesPage.qml:178
#: src/qml/Settings/DevicesPage.qml:161
#, kde-format
msgid "Confirm"
msgstr "Stadfest"
@@ -2801,11 +2620,6 @@ 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
@@ -2818,80 +2632,80 @@ msgstr ""
msgid "General settings"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:31
#: src/qml/Settings/GeneralSettingsPage.qml:30
#, kde-format
msgid "Close to system tray"
msgstr "Minimer til systemtrauet"
#: src/qml/Settings/GeneralSettingsPage.qml:45
#: src/qml/Settings/GeneralSettingsPage.qml:44
#, kde-format
msgid "Minimize to system tray on startup"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:59
#: src/qml/Settings/GeneralSettingsPage.qml:58
#, kde-format
msgid "Automatically hide/unhide the room information when resizing the window"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:77
#: src/qml/Settings/GeneralSettingsPage.qml:76
#, kde-format
msgid "Timeline Events"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:82
#: src/qml/Settings/GeneralSettingsPage.qml:81
#, kde-format
msgid "Show leave and join events"
msgstr "Vis når personar kjem eller går"
#: src/qml/Settings/GeneralSettingsPage.qml:95
#: src/qml/Settings/GeneralSettingsPage.qml:94
#, kde-format
msgid "Show name change events"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:108
#: src/qml/Settings/GeneralSettingsPage.qml:107
#, kde-format
msgid "Show avatar update events"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:125
#: src/qml/Settings/GeneralSettingsPage.qml:124
#, kde-format
msgid "Rooms and private chats"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:128
#: src/qml/Settings/GeneralSettingsPage.qml:127
#, kde-format
msgid "Separated"
msgstr "Skilde"
#: src/qml/Settings/GeneralSettingsPage.qml:137
#: src/qml/Settings/GeneralSettingsPage.qml:136
#, kde-format
msgid "Intermixed"
msgstr "Blanda"
#: src/qml/Settings/GeneralSettingsPage.qml:154
#: src/qml/Settings/GeneralSettingsPage.qml:153
#, kde-format
msgctxt "Chat Editor"
msgid "Editor"
msgid "Editor:"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:158
#: src/qml/Settings/GeneralSettingsPage.qml:157
#, kde-format
msgid "Use s/text/replacement syntax to edit your last message"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:169
#: src/qml/Settings/GeneralSettingsPage.qml:168
#, kde-format
msgid "Send typing notifications"
msgid "Send Typing Notifications"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:186
#: src/qml/Settings/GeneralSettingsPage.qml:185
#, kde-format
msgid "Developer Settings"
msgstr ""
#: src/qml/Settings/GeneralSettingsPage.qml:189
#: src/qml/Settings/GeneralSettingsPage.qml:188
#, kde-format
msgid "Enable developer tools"
msgid "Enable Developer Tools"
msgstr ""
#: src/qml/Settings/GlobalNotificationsPage.qml:14

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -165,8 +165,6 @@ if(ANDROID)
"download"
"smiley"
"tools-check-spelling"
"username-copy"
"edit-copy"
)
else()
target_link_libraries(neochat PUBLIC Qt::Widgets KF5::KIOWidgets)

View File

@@ -139,10 +139,6 @@ 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;

View File

@@ -7,8 +7,7 @@
#include <events/roommessageevent.h>
#include "neochatroom.h"
class NeoChatRoom;
class CustomEmojiModel;
class NeoChatRoom;

View File

@@ -6,7 +6,6 @@
#include "controller.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include "roommanager.h"
#include <events/roommemberevent.h>
#include <events/roompowerlevelsevent.h>
@@ -194,9 +193,8 @@ 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();
}
auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text);
if (targetRoom) {
RoomManager::instance().enterRoom(dynamic_cast<NeoChatRoom *>(targetRoom));
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));
return QString();
}
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text));

View File

@@ -135,11 +135,7 @@ int ChatDocumentHandler::completionStartIndex() const
return 0;
}
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
const long long cursor = cursorPosition();
#else
const auto cursor = cursorPosition();
#endif
const auto &cursor = cursorPosition();
const auto &text = m_room->chatBoxText();
auto start = std::min(cursor, text.size()) - 1;
while (start > -1) {
@@ -203,7 +199,7 @@ void ChatDocumentHandler::setRoom(NeoChatRoom *room)
void ChatDocumentHandler::complete(int index)
{
if (m_completionModel->autoCompletionType() == CompletionModel::User) {
if (m_completionModel->autoCompletionType() == ChatDocumentHandler::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();
@@ -217,7 +213,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() == CompletionModel::Command) {
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Command) {
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
auto text = m_room->chatBoxText();
auto at = text.lastIndexOf(QLatin1Char('/'));
@@ -225,7 +221,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() == CompletionModel::Room) {
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::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);
@@ -238,7 +234,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() == CompletionModel::Emoji) {
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
auto text = m_room->chatBoxText();
auto at = text.lastIndexOf(QLatin1Char(':'));

View File

@@ -4,15 +4,16 @@
#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
{
@@ -27,6 +28,15 @@ 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;
@@ -70,7 +80,9 @@ private:
SyntaxHighlighter *m_highlighter = nullptr;
CompletionModel::AutoCompletionType m_completionType = CompletionModel::None;
AutoCompletionType m_completionType = None;
CompletionModel *m_completionModel = nullptr;
};
Q_DECLARE_METATYPE(ChatDocumentHandler::AutoCompletionType);

View File

@@ -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 == None) {
if (m_autoCompletionType == ChatDocumentHandler::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 == User) {
if (m_autoCompletionType == ChatDocumentHandler::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 == Command) {
if (m_autoCompletionType == ChatDocumentHandler::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 == Room) {
if (m_autoCompletionType == ChatDocumentHandler::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 == Emoji) {
if (m_autoCompletionType == ChatDocumentHandler::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 = User;
m_autoCompletionType = ChatDocumentHandler::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 = Command;
m_autoCompletionType = ChatDocumentHandler::Command;
m_filterModel->invalidate();
} else if (text().startsWith(QLatin1Char('#'))) {
m_autoCompletionType = Room;
m_autoCompletionType = ChatDocumentHandler::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 = None;
m_autoCompletionType = ChatDocumentHandler::None;
}
beginResetModel();
endResetModel();
@@ -171,12 +171,12 @@ void CompletionModel::setRoom(NeoChatRoom *room)
Q_EMIT roomChanged();
}
CompletionModel::AutoCompletionType CompletionModel::autoCompletionType() const
ChatDocumentHandler::AutoCompletionType CompletionModel::autoCompletionType() const
{
return m_autoCompletionType;
}
void CompletionModel::setAutoCompletionType(AutoCompletionType autoCompletionType)
void CompletionModel::setAutoCompletionType(ChatDocumentHandler::AutoCompletionType autoCompletionType)
{
m_autoCompletionType = autoCompletionType;
Q_EMIT autoCompletionTypeChanged();

View File

@@ -7,7 +7,7 @@
#include <KConcatenateRowsProxyModel>
#include "roomlistmodel.h"
#include "chatdocumenthandler.h"
class CompletionProxyModel;
class UserListModel;
@@ -19,19 +19,10 @@ 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(AutoCompletionType autoCompletionType READ autoCompletionType NOTIFY autoCompletionTypeChanged);
Q_PROPERTY(ChatDocumentHandler::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,
@@ -56,7 +47,7 @@ public:
RoomListModel *roomListModel() const;
void setRoomListModel(RoomListModel *roomListModel);
AutoCompletionType autoCompletionType() const;
ChatDocumentHandler::AutoCompletionType autoCompletionType() const;
Q_SIGNALS:
void textChanged();
@@ -69,12 +60,11 @@ private:
QString m_fullText;
CompletionProxyModel *m_filterModel;
NeoChatRoom *m_room = nullptr;
AutoCompletionType m_autoCompletionType = None;
ChatDocumentHandler::AutoCompletionType m_autoCompletionType = ChatDocumentHandler::None;
void setAutoCompletionType(AutoCompletionType autoCompletionType);
void setAutoCompletionType(ChatDocumentHandler::AutoCompletionType autoCompletionType);
UserListModel *m_userListModel;
RoomListModel *m_roomListModel;
KConcatenateRowsProxyModel *m_emojiModel;
};
Q_DECLARE_METATYPE(CompletionModel::AutoCompletionType);

View File

@@ -18,11 +18,7 @@ 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

View File

@@ -234,6 +234,13 @@ 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()) {
@@ -274,6 +281,7 @@ 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);
@@ -366,7 +374,15 @@ void Controller::invokeLogin()
if (accessTokenLoadingJob->error() == QKeychain::Error::NoError) {
accessToken = accessTokenLoadingJob->binaryData();
} else {
return;
// 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;
}
}
auto connection = new Connection(account.homeserver());
@@ -400,6 +416,21 @@ 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();
@@ -411,6 +442,24 @@ 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:
@@ -435,6 +484,22 @@ 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();
@@ -449,7 +514,7 @@ bool Controller::saveAccessTokenToKeyChain(const AccountSettings &account, const
if (job.error()) {
qWarning() << "Could not save access token to the keychain: " << qPrintable(job.errorString());
return false;
return saveAccessTokenToFile(account, accessToken);
}
return true;
}

View File

@@ -68,6 +68,7 @@ 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;
@@ -110,6 +111,7 @@ 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();

View File

@@ -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.
auto username = m_matrixId.mid(1, m_matrixId.indexOf(":") - 1);
m_connection->loginWithPassword(username, m_password, m_deviceName, QString());
QStringRef username(&m_matrixId, 1, m_matrixId.indexOf(":") - 1);
m_connection->loginWithPassword(username.toString(), m_password, m_deviceName, QString());
}
bool Login::supportsPassword() const

View File

@@ -66,7 +66,6 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[AuthorDisplayNameRole] = "authorDisplayName";
roles[IsNameChangeRole] = "isNameChange";
roles[IsAvatarChangeRole] = "isAvatarChange";
roles[IsRedactedRole] = "isRedacted";
return roles;
}
@@ -895,9 +894,6 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
return false;
}
if (role == IsRedactedRole) {
return evt.isRedacted();
}
return {};
}

View File

@@ -71,7 +71,6 @@ public:
AuthorDisplayNameRole,
IsNameChangeRole,
IsAvatarChangeRole,
IsRedactedRole,
LastRole, // Keep this last
};
Q_ENUM(EventRoles)

View File

@@ -25,10 +25,6 @@ MessageFilterModel::MessageFilterModel(QObject *parent)
beginResetModel();
endResetModel();
});
connect(NeoChatConfig::self(), &NeoChatConfig::ShowDeletedMessagesChanged, this, [this] {
beginResetModel();
endResetModel();
});
}
bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
@@ -43,15 +39,12 @@ 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 auto eventType = index.data(MessageEventModel::EventTypeRole).toInt();
const QString eventType = index.data(MessageEventModel::EventTypeRole).toString();
if (eventType == MessageEventModel::Other) {
return false;

View File

@@ -62,9 +62,6 @@
<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">
@@ -83,10 +80,6 @@
<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>

View File

@@ -17,7 +17,6 @@
#include <qcoro/task.h>
#include <connection.h>
#include <csapi/directory.h>
#include <csapi/pushrules.h>
#include <csapi/redaction.h>
#include <csapi/report_content.h>
@@ -474,6 +473,13 @@ 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;
}
@@ -495,14 +501,18 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
plainBody = e.plainBody();
}
if (prettyPrint) {
if (removeReply) {
plainBody.remove(utils::removeReplyRegex);
}
return Quotient::prettyPrint(plainBody);
}
if (removeReply) {
return plainBody.remove(utils::removeReplyRegex);
plainBody = plainBody.remove(utils::removeReplyRegex);
}
if (prettyPrint) {
plainBody = 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> ");
}
return plainBody;
},
@@ -1325,46 +1335,3 @@ 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);
}
}
});
}

View File

@@ -3,7 +3,6 @@
#pragma once
#include <qobjectdefs.h>
#include <room.h>
#include <QCache>
@@ -202,16 +201,6 @@ 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

View File

@@ -137,9 +137,6 @@ 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()
}
}
@@ -150,10 +147,10 @@ QQC2.ToolBar {
onTextChanged: {
if (!repeatTimer.running && Config.typingNotifications) {
var textExists = text.length > 0
currentRoom.sendTypingNotification(textExists)
textExists ? repeatTimer.start() : repeatTimer.stop()
currentRoom.sendTypingNotification(true)
}
repeatTimer.start()
currentRoom.chatBoxText = text
}
}
@@ -270,7 +267,7 @@ QQC2.ToolBar {
function postMessage() {
actionsHandler.handleMessage();
repeatTimer.stop()
currentRoom.markAllMessagesAsRead();
inputField.clear();
currentRoom.chatBoxReplyId = "";

View File

@@ -293,10 +293,8 @@ QQC2.Popup {
id: saveAsDialog
FileDialog {
fileMode: FileDialog.SaveFile
folder: Config.lastSaveDirectory.length > 0 ? Config.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation)
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
onAccepted: {
Config.lastSaveDirectory = folder
Config.save()
if (!currentFile) {
return;
}

View File

@@ -5,15 +5,23 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
Kirigami.LoadingPlaceholder {
Kirigami.PlaceholderMessage {
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
}
}

View File

@@ -159,15 +159,11 @@ TimelineContainer {
FileDialog {
fileMode: FileDialog.SaveFile
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);
}
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
onAccepted: if (autoOpenFile) {
UrlHelper.copyTo(progressInfo.localPath, file)
} else {
currentRoom.download(eventId, file);
}
}
}

View File

@@ -75,7 +75,7 @@ a{
background: " + Kirigami.Theme.textColor + ";
}
" : "") + "
</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>") : "")
</style>" + 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

View File

@@ -160,15 +160,6 @@ 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

View File

@@ -113,13 +113,11 @@ MessageDelegateContextMenu {
id: saveAsDialog
FileDialog {
fileMode: FileDialog.SaveFile
folder: Config.lastSaveDirectory.length > 0 ? Config.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation)
folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
onAccepted: {
if (!currentFile) {
return;
}
Config.lastSaveDirectory = folder
Config.save()
currentRoom.downloadFile(eventId, currentFile)
}
}

View File

@@ -76,13 +76,6 @@ 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)
}
}
]
@@ -150,7 +143,6 @@ Loader {
QQC2.MenuItem {
text: i18n("Configure Web Shortcuts...")
icon.name: "configure"
visible: !Controller.isFlatpak
onTriggered: webshortcutmodel.configureWebShortcuts()
}
}

View File

@@ -348,7 +348,6 @@ Kirigami.ScrollablePage {
visible: currentRoom && currentRoom.hasUnreadMessages && currentRoom.readMarkerLoaded
action: Kirigami.Action {
onTriggered: {
chatBox.focusInputField();
messageListView.goToEvent(currentRoom.readMarkerEventId)
}
icon.name: "go-up"
@@ -361,7 +360,7 @@ Kirigami.ScrollablePage {
QQC2.RoundButton {
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.bottomMargin: Kirigami.Units.largeSpacing
anchors.bottomMargin: Kirigami.Units.largeSpacing + messageListView.headerItem.height
anchors.rightMargin: Kirigami.Units.largeSpacing
implicitWidth: Kirigami.Units.gridUnit * 2
implicitHeight: Kirigami.Units.gridUnit * 2
@@ -372,7 +371,6 @@ Kirigami.ScrollablePage {
visible: !messageListView.atYEnd
action: Kirigami.Action {
onTriggered: {
chatBox.focusInputField();
goToLastMessage();
currentRoom.markAllMessagesAsRead();
}

View File

@@ -195,7 +195,7 @@ Kirigami.OverlayDrawer {
Layout.preferredWidth: Kirigami.Units.gridUnit * 3.5
Layout.preferredHeight: Kirigami.Units.gridUnit * 3.5
name: room ? room.displayName : ""
name: room ? room.name : i18n("No name")
source: room ? ("image://mxc/" + room.avatarMediaId) : ""
}

View File

@@ -5,9 +5,7 @@
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
@@ -16,202 +14,108 @@ 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 {
MobileForm.FormCard {
Kirigami.FormLayout {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormCardHeader {
title: i18n("Room Information")
}
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
onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
Kirigami.Avatar {
Layout.bottomMargin: Kirigami.Units.largeSpacing
fileDialog.chosen.connect(function(path) {
if (!path) return
name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
room.changeAvatar(path)
})
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.open()
}
fileDialog.chosen.connect(function(path) {
if (!path) return
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)
}
room.changeAvatar(path)
})
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
fileDialog.open()
}
}
}
}
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()
QQC2.TextField {
id: roomNameField
text: room.name
Kirigami.FormData.label: i18n("Room Name:")
enabled: canChangeName
}
delegate: MobileForm.FormTextDelegate {
text: modelData
description: room.canonicalAlias.length > 0 && modelData === room.canonicalAlias ? "Canonical alias" : ""
contentItem.children: [
QQC2.ToolButton {
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
QQC2.TextArea {
id: roomTopicField
Layout.fillWidth: true
text: room.topic
Kirigami.FormData.label: i18n("Room topic:")
enabled: canChangeTopic
}
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
}
}
]
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])
}
}
MobileForm.AbstractFormDelegate {
}
RowLayout {
id: altAlias
Kirigami.FormData.label: i18n("Other Aliases:")
Layout.fillWidth: true
visible: room.altAliases && room.altAliases.length
ColumnLayout {
Layout.fillWidth: true
contentItem : RowLayout {
Kirigami.ActionTextField {
id: aliasAddField
spacing: 0
Layout.fillWidth: true
Repeater {
model: room.altAliases
placeholderText: i18n("#new_alias:server.org")
delegate: RowLayout {
Layout.maximumWidth: parent.width
rightActions: Kirigami.Action {
icon.name: "edit-clear"
visible: aliasAddField.text.length > 0
onTriggered: {
aliasAddField.text = ""
}
QQC2.Label {
text: modelData
}
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
QQC2.ToolButton {
icon.name: ""
onClicked: room.removeLocalAlias(modelData)
}
}
}
@@ -219,33 +123,47 @@ Kirigami.ScrollablePage {
}
}
Kirigami.InlineMessage {
Kirigami.Separator {
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: next.visible || prev.visible
}
QQC2.Control {
id: next
Layout.fillWidth: true
visible: room.predecessorId && room.connection.room(room.predecessorId)
actions: Kirigami.Action {
text: i18n("See older messages…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
root.close();
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()
}
}
}
}
Kirigami.InlineMessage {
QQC2.Control {
id: prev
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)
actions: Kirigami.Action {
text: i18n("See new room…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
root.close();
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()
}
}
}
}
@@ -256,5 +174,27 @@ 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)
}
}
}
}
}
}

View File

@@ -113,19 +113,6 @@ 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()
}
}
}
}

View File

@@ -238,13 +238,13 @@ Kirigami.ApplicationWindow {
text: i18n("Explore rooms")
icon.name: "compass"
onTriggered: pushReplaceLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection})
enabled: pageStack.layers.depth === 1 && Controller.accountCount > 0
enabled: pageStack.layers.currentItem.title !== i18n("Explore Rooms") && 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.depth === 1 && Controller.accountCount > 0
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && 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.depth === 1
enabled: pageStack.layers.currentItem.title !== i18n("Configure NeoChat...")
shortcut: StandardKey.Preferences
},
Kirigami.Action {

View File

@@ -3,6 +3,7 @@
#include "sortfilterroomlistmodel.h"
#include "neochatconfig.h"
#include "roomlistmodel.h"
#include "spacehierarchycache.h"
@@ -14,6 +15,15 @@ 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)