Compare commits
53 Commits
work/thiag
...
work/tobia
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68a917e385 | ||
|
|
39046632aa | ||
|
|
fbb2afdb49 | ||
|
|
aff0402f71 | ||
|
|
cee9058c77 | ||
|
|
3f922b4c90 | ||
|
|
02d2d31cf3 | ||
|
|
240cf6a0ed | ||
|
|
dcd9ee93de | ||
|
|
2a8cd74ab1 | ||
|
|
63bc7055c2 | ||
|
|
1cca9733d6 | ||
|
|
1104da5e2c | ||
|
|
3a9718c09d | ||
|
|
55362c5573 | ||
|
|
0bba2299b3 | ||
|
|
45685af9e9 | ||
|
|
6c416a9338 | ||
|
|
1b0027e1d2 | ||
|
|
2409adf516 | ||
|
|
554801dfe4 | ||
|
|
20c23917e9 | ||
|
|
ef953b7574 | ||
|
|
6b79795229 | ||
|
|
9cb7ec2348 | ||
|
|
437c981d30 | ||
|
|
0334cae4c8 | ||
|
|
24c405d747 | ||
|
|
a3f5962809 | ||
|
|
0deb7495f0 | ||
|
|
d34f89fc4b | ||
|
|
a909ed498f | ||
|
|
16f4e17e8f | ||
|
|
0e9592a96c | ||
|
|
704ee6a53a | ||
|
|
5b9afbce9a | ||
|
|
396cc8e8ef | ||
|
|
bf776b5c06 | ||
|
|
be319f88d3 | ||
|
|
af40d555d4 | ||
|
|
f802dbe686 | ||
|
|
2379e3d83b | ||
|
|
9e90ac0412 | ||
|
|
c27948ca3c | ||
|
|
c3b9d664df | ||
|
|
31ef0a5223 | ||
|
|
14c58acea1 | ||
|
|
5dae20603e | ||
|
|
3f6fa94289 | ||
|
|
117615a8b0 | ||
|
|
4a52773c7d | ||
|
|
edfee495c6 | ||
|
|
7d112df7c6 |
@@ -11,7 +11,6 @@
|
||||
#include <qnamespace.h>
|
||||
|
||||
#include "enums/messagecomponenttype.h"
|
||||
#include "models/customemojimodel.h"
|
||||
#include "neochatconnection.h"
|
||||
|
||||
#include "testutils.h"
|
||||
@@ -77,7 +76,6 @@ void TextHandlerTest::initTestCase()
|
||||
QJsonObject{{"body"_ls, "Test custom emoji"_ls},
|
||||
{"url"_ls, "mxc://example.org/test"_ls},
|
||||
{"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}});
|
||||
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection));
|
||||
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-texthandler-sync.json"));
|
||||
}
|
||||
@@ -535,7 +533,7 @@ void TextHandlerTest::componentOutput_data()
|
||||
QVariantMap{{QStringLiteral("class"), QStringLiteral("html")}}}};
|
||||
QTest::newRow("quote") << QStringLiteral("<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Quote, QStringLiteral("\"blockquote\""), {}}};
|
||||
MessageComponent{MessageComponentType::Quote, QStringLiteral("“blockquote”"), {}}};
|
||||
QTest::newRow("no tag first paragraph") << QStringLiteral("Text\n<p>Text</p>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
<summary xml:lang="eu">Berriketa Matrix-en</summary>
|
||||
<summary xml:lang="fr">Discuter sur Matrix</summary>
|
||||
<summary xml:lang="gl">Charlar en Matrix</summary>
|
||||
<summary xml:lang="hu">Csevegés Matrixon</summary>
|
||||
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
||||
<summary xml:lang="it">Chat su Matrix</summary>
|
||||
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
|
||||
|
||||
@@ -89,16 +89,20 @@ GenericName[zh_CN]=Matrix 客户端
|
||||
GenericName[zh_TW]=Matrix 用戶端
|
||||
Comment=Chat on Matrix
|
||||
Comment[ca]=Xat a Matrix
|
||||
Comment[ca@valencia]=Xat a Matrix
|
||||
Comment[en_GB]=Chat on Matrix
|
||||
Comment[es]=Chat en Matrix
|
||||
Comment[eu]=Berriketa Matrix-en
|
||||
Comment[fr]=Clavarder sur Matrix
|
||||
Comment[gl]=Charle en Matrix
|
||||
Comment[hu]=Csevegés Matrixon
|
||||
Comment[ia]=Conversation en ditecto sur Matrix
|
||||
Comment[it]= su Matrix
|
||||
Comment[ka]=ჩატი Matrix-ზე
|
||||
Comment[nl]=Chat op Matrix
|
||||
Comment[pl]=Rozmawiaj na Matriksie
|
||||
Comment[sl]=Klepet na Matrixu
|
||||
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
||||
Comment[tr]=Matrix Üzerinde Sohbet Et
|
||||
Comment[uk]=Спілкування у Matrix
|
||||
Comment[x-test]=xxChat on Matrixxx
|
||||
|
||||
403
po/ar/neochat.po
403
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neochat\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2024-11-13 00:40+0000\n"
|
||||
"POT-Creation-Date: 2024-11-19 00:40+0000\n"
|
||||
"PO-Revision-Date: 2023-12-12 01:02+0100\n"
|
||||
"Last-Translator: Enol P. <enolp@softastur.org>\n"
|
||||
"Language-Team: Asturian <alministradores@softastur.org>\n"
|
||||
@@ -47,33 +47,33 @@ msgstr ""
|
||||
msgid "Send message"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send an encrypted message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Set an attachment caption…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send a message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:376
|
||||
#: src/chatbar/ChatBar.qml:375
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No stickers"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No emojis"
|
||||
msgstr ""
|
||||
@@ -910,7 +910,7 @@ msgstr ""
|
||||
msgid "Loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Loading.qml:16
|
||||
#: src/login/Loading.qml:17
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Please wait while your messages are loaded from the server. This might take "
|
||||
@@ -934,7 +934,7 @@ msgstr ""
|
||||
msgid "Loading…"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:232
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:249
|
||||
#: src/settings/ThreePIdCard.qml:183
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -976,7 +976,7 @@ msgstr ""
|
||||
msgid "Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:152
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:154
|
||||
#: src/settings/NetworkProxyPage.qml:122
|
||||
#, kde-format
|
||||
msgid "Password"
|
||||
@@ -1030,47 +1030,47 @@ msgstr ""
|
||||
msgid "Username unavailable"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:25
|
||||
#: src/login/WelcomePage.qml:26
|
||||
#, kde-format
|
||||
msgid "Welcome"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:73 src/main.cpp:141
|
||||
#: src/login/WelcomePage.qml:74 src/main.cpp:141
|
||||
#, kde-format
|
||||
msgid "NeoChat"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:81
|
||||
#: src/login/WelcomePage.qml:82
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Continue with an existing account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:115
|
||||
#: src/login/WelcomePage.qml:132
|
||||
#, kde-format
|
||||
msgctxt "As in 'this account is still loading'"
|
||||
msgid "%1 (loading)"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:124
|
||||
#: src/login/WelcomePage.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Log out of this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:153
|
||||
#: src/login/WelcomePage.qml:170
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Log in or Create a New Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:240
|
||||
#: src/login/WelcomePage.qml:257
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Go back"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:252
|
||||
#: src/login/WelcomePage.qml:269
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Settings"
|
||||
@@ -1850,7 +1850,7 @@ msgstr ""
|
||||
msgid "Open NeoChat in this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:110
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:111
|
||||
#: src/qml/HoverActions.qml:123
|
||||
#, kde-format
|
||||
msgid "Reply"
|
||||
@@ -1905,58 +1905,58 @@ msgctxt "@action:button"
|
||||
msgid "Show QR code"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:39 src/qml/UserInfo.qml:46
|
||||
#: src/qml/AccountMenu.qml:40 src/qml/UserInfo.qml:46
|
||||
#, kde-format
|
||||
msgid "Edit this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:44 src/settings/AccountsPage.qml:33
|
||||
#: src/qml/AccountMenu.qml:45 src/settings/AccountsPage.qml:33
|
||||
#: src/settings/AccountsPage.qml:50
|
||||
#, kde-format
|
||||
msgid "Account editor"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:48
|
||||
#: src/qml/AccountMenu.qml:49
|
||||
#, kde-format
|
||||
msgid "Notification settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:55 src/settings/DevicesPage.qml:17
|
||||
#: src/qml/AccountMenu.qml:56 src/settings/DevicesPage.qml:17
|
||||
#: src/settings/NeoChatSettingsView.qml:89
|
||||
#, kde-format
|
||||
msgid "Devices"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:62 src/settings/NeoChatGeneralPage.qml:269
|
||||
#: src/qml/AccountMenu.qml:63 src/settings/NeoChatGeneralPage.qml:269
|
||||
#, kde-format
|
||||
msgid "Open developer tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:68
|
||||
#: src/qml/AccountMenu.qml:69
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Developer Tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:74
|
||||
#: src/qml/AccountMenu.qml:75
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Secret Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:78
|
||||
#: src/qml/AccountMenu.qml:79
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Open Key Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:82
|
||||
#: src/qml/AccountMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Verify this Device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:88 src/settings/AccountsPage.qml:87
|
||||
#: src/qml/AccountMenu.qml:89 src/settings/AccountsPage.qml:88
|
||||
#, kde-format
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
@@ -2007,7 +2007,7 @@ msgid "Attachment:"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AttachmentPane.qml:38 src/qml/HoverActions.qml:106
|
||||
#: src/qml/ImageEditorPage.qml:21 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:20 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#, kde-format
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
@@ -2139,61 +2139,29 @@ msgctxt "@action:button"
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:43 src/qml/ContextMenu.qml:204
|
||||
#: src/qml/ContextMenu.qml:31 src/qml/ContextMenu.qml:209
|
||||
#, kde-format
|
||||
msgid "Mark as Read"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49
|
||||
#: src/qml/ContextMenu.qml:40
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:61
|
||||
#, kde-format
|
||||
msgid "Notification State"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:65
|
||||
#: src/qml/ContextMenu.qml:44
|
||||
#, kde-format
|
||||
msgid "Follow Global Setting"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:76 src/settings/PushNotification.qml:39
|
||||
#: src/qml/ContextMenu.qml:55 src/settings/PushNotification.qml:39
|
||||
#, kde-format
|
||||
msgctxt "As in 'notify for all messages'"
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:87 src/settings/PushNotification.qml:47
|
||||
#: src/qml/ContextMenu.qml:66 src/settings/PushNotification.qml:47
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"As in 'notify when the user is mentioned or the message contains a set "
|
||||
@@ -2201,34 +2169,67 @@ msgctxt ""
|
||||
msgid "@Mentions and Keywords"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:98 src/settings/PushNotification.qml:55
|
||||
#: src/qml/ContextMenu.qml:77 src/settings/PushNotification.qml:55
|
||||
#, kde-format
|
||||
msgctxt "As in 'do not notify for any messages'"
|
||||
msgid "Off"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:111
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:116
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Room Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:121 src/qml/ContextMenu.qml:211
|
||||
#: src/qml/ContextMenu.qml:126 src/qml/ContextMenu.qml:216
|
||||
#, kde-format
|
||||
msgid "Leave Room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Remove from Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Add to Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#: src/qml/ContextMenu.qml:192
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room Settings"
|
||||
@@ -2351,74 +2352,74 @@ msgctxt "@action:button"
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:83
|
||||
#: src/qml/DelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgid "View Source"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:90 src/settings/ThreePIdCard.qml:66
|
||||
#: src/qml/DelegateContextMenu.qml:91 src/settings/ThreePIdCard.qml:66
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:95 src/qml/DelegateContextMenu.qml:100
|
||||
#: src/qml/FileDelegateContextMenu.qml:76
|
||||
#: src/qml/FileDelegateContextMenu.qml:81
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/DelegateContextMenu.qml:101
|
||||
#: src/qml/FileDelegateContextMenu.qml:82
|
||||
#: src/qml/FileDelegateContextMenu.qml:87
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/FileDelegateContextMenu.qml:77
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:78
|
||||
#: src/qml/DelegateContextMenu.qml:98 src/qml/FileDelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove this message'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:120 src/qml/DelegateContextMenu.qml:128
|
||||
#: src/qml/DelegateContextMenu.qml:121 src/qml/DelegateContextMenu.qml:129
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"@action:button 'Report' as in 'Report this event to the administrators'"
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:125
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#: src/qml/DelegateContextMenu.qml:127
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for reporting this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:130
|
||||
#: src/qml/DelegateContextMenu.qml:131
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:140
|
||||
#: src/qml/DelegateContextMenu.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Show User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:188
|
||||
#: src/qml/DelegateContextMenu.qml:204
|
||||
#, kde-format
|
||||
msgid "Search for '%1'"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:210
|
||||
#: src/qml/DelegateContextMenu.qml:226
|
||||
#, kde-format
|
||||
msgid "Configure Web Shortcuts..."
|
||||
msgstr ""
|
||||
@@ -2613,23 +2614,25 @@ msgctxt "@info:label"
|
||||
msgid "No public rooms found"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:46
|
||||
#: src/qml/FileDelegateContextMenu.qml:50
|
||||
#, kde-format
|
||||
msgid "Open Externally"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:53
|
||||
#: src/qml/FileDelegateContextMenu.qml:57
|
||||
#, kde-format
|
||||
msgid "Save As"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Save Image…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:63
|
||||
#: src/qml/MessageDelegateContextMenu.qml:64
|
||||
#: src/qml/FileDelegateContextMenu.qml:66
|
||||
#, kde-format
|
||||
msgid "Copy"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:71
|
||||
#: src/qml/FileDelegateContextMenu.qml:77
|
||||
#, kde-format
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
@@ -2779,55 +2782,55 @@ msgctxt "@info screenreader"
|
||||
msgid "The currently selected link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:36
|
||||
#, kde-format
|
||||
msgctxt "@action:button Undo modification"
|
||||
msgid "Undo"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:44
|
||||
#: src/qml/ImageEditorPage.qml:43
|
||||
#, kde-format
|
||||
msgctxt "@action:button Accept image modification"
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:52
|
||||
#: src/qml/ImageEditorPage.qml:51
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Unable to save file. Check if you have the correct permission to edit the "
|
||||
"cache directory."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124
|
||||
#: src/qml/ImageEditorPage.qml:123
|
||||
#, kde-format
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124 src/qml/ImageEditorPage.qml:140
|
||||
#: src/qml/ImageEditorPage.qml:123 src/qml/ImageEditorPage.qml:139
|
||||
#, kde-format
|
||||
msgctxt "@action:button Crop an image"
|
||||
msgid "Crop"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:145
|
||||
#: src/qml/ImageEditorPage.qml:144
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the left"
|
||||
msgid "Rotate left"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:151
|
||||
#: src/qml/ImageEditorPage.qml:150
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the right"
|
||||
msgid "Rotate right"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:157
|
||||
#: src/qml/ImageEditorPage.qml:156
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image vertically"
|
||||
msgid "Flip"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:163
|
||||
#: src/qml/ImageEditorPage.qml:162
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image horizontally"
|
||||
msgid "Mirror"
|
||||
@@ -3055,7 +3058,7 @@ msgstr ""
|
||||
#: src/qml/MessageDelegateContextMenu.qml:47
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu As in 'Forward this message'"
|
||||
msgid "Forward"
|
||||
msgid "Forward…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:53
|
||||
@@ -3064,9 +3067,16 @@ msgctxt "@title"
|
||||
msgid "Forward Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:67
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Text"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:72
|
||||
#, kde-format
|
||||
msgid "Copy Link"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Message Link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageSourceSheet.qml:46
|
||||
@@ -3161,7 +3171,7 @@ msgctxt "@action:button"
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RecommendedSpaceDialog.qml:61
|
||||
#: src/qml/RecommendedSpaceDialog.qml:63
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Ignore"
|
||||
@@ -3195,18 +3205,18 @@ msgstr ""
|
||||
msgid "Configure room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:111 src/qml/RoomDrawerPage.qml:45
|
||||
#: src/qml/RoomDrawer.qml:114 src/qml/RoomDrawerPage.qml:45
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:160 src/qml/RoomDrawerPage.qml:85
|
||||
#: src/qml/RoomDrawer.qml:163 src/qml/RoomDrawerPage.qml:85
|
||||
#, kde-format
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:165 src/qml/RoomDrawerPage.qml:90
|
||||
#: src/qml/RoomDrawer.qml:168 src/qml/RoomDrawerPage.qml:90
|
||||
#, kde-format
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
@@ -3220,7 +3230,7 @@ msgstr ""
|
||||
#: src/qml/RoomInformation.qml:42
|
||||
#, kde-format
|
||||
msgctxt "@action:title"
|
||||
msgid "Room information"
|
||||
msgid "Room Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:70
|
||||
@@ -3261,6 +3271,12 @@ msgstr ""
|
||||
msgid "Show locations for this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136 src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Leave this space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -3332,7 +3348,7 @@ msgctxt "@action:title"
|
||||
msgid "Room Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomPage.qml:93
|
||||
#: src/qml/RoomPage.qml:92
|
||||
#, kde-format
|
||||
msgid "NeoChat is offline. Please check your network connection."
|
||||
msgstr ""
|
||||
@@ -3570,12 +3586,6 @@ msgctxt "@button"
|
||||
msgid "Invite user to space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@button"
|
||||
msgid "Leave the space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:76 src/qml/SpaceListContextMenu.qml:48
|
||||
#: src/qml/SpaceListContextMenu.qml:130
|
||||
#, kde-format
|
||||
@@ -3629,7 +3639,7 @@ msgid_plural "%2 are typing"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/qml/UnlockSSSSDialog.qml:17
|
||||
#: src/qml/UnlockSSSSDialog.qml:16
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Load your encrypted messages"
|
||||
@@ -3717,129 +3727,129 @@ msgctxt "@title:menu Account details dialog"
|
||||
msgid "Account Details"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Ignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:122
|
||||
#: src/qml/UserDetailDialog.qml:124
|
||||
#, kde-format
|
||||
msgid "Kick this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:126 src/qml/UserDetailDialog.qml:131
|
||||
#: src/qml/UserDetailDialog.qml:128 src/qml/UserDetailDialog.qml:133
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Kick User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:127
|
||||
#: src/qml/UserDetailDialog.qml:129
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for kicking this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:128
|
||||
#: src/qml/UserDetailDialog.qml:130
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Kick' as in 'Kick this user from the room'"
|
||||
msgid "Kick"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:147
|
||||
#: src/qml/UserDetailDialog.qml:149
|
||||
#, kde-format
|
||||
msgid "Invite this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:160
|
||||
#: src/qml/UserDetailDialog.qml:162
|
||||
#, kde-format
|
||||
msgid "Ban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:165 src/qml/UserDetailDialog.qml:170
|
||||
#: src/qml/UserDetailDialog.qml:167 src/qml/UserDetailDialog.qml:172
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Ban User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:166
|
||||
#: src/qml/UserDetailDialog.qml:168
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for banning this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:167
|
||||
#: src/qml/UserDetailDialog.qml:169
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Ban' as in 'Ban this user'"
|
||||
msgid "Ban"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:185
|
||||
#: src/qml/UserDetailDialog.qml:187
|
||||
#, kde-format
|
||||
msgid "Unban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:198
|
||||
#: src/qml/UserDetailDialog.qml:200
|
||||
#, kde-format
|
||||
msgid "Set user power level"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:223
|
||||
#: src/qml/UserDetailDialog.qml:225
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove recent messages by this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:228
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:229
|
||||
#: src/qml/UserDetailDialog.qml:231
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this user's recent messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#: src/qml/UserDetailDialog.qml:232
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove these messages'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:233
|
||||
#: src/qml/UserDetailDialog.qml:235
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgctxt "%1 is the name of the user."
|
||||
msgid "Chat with %1"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgid "Invite to private chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:258
|
||||
#: src/qml/UserDetailDialog.qml:260
|
||||
#, kde-format
|
||||
msgid "Copy link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:91
|
||||
#: src/qml/UserInfo.qml:92
|
||||
#, kde-format
|
||||
msgid "Switch User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:100
|
||||
#: src/qml/UserInfo.qml:101
|
||||
#, kde-format
|
||||
msgid "Open Settings"
|
||||
msgstr ""
|
||||
@@ -4057,7 +4067,7 @@ msgstr ""
|
||||
msgid "Working"
|
||||
msgstr ""
|
||||
|
||||
#: src/roommanager.cpp:146
|
||||
#: src/roommanager.cpp:145
|
||||
#, kde-format
|
||||
msgid "Malformed or empty Matrix id<br />%1 is not a correct Matrix identifier"
|
||||
msgstr ""
|
||||
@@ -4082,126 +4092,126 @@ msgstr ""
|
||||
msgid "Edit Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:61
|
||||
#: src/settings/AccountEditorPage.qml:62
|
||||
#, kde-format
|
||||
msgid "Upload new avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:78
|
||||
#: src/settings/AccountEditorPage.qml:79
|
||||
#, kde-format
|
||||
msgid "Remove current avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:101
|
||||
#: src/settings/AccountEditorPage.qml:102
|
||||
#, kde-format
|
||||
msgid "User Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:106
|
||||
#: src/settings/AccountEditorPage.qml:107
|
||||
#, kde-format
|
||||
msgid "Display Name:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:112
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#, kde-format
|
||||
msgid "Label:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#: src/settings/AccountEditorPage.qml:114
|
||||
#, kde-format
|
||||
msgid "Work"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:118
|
||||
#: src/settings/AccountEditorPage.qml:119
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Show QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:135
|
||||
#: src/settings/AccountEditorPage.qml:191
|
||||
#: src/settings/AccountEditorPage.qml:137
|
||||
#: src/settings/AccountEditorPage.qml:193
|
||||
#: src/settings/EmoticonEditorPage.qml:108 src/settings/RoomGeneralPage.qml:98
|
||||
#, kde-format
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:157
|
||||
#: src/settings/AccountEditorPage.qml:159
|
||||
#, kde-format
|
||||
msgid "Your server doesn't support changing your password"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:164
|
||||
#: src/settings/AccountEditorPage.qml:166
|
||||
#, kde-format
|
||||
msgid "Current Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:171
|
||||
#: src/settings/AccountEditorPage.qml:173
|
||||
#, kde-format
|
||||
msgid "New Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:178
|
||||
#: src/settings/AccountEditorPage.qml:180
|
||||
#, kde-format
|
||||
msgid "Confirm new Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:183
|
||||
#: src/settings/AccountEditorPage.qml:185
|
||||
#, kde-format
|
||||
msgid "Passwords don't match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:198
|
||||
#: src/settings/AccountEditorPage.qml:200
|
||||
#, kde-format
|
||||
msgid "Passwords do not match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:205
|
||||
#: src/settings/AccountEditorPage.qml:207
|
||||
#, kde-format
|
||||
msgid "Email Addresses"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:211
|
||||
#: src/settings/AccountEditorPage.qml:213
|
||||
#, kde-format
|
||||
msgid "Phone Numbers"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:216
|
||||
#: src/settings/AccountEditorPage.qml:218
|
||||
#, kde-format
|
||||
msgid "Identity Server"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:225
|
||||
#: src/settings/AccountEditorPage.qml:227
|
||||
#, kde-format
|
||||
msgid "Server Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:229
|
||||
#: src/settings/AccountEditorPage.qml:231
|
||||
#, kde-format
|
||||
msgid "Homeserver url"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:250
|
||||
#: src/settings/AccountEditorPage.qml:252
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Account Management"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:255
|
||||
#: src/settings/AccountEditorPage.qml:257
|
||||
#, kde-format
|
||||
msgid "Deactivate Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:271
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#, kde-format
|
||||
msgid "Password changed successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#, kde-format
|
||||
msgid "Wrong password entered"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#: src/settings/AccountEditorPage.qml:277
|
||||
#, kde-format
|
||||
msgid "Unknown problem while trying to change password"
|
||||
msgstr ""
|
||||
@@ -4212,7 +4222,7 @@ msgstr ""
|
||||
msgid "Accounts"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountsPage.qml:117
|
||||
#: src/settings/AccountsPage.qml:118
|
||||
#, kde-format
|
||||
msgid "Add Account"
|
||||
msgstr ""
|
||||
@@ -4442,7 +4452,7 @@ msgctxt "@title"
|
||||
msgid "Stickers & Emojis"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ExportKeysDialog.qml:18
|
||||
#: src/settings/ExportKeysDialog.qml:17
|
||||
#: src/settings/NeoChatSecurityPage.qml:107
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
@@ -4591,7 +4601,7 @@ msgctxt "@action:button"
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ImportKeysDialog.qml:22 src/settings/NeoChatSecurityPage.qml:84
|
||||
#: src/settings/ImportKeysDialog.qml:21 src/settings/NeoChatSecurityPage.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Import Keys"
|
||||
@@ -4755,7 +4765,7 @@ msgctxt "@action:button"
|
||||
msgid "Reset all configuration values to their default"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/NeoChatSecurityPage.qml:19
|
||||
#: src/settings/NeoChatSecurityPage.qml:18
|
||||
#: src/settings/NeoChatSettingsView.qml:51
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
|
||||
397
po/az/neochat.po
397
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
383
po/ca/neochat.po
383
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
401
po/cs/neochat.po
401
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
391
po/da/neochat.po
391
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/de/neochat.po
403
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
402
po/el/neochat.po
402
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
405
po/eo/neochat.po
405
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/es/neochat.po
403
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
383
po/eu/neochat.po
383
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
404
po/fi/neochat.po
404
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
405
po/fr/neochat.po
405
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/gl/neochat.po
403
po/gl/neochat.po
File diff suppressed because it is too large
Load Diff
478
po/hu/neochat.po
478
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/ia/neochat.po
403
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/id/neochat.po
407
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
395
po/ie/neochat.po
395
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
405
po/it/neochat.po
405
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
356
po/ja/neochat.po
356
po/ja/neochat.po
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neochat\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2024-11-13 00:40+0000\n"
|
||||
"POT-Creation-Date: 2024-11-19 00:40+0000\n"
|
||||
"PO-Revision-Date: 2020-11-05 23:50-0800\n"
|
||||
"Last-Translator: Japanese KDE translation team <kde-jp@kde.org>\n"
|
||||
"Language-Team: Japanese <kde-jp@kde.org>\n"
|
||||
@@ -44,33 +44,33 @@ msgstr ""
|
||||
msgid "Send message"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send an encrypted message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Set an attachment caption…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send a message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:376
|
||||
#: src/chatbar/ChatBar.qml:375
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No stickers"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No emojis"
|
||||
msgstr ""
|
||||
@@ -906,7 +906,7 @@ msgstr ""
|
||||
msgid "Loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Loading.qml:16
|
||||
#: src/login/Loading.qml:17
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Please wait while your messages are loaded from the server. This might take "
|
||||
@@ -930,7 +930,7 @@ msgstr ""
|
||||
msgid "Loading…"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:232
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:249
|
||||
#: src/settings/ThreePIdCard.qml:183
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -972,7 +972,7 @@ msgstr ""
|
||||
msgid "Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:152
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:154
|
||||
#: src/settings/NetworkProxyPage.qml:122
|
||||
#, kde-format
|
||||
msgid "Password"
|
||||
@@ -1026,47 +1026,47 @@ msgstr ""
|
||||
msgid "Username unavailable"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:25
|
||||
#: src/login/WelcomePage.qml:26
|
||||
#, kde-format
|
||||
msgid "Welcome"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:73 src/main.cpp:141
|
||||
#: src/login/WelcomePage.qml:74 src/main.cpp:141
|
||||
#, kde-format
|
||||
msgid "NeoChat"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:81
|
||||
#: src/login/WelcomePage.qml:82
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Continue with an existing account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:115
|
||||
#: src/login/WelcomePage.qml:132
|
||||
#, kde-format
|
||||
msgctxt "As in 'this account is still loading'"
|
||||
msgid "%1 (loading)"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:124
|
||||
#: src/login/WelcomePage.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Log out of this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:153
|
||||
#: src/login/WelcomePage.qml:170
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Log in or Create a New Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:240
|
||||
#: src/login/WelcomePage.qml:257
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Go back"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:252
|
||||
#: src/login/WelcomePage.qml:269
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Settings"
|
||||
@@ -1843,7 +1843,7 @@ msgstr ""
|
||||
msgid "Open NeoChat in this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:110
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:111
|
||||
#: src/qml/HoverActions.qml:123
|
||||
#, kde-format
|
||||
msgid "Reply"
|
||||
@@ -1898,58 +1898,58 @@ msgctxt "@action:button"
|
||||
msgid "Show QR code"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:39 src/qml/UserInfo.qml:46
|
||||
#: src/qml/AccountMenu.qml:40 src/qml/UserInfo.qml:46
|
||||
#, kde-format
|
||||
msgid "Edit this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:44 src/settings/AccountsPage.qml:33
|
||||
#: src/qml/AccountMenu.qml:45 src/settings/AccountsPage.qml:33
|
||||
#: src/settings/AccountsPage.qml:50
|
||||
#, kde-format
|
||||
msgid "Account editor"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:48
|
||||
#: src/qml/AccountMenu.qml:49
|
||||
#, kde-format
|
||||
msgid "Notification settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:55 src/settings/DevicesPage.qml:17
|
||||
#: src/qml/AccountMenu.qml:56 src/settings/DevicesPage.qml:17
|
||||
#: src/settings/NeoChatSettingsView.qml:89
|
||||
#, kde-format
|
||||
msgid "Devices"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:62 src/settings/NeoChatGeneralPage.qml:269
|
||||
#: src/qml/AccountMenu.qml:63 src/settings/NeoChatGeneralPage.qml:269
|
||||
#, kde-format
|
||||
msgid "Open developer tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:68
|
||||
#: src/qml/AccountMenu.qml:69
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Developer Tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:74
|
||||
#: src/qml/AccountMenu.qml:75
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Secret Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:78
|
||||
#: src/qml/AccountMenu.qml:79
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Open Key Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:82
|
||||
#: src/qml/AccountMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Verify this Device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:88 src/settings/AccountsPage.qml:87
|
||||
#: src/qml/AccountMenu.qml:89 src/settings/AccountsPage.qml:88
|
||||
#, kde-format
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
@@ -2000,7 +2000,7 @@ msgid "Attachment:"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AttachmentPane.qml:38 src/qml/HoverActions.qml:106
|
||||
#: src/qml/ImageEditorPage.qml:21 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:20 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#, kde-format
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
@@ -2132,61 +2132,29 @@ msgctxt "@action:button"
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:43 src/qml/ContextMenu.qml:204
|
||||
#: src/qml/ContextMenu.qml:31 src/qml/ContextMenu.qml:209
|
||||
#, kde-format
|
||||
msgid "Mark as Read"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49
|
||||
#: src/qml/ContextMenu.qml:40
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:61
|
||||
#, kde-format
|
||||
msgid "Notification State"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:65
|
||||
#: src/qml/ContextMenu.qml:44
|
||||
#, kde-format
|
||||
msgid "Follow Global Setting"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:76 src/settings/PushNotification.qml:39
|
||||
#: src/qml/ContextMenu.qml:55 src/settings/PushNotification.qml:39
|
||||
#, kde-format
|
||||
msgctxt "As in 'notify for all messages'"
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:87 src/settings/PushNotification.qml:47
|
||||
#: src/qml/ContextMenu.qml:66 src/settings/PushNotification.qml:47
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"As in 'notify when the user is mentioned or the message contains a set "
|
||||
@@ -2194,34 +2162,67 @@ msgctxt ""
|
||||
msgid "@Mentions and Keywords"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:98 src/settings/PushNotification.qml:55
|
||||
#: src/qml/ContextMenu.qml:77 src/settings/PushNotification.qml:55
|
||||
#, kde-format
|
||||
msgctxt "As in 'do not notify for any messages'"
|
||||
msgid "Off"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:111
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:116
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Room Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:121 src/qml/ContextMenu.qml:211
|
||||
#: src/qml/ContextMenu.qml:126 src/qml/ContextMenu.qml:216
|
||||
#, kde-format
|
||||
msgid "Leave Room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Remove from Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Add to Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#: src/qml/ContextMenu.qml:192
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room Settings"
|
||||
@@ -2344,74 +2345,74 @@ msgctxt "@action:button"
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:83
|
||||
#: src/qml/DelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgid "View Source"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:90 src/settings/ThreePIdCard.qml:66
|
||||
#: src/qml/DelegateContextMenu.qml:91 src/settings/ThreePIdCard.qml:66
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:95 src/qml/DelegateContextMenu.qml:100
|
||||
#: src/qml/FileDelegateContextMenu.qml:76
|
||||
#: src/qml/FileDelegateContextMenu.qml:81
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/DelegateContextMenu.qml:101
|
||||
#: src/qml/FileDelegateContextMenu.qml:82
|
||||
#: src/qml/FileDelegateContextMenu.qml:87
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/FileDelegateContextMenu.qml:77
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:78
|
||||
#: src/qml/DelegateContextMenu.qml:98 src/qml/FileDelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove this message'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:120 src/qml/DelegateContextMenu.qml:128
|
||||
#: src/qml/DelegateContextMenu.qml:121 src/qml/DelegateContextMenu.qml:129
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"@action:button 'Report' as in 'Report this event to the administrators'"
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:125
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#: src/qml/DelegateContextMenu.qml:127
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for reporting this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:130
|
||||
#: src/qml/DelegateContextMenu.qml:131
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:140
|
||||
#: src/qml/DelegateContextMenu.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Show User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:188
|
||||
#: src/qml/DelegateContextMenu.qml:204
|
||||
#, kde-format
|
||||
msgid "Search for '%1'"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:210
|
||||
#: src/qml/DelegateContextMenu.qml:226
|
||||
#, kde-format
|
||||
msgid "Configure Web Shortcuts..."
|
||||
msgstr ""
|
||||
@@ -2606,23 +2607,25 @@ msgctxt "@info:label"
|
||||
msgid "No public rooms found"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:46
|
||||
#: src/qml/FileDelegateContextMenu.qml:50
|
||||
#, kde-format
|
||||
msgid "Open Externally"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:53
|
||||
#: src/qml/FileDelegateContextMenu.qml:57
|
||||
#, kde-format
|
||||
msgid "Save As"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Save Image…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:63
|
||||
#: src/qml/MessageDelegateContextMenu.qml:64
|
||||
#: src/qml/FileDelegateContextMenu.qml:66
|
||||
#, kde-format
|
||||
msgid "Copy"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:71
|
||||
#: src/qml/FileDelegateContextMenu.qml:77
|
||||
#, kde-format
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
@@ -2772,55 +2775,55 @@ msgctxt "@info screenreader"
|
||||
msgid "The currently selected link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:36
|
||||
#, kde-format
|
||||
msgctxt "@action:button Undo modification"
|
||||
msgid "Undo"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:44
|
||||
#: src/qml/ImageEditorPage.qml:43
|
||||
#, kde-format
|
||||
msgctxt "@action:button Accept image modification"
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:52
|
||||
#: src/qml/ImageEditorPage.qml:51
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Unable to save file. Check if you have the correct permission to edit the "
|
||||
"cache directory."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124
|
||||
#: src/qml/ImageEditorPage.qml:123
|
||||
#, kde-format
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124 src/qml/ImageEditorPage.qml:140
|
||||
#: src/qml/ImageEditorPage.qml:123 src/qml/ImageEditorPage.qml:139
|
||||
#, kde-format
|
||||
msgctxt "@action:button Crop an image"
|
||||
msgid "Crop"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:145
|
||||
#: src/qml/ImageEditorPage.qml:144
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the left"
|
||||
msgid "Rotate left"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:151
|
||||
#: src/qml/ImageEditorPage.qml:150
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the right"
|
||||
msgid "Rotate right"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:157
|
||||
#: src/qml/ImageEditorPage.qml:156
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image vertically"
|
||||
msgid "Flip"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:163
|
||||
#: src/qml/ImageEditorPage.qml:162
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image horizontally"
|
||||
msgid "Mirror"
|
||||
@@ -3048,7 +3051,7 @@ msgstr ""
|
||||
#: src/qml/MessageDelegateContextMenu.qml:47
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu As in 'Forward this message'"
|
||||
msgid "Forward"
|
||||
msgid "Forward…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:53
|
||||
@@ -3057,9 +3060,16 @@ msgctxt "@title"
|
||||
msgid "Forward Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:67
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Text"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:72
|
||||
#, kde-format
|
||||
msgid "Copy Link"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Message Link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageSourceSheet.qml:46
|
||||
@@ -3154,7 +3164,7 @@ msgctxt "@action:button"
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RecommendedSpaceDialog.qml:61
|
||||
#: src/qml/RecommendedSpaceDialog.qml:63
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Ignore"
|
||||
@@ -3188,18 +3198,18 @@ msgstr ""
|
||||
msgid "Configure room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:111 src/qml/RoomDrawerPage.qml:45
|
||||
#: src/qml/RoomDrawer.qml:114 src/qml/RoomDrawerPage.qml:45
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:160 src/qml/RoomDrawerPage.qml:85
|
||||
#: src/qml/RoomDrawer.qml:163 src/qml/RoomDrawerPage.qml:85
|
||||
#, kde-format
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:165 src/qml/RoomDrawerPage.qml:90
|
||||
#: src/qml/RoomDrawer.qml:168 src/qml/RoomDrawerPage.qml:90
|
||||
#, kde-format
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
@@ -3213,7 +3223,7 @@ msgstr ""
|
||||
#: src/qml/RoomInformation.qml:42
|
||||
#, kde-format
|
||||
msgctxt "@action:title"
|
||||
msgid "Room information"
|
||||
msgid "Room Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:70
|
||||
@@ -3254,6 +3264,12 @@ msgstr ""
|
||||
msgid "Show locations for this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136 src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Leave this space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -3324,7 +3340,7 @@ msgctxt "@action:title"
|
||||
msgid "Room Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomPage.qml:93
|
||||
#: src/qml/RoomPage.qml:92
|
||||
#, kde-format
|
||||
msgid "NeoChat is offline. Please check your network connection."
|
||||
msgstr ""
|
||||
@@ -3560,12 +3576,6 @@ msgctxt "@button"
|
||||
msgid "Invite user to space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@button"
|
||||
msgid "Leave the space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:76 src/qml/SpaceListContextMenu.qml:48
|
||||
#: src/qml/SpaceListContextMenu.qml:130
|
||||
#, kde-format
|
||||
@@ -3618,7 +3628,7 @@ msgid "%2 is typing"
|
||||
msgid_plural "%2 are typing"
|
||||
msgstr[0] ""
|
||||
|
||||
#: src/qml/UnlockSSSSDialog.qml:17
|
||||
#: src/qml/UnlockSSSSDialog.qml:16
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Load your encrypted messages"
|
||||
@@ -3706,129 +3716,129 @@ msgctxt "@title:menu Account details dialog"
|
||||
msgid "Account Details"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Ignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:122
|
||||
#: src/qml/UserDetailDialog.qml:124
|
||||
#, kde-format
|
||||
msgid "Kick this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:126 src/qml/UserDetailDialog.qml:131
|
||||
#: src/qml/UserDetailDialog.qml:128 src/qml/UserDetailDialog.qml:133
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Kick User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:127
|
||||
#: src/qml/UserDetailDialog.qml:129
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for kicking this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:128
|
||||
#: src/qml/UserDetailDialog.qml:130
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Kick' as in 'Kick this user from the room'"
|
||||
msgid "Kick"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:147
|
||||
#: src/qml/UserDetailDialog.qml:149
|
||||
#, kde-format
|
||||
msgid "Invite this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:160
|
||||
#: src/qml/UserDetailDialog.qml:162
|
||||
#, kde-format
|
||||
msgid "Ban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:165 src/qml/UserDetailDialog.qml:170
|
||||
#: src/qml/UserDetailDialog.qml:167 src/qml/UserDetailDialog.qml:172
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Ban User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:166
|
||||
#: src/qml/UserDetailDialog.qml:168
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for banning this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:167
|
||||
#: src/qml/UserDetailDialog.qml:169
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Ban' as in 'Ban this user'"
|
||||
msgid "Ban"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:185
|
||||
#: src/qml/UserDetailDialog.qml:187
|
||||
#, kde-format
|
||||
msgid "Unban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:198
|
||||
#: src/qml/UserDetailDialog.qml:200
|
||||
#, kde-format
|
||||
msgid "Set user power level"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:223
|
||||
#: src/qml/UserDetailDialog.qml:225
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove recent messages by this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:228
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:229
|
||||
#: src/qml/UserDetailDialog.qml:231
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this user's recent messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#: src/qml/UserDetailDialog.qml:232
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove these messages'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:233
|
||||
#: src/qml/UserDetailDialog.qml:235
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgctxt "%1 is the name of the user."
|
||||
msgid "Chat with %1"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgid "Invite to private chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:258
|
||||
#: src/qml/UserDetailDialog.qml:260
|
||||
#, kde-format
|
||||
msgid "Copy link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:91
|
||||
#: src/qml/UserInfo.qml:92
|
||||
#, kde-format
|
||||
msgid "Switch User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:100
|
||||
#: src/qml/UserInfo.qml:101
|
||||
#, kde-format
|
||||
msgid "Open Settings"
|
||||
msgstr ""
|
||||
@@ -4046,7 +4056,7 @@ msgstr ""
|
||||
msgid "Working"
|
||||
msgstr ""
|
||||
|
||||
#: src/roommanager.cpp:146
|
||||
#: src/roommanager.cpp:145
|
||||
#, kde-format
|
||||
msgid "Malformed or empty Matrix id<br />%1 is not a correct Matrix identifier"
|
||||
msgstr ""
|
||||
@@ -4071,126 +4081,126 @@ msgstr ""
|
||||
msgid "Edit Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:61
|
||||
#: src/settings/AccountEditorPage.qml:62
|
||||
#, kde-format
|
||||
msgid "Upload new avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:78
|
||||
#: src/settings/AccountEditorPage.qml:79
|
||||
#, kde-format
|
||||
msgid "Remove current avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:101
|
||||
#: src/settings/AccountEditorPage.qml:102
|
||||
#, kde-format
|
||||
msgid "User Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:106
|
||||
#: src/settings/AccountEditorPage.qml:107
|
||||
#, kde-format
|
||||
msgid "Display Name:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:112
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#, kde-format
|
||||
msgid "Label:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#: src/settings/AccountEditorPage.qml:114
|
||||
#, kde-format
|
||||
msgid "Work"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:118
|
||||
#: src/settings/AccountEditorPage.qml:119
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Show QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:135
|
||||
#: src/settings/AccountEditorPage.qml:191
|
||||
#: src/settings/AccountEditorPage.qml:137
|
||||
#: src/settings/AccountEditorPage.qml:193
|
||||
#: src/settings/EmoticonEditorPage.qml:108 src/settings/RoomGeneralPage.qml:98
|
||||
#, kde-format
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:157
|
||||
#: src/settings/AccountEditorPage.qml:159
|
||||
#, kde-format
|
||||
msgid "Your server doesn't support changing your password"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:164
|
||||
#: src/settings/AccountEditorPage.qml:166
|
||||
#, kde-format
|
||||
msgid "Current Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:171
|
||||
#: src/settings/AccountEditorPage.qml:173
|
||||
#, kde-format
|
||||
msgid "New Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:178
|
||||
#: src/settings/AccountEditorPage.qml:180
|
||||
#, kde-format
|
||||
msgid "Confirm new Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:183
|
||||
#: src/settings/AccountEditorPage.qml:185
|
||||
#, kde-format
|
||||
msgid "Passwords don't match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:198
|
||||
#: src/settings/AccountEditorPage.qml:200
|
||||
#, kde-format
|
||||
msgid "Passwords do not match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:205
|
||||
#: src/settings/AccountEditorPage.qml:207
|
||||
#, kde-format
|
||||
msgid "Email Addresses"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:211
|
||||
#: src/settings/AccountEditorPage.qml:213
|
||||
#, kde-format
|
||||
msgid "Phone Numbers"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:216
|
||||
#: src/settings/AccountEditorPage.qml:218
|
||||
#, kde-format
|
||||
msgid "Identity Server"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:225
|
||||
#: src/settings/AccountEditorPage.qml:227
|
||||
#, kde-format
|
||||
msgid "Server Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:229
|
||||
#: src/settings/AccountEditorPage.qml:231
|
||||
#, kde-format
|
||||
msgid "Homeserver url"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:250
|
||||
#: src/settings/AccountEditorPage.qml:252
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Account Management"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:255
|
||||
#: src/settings/AccountEditorPage.qml:257
|
||||
#, kde-format
|
||||
msgid "Deactivate Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:271
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#, kde-format
|
||||
msgid "Password changed successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#, kde-format
|
||||
msgid "Wrong password entered"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#: src/settings/AccountEditorPage.qml:277
|
||||
#, kde-format
|
||||
msgid "Unknown problem while trying to change password"
|
||||
msgstr ""
|
||||
@@ -4201,7 +4211,7 @@ msgstr ""
|
||||
msgid "Accounts"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountsPage.qml:117
|
||||
#: src/settings/AccountsPage.qml:118
|
||||
#, kde-format
|
||||
msgid "Add Account"
|
||||
msgstr ""
|
||||
@@ -4431,7 +4441,7 @@ msgctxt "@title"
|
||||
msgid "Stickers & Emojis"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ExportKeysDialog.qml:18
|
||||
#: src/settings/ExportKeysDialog.qml:17
|
||||
#: src/settings/NeoChatSecurityPage.qml:107
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
@@ -4580,7 +4590,7 @@ msgctxt "@action:button"
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ImportKeysDialog.qml:22 src/settings/NeoChatSecurityPage.qml:84
|
||||
#: src/settings/ImportKeysDialog.qml:21 src/settings/NeoChatSecurityPage.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Import Keys"
|
||||
@@ -4744,7 +4754,7 @@ msgctxt "@action:button"
|
||||
msgid "Reset all configuration values to their default"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/NeoChatSecurityPage.qml:19
|
||||
#: src/settings/NeoChatSecurityPage.qml:18
|
||||
#: src/settings/NeoChatSettingsView.qml:51
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
|
||||
383
po/ka/neochat.po
383
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
406
po/ko/neochat.po
406
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
356
po/lt/neochat.po
356
po/lt/neochat.po
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neochat\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2024-11-13 00:40+0000\n"
|
||||
"POT-Creation-Date: 2024-11-19 00:40+0000\n"
|
||||
"PO-Revision-Date: 2023-02-25 01:00+0000\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
@@ -48,33 +48,33 @@ msgstr ""
|
||||
msgid "Send message"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send an encrypted message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Set an attachment caption…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send a message…"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/ChatBar.qml:376
|
||||
#: src/chatbar/ChatBar.qml:375
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No stickers"
|
||||
msgstr ""
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No emojis"
|
||||
msgstr ""
|
||||
@@ -913,7 +913,7 @@ msgstr ""
|
||||
msgid "Loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Loading.qml:16
|
||||
#: src/login/Loading.qml:17
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Please wait while your messages are loaded from the server. This might take "
|
||||
@@ -937,7 +937,7 @@ msgstr ""
|
||||
msgid "Loading…"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:232
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:249
|
||||
#: src/settings/ThreePIdCard.qml:183
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -979,7 +979,7 @@ msgstr ""
|
||||
msgid "Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:152
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:154
|
||||
#: src/settings/NetworkProxyPage.qml:122
|
||||
#, kde-format
|
||||
msgid "Password"
|
||||
@@ -1033,47 +1033,47 @@ msgstr ""
|
||||
msgid "Username unavailable"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:25
|
||||
#: src/login/WelcomePage.qml:26
|
||||
#, kde-format
|
||||
msgid "Welcome"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:73 src/main.cpp:141
|
||||
#: src/login/WelcomePage.qml:74 src/main.cpp:141
|
||||
#, kde-format
|
||||
msgid "NeoChat"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:81
|
||||
#: src/login/WelcomePage.qml:82
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Continue with an existing account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:115
|
||||
#: src/login/WelcomePage.qml:132
|
||||
#, kde-format
|
||||
msgctxt "As in 'this account is still loading'"
|
||||
msgid "%1 (loading)"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:124
|
||||
#: src/login/WelcomePage.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Log out of this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:153
|
||||
#: src/login/WelcomePage.qml:170
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Log in or Create a New Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:240
|
||||
#: src/login/WelcomePage.qml:257
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Go back"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:252
|
||||
#: src/login/WelcomePage.qml:269
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Settings"
|
||||
@@ -1857,7 +1857,7 @@ msgstr ""
|
||||
msgid "Open NeoChat in this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:110
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:111
|
||||
#: src/qml/HoverActions.qml:123
|
||||
#, kde-format
|
||||
msgid "Reply"
|
||||
@@ -1912,58 +1912,58 @@ msgctxt "@action:button"
|
||||
msgid "Show QR code"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:39 src/qml/UserInfo.qml:46
|
||||
#: src/qml/AccountMenu.qml:40 src/qml/UserInfo.qml:46
|
||||
#, kde-format
|
||||
msgid "Edit this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:44 src/settings/AccountsPage.qml:33
|
||||
#: src/qml/AccountMenu.qml:45 src/settings/AccountsPage.qml:33
|
||||
#: src/settings/AccountsPage.qml:50
|
||||
#, kde-format
|
||||
msgid "Account editor"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:48
|
||||
#: src/qml/AccountMenu.qml:49
|
||||
#, kde-format
|
||||
msgid "Notification settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:55 src/settings/DevicesPage.qml:17
|
||||
#: src/qml/AccountMenu.qml:56 src/settings/DevicesPage.qml:17
|
||||
#: src/settings/NeoChatSettingsView.qml:89
|
||||
#, kde-format
|
||||
msgid "Devices"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:62 src/settings/NeoChatGeneralPage.qml:269
|
||||
#: src/qml/AccountMenu.qml:63 src/settings/NeoChatGeneralPage.qml:269
|
||||
#, kde-format
|
||||
msgid "Open developer tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:68
|
||||
#: src/qml/AccountMenu.qml:69
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Developer Tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:74
|
||||
#: src/qml/AccountMenu.qml:75
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Secret Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:78
|
||||
#: src/qml/AccountMenu.qml:79
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Open Key Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:82
|
||||
#: src/qml/AccountMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Verify this Device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:88 src/settings/AccountsPage.qml:87
|
||||
#: src/qml/AccountMenu.qml:89 src/settings/AccountsPage.qml:88
|
||||
#, kde-format
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
@@ -2014,7 +2014,7 @@ msgid "Attachment:"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AttachmentPane.qml:38 src/qml/HoverActions.qml:106
|
||||
#: src/qml/ImageEditorPage.qml:21 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:20 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#, kde-format
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
@@ -2146,61 +2146,29 @@ msgctxt "@action:button"
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:43 src/qml/ContextMenu.qml:204
|
||||
#: src/qml/ContextMenu.qml:31 src/qml/ContextMenu.qml:209
|
||||
#, kde-format
|
||||
msgid "Mark as Read"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49
|
||||
#: src/qml/ContextMenu.qml:40
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:49 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:61
|
||||
#, kde-format
|
||||
msgid "Notification State"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:65
|
||||
#: src/qml/ContextMenu.qml:44
|
||||
#, kde-format
|
||||
msgid "Follow Global Setting"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:76 src/settings/PushNotification.qml:39
|
||||
#: src/qml/ContextMenu.qml:55 src/settings/PushNotification.qml:39
|
||||
#, kde-format
|
||||
msgctxt "As in 'notify for all messages'"
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:87 src/settings/PushNotification.qml:47
|
||||
#: src/qml/ContextMenu.qml:66 src/settings/PushNotification.qml:47
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"As in 'notify when the user is mentioned or the message contains a set "
|
||||
@@ -2208,34 +2176,67 @@ msgctxt ""
|
||||
msgid "@Mentions and Keywords"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:98 src/settings/PushNotification.qml:55
|
||||
#: src/qml/ContextMenu.qml:77 src/settings/PushNotification.qml:55
|
||||
#, kde-format
|
||||
msgctxt "As in 'do not notify for any messages'"
|
||||
msgid "Off"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:111
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:104 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:116
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Room Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:121 src/qml/ContextMenu.qml:211
|
||||
#: src/qml/ContextMenu.qml:126 src/qml/ContextMenu.qml:216
|
||||
#, kde-format
|
||||
msgid "Leave Room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Remove from Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Add to Favourites"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#: src/qml/ContextMenu.qml:192
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room Settings"
|
||||
@@ -2358,74 +2359,74 @@ msgctxt "@action:button"
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:83
|
||||
#: src/qml/DelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgid "View Source"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:90 src/settings/ThreePIdCard.qml:66
|
||||
#: src/qml/DelegateContextMenu.qml:91 src/settings/ThreePIdCard.qml:66
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:95 src/qml/DelegateContextMenu.qml:100
|
||||
#: src/qml/FileDelegateContextMenu.qml:76
|
||||
#: src/qml/FileDelegateContextMenu.qml:81
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/DelegateContextMenu.qml:101
|
||||
#: src/qml/FileDelegateContextMenu.qml:82
|
||||
#: src/qml/FileDelegateContextMenu.qml:87
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/FileDelegateContextMenu.qml:77
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:78
|
||||
#: src/qml/DelegateContextMenu.qml:98 src/qml/FileDelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove this message'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:120 src/qml/DelegateContextMenu.qml:128
|
||||
#: src/qml/DelegateContextMenu.qml:121 src/qml/DelegateContextMenu.qml:129
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"@action:button 'Report' as in 'Report this event to the administrators'"
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:125
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#: src/qml/DelegateContextMenu.qml:127
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for reporting this message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:130
|
||||
#: src/qml/DelegateContextMenu.qml:131
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Report Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:140
|
||||
#: src/qml/DelegateContextMenu.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Show User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:188
|
||||
#: src/qml/DelegateContextMenu.qml:204
|
||||
#, kde-format
|
||||
msgid "Search for '%1'"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:210
|
||||
#: src/qml/DelegateContextMenu.qml:226
|
||||
#, kde-format
|
||||
msgid "Configure Web Shortcuts..."
|
||||
msgstr ""
|
||||
@@ -2620,23 +2621,25 @@ msgctxt "@info:label"
|
||||
msgid "No public rooms found"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:46
|
||||
#: src/qml/FileDelegateContextMenu.qml:50
|
||||
#, kde-format
|
||||
msgid "Open Externally"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:53
|
||||
#: src/qml/FileDelegateContextMenu.qml:57
|
||||
#, kde-format
|
||||
msgid "Save As"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Save Image…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:63
|
||||
#: src/qml/MessageDelegateContextMenu.qml:64
|
||||
#: src/qml/FileDelegateContextMenu.qml:66
|
||||
#, kde-format
|
||||
msgid "Copy"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:71
|
||||
#: src/qml/FileDelegateContextMenu.qml:77
|
||||
#, kde-format
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
@@ -2786,55 +2789,55 @@ msgctxt "@info screenreader"
|
||||
msgid "The currently selected link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:36
|
||||
#, kde-format
|
||||
msgctxt "@action:button Undo modification"
|
||||
msgid "Undo"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:44
|
||||
#: src/qml/ImageEditorPage.qml:43
|
||||
#, kde-format
|
||||
msgctxt "@action:button Accept image modification"
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:52
|
||||
#: src/qml/ImageEditorPage.qml:51
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Unable to save file. Check if you have the correct permission to edit the "
|
||||
"cache directory."
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124
|
||||
#: src/qml/ImageEditorPage.qml:123
|
||||
#, kde-format
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124 src/qml/ImageEditorPage.qml:140
|
||||
#: src/qml/ImageEditorPage.qml:123 src/qml/ImageEditorPage.qml:139
|
||||
#, kde-format
|
||||
msgctxt "@action:button Crop an image"
|
||||
msgid "Crop"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:145
|
||||
#: src/qml/ImageEditorPage.qml:144
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the left"
|
||||
msgid "Rotate left"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:151
|
||||
#: src/qml/ImageEditorPage.qml:150
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the right"
|
||||
msgid "Rotate right"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:157
|
||||
#: src/qml/ImageEditorPage.qml:156
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image vertically"
|
||||
msgid "Flip"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:163
|
||||
#: src/qml/ImageEditorPage.qml:162
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image horizontally"
|
||||
msgid "Mirror"
|
||||
@@ -3062,7 +3065,7 @@ msgstr ""
|
||||
#: src/qml/MessageDelegateContextMenu.qml:47
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu As in 'Forward this message'"
|
||||
msgid "Forward"
|
||||
msgid "Forward…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:53
|
||||
@@ -3071,9 +3074,16 @@ msgctxt "@title"
|
||||
msgid "Forward Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:67
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Text"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:72
|
||||
#, kde-format
|
||||
msgid "Copy Link"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Message Link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageSourceSheet.qml:46
|
||||
@@ -3168,7 +3178,7 @@ msgctxt "@action:button"
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RecommendedSpaceDialog.qml:61
|
||||
#: src/qml/RecommendedSpaceDialog.qml:63
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Ignore"
|
||||
@@ -3202,18 +3212,18 @@ msgstr ""
|
||||
msgid "Configure room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:111 src/qml/RoomDrawerPage.qml:45
|
||||
#: src/qml/RoomDrawer.qml:114 src/qml/RoomDrawerPage.qml:45
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:160 src/qml/RoomDrawerPage.qml:85
|
||||
#: src/qml/RoomDrawer.qml:163 src/qml/RoomDrawerPage.qml:85
|
||||
#, kde-format
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomDrawer.qml:165 src/qml/RoomDrawerPage.qml:90
|
||||
#: src/qml/RoomDrawer.qml:168 src/qml/RoomDrawerPage.qml:90
|
||||
#, kde-format
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
@@ -3227,7 +3237,7 @@ msgstr ""
|
||||
#: src/qml/RoomInformation.qml:42
|
||||
#, kde-format
|
||||
msgctxt "@action:title"
|
||||
msgid "Room information"
|
||||
msgid "Room Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:70
|
||||
@@ -3268,6 +3278,12 @@ msgstr ""
|
||||
msgid "Show locations for this room"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136 src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Leave this space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -3341,7 +3357,7 @@ msgctxt "@action:title"
|
||||
msgid "Room Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomPage.qml:93
|
||||
#: src/qml/RoomPage.qml:92
|
||||
#, kde-format
|
||||
msgid "NeoChat is offline. Please check your network connection."
|
||||
msgstr ""
|
||||
@@ -3583,12 +3599,6 @@ msgctxt "@button"
|
||||
msgid "Invite user to space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@button"
|
||||
msgid "Leave the space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:76 src/qml/SpaceListContextMenu.qml:48
|
||||
#: src/qml/SpaceListContextMenu.qml:130
|
||||
#, kde-format
|
||||
@@ -3643,7 +3653,7 @@ msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: src/qml/UnlockSSSSDialog.qml:17
|
||||
#: src/qml/UnlockSSSSDialog.qml:16
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Load your encrypted messages"
|
||||
@@ -3731,129 +3741,129 @@ msgctxt "@title:menu Account details dialog"
|
||||
msgid "Account Details"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Ignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:122
|
||||
#: src/qml/UserDetailDialog.qml:124
|
||||
#, kde-format
|
||||
msgid "Kick this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:126 src/qml/UserDetailDialog.qml:131
|
||||
#: src/qml/UserDetailDialog.qml:128 src/qml/UserDetailDialog.qml:133
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Kick User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:127
|
||||
#: src/qml/UserDetailDialog.qml:129
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for kicking this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:128
|
||||
#: src/qml/UserDetailDialog.qml:130
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Kick' as in 'Kick this user from the room'"
|
||||
msgid "Kick"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:147
|
||||
#: src/qml/UserDetailDialog.qml:149
|
||||
#, kde-format
|
||||
msgid "Invite this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:160
|
||||
#: src/qml/UserDetailDialog.qml:162
|
||||
#, kde-format
|
||||
msgid "Ban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:165 src/qml/UserDetailDialog.qml:170
|
||||
#: src/qml/UserDetailDialog.qml:167 src/qml/UserDetailDialog.qml:172
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Ban User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:166
|
||||
#: src/qml/UserDetailDialog.qml:168
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for banning this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:167
|
||||
#: src/qml/UserDetailDialog.qml:169
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Ban' as in 'Ban this user'"
|
||||
msgid "Ban"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:185
|
||||
#: src/qml/UserDetailDialog.qml:187
|
||||
#, kde-format
|
||||
msgid "Unban this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:198
|
||||
#: src/qml/UserDetailDialog.qml:200
|
||||
#, kde-format
|
||||
msgid "Set user power level"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:223
|
||||
#: src/qml/UserDetailDialog.qml:225
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove recent messages by this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:228
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:229
|
||||
#: src/qml/UserDetailDialog.qml:231
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this user's recent messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#: src/qml/UserDetailDialog.qml:232
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove these messages'"
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:233
|
||||
#: src/qml/UserDetailDialog.qml:235
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Remove Messages"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgctxt "%1 is the name of the user."
|
||||
msgid "Chat with %1"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgid "Invite to private chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:258
|
||||
#: src/qml/UserDetailDialog.qml:260
|
||||
#, kde-format
|
||||
msgid "Copy link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:91
|
||||
#: src/qml/UserInfo.qml:92
|
||||
#, kde-format
|
||||
msgid "Switch User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserInfo.qml:100
|
||||
#: src/qml/UserInfo.qml:101
|
||||
#, kde-format
|
||||
msgid "Open Settings"
|
||||
msgstr ""
|
||||
@@ -4071,7 +4081,7 @@ msgstr ""
|
||||
msgid "Working"
|
||||
msgstr ""
|
||||
|
||||
#: src/roommanager.cpp:146
|
||||
#: src/roommanager.cpp:145
|
||||
#, kde-format
|
||||
msgid "Malformed or empty Matrix id<br />%1 is not a correct Matrix identifier"
|
||||
msgstr ""
|
||||
@@ -4096,126 +4106,126 @@ msgstr ""
|
||||
msgid "Edit Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:61
|
||||
#: src/settings/AccountEditorPage.qml:62
|
||||
#, kde-format
|
||||
msgid "Upload new avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:78
|
||||
#: src/settings/AccountEditorPage.qml:79
|
||||
#, kde-format
|
||||
msgid "Remove current avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:101
|
||||
#: src/settings/AccountEditorPage.qml:102
|
||||
#, kde-format
|
||||
msgid "User Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:106
|
||||
#: src/settings/AccountEditorPage.qml:107
|
||||
#, kde-format
|
||||
msgid "Display Name:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:112
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#, kde-format
|
||||
msgid "Label:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#: src/settings/AccountEditorPage.qml:114
|
||||
#, kde-format
|
||||
msgid "Work"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:118
|
||||
#: src/settings/AccountEditorPage.qml:119
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Show QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:135
|
||||
#: src/settings/AccountEditorPage.qml:191
|
||||
#: src/settings/AccountEditorPage.qml:137
|
||||
#: src/settings/AccountEditorPage.qml:193
|
||||
#: src/settings/EmoticonEditorPage.qml:108 src/settings/RoomGeneralPage.qml:98
|
||||
#, kde-format
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:157
|
||||
#: src/settings/AccountEditorPage.qml:159
|
||||
#, kde-format
|
||||
msgid "Your server doesn't support changing your password"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:164
|
||||
#: src/settings/AccountEditorPage.qml:166
|
||||
#, kde-format
|
||||
msgid "Current Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:171
|
||||
#: src/settings/AccountEditorPage.qml:173
|
||||
#, kde-format
|
||||
msgid "New Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:178
|
||||
#: src/settings/AccountEditorPage.qml:180
|
||||
#, kde-format
|
||||
msgid "Confirm new Password:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:183
|
||||
#: src/settings/AccountEditorPage.qml:185
|
||||
#, kde-format
|
||||
msgid "Passwords don't match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:198
|
||||
#: src/settings/AccountEditorPage.qml:200
|
||||
#, kde-format
|
||||
msgid "Passwords do not match"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:205
|
||||
#: src/settings/AccountEditorPage.qml:207
|
||||
#, kde-format
|
||||
msgid "Email Addresses"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:211
|
||||
#: src/settings/AccountEditorPage.qml:213
|
||||
#, kde-format
|
||||
msgid "Phone Numbers"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:216
|
||||
#: src/settings/AccountEditorPage.qml:218
|
||||
#, kde-format
|
||||
msgid "Identity Server"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:225
|
||||
#: src/settings/AccountEditorPage.qml:227
|
||||
#, kde-format
|
||||
msgid "Server Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:229
|
||||
#: src/settings/AccountEditorPage.qml:231
|
||||
#, kde-format
|
||||
msgid "Homeserver url"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:250
|
||||
#: src/settings/AccountEditorPage.qml:252
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Account Management"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:255
|
||||
#: src/settings/AccountEditorPage.qml:257
|
||||
#, kde-format
|
||||
msgid "Deactivate Account"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:271
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#, kde-format
|
||||
msgid "Password changed successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#, kde-format
|
||||
msgid "Wrong password entered"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#: src/settings/AccountEditorPage.qml:277
|
||||
#, kde-format
|
||||
msgid "Unknown problem while trying to change password"
|
||||
msgstr ""
|
||||
@@ -4226,7 +4236,7 @@ msgstr ""
|
||||
msgid "Accounts"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountsPage.qml:117
|
||||
#: src/settings/AccountsPage.qml:118
|
||||
#, kde-format
|
||||
msgid "Add Account"
|
||||
msgstr ""
|
||||
@@ -4456,7 +4466,7 @@ msgctxt "@title"
|
||||
msgid "Stickers & Emojis"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ExportKeysDialog.qml:18
|
||||
#: src/settings/ExportKeysDialog.qml:17
|
||||
#: src/settings/NeoChatSecurityPage.qml:107
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
@@ -4605,7 +4615,7 @@ msgctxt "@action:button"
|
||||
msgid "Unignore this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/ImportKeysDialog.qml:22 src/settings/NeoChatSecurityPage.qml:84
|
||||
#: src/settings/ImportKeysDialog.qml:21 src/settings/NeoChatSecurityPage.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Import Keys"
|
||||
@@ -4769,7 +4779,7 @@ msgctxt "@action:button"
|
||||
msgid "Reset all configuration values to their default"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/NeoChatSecurityPage.qml:19
|
||||
#: src/settings/NeoChatSecurityPage.qml:18
|
||||
#: src/settings/NeoChatSettingsView.qml:51
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
|
||||
403
po/lv/neochat.po
403
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
385
po/nl/neochat.po
385
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
406
po/nn/neochat.po
406
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
397
po/pa/neochat.po
397
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
405
po/pl/neochat.po
405
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/pt/neochat.po
407
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
399
po/ru/neochat.po
399
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
397
po/sk/neochat.po
397
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
383
po/sl/neochat.po
383
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/sv/neochat.po
403
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
428
po/ta/neochat.po
428
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
403
po/tr/neochat.po
403
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
387
po/uk/neochat.po
387
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdeorg\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2024-11-13 00:40+0000\n"
|
||||
"POT-Creation-Date: 2024-11-19 00:40+0000\n"
|
||||
"PO-Revision-Date: 2024-04-23 19:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
@@ -47,33 +47,33 @@ msgstr "发送位置"
|
||||
msgid "Send message"
|
||||
msgstr "发送消息"
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send an encrypted message…"
|
||||
msgstr "发送一条加密消息..."
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Set an attachment caption…"
|
||||
msgstr "设置附件说明"
|
||||
|
||||
#: src/chatbar/ChatBar.qml:201
|
||||
#: src/chatbar/ChatBar.qml:202
|
||||
#, kde-format
|
||||
msgid "Send a message…"
|
||||
msgstr "发送一条消息..."
|
||||
|
||||
#: src/chatbar/ChatBar.qml:376
|
||||
#: src/chatbar/ChatBar.qml:375
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Cancel reply"
|
||||
msgstr "取消回复"
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No stickers"
|
||||
msgstr "无贴纸"
|
||||
|
||||
#: src/chatbar/EmojiGrid.qml:87
|
||||
#: src/chatbar/EmojiGrid.qml:88
|
||||
#, kde-format
|
||||
msgid "No emojis"
|
||||
msgstr "无表情"
|
||||
@@ -910,7 +910,7 @@ msgstr "此服务器已禁用注册。"
|
||||
msgid "Loading"
|
||||
msgstr "加载中"
|
||||
|
||||
#: src/login/Loading.qml:16
|
||||
#: src/login/Loading.qml:17
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Please wait while your messages are loaded from the server. This might take "
|
||||
@@ -934,7 +934,7 @@ msgstr "Matrix ID"
|
||||
msgid "Loading…"
|
||||
msgstr "加载中…"
|
||||
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:232
|
||||
#: src/login/Login.qml:38 src/login/WelcomePage.qml:249
|
||||
#: src/settings/ThreePIdCard.qml:183
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -976,7 +976,7 @@ msgstr "注册"
|
||||
msgid "Password:"
|
||||
msgstr "密码:"
|
||||
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:152
|
||||
#: src/login/Password.qml:32 src/settings/AccountEditorPage.qml:154
|
||||
#: src/settings/NetworkProxyPage.qml:122
|
||||
#, kde-format
|
||||
msgid "Password"
|
||||
@@ -1030,47 +1030,47 @@ msgstr "用户名:"
|
||||
msgid "Username unavailable"
|
||||
msgstr "用户名不可用"
|
||||
|
||||
#: src/login/WelcomePage.qml:25
|
||||
#: src/login/WelcomePage.qml:26
|
||||
#, kde-format
|
||||
msgid "Welcome"
|
||||
msgstr "欢迎使用"
|
||||
|
||||
#: src/login/WelcomePage.qml:73 src/main.cpp:141
|
||||
#: src/login/WelcomePage.qml:74 src/main.cpp:141
|
||||
#, kde-format
|
||||
msgid "NeoChat"
|
||||
msgstr "NeoChat"
|
||||
|
||||
#: src/login/WelcomePage.qml:81
|
||||
#: src/login/WelcomePage.qml:82
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Continue with an existing account"
|
||||
msgstr "使用现有账户登录"
|
||||
|
||||
#: src/login/WelcomePage.qml:115
|
||||
#: src/login/WelcomePage.qml:132
|
||||
#, kde-format
|
||||
msgctxt "As in 'this account is still loading'"
|
||||
msgid "%1 (loading)"
|
||||
msgstr "%1 (加载中)"
|
||||
|
||||
#: src/login/WelcomePage.qml:124
|
||||
#: src/login/WelcomePage.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Log out of this account"
|
||||
msgstr ""
|
||||
|
||||
#: src/login/WelcomePage.qml:153
|
||||
#: src/login/WelcomePage.qml:170
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Log in or Create a New Account"
|
||||
msgstr "登录或创建一个新账户"
|
||||
|
||||
#: src/login/WelcomePage.qml:240
|
||||
#: src/login/WelcomePage.qml:257
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Go back"
|
||||
msgstr "返回"
|
||||
|
||||
#: src/login/WelcomePage.qml:252
|
||||
#: src/login/WelcomePage.qml:269
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Settings"
|
||||
@@ -1851,7 +1851,7 @@ msgstr "%1:%2"
|
||||
msgid "Open NeoChat in this room"
|
||||
msgstr "在此聊天室打开 NeoChat"
|
||||
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:110
|
||||
#: src/notificationsmanager.cpp:246 src/qml/DelegateContextMenu.qml:111
|
||||
#: src/qml/HoverActions.qml:123
|
||||
#, kde-format
|
||||
msgid "Reply"
|
||||
@@ -1906,58 +1906,58 @@ msgctxt "@action:button"
|
||||
msgid "Show QR code"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:39 src/qml/UserInfo.qml:46
|
||||
#: src/qml/AccountMenu.qml:40 src/qml/UserInfo.qml:46
|
||||
#, kde-format
|
||||
msgid "Edit this account"
|
||||
msgstr "编辑此账户"
|
||||
|
||||
#: src/qml/AccountMenu.qml:44 src/settings/AccountsPage.qml:33
|
||||
#: src/qml/AccountMenu.qml:45 src/settings/AccountsPage.qml:33
|
||||
#: src/settings/AccountsPage.qml:50
|
||||
#, kde-format
|
||||
msgid "Account editor"
|
||||
msgstr "账户编辑器"
|
||||
|
||||
#: src/qml/AccountMenu.qml:48
|
||||
#: src/qml/AccountMenu.qml:49
|
||||
#, kde-format
|
||||
msgid "Notification settings"
|
||||
msgstr "通知设置"
|
||||
|
||||
#: src/qml/AccountMenu.qml:55 src/settings/DevicesPage.qml:17
|
||||
#: src/qml/AccountMenu.qml:56 src/settings/DevicesPage.qml:17
|
||||
#: src/settings/NeoChatSettingsView.qml:89
|
||||
#, kde-format
|
||||
msgid "Devices"
|
||||
msgstr "设备"
|
||||
|
||||
#: src/qml/AccountMenu.qml:62 src/settings/NeoChatGeneralPage.qml:269
|
||||
#: src/qml/AccountMenu.qml:63 src/settings/NeoChatGeneralPage.qml:269
|
||||
#, kde-format
|
||||
msgid "Open developer tools"
|
||||
msgstr "打开开发者工具"
|
||||
|
||||
#: src/qml/AccountMenu.qml:68
|
||||
#: src/qml/AccountMenu.qml:69
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Developer Tools"
|
||||
msgstr "开发者工具"
|
||||
|
||||
#: src/qml/AccountMenu.qml:74
|
||||
#: src/qml/AccountMenu.qml:75
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Secret Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:78
|
||||
#: src/qml/AccountMenu.qml:79
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Open Key Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:82
|
||||
#: src/qml/AccountMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Verify this Device"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/AccountMenu.qml:88 src/settings/AccountsPage.qml:87
|
||||
#: src/qml/AccountMenu.qml:89 src/settings/AccountsPage.qml:88
|
||||
#, kde-format
|
||||
msgid "Logout"
|
||||
msgstr "退出登录"
|
||||
@@ -2008,7 +2008,7 @@ msgid "Attachment:"
|
||||
msgstr "附件:"
|
||||
|
||||
#: src/qml/AttachmentPane.qml:38 src/qml/HoverActions.qml:106
|
||||
#: src/qml/ImageEditorPage.qml:21 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:20 src/qml/MessageDelegateContextMenu.qml:37
|
||||
#, kde-format
|
||||
msgid "Edit"
|
||||
msgstr "编辑"
|
||||
@@ -2144,61 +2144,29 @@ msgctxt "@action:button"
|
||||
msgid "Open"
|
||||
msgstr "打开"
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "从收藏夹中移除"
|
||||
|
||||
#: src/qml/ContextMenu.qml:31
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr "添加到收藏夹"
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr "恢复优先级"
|
||||
|
||||
#: src/qml/ContextMenu.qml:37 src/qml/ContextMenu.qml:197
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr "降低优先级"
|
||||
|
||||
#: src/qml/ContextMenu.qml:43 src/qml/ContextMenu.qml:204
|
||||
#: src/qml/ContextMenu.qml:31 src/qml/ContextMenu.qml:209
|
||||
#, kde-format
|
||||
msgid "Mark as Read"
|
||||
msgstr "标记为已读"
|
||||
|
||||
#: src/qml/ContextMenu.qml:49
|
||||
#: src/qml/ContextMenu.qml:40
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgstr "将用户的 Matrix ID 复制到剪贴板"
|
||||
msgid "Notifications"
|
||||
msgstr "通知"
|
||||
|
||||
#: src/qml/ContextMenu.qml:49 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr "将地址复制到剪贴板"
|
||||
|
||||
#: src/qml/ContextMenu.qml:61
|
||||
#, kde-format
|
||||
msgid "Notification State"
|
||||
msgstr "通知状态"
|
||||
|
||||
#: src/qml/ContextMenu.qml:65
|
||||
#: src/qml/ContextMenu.qml:44
|
||||
#, kde-format
|
||||
msgid "Follow Global Setting"
|
||||
msgstr "使用全局设置"
|
||||
|
||||
#: src/qml/ContextMenu.qml:76 src/settings/PushNotification.qml:39
|
||||
#: src/qml/ContextMenu.qml:55 src/settings/PushNotification.qml:39
|
||||
#, kde-format
|
||||
msgctxt "As in 'notify for all messages'"
|
||||
msgid "All"
|
||||
msgstr "全部"
|
||||
|
||||
#: src/qml/ContextMenu.qml:87 src/settings/PushNotification.qml:47
|
||||
#: src/qml/ContextMenu.qml:66 src/settings/PushNotification.qml:47
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"As in 'notify when the user is mentioned or the message contains a set "
|
||||
@@ -2206,34 +2174,67 @@ msgctxt ""
|
||||
msgid "@Mentions and Keywords"
|
||||
msgstr "@提及 和关键词"
|
||||
|
||||
#: src/qml/ContextMenu.qml:98 src/settings/PushNotification.qml:55
|
||||
#: src/qml/ContextMenu.qml:77 src/settings/PushNotification.qml:55
|
||||
#, kde-format
|
||||
msgctxt "As in 'do not notify for any messages'"
|
||||
msgid "Off"
|
||||
msgstr "关闭"
|
||||
|
||||
#: src/qml/ContextMenu.qml:111
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "从收藏夹中移除"
|
||||
|
||||
#: src/qml/ContextMenu.qml:90
|
||||
#, kde-format
|
||||
msgid "Add to Favorites"
|
||||
msgstr "添加到收藏夹"
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Reprioritize"
|
||||
msgstr "恢复优先级"
|
||||
|
||||
#: src/qml/ContextMenu.qml:96 src/qml/ContextMenu.qml:202
|
||||
#, kde-format
|
||||
msgid "Deprioritize"
|
||||
msgstr "降低优先级"
|
||||
|
||||
#: src/qml/ContextMenu.qml:104
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy user's Matrix ID to Clipboard"
|
||||
msgstr "将用户的 Matrix ID 复制到剪贴板"
|
||||
|
||||
#: src/qml/ContextMenu.qml:104 src/qml/SpaceListContextMenu.qml:38
|
||||
#: src/qml/SpaceListContextMenu.qml:120
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Address to Clipboard"
|
||||
msgstr "将地址复制到剪贴板"
|
||||
|
||||
#: src/qml/ContextMenu.qml:116
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Room Settings"
|
||||
msgstr "聊天室设置"
|
||||
|
||||
#: src/qml/ContextMenu.qml:121 src/qml/ContextMenu.qml:211
|
||||
#: src/qml/ContextMenu.qml:126 src/qml/ContextMenu.qml:216
|
||||
#, kde-format
|
||||
msgid "Leave Room"
|
||||
msgstr "离开聊天室"
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Remove from Favourites"
|
||||
msgstr "移出收藏夹"
|
||||
|
||||
#: src/qml/ContextMenu.qml:182
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#, kde-format
|
||||
msgid "Add to Favourites"
|
||||
msgstr "移入收藏夹"
|
||||
|
||||
#: src/qml/ContextMenu.qml:187
|
||||
#: src/qml/ContextMenu.qml:192
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room Settings"
|
||||
@@ -2356,74 +2357,74 @@ msgctxt "@action:button"
|
||||
msgid "Ok"
|
||||
msgstr "确定"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:83
|
||||
#: src/qml/DelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgid "View Source"
|
||||
msgstr "查看源码"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:90 src/settings/ThreePIdCard.qml:66
|
||||
#: src/qml/DelegateContextMenu.qml:91 src/settings/ThreePIdCard.qml:66
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:95 src/qml/DelegateContextMenu.qml:100
|
||||
#: src/qml/FileDelegateContextMenu.qml:76
|
||||
#: src/qml/FileDelegateContextMenu.qml:81
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/DelegateContextMenu.qml:101
|
||||
#: src/qml/FileDelegateContextMenu.qml:82
|
||||
#: src/qml/FileDelegateContextMenu.qml:87
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Message"
|
||||
msgstr "移除消息"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:96 src/qml/FileDelegateContextMenu.qml:77
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:83
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this message"
|
||||
msgstr "移除此消息的原因"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:97 src/qml/FileDelegateContextMenu.qml:78
|
||||
#: src/qml/DelegateContextMenu.qml:98 src/qml/FileDelegateContextMenu.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove this message'"
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:120 src/qml/DelegateContextMenu.qml:128
|
||||
#: src/qml/DelegateContextMenu.qml:121 src/qml/DelegateContextMenu.qml:129
|
||||
#, kde-format
|
||||
msgctxt ""
|
||||
"@action:button 'Report' as in 'Report this event to the administrators'"
|
||||
msgid "Report"
|
||||
msgstr "举报"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:125
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Report Message"
|
||||
msgstr "举报消息"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:126
|
||||
#: src/qml/DelegateContextMenu.qml:127
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for reporting this message"
|
||||
msgstr "举报此消息的原因"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:130
|
||||
#: src/qml/DelegateContextMenu.qml:131
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Report Message"
|
||||
msgstr "举报消息"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:140
|
||||
#: src/qml/DelegateContextMenu.qml:141
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Show User"
|
||||
msgstr "查看用户"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:188
|
||||
#: src/qml/DelegateContextMenu.qml:204
|
||||
#, kde-format
|
||||
msgid "Search for '%1'"
|
||||
msgstr "搜索 '%1'"
|
||||
|
||||
#: src/qml/DelegateContextMenu.qml:210
|
||||
#: src/qml/DelegateContextMenu.qml:226
|
||||
#, kde-format
|
||||
msgid "Configure Web Shortcuts..."
|
||||
msgstr "配置网页快捷键..."
|
||||
@@ -2618,23 +2619,25 @@ msgctxt "@info:label"
|
||||
msgid "No public rooms found"
|
||||
msgstr "未找到公共聊天室"
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:46
|
||||
#: src/qml/FileDelegateContextMenu.qml:50
|
||||
#, kde-format
|
||||
msgid "Open Externally"
|
||||
msgstr "在外部打开"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Open Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:53
|
||||
#: src/qml/FileDelegateContextMenu.qml:57
|
||||
#, kde-format
|
||||
msgid "Save As"
|
||||
msgstr "另存为"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Save Image…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:63
|
||||
#: src/qml/MessageDelegateContextMenu.qml:64
|
||||
#: src/qml/FileDelegateContextMenu.qml:66
|
||||
#, kde-format
|
||||
msgid "Copy"
|
||||
msgstr "复制"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/FileDelegateContextMenu.qml:71
|
||||
#: src/qml/FileDelegateContextMenu.qml:77
|
||||
#, kde-format
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
@@ -2784,55 +2787,55 @@ msgctxt "@info screenreader"
|
||||
msgid "The currently selected link"
|
||||
msgstr "当前选择的链接"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:37
|
||||
#: src/qml/ImageEditorPage.qml:36
|
||||
#, kde-format
|
||||
msgctxt "@action:button Undo modification"
|
||||
msgid "Undo"
|
||||
msgstr "撤销"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:44
|
||||
#: src/qml/ImageEditorPage.qml:43
|
||||
#, kde-format
|
||||
msgctxt "@action:button Accept image modification"
|
||||
msgid "Accept"
|
||||
msgstr "接受"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:52
|
||||
#: src/qml/ImageEditorPage.qml:51
|
||||
#, kde-format
|
||||
msgid ""
|
||||
"Unable to save file. Check if you have the correct permission to edit the "
|
||||
"cache directory."
|
||||
msgstr "无法保存文件。请检查您是否有编辑缓存目录的正确权限。"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124
|
||||
#: src/qml/ImageEditorPage.qml:123
|
||||
#, kde-format
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:124 src/qml/ImageEditorPage.qml:140
|
||||
#: src/qml/ImageEditorPage.qml:123 src/qml/ImageEditorPage.qml:139
|
||||
#, kde-format
|
||||
msgctxt "@action:button Crop an image"
|
||||
msgid "Crop"
|
||||
msgstr "裁剪"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:145
|
||||
#: src/qml/ImageEditorPage.qml:144
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the left"
|
||||
msgid "Rotate left"
|
||||
msgstr "旋转 (向左)"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:151
|
||||
#: src/qml/ImageEditorPage.qml:150
|
||||
#, kde-format
|
||||
msgctxt "@action:button Rotate an image to the right"
|
||||
msgid "Rotate right"
|
||||
msgstr "旋转 (向右)"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:157
|
||||
#: src/qml/ImageEditorPage.qml:156
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image vertically"
|
||||
msgid "Flip"
|
||||
msgstr "翻转"
|
||||
|
||||
#: src/qml/ImageEditorPage.qml:163
|
||||
#: src/qml/ImageEditorPage.qml:162
|
||||
#, kde-format
|
||||
msgctxt "@action:button Mirror an image horizontally"
|
||||
msgid "Mirror"
|
||||
@@ -3060,8 +3063,8 @@ msgstr "输入内容不是有效的用户 ID"
|
||||
#: src/qml/MessageDelegateContextMenu.qml:47
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu As in 'Forward this message'"
|
||||
msgid "Forward"
|
||||
msgstr "转发"
|
||||
msgid "Forward…"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:53
|
||||
#, kde-format
|
||||
@@ -3069,10 +3072,17 @@ msgctxt "@title"
|
||||
msgid "Forward Message"
|
||||
msgstr "转发消息"
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:67
|
||||
#, kde-format
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Text"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageDelegateContextMenu.qml:72
|
||||
#, kde-format
|
||||
msgid "Copy Link"
|
||||
msgstr "复制链接"
|
||||
msgctxt "@action:inmenu"
|
||||
msgid "Copy Message Link"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/MessageSourceSheet.qml:46
|
||||
#, kde-format
|
||||
@@ -3166,7 +3176,7 @@ msgctxt "@action:button"
|
||||
msgid "Join"
|
||||
msgstr "加入"
|
||||
|
||||
#: src/qml/RecommendedSpaceDialog.qml:61
|
||||
#: src/qml/RecommendedSpaceDialog.qml:63
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Ignore"
|
||||
@@ -3200,18 +3210,18 @@ msgstr "已静音的聊天室"
|
||||
msgid "Configure room"
|
||||
msgstr "配置聊天室"
|
||||
|
||||
#: src/qml/RoomDrawer.qml:111 src/qml/RoomDrawerPage.qml:45
|
||||
#: src/qml/RoomDrawer.qml:114 src/qml/RoomDrawerPage.qml:45
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Room settings"
|
||||
msgstr "聊天室设置"
|
||||
|
||||
#: src/qml/RoomDrawer.qml:160 src/qml/RoomDrawerPage.qml:85
|
||||
#: src/qml/RoomDrawer.qml:163 src/qml/RoomDrawerPage.qml:85
|
||||
#, kde-format
|
||||
msgid "Information"
|
||||
msgstr "信息"
|
||||
|
||||
#: src/qml/RoomDrawer.qml:165 src/qml/RoomDrawerPage.qml:90
|
||||
#: src/qml/RoomDrawer.qml:168 src/qml/RoomDrawerPage.qml:90
|
||||
#, kde-format
|
||||
msgid "Media"
|
||||
msgstr "媒体"
|
||||
@@ -3225,7 +3235,7 @@ msgstr "空间成员"
|
||||
#: src/qml/RoomInformation.qml:42
|
||||
#, kde-format
|
||||
msgctxt "@action:title"
|
||||
msgid "Room information"
|
||||
msgid "Room Information"
|
||||
msgstr "聊天室信息"
|
||||
|
||||
#: src/qml/RoomInformation.qml:70
|
||||
@@ -3266,6 +3276,12 @@ msgstr ""
|
||||
msgid "Show locations for this room"
|
||||
msgstr "显示此聊天室的位置"
|
||||
|
||||
#: src/qml/RoomInformation.qml:136 src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Leave this space"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/RoomInformation.qml:136
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
@@ -3336,7 +3352,7 @@ msgctxt "@action:title"
|
||||
msgid "Room Media"
|
||||
msgstr "聊天室媒体"
|
||||
|
||||
#: src/qml/RoomPage.qml:93
|
||||
#: src/qml/RoomPage.qml:92
|
||||
#, kde-format
|
||||
msgid "NeoChat is offline. Please check your network connection."
|
||||
msgstr "NeoChat 处于离线状态。请检查您的网络连接。"
|
||||
@@ -3572,12 +3588,6 @@ msgctxt "@button"
|
||||
msgid "Invite user to space"
|
||||
msgstr "邀请用户加入空间"
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:65
|
||||
#, kde-format
|
||||
msgctxt "@button"
|
||||
msgid "Leave the space"
|
||||
msgstr "离开空间"
|
||||
|
||||
#: src/qml/SpaceHomePage.qml:76 src/qml/SpaceListContextMenu.qml:48
|
||||
#: src/qml/SpaceListContextMenu.qml:130
|
||||
#, kde-format
|
||||
@@ -3630,7 +3640,7 @@ msgid "%2 is typing"
|
||||
msgid_plural "%2 are typing"
|
||||
msgstr[0] "%2 正在输入"
|
||||
|
||||
#: src/qml/UnlockSSSSDialog.qml:17
|
||||
#: src/qml/UnlockSSSSDialog.qml:16
|
||||
#, kde-format
|
||||
msgctxt "@title:window"
|
||||
msgid "Load your encrypted messages"
|
||||
@@ -3720,129 +3730,129 @@ msgctxt "@title:menu Account details dialog"
|
||||
msgid "Account Details"
|
||||
msgstr "账户详情"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Unignore this user"
|
||||
msgstr "取消忽略此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:109
|
||||
#: src/qml/UserDetailDialog.qml:111
|
||||
#, kde-format
|
||||
msgid "Ignore this user"
|
||||
msgstr "忽略此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:122
|
||||
#: src/qml/UserDetailDialog.qml:124
|
||||
#, kde-format
|
||||
msgid "Kick this user"
|
||||
msgstr "踢出此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:126 src/qml/UserDetailDialog.qml:131
|
||||
#: src/qml/UserDetailDialog.qml:128 src/qml/UserDetailDialog.qml:133
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Kick User"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:127
|
||||
#: src/qml/UserDetailDialog.qml:129
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for kicking this user"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:128
|
||||
#: src/qml/UserDetailDialog.qml:130
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Kick' as in 'Kick this user from the room'"
|
||||
msgid "Kick"
|
||||
msgstr ""
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:147
|
||||
#: src/qml/UserDetailDialog.qml:149
|
||||
#, kde-format
|
||||
msgid "Invite this user"
|
||||
msgstr "邀请此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:160
|
||||
#: src/qml/UserDetailDialog.qml:162
|
||||
#, kde-format
|
||||
msgid "Ban this user"
|
||||
msgstr "封禁此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:165 src/qml/UserDetailDialog.qml:170
|
||||
#: src/qml/UserDetailDialog.qml:167 src/qml/UserDetailDialog.qml:172
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Ban User"
|
||||
msgstr "封禁用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:166
|
||||
#: src/qml/UserDetailDialog.qml:168
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for banning this user"
|
||||
msgstr "封禁此用户的原因"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:167
|
||||
#: src/qml/UserDetailDialog.qml:169
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Ban' as in 'Ban this user'"
|
||||
msgid "Ban"
|
||||
msgstr "封禁"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:185
|
||||
#: src/qml/UserDetailDialog.qml:187
|
||||
#, kde-format
|
||||
msgid "Unban this user"
|
||||
msgstr "解封此用户"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:198
|
||||
#: src/qml/UserDetailDialog.qml:200
|
||||
#, kde-format
|
||||
msgid "Set user power level"
|
||||
msgstr "设置用户权力等级"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:223
|
||||
#: src/qml/UserDetailDialog.qml:225
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Remove recent messages by this user"
|
||||
msgstr "移除此用户最近的消息"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:228
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#, kde-format
|
||||
msgctxt "@title:dialog"
|
||||
msgid "Remove Messages"
|
||||
msgstr "移除消息"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:229
|
||||
#: src/qml/UserDetailDialog.qml:231
|
||||
#, kde-format
|
||||
msgctxt "@info:placeholder"
|
||||
msgid "Reason for removing this user's recent messages"
|
||||
msgstr "移除此用户最近消息的原因"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:230
|
||||
#: src/qml/UserDetailDialog.qml:232
|
||||
#, kde-format
|
||||
msgctxt "@action:button 'Remove' as in 'Remove these messages'"
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:233
|
||||
#: src/qml/UserDetailDialog.qml:235
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Remove Messages"
|
||||
msgstr "移除消息"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgctxt "%1 is the name of the user."
|
||||
msgid "Chat with %1"
|
||||
msgstr "与 %1 聊天"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:247
|
||||
#: src/qml/UserDetailDialog.qml:249
|
||||
#, kde-format
|
||||
msgid "Invite to private chat"
|
||||
msgstr "邀请到私人聊天"
|
||||
|
||||
#: src/qml/UserDetailDialog.qml:258
|
||||
#: src/qml/UserDetailDialog.qml:260
|
||||
#, kde-format
|
||||
msgid "Copy link"
|
||||
msgstr "复制链接"
|
||||
|
||||
#: src/qml/UserInfo.qml:91
|
||||
#: src/qml/UserInfo.qml:92
|
||||
#, kde-format
|
||||
msgid "Switch User"
|
||||
msgstr "切换用户"
|
||||
|
||||
#: src/qml/UserInfo.qml:100
|
||||
#: src/qml/UserInfo.qml:101
|
||||
#, kde-format
|
||||
msgid "Open Settings"
|
||||
msgstr "打开设置"
|
||||
@@ -4063,7 +4073,7 @@ msgstr "继续"
|
||||
msgid "Working"
|
||||
msgstr "正在处理"
|
||||
|
||||
#: src/roommanager.cpp:146
|
||||
#: src/roommanager.cpp:145
|
||||
#, kde-format
|
||||
msgid "Malformed or empty Matrix id<br />%1 is not a correct Matrix identifier"
|
||||
msgstr ""
|
||||
@@ -4088,126 +4098,126 @@ msgstr ""
|
||||
msgid "Edit Account"
|
||||
msgstr "编辑账户"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:61
|
||||
#: src/settings/AccountEditorPage.qml:62
|
||||
#, kde-format
|
||||
msgid "Upload new avatar"
|
||||
msgstr "上传新头像"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:78
|
||||
#: src/settings/AccountEditorPage.qml:79
|
||||
#, kde-format
|
||||
msgid "Remove current avatar"
|
||||
msgstr "移除当前头像"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:101
|
||||
#: src/settings/AccountEditorPage.qml:102
|
||||
#, kde-format
|
||||
msgid "User Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:106
|
||||
#: src/settings/AccountEditorPage.qml:107
|
||||
#, kde-format
|
||||
msgid "Display Name:"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:112
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#, kde-format
|
||||
msgid "Label:"
|
||||
msgstr "标签:"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:113
|
||||
#: src/settings/AccountEditorPage.qml:114
|
||||
#, kde-format
|
||||
msgid "Work"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:118
|
||||
#: src/settings/AccountEditorPage.qml:119
|
||||
#, kde-format
|
||||
msgctxt "@action:button"
|
||||
msgid "Show QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:135
|
||||
#: src/settings/AccountEditorPage.qml:191
|
||||
#: src/settings/AccountEditorPage.qml:137
|
||||
#: src/settings/AccountEditorPage.qml:193
|
||||
#: src/settings/EmoticonEditorPage.qml:108 src/settings/RoomGeneralPage.qml:98
|
||||
#, kde-format
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:157
|
||||
#: src/settings/AccountEditorPage.qml:159
|
||||
#, kde-format
|
||||
msgid "Your server doesn't support changing your password"
|
||||
msgstr "您的服务器不支持更改您的密码"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:164
|
||||
#: src/settings/AccountEditorPage.qml:166
|
||||
#, kde-format
|
||||
msgid "Current Password:"
|
||||
msgstr "当前密码:"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:171
|
||||
#: src/settings/AccountEditorPage.qml:173
|
||||
#, kde-format
|
||||
msgid "New Password:"
|
||||
msgstr "新密码:"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:178
|
||||
#: src/settings/AccountEditorPage.qml:180
|
||||
#, kde-format
|
||||
msgid "Confirm new Password:"
|
||||
msgstr "确认新密码:"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:183
|
||||
#: src/settings/AccountEditorPage.qml:185
|
||||
#, kde-format
|
||||
msgid "Passwords don't match"
|
||||
msgstr "密码不匹配"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:198
|
||||
#: src/settings/AccountEditorPage.qml:200
|
||||
#, kde-format
|
||||
msgid "Passwords do not match"
|
||||
msgstr "密码不匹配"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:205
|
||||
#: src/settings/AccountEditorPage.qml:207
|
||||
#, kde-format
|
||||
msgid "Email Addresses"
|
||||
msgstr "电子邮件地址"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:211
|
||||
#: src/settings/AccountEditorPage.qml:213
|
||||
#, kde-format
|
||||
msgid "Phone Numbers"
|
||||
msgstr "电话号码"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:216
|
||||
#: src/settings/AccountEditorPage.qml:218
|
||||
#, kde-format
|
||||
msgid "Identity Server"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:225
|
||||
#: src/settings/AccountEditorPage.qml:227
|
||||
#, kde-format
|
||||
msgid "Server Information"
|
||||
msgstr "服务器信息"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:229
|
||||
#: src/settings/AccountEditorPage.qml:231
|
||||
#, kde-format
|
||||
msgid "Homeserver url"
|
||||
msgstr "主服务器 URL"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:250
|
||||
#: src/settings/AccountEditorPage.qml:252
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Account Management"
|
||||
msgstr "账户管理"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:255
|
||||
#: src/settings/AccountEditorPage.qml:257
|
||||
#, kde-format
|
||||
msgid "Deactivate Account"
|
||||
msgstr "停用账户"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:271
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#, kde-format
|
||||
msgid "Password changed successfully"
|
||||
msgstr "密码修改成功"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:273
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#, kde-format
|
||||
msgid "Wrong password entered"
|
||||
msgstr "输入的密码错误"
|
||||
|
||||
#: src/settings/AccountEditorPage.qml:275
|
||||
#: src/settings/AccountEditorPage.qml:277
|
||||
#, kde-format
|
||||
msgid "Unknown problem while trying to change password"
|
||||
msgstr "尝试更改密码时出现未知问题"
|
||||
@@ -4218,7 +4228,7 @@ msgstr "尝试更改密码时出现未知问题"
|
||||
msgid "Accounts"
|
||||
msgstr "账户"
|
||||
|
||||
#: src/settings/AccountsPage.qml:117
|
||||
#: src/settings/AccountsPage.qml:118
|
||||
#, kde-format
|
||||
msgid "Add Account"
|
||||
msgstr "添加账户"
|
||||
@@ -4448,7 +4458,7 @@ msgctxt "@title"
|
||||
msgid "Stickers & Emojis"
|
||||
msgstr "贴纸和表情"
|
||||
|
||||
#: src/settings/ExportKeysDialog.qml:18
|
||||
#: src/settings/ExportKeysDialog.qml:17
|
||||
#: src/settings/NeoChatSecurityPage.qml:107
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
@@ -4597,7 +4607,7 @@ msgctxt "@action:button"
|
||||
msgid "Unignore this user"
|
||||
msgstr "取消忽略此用户"
|
||||
|
||||
#: src/settings/ImportKeysDialog.qml:22 src/settings/NeoChatSecurityPage.qml:84
|
||||
#: src/settings/ImportKeysDialog.qml:21 src/settings/NeoChatSecurityPage.qml:84
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
msgid "Import Keys"
|
||||
@@ -4761,7 +4771,7 @@ msgctxt "@action:button"
|
||||
msgid "Reset all configuration values to their default"
|
||||
msgstr ""
|
||||
|
||||
#: src/settings/NeoChatSecurityPage.qml:19
|
||||
#: src/settings/NeoChatSecurityPage.qml:18
|
||||
#: src/settings/NeoChatSettingsView.qml:51
|
||||
#, kde-format
|
||||
msgctxt "@title"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,12 +10,6 @@ endif()
|
||||
add_library(neochat STATIC
|
||||
controller.cpp
|
||||
controller.h
|
||||
models/emojimodel.cpp
|
||||
models/emojimodel.h
|
||||
emojitones.cpp
|
||||
emojitones.h
|
||||
models/customemojimodel.cpp
|
||||
models/customemojimodel.h
|
||||
clipboard.cpp
|
||||
clipboard.h
|
||||
models/messageeventmodel.cpp
|
||||
@@ -26,8 +20,6 @@ add_library(neochat STATIC
|
||||
models/roomlistmodel.h
|
||||
models/sortfilterspacelistmodel.cpp
|
||||
models/sortfilterspacelistmodel.h
|
||||
models/accountemoticonmodel.cpp
|
||||
models/accountemoticonmodel.h
|
||||
spacehierarchycache.cpp
|
||||
spacehierarchycache.h
|
||||
roommanager.cpp
|
||||
@@ -50,8 +42,6 @@ add_library(neochat STATIC
|
||||
models/userdirectorylistmodel.h
|
||||
models/pushrulemodel.cpp
|
||||
models/pushrulemodel.h
|
||||
models/emoticonfiltermodel.cpp
|
||||
models/emoticonfiltermodel.h
|
||||
notificationsmanager.cpp
|
||||
notificationsmanager.h
|
||||
models/sortfilterroomlistmodel.cpp
|
||||
@@ -101,10 +91,6 @@ add_library(neochat STATIC
|
||||
texthandler.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
models/stickermodel.cpp
|
||||
models/stickermodel.h
|
||||
models/imagepacksmodel.cpp
|
||||
models/imagepacksmodel.h
|
||||
events/imagepackevent.cpp
|
||||
events/imagepackevent.h
|
||||
events/joinrulesevent.cpp
|
||||
@@ -282,6 +268,9 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||
qml/ConfirmLeaveDialog.qml
|
||||
qml/CodeMaximizeComponent.qml
|
||||
qml/EditStateDialog.qml
|
||||
qml/EmojiPickerTypeHeader.qml
|
||||
qml/EmojiPickerPackHeader.qml
|
||||
qml/QuickReaction.qml
|
||||
qml/ConsentDialog.qml
|
||||
qml/AskDirectChatConfirmation.qml
|
||||
qml/HoverLinkIndicator.qml
|
||||
|
||||
@@ -176,13 +176,14 @@ QQC2.Control {
|
||||
RowLayout {
|
||||
QQC2.ScrollView {
|
||||
id: chatBarScrollView
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumHeight: Kirigami.Units.gridUnit * 8
|
||||
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 2
|
||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 3
|
||||
|
||||
// HACK: This is to stop the ScrollBar flickering on and off as the height is increased
|
||||
QQC2.ScrollBar.vertical.policy: chatBarHeightAnimation.running && implicitHeight <= height ? QQC2.ScrollBar.AlwaysOff : QQC2.ScrollBar.AsNeeded
|
||||
@@ -320,12 +321,11 @@ QQC2.Control {
|
||||
id: actionsRow
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing * 1.5
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing * 4
|
||||
|
||||
Repeater {
|
||||
model: root.actions
|
||||
delegate: QQC2.ToolButton {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.name: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
|
||||
onClicked: modelData.trigger()
|
||||
|
||||
@@ -342,7 +342,6 @@ QQC2.Control {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DelegateSizeHelper {
|
||||
id: chatBarSizeHelper
|
||||
startBreakpoint: Kirigami.Units.gridUnit * 46
|
||||
@@ -520,7 +519,6 @@ QQC2.Control {
|
||||
y: -implicitHeight
|
||||
|
||||
modal: false
|
||||
includeCustom: true
|
||||
closeOnChosen: false
|
||||
|
||||
currentRoom: root.currentRoom
|
||||
|
||||
@@ -5,56 +5,30 @@ import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
QQC2.ItemDelegate {
|
||||
QQC2.Button {
|
||||
id: root
|
||||
|
||||
property string name
|
||||
property string emoji
|
||||
required property string toolTip
|
||||
property bool showTones: false
|
||||
property bool isImage: false
|
||||
|
||||
QQC2.ToolTip.text: root.name
|
||||
QQC2.ToolTip.visible: hovered && root.name !== ""
|
||||
QQC2.ToolTip.text: toolTip
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
leftInset: Kirigami.Units.smallSpacing
|
||||
topInset: Kirigami.Units.smallSpacing
|
||||
rightInset: Kirigami.Units.smallSpacing
|
||||
bottomInset: Kirigami.Units.smallSpacing
|
||||
|
||||
contentItem: Item {
|
||||
Kirigami.Heading {
|
||||
anchors.fill: parent
|
||||
visible: !root.emoji.startsWith("mxc") && !root.isImage
|
||||
text: root.emoji
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.family: "emoji"
|
||||
flat: true
|
||||
|
||||
Kirigami.Icon {
|
||||
width: Kirigami.Units.gridUnit * 0.5
|
||||
height: Kirigami.Units.gridUnit * 0.5
|
||||
source: "arrow-down-symbolic"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
visible: root.showTones
|
||||
}
|
||||
}
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
visible: root.emoji.startsWith("mxc") || root.isImage
|
||||
source: visible ? root.emoji : ""
|
||||
}
|
||||
}
|
||||
contentItem: Kirigami.Heading {
|
||||
text: root.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
background: Rectangle {
|
||||
color: root.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
|
||||
Rectangle {
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
anchors.fill: parent
|
||||
color: Kirigami.Theme.highlightColor
|
||||
opacity: root.hovered && !root.pressed ? 0.2 : 0
|
||||
Kirigami.Icon {
|
||||
width: Kirigami.Units.gridUnit * 0.5
|
||||
height: Kirigami.Units.gridUnit * 0.5
|
||||
source: "arrow-down-symbolic"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
visible: root.showTones
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@ QQC2.Popup {
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
|
||||
property bool includeCustom: false
|
||||
property bool closeOnChosen: true
|
||||
property bool showQuickReaction: false
|
||||
|
||||
signal chosen(string emoji)
|
||||
|
||||
@@ -64,15 +62,15 @@ QQC2.Popup {
|
||||
padding: 2
|
||||
|
||||
implicitHeight: Kirigami.Units.gridUnit * 20 + 2 * padding
|
||||
width: Math.min(contentItem.categoryIconSize * 11 + 2 * padding, applicationWindow().width)
|
||||
width: Math.min(contentItem.implicitWidth + 2 * padding, applicationWindow().width)
|
||||
|
||||
contentItem: EmojiPicker {
|
||||
id: emojiPicker
|
||||
height: 400
|
||||
currentRoom: root.currentRoom
|
||||
includeCustom: root.includeCustom
|
||||
showQuickReaction: root.showQuickReaction
|
||||
onChosen: emoji => {
|
||||
root.chosen(emoji);
|
||||
ImageContentManager.emojiUsed(emoji)
|
||||
if (root.closeOnChosen) {
|
||||
root.close();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
// SPDX-FileCopyrightText: 2022 Tobias Fella
|
||||
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
import org.kde.textaddons.emoticons
|
||||
|
||||
QQC2.ScrollView {
|
||||
id: root
|
||||
|
||||
property alias model: emojis.model
|
||||
property alias count: emojis.count
|
||||
required property int targetIconSize
|
||||
readonly property int emojisPerRow: emojis.width / targetIconSize
|
||||
required property bool withCustom
|
||||
readonly property var searchCategory: withCustom ? EmojiModel.Search : EmojiModel.SearchNoCustom
|
||||
readonly property int emojisPerRow: emojis.width / Kirigami.Units.iconSizes.large
|
||||
required property QtObject header
|
||||
property bool stickers: false
|
||||
|
||||
@@ -25,6 +22,8 @@ QQC2.ScrollView {
|
||||
emojis.forceActiveFocus();
|
||||
}
|
||||
|
||||
width: Kirigami.Units.gridUnit * 24
|
||||
|
||||
GridView {
|
||||
id: emojis
|
||||
|
||||
@@ -41,7 +40,9 @@ QQC2.ScrollView {
|
||||
onModelChanged: currentIndex = -1
|
||||
|
||||
cellWidth: emojis.width / root.emojisPerRow
|
||||
cellHeight: root.targetIconSize
|
||||
cellHeight: Kirigami.Units.iconSizes.large
|
||||
|
||||
model: EmojiModelManager.emojiModel
|
||||
|
||||
KeyNavigation.up: root.header
|
||||
|
||||
@@ -49,49 +50,49 @@ QQC2.ScrollView {
|
||||
|
||||
delegate: EmojiDelegate {
|
||||
id: emojiDelegate
|
||||
checked: emojis.currentIndex === model.index
|
||||
emoji: !!modelData ? modelData.unicode : model.url
|
||||
name: !!modelData ? modelData.shortName : model.body
|
||||
|
||||
required property string unicode
|
||||
required property string identifier
|
||||
required property int index
|
||||
|
||||
text: emojiDelegate.unicode
|
||||
toolTip: emojiDelegate.identifier
|
||||
checked: emojis.currentIndex === emojiDelegate.index
|
||||
|
||||
width: emojis.cellWidth
|
||||
height: emojis.cellHeight
|
||||
|
||||
isImage: root.stickers
|
||||
Keys.onEnterPressed: clicked()
|
||||
Keys.onReturnPressed: clicked()
|
||||
onClicked: {
|
||||
if (root.stickers) {
|
||||
root.stickerChosen(model.index);
|
||||
}
|
||||
root.chosen(modelData.isCustom ? modelData.shortName : modelData.unicode);
|
||||
EmojiModel.emojiUsed(modelData);
|
||||
}
|
||||
Keys.onSpacePressed: pressAndHold()
|
||||
onPressAndHold: {
|
||||
if (EmojiModel.tones(modelData.shortName).length === 0) {
|
||||
return;
|
||||
}
|
||||
let tones = tonesPopupComponent.createObject(emojiDelegate, {
|
||||
shortName: modelData.shortName,
|
||||
unicode: modelData.unicode,
|
||||
categoryIconSize: root.targetIconSize
|
||||
});
|
||||
tones.open();
|
||||
tones.forceActiveFocus();
|
||||
}
|
||||
showTones: !!modelData && EmojiModel.tones(modelData.shortName).length > 0
|
||||
// onClicked: {
|
||||
// if (root.stickers) {
|
||||
// root.stickerChosen(model.index);
|
||||
// }
|
||||
// root.chosen(modelData.isCustom ? modelData.shortName : modelData.unicode);
|
||||
// EmojiModel.emojiUsed(modelData);
|
||||
// }
|
||||
// Keys.onSpacePressed: pressAndHold()
|
||||
// onPressAndHold: {
|
||||
// if (!showTones) {
|
||||
// return;
|
||||
// }
|
||||
// let tones = Qt.createComponent("org.kde.neochat", "EmojiTonesPicker").createObject(emojiDelegate, {
|
||||
// shortName: modelData.shortName,
|
||||
// unicode: modelData.unicode,
|
||||
// categoryIconSize: root.targetIconSize,
|
||||
// onChosen: root.chosen(emoji => root.chosen(emoji))
|
||||
// });
|
||||
// tones.open();
|
||||
// tones.forceActiveFocus();
|
||||
// }
|
||||
// showTones: model.hasTones
|
||||
}
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
text: root.stickers ? i18n("No stickers") : i18n("No emojis")
|
||||
icon.name: root.stickers ? "stickers" : "preferences-desktop-emoticons"
|
||||
text: root.stickers ? i18nc("@info", "No stickers") : i18nc("@info", "No emojis")
|
||||
visible: emojis.count === 0
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: tonesPopupComponent
|
||||
EmojiTonesPicker {
|
||||
onChosen: root.chosen(emoji)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022-2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
@@ -6,6 +6,7 @@ import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.neochat
|
||||
import org.kde.textaddons.emoticons
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
@@ -13,86 +14,29 @@ ColumnLayout {
|
||||
/**
|
||||
* @brief The current room that user is viewing.
|
||||
*/
|
||||
property NeoChatRoom currentRoom
|
||||
|
||||
property bool includeCustom: false
|
||||
property bool showQuickReaction: false
|
||||
|
||||
readonly property var currentEmojiModel: {
|
||||
if (includeCustom) {
|
||||
EmojiModel.categoriesWithCustom;
|
||||
} else {
|
||||
EmojiModel.categories;
|
||||
}
|
||||
}
|
||||
|
||||
readonly property int categoryIconSize: Math.round(Kirigami.Units.gridUnit * 2.5)
|
||||
readonly property var currentCategory: currentEmojiModel[categories.currentIndex].category
|
||||
readonly property alias categoryCount: categories.count
|
||||
property int selectedType: 0
|
||||
required property NeoChatRoom currentRoom
|
||||
|
||||
signal chosen(string emoji)
|
||||
|
||||
spacing: 0
|
||||
|
||||
onActiveFocusChanged: if (activeFocus) {
|
||||
searchField.forceActiveFocus();
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
EmojiPickerTypeHeader {
|
||||
id: emoticonPickerTypeHeader
|
||||
|
||||
Kirigami.NavigationTabBar {
|
||||
id: types
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
|
||||
background: null
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
id: emojis
|
||||
icon.name: "smiley"
|
||||
text: i18n("Emojis")
|
||||
checked: true
|
||||
onTriggered: root.selectedType = 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
id: stickers
|
||||
icon.name: "stickers"
|
||||
text: i18n("Stickers")
|
||||
onTriggered: root.selectedType = 1
|
||||
}
|
||||
]
|
||||
onSelectedTypeChanged: emoticonPickerCategoryHeader.currentIndex = 0
|
||||
}
|
||||
|
||||
QQC2.ScrollView {
|
||||
EmojiPickerPackHeader {
|
||||
id: emoticonPickerCategoryHeader
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height
|
||||
QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0
|
||||
|
||||
ListView {
|
||||
id: categories
|
||||
clip: true
|
||||
focus: true
|
||||
orientation: ListView.Horizontal
|
||||
|
||||
Keys.onReturnPressed: if (emojiGrid.count > 0) {
|
||||
emojiGrid.focus = true;
|
||||
}
|
||||
Keys.onEnterPressed: if (emojiGrid.count > 0) {
|
||||
emojiGrid.focus = true;
|
||||
}
|
||||
|
||||
KeyNavigation.down: emojiGrid.count > 0 ? emojiGrid : categories
|
||||
KeyNavigation.tab: emojiGrid.count > 0 ? emojiGrid : categories
|
||||
|
||||
keyNavigationEnabled: true
|
||||
keyNavigationWraps: true
|
||||
Keys.forwardTo: searchField
|
||||
interactive: width !== contentWidth
|
||||
|
||||
model: root.selectedType === 0 ? root.currentEmojiModel : stickerPackModel
|
||||
Component.onCompleted: categories.forceActiveFocus()
|
||||
|
||||
delegate: root.selectedType === 0 ? emojiDelegate : stickerDelegate
|
||||
}
|
||||
model: UnicodeEmoticonManager.categories
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
@@ -104,114 +48,34 @@ ColumnLayout {
|
||||
id: searchField
|
||||
Layout.margins: Kirigami.Units.smallSpacing
|
||||
Layout.fillWidth: true
|
||||
visible: selectedType === 0
|
||||
|
||||
/**
|
||||
* The focus is manged by the parent and we don't want to use the standard
|
||||
* shortcut as it could block other SearchFields from using it.
|
||||
*/
|
||||
focusSequence: ""
|
||||
}
|
||||
|
||||
EmojiGrid {
|
||||
id: emojiGrid
|
||||
targetIconSize: root.currentCategory === EmojiModel.Custom ? Kirigami.Units.gridUnit * 3 : root.categoryIconSize // Custom emojis are bigger
|
||||
model: root.selectedType === 1 ? emoticonFilterModel : searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false))
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
withCustom: root.includeCustom
|
||||
onChosen: unicode => root.chosen(unicode)
|
||||
header: categories
|
||||
header: emoticonPickerCategoryHeader
|
||||
Keys.forwardTo: searchField
|
||||
stickers: root.selectedType === 1
|
||||
stickers: emoticonPickerTypeHeader.selectedType === EmojiPickerTypeHeader.EmoticonType.Sticker
|
||||
onStickerChosen: stickerModel.postSticker(emoticonFilterModel.mapToSource(emoticonFilterModel.index(index, 0)).row)
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
visible: showQuickReaction
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
}
|
||||
|
||||
QQC2.ScrollView {
|
||||
visible: showQuickReaction
|
||||
QuickReaction {
|
||||
id: quickReaction
|
||||
onChosen: root.chosen(text)
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height
|
||||
QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0
|
||||
|
||||
ListView {
|
||||
id: quickReactions
|
||||
Layout.fillWidth: true
|
||||
|
||||
model: ["👍", "👎", "😄", "🎉", "😕", "❤", "🚀", "👀"]
|
||||
|
||||
delegate: EmojiDelegate {
|
||||
emoji: modelData
|
||||
|
||||
height: root.categoryIconSize
|
||||
width: height
|
||||
|
||||
onClicked: root.chosen(modelData)
|
||||
}
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
}
|
||||
}
|
||||
|
||||
ImagePacksModel {
|
||||
id: stickerPackModel
|
||||
room: root.currentRoom
|
||||
showStickers: true
|
||||
showEmoticons: false
|
||||
}
|
||||
|
||||
StickerModel {
|
||||
id: stickerModel
|
||||
model: stickerPackModel
|
||||
packIndex: 0
|
||||
room: root.currentRoom
|
||||
}
|
||||
|
||||
EmoticonFilterModel {
|
||||
id: emoticonFilterModel
|
||||
sourceModel: stickerModel
|
||||
showStickers: true
|
||||
}
|
||||
|
||||
Component {
|
||||
id: emojiDelegate
|
||||
Kirigami.NavigationTabButton {
|
||||
width: root.categoryIconSize
|
||||
height: width
|
||||
checked: categories.currentIndex === model.index
|
||||
text: modelData ? modelData.emoji : ""
|
||||
QQC2.ToolTip.text: modelData ? modelData.name : ""
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: hovered
|
||||
onClicked: {
|
||||
categories.currentIndex = index;
|
||||
categories.focus = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: stickerDelegate
|
||||
Kirigami.NavigationTabButton {
|
||||
width: root.categoryIconSize
|
||||
height: width
|
||||
checked: stickerModel.packIndex === model.index
|
||||
contentItem: Image {
|
||||
source: model.avatarUrl
|
||||
}
|
||||
QQC2.ToolTip.text: model.name
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: hovered && !!model.name
|
||||
onClicked: stickerModel.packIndex = model.index
|
||||
}
|
||||
}
|
||||
|
||||
function clearSearchField() {
|
||||
searchField.text = "";
|
||||
searchField.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
@@ -54,8 +54,8 @@ QQC2.Popup {
|
||||
delegate: EmojiDelegate {
|
||||
id: emojiDelegate
|
||||
checked: tonesList.currentIndex === model.index
|
||||
emoji: modelData.unicode
|
||||
name: modelData.shortName
|
||||
text: modelData.unicode
|
||||
toolTip: modelData.shortName
|
||||
|
||||
width: root.categoryIconSize
|
||||
height: width
|
||||
|
||||
1857
src/emojis.h
1857
src/emojis.h
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
// SPDX-FileCopyrightText: None
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "emojitones.h"
|
||||
#include "models/emojimodel.h"
|
||||
|
||||
QMultiHash<QString, QVariant> EmojiTones::_tones = {
|
||||
#include "emojitones_data.h"
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
// SPDX-FileCopyrightText: None
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
/**
|
||||
* @class EmojiTones
|
||||
*
|
||||
* This class provides a _tones variable with the available emoji tones to EmojiModel.
|
||||
*
|
||||
* @sa EmojiModel
|
||||
*/
|
||||
class EmojiTones
|
||||
{
|
||||
private:
|
||||
static QMultiHash<QString, QVariant> _tones;
|
||||
|
||||
friend class EmojiModel;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ LoginStep {
|
||||
id: root
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
textItem.wrapMode: Text.Wrap
|
||||
text: i18n("Please wait while your messages are loaded from the server. This might take a little while.")
|
||||
}
|
||||
FormCard.AbstractFormDelegate {
|
||||
|
||||
@@ -7,6 +7,7 @@ import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.formcard as FormCard
|
||||
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
||||
|
||||
import org.kde.neochat
|
||||
import org.kde.neochat.settings
|
||||
@@ -90,11 +91,27 @@ Kirigami.Page {
|
||||
id: loadedAccounts
|
||||
model: AccountRegistry
|
||||
delegate: FormCard.FormButtonDelegate {
|
||||
text: model.userId
|
||||
id: delegate
|
||||
|
||||
required property string userId
|
||||
required property NeoChatConnection connection
|
||||
|
||||
text: QmlUtils.escapeString(connection.localUser.displayName)
|
||||
description: connection.localUser.id
|
||||
leadingPadding: Kirigami.Units.largeSpacing
|
||||
|
||||
onClicked: {
|
||||
Controller.activeConnection = model.connection;
|
||||
Controller.activeConnection = delegate.connection;
|
||||
root.connectionChosen();
|
||||
}
|
||||
leading: KirigamiComponents.Avatar {
|
||||
id: avatar
|
||||
name: delegate.text
|
||||
// Note: User::avatarUrl does not set user_id, and thus cannot be used directly here. Hence the makeMediaUrl.
|
||||
source: delegate.connection.localUser.avatarUrl.toString().length > 0 ? delegate.connection.makeMediaUrl(delegate.connection.localUser.avatarUrl) : ""
|
||||
implicitWidth: Kirigami.Units.iconSizes.medium
|
||||
implicitHeight: Kirigami.Units.iconSizes.medium
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021-2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "accountemoticonmodel.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QMimeDatabase>
|
||||
|
||||
#include <Quotient/csapi/content-repo.h>
|
||||
#include <Quotient/events/eventcontent.h>
|
||||
#include <qcoro/qcorosignal.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int AccountEmoticonModel::rowCount(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
if (!m_images) {
|
||||
return 0;
|
||||
}
|
||||
return m_images->images.size();
|
||||
}
|
||||
|
||||
QVariant AccountEmoticonModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto &row = index.row();
|
||||
const auto &image = m_images->images[row];
|
||||
if (role == UrlRole) {
|
||||
return m_connection->makeMediaUrl(image.url).toString();
|
||||
}
|
||||
if (role == BodyRole) {
|
||||
if (image.body) {
|
||||
return *image.body;
|
||||
}
|
||||
}
|
||||
if (role == ShortCodeRole) {
|
||||
return image.shortcode;
|
||||
}
|
||||
if (role == IsStickerRole) {
|
||||
if (image.usage) {
|
||||
return image.usage->isEmpty() || image.usage->contains("sticker"_ls);
|
||||
}
|
||||
if (m_images->pack && m_images->pack->usage) {
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("sticker"_ls);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (role == IsEmojiRole) {
|
||||
if (image.usage) {
|
||||
return image.usage->isEmpty() || image.usage->contains("emoticon"_ls);
|
||||
}
|
||||
if (m_images->pack && m_images->pack->usage) {
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("emoticon"_ls);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{AccountEmoticonModel::UrlRole, "url"},
|
||||
{AccountEmoticonModel::BodyRole, "body"},
|
||||
{AccountEmoticonModel::ShortCodeRole, "shortcode"},
|
||||
{AccountEmoticonModel::IsStickerRole, "isSticker"},
|
||||
{AccountEmoticonModel::IsEmojiRole, "isEmoji"},
|
||||
};
|
||||
}
|
||||
|
||||
NeoChatConnection *AccountEmoticonModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
m_connection = connection;
|
||||
Q_EMIT connectionChanged();
|
||||
connect(m_connection, &Connection::accountDataChanged, this, [this](QString type) {
|
||||
if (type == QStringLiteral("im.ponies.user_emotes")) {
|
||||
reloadEmoticons();
|
||||
}
|
||||
});
|
||||
reloadEmoticons();
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::reloadEmoticons()
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json;
|
||||
if (m_connection->hasAccountData("im.ponies.user_emotes"_ls)) {
|
||||
json = m_connection->accountData("im.ponies.user_emotes"_ls)->contentJson();
|
||||
}
|
||||
const auto &content = ImagePackEventContent(json);
|
||||
beginResetModel();
|
||||
m_images = content;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::deleteEmoticon(int index)
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject data;
|
||||
m_images->images.removeAt(index);
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonBody(int index, const QString &text)
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_images->images[index].body = text;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonShortcode(int index, const QString &shortcode)
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_images->images[index].shortcode = shortcode;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonImage(int index, const QUrl &source)
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
doSetEmoticonImage(index, source);
|
||||
}
|
||||
|
||||
QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl source)
|
||||
{
|
||||
auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
co_await qCoro(job.get(), &BaseJob::finished);
|
||||
if (job->error() != BaseJob::NoError) {
|
||||
co_return;
|
||||
}
|
||||
m_images->images[index].url = job->contentUri();
|
||||
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||
source.setScheme("file"_ls);
|
||||
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
EventContent::ImageInfo info;
|
||||
if (mime.name().startsWith("image/"_ls)) {
|
||||
QImage image(source.toLocalFile());
|
||||
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||
}
|
||||
m_images->images[index].info = info;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString shortcode, QString description, QString type)
|
||||
{
|
||||
auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
co_await qCoro(job.get(), &BaseJob::finished);
|
||||
if (job->error() != BaseJob::NoError) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||
source.setScheme("file"_ls);
|
||||
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
EventContent::ImageInfo info;
|
||||
if (mime.name().startsWith("image/"_ls)) {
|
||||
QImage image(source.toLocalFile());
|
||||
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||
}
|
||||
|
||||
m_images->images.append(ImagePackEventContent::ImagePackImage{
|
||||
shortcode,
|
||||
job->contentUri(),
|
||||
description,
|
||||
info,
|
||||
QStringList{type},
|
||||
});
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortcode, const QString &description, const QString &type)
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
doAddEmoticon(source, shortcode, description, type);
|
||||
}
|
||||
|
||||
#include "moc_accountemoticonmodel.cpp"
|
||||
@@ -1,104 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "events/imagepackevent.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QCoroTask>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class AccountEmoticonModel
|
||||
*
|
||||
* This class defines the model for visualising the account stickers and emojis.
|
||||
*
|
||||
* This is based upon the im.ponies.user_emotes spec (MSC2545).
|
||||
*/
|
||||
class AccountEmoticonModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
/**
|
||||
* @brief The connection to get emoticons from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
UrlRole = Qt::UserRole + 1, /**< The URL for the emoticon. */
|
||||
ShortCodeRole, /**< The shortcode for the emoticon. */
|
||||
BodyRole, //**< A textual description of the emoticon */
|
||||
IsStickerRole, //**< Whether this emoticon is a sticker */
|
||||
IsEmojiRole, //**< Whether this emoticon is an emoji */
|
||||
};
|
||||
|
||||
explicit AccountEmoticonModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Number of rows in the model.
|
||||
*
|
||||
* @sa QAbstractItemModel::rowCount
|
||||
*/
|
||||
[[nodiscard]] int rowCount(const QModelIndex &index) const override;
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
*
|
||||
* @sa QAbstractItemModel::data
|
||||
*/
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
/**
|
||||
* @brief Returns a mapping from Role enum values to role names.
|
||||
*
|
||||
* @sa Roles, QAbstractItemModel::roleNames()
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
/**
|
||||
* @brief Deletes the emoticon at the given index.
|
||||
*/
|
||||
Q_INVOKABLE void deleteEmoticon(int index);
|
||||
|
||||
/**
|
||||
* @brief Changes the description for the emoticon at the given index.
|
||||
*/
|
||||
Q_INVOKABLE void setEmoticonBody(int index, const QString &text);
|
||||
|
||||
/**
|
||||
* @brief Changes the shortcode for the emoticon at the given index.
|
||||
*/
|
||||
Q_INVOKABLE void setEmoticonShortcode(int index, const QString &shortCode);
|
||||
|
||||
/**
|
||||
* @brief Changes the image for the emoticon at the given index.
|
||||
*/
|
||||
Q_INVOKABLE void setEmoticonImage(int index, const QUrl &source);
|
||||
|
||||
/**
|
||||
* @brief Add an emoticon with the given parameters.
|
||||
*/
|
||||
Q_INVOKABLE void addEmoticon(const QUrl &source, const QString &shortcode, const QString &description, const QString &type);
|
||||
|
||||
Q_SIGNALS:
|
||||
void connectionChanged();
|
||||
|
||||
private:
|
||||
std::optional<Quotient::ImagePackEventContent> m_images;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QCoro::Task<void> doSetEmoticonImage(int index, QUrl source);
|
||||
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);
|
||||
|
||||
void reloadEmoticons();
|
||||
};
|
||||
@@ -600,14 +600,19 @@ bool ActionsModel::handleQuickEditAction(NeoChatRoom *room, const QString &messa
|
||||
} else {
|
||||
originalString = event->plainBody();
|
||||
}
|
||||
QString replaceId = event->id();
|
||||
const auto eventRelation = event->relatesTo();
|
||||
if (eventRelation && eventRelation->type == "m.replace"_L1) {
|
||||
replaceId = eventRelation->eventId;
|
||||
}
|
||||
if (flags == "/g"_L1) {
|
||||
room->postHtmlMessage(messageText, originalString.replace(regex, replacement), event->msgtype(), {}, event->id());
|
||||
room->postHtmlMessage(messageText, originalString.replace(regex, replacement), event->msgtype(), {}, replaceId);
|
||||
} else {
|
||||
room->postHtmlMessage(messageText,
|
||||
originalString.replace(originalString.indexOf(regex), regex.size(), replacement),
|
||||
event->msgtype(),
|
||||
{},
|
||||
event->id());
|
||||
replaceId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#include "actionsmodel.h"
|
||||
#include "completionproxymodel.h"
|
||||
#include "customemojimodel.h"
|
||||
#include "emojimodel.h"
|
||||
// #include "emojimodel.h"
|
||||
#include "neochatroom.h"
|
||||
#include "roommanager.h"
|
||||
#include "userlistmodel.h"
|
||||
@@ -16,11 +15,13 @@ CompletionModel::CompletionModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_filterModel(new CompletionProxyModel())
|
||||
, m_userListModel(RoomManager::instance().userListModel())
|
||||
, m_emojiModel(new QConcatenateTablesProxyModel(this))
|
||||
//, m_emojiModel(new QConcatenateTablesProxyModel(this))
|
||||
{
|
||||
connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion);
|
||||
m_emojiModel->addSourceModel(&CustomEmojiModel::instance());
|
||||
m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||
connect(this, &CompletionModel::roomChanged, this, [this]() {
|
||||
m_userListModel->setRoom(m_room);
|
||||
});
|
||||
// TODO m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||
}
|
||||
|
||||
QString CompletionModel::text() const
|
||||
@@ -85,29 +86,23 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
auto mediaId = m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
|
||||
if (mediaId.isEmpty()) {
|
||||
return QVariant();
|
||||
}
|
||||
if (m_room) {
|
||||
return m_room->connection()->makeMediaUrl(QUrl(QStringLiteral("mxc://%1").arg(mediaId)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_autoCompletionType == Emoji) {
|
||||
if (role == DisplayNameRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
||||
}
|
||||
if (role == ReplacedTextRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
|
||||
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
|
||||
}
|
||||
}
|
||||
// if (m_autoCompletionType == Emoji) {
|
||||
// if (role == DisplayNameRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||
// }
|
||||
// if (role == IconNameRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
||||
// }
|
||||
// if (role == ReplacedTextRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
|
||||
// }
|
||||
// if (role == SubtitleRole) {
|
||||
// // TODO return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
|
||||
// }
|
||||
// }
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -153,8 +148,8 @@ void CompletionModel::updateCompletion()
|
||||
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
||||
m_filterModel->setSourceModel(m_emojiModel);
|
||||
m_autoCompletionType = Emoji;
|
||||
m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||
m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole);
|
||||
// m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||
// TODO m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_filterModel->invalidate();
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carson Black <uhhadd@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "customemojimodel.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QMimeDatabase>
|
||||
|
||||
#include "emojimodel.h"
|
||||
|
||||
#include <Quotient/csapi/account-data.h>
|
||||
#include <Quotient/csapi/content-repo.h>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
void CustomEmojiModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (connection == m_connection) {
|
||||
return;
|
||||
}
|
||||
m_connection = connection;
|
||||
Q_EMIT connectionChanged();
|
||||
fetchEmojis();
|
||||
}
|
||||
|
||||
NeoChatConnection *CustomEmojiModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void CustomEmojiModel::fetchEmojis()
|
||||
{
|
||||
if (!m_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &data = m_connection->accountData("im.ponies.user_emotes"_ls);
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
QJsonObject emojis = data->contentJson()["images"_ls].toObject();
|
||||
|
||||
// TODO: Remove with stable migration
|
||||
const auto legacyEmojis = data->contentJson()["emoticons"_ls].toObject();
|
||||
for (const auto &emoji : legacyEmojis.keys()) {
|
||||
if (!emojis.contains(emoji)) {
|
||||
emojis[emoji] = legacyEmojis[emoji];
|
||||
}
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_emojis.clear();
|
||||
|
||||
for (const auto &emoji : emojis.keys()) {
|
||||
const auto &data = emojis[emoji];
|
||||
|
||||
const auto e = emoji.startsWith(":"_ls) ? emoji : (QStringLiteral(":") + emoji + QStringLiteral(":"));
|
||||
|
||||
m_emojis << CustomEmoji{e, data.toObject()["url"_ls].toString(), QRegularExpression(e)};
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void CustomEmojiModel::addEmoji(const QString &name, const QUrl &location)
|
||||
{
|
||||
using namespace Quotient;
|
||||
|
||||
auto job = m_connection->uploadFile(location.toLocalFile());
|
||||
|
||||
connect(job, &BaseJob::success, this, [name, location, job, this] {
|
||||
const auto &data = m_connection->accountData("im.ponies.user_emotes"_ls);
|
||||
auto json = data != nullptr ? data->contentJson() : QJsonObject();
|
||||
auto emojiData = json["images"_ls].toObject();
|
||||
|
||||
QString url;
|
||||
url = job->contentUri().toString();
|
||||
|
||||
QImage image(location.toLocalFile());
|
||||
QJsonObject imageInfo;
|
||||
imageInfo["w"_ls] = image.width();
|
||||
imageInfo["h"_ls] = image.height();
|
||||
imageInfo["mimetype"_ls] = QMimeDatabase().mimeTypeForFile(location.toLocalFile()).name();
|
||||
imageInfo["size"_ls] = image.sizeInBytes();
|
||||
|
||||
emojiData[QStringLiteral("%1").arg(name)] = QJsonObject({
|
||||
{QStringLiteral("url"), url},
|
||||
{QStringLiteral("info"), imageInfo},
|
||||
{QStringLiteral("body"), location.fileName()},
|
||||
{"usage"_ls, "emoticon"_ls},
|
||||
});
|
||||
|
||||
json["images"_ls] = emojiData;
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, json);
|
||||
});
|
||||
}
|
||||
|
||||
void CustomEmojiModel::removeEmoji(const QString &name)
|
||||
{
|
||||
using namespace Quotient;
|
||||
|
||||
const auto &data = m_connection->accountData("im.ponies.user_emotes"_ls);
|
||||
Q_ASSERT(data);
|
||||
auto json = data->contentJson();
|
||||
const QString _name = name.mid(1).chopped(1);
|
||||
auto emojiData = json["images"_ls].toObject();
|
||||
|
||||
if (emojiData.contains(name)) {
|
||||
emojiData.remove(name);
|
||||
json["images"_ls] = emojiData;
|
||||
}
|
||||
if (emojiData.contains(_name)) {
|
||||
emojiData.remove(_name);
|
||||
json["images"_ls] = emojiData;
|
||||
}
|
||||
emojiData = json["emoticons"_ls].toObject();
|
||||
if (emojiData.contains(name)) {
|
||||
emojiData.remove(name);
|
||||
json["emoticons"_ls] = emojiData;
|
||||
}
|
||||
if (emojiData.contains(_name)) {
|
||||
emojiData.remove(_name);
|
||||
json["emoticons"_ls] = emojiData;
|
||||
}
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, json);
|
||||
}
|
||||
|
||||
CustomEmojiModel::CustomEmojiModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
connect(this, &CustomEmojiModel::connectionChanged, this, [this]() {
|
||||
if (!m_connection) {
|
||||
return;
|
||||
}
|
||||
CustomEmojiModel::fetchEmojis();
|
||||
connect(m_connection, &Connection::accountDataChanged, this, [this](const QString &id) {
|
||||
if (id != QStringLiteral("im.ponies.user_emotes")) {
|
||||
return;
|
||||
}
|
||||
fetchEmojis();
|
||||
});
|
||||
});
|
||||
CustomEmojiModel::fetchEmojis();
|
||||
}
|
||||
|
||||
QVariant CustomEmojiModel::data(const QModelIndex &idx, int role) const
|
||||
{
|
||||
const auto row = idx.row();
|
||||
if (row >= m_emojis.length()) {
|
||||
return QVariant();
|
||||
}
|
||||
const auto &data = m_emojis[row];
|
||||
|
||||
switch (Roles(role)) {
|
||||
case Roles::ModelData:
|
||||
return QVariant::fromValue(Emoji(m_connection->makeMediaUrl(QUrl(data.url)).toString(), data.name, true));
|
||||
case Roles::Name:
|
||||
case Roles::DisplayRole:
|
||||
case Roles::ReplacedTextRole:
|
||||
return data.name;
|
||||
case Roles::ImageURL:
|
||||
return m_connection->makeMediaUrl(QUrl(data.url));
|
||||
case Roles::MxcUrl:
|
||||
return m_connection->makeMediaUrl(QUrl(data.url));
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int CustomEmojiModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return m_emojis.length();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> CustomEmojiModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{Name, "name"},
|
||||
{ImageURL, "imageURL"},
|
||||
{ModelData, "modelData"},
|
||||
{MxcUrl, "mxcUrl"},
|
||||
};
|
||||
}
|
||||
|
||||
QString CustomEmojiModel::preprocessText(QString text)
|
||||
{
|
||||
for (const auto &emoji : std::as_const(m_emojis)) {
|
||||
text.replace(
|
||||
emoji.regexp,
|
||||
QStringLiteral(R"(<img data-mx-emoticon="" src="%1" alt="%2" title="%2" height="32" vertical-align="middle" />)").arg(emoji.url, emoji.name));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
QVariantList CustomEmojiModel::filterModel(const QString &filter)
|
||||
{
|
||||
QVariantList results;
|
||||
for (const auto &emoji : std::as_const(m_emojis)) {
|
||||
if (results.length() >= 10)
|
||||
break;
|
||||
if (!emoji.name.contains(filter, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
||||
results << QVariant::fromValue(Emoji(m_connection->makeMediaUrl(QUrl(emoji.url)).toString(), emoji.name, true));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
#include "moc_customemojimodel.cpp"
|
||||
@@ -1,116 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carson Black <uhhadd@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QQmlEngine>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
struct CustomEmoji {
|
||||
QString name; // with :semicolons:
|
||||
QString url; // mxc://
|
||||
QRegularExpression regexp;
|
||||
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QString unicode MEMBER url)
|
||||
Q_PROPERTY(QString name MEMBER name)
|
||||
};
|
||||
|
||||
/**
|
||||
* @class CustomEmojiModel
|
||||
*
|
||||
* This class defines the model for custom user emojis.
|
||||
*
|
||||
* This is based upon the im.ponies.user_emotes spec (MSC2545).
|
||||
*/
|
||||
class CustomEmojiModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Defines the model roles.
|
||||
*/
|
||||
enum Roles {
|
||||
Name = Qt::DisplayRole, /**< The name of the emoji. */
|
||||
ImageURL, /**< The URL for the custom emoji. */
|
||||
ModelData, /**< for emulating the regular emoji model's usage, otherwise the UI code would get too complicated. */
|
||||
MxcUrl = 50, /**< The mxc source URL for the custom emoji. */
|
||||
DisplayRole = 51, /**< The name of the emoji. For compatibility with EmojiModel. */
|
||||
ReplacedTextRole = 52, /**< The name of the emoji. For compatibility with EmojiModel. */
|
||||
DescriptionRole = 53, /**< Invalid, reserved. For compatibility with EmojiModel. */
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
static CustomEmojiModel &instance()
|
||||
{
|
||||
static CustomEmojiModel _instance;
|
||||
return _instance;
|
||||
}
|
||||
static CustomEmojiModel *create(QQmlEngine *engine, QJSEngine *)
|
||||
{
|
||||
engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
|
||||
return &instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
*
|
||||
* @sa QAbstractItemModel::data
|
||||
*/
|
||||
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/**
|
||||
* @brief Number of rows in the model.
|
||||
*
|
||||
* @sa QAbstractItemModel::rowCount
|
||||
*/
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
/**
|
||||
* @brief Returns a mapping from Role enum values to role names.
|
||||
*
|
||||
* @sa Roles, QAbstractItemModel::roleNames()
|
||||
*/
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
/**
|
||||
* @brief Substitute any custom emojis for an image in the input text.
|
||||
*/
|
||||
Q_INVOKABLE QString preprocessText(QString text);
|
||||
|
||||
/**
|
||||
* @brief Return a list of custom emojis where the name contains the filter text.
|
||||
*/
|
||||
Q_INVOKABLE QVariantList filterModel(const QString &filter);
|
||||
|
||||
/**
|
||||
* @brief Add a new emoji to the model.
|
||||
*/
|
||||
Q_INVOKABLE void addEmoji(const QString &name, const QUrl &location);
|
||||
|
||||
/**
|
||||
* @brief Remove an emoji from the model.
|
||||
*/
|
||||
Q_INVOKABLE void removeEmoji(const QString &name);
|
||||
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
NeoChatConnection *connection() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void connectionChanged();
|
||||
|
||||
private:
|
||||
explicit CustomEmojiModel(QObject *parent = nullptr);
|
||||
QList<CustomEmoji> m_emojis;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
void fetchEmojis();
|
||||
};
|
||||
@@ -1,242 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include "emojimodel.h"
|
||||
#include "emojitones.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "customemojimodel.h"
|
||||
#include <KLocalizedString>
|
||||
|
||||
EmojiModel::EmojiModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_config(KSharedConfig::openStateConfig())
|
||||
, m_configGroup(KConfigGroup(m_config, QStringLiteral("Editor")))
|
||||
{
|
||||
if (_emojis.isEmpty()) {
|
||||
#include "emojis.h"
|
||||
}
|
||||
}
|
||||
|
||||
int EmojiModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
int total = 0;
|
||||
for (const auto &category : std::as_const(_emojis)) {
|
||||
total += category.count();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
QVariant EmojiModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
auto row = index.row();
|
||||
for (const auto &category : std::as_const(_emojis)) {
|
||||
if (row >= category.count()) {
|
||||
row -= category.count();
|
||||
continue;
|
||||
}
|
||||
auto emoji = category[row].value<Emoji>();
|
||||
switch (role) {
|
||||
case ShortNameRole:
|
||||
return QStringLiteral(":%1:").arg(emoji.shortName);
|
||||
case UnicodeRole:
|
||||
case ReplacedTextRole:
|
||||
return emoji.unicode;
|
||||
case InvalidRole:
|
||||
return QStringLiteral("invalid");
|
||||
case DisplayRole:
|
||||
return QStringLiteral("%2 :%1:").arg(emoji.shortName, emoji.unicode);
|
||||
case DescriptionRole:
|
||||
return emoji.description;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> EmojiModel::roleNames() const
|
||||
{
|
||||
return {{ShortNameRole, "shortName"}, {UnicodeRole, "unicode"}};
|
||||
}
|
||||
|
||||
QStringList EmojiModel::lastUsedEmojis() const
|
||||
{
|
||||
return m_configGroup.readEntry(QStringLiteral("lastUsedEmojis"), QStringList());
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::filterModel(const QString &filter, bool limit)
|
||||
{
|
||||
auto emojis = CustomEmojiModel::instance().filterModel(filter);
|
||||
emojis += filterModelNoCustom(filter, limit);
|
||||
return emojis;
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::filterModelNoCustom(const QString &filter, bool limit)
|
||||
{
|
||||
QVariantList result;
|
||||
|
||||
const auto &values = _emojis.values();
|
||||
for (const auto &e : values) {
|
||||
for (const auto &variant : e) {
|
||||
const auto &emoji = qvariant_cast<Emoji>(variant);
|
||||
if (emoji.shortName.contains(filter, Qt::CaseInsensitive)) {
|
||||
result.append(variant);
|
||||
if (result.length() > 10 && limit) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EmojiModel::emojiUsed(const QVariant &modelData)
|
||||
{
|
||||
auto list = lastUsedEmojis();
|
||||
const auto emoji = modelData.value<Emoji>();
|
||||
|
||||
auto it = list.begin();
|
||||
while (it != list.end()) {
|
||||
if (*it == emoji.shortName) {
|
||||
it = list.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
list.push_front(emoji.shortName);
|
||||
|
||||
m_configGroup.writeEntry(QStringLiteral("lastUsedEmojis"), list);
|
||||
|
||||
Q_EMIT historyChanged();
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::emojis(Category category) const
|
||||
{
|
||||
if (category == History) {
|
||||
return emojiHistory();
|
||||
}
|
||||
if (category == HistoryNoCustom) {
|
||||
QVariantList list;
|
||||
const auto &history = emojiHistory();
|
||||
for (const auto &e : history) {
|
||||
auto emoji = qvariant_cast<Emoji>(e);
|
||||
if (!emoji.isCustom) {
|
||||
list.append(e);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
if (category == Custom) {
|
||||
return CustomEmojiModel::instance().filterModel({});
|
||||
}
|
||||
return _emojis[category];
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::tones(const QString &baseEmoji) const
|
||||
{
|
||||
if (baseEmoji.endsWith(QStringLiteral("tone"))) {
|
||||
return EmojiTones::_tones.values(baseEmoji.split(QStringLiteral(":"))[0]);
|
||||
}
|
||||
return EmojiTones::_tones.values(baseEmoji);
|
||||
}
|
||||
|
||||
QHash<EmojiModel::Category, QVariantList> EmojiModel::_emojis;
|
||||
|
||||
QVariantList EmojiModel::categories() const
|
||||
{
|
||||
return QVariantList{
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::HistoryNoCustom},
|
||||
{QStringLiteral("name"), i18nc("Previously used emojis", "History")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("⌛️")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Smileys},
|
||||
{QStringLiteral("name"), i18nc("'Smileys' is a category of emoji", "Smileys")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("😏")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::People},
|
||||
{QStringLiteral("name"), i18nc("'People' is a category of emoji", "People")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🙋♂️")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Nature},
|
||||
{QStringLiteral("name"), i18nc("'Nature' is a category of emoji", "Nature")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🌲")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Food},
|
||||
{QStringLiteral("name"), i18nc("'Food' is a category of emoji", "Food")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🍛")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Activities},
|
||||
{QStringLiteral("name"), i18nc("'Activities' is a category of emoji", "Activities")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🚁")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Travel},
|
||||
{QStringLiteral("name"), i18nc("'Travel' is a category of emoji", "Travel")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🚅")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Objects},
|
||||
{QStringLiteral("name"), i18nc("'Objects' is a category of emoji", "Objects")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("💡")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Symbols},
|
||||
{QStringLiteral("name"), i18nc("'Symbols' is a category of emoji", "Symbols")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🔣")},
|
||||
}},
|
||||
{QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Flags},
|
||||
{QStringLiteral("name"), i18nc("'Flags' is a category of emoji", "Flags")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🏁")},
|
||||
}},
|
||||
};
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::categoriesWithCustom() const
|
||||
{
|
||||
auto cats = categories();
|
||||
cats.removeAt(0);
|
||||
cats.insert(0,
|
||||
QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::History},
|
||||
{QStringLiteral("name"), i18nc("Previously used emojis", "History")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("⌛️")},
|
||||
});
|
||||
cats.insert(1,
|
||||
QVariantMap{
|
||||
{QStringLiteral("category"), EmojiModel::Custom},
|
||||
{QStringLiteral("name"), i18nc("'Custom' is a category of emoji", "Custom")},
|
||||
{QStringLiteral("emoji"), QStringLiteral("🖼️")},
|
||||
});
|
||||
;
|
||||
return cats;
|
||||
}
|
||||
|
||||
QVariantList EmojiModel::emojiHistory() const
|
||||
{
|
||||
QVariantList list;
|
||||
const auto &lastUsed = lastUsedEmojis();
|
||||
for (const auto &historicEmoji : lastUsed) {
|
||||
for (const auto &emojiCategory : std::as_const(_emojis)) {
|
||||
for (const auto &emoji : emojiCategory) {
|
||||
if (qvariant_cast<Emoji>(emoji).shortName == historicEmoji) {
|
||||
list.append(emoji);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
#include "moc_emojimodel.cpp"
|
||||
@@ -1,184 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2018 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
struct Emoji {
|
||||
Emoji(QString unicode, QString shortname, bool isCustom = false)
|
||||
: unicode(std::move(unicode))
|
||||
, shortName(std::move(shortname))
|
||||
, isCustom(isCustom)
|
||||
{
|
||||
}
|
||||
Emoji(QString unicode, QString shortname, QString description)
|
||||
: unicode(std::move(unicode))
|
||||
, shortName(std::move(shortname))
|
||||
, description(std::move(description))
|
||||
{
|
||||
}
|
||||
Emoji() = default;
|
||||
|
||||
QString unicode;
|
||||
QString shortName;
|
||||
QString description;
|
||||
bool isCustom = false;
|
||||
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QString unicode MEMBER unicode)
|
||||
Q_PROPERTY(QString shortName MEMBER shortName)
|
||||
Q_PROPERTY(QString description MEMBER description)
|
||||
Q_PROPERTY(bool isCustom MEMBER isCustom)
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Emoji)
|
||||
|
||||
/**
|
||||
* @class EmojiModel
|
||||
*
|
||||
* This class defines the model for visualising a list of emojis.
|
||||
*/
|
||||
class EmojiModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
/**
|
||||
* @brief Return a list of emoji categories.
|
||||
*
|
||||
* @note No custom emoji categories will be included.
|
||||
*/
|
||||
Q_PROPERTY(QVariantList categories READ categories CONSTANT)
|
||||
|
||||
/**
|
||||
* @brief Return a list of emoji categories with custom emojis.
|
||||
*/
|
||||
Q_PROPERTY(QVariantList categoriesWithCustom READ categoriesWithCustom CONSTANT)
|
||||
|
||||
public:
|
||||
static EmojiModel &instance()
|
||||
{
|
||||
static EmojiModel _instance;
|
||||
return _instance;
|
||||
}
|
||||
static EmojiModel *create(QQmlEngine *engine, QJSEngine *)
|
||||
{
|
||||
engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
|
||||
return &instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Defines the model roles.
|
||||
*/
|
||||
enum RoleNames {
|
||||
ShortNameRole = Qt::DisplayRole, /**< The name of the emoji. */
|
||||
UnicodeRole, /**< The unicode character of the emoji. */
|
||||
InvalidRole = 50, /**< Invalid, reserved. */
|
||||
DisplayRole = 51, /**< The display text for an emoji. */
|
||||
ReplacedTextRole = 52, /**< The text to replace the short name with (i.e. the unicode character). */
|
||||
DescriptionRole = 53, /**< The long description of an emoji. */
|
||||
};
|
||||
Q_ENUM(RoleNames)
|
||||
|
||||
/**
|
||||
* @brief Defines the potential categories an emoji can be placed in.
|
||||
*/
|
||||
enum Category {
|
||||
Custom, /**< A custom user emoji. */
|
||||
Search, /**< The results of a filter. */
|
||||
SearchNoCustom, /**< The results of a filter with no custom emojis. */
|
||||
History, /**< Recently used emojis. */
|
||||
HistoryNoCustom, /**< Recently used emojis with no custom emojis. */
|
||||
Smileys, /**< Smileys & emotion emojis. */
|
||||
People, /**< People & Body emojis. */
|
||||
Nature, /**< Animals & Nature emojis. */
|
||||
Food, /**< Food & Drink emojis. */
|
||||
Activities, /**< Activities emojis. */
|
||||
Travel, /**< Travel & Places emojis. */
|
||||
Objects, /**< Objects emojis. */
|
||||
Symbols, /**< Symbols emojis. */
|
||||
Flags, /**< Flags emojis. */
|
||||
Component, /**< ??? */
|
||||
};
|
||||
Q_ENUM(Category)
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
*
|
||||
* @sa QAbstractItemModel::data
|
||||
*/
|
||||
[[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/**
|
||||
* @brief Number of rows in the model.
|
||||
*
|
||||
* @sa QAbstractItemModel::rowCount
|
||||
*/
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
/**
|
||||
* @brief Returns a mapping from Role enum values to role names.
|
||||
*
|
||||
* @sa RoleNames, QAbstractItemModel::roleNames()
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
/**
|
||||
* @brief Return a filtered list of emojis.
|
||||
*
|
||||
* @note This includes custom emojis, use filterModelNoCustom to return a result
|
||||
* without custom emojis.
|
||||
*
|
||||
* @sa filterModelNoCustom
|
||||
*/
|
||||
Q_INVOKABLE static QVariantList filterModel(const QString &filter, bool limit = true);
|
||||
|
||||
/**
|
||||
* @brief Return a filtered list of emojis without custom emojis.
|
||||
*
|
||||
* @note Use filterModel to return a result with custom emojis.
|
||||
*
|
||||
* @sa filterModel
|
||||
*/
|
||||
Q_INVOKABLE static QVariantList filterModelNoCustom(const QString &filter, bool limit = true);
|
||||
|
||||
/**
|
||||
* @brief Return a list of emojis for the given category.
|
||||
*/
|
||||
Q_INVOKABLE QVariantList emojis(Category category) const;
|
||||
|
||||
/**
|
||||
* @brief Return a list of emoji tones for the given base emoji.
|
||||
*/
|
||||
Q_INVOKABLE QVariantList tones(const QString &baseEmoji) const;
|
||||
|
||||
/**
|
||||
* @brief Return a list of the last used emoji shortnames
|
||||
*/
|
||||
QStringList lastUsedEmojis() const;
|
||||
|
||||
QVariantList categories() const;
|
||||
QVariantList categoriesWithCustom() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void historyChanged();
|
||||
|
||||
public Q_SLOTS:
|
||||
void emojiUsed(const QVariant &modelData);
|
||||
|
||||
private:
|
||||
static QHash<Category, QVariantList> _emojis;
|
||||
|
||||
/// Returns QVariants containing the last used Emojis
|
||||
QVariantList emojiHistory() const;
|
||||
|
||||
KSharedConfig::Ptr m_config;
|
||||
KConfigGroup m_configGroup;
|
||||
EmojiModel(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "emoticonfiltermodel.h"
|
||||
|
||||
#include "accountemoticonmodel.h"
|
||||
#include "stickermodel.h"
|
||||
|
||||
EmoticonFilterModel::EmoticonFilterModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
connect(this, &EmoticonFilterModel::sourceModelChanged, this, [this]() {
|
||||
if (dynamic_cast<StickerModel *>(sourceModel())) {
|
||||
m_stickerRole = StickerModel::IsStickerRole;
|
||||
m_emojiRole = StickerModel::IsEmojiRole;
|
||||
} else {
|
||||
m_stickerRole = AccountEmoticonModel::IsStickerRole;
|
||||
m_emojiRole = AccountEmoticonModel::IsEmojiRole;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool EmoticonFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
Q_UNUSED(sourceParent);
|
||||
auto stickerUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), m_stickerRole).toBool();
|
||||
auto emojiUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), m_emojiRole).toBool();
|
||||
return (stickerUsage && m_showStickers) || (emojiUsage && m_showEmojis);
|
||||
}
|
||||
|
||||
bool EmoticonFilterModel::showStickers() const
|
||||
{
|
||||
return m_showStickers;
|
||||
}
|
||||
|
||||
void EmoticonFilterModel::setShowStickers(bool showStickers)
|
||||
{
|
||||
beginResetModel();
|
||||
m_showStickers = showStickers;
|
||||
endResetModel();
|
||||
Q_EMIT showStickersChanged();
|
||||
}
|
||||
|
||||
bool EmoticonFilterModel::showEmojis() const
|
||||
{
|
||||
return m_showEmojis;
|
||||
}
|
||||
|
||||
void EmoticonFilterModel::setShowEmojis(bool showEmojis)
|
||||
{
|
||||
beginResetModel();
|
||||
m_showEmojis = showEmojis;
|
||||
endResetModel();
|
||||
Q_EMIT showEmojisChanged();
|
||||
}
|
||||
|
||||
#include "moc_emoticonfiltermodel.cpp"
|
||||
@@ -1,55 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
/**
|
||||
* @class EmoticonFilterModel
|
||||
*
|
||||
* This class creates a custom QSortFilterProxyModel for filtering a emoticon by type
|
||||
* (Sticker or Emoji).
|
||||
*/
|
||||
class EmoticonFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
/**
|
||||
* @brief Whether stickers should be shown
|
||||
*/
|
||||
Q_PROPERTY(bool showStickers READ showStickers WRITE setShowStickers NOTIFY showStickersChanged)
|
||||
|
||||
/**
|
||||
* @brief Whether emojis show be shown
|
||||
*/
|
||||
Q_PROPERTY(bool showEmojis READ showEmojis WRITE setShowEmojis NOTIFY showEmojisChanged)
|
||||
|
||||
public:
|
||||
explicit EmoticonFilterModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Custom filter function checking the type of emoticon
|
||||
*
|
||||
* @note The filter cannot be modified and will always use the same filter properties.
|
||||
*/
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
[[nodiscard]] bool showStickers() const;
|
||||
void setShowStickers(bool showStickers);
|
||||
|
||||
[[nodiscard]] bool showEmojis() const;
|
||||
void setShowEmojis(bool showEmojis);
|
||||
|
||||
Q_SIGNALS:
|
||||
void showStickersChanged();
|
||||
void showEmojisChanged();
|
||||
|
||||
private:
|
||||
bool m_showStickers = false;
|
||||
bool m_showEmojis = false;
|
||||
int m_stickerRole = 0;
|
||||
int m_emojiRole = 0;
|
||||
};
|
||||
@@ -1,170 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "imagepacksmodel.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
ImagePacksModel::ImagePacksModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int ImagePacksModel::rowCount(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
return m_events.count();
|
||||
}
|
||||
|
||||
QVariant ImagePacksModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const auto row = index.row();
|
||||
if (row < 0 || row >= m_events.size()) {
|
||||
return {};
|
||||
}
|
||||
const auto &event = m_events[row];
|
||||
if (role == DisplayNameRole) {
|
||||
if (event.pack->displayName) {
|
||||
return *event.pack->displayName;
|
||||
}
|
||||
}
|
||||
if (role == AvatarUrlRole) {
|
||||
if (event.pack->avatarUrl) {
|
||||
return m_room->connection()->makeMediaUrl(*event.pack->avatarUrl);
|
||||
} else if (!event.images.empty()) {
|
||||
return m_room->connection()->makeMediaUrl(event.images[0].url);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ImagePacksModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{DisplayNameRole, "displayName"},
|
||||
{AvatarUrlRole, "avatarUrl"},
|
||||
{AttributionRole, "attribution"},
|
||||
{IdRole, "id"},
|
||||
};
|
||||
}
|
||||
|
||||
NeoChatRoom *ImagePacksModel::room() const
|
||||
{
|
||||
return m_room;
|
||||
}
|
||||
|
||||
void ImagePacksModel::setRoom(NeoChatRoom *room)
|
||||
{
|
||||
if (m_room) {
|
||||
disconnect(m_room, nullptr, this, nullptr);
|
||||
disconnect(m_room->connection(), nullptr, this, nullptr);
|
||||
}
|
||||
m_room = room;
|
||||
|
||||
if (m_room) {
|
||||
connect(m_room->connection(), &Connection::accountDataChanged, this, [this](const QString &type) {
|
||||
if (type == "im.ponies.user_emotes"_ls) {
|
||||
reloadImages();
|
||||
}
|
||||
});
|
||||
}
|
||||
// TODO listen to packs changing
|
||||
reloadImages();
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
void ImagePacksModel::reloadImages()
|
||||
{
|
||||
if (!m_room) {
|
||||
return;
|
||||
}
|
||||
beginResetModel();
|
||||
m_events.clear();
|
||||
|
||||
// Load emoticons from the account data
|
||||
if (m_room->connection()->hasAccountData("im.ponies.user_emotes"_ls)) {
|
||||
auto json = m_room->connection()->accountData("im.ponies.user_emotes"_ls)->contentJson();
|
||||
json["pack"_ls] = QJsonObject{
|
||||
{"display_name"_ls,
|
||||
m_showStickers ? i18nc("As in 'The user's own Stickers'", "Own Stickers") : i18nc("As in 'The user's own emojis", "Own Emojis")},
|
||||
};
|
||||
const auto &content = ImagePackEventContent(json);
|
||||
if (!content.images.isEmpty()) {
|
||||
m_events += ImagePackEventContent(json);
|
||||
}
|
||||
}
|
||||
|
||||
// Load emoticons from the saved rooms
|
||||
const auto &accountData = m_room->connection()->accountData("im.ponies.emote_rooms"_ls);
|
||||
if (accountData) {
|
||||
const auto &rooms = accountData->contentJson()["rooms"_ls].toObject();
|
||||
for (const auto &roomId : rooms.keys()) {
|
||||
if (roomId == m_room->id()) {
|
||||
continue;
|
||||
}
|
||||
auto packs = rooms[roomId].toObject();
|
||||
const auto &stickerRoom = m_room->connection()->room(roomId);
|
||||
if (!stickerRoom) {
|
||||
continue;
|
||||
}
|
||||
for (const auto &packKey : packs.keys()) {
|
||||
if (const auto &pack = stickerRoom->currentState().get<ImagePackEvent>(packKey)) {
|
||||
const auto packContent = pack->content();
|
||||
if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon"_ls) && showEmoticons())
|
||||
|| (packContent.pack->usage->contains("sticker"_ls) && showStickers()))
|
||||
&& !packContent.images.isEmpty()) {
|
||||
m_events += packContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load emoticons from the current room
|
||||
auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes"_ls);
|
||||
for (const auto &event : events) {
|
||||
auto packContent = eventCast<const ImagePackEvent>(event)->content();
|
||||
if (packContent.pack.has_value()) {
|
||||
if (!packContent.pack->usage || (packContent.pack->usage->contains("emoticon"_ls) && showEmoticons())
|
||||
|| (packContent.pack->usage->contains("sticker"_ls) && showStickers())) {
|
||||
m_events += packContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
Q_EMIT imagesLoaded();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
bool ImagePacksModel::showStickers() const
|
||||
{
|
||||
return m_showStickers;
|
||||
}
|
||||
|
||||
void ImagePacksModel::setShowStickers(bool showStickers)
|
||||
{
|
||||
m_showStickers = showStickers;
|
||||
Q_EMIT showStickersChanged();
|
||||
}
|
||||
|
||||
bool ImagePacksModel::showEmoticons() const
|
||||
{
|
||||
return m_showEmoticons;
|
||||
}
|
||||
|
||||
void ImagePacksModel::setShowEmoticons(bool showEmoticons)
|
||||
{
|
||||
m_showEmoticons = showEmoticons;
|
||||
Q_EMIT showEmoticonsChanged();
|
||||
}
|
||||
QList<Quotient::ImagePackEventContent::ImagePackImage> ImagePacksModel::images(int index)
|
||||
{
|
||||
if (index < 0 || index >= m_events.size()) {
|
||||
return {};
|
||||
}
|
||||
return m_events[index].images;
|
||||
}
|
||||
|
||||
#include "moc_imagepacksmodel.cpp"
|
||||
@@ -1,103 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021-2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "events/imagepackevent.h"
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class NeoChatRoom;
|
||||
|
||||
/**
|
||||
* @class ImagePacksModel
|
||||
*
|
||||
* Defines the model for visualising image packs.
|
||||
*
|
||||
* See Matrix MSC2545 for more details on image packs.
|
||||
* https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md
|
||||
*/
|
||||
class ImagePacksModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
/**
|
||||
* @brief The current room that the model is being used in.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
|
||||
|
||||
/**
|
||||
* @brief Whether sticker image packs should be shown.
|
||||
*/
|
||||
Q_PROPERTY(bool showStickers READ showStickers WRITE setShowStickers NOTIFY showStickersChanged)
|
||||
|
||||
/**
|
||||
* @brief Whether emoticon image packs should be shown.
|
||||
*/
|
||||
Q_PROPERTY(bool showEmoticons READ showEmoticons WRITE setShowEmoticons NOTIFY showEmoticonsChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Defines the model roles.
|
||||
*/
|
||||
enum Roles {
|
||||
DisplayNameRole = Qt::DisplayRole, /**< The display name of the image pack. */
|
||||
AvatarUrlRole, /**< The source mxc URL for the pack avatar. */
|
||||
AttributionRole, /**< The attribution for the pack author(s). */
|
||||
IdRole, /**< The ID of the image pack. */
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
explicit ImagePacksModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
*
|
||||
* @sa QAbstractItemModel::data
|
||||
*/
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
/**
|
||||
* @brief Number of rows in the model.
|
||||
*
|
||||
* @sa QAbstractItemModel::rowCount
|
||||
*/
|
||||
[[nodiscard]] int rowCount(const QModelIndex &index) const override;
|
||||
|
||||
/**
|
||||
* @brief Returns a mapping from Role enum values to role names.
|
||||
*
|
||||
* @sa Roles, QAbstractItemModel::roleNames()
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] NeoChatRoom *room() const;
|
||||
void setRoom(NeoChatRoom *room);
|
||||
|
||||
[[nodiscard]] bool showStickers() const;
|
||||
void setShowStickers(bool showStickers);
|
||||
|
||||
[[nodiscard]] bool showEmoticons() const;
|
||||
void setShowEmoticons(bool showEmoticons);
|
||||
|
||||
/**
|
||||
* @brief Return a vector of the images in the pack at the given index.
|
||||
*/
|
||||
[[nodiscard]] QList<Quotient::ImagePackEventContent::ImagePackImage> images(int index);
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void showStickersChanged();
|
||||
void showEmoticonsChanged();
|
||||
void imagesLoaded();
|
||||
|
||||
private:
|
||||
QPointer<NeoChatRoom> m_room;
|
||||
QList<Quotient::ImagePackEventContent> m_events;
|
||||
bool m_showStickers = true;
|
||||
bool m_showEmoticons = true;
|
||||
void reloadImages();
|
||||
};
|
||||
@@ -588,15 +588,22 @@ QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentT
|
||||
case MessageComponentType::Video: {
|
||||
if (!event.first->is<StickerEvent>()) {
|
||||
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event.first);
|
||||
QList<MessageComponent> components;
|
||||
components += MessageComponent{type, QString(), {}};
|
||||
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
||||
components += TextHandler().textComponents(body,
|
||||
EventHandler::messageBodyInputFormat(*roomMessageEvent),
|
||||
m_room,
|
||||
roomMessageEvent,
|
||||
roomMessageEvent->isReplaced());
|
||||
return components;
|
||||
const auto fileContent = roomMessageEvent->get<EventContent::FileContentBase>();
|
||||
if (fileContent != nullptr) {
|
||||
const auto fileInfo = fileContent->commonInfo();
|
||||
const auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
||||
// Do not attach the description to the image, if it's the same as the original filename.
|
||||
if (fileInfo.originalName != body) {
|
||||
QList<MessageComponent> components;
|
||||
components += MessageComponent{type, QString(), {}};
|
||||
components += TextHandler().textComponents(body,
|
||||
EventHandler::messageBodyInputFormat(*roomMessageEvent),
|
||||
m_room,
|
||||
roomMessageEvent,
|
||||
roomMessageEvent->isReplaced());
|
||||
return components;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -212,7 +212,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
|
||||
return room->displayName().toHtmlEscaped();
|
||||
}
|
||||
if (role == AvatarRole) {
|
||||
return room->avatarMediaId();
|
||||
return room->avatarMediaUrl();
|
||||
}
|
||||
if (role == CanonicalAliasRole) {
|
||||
return room->canonicalAlias();
|
||||
|
||||
@@ -324,7 +324,7 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
|
||||
return room->displayName();
|
||||
}
|
||||
if (role == AvatarRole) {
|
||||
return room->avatarMediaId();
|
||||
return room->avatarMediaUrl();
|
||||
}
|
||||
if (role == CanonicalAliasRole) {
|
||||
return room->canonicalAlias();
|
||||
|
||||
@@ -261,7 +261,7 @@ Action=Popup
|
||||
Name=Share
|
||||
Name[ar]=شارك
|
||||
Name[ca]=Compartició
|
||||
Name[ca@valencia]=Compartició
|
||||
Name[ca@valencia]=Compartiu
|
||||
Name[cs]=Sdílet
|
||||
Name[de]=Teilen
|
||||
Name[el]=Κοινοποίηση
|
||||
|
||||
@@ -431,9 +431,9 @@ QDateTime NeoChatRoom::lastActiveTime()
|
||||
return messageEvents().rbegin()->get()->originTimestamp();
|
||||
}
|
||||
|
||||
QString NeoChatRoom::avatarMediaId() const
|
||||
QUrl NeoChatRoom::avatarMediaUrl() const
|
||||
{
|
||||
if (const auto avatar = Room::avatarMediaId(); !avatar.isEmpty()) {
|
||||
if (const auto avatar = Room::avatarUrl(); !avatar.isEmpty()) {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ QString NeoChatRoom::avatarMediaId() const
|
||||
const auto directChatMembers = this->directChatMembers();
|
||||
for (const auto member : directChatMembers) {
|
||||
if (member != localMember()) {
|
||||
return member.avatarMediaId();
|
||||
return member.avatarUrl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ class NeoChatRoom : public Quotient::Room
|
||||
Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged)
|
||||
|
||||
/**
|
||||
* @brief The avatar image to be used for the room.
|
||||
* @brief The avatar image to be used for the room, as a mxc:// URL.
|
||||
*/
|
||||
Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false)
|
||||
Q_PROPERTY(QUrl avatarMediaUrl READ avatarMediaUrl NOTIFY avatarChanged STORED false)
|
||||
|
||||
/**
|
||||
* @brief Get a RoomMember object for the other person in a direct chat.
|
||||
@@ -320,7 +320,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool readMarkerLoaded() const;
|
||||
|
||||
[[nodiscard]] QString avatarMediaId() const;
|
||||
[[nodiscard]] QUrl avatarMediaUrl() const;
|
||||
|
||||
NeochatRoomMember *directChatRemoteMember();
|
||||
|
||||
|
||||
@@ -153,15 +153,6 @@ QColor NeochatRoomMember::color() const
|
||||
return m_room->member(m_memberId).color();
|
||||
}
|
||||
|
||||
QString NeochatRoomMember::avatarMediaId() const
|
||||
{
|
||||
if (m_room == nullptr || m_memberId.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return m_room->member(m_memberId).avatarMediaId();
|
||||
}
|
||||
|
||||
QUrl NeochatRoomMember::avatarUrl() const
|
||||
{
|
||||
if (m_room == nullptr || m_memberId.isEmpty()) {
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
int hue() const;
|
||||
qreal hueF() const;
|
||||
QColor color() const;
|
||||
QString avatarMediaId() const;
|
||||
QUrl avatarUrl() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
@@ -27,7 +27,8 @@ QQC2.Menu {
|
||||
text: "https://matrix.to/#/" + root.connection.localUser.id,
|
||||
title: root.connection.localUser.displayName,
|
||||
subtitle: root.connection.localUser.id,
|
||||
avatarSource: root.connection.makeMediaUrl(root.connection.localUser.avatarUrl)
|
||||
// Note: User::avatarUrl does not set user_id, and thus cannot be used directly here. Hence the makeMediaUrl.
|
||||
avatarSource: root.connection.localUser.avatarUrl.toString().length > 0 ? root.connection.makeMediaUrl(root.connection.localUser.avatarUrl) : ""
|
||||
});
|
||||
if (typeof root.closeDialog === "function") {
|
||||
root.closeDialog();
|
||||
|
||||
@@ -125,7 +125,7 @@ Kirigami.Dialog {
|
||||
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
|
||||
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
|
||||
}
|
||||
source: userDelegate.connection.localUser.avatarMediaId ? userDelegate.connection.makeMediaUrl("mxc://" + userDelegate.connection.localUser.avatarMediaId) : ""
|
||||
source: userDelegate.connection.localUser.avatarUrl.toString().length > 0 ? userDelegate.connection.makeMediaUrl(userDelegate.connection.localUser.avatarUrl) : ""
|
||||
name: userDelegate.connection.localUser.displayName ?? userDelegate.connection.localUser.id
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ QQC2.ItemDelegate {
|
||||
required property NeoChatRoom currentRoom
|
||||
required property bool categoryVisible
|
||||
required property string filterText
|
||||
required property string avatar
|
||||
required property url avatar
|
||||
required property string displayName
|
||||
|
||||
topPadding: Kirigami.Units.largeSpacing
|
||||
@@ -32,7 +32,7 @@ QQC2.ItemDelegate {
|
||||
visible: root.categoryVisible || filterText.length > 0
|
||||
|
||||
contentItem: KirigamiComponents.Avatar {
|
||||
source: root.avatar ? root.currentRoom.connection.makeMediaUrl("mxc://" + root.avatar) : ""
|
||||
source: root.avatar
|
||||
name: root.displayName
|
||||
|
||||
sourceSize {
|
||||
|
||||
@@ -27,38 +27,17 @@ Loader {
|
||||
Component {
|
||||
id: regularMenu
|
||||
QQC2.Menu {
|
||||
QQC2.MenuItem {
|
||||
text: room.isFavourite ? i18n("Remove from Favorites") : i18n("Add to Favorites")
|
||||
icon.name: room.isFavourite ? "bookmark-remove" : "bookmark-new"
|
||||
onTriggered: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0)
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: room.isLowPriority ? i18n("Reprioritize") : i18n("Deprioritize")
|
||||
icon.name: room.isLowPriority ? "arrow-up-symbolic" : "arrow-down-symbolic"
|
||||
onTriggered: room.isLowPriority ? room.removeTag("m.lowpriority") : room.addTag("m.lowpriority", 1.0)
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18n("Mark as Read")
|
||||
icon.name: "checkmark"
|
||||
enabled: room.notificationCount > 0
|
||||
onTriggered: room.markAllMessagesAsRead()
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: room.isDirectChat() ? i18nc("@action:inmenu", "Copy user's Matrix ID to Clipboard") : i18nc("@action:inmenu", "Copy Address to Clipboard")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: if (room.isDirectChat()) {
|
||||
Clipboard.saveText(room.directChatRemoteMember.id);
|
||||
} else if (room.canonicalAlias.length === 0) {
|
||||
Clipboard.saveText(room.id);
|
||||
} else {
|
||||
Clipboard.saveText(room.canonicalAlias);
|
||||
}
|
||||
}
|
||||
QQC2.MenuSeparator {}
|
||||
|
||||
QQC2.Menu {
|
||||
title: i18n("Notification State")
|
||||
title: i18nc("@action:inmenu", "Notifications")
|
||||
icon.name: "notifications"
|
||||
|
||||
QQC2.MenuItem {
|
||||
@@ -107,6 +86,32 @@ Loader {
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: room.isFavourite ? i18n("Remove from Favorites") : i18n("Add to Favorites")
|
||||
icon.name: room.isFavourite ? "rating" : "rating-unrated"
|
||||
onTriggered: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0)
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: room.isLowPriority ? i18n("Reprioritize") : i18n("Deprioritize")
|
||||
icon.name: room.isLowPriority ? "arrow-up-symbolic" : "arrow-down-symbolic"
|
||||
onTriggered: room.isLowPriority ? room.removeTag("m.lowpriority") : room.addTag("m.lowpriority", 1.0)
|
||||
}
|
||||
|
||||
QQC2.MenuSeparator {}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: room.isDirectChat() ? i18nc("@action:inmenu", "Copy user's Matrix ID to Clipboard") : i18nc("@action:inmenu", "Copy Address to Clipboard")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: if (room.isDirectChat()) {
|
||||
Clipboard.saveText(room.directChatRemoteMember.id);
|
||||
} else if (room.canonicalAlias.length === 0) {
|
||||
Clipboard.saveText(room.id);
|
||||
} else {
|
||||
Clipboard.saveText(room.canonicalAlias);
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@action:inmenu", "Room Settings")
|
||||
icon.name: 'settings-configure-symbolic'
|
||||
@@ -163,7 +168,7 @@ Loader {
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
KirigamiComponents.Avatar {
|
||||
id: avatar
|
||||
source: room.avatarMediaId ? root.connection.makeMediaUrl("mxc://" + room.avatarMediaId) : ""
|
||||
source: room.avatarMediaUrl
|
||||
name: room.displayName
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 3
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.qmlmodels
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
||||
import org.kde.kirigamiaddons.formcard as FormCard
|
||||
@@ -177,10 +178,25 @@ Loader {
|
||||
|
||||
Repeater {
|
||||
model: root.actions
|
||||
QQC2.MenuItem {
|
||||
visible: modelData.visible
|
||||
action: modelData
|
||||
onClicked: root.item.close()
|
||||
DelegateChooser {
|
||||
role: "separator"
|
||||
DelegateChoice {
|
||||
roleValue: true
|
||||
|
||||
QQC2.MenuSeparator {
|
||||
visible: modelData.visible
|
||||
}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: false
|
||||
|
||||
QQC2.MenuItem {
|
||||
visible: modelData.visible
|
||||
action: modelData
|
||||
onClicked: root.item.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QQC2.Menu {
|
||||
@@ -341,15 +357,30 @@ Loader {
|
||||
id: listViewAction
|
||||
model: root.actions
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
icon.name: modelData.icon.name
|
||||
icon.color: modelData.icon.color ?? undefined
|
||||
enabled: modelData.enabled
|
||||
visible: modelData.visible
|
||||
text: modelData.text
|
||||
onClicked: {
|
||||
modelData.triggered();
|
||||
root.item.close();
|
||||
DelegateChooser {
|
||||
role: "separator"
|
||||
DelegateChoice {
|
||||
roleValue: true
|
||||
|
||||
FormCard.FormDelegateSeparator {
|
||||
visible: modelData.visible
|
||||
}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: false
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
icon.name: modelData.icon.name
|
||||
icon.color: modelData.icon.color ?? undefined
|
||||
enabled: modelData.enabled
|
||||
visible: modelData.visible
|
||||
text: modelData.text
|
||||
onClicked: {
|
||||
modelData.triggered();
|
||||
root.item.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ ColumnLayout {
|
||||
|
||||
contentItem: KirigamiComponents.Avatar {
|
||||
name: root.room ? root.room.displayName : ""
|
||||
source: root.room ? root.room.connection.makeMediaUrl("mxc://" + root.room.avatarMediaId) : ""
|
||||
source: root.room ? root.room.avatarMediaUrl : ""
|
||||
|
||||
Rectangle {
|
||||
visible: root.room.usesEncryption
|
||||
|
||||
60
src/qml/EmojiPickerPackHeader.qml
Normal file
60
src/qml/EmojiPickerPackHeader.qml
Normal file
@@ -0,0 +1,60 @@
|
||||
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
QQC2.ScrollView {
|
||||
id: root
|
||||
|
||||
QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0
|
||||
|
||||
required property var model
|
||||
property int currentIndex: 0
|
||||
readonly property string category: root.model.data(root.model.index(root.currentIndex, 0), ImageContentPackRole.IdentifierRole)
|
||||
|
||||
implicitHeight: Kirigami.Units.iconSizes.large + root.QQC2.ScrollBar.horizontal.height
|
||||
|
||||
ListView {
|
||||
id: categories
|
||||
clip: true
|
||||
focus: true
|
||||
orientation: ListView.Horizontal
|
||||
currentIndex: root.currentIndex
|
||||
|
||||
Keys.onReturnPressed: if (emojiGrid.count > 0) emojiGrid.focus = true
|
||||
Keys.onEnterPressed: if (emojiGrid.count > 0) emojiGrid.focus = true
|
||||
|
||||
KeyNavigation.down: emojiGrid.count > 0 ? emojiGrid : categories
|
||||
KeyNavigation.tab: emojiGrid.count > 0 ? emojiGrid : categories
|
||||
|
||||
keyNavigationEnabled: true
|
||||
keyNavigationWraps: true
|
||||
Keys.forwardTo: searchField
|
||||
interactive: width !== contentWidth
|
||||
|
||||
Component.onCompleted: categories.forceActiveFocus()
|
||||
|
||||
model: root.model
|
||||
|
||||
delegate: EmojiDelegate {
|
||||
id: packDelegate
|
||||
required property string name
|
||||
required property string i18nName
|
||||
width: Kirigami.Units.iconSizes.large
|
||||
height: width
|
||||
checked: categories.currentIndex === model.index
|
||||
toolTip: packDelegate.i18nName
|
||||
text: packDelegate.name
|
||||
|
||||
onClicked: {
|
||||
root.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/qml/EmojiPickerTypeHeader.qml
Normal file
39
src/qml/EmojiPickerTypeHeader.qml
Normal file
@@ -0,0 +1,39 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Kirigami.NavigationTabBar {
|
||||
id: root
|
||||
|
||||
enum EmoticonType {
|
||||
Emoji,
|
||||
Sticker
|
||||
}
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
property var selectedType: EmojiPickerTypeHeader.EmoticonType.Emoji
|
||||
|
||||
background: null
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
id: emojis
|
||||
icon.name: "smiley"
|
||||
text: i18n("Emojis")
|
||||
checked: root.selectedType === EmojiPickerTypeHeader.EmoticonType.Emoji
|
||||
|
||||
onTriggered: root.selectedType = EmojiPickerTypeHeader.EmoticonType.Emoji
|
||||
},
|
||||
Kirigami.Action {
|
||||
id: stickers
|
||||
icon.name: "stickers"
|
||||
text: i18n("Stickers")
|
||||
checked: root.selectedType === EmojiPickerTypeHeader.EmoticonType.Sticker
|
||||
onTriggered: root.selectedType = EmojiPickerTypeHeader.EmoticonType.Sticker
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -42,30 +42,36 @@ DelegateContextMenu {
|
||||
* Each action will be instantiated as a single line in the menu.
|
||||
*/
|
||||
property list<Kirigami.Action> actions: [
|
||||
DelegateContextMenu.ReplyMessageAction {},
|
||||
Kirigami.Action {
|
||||
text: i18n("Open Externally")
|
||||
separator: true
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18nc("@action:inmenu", "Open Image")
|
||||
icon.name: "document-open"
|
||||
onTriggered: {
|
||||
currentRoom.openEventMediaExternally(root.eventId);
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Save As")
|
||||
text: i18nc("@action:inmenu", "Save Image…")
|
||||
icon.name: "document-save"
|
||||
onTriggered: {
|
||||
var dialog = saveAsDialog.createObject(QQC2.Overlay.overlay);
|
||||
dialog.selectedFile = currentRoom.fileNameToDownload(eventId);
|
||||
dialog.open();
|
||||
dialog.currentFile = dialog.folder + "/" + currentRoom.fileNameToDownload(eventId);
|
||||
}
|
||||
},
|
||||
DelegateContextMenu.ReplyMessageAction {},
|
||||
Kirigami.Action {
|
||||
text: i18n("Copy")
|
||||
text: i18nc("@action:inmenu", "Copy Image")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: {
|
||||
currentRoom.copyEventMedia(root.eventId);
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
},
|
||||
Kirigami.Action {
|
||||
visible: author.id === currentRoom.localMember.id || currentRoom.canSendState("redact")
|
||||
text: i18n("Remove")
|
||||
@@ -88,7 +94,13 @@ DelegateContextMenu {
|
||||
},
|
||||
DelegateContextMenu.ReportMessageAction {},
|
||||
DelegateContextMenu.ShowUserAction {},
|
||||
DelegateContextMenu.ViewSourceAction {}
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
visible: viewSourceAction.visible
|
||||
},
|
||||
DelegateContextMenu.ViewSourceAction {
|
||||
id: viewSourceAction
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,7 +102,7 @@ Labs.MenuBar {
|
||||
}
|
||||
Labs.MenuItem {
|
||||
text: i18nc("menu", "About KDE")
|
||||
onTriggered: pageStack.pushDialogLayer(Qt.createComponent("org.kde.kirigamiaddons.formcard", "AboutKDE"))
|
||||
onTriggered: pageStack.pushDialogLayer(Qt.createComponent("org.kde.kirigamiaddons.formcard", "AboutKDEPage"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ ColumnLayout {
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.large
|
||||
|
||||
name: root.room ? root.room.displayName : ""
|
||||
source: root.room ? root.room.connection.makeMediaUrl("mxc://" + root.room.avatarMediaId) : ""
|
||||
source: root.room ? root.room.avatarMediaUrl : ""
|
||||
|
||||
Rectangle {
|
||||
visible: room.usesEncryption
|
||||
@@ -75,6 +75,7 @@ ColumnLayout {
|
||||
textFormat: TextEdit.PlainText
|
||||
visible: root.room && root.room.canonicalAlias
|
||||
text: root.room && root.room.canonicalAlias ? root.room.canonicalAlias : ""
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
}
|
||||
}
|
||||
QQC2.AbstractButton {
|
||||
@@ -92,7 +93,7 @@ ColumnLayout {
|
||||
text: barcode.content,
|
||||
title: root.room ? root.room.displayName : "",
|
||||
subtitle: root.room ? root.room.id : "",
|
||||
avatarSource: root.room && root.room.avatarMediaId ? root.room.connection.makeMediaUrl("mxc://" + root.room.avatarMediaId) : ""
|
||||
avatarSource: root.room ? root.room.avatarMediaUrl : ""
|
||||
});
|
||||
map.open();
|
||||
}
|
||||
|
||||
@@ -156,7 +156,6 @@ QQC2.Control {
|
||||
EmojiDialog {
|
||||
id: emojiDialog
|
||||
currentRoom: root.currentRoom
|
||||
showQuickReaction: true
|
||||
onChosen: emoji => {
|
||||
root.currentRoom.toggleReaction(root.delegate.eventId, emoji);
|
||||
if (!Kirigami.Settings.isMobile) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import QtQuick.Layouts
|
||||
import QtCore as Core
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
||||
import org.kde.kquickimageeditor as KQuickImageEditor
|
||||
|
||||
Kirigami.Page {
|
||||
@@ -168,10 +167,11 @@ Kirigami.Page {
|
||||
}
|
||||
}
|
||||
|
||||
footer: KirigamiComponents.Banner {
|
||||
footer: Kirigami.InlineMessage {
|
||||
id: msg
|
||||
type: Kirigami.MessageType.Error
|
||||
showCloseButton: true
|
||||
visible: false
|
||||
position: Kirigami.InlineMessage.Position.Header
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ Kirigami.ApplicationWindow {
|
||||
}
|
||||
|
||||
onConnectionChanged: {
|
||||
CustomEmojiModel.connection = root.connection;
|
||||
SpaceHierarchyCache.connection = root.connection;
|
||||
NeoChatSettingsView.connection = root.connection;
|
||||
if (ShareHandler.text && root.connection) {
|
||||
@@ -176,7 +175,6 @@ Kirigami.ApplicationWindow {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
CustomEmojiModel.connection = root.connection;
|
||||
SpaceHierarchyCache.connection = root.connection;
|
||||
RoomSettingsView.window = root;
|
||||
NeoChatSettingsView.window = root;
|
||||
|
||||
@@ -44,7 +44,7 @@ DelegateContextMenu {
|
||||
},
|
||||
DelegateContextMenu.ReplyMessageAction {},
|
||||
Kirigami.Action {
|
||||
text: i18nc("@action:inmenu As in 'Forward this message'", "Forward")
|
||||
text: i18nc("@action:inmenu As in 'Forward this message'", "Forward…")
|
||||
icon.name: "mail-forward-symbolic"
|
||||
onTriggered: {
|
||||
let page = applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ChooseRoomDialog'), {
|
||||
@@ -59,21 +59,33 @@ DelegateContextMenu {
|
||||
});
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
},
|
||||
DelegateContextMenu.RemoveMessageAction {},
|
||||
Kirigami.Action {
|
||||
text: i18n("Copy")
|
||||
text: i18nc("@action:inmenu", "Copy Text")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: Clipboard.saveText(root.selectedText.length > 0 ? root.selectedText : root.plainText)
|
||||
},
|
||||
DelegateContextMenu.ReportMessageAction {},
|
||||
DelegateContextMenu.ShowUserAction {},
|
||||
DelegateContextMenu.ViewSourceAction {},
|
||||
Kirigami.Action {
|
||||
text: i18n("Copy Link")
|
||||
text: i18nc("@action:inmenu", "Copy Message Link")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: {
|
||||
Clipboard.saveText("https://matrix.to/#/" + currentRoom.id + "/" + root.eventId);
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
},
|
||||
DelegateContextMenu.ReportMessageAction {},
|
||||
DelegateContextMenu.ShowUserAction {},
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
visible: viewSourceAction.visible
|
||||
},
|
||||
DelegateContextMenu.ViewSourceAction {
|
||||
id: viewSourceAction
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -110,8 +110,8 @@ Components.AlbumMaximizeComponent {
|
||||
|
||||
onSaveItem: {
|
||||
var dialog = saveAsDialog.createObject(QQC2.Overlay.overlay);
|
||||
dialog.selectedFile = currentRoom.fileNameToDownload(root.currentEventId);
|
||||
dialog.open();
|
||||
dialog.currentFile = dialog.folder + "/" + currentRoom.fileNameToDownload(root.currentEventId);
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
||||
@@ -12,7 +12,7 @@ Components.AbstractMaximizeComponent {
|
||||
|
||||
required property string text
|
||||
property color avatarColor
|
||||
required property string avatarSource
|
||||
required property url avatarSource
|
||||
|
||||
onOpened: forceActiveFocus()
|
||||
|
||||
|
||||
37
src/qml/QuickReaction.qml
Normal file
37
src/qml/QuickReaction.qml
Normal file
@@ -0,0 +1,37 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
QQC2.ScrollView {
|
||||
id: root
|
||||
|
||||
signal chosen(string text)
|
||||
|
||||
QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0
|
||||
|
||||
implicitHeight: Kirigami.Units.iconSizes.large + QQC2.ScrollBar.horizontal.height
|
||||
|
||||
ListView {
|
||||
id: quickReactions
|
||||
Layout.fillWidth: true
|
||||
|
||||
model: ["👍", "👎", "😄", "🎉", "😕", "❤", "🚀", "👀"]
|
||||
|
||||
delegate: EmojiDelegate {
|
||||
height: Kirigami.Units.iconSizes.large
|
||||
width: height
|
||||
|
||||
text: modelData
|
||||
onClicked: root.chosen(modelData)
|
||||
}
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
}
|
||||
}
|
||||
@@ -30,9 +30,9 @@ Kirigami.Dialog {
|
||||
FormCard.AbstractFormDelegate {
|
||||
background: null
|
||||
contentItem: RowLayout {
|
||||
spacing: Kirigami.Units.largeSpacing * 4
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
Avatar {
|
||||
source: root.connection.makeMediaUrl(SpaceHierarchyCache.recommendedSpaceAvatar)
|
||||
source: SpaceHierarchyCache.recommendedSpaceAvatar.toString().length > 0 ? root.connection.makeMediaUrl(SpaceHierarchyCache.recommendedSpaceAvatar) : 0
|
||||
name: SpaceHierarchyCache.recommendedSpaceDisplayName
|
||||
}
|
||||
ColumnLayout {
|
||||
@@ -51,6 +51,7 @@ Kirigami.Dialog {
|
||||
FormCard.FormDelegateSeparator {}
|
||||
FormCard.FormButtonDelegate {
|
||||
text: i18nc("@action:button", "Join")
|
||||
icon.name: "list-add-symbolic"
|
||||
onClicked: {
|
||||
SpaceHierarchyCache.recommendedSpaceHidden = true;
|
||||
RoomManager.resolveResource(SpaceHierarchyCache.recommendedSpaceId, "join");
|
||||
@@ -58,6 +59,7 @@ Kirigami.Dialog {
|
||||
}
|
||||
}
|
||||
FormCard.FormButtonDelegate {
|
||||
icon.name: "mail-thread-ignored-symbolic"
|
||||
text: i18nc("@action:button", "Ignore")
|
||||
onClicked: {
|
||||
SpaceHierarchyCache.recommendedSpaceHidden = true;
|
||||
|
||||
@@ -21,7 +21,7 @@ Delegates.RoundedItemDelegate {
|
||||
required property bool hasHighlightNotifications
|
||||
required property NeoChatRoom currentRoom
|
||||
required property NeoChatConnection connection
|
||||
required property string avatar
|
||||
required property url avatar
|
||||
required property string subtitleText
|
||||
required property string displayName
|
||||
|
||||
@@ -55,7 +55,7 @@ Delegates.RoundedItemDelegate {
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
AvatarNotification {
|
||||
source: root.avatar ? root.connection.makeMediaUrl("mxc://" + root.avatar) : ""
|
||||
source: root.avatar
|
||||
name: root.displayName
|
||||
visible: NeoChatConfig.showAvatarInRoomDrawer
|
||||
implicitHeight: Kirigami.Units.gridUnit + (NeoChatConfig.compactRoomList ? 0 : Kirigami.Units.largeSpacing * 2)
|
||||
|
||||
@@ -99,8 +99,11 @@ Kirigami.OverlayDrawer {
|
||||
Layout.preferredHeight: pageStack.globalToolBar.preferredHeight
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
text: drawerItemLoader.item ? drawerItemLoader.item.title : ""
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ QQC2.ScrollView {
|
||||
/**
|
||||
* @brief The title that should be displayed for this component if available.
|
||||
*/
|
||||
readonly property string title: root.room.isSpace ? i18nc("@action:title", "Space Members") : i18nc("@action:title", "Room information")
|
||||
readonly property string title: root.room.isSpace ? i18nc("@action:title", "Space Members") : i18nc("@action:title", "Room Information")
|
||||
|
||||
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
||||
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||
@@ -133,7 +133,7 @@ QQC2.ScrollView {
|
||||
Delegates.RoundedItemDelegate {
|
||||
id: leaveButton
|
||||
icon.name: "arrow-left-symbolic"
|
||||
text: i18nc("@action:button", "Leave this room")
|
||||
text: root.room.isSpace ? i18nc("@action:button", "Leave this space") : i18nc("@action:button", "Leave this room")
|
||||
activeFocusOnTab: true
|
||||
|
||||
Layout.fillWidth: true
|
||||
@@ -219,7 +219,7 @@ QQC2.ScrollView {
|
||||
required property int index
|
||||
required property string name
|
||||
required property string userId
|
||||
required property string avatar
|
||||
required property url avatar
|
||||
required property int powerLevel
|
||||
required property string powerLevelString
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user