diff options
author | Joseph Donofry <joedonofry@gmail.com> | 2021-08-10 19:29:58 -0400 |
---|---|---|
committer | Joseph Donofry <joedonofry@gmail.com> | 2021-08-10 19:29:58 -0400 |
commit | c91e771d538d99c9353b779ac4dd0d93a77cca6b (patch) | |
tree | a0b583cf945b5cd09622ccb68b9fc8ad0e369794 | |
parent | Merge remote-tracking branch 'nheko-im/master' into video_player_enhancements (diff) | |
parent | Protect against replay attacks (diff) | |
download | nheko-c91e771d538d99c9353b779ac4dd0d93a77cca6b.tar.xz |
Merge origin/master and fix conflicts
124 files changed, 8433 insertions, 4460 deletions
diff --git a/.ci/format.sh b/.ci/format.sh index 2d922ee1..cc4a3b82 100755 --- a/.ci/format.sh +++ b/.ci/format.sh @@ -14,17 +14,4 @@ do clang-format -i "$f" done; -QMLFORMAT_PATH=$(command -v qmlformat || true) - -if [ -n "$QMLFORMAT_PATH" ]; then - QML_FILES=$(find resources -type f -iname "*.qml") - - for f in $QML_FILES - do - $QMLFORMAT_PATH -i "$f" - done; -else - echo "qmlformat not found; skipping qml formatting" -fi - git diff --exit-code diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ff92c17..cea6be7b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,14 +52,14 @@ build-macos: stage: build tags: [macos] before_script: - - brew update - - brew reinstall --force python3 - - brew bundle --file=./.ci/macos/Brewfile --force --cleanup + #- brew update + #- brew reinstall --force python3 + #- brew bundle --file=./.ci/macos/Brewfile --force --cleanup - pip3 install dmgbuild - rm -rf ../.hunter && mv .hunter ../.hunter || true script: - - export PATH=/usr/local/opt/qt/bin/:${PATH} - - export CMAKE_PREFIX_PATH=/usr/local/opt/qt5 + - export PATH=/usr/local/opt/qt@5/bin/:${PATH} + - export CMAKE_PREFIX_PATH=/usr/local/opt/qt@5 - cmake -GNinja -H. -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=.deps/usr @@ -91,7 +91,9 @@ build-flatpak-amd64: #image: 'registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master' tags: [docker] before_script: - - apt-get update && apt-get -y install flatpak-builder git python curl python3-aiohttp python3-tenacity gir1.2-ostree-1.0 + # need flatpak 1.11.1 at least + - apt-get update && apt-get install -y software-properties-common + - add-apt-repository ppa:alexlarsson/flatpak && apt-get update && apt-get -y install flatpak-builder git python curl python3-aiohttp python3-tenacity gir1.2-ostree-1.0 - flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo - flatpak --noninteractive install --user flathub org.kde.Platform//5.15 - flatpak --noninteractive install --user flathub org.kde.Sdk//5.15 @@ -119,7 +121,9 @@ build-flatpak-arm64: #image: 'registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master' tags: [docker-arm64] before_script: - - apt-get update && apt-get -y install flatpak-builder git python curl python3-aiohttp python3-tenacity gir1.2-ostree-1.0 + # need flatpak 1.11.1 at least + - apt-get update && apt-get install -y software-properties-common + - add-apt-repository ppa:alexlarsson/flatpak && apt-get update && apt-get -y install flatpak-builder git python curl python3-aiohttp python3-tenacity gir1.2-ostree-1.0 - flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo - flatpak --noninteractive install --user flathub org.kde.Platform//5.15 - flatpak --noninteractive install --user flathub org.kde.Sdk//5.15 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b26b2e5..049ed8a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,14 +281,11 @@ set(SRC_FILES src/dialogs/CreateRoom.cpp src/dialogs/FallbackAuth.cpp src/dialogs/ImageOverlay.cpp - src/dialogs/InviteUsers.cpp src/dialogs/JoinRoom.cpp src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp - src/dialogs/MemberList.cpp src/dialogs/PreviewUploadOverlay.cpp src/dialogs/ReCaptcha.cpp - src/dialogs/ReadReceipts.cpp # Emoji src/emoji/EmojiModel.cpp @@ -307,7 +304,6 @@ set(SRC_FILES src/timeline/RoomlistModel.cpp # UI components - src/ui/Avatar.cpp src/ui/Badge.cpp src/ui/DropShadow.cpp src/ui/FlatButton.cpp @@ -346,16 +342,20 @@ set(SRC_FILES src/CompletionProxyModel.cpp src/DeviceVerificationFlow.cpp src/EventAccessors.cpp - src/InviteeItem.cpp + src/InviteesModel.cpp src/Logging.cpp src/LoginPage.cpp src/MainWindow.cpp src/MatrixClient.cpp + src/MemberList.cpp src/MxcImageProvider.cpp src/Olm.cpp + src/ReadReceiptsModel.cpp src/RegisterPage.cpp src/SSOHandler.cpp - src/ImagePackModel.cpp + src/CombinedImagePackModel.cpp + src/SingleImagePackModel.cpp + src/ImagePackListModel.cpp src/TrayIcon.cpp src/UserSettingsPage.cpp src/UsersModel.cpp @@ -381,7 +381,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG 1c277e9ac69aafdaf6888ce595b21dc86e970f28 + GIT_TAG bcf363cb5e6c423f40c96123e227bc8c5f6d6f80 ) set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") @@ -492,15 +492,11 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/CreateRoom.h src/dialogs/FallbackAuth.h src/dialogs/ImageOverlay.h - src/dialogs/InviteUsers.h src/dialogs/JoinRoom.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h - src/dialogs/MemberList.h src/dialogs/PreviewUploadOverlay.h - src/dialogs/RawMessage.h src/dialogs/ReCaptcha.h - src/dialogs/ReadReceipts.h # Emoji src/emoji/EmojiModel.h @@ -518,7 +514,6 @@ qt5_wrap_cpp(MOC_HEADERS src/timeline/RoomlistModel.h # UI components - src/ui/Avatar.h src/ui/Badge.h src/ui/FlatButton.h src/ui/FloatingButton.h @@ -546,28 +541,33 @@ qt5_wrap_cpp(MOC_HEADERS src/AvatarProvider.h src/BlurhashProvider.h - src/Cache_p.h src/CacheCryptoStructs.h + src/Cache_p.h src/CallDevices.h src/CallManager.h src/ChatPage.h src/Clipboard.h + src/CombinedImagePackModel.h src/CompletionProxyModel.h src/DeviceVerificationFlow.h - src/InviteeItem.h + src/ImagePackListModel.h + src/InviteesModel.h src/LoginPage.h src/MainWindow.h + src/MemberList.h src/MxcImageProvider.h + src/Olm.h src/RegisterPage.h + src/RoomsModel.h src/SSOHandler.h - src/ImagePackModel.h + src/SingleImagePackModel.h src/TrayIcon.h src/UserSettingsPage.h src/UsersModel.h - src/RoomsModel.h src/WebRTCSession.h src/WelcomePage.h - ) + src/ReadReceiptsModel.h +) # # Bundle translations. diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml index b6f468db..a0e57b09 100644 --- a/io.github.NhekoReborn.Nheko.yaml +++ b/io.github.NhekoReborn.Nheko.yaml @@ -19,6 +19,8 @@ finish-args: - --talk-name=org.freedesktop.secrets - --talk-name=org.freedesktop.StatusNotifierItem - --talk-name=org.kde.* + # needed for SingleApplication to work + - --allow=per-app-dev-shm cleanup: - /include - /bin/mdb* @@ -161,7 +163,7 @@ modules: buildsystem: cmake-ninja name: mtxclient sources: - - commit: 1c277e9ac69aafdaf6888ce595b21dc86e970f28 + - commit: bcf363cb5e6c423f40c96123e227bc8c5f6d6f80 type: git url: https://github.com/Nheko-Reborn/mtxclient.git - config-opts: diff --git a/nheko-nightly.flatpakref b/nheko-nightly.flatpakref index 7d27bdfe..74e47ecd 100644 --- a/nheko-nightly.flatpakref +++ b/nheko-nightly.flatpakref @@ -3,6 +3,7 @@ Title=Nheko Nightly Name=io.github.NhekoReborn.Nheko Branch=master Url=https://flatpak.neko.dev/repo/nightly +SuggestRemoteName=nheko-nightlies Homepage=https://nheko-reborn.github.io/ Icon=https://nheko.im/nheko-reborn/nheko/-/raw/master/resources/nheko.svg RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo diff --git a/nheko-nightly.flatpakrepo b/nheko-nightly.flatpakrepo index 4fb1bc55..680558af 100644 --- a/nheko-nightly.flatpakrepo +++ b/nheko-nightly.flatpakrepo @@ -1,6 +1,7 @@ [Flatpak Repo] Title=Nheko Nightly Url=https://flatpak.neko.dev/repo/nightly +SuggestRemoteName=nheko-nightlies Homepage=https://nheko.im/ Comment=Nheko nightly release repository Description=Nheko nightly release repository diff --git a/resources/langs/nheko_cs.ts b/resources/langs/nheko_cs.ts index c544bf6d..99813f81 100644 --- a/resources/langs/nheko_cs.ts +++ b/resources/langs/nheko_cs.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished"></translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation type="unfinished"></translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,16 +655,42 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> <translation type="unfinished"></translation> </message> </context> @@ -741,27 +805,14 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -781,17 +832,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -806,23 +857,23 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,42 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1485,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1515,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1547,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1621,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1642,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1670,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1681,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1713,12 +1816,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1747,7 +1850,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1755,17 +1858,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1773,7 +1891,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1781,18 +1899,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1833,7 +1950,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1843,7 +1960,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1892,7 +2009,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1901,7 +2018,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2347,7 +2464,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2398,7 +2515,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2470,19 +2587,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2593,7 +2697,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index 58c209a2..cb5b54fb 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Auf Bestätigung warten</translation> </message> @@ -48,7 +48,7 @@ <translation>Wartet darauf, dass die andere Seite die Verifizierung abschließt.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Abbrechen</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Nutzer konnte nicht eingeladen werden: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Einladung bestätigen</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Nutzer %1 (%2) wirklich einladen?</translation> </message> @@ -227,12 +227,12 @@ <translation>Verbannung aufgehoben: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Möchtest du wirklich eine private Konversation mit %1 beginnen?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Migration des Caches fehlgeschlagen!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Geheimnisse entschlüsseln</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Suche</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Leute</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Schließen</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Datei auswählen</translation> </message> @@ -617,17 +655,43 @@ <translation>Alle Dateien (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Medienupload fehlgeschlagen. Bitte versuche es erneut.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation>Lade Benutzer in %1 ein</translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation>Benutzer-ID, die eingeladen werden soll</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation>@joe:matrix.org</translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation>Hinzufügen</translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation>Einladen</translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Löschen</translation> + <location line="+7"/> + <source>Cancel</source> + <translation>Abbrechen</translation> </message> </context> <context> @@ -745,22 +809,9 @@ Beispiel: https://mein.server:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Teilnehmerliste</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation>entfernt</translation> @@ -771,7 +822,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Verschlüsselung aktiviert</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>Raumname wurde gändert auf: %1</translation> </message> @@ -781,7 +832,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Raumname wurde entfernt</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>Raumthema wurde geändert auf: %1</translation> </message> @@ -791,17 +842,17 @@ Beispiel: https://mein.server:8787</translation> <translation>Thema wurde entfernt</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation>%1 hat dem Raumavatar geändert</translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 hat den Raum erstellt: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 hat einen Sprachanruf gestartet.</translation> </message> @@ -816,17 +867,17 @@ Beispiel: https://mein.server:8787</translation> <translation>%1 hat angerufen.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 hat den Anruf angenommen.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 hat den Anruf beendet.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation>Wählt…</translation> </message> @@ -834,7 +885,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Auflegen</translation> </message> @@ -855,6 +906,11 @@ Beispiel: https://mein.server:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation>Sticker</translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Emoji</translation> </message> @@ -872,17 +928,17 @@ Beispiel: https://mein.server:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Bearbeiten</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reaktion senden</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Antworten</translation> </message> @@ -892,7 +948,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Optionen</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation>&Kopieren</translation> </message> @@ -1100,7 +1156,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>Unimplementiertes Event: </translation> </message> @@ -1220,7 +1276,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Schließen</translation> </message> @@ -1233,7 +1289,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>keine Version gespeichert</translation> </message> @@ -1241,7 +1297,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation>Neuer Tag</translation> </message> @@ -1251,6 +1307,16 @@ Beispiel: https://mein.server:8787</translation> <translation>Gib den Tag, den du verwenden willst, ein:</translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation>Raum verlassen</translation> @@ -1281,17 +1347,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Neuen Tag erstellen...</translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation>Akzeptieren</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation>Ablehnen</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation>Statusnachricht</translation> </message> @@ -1342,19 +1398,41 @@ Beispiel: https://mein.server:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation>Teilnehmer in %1</translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation> + <numerusform>%n Person in %1</numerusform> + <numerusform>%n Personen in %1</numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation>Lade mehr Leute ein</translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Raumeinstellungen</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 Teilnehmer</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>EINSTELLUNGEN</translation> </message> @@ -1410,19 +1488,22 @@ Beispiel: https://mein.server:8787</translation> <translation>Verschlüsselung ist derzeit experimentell und könnte unerwartete Probleme verursachen.<br>Bitte beachte, dass dies später nicht mehr deaktiviert werden kann.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Auf Schlüsselanfragen antworten</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> - <translation>Soll der Client automatisch mit den Sitzungsschlüsseln auf Anfragen antworten oder nicht? Bitte mit Vorsicht benutzen, dies ist eine vorübergehende Maßnahme, um die Ende-zu-Ende-Implementierung zu testen, bis die Geräteverifizierung abgeschlossen ist.</translation> + <location line="+4"/> + <source>Change</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>INFO</translation> </message> @@ -1437,12 +1518,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Raumversion</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Aktivierung der Verschlüsselung fehlgeschlagen: %1</translation> </message> @@ -1474,6 +1550,24 @@ Beispiel: https://mein.server:8787</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation>Offene Einladung.</translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation>Vorschau dieses Raums</translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation>Keine Vorschau verfügbar</translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1530,7 +1624,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Fehlgeschlagen</translation> </message> @@ -1551,6 +1645,14 @@ Beispiel: https://mein.server:8787</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation>Suche</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1571,7 +1673,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Nachricht zurückziehen fehlgeschlagen: %1</translation> </message> @@ -1582,7 +1684,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Event konnte nicht verschlüsselt werden, senden wurde abgebrochen!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Bild speichern</translation> </message> @@ -1716,12 +1818,12 @@ Beispiel: https://mein.server:8787</translation> <translation>%1 hat das Anklopfen zurückgezogen.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Du bist dem Raum beigetreten.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation>%1 hat den eigenen Avatar und Namen geändert zu %2.</translation> </message> @@ -1750,7 +1852,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Bearbeitet</translation> </message> @@ -1758,17 +1860,32 @@ Beispiel: https://mein.server:8787</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Kein Raum geöffnet</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation>%1 Teilnehmer</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation>An der Unterhaltung teilnehmen</translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation>Einladung annehmen</translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation>Einladung ablehnen</translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation>Zurück zur Raumliste</translation> </message> @@ -1776,7 +1893,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Keinen verschlüsselten Chat mit diesem User gefunden. Erstelle einen verschlüsselten 1:1 Chat mit diesem Nutzer und versuche es erneut.</translation> </message> @@ -1784,18 +1901,17 @@ Beispiel: https://mein.server:8787</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Zurück zur Raumliste</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Kein Raum ausgewählt</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Raumoptionen</translation> </message> @@ -1836,7 +1952,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Globales Nutzerprofil</translation> </message> @@ -1846,7 +1962,7 @@ Beispiel: https://mein.server:8787</translation> <translation>Raumspezifisches Nutzerprofil</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Verifizieren</translation> @@ -1895,7 +2011,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>Standard</translation> @@ -1904,7 +2020,7 @@ Beispiel: https://mein.server:8787</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Ins Benachrichtigungsfeld minimieren</translation> </message> @@ -2360,7 +2476,7 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein.</ <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Auf Gegenseite warten…</translation> </message> @@ -2411,7 +2527,7 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein.</ <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Gestern</translation> </message> @@ -2483,19 +2599,6 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein.</ </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Abbrechen</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Benutzer-ID, die eingeladen werden soll</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2608,7 +2711,7 @@ Medien-Größe: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Du hast eine Audiodatei gesendet</translation> </message> diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index d5d5f323..d40a6433 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished">Άκυρο</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation type="unfinished"></translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">Διάλεξε ένα αρχείο</translation> </message> @@ -617,18 +655,44 @@ <translation type="unfinished">Όλα τα αρχεία (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Όνομα χρήστη</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+58"/> + <source>Invite</source> <translation type="unfinished"></translation> </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Άκυρο</translation> + </message> </context> <context> <name>LoginPage</name> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Μέλη</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Βγές</translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Αποδοχή</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Απόρριψη</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished">Αποθήκευση Εικόνας</translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Ελαχιστοποίηση</translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">Άκυρο</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Όνομα χρήστη</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 7d3f8276..1851fff1 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Awaiting Confirmation</translation> </message> @@ -48,7 +48,7 @@ <translation>Waiting for other side to complete verification.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Cancel</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Failed to invite user: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Confirm invite</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Do you really want to invite %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Unbanned user: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Do you really want to start a private chat with %1?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Cache migration failed!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Decrypt secrets</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Search</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>People</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Close</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Select a file</translation> </message> @@ -617,17 +655,43 @@ <translation>All Files (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Failed to upload media. Please try again.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation>Invite users to %1</translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation>User ID to invite</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation>@joe:matrix.org</translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation>Add</translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation>Invite</translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Remove</translation> + <location line="+7"/> + <source>Cancel</source> + <translation>Cancel</translation> </message> </context> <context> @@ -745,27 +809,14 @@ Example: https://server.my:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Room members</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation>Encryption enabled</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>room name changed to: %1</translation> </message> @@ -775,7 +826,7 @@ Example: https://server.my:8787</translation> <translation>removed room name</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>topic changed to: %1</translation> </message> @@ -785,17 +836,17 @@ Example: https://server.my:8787</translation> <translation>removed topic</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation>%1 changed the room avatar</translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 created and configured room: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 placed a voice call.</translation> </message> @@ -810,23 +861,23 @@ Example: https://server.my:8787</translation> <translation>%1 placed a call.</translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation>Negotiating call…</translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation>%1 answered the call.</translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation>removed</translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation>%1 ended the call.</translation> </message> @@ -834,7 +885,7 @@ Example: https://server.my:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Hang up</translation> </message> @@ -855,6 +906,11 @@ Example: https://server.my:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation>Stickers</translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Emoji</translation> </message> @@ -872,17 +928,17 @@ Example: https://server.my:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Edit</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>React</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Reply</translation> </message> @@ -892,7 +948,7 @@ Example: https://server.my:8787</translation> <translation>Options</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation>&Copy</translation> </message> @@ -1100,7 +1156,7 @@ Example: https://server.my:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>unimplemented event: </translation> </message> @@ -1220,7 +1276,7 @@ Example: https://server.my:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Close</translation> </message> @@ -1233,7 +1289,7 @@ Example: https://server.my:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>no version stored</translation> </message> @@ -1241,7 +1297,7 @@ Example: https://server.my:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation>New tag</translation> </message> @@ -1251,6 +1307,16 @@ Example: https://server.my:8787</translation> <translation>Enter the tag you want to use:</translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation>Leave room</translation> @@ -1281,17 +1347,7 @@ Example: https://server.my:8787</translation> <translation>Create new tag...</translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation>Accept</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation>Decline</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation>Status Message</translation> </message> @@ -1342,19 +1398,41 @@ Example: https://server.my:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation>Members of %1</translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation> + <numerusform>%n person in %1</numerusform> + <numerusform>%n people in %1</numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation>Invite more people</translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Room Settings</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 member(s)</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>SETTINGS</translation> </message> @@ -1410,21 +1488,22 @@ Example: https://server.my:8787</translation> <translation>Encryption is currently experimental and things might break unexpectedly.<br>Please take note that it can't be disabled afterwards.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Respond to key requests</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> - <translation>Whether or not the client should respond automatically with the session keys -upon request. Use with caution, this is a temporary measure to test the -E2E implementation until device verification is completed.</translation> + <location line="+4"/> + <source>Change</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>INFO</translation> </message> @@ -1439,12 +1518,7 @@ E2E implementation until device verification is completed.</translation> <translation>Room Version</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Failed to enable encryption: %1</translation> </message> @@ -1476,6 +1550,24 @@ E2E implementation until device verification is completed.</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation>Pending invite.</translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation>Previewing this room</translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation>No preview available</translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1532,7 +1624,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Failed</translation> </message> @@ -1553,6 +1645,14 @@ E2E implementation until device verification is completed.</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation>Search</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1573,7 +1673,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Message redaction failed: %1</translation> </message> @@ -1584,7 +1684,7 @@ E2E implementation until device verification is completed.</translation> <translation>Failed to encrypt event, sending aborted!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Save image</translation> </message> @@ -1718,12 +1818,12 @@ E2E implementation until device verification is completed.</translation> <translation>%1 redacted their knock.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>You joined this room.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation>%1 has changed their avatar and changed their display name to %2.</translation> </message> @@ -1752,7 +1852,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Edited</translation> </message> @@ -1760,17 +1860,32 @@ E2E implementation until device verification is completed.</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>No room open</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation>%1 member(s)</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation>join the conversation</translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation>accept invite</translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation>decline invite</translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation>Back to room list</translation> </message> @@ -1778,7 +1893,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</translation> </message> @@ -1786,18 +1901,17 @@ E2E implementation until device verification is completed.</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Back to room list</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>No room selected</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Room options</translation> </message> @@ -1838,7 +1952,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Global User Profile</translation> </message> @@ -1848,7 +1962,7 @@ E2E implementation until device verification is completed.</translation> <translation>Room User Profile</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Verify</translation> @@ -1897,7 +2011,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>Default</translation> @@ -1906,7 +2020,7 @@ E2E implementation until device verification is completed.</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Minimize to tray</translation> </message> @@ -2363,7 +2477,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Waiting for other party…</translation> </message> @@ -2414,7 +2528,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Yesterday</translation> </message> @@ -2486,19 +2600,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Cancel</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>User ID to invite</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2611,7 +2712,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>You sent an audio clip</translation> </message> diff --git a/resources/langs/nheko_eo.ts b/resources/langs/nheko_eo.ts index 26a67d49..a77c5c25 100644 --- a/resources/langs/nheko_eo.ts +++ b/resources/langs/nheko_eo.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Atendante konfirmon</translation> </message> @@ -48,7 +48,7 @@ <translation>Atendante kontrolon venontan de la alia flanko.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Nuligi</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Malsukcesis inviti uzanton: %1</translation> </message> @@ -158,12 +158,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Konfirmu inviton</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Ĉu vi certe volas inviti uzanton %1 (%2)?</translation> </message> @@ -228,12 +228,12 @@ <translation>Malforbaris uzanton: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Ĉu vi certe volas komenci privatan babilon kun %1?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Malsukcesis migrado de kaŝmemoro!</translation> </message> @@ -353,7 +353,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Malĉifri sekretojn</translation> </message> @@ -427,12 +427,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Serĉu</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Homoj</translation> </message> @@ -606,9 +606,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Fermi</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">Elektu dosieron</translation> </message> @@ -618,17 +656,43 @@ <translation>Ĉiuj dosieroj (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Malsukcesis alŝuti vidaŭdaĵojn. Bonvolu reprovi.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Forigi</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Nuligi</translation> </message> </context> <context> @@ -748,22 +812,9 @@ Ekzemplo: https://servilo.mia:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Membroj de la ĉambro</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>Bone</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation>forigita</translation> @@ -774,7 +825,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>Nomo da ĉambro ŝanĝiĝis al: %1</translation> </message> @@ -784,7 +835,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -794,17 +845,17 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 metis voĉvokon.</translation> </message> @@ -819,17 +870,17 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation>%1 metis vokon.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 respondis la vokon.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 finis la vokon.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation>Traktante vokon…</translation> </message> @@ -837,7 +888,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -858,6 +909,11 @@ Ekzemplo: https://servilo.mia:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Bildosignoj</translation> </message> @@ -875,17 +931,17 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Redakti</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reagi</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Respondi</translation> </message> @@ -895,7 +951,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation>Elektebloj</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1103,7 +1159,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>neprogramita okazo: </translation> </message> @@ -1223,7 +1279,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Fermi</translation> </message> @@ -1236,7 +1292,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1244,7 +1300,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1254,6 +1310,16 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Eliri el ĉambro</translation> @@ -1284,17 +1350,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Akcepti</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Rifuzi</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1345,19 +1401,41 @@ Ekzemplo: https://servilo.mia:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Agordoj de ĉambro</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 ĉambrano(j)</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>AGORDOJ</translation> </message> @@ -1413,19 +1491,22 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation>Ĉifrado nun estas eksperimenta kaj povus rompiĝi neatendite.<br>Bonvole sciu, ke ne eblas ĝin malŝalti poste.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Respondi al petoj de ŝlosiloj</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>INFORMOJ</translation> </message> @@ -1440,12 +1521,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation>Versio de ĉambro</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>Bone</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Malsukcesis ŝalti ĉifradon: %1</translation> </message> @@ -1477,6 +1553,24 @@ Ekzemplo: https://servilo.mia:8787</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1533,7 +1627,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Estas malsukcesa</translation> </message> @@ -1555,6 +1649,14 @@ Ekzemplo: https://servilo.mia:8787</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Serĉu</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1575,7 +1677,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1586,7 +1688,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Konservi bildon</translation> </message> @@ -1722,12 +1824,12 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Vi aliĝis ĉi tiun ĉambron.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1756,7 +1858,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Redaktita</translation> </message> @@ -1764,17 +1866,32 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished">%1 ĉambrano(j)</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1782,7 +1899,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1790,18 +1907,17 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1852,7 +1968,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1901,7 +2017,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1910,7 +2026,7 @@ Ekzemplo: https://servilo.mia:8787</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2373,7 +2489,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2425,7 +2541,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Hieraŭ</translation> </message> @@ -2497,19 +2613,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">Nuligi</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2620,7 +2723,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_es.ts b/resources/langs/nheko_es.ts index 6318b9c4..922e0500 100644 --- a/resources/langs/nheko_es.ts +++ b/resources/langs/nheko_es.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Esperando confirmación</translation> </message> @@ -48,7 +48,7 @@ <translation>Esperando a que la otra parte complete la verificación.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Cancelar</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>No se pudo invitar al usuario: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Confirmar invitación</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,18 +655,44 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> <translation type="unfinished"></translation> </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Cancelar</translation> + </message> </context> <context> <name>LoginPage</name> @@ -741,27 +805,14 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -781,17 +832,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -806,23 +857,23 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Aceptar</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Rechazar</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1722,12 +1824,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">Te has unido a esta sala.</translation> </message> <message> - <location line="+885"/> + <location line="+886"/> <source>Rejected the knock from %1.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">Cancelar</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_et.ts b/resources/langs/nheko_et.ts index 198ec332..57eac1c3 100644 --- a/resources/langs/nheko_et.ts +++ b/resources/langs/nheko_et.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Ootan kinnitust</translation> </message> @@ -48,7 +48,7 @@ <translation>Ootan et teine osapool lõpetaks verifitseerimise.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Katkesta</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Kutse saatmine kasutajale ei õnnestunud: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Kinnita kutse</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Kas sa tõesti soovid saata kutset kasutajale %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Suhtluskeeld eemaldatud: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Kas sa kindlasti soovid alustada otsevestlust kasutajaga %1?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Puhvri versiooniuuendus ebaõnnestus!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Dekrüpti andmed</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Otsi</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Inimesed</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Sulge</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Vali fail</translation> </message> @@ -617,17 +655,43 @@ <translation>Kõik failid (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Meediafailide üleslaadimine ei õnnestunud. Palun proovi uuesti.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Kasutajatunnus, kellele soovid kutset saata</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Eemalda</translation> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -745,27 +809,14 @@ Näiteks: https://server.minu:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Jututoa liikmed</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>Sobib</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation>Krüptimine on kasutusel</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>jututoa uus nimi on: %1</translation> </message> @@ -775,7 +826,7 @@ Näiteks: https://server.minu:8787</translation> <translation>eemaldas jututoa nime</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>jututoa uus teema on: %1</translation> </message> @@ -785,17 +836,17 @@ Näiteks: https://server.minu:8787</translation> <translation>teema on eemaldatud</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation>%1 muutis jututoa tunnuspilti</translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 lõi ja seadistas jututoa: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 helistas.</translation> </message> @@ -810,23 +861,23 @@ Näiteks: https://server.minu:8787</translation> <translation>%1 helistas.</translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation>Ühendan kõnet…</translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation>%1 vastas kõnele.</translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation>eemaldatud</translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation>%1 lõpetas kõne.</translation> </message> @@ -834,7 +885,7 @@ Näiteks: https://server.minu:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Lõpeta kõne</translation> </message> @@ -855,6 +906,11 @@ Näiteks: https://server.minu:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Emoji</translation> </message> @@ -872,17 +928,17 @@ Näiteks: https://server.minu:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Muuda</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reageeri</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Vasta</translation> </message> @@ -892,7 +948,7 @@ Näiteks: https://server.minu:8787</translation> <translation>Valikud</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation>&Kopeeri</translation> </message> @@ -1100,7 +1156,7 @@ Näiteks: https://server.minu:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>implementeerimata sündmus: </translation> </message> @@ -1220,7 +1276,7 @@ Näiteks: https://server.minu:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Sulge</translation> </message> @@ -1233,7 +1289,7 @@ Näiteks: https://server.minu:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>salvestatud versiooni ei leidu</translation> </message> @@ -1241,7 +1297,7 @@ Näiteks: https://server.minu:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation>Uus silt</translation> </message> @@ -1251,6 +1307,16 @@ Näiteks: https://server.minu:8787</translation> <translation>Kirjuta silt, mida soovid kasutada:</translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation>Lahku jututoast</translation> @@ -1281,17 +1347,7 @@ Näiteks: https://server.minu:8787</translation> <translation>Loo uus silt...</translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation>Nõustu</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation>Keeldu</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation>Olekuteade</translation> </message> @@ -1342,19 +1398,41 @@ Näiteks: https://server.minu:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Jututoa seadistused</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 liige(t)</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>SEADISTUSED</translation> </message> @@ -1410,21 +1488,22 @@ Näiteks: https://server.minu:8787</translation> <translation>Krüptimine on nhekos hetkel veel katseline ning nii mõndagi võib ootamatult katki minna. <br>Palun arvesta, et krüptimist ei saa hiljem enam välja lülitada.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Vasta krüptovõtmete päringutele</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> - <translation>Kas klient peaks automaatselt vastama või mitte vastama sessioonivõtmete päringule. -Kasuta seda võimalust ettevaatlikult. Tegemist on ajutise lahendusega läbiva krüptimise -testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.</translation> + <location line="+4"/> + <source>Change</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>TEAVE</translation> </message> @@ -1439,12 +1518,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <translation>Jututoa versioon</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>Sobib</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Krüptimise kasutuselevõtmine ei õnnestunud: %1</translation> </message> @@ -1476,6 +1550,24 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1532,7 +1624,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Ebaõnnestus</translation> </message> @@ -1553,6 +1645,14 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Otsi</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1573,7 +1673,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Sõnumi ümbersõnastamine ebaõnnestus: %1</translation> </message> @@ -1584,7 +1684,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <translation>Sündmuse krüptimine ei õnnestunud, katkestame saatmise!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Salvesta pilt</translation> </message> @@ -1718,12 +1818,12 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <translation>%1 muutis oma koputust jututoa uksele.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Sa liitusid jututoaga.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation>%1 muutis oma tunnuspilti ja seadistas uueks kuvatavaks nimeks %2.</translation> </message> @@ -1752,7 +1852,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Muudetud</translation> </message> @@ -1760,17 +1860,32 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Ühtegi jututuba pole avatud</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation>%1 liige(t)</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation>Tagasi jututubade loendisse</translation> </message> @@ -1778,7 +1893,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Ühtegi krüptitud vestlust selle kasutajaga ei leidunud. Palun loo temaga krüptitud vestlus ja proovi uuesti.</translation> </message> @@ -1786,18 +1901,17 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Tagasi jututubade loendisse</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Jututuba on valimata</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Jututoa valikud</translation> </message> @@ -1838,7 +1952,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Üldine kasutajaprofiil</translation> </message> @@ -1848,7 +1962,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <translation>Kasutajaprofiil jututoas</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Verifitseeri</translation> @@ -1897,7 +2011,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>Vaikimisi</translation> @@ -1906,7 +2020,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Vähenda tegumiribale</translation> </message> @@ -2363,7 +2477,7 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Ootan teise osapoole tegevust…</translation> </message> @@ -2414,7 +2528,7 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Eile</translation> </message> @@ -2486,19 +2600,6 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Tühista</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Kasutajatunnus, kellele soovid kutset saata</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2611,7 +2712,7 @@ Meedia suurus: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Sa saatsid helifaili</translation> </message> diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index 9c48e98f..422c2957 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Odotetaan vahvistusta</translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Peruuta</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation type="unfinished"></translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Hae</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Ihmiset</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Sulje</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Valitse tiedosto</translation> </message> @@ -617,17 +655,43 @@ <translation>Kaikki Tiedostot (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Poista</translation> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Käyttäjätunnus kutsuttavaksi</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Peruuta</translation> </message> </context> <context> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Huoneen jäsenet</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation>Salaus on käytössä</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>huoneen nimi muutettu: %1</translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation>%1 soitti puhelun.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 vastasi puheluun.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Emoji</translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Muokkaa</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reagoi</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Vastaa</translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation>Asetukset</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Sulje</translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>ei tallennettua versiota</translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation>Poistu huoneesta</translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation>Hyväksy</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation>Hylkää</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation>Huoneen versio</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Salauksen aktivointi epäonnistui: %1</translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Hae</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Viestin muokkaus epäonnistui: %1</translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Tallenna kuva</translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Sinä liityit tähän huoneeseen.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Muokattu</translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Huoneen asetukset</translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Pienennä ilmoitusalueelle</translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Eilen</translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Peruuta</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Käyttäjätunnus kutsuttavaksi</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2594,7 +2697,7 @@ Median koko: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Lähetit äänileikkeen</translation> </message> diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index b6345d62..c6d42299 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Attente de confirmation</translation> </message> @@ -48,7 +48,7 @@ <translation>Attente de la vérification par le correspondant.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Annuler</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Échec lors de l'invitation de %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Confirmer l'invitation</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Voulez-vous vraiment inviter %1 (%2) ?</translation> </message> @@ -227,12 +227,12 @@ <translation>%1 n'est plus banni(e)</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Voulez-vous vraimer commencer une discussion privée avec %1 ?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Échec de la migration du cache !</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Déchiffrer les secrets</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Chercher</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Personnes</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Fermer</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Sélectionnez un fichier</translation> </message> @@ -617,17 +655,43 @@ <translation>Tous les types de fichiers (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Échec de l'envoi du média. Veuillez réessayer.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Identifiant d'utilisateur à inviter</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Retirer</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Annuler</translation> </message> </context> <context> @@ -745,22 +809,9 @@ Exemple : https ://monserveur.example.com :8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Membres du salon</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation>retiré</translation> @@ -771,7 +822,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>Chiffrement activé</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>nom du salon changé en : %1</translation> </message> @@ -781,7 +832,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>nom du salon retiré</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>sujet changé pour : %1</translation> </message> @@ -791,17 +842,17 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>sujet retiré</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 a créé et configuré le salon : %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 a effectué un appel vocal.</translation> </message> @@ -816,17 +867,17 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>%1 a appelé.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 a répondu à l'appel.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 a terminé l'appel.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation>Négociation de l'appel…</translation> </message> @@ -834,7 +885,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Raccrocher</translation> </message> @@ -855,6 +906,11 @@ Exemple : https ://monserveur.example.com :8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Émoji</translation> </message> @@ -872,17 +928,17 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Modifier</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Réagir</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Répondre</translation> </message> @@ -892,7 +948,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>Options</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1100,7 +1156,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>Évènement non implémenté : </translation> </message> @@ -1220,7 +1276,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Fermer</translation> </message> @@ -1233,7 +1289,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>pas de version enregistrée</translation> </message> @@ -1241,7 +1297,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1251,6 +1307,16 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Quitter le salon</translation> @@ -1281,17 +1347,7 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1342,19 +1398,41 @@ Exemple : https ://monserveur.example.com :8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Configuration du salon</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 membre(s)</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>CONFIGURATION</translation> </message> @@ -1410,21 +1488,22 @@ Exemple : https ://monserveur.example.com :8787</translation> <translation>Le chiffrement actuellement expérimental et des comportements inattendus peuvent être rencontrés. <br>Veuillez noter qu'il n'est pas possible de le désactiver par la suite.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Répondre aux demandes de clé</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> - <translation>Si le client doit répondre automatiquement avec les clés de session lorsqu'elles sont -demandées. Utiliser précautionneusement, il s'agit d'une mesure temporaire afin de -tester le chiffrement de bout en bout tant que la vérification des appareils n'est pas au point.</translation> + <location line="+4"/> + <source>Change</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>INFO</translation> </message> @@ -1439,12 +1518,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <translation>Version du salon</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Échec de l'activation du chiffrement  : %1</translation> </message> @@ -1476,6 +1550,24 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1532,7 +1624,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Échec</translation> </message> @@ -1553,6 +1645,14 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Chercher</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1573,7 +1673,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Échec de la suppression du message : %1</translation> </message> @@ -1584,7 +1684,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <translation>Échec du chiffrement de l'évènement, envoi abandonné !</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Enregistrer l'image</translation> </message> @@ -1718,12 +1818,12 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <translation>%1 ne frappe plus au salon.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Vous avez rejoint ce salon.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1752,7 +1852,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Modifié</translation> </message> @@ -1760,17 +1860,32 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Aucun salon ouvert</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished">%1 membre(s)</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished">Revenir à la liste des salons</translation> </message> @@ -1778,7 +1893,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Pas de discussion privée et chiffrée trouvée avec cet utilisateur. Créez-en une et réessayez.</translation> </message> @@ -1786,18 +1901,17 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Revenir à la liste des salons</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Pas de salon sélectionné</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Options du salon</translation> </message> @@ -1838,7 +1952,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Profil général de l'utilisateur</translation> </message> @@ -1848,7 +1962,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <translation>Profil utilisateur spécifique au salon</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Vérifier</translation> @@ -1897,7 +2011,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>Défaut</translation> @@ -1906,7 +2020,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Réduire à la barre des tâches</translation> </message> @@ -2365,7 +2479,7 @@ Cela met l'application en évidence dans la barre des tâches.</translation <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Attente du correspondant…</translation> </message> @@ -2416,7 +2530,7 @@ Cela met l'application en évidence dans la barre des tâches.</translation <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Hier</translation> </message> @@ -2488,19 +2602,6 @@ Cela met l'application en évidence dans la barre des tâches.</translation </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Annuler</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Identifiant d'utilisateur à inviter</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2613,7 +2714,7 @@ Taille du média : %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Vous avez envoyé un message audio</translation> </message> diff --git a/resources/langs/nheko_hu.ts b/resources/langs/nheko_hu.ts index e989a6ce..7c29338c 100644 --- a/resources/langs/nheko_hu.ts +++ b/resources/langs/nheko_hu.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Várakozás megerősítésre</translation> </message> @@ -48,7 +48,7 @@ <translation>Várakozás a másik oldalra a hitelesítés befejezéséhez.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Mégse</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Nem sikerült meghívni a felhasználót: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Meghívás megerősítése</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Biztos, hogy meg akarod hívni a következő felhasználót: %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Kitiltás feloldva a felhasználónak: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Biztosan privát csevegést akarsz indítani %1 felhasználóval?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Gyorsítótár migráció nem sikerült!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Titkos tároló feloldása</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Keresés</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Emberek</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Bezárás</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Fájl kiválasztása</translation> </message> @@ -617,17 +655,43 @@ <translation>Minden fájl (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Nem sikerült feltölteni a médiafájlt. Kérlek, próbáld újra!</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Eltávolítás</translation> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Meghívandó felhasználó azonosítója</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Mégse</translation> </message> </context> <context> @@ -745,27 +809,14 @@ Példa: https://szerver.em:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Szobatagok</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation>Titkosítás bekapcsolva</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>a szoba neve megváltoztatva erre: %1</translation> </message> @@ -775,7 +826,7 @@ Példa: https://szerver.em:8787</translation> <translation>szobanév eltávolítva</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>a téma megváltoztatva erre: %1</translation> </message> @@ -785,17 +836,17 @@ Példa: https://szerver.em:8787</translation> <translation>téma eltávolítva</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 létrehozta és beállította a következő szobát: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 hanghívást kezdeményezett.</translation> </message> @@ -810,23 +861,23 @@ Példa: https://szerver.em:8787</translation> <translation>%1 hívást kezdeményezett.</translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation>Hívás előkészítése…</translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation>%1 fogadta a hívást.</translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation>eltávolítva</translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation>%1 befejezte a hívást.</translation> </message> @@ -834,7 +885,7 @@ Példa: https://szerver.em:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Hívás befejezése</translation> </message> @@ -855,6 +906,11 @@ Példa: https://szerver.em:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Hangulatjelek</translation> </message> @@ -872,17 +928,17 @@ Példa: https://szerver.em:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Szerkesztés</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reakció</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Válasz</translation> </message> @@ -892,7 +948,7 @@ Példa: https://szerver.em:8787</translation> <translation>Műveletek</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1100,7 +1156,7 @@ Példa: https://szerver.em:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>nem implementált esemény: </translation> </message> @@ -1220,7 +1276,7 @@ Példa: https://szerver.em:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Bezárás</translation> </message> @@ -1233,7 +1289,7 @@ Példa: https://szerver.em:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>nincs tárolva verzió</translation> </message> @@ -1241,7 +1297,7 @@ Példa: https://szerver.em:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1251,6 +1307,16 @@ Példa: https://szerver.em:8787</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Szoba elhagyása</translation> @@ -1281,17 +1347,7 @@ Példa: https://szerver.em:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Elfogadás</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Elutasítás</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1342,19 +1398,40 @@ Példa: https://szerver.em:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Szobabeállítások</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 tag</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>BEÁLLÍTÁSOK</translation> </message> @@ -1410,21 +1487,22 @@ Példa: https://szerver.em:8787</translation> <translation>A titkosítás jelenleg kísérleti stádiumú és váratlan furcsaságok történhetnek.<br>Kérlek, vedd vigyelembe, hogy ha egyszer aktiváltad, nem lehet utána kikapcsolni.</translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Válasz kulcskérelmekre</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> - <translation>Válaszoljon-e kérés esetén a kliens munkamenetkulcsokkal automatikusan. -Óvatosan használandó, mivel ez csak egy átmeneti megoldás a végponttól -végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközhitelesítés.</translation> + <location line="+4"/> + <source>Change</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>INFÓ</translation> </message> @@ -1439,12 +1517,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <translation>Szoba verziója</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Nem sikerült a titkosítás aktiválása: %1</translation> </message> @@ -1476,6 +1549,24 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1532,7 +1623,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Sikertelen</translation> </message> @@ -1553,6 +1644,14 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Keresés</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1573,7 +1672,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Az üzenet visszavonása nem sikerült: %1</translation> </message> @@ -1584,7 +1683,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <translation>Nem sikerült titkosítani az eseményt, küldés megszakítva!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Kép mentése</translation> </message> @@ -1717,12 +1816,12 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <translation>%1 visszavonta a kopogását.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Csatlakoztál ehhez a szobához.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1751,7 +1850,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Szerkesztve</translation> </message> @@ -1759,17 +1858,32 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Nincs nyitott szoba</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished">%1 tag</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished">Vissza a szobák listájára</translation> </message> @@ -1777,7 +1891,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Nem található titkosított privát csevegés ezzel a felhasználóval. Hozz létre egy titkosított privát csevegést vele, és próbáld újra!</translation> </message> @@ -1785,18 +1899,17 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Vissza a szobák listájára</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Nincs kiválasztva szoba</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Szoba beállításai</translation> </message> @@ -1837,7 +1950,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Globális felhasználói profil</translation> </message> @@ -1847,7 +1960,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <translation>Szobai felhasználói profil</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Hitelesítés</translation> @@ -1896,7 +2009,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>Alapértelmezett</translation> @@ -1905,7 +2018,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Kicsinyítés a tálcára</translation> </message> @@ -2363,7 +2476,7 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Várakozás a másik félre…</translation> </message> @@ -2414,7 +2527,7 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Tegnap</translation> </message> @@ -2486,19 +2599,6 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Mégse</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Meghívandó felhasználó azonosítója</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2611,7 +2711,7 @@ Média mérete: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Küldtél egy hangfájlt</translation> </message> diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts index b0b8ec48..5a1d45f8 100644 --- a/resources/langs/nheko_it.ts +++ b/resources/langs/nheko_it.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>In attesa di conferma</translation> </message> @@ -48,7 +48,7 @@ <translation>In attesa della conferma dall'altra parte per la verifica.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Annulla</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Impossibile invitare l'utente: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Conferma Invito</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Vuoi davvero inviare %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Rimosso il ban dall'utente: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Sei sicuro di voler avviare una chat privata con %1?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Migrazione della cache fallita!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Decifra i segreti</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Cerca</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Membri</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Chiudi</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">Seleziona un file</translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished">Tutti i File (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished">Impossibile inviare il file multimediale. Per favore riprova.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">ID utente da invitare</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Rimuovi</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Annulla</translation> </message> </context> <context> @@ -745,22 +809,9 @@ Esempio: https://server.mio:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Membri della stanza</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation>rimosso</translation> @@ -771,7 +822,7 @@ Esempio: https://server.mio:8787</translation> <translation>Crittografia abilitata</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>nome della stanza cambiato in: %1</translation> </message> @@ -781,7 +832,7 @@ Esempio: https://server.mio:8787</translation> <translation>nome della stanza rimosso</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>argomento cambiato in: %1</translation> </message> @@ -791,17 +842,17 @@ Esempio: https://server.mio:8787</translation> <translation>argomento rimosso</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 creato e configurata stanza: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 ha avviato una chiamata audio.</translation> </message> @@ -816,17 +867,17 @@ Esempio: https://server.mio:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 ha risposto alla chiamata.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 ha terminato la chiamata.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -834,7 +885,7 @@ Esempio: https://server.mio:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Termina</translation> </message> @@ -855,6 +906,11 @@ Esempio: https://server.mio:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished">Emoji</translation> </message> @@ -872,17 +928,17 @@ Esempio: https://server.mio:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Modifica</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Reagisci</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished">Risposta</translation> </message> @@ -892,7 +948,7 @@ Esempio: https://server.mio:8787</translation> <translation type="unfinished">Opzioni</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1101,7 +1157,7 @@ Verificare %1 adesso?</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>evento non implementato: </translation> </message> @@ -1221,7 +1277,7 @@ Verificare %1 adesso?</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Chiudi</translation> </message> @@ -1234,7 +1290,7 @@ Verificare %1 adesso?</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>nessuna versione memorizzata</translation> </message> @@ -1242,7 +1298,7 @@ Verificare %1 adesso?</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1252,6 +1308,16 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Lascia la stanza</translation> @@ -1282,17 +1348,7 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Accetta</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Rifiuta</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1343,19 +1399,41 @@ Verificare %1 adesso?</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1411,19 +1489,22 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1438,12 +1519,7 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">Impossibile abilitare la crittografia: %1</translation> </message> @@ -1475,6 +1551,24 @@ Verificare %1 adesso?</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1531,7 +1625,7 @@ Verificare %1 adesso?</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Fallito</translation> </message> @@ -1552,6 +1646,14 @@ Verificare %1 adesso?</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Cerca</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1572,7 +1674,7 @@ Verificare %1 adesso?</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Oscuramento del messaggio fallito: %1</translation> </message> @@ -1583,7 +1685,7 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Salva immagine</translation> </message> @@ -1717,12 +1819,12 @@ Verificare %1 adesso?</translation> <translation>%1 ha oscurato la sua bussata.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Sei entrato in questa stanza.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1751,7 +1853,7 @@ Verificare %1 adesso?</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1759,17 +1861,32 @@ Verificare %1 adesso?</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Nessuna stanza aperta</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1777,7 +1894,7 @@ Verificare %1 adesso?</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1785,18 +1902,17 @@ Verificare %1 adesso?</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished">Opzioni della stanza</translation> </message> @@ -1837,7 +1953,7 @@ Verificare %1 adesso?</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1847,7 +1963,7 @@ Verificare %1 adesso?</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1896,7 +2012,7 @@ Verificare %1 adesso?</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1905,7 +2021,7 @@ Verificare %1 adesso?</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Minimizza nella tray</translation> </message> @@ -2351,7 +2467,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2402,7 +2518,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Ieri</translation> </message> @@ -2474,19 +2590,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Annulla</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>ID utente da invitare</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2599,7 +2702,7 @@ Peso media: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Hai inviato una clip audio</translation> </message> diff --git a/resources/langs/nheko_ja.ts b/resources/langs/nheko_ja.ts index c7872ce0..1ec862b0 100644 --- a/resources/langs/nheko_ja.ts +++ b/resources/langs/nheko_ja.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished">キャンセル</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>ユーザーを招待できませんでした: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation>永久追放を解除されたユーザー: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">閉じる</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">ファイルを選択</translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished">全てのファイル (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished">メディアをアップロードできませんでした。やり直して下さい。</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">招待するユーザーのID</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>削除</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">キャンセル</translation> </message> </context> <context> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>部屋の参加者</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation>暗号化が有効です</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>部屋名が変更されました: %1</translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation>部屋名が削除されました</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>話題が変更されました: %1</translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation>話題が削除されました</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished">絵文字</translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished">返信</translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished">オプション</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>未実装のイベント: </translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished">閉じる</translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>バージョンが保存されていません</translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">部屋を出る</translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">容認</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">拒否</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,40 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1483,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1513,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">暗号化を有効にできませんでした: %1</translation> </message> @@ -1470,6 +1545,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1619,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>失敗</translation> </message> @@ -1547,6 +1640,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1668,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>メッセージを編集できませんでした: %1</translation> </message> @@ -1578,7 +1679,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>画像を保存</translation> </message> @@ -1711,12 +1812,12 @@ Example: https://server.my:8787</source> <translation>%1がノックを編集しました。</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1745,7 +1846,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1753,17 +1854,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>部屋が開いていません</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1771,7 +1887,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1779,18 +1895,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished">部屋のオプション</translation> </message> @@ -1831,7 +1946,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1841,7 +1956,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1890,7 +2005,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1899,7 +2014,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>トレイへ最小化</translation> </message> @@ -2345,7 +2460,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2396,7 +2511,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>昨日</translation> </message> @@ -2468,19 +2583,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>キャンセル</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>招待するユーザーのID</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2593,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>音声データを送信しました</translation> </message> diff --git a/resources/langs/nheko_ml.ts b/resources/langs/nheko_ml.ts index 0bdf3b63..011107c2 100644 --- a/resources/langs/nheko_ml.ts +++ b/resources/langs/nheko_ml.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>സ്ഥിരീകരണത്തിനായി കാത്തിരിക്കുന്നു</translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>റദ്ദാക്കു</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>ഉപയോക്താവിനെ ക്ഷണിക്കുന്നതിൽ പരാജയപ്പെട്ടു: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>ക്ഷണം ഉറപ്പാക്കു</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>തിരയുക</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>ആളുകൾ</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">അടയ്ക്കുക</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>ഒരു ഫയൽ തിരഞ്ഞെടുക്കുക</translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>നീക്കംചെയ്യുക</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">റദ്ദാക്കു</translation> </message> </context> <context> @@ -741,27 +805,14 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>ശരി</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -781,17 +832,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -806,23 +857,23 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation>നീക്കംചെയ്തു</translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>ഇമോജി</translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished">അടയ്ക്കുക</translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">നിരസിക്കുക</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">ശരി</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">തിരയുക</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">നിങ്ങൾ ഈ മുറിയിൽ ചേർന്നു.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">റദ്ദാക്കു</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 3f2a147f..b21db075 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished">Annuleren</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Gebruiker uitnodigen mislukt: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">Kies een bestand</translation> </message> @@ -617,18 +655,44 @@ <translation type="unfinished">Alle bestanden (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Uit te nodigen gebruikers-id</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+58"/> + <source>Invite</source> <translation type="unfinished"></translation> </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Annuleren</translation> + </message> </context> <context> <name>LoginPage</name> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Kamerleden</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Kamer verlaten</translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Accepteren</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Afwijzen</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished">Afbeelding opslaan</translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">Je bent lid geworden van deze kamer.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Minimaliseren naar systeemvak</translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">Annuleren</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Uit te nodigen gebruikers-id</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2594,7 +2697,7 @@ Mediagrootte: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 6abcd147..72e4e771 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Oczekiwanie na potwierdzenie</translation> </message> @@ -48,7 +48,7 @@ <translation>Oczekiwanie na dokończenie weryfikacji przez drugą stronę.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Anuluj</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Nie udało się zaprosić użytkownika: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Czy na pewno chcesz zaprosić %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Odblokowano użytkownika: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Nie udało się przenieść pamięci podręcznej!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Szukaj</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Ludzie</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Zamknij</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">Wybierz plik</translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished">Wszystkie pliki (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">ID użytkownika do zaproszenia</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Usuń</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Anuluj</translation> </message> </context> <context> @@ -743,22 +807,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Członkowie pokoju</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -769,7 +820,7 @@ Example: https://server.my:8787</source> <translation>Szyfrowanie włączone</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>Nazwa pokoju zmieniona na: %1</translation> </message> @@ -779,7 +830,7 @@ Example: https://server.my:8787</source> <translation>usunięto nazwę pokoju</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>temat zmieniono na: %1</translation> </message> @@ -789,17 +840,17 @@ Example: https://server.my:8787</source> <translation>usunięto temat</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 utworzył i skonfigurował pokój: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 rozpoczął(-ęła) połączenie głosowe.</translation> </message> @@ -814,17 +865,17 @@ Example: https://server.my:8787</source> <translation>%1 rozpoczął(-ęła) połączenie.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 odebrał(a) połączenie.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 zakończył(a) połączenie.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation>Negocjowanie połączenia…</translation> </message> @@ -832,7 +883,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -853,6 +904,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished">Emoji</translation> </message> @@ -870,17 +926,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -890,7 +946,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1098,7 +1154,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>Niezaimplementowane wydarzenie: </translation> </message> @@ -1218,7 +1274,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Zamknij</translation> </message> @@ -1231,7 +1287,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1239,7 +1295,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1249,6 +1305,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Opuść pokój</translation> @@ -1279,17 +1345,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Akceptuj</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Odrzuć</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1340,19 +1396,42 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1408,19 +1487,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1435,12 +1517,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">Nie udało się włączyć szyfrowania: %1</translation> </message> @@ -1472,6 +1549,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1528,7 +1623,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1549,6 +1644,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Szukaj</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1569,7 +1672,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished">Redagowanie wiadomości nie powiodło się: %1</translation> </message> @@ -1580,7 +1683,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished">Zapisz obraz</translation> </message> @@ -1715,12 +1818,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">Dołączyłeś(-łaś) do tego pokoju.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1749,7 +1852,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1757,17 +1860,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1775,7 +1893,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1783,18 +1901,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished">Ustawienia pokoju</translation> </message> @@ -1835,7 +1952,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1845,7 +1962,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1894,7 +2011,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1903,7 +2020,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Zminimalizuj do paska zadań</translation> </message> @@ -2349,7 +2466,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2400,7 +2517,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2472,19 +2589,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Anuluj</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>ID użytkownika do zaproszenia</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2597,7 +2701,7 @@ Rozmiar multimediów: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_pt_BR.ts b/resources/langs/nheko_pt_BR.ts index fa0ea193..b83585fb 100644 --- a/resources/langs/nheko_pt_BR.ts +++ b/resources/langs/nheko_pt_BR.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation>Esperando o outro lado completar a verificação.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Cancelar</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Falha ao convidar usuário: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Confirmar convite</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation>Usuário desbanido: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Migração do cache falhou!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,18 +655,44 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> <translation type="unfinished"></translation> </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Cancelar</translation> + </message> </context> <context> <name>LoginPage</name> @@ -741,27 +805,14 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -781,17 +832,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -806,23 +857,23 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Aceitar</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Rejeitar</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">Você entrou nessa sala.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished">Cancelar</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_pt_PT.ts b/resources/langs/nheko_pt_PT.ts index 81343f97..a0a8c8a8 100644 --- a/resources/langs/nheko_pt_PT.ts +++ b/resources/langs/nheko_pt_PT.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished"></translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation type="unfinished"></translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,16 +655,42 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> <translation type="unfinished"></translation> </message> </context> @@ -741,27 +805,14 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -781,17 +832,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -806,23 +857,23 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_ro.ts b/resources/langs/nheko_ro.ts index c21bb069..6ea496f1 100644 --- a/resources/langs/nheko_ro.ts +++ b/resources/langs/nheko_ro.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished"></translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Nu s-a putut invita utilizatorul: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation>Utilizator dezinterzis: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Nu s-a putut migra cache-ul!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Închide</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished">Toate fișierele (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">IDul utilizatorului de invitat</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Ștergere</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -745,22 +809,9 @@ Exemplu: https://serverul.meu:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Membrii camerei</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -771,7 +822,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation>Criptare activată</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>numele camerei schimbat la: %1</translation> </message> @@ -781,7 +832,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation>numele camerei șters</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>subiect schimbat la: %1</translation> </message> @@ -791,17 +842,17 @@ Exemplu: https://serverul.meu:8787</translation> <translation>subiect șters</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 a creat și configurat camera: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -816,17 +867,17 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 a răspuns apelului.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 a închis apelul.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -834,7 +885,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -855,6 +906,11 @@ Exemplu: https://serverul.meu:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -872,17 +928,17 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished">Răspuns</translation> </message> @@ -892,7 +948,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished">Opțiuni</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1100,7 +1156,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>eveniment neimplementat: </translation> </message> @@ -1220,7 +1276,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished">Închide</translation> </message> @@ -1233,7 +1289,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>nicio versiune stocată</translation> </message> @@ -1241,7 +1297,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1251,6 +1307,16 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Părăsește camera</translation> @@ -1281,17 +1347,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Acceptare</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Refuzare</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1342,19 +1398,42 @@ Exemplu: https://serverul.meu:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1410,19 +1489,22 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1437,12 +1519,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">Nu s-a putut activa criptarea: %1</translation> </message> @@ -1474,6 +1551,24 @@ Exemplu: https://serverul.meu:8787</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1530,7 +1625,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Eșuat</translation> </message> @@ -1551,6 +1646,14 @@ Exemplu: https://serverul.meu:8787</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1571,7 +1674,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Redactare mesaj eșuată: %1</translation> </message> @@ -1582,7 +1685,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Salvați imaginea</translation> </message> @@ -1717,12 +1820,12 @@ Exemplu: https://serverul.meu:8787</translation> <translation>%1 și-a redactat ciocănitul.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Te-ai alăturat camerei.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1751,7 +1854,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1759,17 +1862,32 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Nicio cameră deschisă</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1777,7 +1895,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1785,18 +1903,17 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1837,7 +1954,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1847,7 +1964,7 @@ Exemplu: https://serverul.meu:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1896,7 +2013,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1905,7 +2022,7 @@ Exemplu: https://serverul.meu:8787</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Minimizează în bara de notificări</translation> </message> @@ -2351,7 +2468,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2402,7 +2519,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Ieri</translation> </message> @@ -2474,19 +2591,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Anulare</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>IDul utilizatorului de invitat</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2599,7 +2703,7 @@ Dimensiune media: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Ai trimis un clip audio</translation> </message> diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 6f2b19af..67a306f2 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Ожидание Подтверждения</translation> </message> @@ -48,7 +48,7 @@ <translation>Ожидание подтверждения у собеседника.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Отмена</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Не удалось пригласить пользователя: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Подтвердите приглашение</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Вы точно хотите пригласить %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Разблокированный пользователь: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation>Вы действительно хотите начать личную переписку с %1?</translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Миграция кэша не удалась!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Расшифровать секреты</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Поиск</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Люди</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Закрыть</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Выберите файл</translation> </message> @@ -617,17 +655,43 @@ <translation>Все файлы (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Не удалось загрузить медиа. Пожалуйста попробуйте ещё раз</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Удалить</translation> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Идентификатор пользователя</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -745,22 +809,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Участники комнаты</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>ОК</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation>убрано</translation> @@ -771,7 +822,7 @@ Example: https://server.my:8787</source> <translation>Шифрование включено</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>имя комнаты изменено на: %1</translation> </message> @@ -781,7 +832,7 @@ Example: https://server.my:8787</source> <translation>название комнаты убрано</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>тема изменена на: %1</translation> </message> @@ -791,17 +842,17 @@ Example: https://server.my:8787</source> <translation>тема убрана</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 создал и настроил комнату: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 начал голосовой звонок.</translation> </message> @@ -816,17 +867,17 @@ Example: https://server.my:8787</source> <translation>%1 начал вызов.</translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation>%1 ответил на звонок.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation>%1 завершил вызов.</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation>Совершение звонка...</translation> </message> @@ -834,7 +885,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Завершить звонок</translation> </message> @@ -855,6 +906,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Эмоджи</translation> </message> @@ -872,17 +928,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation>Редактировать</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation>Реакция</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation>Ответить</translation> </message> @@ -892,7 +948,7 @@ Example: https://server.my:8787</source> <translation>Опции</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1100,7 +1156,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>не реализованное событие</translation> </message> @@ -1220,7 +1276,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Закрыть</translation> </message> @@ -1233,7 +1289,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>нет сохраненной версии</translation> </message> @@ -1241,7 +1297,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1251,6 +1307,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Покинуть комнату</translation> @@ -1281,17 +1347,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Принять</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">Отказаться</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1342,19 +1398,42 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation>Настройки комнаты</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation>%1 участник(ов)</translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation>НАЙСТРОЙКИ</translation> </message> @@ -1410,19 +1489,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> - <translation>Отвечать на запрос ключей</translation> + <location line="+16"/> + <source>Sticker & Emote Settings</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation>ИНФОРМАЦИЯ</translation> </message> @@ -1437,12 +1519,7 @@ Example: https://server.my:8787</source> <translation>Версия Комнаты</translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation>ОК</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation>Не удалось включить шифрование: %1</translation> </message> @@ -1474,6 +1551,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1530,7 +1625,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Не удалоcь</translation> </message> @@ -1551,6 +1646,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Поиск</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1571,7 +1674,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Ошибка редактирования сообщения: %1</translation> </message> @@ -1582,7 +1685,7 @@ Example: https://server.my:8787</source> <translation>Не удалось зашифровать сообщение, отправка отменена!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Сохранить изображение</translation> </message> @@ -1717,12 +1820,12 @@ Example: https://server.my:8787</source> <translation>%1 отредактировал его "стук".</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Вы присоединились к этой комнате.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1751,7 +1854,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation>Изменено</translation> </message> @@ -1759,17 +1862,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Комната не выбрана</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished">%1 участник(ов)</translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished">Вернуться к списку комнат</translation> </message> @@ -1777,7 +1895,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Не найдено личного чата с этим пользователем. Создайте зашифрованный личный чат с этим пользователем и попытайтесь еще раз.</translation> </message> @@ -1785,18 +1903,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Вернуться к списку комнат</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Комнаты не выбраны</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Настройки комнаты</translation> </message> @@ -1837,7 +1954,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation>Глобальный Пользовательский Профиль</translation> </message> @@ -1847,7 +1964,7 @@ Example: https://server.my:8787</source> <translation>Поользовательский Профиль в Комнате</translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Верифицировать</translation> @@ -1896,7 +2013,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation>По умолчанию</translation> @@ -1905,7 +2022,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Сворачивать в системную панель</translation> </message> @@ -2357,7 +2474,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2408,7 +2525,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Вчера</translation> </message> @@ -2480,19 +2597,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Отмена</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Идентификатор пользователя</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2605,7 +2709,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Вы отправили аудио запись</translation> </message> diff --git a/resources/langs/nheko_si.ts b/resources/langs/nheko_si.ts index a80adb1b..cf425990 100644 --- a/resources/langs/nheko_si.ts +++ b/resources/langs/nheko_si.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation type="unfinished"></translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation type="unfinished"></translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation type="unfinished"></translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished"></translation> </message> @@ -617,16 +655,42 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> + <location line="+7"/> + <source>Cancel</source> <translation type="unfinished"></translation> </message> </context> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished"></translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,41 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1484,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1514,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished"></translation> </message> @@ -1470,6 +1546,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1620,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1641,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1669,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished"></translation> </message> @@ -1578,7 +1680,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished"></translation> </message> @@ -1712,12 +1814,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1746,7 +1848,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1754,17 +1856,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1772,7 +1889,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1780,18 +1897,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished"></translation> </message> @@ -1832,7 +1948,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1842,7 +1958,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1891,7 +2007,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1900,7 +2016,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation type="unfinished"></translation> </message> @@ -2346,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2397,7 +2513,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2469,19 +2585,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2592,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/langs/nheko_sv.ts b/resources/langs/nheko_sv.ts index 8069dcea..25db1c4b 100644 --- a/resources/langs/nheko_sv.ts +++ b/resources/langs/nheko_sv.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation>Inväntar Bekräftelse</translation> </message> @@ -48,7 +48,7 @@ <translation>Väntar på att motparten ska slutföra verifikationen.</translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>Avbryt</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>Kunde inte bjuda in användare: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation>Bekräfta inbjudan</translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation>Är du säker på att du vill bjuda in %1 (%2)?</translation> </message> @@ -227,12 +227,12 @@ <translation>Hävde bannlysningen av användare: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>Cache-migration misslyckades!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation>Dekryptera hemliga nycklar</translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation>Sök</translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation>Personer</translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished">Stäng</translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation>Välj en fil</translation> </message> @@ -617,17 +655,43 @@ <translation>Alla Filer (*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation>Kunde inte ladda upp media. Vänligen försök igen.</translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>Ta bort</translation> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">Användar-ID att bjuda in</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">Avbryt</translation> </message> </context> <context> @@ -745,27 +809,14 @@ Exempel: https://server.my:8787</translation> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>Rumsmedlemmar</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation>OK</translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+128"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+187"/> <source>Encryption enabled</source> <translation>Kryptering aktiverad</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation>rummets namn ändrat till: %1</translation> </message> @@ -775,7 +826,7 @@ Exempel: https://server.my:8787</translation> <translation>tog bort rummets namn</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation>ämne ändrat till: %1</translation> </message> @@ -785,17 +836,17 @@ Exempel: https://server.my:8787</translation> <translation>tog bort ämne</translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation>%1 skapade och konfigurerade rum: %2</translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation>%1 påbörjade ett röstsamtal.</translation> </message> @@ -810,23 +861,23 @@ Exempel: https://server.my:8787</translation> <translation>%1 påbörjade ett samtal.</translation> </message> <message> - <location line="+29"/> + <location line="+38"/> <source>Negotiating call...</source> <translation>Förhandlar samtal…</translation> </message> <message> - <location line="-18"/> + <location line="-24"/> <source>%1 answered the call.</source> <translation>%1 besvarade samtalet.</translation> </message> <message> - <location line="-80"/> + <location line="-99"/> <location line="+9"/> <source>removed</source> <translation>borttagen</translation> </message> <message> - <location line="+80"/> + <location line="+102"/> <source>%1 ended the call.</source> <translation>%1 avslutade samtalet.</translation> </message> @@ -834,7 +885,7 @@ Exempel: https://server.my:8787</translation> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation>Lägg på</translation> </message> @@ -855,6 +906,11 @@ Exempel: https://server.my:8787</translation> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation>Emoji</translation> </message> @@ -872,17 +928,17 @@ Exempel: https://server.my:8787</translation> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished">Reagera</translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished">Svara</translation> </message> @@ -892,7 +948,7 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished">Alternativ</translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1100,7 +1156,7 @@ Exempel: https://server.my:8787</translation> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation>ej implementerat event: </translation> </message> @@ -1220,7 +1276,7 @@ Exempel: https://server.my:8787</translation> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation>Stäng</translation> </message> @@ -1233,7 +1289,7 @@ Exempel: https://server.my:8787</translation> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation>ingen version lagrad</translation> </message> @@ -1241,7 +1297,7 @@ Exempel: https://server.my:8787</translation> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1251,6 +1307,16 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">Lämna rum</translation> @@ -1281,17 +1347,7 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">Godkänn</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1342,19 +1398,41 @@ Exempel: https://server.my:8787</translation> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1410,19 +1488,22 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1437,12 +1518,7 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished">OK</translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">Kunde inte aktivera kryptering: %1</translation> </message> @@ -1474,6 +1550,24 @@ Exempel: https://server.my:8787</translation> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1530,7 +1624,7 @@ Exempel: https://server.my:8787</translation> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation>Misslyckat</translation> </message> @@ -1551,6 +1645,14 @@ Exempel: https://server.my:8787</translation> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished">Sök</translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1571,7 +1673,7 @@ Exempel: https://server.my:8787</translation> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation>Kunde inte maskera meddelande: %1</translation> </message> @@ -1582,7 +1684,7 @@ Exempel: https://server.my:8787</translation> <translation>Kunde inte kryptera event, sändning avbruten!</translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation>Spara bild</translation> </message> @@ -1716,12 +1818,12 @@ Exempel: https://server.my:8787</translation> <translation>%1 maskerade sin knackning.</translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation>Du gick med i detta rum.</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1750,7 +1852,7 @@ Exempel: https://server.my:8787</translation> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1758,17 +1860,32 @@ Exempel: https://server.my:8787</translation> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation>Inget rum öppet</translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished">Tillbaka till rumlista</translation> </message> @@ -1776,7 +1893,7 @@ Exempel: https://server.my:8787</translation> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation>Ingen krypterad privat chatt med denna användare kunde hittas. Skapa en krypterad privat chatt med användaren och försök igen.</translation> </message> @@ -1784,18 +1901,17 @@ Exempel: https://server.my:8787</translation> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation>Tillbaka till rumlista</translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation>Inget rum markerat</translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation>Alternativ för rum</translation> </message> @@ -1836,7 +1952,7 @@ Exempel: https://server.my:8787</translation> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1846,7 +1962,7 @@ Exempel: https://server.my:8787</translation> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation>Bekräfta</translation> @@ -1895,7 +2011,7 @@ Exempel: https://server.my:8787</translation> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1904,7 +2020,7 @@ Exempel: https://server.my:8787</translation> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>Minimera till systemtråg</translation> </message> @@ -2358,7 +2474,7 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation>Väntar på motparten…</translation> </message> @@ -2409,7 +2525,7 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation>Igår</translation> </message> @@ -2481,19 +2597,6 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>Avbryt</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>Användar-ID att bjuda in</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2606,7 +2709,7 @@ Mediastorlek: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation>Du skickade ett ljudklipp</translation> </message> diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index d468dfaa..75e9db95 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -38,7 +38,7 @@ <context> <name>AwaitingVerificationConfirmation</name> <message> - <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+11"/> + <location filename="../qml/device-verification/AwaitingVerificationConfirmation.qml" line="+12"/> <source>Awaiting Confirmation</source> <translation type="unfinished"></translation> </message> @@ -48,7 +48,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>Cancel</source> <translation>取消</translation> </message> @@ -125,7 +125,7 @@ <context> <name>ChatPage</name> <message> - <location filename="../../src/ChatPage.cpp" line="+133"/> + <location filename="../../src/ChatPage.cpp" line="+135"/> <source>Failed to invite user: %1</source> <translation>邀请用户失败: %1</translation> </message> @@ -157,12 +157,12 @@ </message> <message> <location line="+34"/> - <location line="+280"/> + <location line="+286"/> <source>Confirm invite</source> <translation type="unfinished"></translation> </message> <message> - <location line="-279"/> + <location line="-285"/> <source>Do you really want to invite %1 (%2)?</source> <translation type="unfinished"></translation> </message> @@ -227,12 +227,12 @@ <translation>解禁用户: %1</translation> </message> <message> - <location line="+183"/> + <location line="+189"/> <source>Do you really want to start a private chat with %1?</source> <translation type="unfinished"></translation> </message> <message> - <location line="-721"/> + <location line="-727"/> <source>Cache migration failed!</source> <translation>缓存迁移失败!</translation> </message> @@ -352,7 +352,7 @@ <context> <name>CrossSigningSecrets</name> <message> - <location filename="../../src/ChatPage.cpp" line="+183"/> + <location filename="../../src/ChatPage.cpp" line="+189"/> <source>Decrypt secrets</source> <translation type="unfinished"></translation> </message> @@ -426,12 +426,12 @@ <context> <name>EmojiPicker</name> <message> - <location filename="../qml/emoji/EmojiPicker.qml" line="+59"/> + <location filename="../qml/emoji/EmojiPicker.qml" line="+68"/> <source>Search</source> <translation type="unfinished"></translation> </message> <message> - <location line="+172"/> + <location line="+186"/> <source>People</source> <translation type="unfinished"></translation> </message> @@ -605,9 +605,47 @@ </message> </context> <context> + <name>ImagePackSettingsDialog</name> + <message> + <location filename="../qml/dialogs/ImagePackSettingsDialog.qml" line="+22"/> + <source>Image pack settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+151"/> + <source>Private pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Pack from this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Globally enabled pack</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+59"/> + <source>Enable globally</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Enables this pack to be used in all rooms</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+62"/> + <source>Close</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>InputBar</name> <message> - <location filename="../../src/timeline/InputBar.cpp" line="+233"/> + <location filename="../../src/timeline/InputBar.cpp" line="+234"/> <source>Select a file</source> <translation type="unfinished">选择一个文件</translation> </message> @@ -617,17 +655,43 @@ <translation type="unfinished">所有文件(*)</translation> </message> <message> - <location line="+417"/> + <location line="+442"/> <source>Failed to upload media. Please try again.</source> <translation type="unfinished"></translation> </message> </context> <context> - <name>InviteeItem</name> + <name>InviteDialog</name> + <message> + <location filename="../qml/InviteDialog.qml" line="+32"/> + <source>Invite users to %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> + <source>User ID to invite</source> + <translation type="unfinished">要邀请的用户 ID</translation> + </message> + <message> + <location line="+14"/> + <source>@joe:matrix.org</source> + <comment>Example user id. The name 'joe' can be localized however you want.</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Add</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../src/InviteeItem.cpp" line="+22"/> - <source>Remove</source> - <translation>移除</translation> + <location line="+58"/> + <source>Invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation type="unfinished">取消</translation> </message> </context> <context> @@ -741,22 +805,9 @@ Example: https://server.my:8787</source> </message> </context> <context> - <name>MemberList</name> - <message> - <location filename="../../src/dialogs/MemberList.cpp" line="+94"/> - <source>Room members</source> - <translation>聊天室成员</translation> - </message> - <message> - <location line="+4"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> <name>MessageDelegate</name> <message> - <location filename="../qml/delegates/MessageDelegate.qml" line="+110"/> + <location filename="../qml/delegates/MessageDelegate.qml" line="+169"/> <location line="+9"/> <source>removed</source> <translation type="unfinished"></translation> @@ -767,7 +818,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>room name changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -777,7 +828,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>topic changed to: %1</source> <translation type="unfinished"></translation> </message> @@ -787,17 +838,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 changed the room avatar</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+12"/> <source>%1 created and configured room: %2</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+15"/> <source>%1 placed a voice call.</source> <translation type="unfinished"></translation> </message> @@ -812,17 +863,17 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>%1 answered the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>%1 ended the call.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+12"/> <source>Negotiating call...</source> <translation type="unfinished"></translation> </message> @@ -830,7 +881,7 @@ Example: https://server.my:8787</source> <context> <name>MessageInput</name> <message> - <location filename="../qml/MessageInput.qml" line="+43"/> + <location filename="../qml/MessageInput.qml" line="+44"/> <source>Hang up</source> <translation type="unfinished"></translation> </message> @@ -851,6 +902,11 @@ Example: https://server.my:8787</source> </message> <message> <location line="+214"/> + <source>Stickers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+24"/> <source>Emoji</source> <translation type="unfinished"></translation> </message> @@ -868,17 +924,17 @@ Example: https://server.my:8787</source> <context> <name>MessageView</name> <message> - <location filename="../qml/MessageView.qml" line="+83"/> + <location filename="../qml/MessageView.qml" line="+87"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>React</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Reply</source> <translation type="unfinished"></translation> </message> @@ -888,7 +944,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+329"/> + <location line="+405"/> <source>&Copy</source> <translation type="unfinished"></translation> </message> @@ -1096,7 +1152,7 @@ Example: https://server.my:8787</source> <context> <name>Placeholder</name> <message> - <location filename="../qml/delegates/Placeholder.qml" line="+9"/> + <location filename="../qml/delegates/Placeholder.qml" line="+11"/> <source>unimplemented event: </source> <translation type="unfinished"></translation> </message> @@ -1216,7 +1272,7 @@ Example: https://server.my:8787</source> <context> <name>ReplyPopup</name> <message> - <location filename="../qml/ReplyPopup.qml" line="+47"/> + <location filename="../qml/ReplyPopup.qml" line="+62"/> <source>Close</source> <translation type="unfinished"></translation> </message> @@ -1229,7 +1285,7 @@ Example: https://server.my:8787</source> <context> <name>RoomInfo</name> <message> - <location filename="../../src/Cache.cpp" line="+4009"/> + <location filename="../../src/Cache.cpp" line="+4180"/> <source>no version stored</source> <translation type="unfinished"></translation> </message> @@ -1237,7 +1293,7 @@ Example: https://server.my:8787</source> <context> <name>RoomList</name> <message> - <location filename="../qml/RoomList.qml" line="+56"/> + <location filename="../qml/RoomList.qml" line="+57"/> <source>New tag</source> <translation type="unfinished"></translation> </message> @@ -1247,6 +1303,16 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> + <location line="+9"/> + <source>Leave Room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Are you sure you want to leave this room?</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+7"/> <source>Leave room</source> <translation type="unfinished">离开聊天室</translation> @@ -1277,17 +1343,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+222"/> - <source>Accept</source> - <translation type="unfinished">接受</translation> - </message> - <message> - <location line="+21"/> - <source>Decline</source> - <translation type="unfinished">拒绝</translation> - </message> - <message> - <location line="+68"/> + <location line="+268"/> <source>Status Message</source> <translation type="unfinished"></translation> </message> @@ -1338,19 +1394,40 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomMembers</name> + <message> + <location filename="../qml/RoomMembers.qml" line="+17"/> + <source>Members of %1</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+32"/> + <source>%n people in %1</source> + <comment>Summary above list of members</comment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="+10"/> + <source>Invite more people</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>RoomSettings</name> <message> - <location filename="../qml/RoomSettings.qml" line="+25"/> + <location filename="../qml/RoomSettings.qml" line="+26"/> <source>Room Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+55"/> <source>SETTINGS</source> <translation type="unfinished"></translation> </message> @@ -1406,19 +1483,22 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> - <source>Respond to key requests</source> + <location line="+16"/> + <source>Sticker & Emote Settings</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.</source> + <location line="+4"/> + <source>Change</source> <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+1"/> + <source>Change what packs are enabled, remove packs or create new ones</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> <source>INFO</source> <translation type="unfinished"></translation> </message> @@ -1433,12 +1513,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>OK</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../src/ui/RoomSettings.cpp" line="+268"/> + <location filename="../../src/ui/RoomSettings.cpp" line="+255"/> <source>Failed to enable encryption: %1</source> <translation type="unfinished">启用加密失败:%1</translation> </message> @@ -1470,6 +1545,24 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>RoomlistModel</name> + <message> + <location filename="../../src/timeline/RoomlistModel.cpp" line="+143"/> + <source>Pending invite.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Previewing this room</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> + <source>No preview available</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>ScreenShare</name> <message> <location filename="../qml/voip/ScreenShare.qml" line="+30"/> @@ -1526,7 +1619,7 @@ Example: https://server.my:8787</source> <context> <name>StatusIndicator</name> <message> - <location filename="../qml/StatusIndicator.qml" line="+21"/> + <location filename="../qml/StatusIndicator.qml" line="+24"/> <source>Failed</source> <translation type="unfinished"></translation> </message> @@ -1547,6 +1640,14 @@ Example: https://server.my:8787</source> </message> </context> <context> + <name>StickerPicker</name> + <message> + <location filename="../qml/emoji/StickerPicker.qml" line="+70"/> + <source>Search</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Success</name> <message> <location filename="../qml/device-verification/Success.qml" line="+11"/> @@ -1567,7 +1668,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineModel</name> <message> - <location filename="../../src/timeline/TimelineModel.cpp" line="+1095"/> + <location filename="../../src/timeline/TimelineModel.cpp" line="+1107"/> <source>Message redaction failed: %1</source> <translation type="unfinished">删除消息失败:%1</translation> </message> @@ -1578,7 +1679,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+173"/> <source>Save image</source> <translation type="unfinished">保存图像</translation> </message> @@ -1711,12 +1812,12 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="-883"/> + <location line="-884"/> <source>You joined this room.</source> <translation type="unfinished">您已加入此房间</translation> </message> <message> - <location line="+849"/> + <location line="+850"/> <source>%1 has changed their avatar and changed their display name to %2.</source> <translation type="unfinished"></translation> </message> @@ -1745,7 +1846,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineRow</name> <message> - <location filename="../qml/TimelineRow.qml" line="+106"/> + <location filename="../qml/TimelineRow.qml" line="+180"/> <source>Edited</source> <translation type="unfinished"></translation> </message> @@ -1753,17 +1854,32 @@ Example: https://server.my:8787</source> <context> <name>TimelineView</name> <message> - <location filename="../qml/TimelineView.qml" line="+27"/> + <location filename="../qml/TimelineView.qml" line="+30"/> <source>No room open</source> <translation type="unfinished"></translation> </message> <message> - <location line="+127"/> + <location line="+139"/> <source>%1 member(s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+46"/> + <location line="+33"/> + <source>join the conversation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>accept invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>decline invite</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+27"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> @@ -1771,7 +1887,7 @@ Example: https://server.my:8787</source> <context> <name>TimelineViewManager</name> <message> - <location filename="../../src/timeline/TimelineViewManager.cpp" line="+461"/> + <location filename="../../src/timeline/TimelineViewManager.cpp" line="+527"/> <source>No encrypted private chat found with this user. Create an encrypted private chat with this user and try again.</source> <translation type="unfinished"></translation> </message> @@ -1779,18 +1895,17 @@ Example: https://server.my:8787</source> <context> <name>TopBar</name> <message> - <location filename="../qml/TopBar.qml" line="+51"/> + <location filename="../qml/TopBar.qml" line="+54"/> <source>Back to room list</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> - <location line="+10"/> + <location line="-39"/> <source>No room selected</source> <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+90"/> <source>Room options</source> <translation type="unfinished">聊天室选项</translation> </message> @@ -1831,7 +1946,7 @@ Example: https://server.my:8787</source> <context> <name>UserProfile</name> <message> - <location filename="../qml/UserProfile.qml" line="+24"/> + <location filename="../qml/UserProfile.qml" line="+25"/> <source>Global User Profile</source> <translation type="unfinished"></translation> </message> @@ -1841,7 +1956,7 @@ Example: https://server.my:8787</source> <translation type="unfinished"></translation> </message> <message> - <location line="+114"/> + <location line="+115"/> <location line="+107"/> <source>Verify</source> <translation type="unfinished"></translation> @@ -1890,7 +2005,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettings</name> <message> - <location filename="../../src/UserSettingsPage.cpp" line="+362"/> + <location filename="../../src/UserSettingsPage.cpp" line="+363"/> <location filename="../../src/UserSettingsPage.h" line="+194"/> <source>Default</source> <translation type="unfinished"></translation> @@ -1899,7 +2014,7 @@ Example: https://server.my:8787</source> <context> <name>UserSettingsPage</name> <message> - <location line="+524"/> + <location line="+525"/> <source>Minimize to tray</source> <translation>最小化至托盘</translation> </message> @@ -2345,7 +2460,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>Waiting</name> <message> - <location filename="../qml/device-verification/Waiting.qml" line="+11"/> + <location filename="../qml/device-verification/Waiting.qml" line="+12"/> <source>Waiting for other party…</source> <translation type="unfinished"></translation> </message> @@ -2396,7 +2511,7 @@ This usually causes the application icon in the task bar to animate in some fash <context> <name>descriptiveTime</name> <message> - <location filename="../../src/Utils.cpp" line="+207"/> + <location filename="../../src/Utils.cpp" line="+184"/> <source>Yesterday</source> <translation type="unfinished"></translation> </message> @@ -2468,19 +2583,6 @@ This usually causes the application icon in the task bar to animate in some fash </message> </context> <context> - <name>dialogs::InviteUsers</name> - <message> - <location filename="../../src/dialogs/InviteUsers.cpp" line="+46"/> - <source>Cancel</source> - <translation>取消</translation> - </message> - <message> - <location line="+8"/> - <source>User ID to invite</source> - <translation>要邀请的用户 ID</translation> - </message> -</context> -<context> <name>dialogs::JoinRoom</name> <message> <location filename="../../src/dialogs/JoinRoom.cpp" line="+34"/> @@ -2593,7 +2695,7 @@ Media size: %2 <context> <name>message-description sent:</name> <message> - <location filename="../../src/Utils.h" line="+124"/> + <location filename="../../src/Utils.h" line="+115"/> <source>You sent an audio clip</source> <translation type="unfinished"></translation> </message> diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml index 6c12952a..9685dde1 100644 --- a/resources/qml/Avatar.qml +++ b/resources/qml/Avatar.qml @@ -11,10 +11,11 @@ import im.nheko 1.0 Rectangle { id: avatar - property alias url: img.source + property string url property string userid property string displayName property alias textColor: label.color + property bool crop: true signal clicked(var mouse) @@ -44,12 +45,13 @@ Rectangle { anchors.fill: parent asynchronous: true - fillMode: Image.PreserveAspectCrop + fillMode: avatar.crop ? Image.PreserveAspectCrop : Image.PreserveAspectFit mipmap: true smooth: true sourceSize.width: avatar.width sourceSize.height: avatar.height layer.enabled: true + source: avatar.url + ((avatar.crop || !avatar.url) ? "" : "?scale") MouseArea { id: mouseArea diff --git a/resources/qml/ChatPage.qml b/resources/qml/ChatPage.qml index ae37187b..e56d7d46 100644 --- a/resources/qml/ChatPage.qml +++ b/resources/qml/ChatPage.qml @@ -56,6 +56,7 @@ Rectangle { RoomList { id: roomlist + implicitHeight: chatPage.height collapsed: parent.collapsed } diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index 333fb11d..00fc3216 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -70,7 +70,7 @@ Popup { onCompleterNameChanged: { if (completerName) { if (completerName == "user") - completer = TimelineManager.completerFor(completerName, room.roomId()); + completer = TimelineManager.completerFor(completerName, room.roomId); else completer = TimelineManager.completerFor(completerName); completer.setSearchString(""); diff --git a/resources/qml/ForwardCompleter.qml b/resources/qml/ForwardCompleter.qml index 127b59c2..525477cd 100644 --- a/resources/qml/ForwardCompleter.qml +++ b/resources/qml/ForwardCompleter.qml @@ -109,15 +109,17 @@ Popup { } Connections { - onCompletionSelected: { + function onCompletionSelected(id) { room.forwardMessage(messageContextMenu.eventId, id); forwardMessagePopup.close(); } - onCountChanged: { + + function onCountChanged() { if (completerPopup.count > 0 && (completerPopup.currentIndex < 0 || completerPopup.currentIndex >= completerPopup.count)) completerPopup.currentIndex = 0; } + target: completerPopup } diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml new file mode 100644 index 00000000..2c0e15a7 --- /dev/null +++ b/resources/qml/InviteDialog.qml @@ -0,0 +1,159 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import im.nheko 1.0 + +ApplicationWindow { + id: inviteDialogRoot + + property string roomId + property string plainRoomName + property InviteesModel invitees + + function addInvite() { + if (inviteeEntry.isValidMxid) { + invitees.addUser(inviteeEntry.text); + inviteeEntry.clear(); + } + } + + function cleanUpAndClose() { + if (inviteeEntry.isValidMxid) + addInvite(); + + invitees.accept(); + close(); + } + + title: qsTr("Invite users to %1").arg(plainRoomName) + height: 380 + width: 340 + palette: Nheko.colors + color: Nheko.colors.window + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(inviteDialogRoot) + + Shortcut { + sequence: "Ctrl+Enter" + onActivated: cleanUpAndClose() + } + + Shortcut { + sequence: StandardKey.Cancel + onActivated: inviteDialogRoot.close() + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + spacing: Nheko.paddingMedium + + Label { + text: qsTr("User ID to invite") + Layout.fillWidth: true + color: Nheko.colors.text + } + + RowLayout { + spacing: Nheko.paddingMedium + + MatrixTextField { + id: inviteeEntry + + property bool isValidMxid: text.match("@.+?:.{3,}") + + backgroundColor: Nheko.colors.window + placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") + Layout.fillWidth: true + onAccepted: { + if (isValidMxid) + addInvite(); + + } + Component.onCompleted: forceActiveFocus() + Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) + Keys.onPressed: { + if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) + cleanUpAndClose(); + + } + } + + Button { + text: qsTr("Add") + enabled: inviteeEntry.isValidMxid + onClicked: addInvite() + } + + } + + ListView { + id: inviteesList + + Layout.fillWidth: true + Layout.fillHeight: true + model: invitees + + delegate: RowLayout { + spacing: Nheko.paddingMedium + + Avatar { + width: Nheko.avatarSize + height: Nheko.avatarSize + userid: model.mxid + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.displayName + onClicked: TimelineManager.openGlobalUserProfile(model.mxid) + } + + ColumnLayout { + spacing: Nheko.paddingSmall + + Label { + text: model.displayName + color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) + font.pointSize: fontMetrics.font.pointSize + } + + Label { + text: model.mxid + color: Nheko.colors.buttonText + font.pointSize: fontMetrics.font.pointSize * 0.9 + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + + } + + } + + } + + } + + footer: DialogButtonBox { + id: buttons + + Button { + text: qsTr("Invite") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + enabled: invitees.count > 0 + onClicked: cleanUpAndClose() + } + + Button { + text: qsTr("Cancel") + DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole + onClicked: inviteDialogRoot.close() + } + + } + +} diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml index 35e5f7e7..7253cbe6 100644 --- a/resources/qml/MatrixText.qml +++ b/resources/qml/MatrixText.qml @@ -18,8 +18,8 @@ TextEdit { //enabled: selectByMouse color: Nheko.colors.text onLinkActivated: Nheko.openLink(link) - ToolTip.visible: hoveredLink - ToolTip.text: hoveredLink + ToolTip.visible: hoveredLink || false + ToolTip.text: hoveredLink || "" Component.onCompleted: { TimelineManager.fixImageRendering(r.textDocument, r); } diff --git a/resources/qml/MatrixTextField.qml b/resources/qml/MatrixTextField.qml index 3c660bac..80732b27 100644 --- a/resources/qml/MatrixTextField.qml +++ b/resources/qml/MatrixTextField.qml @@ -10,6 +10,8 @@ import im.nheko 1.0 TextField { id: input + property alias backgroundColor: backgroundRect.color + palette: Nheko.colors color: Nheko.colors.text @@ -62,6 +64,8 @@ TextField { } background: Rectangle { + id: backgroundRect + color: Nheko.colors.base } diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index 415d67a7..7fb09684 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -7,7 +7,7 @@ import "./voip" import QtQuick 2.12 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.2 +import QtQuick.Window 2.13 import im.nheko 1.0 Rectangle { @@ -261,18 +261,24 @@ Rectangle { background: null Connections { - onRoomChanged: { + function onRoomChanged() { messageInput.clear(); - messageInput.append(room.input.text()); + if (room) + messageInput.append(room.input.text()); + messageInput.completerTriggeredAt = -1; popup.completerName = ""; messageInput.forceActiveFocus(); } + target: timelineView } Connections { - onCompletionClicked: messageInput.insertCompletion(completion) + function onCompletionClicked(completion) { + messageInput.insertCompletion(completion); + } + target: popup } @@ -284,28 +290,39 @@ Rectangle { } Connections { - ignoreUnknownSignals: true - onInsertText: { + function onInsertText(text) { messageInput.remove(messageInput.selectionStart, messageInput.selectionEnd); messageInput.insert(messageInput.cursorPosition, text); } - onTextChanged: { + + function onTextChanged(newText) { messageInput.text = newText; messageInput.cursorPosition = newText.length; } + + ignoreUnknownSignals: true target: room ? room.input : null } Connections { + function onReplyChanged() { + messageInput.forceActiveFocus(); + } + + function onEditChanged() { + messageInput.forceActiveFocus(); + } + ignoreUnknownSignals: true - onReplyChanged: messageInput.forceActiveFocus() - onEditChanged: messageInput.forceActiveFocus() target: room } Connections { + function onFocusInput() { + messageInput.forceActiveFocus(); + } + target: TimelineManager - onFocusInput: messageInput.forceActiveFocus() } MouseArea { @@ -331,7 +348,7 @@ Rectangle { image: ":/icons/icons/ui/sticky-note-solid.svg" ToolTip.visible: hovered ToolTip.text: qsTr("Stickers") - onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId(), function(row) { + onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId, function(row) { room.input.sticker(stickerPopup.model.sourceModel, row); TimelineManager.focusMessageInput(); }) @@ -355,7 +372,7 @@ Rectangle { image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("Emoji") - onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(function(emoji) { + onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) { messageInput.insert(messageInput.cursorPosition, emoji); TimelineManager.focusMessageInput(); }) diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index f56af237..79cbd700 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -10,7 +10,7 @@ import QtGraphicalEffects 1.0 import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.2 +import QtQuick.Window 2.13 import im.nheko 1.0 ScrollView { @@ -200,15 +200,22 @@ ScrollView { } Connections { + function onFocusChanged() { + readTimer.running = TimelineManager.isWindowFocused; + } + target: TimelineManager - onFocusChanged: readTimer.running = TimelineManager.isWindowFocused } Timer { id: readTimer // force current read index to update - onTriggered: chat.model.setCurrentIndex(chat.model.currentIndex) + onTriggered: { + if (chat.model) + chat.model.setCurrentIndex(chat.model.currentIndex); + + } interval: 1000 } @@ -265,11 +272,15 @@ ScrollView { } Connections { - target: chat.model - onRoomAvatarUrlChanged: { + function onRoomAvatarUrlChanged() { messageUserAvatar.url = chat.model.avatarUrl(userId).replace("mxc://", "image://MxcImage/"); } - onScrollToIndex: chat.positionViewAtIndex(index, ListView.Visible) + + function onScrollToIndex(index) { + chat.positionViewAtIndex(index, ListView.Visible); + } + + target: chat.model } Label { @@ -338,9 +349,11 @@ ScrollView { required property string callType required property var reactions required property int trustlevel + required property int encryptionError required property var timestamp required property int status required property int index + required property int relatedEventCacheBuster required property string previousMessageUserId required property string day required property string previousMessageDay @@ -444,8 +457,10 @@ ScrollView { callType: wrapper.callType reactions: wrapper.reactions trustlevel: wrapper.trustlevel + encryptionError: wrapper.encryptionError timestamp: wrapper.timestamp status: wrapper.status + relatedEventCacheBuster: wrapper.relatedEventCacheBuster y: section.visible && section.active ? section.y + section.height : 0 HoverHandler { @@ -465,22 +480,34 @@ ScrollView { } Connections { - target: chat - onMovementEnded: { + function onMovementEnded() { if (y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height) chat.model.currentIndex = index; } + + target: chat } } - footer: Spinner { + footer: Item { anchors.horizontalCenter: parent.horizontalCenter - running: chat.model && chat.model.paginationInProgress - foreground: Nheko.colors.mid + anchors.margins: Nheko.paddingLarge visible: chat.model && chat.model.paginationInProgress - z: 3 + // hacky, but works + height: loadingSpinner.height + 2 * Nheko.paddingLarge + + Spinner { + id: loadingSpinner + + anchors.centerIn: parent + anchors.margins: Nheko.paddingLarge + running: chat.model && chat.model.paginationInProgress + foreground: Nheko.colors.mid + z: 3 + } + } } @@ -555,7 +582,7 @@ ScrollView { Platform.MenuItem { text: qsTr("Read receip&ts") - onTriggered: room.readReceiptsAction(messageContextMenu.eventId) + onTriggered: room.showReadReceipts(messageContextMenu.eventId) } Platform.MenuItem { diff --git a/resources/qml/PrivacyScreen.qml b/resources/qml/PrivacyScreen.qml index ca73cfd7..5f18a1ce 100644 --- a/resources/qml/PrivacyScreen.qml +++ b/resources/qml/PrivacyScreen.qml @@ -13,8 +13,7 @@ Item { property int screenTimeout Connections { - target: TimelineManager - onFocusChanged: { + function onFocusChanged() { if (TimelineManager.isWindowFocused) { screenSaverTimer.stop(); screenSaver.state = "Invisible"; @@ -24,6 +23,8 @@ Item { } } + + target: TimelineManager } Timer { diff --git a/resources/qml/QuickSwitcher.qml b/resources/qml/QuickSwitcher.qml index 8c4f47ca..61155acf 100644 --- a/resources/qml/QuickSwitcher.qml +++ b/resources/qml/QuickSwitcher.qml @@ -71,15 +71,17 @@ Popup { } Connections { - onCompletionSelected: { + function onCompletionSelected(id) { Rooms.setCurrentRoom(id); quickSwitcher.close(); } - onCountChanged: { + + function onCountChanged() { if (completerPopup.count > 0 && (completerPopup.currentIndex < 0 || completerPopup.currentIndex >= completerPopup.count)) completerPopup.currentIndex = 0; } + target: completerPopup } diff --git a/resources/qml/RawMessageDialog.qml b/resources/qml/RawMessageDialog.qml new file mode 100644 index 00000000..e2a476cd --- /dev/null +++ b/resources/qml/RawMessageDialog.qml @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import im.nheko 1.0 + +ApplicationWindow { + id: rawMessageRoot + + property alias rawMessage: rawMessageView.text + + height: 420 + width: 420 + palette: Nheko.colors + color: Nheko.colors.window + flags: Qt.Tool | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(rawMessageRoot) + + Shortcut { + sequence: StandardKey.Cancel + onActivated: rawMessageRoot.close() + } + + ScrollView { + anchors.margins: Nheko.paddingMedium + anchors.fill: parent + palette: Nheko.colors + padding: Nheko.paddingMedium + + TextArea { + id: rawMessageView + + font: Nheko.monospaceFont() + color: Nheko.colors.text + readOnly: true + + background: Rectangle { + color: Nheko.colors.base + } + + } + + } + + footer: DialogButtonBox { + standardButtons: DialogButtonBox.Ok + onAccepted: rawMessageRoot.close() + } + +} diff --git a/resources/qml/ReadReceipts.qml b/resources/qml/ReadReceipts.qml new file mode 100644 index 00000000..9adbfd5c --- /dev/null +++ b/resources/qml/ReadReceipts.qml @@ -0,0 +1,130 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import im.nheko 1.0 + +ApplicationWindow { + id: readReceiptsRoot + + property ReadReceiptsProxy readReceipts + property Room room + + height: 380 + width: 340 + minimumHeight: 380 + minimumWidth: headerTitle.width + 2 * Nheko.paddingMedium + palette: Nheko.colors + color: Nheko.colors.window + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(readReceiptsRoot) + + Shortcut { + sequence: StandardKey.Cancel + onActivated: readReceiptsRoot.close() + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + spacing: Nheko.paddingMedium + + Label { + id: headerTitle + + color: Nheko.colors.text + Layout.alignment: Qt.AlignCenter + text: qsTr("Read receipts") + font.pointSize: fontMetrics.font.pointSize * 1.5 + } + + ScrollView { + palette: Nheko.colors + padding: Nheko.paddingMedium + ScrollBar.horizontal.visible: false + Layout.fillHeight: true + Layout.minimumHeight: 200 + Layout.fillWidth: true + + ListView { + id: readReceiptsList + + clip: true + spacing: Nheko.paddingMedium + boundsBehavior: Flickable.StopAtBounds + model: readReceipts + + delegate: RowLayout { + spacing: Nheko.paddingMedium + + Avatar { + width: Nheko.avatarSize + height: Nheko.avatarSize + userid: model.mxid + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.displayName + onClicked: room.openUserProfile(model.mxid) + ToolTip.visible: avatarHover.hovered + ToolTip.text: model.mxid + + HoverHandler { + id: avatarHover + } + + } + + ColumnLayout { + spacing: Nheko.paddingSmall + + Label { + text: model.displayName + color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) + font.pointSize: fontMetrics.font.pointSize + ToolTip.visible: displayNameHover.hovered + ToolTip.text: model.mxid + + TapHandler { + onSingleTapped: room.openUserProfile(userId) + } + + CursorShape { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + } + + HoverHandler { + id: displayNameHover + } + + } + + Label { + text: model.timestamp + color: Nheko.colors.buttonText + font.pointSize: fontMetrics.font.pointSize * 0.9 + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + + } + + } + + } + + } + + } + + footer: DialogButtonBox { + standardButtons: DialogButtonBox.Ok + onAccepted: readReceiptsRoot.close() + } + +} diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index a1ce8d7e..98532606 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -32,11 +32,12 @@ Page { } Connections { - onActiveTimelineChanged: { - roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId()), ListView.Contain); - console.log("Test" + Rooms.currentRoom.roomId() + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId())); + function onCurrentRoomChanged() { + roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId), ListView.Contain); + console.log("Test" + Rooms.currentRoom.roomId + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId)); } - target: TimelineManager + + target: Rooms } Platform.Menu { @@ -61,9 +62,19 @@ Page { } } + Platform.MessageDialog { + id: leaveRoomDialog + + title: qsTr("Leave Room") + text: qsTr("Are you sure you want to leave this room?") + modality: Qt.ApplicationModal + onAccepted: Rooms.leave(roomContextMenu.roomid) + buttons: Dialog.Ok | Dialog.Cancel + } + Platform.MenuItem { text: qsTr("Leave room") - onTriggered: Rooms.leave(roomContextMenu.roomid) + onTriggered: leaveRoomDialog.open() } Platform.MenuSeparator { @@ -133,7 +144,7 @@ Page { states: [ State { name: "highlight" - when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId) + when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId) PropertyChanges { target: roomItem @@ -147,7 +158,7 @@ Page { }, State { name: "selected" - when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId + when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId PropertyChanges { target: roomItem @@ -161,31 +172,38 @@ Page { } ] - TapHandler { - margin: -Nheko.paddingSmall - acceptedButtons: Qt.RightButton - onSingleTapped: { - if (!TimelineManager.isInvite) - roomContextMenu.show(roomId, tags); + // NOTE(Nico): We want to prevent the touch areas from overlapping. For some reason we need to add 1px of padding for that... + Item { + anchors.fill: parent + anchors.margins: 1 + TapHandler { + acceptedButtons: Qt.RightButton + onSingleTapped: { + if (!TimelineManager.isInvite) + roomContextMenu.show(roomId, tags); + + } + gesturePolicy: TapHandler.ReleaseWithinBounds + acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad } - gesturePolicy: TapHandler.ReleaseWithinBounds - } - TapHandler { - margin: -Nheko.paddingSmall - onSingleTapped: Rooms.setCurrentRoom(roomId) - onLongPressed: { - if (!isInvite) - roomContextMenu.show(roomId, tags); + TapHandler { + margin: -Nheko.paddingSmall + onSingleTapped: Rooms.setCurrentRoom(roomId) + onLongPressed: { + if (!isInvite) + roomContextMenu.show(roomId, tags); + } } - } - HoverHandler { - id: hovered + HoverHandler { + id: hovered + + acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad + } - margin: -Nheko.paddingSmall } RowLayout { @@ -421,6 +439,7 @@ Page { url: (userInfoGrid.profile ? userInfoGrid.profile.avatarUrl : "").replace("mxc://", "image://MxcImage/") displayName: userInfoGrid.profile ? userInfoGrid.profile.displayName : "" userid: userInfoGrid.profile ? userInfoGrid.profile.userid : "" + enabled: false } ColumnLayout { diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml new file mode 100644 index 00000000..447e6fd1 --- /dev/null +++ b/resources/qml/RoomMembers.qml @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import "./ui" +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtQuick.Window 2.13 +import im.nheko 1.0 + +ApplicationWindow { + id: roomMembersRoot + + property MemberList members + + title: qsTr("Members of %1").arg(members.roomName) + height: 650 + width: 420 + minimumHeight: 420 + palette: Nheko.colors + color: Nheko.colors.window + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(roomMembersRoot) + + Shortcut { + sequence: StandardKey.Cancel + onActivated: roomMembersRoot.close() + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + spacing: Nheko.paddingMedium + + Avatar { + id: roomAvatar + + width: 130 + height: width + displayName: members.roomName + Layout.alignment: Qt.AlignHCenter + url: members.avatarUrl.replace("mxc://", "image://MxcImage/") + onClicked: TimelineManager.openRoomSettings(members.roomId) + } + + ElidedLabel { + font.pixelSize: fontMetrics.font.pixelSize * 2 + fullText: qsTr("%n people in %1", "Summary above list of members", members.memberCount).arg(members.roomName) + Layout.alignment: Qt.AlignHCenter + elideWidth: parent.width - Nheko.paddingMedium + } + + ImageButton { + Layout.alignment: Qt.AlignHCenter + image: ":/icons/icons/ui/add-square-button.png" + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Invite more people") + onClicked: TimelineManager.openInviteUsers(members.roomId) + } + + ScrollView { + palette: Nheko.colors + padding: Nheko.paddingMedium + ScrollBar.horizontal.visible: false + Layout.fillHeight: true + Layout.minimumHeight: 200 + Layout.fillWidth: true + + ListView { + id: memberList + + clip: true + spacing: Nheko.paddingMedium + boundsBehavior: Flickable.StopAtBounds + model: members + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + delegate: RowLayout { + spacing: Nheko.paddingMedium + + Avatar { + width: Nheko.avatarSize + height: Nheko.avatarSize + userid: model.mxid + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.displayName + onClicked: Rooms.currentRoom.openUserProfile(model.mxid) + } + + ColumnLayout { + spacing: Nheko.paddingSmall + + Label { + text: model.displayName + color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) + font.pointSize: fontMetrics.font.pointSize + } + + Label { + text: model.mxid + color: Nheko.colors.buttonText + font.pointSize: fontMetrics.font.pointSize * 0.9 + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + + } + + } + + footer: Item { + width: parent.width + visible: (members.numUsersLoaded < members.memberCount) && members.loadingMoreMembers + // use the default height if it's visible, otherwise no height at all + height: membersLoadingSpinner.height + anchors.margins: Nheko.paddingMedium + + Spinner { + id: membersLoadingSpinner + + anchors.centerIn: parent + height: visible ? 35 : 0 + } + + } + + } + + } + + } + + footer: DialogButtonBox { + standardButtons: DialogButtonBox.Ok + onAccepted: roomMembersRoot.close() + } + +} diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index c852b837..69cf427c 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -4,10 +4,10 @@ import "./ui" import Qt.labs.platform 1.1 as Platform -import QtQuick 2.9 +import QtQuick 2.15 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.3 +import QtQuick.Window 2.13 import im.nheko 1.0 ApplicationWindow { @@ -15,14 +15,13 @@ ApplicationWindow { property var roomSettings - x: MainWindow.x + (MainWindow.width / 2) - (width / 2) - y: MainWindow.y + (MainWindow.height / 2) - (height / 2) minimumWidth: 420 minimumHeight: 650 palette: Nheko.colors color: Nheko.colors.window modality: Qt.NonModal - flags: Qt.Dialog + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(roomSettingsDialog) title: qsTr("Room Settings") Shortcut { @@ -98,13 +97,23 @@ ApplicationWindow { MatrixText { text: roomSettings.roomName - font.pixelSize: 24 + font.pixelSize: fontMetrics.font.pixelSize * 2 Layout.alignment: Qt.AlignHCenter } MatrixText { text: qsTr("%1 member(s)").arg(roomSettings.memberCount) Layout.alignment: Qt.AlignHCenter + + TapHandler { + onTapped: TimelineManager.openRoomMembers(roomSettings.roomId) + } + + CursorShape { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + } + } } @@ -145,7 +154,7 @@ ApplicationWindow { GridLayout { columns: 2 - rowSpacing: 10 + rowSpacing: Nheko.paddingLarge MatrixText { text: qsTr("SETTINGS") @@ -171,7 +180,7 @@ ApplicationWindow { } MatrixText { - text: "Room access" + text: qsTr("Room access") Layout.fillWidth: true } @@ -209,7 +218,7 @@ ApplicationWindow { title: qsTr("End-to-End Encryption") text: qsTr("Encryption is currently experimental and things might break unexpectedly. <br> Please take note that it can't be disabled afterwards.") - modality: Qt.NonModal + modality: Qt.Modal onAccepted: { if (roomSettings.isEncryptionEnabled) return ; @@ -223,19 +232,13 @@ ApplicationWindow { } MatrixText { - visible: roomSettings.isEncryptionEnabled - text: qsTr("Respond to key requests") + text: qsTr("Sticker & Emote Settings") } - ToggleButton { - visible: roomSettings.isEncryptionEnabled - ToolTip.text: qsTr("Whether or not the client should respond automatically with the session keys - upon request. Use with caution, this is a temporary measure to test the - E2E implementation until device verification is completed.") - checked: roomSettings.respondsToKeyRequests - onClicked: { - roomSettings.changeKeyRequestsPreference(checked); - } + Button { + text: qsTr("Change") + ToolTip.text: qsTr("Change what packs are enabled, remove packs or create new ones") + onClicked: TimelineManager.openImagePackSettings(roomSettings.roomId) Layout.alignment: Qt.AlignRight } @@ -264,7 +267,7 @@ ApplicationWindow { MatrixText { text: roomSettings.roomId - font.pixelSize: 14 + font.pixelSize: fontMetrics.font.pixelSize * 1.2 Layout.alignment: Qt.AlignRight } @@ -274,16 +277,16 @@ ApplicationWindow { MatrixText { text: roomSettings.roomVersion - font.pixelSize: 14 + font.pixelSize: fontMetrics.font.pixelSize * 1.2 Layout.alignment: Qt.AlignRight } } - Button { - Layout.alignment: Qt.AlignRight - text: qsTr("OK") - onClicked: close() + DialogButtonBox { + Layout.fillWidth: true + standardButtons: DialogButtonBox.Ok + onAccepted: close() } } diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 5316e20d..b229acda 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -4,14 +4,15 @@ import "./delegates" import "./device-verification" +import "./dialogs" import "./emoji" import "./voip" import Qt.labs.platform 1.1 as Platform import QtGraphicalEffects 1.0 -import QtQuick 2.9 -import QtQuick.Controls 2.5 +import QtQuick 2.15 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.3 -import QtQuick.Window 2.2 +import QtQuick.Window 2.15 import im.nheko 1.0 import im.nheko.EmojiModel 1.0 @@ -48,6 +49,14 @@ Page { } Component { + id: roomMembersComponent + + RoomMembers { + } + + } + + Component { id: mobileCallInviteDialog CallInvite { @@ -63,6 +72,46 @@ Page { } + Component { + id: deviceVerificationDialog + + DeviceVerification { + } + + } + + Component { + id: inviteDialog + + InviteDialog { + } + + } + + Component { + id: packSettingsComponent + + ImagePackSettingsDialog { + } + + } + + Component { + id: readReceiptsDialog + + ReadReceipts { + } + + } + + Component { + id: rawMessageDialog + + RawMessageDialog { + } + + } + Shortcut { sequence: "Ctrl+K" onActivated: { @@ -82,38 +131,64 @@ Page { onActivated: Rooms.previousRoom() } - Component { - id: deviceVerificationDialog - - DeviceVerification { - } - - } - Connections { - target: TimelineManager - onNewDeviceVerificationRequest: { + function onNewDeviceVerificationRequest(flow) { var dialog = deviceVerificationDialog.createObject(timelineRoot, { "flow": flow }); dialog.show(); } - onOpenProfile: { + + function onOpenProfile(profile) { var userProfile = userProfileComponent.createObject(timelineRoot, { "profile": profile }); userProfile.show(); } + + function onShowImagePackSettings(packlist) { + var packSet = packSettingsComponent.createObject(timelineRoot, { + "packlist": packlist + }); + packSet.show(); + } + + function onOpenRoomMembersDialog(members) { + var membersDialog = roomMembersComponent.createObject(timelineRoot, { + "members": members, + "roomName": Rooms.currentRoom.roomName + }); + membersDialog.show(); + } + + function onOpenRoomSettingsDialog(settings) { + var roomSettings = roomSettingsComponent.createObject(timelineRoot, { + "roomSettings": settings + }); + roomSettings.show(); + } + + function onOpenInviteUsersDialog(invitees) { + var dialog = inviteDialog.createObject(timelineRoot, { + "roomId": Rooms.currentRoom.roomId, + "plainRoomName": Rooms.currentRoom.plainRoomName, + "invitees": invitees + }); + dialog.show(); + } + + target: TimelineManager } Connections { - target: CallManager - onNewInviteState: { + function onNewInviteState() { if (CallManager.haveCallInvite && Settings.mobileMode) { var dialog = mobileCallInviteDialog.createObject(msgView); dialog.open(); } } + + target: CallManager } ChatPage { diff --git a/resources/qml/ScrollHelper.qml b/resources/qml/ScrollHelper.qml index 2dd56f27..e84e67fd 100644 --- a/resources/qml/ScrollHelper.qml +++ b/resources/qml/ScrollHelper.qml @@ -23,6 +23,9 @@ MouseArea { // console.warn("Delta: ", wheel.pixelDelta.y); // console.warn("Old position: ", flickable.contentY); // console.warn("New position: ", newPos); + // breaks ListView's with headers... + //if (typeof (flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) + // minYExtent += flickableItem.headerItem.height; id: root @@ -55,9 +58,6 @@ MouseArea { var minYExtent = flickableItem.originY + flickableItem.topMargin; var maxYExtent = (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY) - flickableItem.height; - if (typeof (flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) - minYExtent += flickableItem.headerItem.height; - //Avoid overscrolling return Math.max(minYExtent, Math.min(maxYExtent, flickableItem.contentY - pixelDelta)); } diff --git a/resources/qml/StatusIndicator.qml b/resources/qml/StatusIndicator.qml index 7e471d69..0af02b3c 100644 --- a/resources/qml/StatusIndicator.qml +++ b/resources/qml/StatusIndicator.qml @@ -34,7 +34,7 @@ ImageButton { } onClicked: { if (status == MtxEvent.Read) - room.readReceiptsAction(eventId); + room.showReadReceipts(eventId); } image: { diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 70db08e7..c612479a 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -7,7 +7,7 @@ import "./emoji" import QtQuick 2.12 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.2 +import QtQuick.Window 2.13 import im.nheko 1.0 Item { @@ -38,8 +38,10 @@ Item { required property string callType required property var reactions required property int trustlevel + required property int encryptionError required property var timestamp required property int status + required property int relatedEventCacheBuster anchors.left: parent.left anchors.right: parent.right @@ -90,25 +92,27 @@ Item { } visible: replyTo - userColor: replyTo, TimelineManager.userColor(userId, Nheko.colors.base) - blurhash: replyTo, fromModel(Room.Blurhash) ?? "" - body: replyTo, fromModel(Room.Body) ?? "" - formattedBody: replyTo, fromModel(Room.FormattedBody) ?? "" + userColor: r.relatedEventCacheBuster, TimelineManager.userColor(userId, Nheko.colors.base) + blurhash: r.relatedEventCacheBuster, fromModel(Room.Blurhash) ?? "" + body: r.relatedEventCacheBuster, fromModel(Room.Body) ?? "" + formattedBody: r.relatedEventCacheBuster, fromModel(Room.FormattedBody) ?? "" eventId: fromModel(Room.EventId) ?? "" - filename: replyTo, fromModel(Room.Filename) ?? "" - filesize: replyTo, fromModel(Room.Filesize) ?? "" - proportionalHeight: replyTo, fromModel(Room.ProportionalHeight) ?? 1 - type: replyTo, fromModel(Room.Type) ?? MtxEvent.UnknownMessage - typeString: replyTo, fromModel(Room.TypeString) ?? "" - url: replyTo, fromModel(Room.Url) ?? "" - originalWidth: replyTo, fromModel(Room.OriginalWidth) ?? 0 - isOnlyEmoji: replyTo, fromModel(Room.IsOnlyEmoji) ?? false - userId: replyTo, fromModel(Room.UserId) ?? "" - userName: replyTo, fromModel(Room.UserName) ?? "" - thumbnailUrl: replyTo, fromModel(Room.ThumbnailUrl) ?? "" - roomTopic: replyTo, fromModel(Room.RoomTopic) ?? "" - roomName: replyTo, fromModel(Room.RoomName) ?? "" - callType: replyTo, fromModel(Room.CallType) ?? "" + filename: r.relatedEventCacheBuster, fromModel(Room.Filename) ?? "" + filesize: r.relatedEventCacheBuster, fromModel(Room.Filesize) ?? "" + proportionalHeight: r.relatedEventCacheBuster, fromModel(Room.ProportionalHeight) ?? 1 + type: r.relatedEventCacheBuster, fromModel(Room.Type) ?? MtxEvent.UnknownMessage + typeString: r.relatedEventCacheBuster, fromModel(Room.TypeString) ?? "" + url: r.relatedEventCacheBuster, fromModel(Room.Url) ?? "" + originalWidth: r.relatedEventCacheBuster, fromModel(Room.OriginalWidth) ?? 0 + isOnlyEmoji: r.relatedEventCacheBuster, fromModel(Room.IsOnlyEmoji) ?? false + userId: r.relatedEventCacheBuster, fromModel(Room.UserId) ?? "" + userName: r.relatedEventCacheBuster, fromModel(Room.UserName) ?? "" + thumbnailUrl: r.relatedEventCacheBuster, fromModel(Room.ThumbnailUrl) ?? "" + roomTopic: r.relatedEventCacheBuster, fromModel(Room.RoomTopic) ?? "" + roomName: r.relatedEventCacheBuster, fromModel(Room.RoomName) ?? "" + callType: r.relatedEventCacheBuster, fromModel(Room.CallType) ?? "" + encryptionError: r.relatedEventCacheBuster, fromModel(Room.EncryptionError) ?? "" + relatedEventCacheBuster: r.relatedEventCacheBuster, fromModel(Room.RelatedEventCacheBuster) ?? 0 } // actual message content @@ -134,6 +138,8 @@ Item { roomTopic: r.roomTopic roomName: r.roomName callType: r.callType + encryptionError: r.encryptionError + relatedEventCacheBuster: r.relatedEventCacheBuster isReply: false } diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 148a5817..6fc9d51b 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -13,7 +13,7 @@ import QtGraphicalEffects 1.0 import QtQuick 2.9 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 -import QtQuick.Window 2.2 +import QtQuick.Window 2.13 import im.nheko 1.0 import im.nheko.EmojiModel 1.0 @@ -246,17 +246,26 @@ Item { NhekoDropArea { anchors.fill: parent - roomid: room ? room.roomId() : "" + roomid: room ? room.roomId : "" } Connections { - target: room - onOpenRoomSettingsDialog: { - var roomSettings = roomSettingsComponent.createObject(timelineRoot, { - "roomSettings": settings + function onOpenReadReceiptsDialog(rr) { + var dialog = readReceiptsDialog.createObject(timelineRoot, { + "readReceipts": rr, + "room": room + }); + dialog.show(); + } + + function onShowRawMessageDialog(rawMessage) { + var dialog = rawMessageDialog.createObject(timelineRoot, { + "rawMessage": rawMessage }); - roomSettings.show(); + dialog.show(); } + + target: room } } diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 58aba0c7..8543d02a 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -24,7 +24,7 @@ Rectangle { TapHandler { onSingleTapped: { if (room) - room.openRoomSettings(); + TimelineManager.openRoomSettings(room.roomId); eventPoint.accepted = true; } @@ -66,7 +66,7 @@ Rectangle { displayName: roomName onClicked: { if (room) - room.openRoomSettings(); + TimelineManager.openRoomSettings(room.roomId); } } @@ -111,22 +111,22 @@ Rectangle { Platform.MenuItem { visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") - onTriggered: TimelineManager.openInviteUsersDialog() + onTriggered: TimelineManager.openInviteUsers(room.roomId) } Platform.MenuItem { text: qsTr("Members") - onTriggered: TimelineManager.openMemberListDialog(room.roomId()) + onTriggered: TimelineManager.openRoomMembers(room.roomId) } Platform.MenuItem { text: qsTr("Leave room") - onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId()) + onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId) } Platform.MenuItem { text: qsTr("Settings") - onTriggered: room.openRoomSettings() + onTriggered: TimelineManager.openRoomSettings(room.roomId) } } diff --git a/resources/qml/UserProfile.qml b/resources/qml/UserProfile.qml index 826d3165..767d2317 100644 --- a/resources/qml/UserProfile.qml +++ b/resources/qml/UserProfile.qml @@ -4,19 +4,20 @@ import "./device-verification" import "./ui" -import QtQuick 2.9 -import QtQuick.Controls 2.3 +import QtQuick 2.15 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.3 +import QtQuick.Window 2.13 import im.nheko 1.0 ApplicationWindow { + // this does not work in ApplicationWindow, just in Window + //transientParent: Nheko.mainwindow() + id: userProfileDialog property var profile - x: MainWindow.x + (MainWindow.width / 2) - (width / 2) - y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 650 width: 420 minimumHeight: 420 @@ -24,7 +25,8 @@ ApplicationWindow { color: Nheko.colors.window title: profile.isGlobalUserProfile ? qsTr("Global User Profile") : qsTr("Room User Profile") modality: Qt.NonModal - flags: Qt.Dialog + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(userProfileDialog) Shortcut { sequence: StandardKey.Cancel @@ -83,12 +85,13 @@ ApplicationWindow { } Connections { - target: profile - onDisplayError: { + function onDisplayError(errorMessage) { errorText.text = errorMessage; errorText.opacity = 1; hideErrorAnimation.restart(); } + + target: profile } TextInput { diff --git a/resources/qml/components/AvatarListTile.qml b/resources/qml/components/AvatarListTile.qml new file mode 100644 index 00000000..36c26a97 --- /dev/null +++ b/resources/qml/components/AvatarListTile.qml @@ -0,0 +1,133 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import im.nheko 1.0 + +Rectangle { + id: tile + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property color bubbleBackground: Nheko.colors.highlight + property color bubbleText: Nheko.colors.highlightedText + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3) + required property string avatarUrl + required property string title + required property string subtitle + required property int index + required property int selectedIndex + property bool crop: true + + color: background + height: avatarSize + 2 * Nheko.paddingMedium + width: ListView.view.width + state: "normal" + states: [ + State { + name: "highlight" + when: hovered.hovered && !(index == selectedIndex) + + PropertyChanges { + target: tile + background: Nheko.colors.dark + importantText: Nheko.colors.brightText + unimportantText: Nheko.colors.brightText + bubbleBackground: Nheko.colors.highlight + bubbleText: Nheko.colors.highlightedText + } + + }, + State { + name: "selected" + when: index == selectedIndex + + PropertyChanges { + target: tile + background: Nheko.colors.highlight + importantText: Nheko.colors.highlightedText + unimportantText: Nheko.colors.highlightedText + bubbleBackground: Nheko.colors.highlightedText + bubbleText: Nheko.colors.highlight + } + + } + ] + + HoverHandler { + id: hovered + } + + RowLayout { + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + + Avatar { + id: avatar + + enabled: false + Layout.alignment: Qt.AlignVCenter + height: avatarSize + width: avatarSize + url: tile.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: title + crop: tile.crop + } + + ColumnLayout { + id: textContent + + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + Layout.minimumWidth: 100 + width: parent.width - avatar.width + Layout.preferredWidth: parent.width - avatar.width + spacing: Nheko.paddingSmall + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: tile.importantText + elideWidth: textContent.width - Nheko.paddingMedium + fullText: title + textFormat: Text.PlainText + } + + Item { + Layout.fillWidth: true + } + + } + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + color: tile.unimportantText + font.pixelSize: fontMetrics.font.pixelSize * 0.9 + elideWidth: textContent.width - Nheko.paddingSmall + fullText: subtitle + textFormat: Text.PlainText + } + + Item { + Layout.fillWidth: true + } + + } + + } + + } + +} diff --git a/resources/qml/delegates/Encrypted.qml b/resources/qml/delegates/Encrypted.qml new file mode 100644 index 00000000..cd00a9d4 --- /dev/null +++ b/resources/qml/delegates/Encrypted.qml @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.2 +import im.nheko 1.0 + +ColumnLayout { + id: r + + required property int encryptionError + required property string eventId + + width: parent ? parent.width : undefined + + MatrixText { + text: { + switch (encryptionError) { + case Olm.MissingSession: + return qsTr("There is no key to unlock this message. We requested the key automatically, but you can try requesting it again if you are impatient."); + case Olm.MissingSessionIndex: + return qsTr("This message couldn't be decrypted, because we only have a key for newer messages. You can try requesting access to this message."); + case Olm.DbError: + return qsTr("There was an internal error reading the decryption key from the database."); + case Olm.DecryptionFailed: + return qsTr("There was an error decrypting this message."); + case Olm.ParsingFailed: + return qsTr("The message couldn't be parsed."); + case Olm.ReplayAttack: + return qsTr("The encryption key was reused! Someone is possibly trying to insert false messages into this chat!"); + default: + return qsTr("Unknown decryption error"); + } + } + color: Nheko.colors.buttonText + width: r ? r.width : undefined + } + + Button { + palette: Nheko.colors + visible: encryptionError == Olm.MissingSession || encryptionError == Olm.MissingSessionIndex + text: qsTr("Request key") + onClicked: room.requestKeyForEvent(eventId) + } + +} diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 0b060629..a8bdf183 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -29,6 +29,8 @@ Item { required property string roomTopic required property string roomName required property string callType + required property int encryptionError + required property int relatedEventCacheBuster height: chooser.childrenRect.height @@ -189,6 +191,16 @@ Item { } DelegateChoice { + roleValue: MtxEvent.Encrypted + + Encrypted { + encryptionError: d.encryptionError + eventId: d.eventId + } + + } + + DelegateChoice { roleValue: MtxEvent.Name NoticeMessage { @@ -231,7 +243,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId()) + formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId) } } @@ -301,7 +313,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatPowerLevelEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatPowerLevelEvent(d.eventId) } } @@ -313,7 +325,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatJoinRuleEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatJoinRuleEvent(d.eventId) } } @@ -325,7 +337,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatHistoryVisibilityEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatHistoryVisibilityEvent(d.eventId) } } @@ -337,7 +349,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatGuestAccessEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatGuestAccessEvent(d.eventId) } } @@ -349,7 +361,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatMemberEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatMemberEvent(d.eventId) } } diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml index 3face74d..aa7ee530 100644 --- a/resources/qml/delegates/PlayableMediaMessage.qml +++ b/resources/qml/delegates/PlayableMediaMessage.qml @@ -52,7 +52,7 @@ ColumnLayout { id: mediaCachedObserver target: room - onMediaCached: { + function onMediaCached(mxcUrl, cacheUrl) { if (mxcUrl == url) { mediaCached = true media.source = "file://" + cacheUrl diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index 3a188d78..8bbce10e 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -5,7 +5,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 -import QtQuick.Window 2.2 +import QtQuick.Window 2.13 import im.nheko 1.0 Item { @@ -30,6 +30,8 @@ Item { property string roomTopic property string roomName property string callType + property int encryptionError + property int relatedEventCacheBuster width: parent.width height: replyContainer.height @@ -95,6 +97,8 @@ Item { roomTopic: r.roomTopic roomName: r.roomName callType: r.callType + relatedEventCacheBuster: r.relatedEventCacheBuster + encryptionError: r.encryptionError enabled: false width: parent.width isReply: true diff --git a/resources/qml/device-verification/DeviceVerification.qml b/resources/qml/device-verification/DeviceVerification.qml index e2c66c5a..8e0271d6 100644 --- a/resources/qml/device-verification/DeviceVerification.qml +++ b/resources/qml/device-verification/DeviceVerification.qml @@ -4,7 +4,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 -import QtQuick.Window 2.10 +import QtQuick.Window 2.13 import im.nheko 1.0 ApplicationWindow { @@ -14,13 +14,12 @@ ApplicationWindow { onClosing: TimelineManager.removeVerificationFlow(flow) title: stack.currentItem.title - flags: Qt.Dialog modality: Qt.NonModal palette: Nheko.colors height: stack.implicitHeight width: stack.implicitWidth - x: MainWindow.x + (MainWindow.width / 2) - (width / 2) - y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(dialog) StackView { id: stack diff --git a/resources/qml/dialogs/ImagePackEditorDialog.qml b/resources/qml/dialogs/ImagePackEditorDialog.qml new file mode 100644 index 00000000..b839c9e3 --- /dev/null +++ b/resources/qml/dialogs/ImagePackEditorDialog.qml @@ -0,0 +1,301 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import "../components" +import Qt.labs.platform 1.1 +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import im.nheko 1.0 + +ApplicationWindow { + //Component.onCompleted: Nheko.reparent(win) + + id: win + + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3) + property SingleImagePackModel imagePack + property int currentImageIndex: -1 + readonly property int stickerDim: 128 + readonly property int stickerDimPad: 128 + Nheko.paddingSmall + + title: qsTr("Editing image pack") + height: 600 + width: 600 + palette: Nheko.colors + color: Nheko.colors.base + modality: Qt.WindowModal + flags: Qt.Dialog | Qt.WindowCloseButtonHint + + AdaptiveLayout { + id: adaptiveView + + anchors.fill: parent + singlePageMode: false + pageIndex: 0 + + AdaptiveLayoutElement { + id: packlistC + + visible: Settings.groupView + minimumWidth: 200 + collapsedWidth: 200 + preferredWidth: 300 + maximumWidth: 300 + clip: true + + ListView { + //required property bool isEmote + //required property bool isSticker + + model: imagePack + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + header: AvatarListTile { + title: imagePack.packname + avatarUrl: imagePack.avatarUrl + subtitle: imagePack.statekey + index: -1 + selectedIndex: currentImageIndex + + TapHandler { + onSingleTapped: currentImageIndex = -1 + } + + Rectangle { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + height: parent.height - Nheko.paddingSmall * 2 + width: 3 + color: Nheko.colors.highlight + } + + } + + footer: Button { + palette: Nheko.colors + onClicked: addFilesDialog.open() + width: ListView.view.width + text: qsTr("Add images") + + FileDialog { + id: addFilesDialog + + folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation) + fileMode: FileDialog.OpenFiles + nameFilters: [qsTr("Stickers (*.png *.webp)")] + onAccepted: imagePack.addStickers(files) + } + + } + + delegate: AvatarListTile { + id: packItem + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property color bubbleBackground: Nheko.colors.highlight + property color bubbleText: Nheko.colors.highlightedText + required property string shortCode + required property string url + required property string body + + title: shortCode + subtitle: body + avatarUrl: url + selectedIndex: currentImageIndex + crop: false + + TapHandler { + onSingleTapped: currentImageIndex = index + } + + } + + } + + } + + AdaptiveLayoutElement { + id: packinfoC + + Rectangle { + color: Nheko.colors.window + + GridLayout { + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + visible: currentImageIndex == -1 + enabled: visible + columns: 2 + rowSpacing: Nheko.paddingLarge + + Avatar { + Layout.columnSpan: 2 + url: imagePack.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: imagePack.packname + height: 130 + width: 130 + crop: false + Layout.alignment: Qt.AlignHCenter + } + + MatrixText { + visible: imagePack.roomid + text: qsTr("State key") + } + + MatrixTextField { + visible: imagePack.roomid + Layout.fillWidth: true + text: imagePack.statekey + onTextEdited: imagePack.statekey = text + } + + MatrixText { + text: qsTr("Packname") + } + + MatrixTextField { + Layout.fillWidth: true + text: imagePack.packname + onTextEdited: imagePack.packname = text + } + + MatrixText { + text: qsTr("Attrbution") + } + + MatrixTextField { + Layout.fillWidth: true + text: imagePack.attribution + onTextEdited: imagePack.attribution = text + } + + MatrixText { + text: qsTr("Use as Emoji") + } + + ToggleButton { + checked: imagePack.isEmotePack + onClicked: imagePack.isEmotePack = checked + Layout.alignment: Qt.AlignRight + } + + MatrixText { + text: qsTr("Use as Sticker") + } + + ToggleButton { + checked: imagePack.isStickerPack + onClicked: imagePack.isStickerPack = checked + Layout.alignment: Qt.AlignRight + } + + Item { + Layout.columnSpan: 2 + Layout.fillHeight: true + } + + } + + GridLayout { + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + visible: currentImageIndex >= 0 + enabled: visible + columns: 2 + rowSpacing: Nheko.paddingLarge + + Avatar { + Layout.columnSpan: 2 + url: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.Url).replace("mxc://", "image://MxcImage/") + displayName: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.ShortCode) + height: 130 + width: 130 + crop: false + Layout.alignment: Qt.AlignHCenter + } + + MatrixText { + text: qsTr("Shortcode") + } + + MatrixTextField { + Layout.fillWidth: true + text: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.ShortCode) + onTextEdited: imagePack.setData(imagePack.index(currentImageIndex, 0), text, SingleImagePackModel.ShortCode) + } + + MatrixText { + text: qsTr("Body") + } + + MatrixTextField { + Layout.fillWidth: true + text: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.Body) + onTextEdited: imagePack.setData(imagePack.index(currentImageIndex, 0), text, SingleImagePackModel.Body) + } + + MatrixText { + text: qsTr("Use as Emoji") + } + + ToggleButton { + checked: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.IsEmote) + onClicked: imagePack.setData(imagePack.index(currentImageIndex, 0), checked, SingleImagePackModel.IsEmote) + Layout.alignment: Qt.AlignRight + } + + MatrixText { + text: qsTr("Use as Sticker") + } + + ToggleButton { + checked: imagePack.data(imagePack.index(currentImageIndex, 0), SingleImagePackModel.IsSticker) + onClicked: imagePack.setData(imagePack.index(currentImageIndex, 0), checked, SingleImagePackModel.IsSticker) + Layout.alignment: Qt.AlignRight + } + + Item { + Layout.columnSpan: 2 + Layout.fillHeight: true + } + + } + + } + + } + + } + + footer: DialogButtonBox { + id: buttons + + Button { + text: qsTr("Cancel") + DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole + onClicked: win.close() + } + + Button { + text: qsTr("Save") + DialogButtonBox.buttonRole: DialogButtonBox.ApplyRole + onClicked: { + imagePack.save(); + win.close(); + } + } + + } + +} diff --git a/resources/qml/dialogs/ImagePackSettingsDialog.qml b/resources/qml/dialogs/ImagePackSettingsDialog.qml new file mode 100644 index 00000000..5181619c --- /dev/null +++ b/resources/qml/dialogs/ImagePackSettingsDialog.qml @@ -0,0 +1,260 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import "../components" +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import im.nheko 1.0 + +ApplicationWindow { + id: win + + property ImagePackListModel packlist + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3) + property SingleImagePackModel currentPack: packlist.packAt(currentPackIndex) + property int currentPackIndex: 0 + readonly property int stickerDim: 128 + readonly property int stickerDimPad: 128 + Nheko.paddingSmall + + title: qsTr("Image pack settings") + height: 600 + width: 800 + palette: Nheko.colors + color: Nheko.colors.base + modality: Qt.NonModal + flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(win) + + Component { + id: packEditor + + ImagePackEditorDialog { + } + + } + + AdaptiveLayout { + id: adaptiveView + + anchors.fill: parent + singlePageMode: false + pageIndex: 0 + + AdaptiveLayoutElement { + id: packlistC + + visible: Settings.groupView + minimumWidth: 200 + collapsedWidth: 200 + preferredWidth: 300 + maximumWidth: 300 + + ListView { + model: packlist + clip: true + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + footer: ColumnLayout { + Button { + palette: Nheko.colors + onClicked: { + var dialog = packEditor.createObject(timelineRoot, { + "imagePack": packlist.newPack(false) + }); + dialog.show(); + } + width: packlist.width + visible: !packlist.containsAccountPack + text: qsTr("Create account pack") + } + + Button { + palette: Nheko.colors + onClicked: { + var dialog = packEditor.createObject(timelineRoot, { + "imagePack": packlist.newPack(true) + }); + dialog.show(); + } + width: packlist.width + text: qsTr("New room pack") + } + + } + + delegate: AvatarListTile { + id: packItem + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property color bubbleBackground: Nheko.colors.highlight + property color bubbleText: Nheko.colors.highlightedText + required property string displayName + required property bool fromAccountData + required property bool fromCurrentRoom + + title: displayName + subtitle: { + if (fromAccountData) + return qsTr("Private pack"); + else if (fromCurrentRoom) + return qsTr("Pack from this room"); + else + return qsTr("Globally enabled pack"); + } + selectedIndex: currentPackIndex + + TapHandler { + onSingleTapped: currentPackIndex = index + } + + } + + } + + } + + AdaptiveLayoutElement { + id: packinfoC + + Rectangle { + color: Nheko.colors.window + + ColumnLayout { + id: packinfo + + property string packName: currentPack ? currentPack.packname : "" + property string attribution: currentPack ? currentPack.attribution : "" + property string avatarUrl: currentPack ? currentPack.avatarUrl : "" + + anchors.fill: parent + anchors.margins: Nheko.paddingLarge + spacing: Nheko.paddingLarge + + Avatar { + url: packinfo.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: packinfo.packName + height: 100 + width: 100 + Layout.alignment: Qt.AlignHCenter + enabled: false + } + + MatrixText { + text: packinfo.packName + font.pixelSize: Math.ceil(fontMetrics.pixelSize * 1.1) + horizontalAlignment: TextEdit.AlignHCenter + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: packinfoC.width - Nheko.paddingLarge * 2 + } + + MatrixText { + text: packinfo.attribution + wrapMode: TextEdit.Wrap + horizontalAlignment: TextEdit.AlignHCenter + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: packinfoC.width - Nheko.paddingLarge * 2 + } + + GridLayout { + Layout.alignment: Qt.AlignHCenter + visible: currentPack && currentPack.roomid != "" + columns: 2 + rowSpacing: Nheko.paddingMedium + + MatrixText { + text: qsTr("Enable globally") + } + + ToggleButton { + ToolTip.text: qsTr("Enables this pack to be used in all rooms") + checked: currentPack ? currentPack.isGloballyEnabled : false + onClicked: currentPack.isGloballyEnabled = !currentPack.isGloballyEnabled + Layout.alignment: Qt.AlignRight + } + + } + + Button { + Layout.alignment: Qt.AlignHCenter + text: qsTr("Edit") + enabled: currentPack.canEdit + onClicked: { + var dialog = packEditor.createObject(timelineRoot, { + "imagePack": currentPack + }); + dialog.show(); + } + } + + GridView { + Layout.fillHeight: true + Layout.fillWidth: true + model: currentPack + cellWidth: stickerDimPad + cellHeight: stickerDimPad + boundsBehavior: Flickable.StopAtBounds + clip: true + currentIndex: -1 // prevent sorting from stealing focus + cacheBuffer: 500 + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + // Individual emoji + delegate: AbstractButton { + width: stickerDim + height: stickerDim + hoverEnabled: true + ToolTip.text: ":" + model.shortCode + ": - " + model.body + ToolTip.visible: hovered + + contentItem: Image { + height: stickerDim + width: stickerDim + source: model.url.replace("mxc://", "image://MxcImage/") + fillMode: Image.PreserveAspectFit + } + + background: Rectangle { + anchors.fill: parent + color: hovered ? Nheko.colors.highlight : 'transparent' + radius: 5 + } + + } + + } + + } + + } + + } + + } + + footer: DialogButtonBox { + id: buttons + + Button { + text: qsTr("Close") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + onClicked: win.close() + } + + } + +} diff --git a/resources/qml/dialogs/InputDialog.qml b/resources/qml/dialogs/InputDialog.qml index 134b78a3..e0f17851 100644 --- a/resources/qml/dialogs/InputDialog.qml +++ b/resources/qml/dialogs/InputDialog.qml @@ -16,6 +16,7 @@ ApplicationWindow { modality: Qt.NonModal flags: Qt.Dialog + Component.onCompleted: Nheko.reparent(inputDialog) width: 350 height: fontMetrics.lineSpacing * 7 diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index 813c0b12..3731a948 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -122,7 +122,6 @@ Menu { id: gridView model: roomid ? TimelineManager.completerFor("stickers", roomid) : null - Layout.preferredHeight: cellHeight * 3.5 Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 Layout.leftMargin: 4 diff --git a/resources/qml/voip/CallInvite.qml b/resources/qml/voip/CallInvite.qml index 1b57976d..253fa25c 100644 --- a/resources/qml/voip/CallInvite.qml +++ b/resources/qml/voip/CallInvite.qml @@ -23,12 +23,13 @@ Popup { } Connections { - target: CallManager - onNewInviteState: { + function onNewInviteState() { if (!CallManager.haveCallInvite) close(); } + + target: CallManager } ColumnLayout { diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml index 5f564853..97932cc9 100644 --- a/resources/qml/voip/PlaceCall.qml +++ b/resources/qml/voip/PlaceCall.qml @@ -88,7 +88,7 @@ Popup { onClicked: { if (buttonLayout.validateMic()) { Settings.microphone = micCombo.currentText; - CallManager.sendInvite(room.roomId(), CallType.VOICE); + CallManager.sendInvite(room.roomId, CallType.VOICE); close(); } } @@ -102,7 +102,7 @@ Popup { if (buttonLayout.validateMic()) { Settings.microphone = micCombo.currentText; Settings.camera = cameraCombo.currentText; - CallManager.sendInvite(room.roomId(), CallType.VIDEO); + CallManager.sendInvite(room.roomId, CallType.VIDEO); close(); } } diff --git a/resources/qml/voip/ScreenShare.qml b/resources/qml/voip/ScreenShare.qml index a10057b2..8cd43b1c 100644 --- a/resources/qml/voip/ScreenShare.qml +++ b/resources/qml/voip/ScreenShare.qml @@ -136,7 +136,7 @@ Popup { Settings.screenSharePiP = pipCheckBox.checked; Settings.screenShareRemoteVideo = remoteVideoCheckBox.checked; Settings.screenShareHideCursor = hideCursorCheckBox.checked; - CallManager.sendInvite(room.roomId(), CallType.SCREEN, windowCombo.currentIndex); + CallManager.sendInvite(room.roomId, CallType.SCREEN, windowCombo.currentIndex); close(); } } diff --git a/resources/res.qrc b/resources/res.qrc index d2024eda..e1761cc0 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -10,7 +10,6 @@ <file>icons/ui/do-not-disturb-rounded-sign@2x.png</file> <file>icons/ui/round-remove-button.png</file> <file>icons/ui/round-remove-button@2x.png</file> - <file>icons/ui/double-tick-indicator.png</file> <file>icons/ui/double-tick-indicator@2x.png</file> <file>icons/ui/lock.png</file> @@ -56,22 +55,17 @@ <file>icons/ui/pause-symbol@2x.png</file> <file>icons/ui/remove-symbol.png</file> <file>icons/ui/remove-symbol@2x.png</file> - <file>icons/ui/world.png</file> <file>icons/ui/world@2x.png</file> - <file>icons/ui/tag.png</file> <file>icons/ui/tag@2x.png</file> <file>icons/ui/star.png</file> <file>icons/ui/star@2x.png</file> <file>icons/ui/lowprio.png</file> <file>icons/ui/lowprio@2x.png</file> - <file>icons/ui/edit.png</file> <file>icons/ui/edit@2x.png</file> - <file>icons/ui/mail-reply.png</file> - <file>icons/ui/place-call.png</file> <file>icons/ui/end-call.png</file> <file>icons/ui/microphone-mute.png</file> @@ -79,7 +73,6 @@ <file>icons/ui/screen-share.png</file> <file>icons/ui/toggle-camera-view.png</file> <file>icons/ui/video-call.png</file> - <file>icons/emoji-categories/people.png</file> <file>icons/emoji-categories/people@2x.png</file> <file>icons/emoji-categories/nature.png</file> @@ -100,16 +93,12 @@ <qresource prefix="/logos"> <file>nheko.png</file> <file>nheko.svg</file> - <file>splash.png</file> <file>splash@2x.png</file> - <file>register.png</file> <file>register@2x.png</file> - <file>login.png</file> <file>login@2x.png</file> - <file>nheko-512.png</file> <file>nheko-256.png</file> <file>nheko-128.png</file> @@ -124,7 +113,6 @@ </qresource> <qresource prefix="/"> <file>qtquickcontrols2.conf</file> - <file>qml/Root.qml</file> <file>qml/ChatPage.qml</file> <file>qml/CommunitiesList.qml</file> @@ -156,14 +144,15 @@ <file>qml/emoji/StickerPicker.qml</file> <file>qml/UserProfile.qml</file> <file>qml/delegates/MessageDelegate.qml</file> - <file>qml/delegates/TextMessage.qml</file> - <file>qml/delegates/NoticeMessage.qml</file> - <file>qml/delegates/ImageMessage.qml</file> - <file>qml/delegates/PlayableMediaMessage.qml</file> + <file>qml/delegates/Encrypted.qml</file> <file>qml/delegates/FileMessage.qml</file> + <file>qml/delegates/ImageMessage.qml</file> + <file>qml/delegates/NoticeMessage.qml</file> <file>qml/delegates/Pill.qml</file> <file>qml/delegates/Placeholder.qml</file> + <file>qml/delegates/PlayableMediaMessage.qml</file> <file>qml/delegates/Reply.qml</file> + <file>qml/delegates/TextMessage.qml</file> <file>qml/device-verification/Waiting.qml</file> <file>qml/device-verification/DeviceVerification.qml</file> <file>qml/device-verification/DigitVerification.qml</file> @@ -172,6 +161,8 @@ <file>qml/device-verification/Failed.qml</file> <file>qml/device-verification/Success.qml</file> <file>qml/dialogs/InputDialog.qml</file> + <file>qml/dialogs/ImagePackSettingsDialog.qml</file> + <file>qml/dialogs/ImagePackEditorDialog.qml</file> <file>qml/ui/Ripple.qml</file> <file>qml/ui/Spinner.qml</file> <file>qml/ui/animations/BlinkAnimation.qml</file> @@ -185,7 +176,12 @@ <file>qml/voip/VideoCall.qml</file> <file>qml/components/AdaptiveLayout.qml</file> <file>qml/components/AdaptiveLayoutElement.qml</file> + <file>qml/components/AvatarListTile.qml</file> <file>qml/components/FlatButton.qml</file> + <file>qml/RoomMembers.qml</file> + <file>qml/InviteDialog.qml</file> + <file>qml/ReadReceipts.qml</file> + <file>qml/RawMessageDialog.qml</file> </qresource> <qresource prefix="/media"> <file>media/ring.ogg</file> diff --git a/src/Cache.cpp b/src/Cache.cpp index 0bcf9fbf..ee991dc2 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -125,7 +125,7 @@ template<class T> bool containsStateUpdates(const T &e) { - return std::visit([](const auto &ev) { return Cache::isStateEvent(ev); }, e); + return std::visit([](const auto &ev) { return Cache::isStateEvent_<decltype(ev)>; }, e); } bool @@ -158,7 +158,7 @@ Cache::isHiddenEvent(lmdb::txn &txn, index.session_id = encryptedEvent->content.session_id; index.sender_key = encryptedEvent->content.sender_key; - auto result = olm::decryptEvent(index, *encryptedEvent); + auto result = olm::decryptEvent(index, *encryptedEvent, true); if (!result.error) e = result.event.value(); } @@ -288,6 +288,9 @@ Cache::setup() outboundMegolmSessionDb_ = lmdb::dbi::open(txn, OUTBOUND_MEGOLM_SESSIONS_DB, MDB_CREATE); megolmSessionDataDb_ = lmdb::dbi::open(txn, MEGOLM_SESSIONS_DATA_DB, MDB_CREATE); + // What rooms are encrypted + encryptedRooms_ = lmdb::dbi::open(txn, ENCRYPTED_ROOMS_DB, MDB_CREATE); + txn.commit(); databaseReady_ = true; @@ -298,8 +301,7 @@ Cache::setEncryptedRoom(lmdb::txn &txn, const std::string &room_id) { nhlog::db()->info("mark room {} as encrypted", room_id); - auto db = lmdb::dbi::open(txn, ENCRYPTED_ROOMS_DB, MDB_CREATE); - db.put(txn, room_id, "0"); + encryptedRooms_.put(txn, room_id, "0"); } bool @@ -308,8 +310,7 @@ Cache::isRoomEncrypted(const std::string &room_id) std::string_view unused; auto txn = ro_txn(env_); - auto db = lmdb::dbi::open(txn, ENCRYPTED_ROOMS_DB, MDB_CREATE); - auto res = db.get(txn, room_id, unused); + auto res = encryptedRooms_.get(txn, room_id, unused); return res; } @@ -715,32 +716,29 @@ Cache::restoreOlmAccount() } void -Cache::storeSecret(const std::string &name, const std::string &secret) +Cache::storeSecret(const std::string name, const std::string secret) { auto settings = UserSettings::instance(); - QKeychain::WritePasswordJob job(QCoreApplication::applicationName()); - job.setAutoDelete(false); - job.setInsecureFallback(true); - job.setKey("matrix." + - QString(QCryptographicHash::hash(settings->profile().toUtf8(), - QCryptographicHash::Sha256)) + - "." + name.c_str()); - job.setTextData(QString::fromStdString(secret)); - QEventLoop loop; - job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); - job.start(); - loop.exec(); - - if (job.error()) { - nhlog::db()->warn( - "Storing secret '{}' failed: {}", name, job.errorString().toStdString()); - } else { - emit secretChanged(name); - } + auto job = new QKeychain::WritePasswordJob(QCoreApplication::applicationName()); + job->setInsecureFallback(true); + job->setKey("matrix." + + QString(QCryptographicHash::hash(settings->profile().toUtf8(), + QCryptographicHash::Sha256)) + + "." + name.c_str()); + job->setTextData(QString::fromStdString(secret)); + QObject::connect(job, &QKeychain::Job::finished, job, [name, this](QKeychain::Job *job) { + if (job->error()) { + nhlog::db()->warn( + "Storing secret '{}' failed: {}", name, job->errorString().toStdString()); + } else { + emit secretChanged(name); + } + }); + job->start(); } void -Cache::deleteSecret(const std::string &name) +Cache::deleteSecret(const std::string name) { auto settings = UserSettings::instance(); QKeychain::DeletePasswordJob job(QCoreApplication::applicationName()); @@ -750,6 +748,8 @@ Cache::deleteSecret(const std::string &name) QString(QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)) + "." + name.c_str()); + // FIXME(Nico): Nested event loops are dangerous. Some other slots may resume in the mean + // time! QEventLoop loop; job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); job.start(); @@ -759,7 +759,7 @@ Cache::deleteSecret(const std::string &name) } std::optional<std::string> -Cache::secret(const std::string &name) +Cache::secret(const std::string name) { auto settings = UserSettings::instance(); QKeychain::ReadPasswordJob job(QCoreApplication::applicationName()); @@ -769,6 +769,8 @@ Cache::secret(const std::string &name) QString(QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)) + "." + name.c_str()); + // FIXME(Nico): Nested event loops are dangerous. Some other slots may resume in the mean + // time! QEventLoop loop; job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); job.start(); @@ -3383,26 +3385,30 @@ Cache::getChildRoomIds(const std::string &room_id) } std::vector<ImagePackInfo> -Cache::getImagePacks(const std::string &room_id, bool stickers) +Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers) { auto txn = ro_txn(env_); std::vector<ImagePackInfo> infos; - auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack) { - if (!pack.pack || (stickers ? pack.pack->is_sticker() : pack.pack->is_emoji())) { + auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack, + const std::string &source_room, + const std::string &state_key) { + if (!pack.pack || !stickers.has_value() || + (stickers.value() ? pack.pack->is_sticker() : pack.pack->is_emoji())) { ImagePackInfo info; - if (pack.pack) - info.packname = pack.pack->display_name; + info.source_room = source_room; + info.state_key = state_key; + info.pack.pack = pack.pack; for (const auto &img : pack.images) { - if (img.second.overrides_usage() && + if (stickers.has_value() && img.second.overrides_usage() && (stickers ? !img.second.is_sticker() : !img.second.is_emoji())) continue; - info.images.insert(img); + info.pack.images.insert(img); } - if (!info.images.empty()) + if (!info.pack.images.empty()) infos.push_back(std::move(info)); } }; @@ -3414,7 +3420,7 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) std::get_if<mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePack>>( &*accountpack); if (tmp) - addPack(tmp->content); + addPack(tmp->content, "", ""); } // packs from rooms, that were enabled globally @@ -3433,7 +3439,7 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) if (auto pack = getStateEvent<mtx::events::msc2545::ImagePack>( txn, room_id2, state_id)) - addPack(pack->content); + addPack(pack->content, room_id2, state_id); } } } @@ -3441,17 +3447,24 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) // packs from current room if (auto pack = getStateEvent<mtx::events::msc2545::ImagePack>(txn, room_id)) { - addPack(pack->content); + addPack(pack->content, room_id, ""); } for (const auto &pack : getStateEventsWithType<mtx::events::msc2545::ImagePack>(txn, room_id)) { - addPack(pack.content); + addPack(pack.content, room_id, pack.state_key); } return infos; } std::optional<mtx::events::collections::RoomAccountDataEvents> +Cache::getAccountData(mtx::events::EventType type, const std::string &room_id) +{ + auto txn = ro_txn(env_); + return getAccountData(txn, type, room_id); +} + +std::optional<mtx::events::collections::RoomAccountDataEvents> Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id) { try { @@ -3529,7 +3542,7 @@ Cache::roomMembers(const std::string &room_id) } std::map<std::string, std::optional<UserKeyCache>> -Cache::getMembersWithKeys(const std::string &room_id) +Cache::getMembersWithKeys(const std::string &room_id, bool verified_only) { std::string_view keys; @@ -3546,10 +3559,51 @@ Cache::getMembersWithKeys(const std::string &room_id) auto res = keysDb.get(txn, user_id, keys); if (res) { - members[std::string(user_id)] = - json::parse(keys).get<UserKeyCache>(); + auto k = json::parse(keys).get<UserKeyCache>(); + if (verified_only) { + auto verif = verificationStatus(std::string(user_id)); + if (verif.user_verified == crypto::Trust::Verified || + !verif.verified_devices.empty()) { + auto keyCopy = k; + keyCopy.device_keys.clear(); + + std::copy_if( + k.device_keys.begin(), + k.device_keys.end(), + std::inserter(keyCopy.device_keys, + keyCopy.device_keys.end()), + [&verif](const auto &key) { + auto curve25519 = key.second.keys.find( + "curve25519:" + key.first); + if (curve25519 == key.second.keys.end()) + return false; + if (auto t = + verif.verified_device_keys.find( + curve25519->second); + t == + verif.verified_device_keys.end() || + t->second != crypto::Trust::Verified) + return false; + + return key.first == + key.second.device_id && + std::find( + verif.verified_devices.begin(), + verif.verified_devices.end(), + key.first) != + verif.verified_devices.end(); + }); + + if (!keyCopy.device_keys.empty()) + members[std::string(user_id)] = + std::move(keyCopy); + } + } else { + members[std::string(user_id)] = std::move(k); + } } else { - members[std::string(user_id)] = {}; + if (!verified_only) + members[std::string(user_id)] = {}; } } cursor.close(); @@ -4240,6 +4294,8 @@ to_json(nlohmann::json &obj, const GroupSessionData &msg) obj["forwarding_curve25519_key_chain"] = msg.forwarding_curve25519_key_chain; obj["currently"] = msg.currently; + + obj["indices"] = msg.indices; } void @@ -4253,6 +4309,8 @@ from_json(const nlohmann::json &obj, GroupSessionData &msg) obj.value("forwarding_curve25519_key_chain", std::vector<std::string>{}); msg.currently = obj.value("currently", SharedWithUsers{}); + + msg.indices = obj.value("indices", std::map<uint32_t, std::string>()); } void diff --git a/src/CacheCryptoStructs.h b/src/CacheCryptoStructs.h index 409c9d67..69d64885 100644 --- a/src/CacheCryptoStructs.h +++ b/src/CacheCryptoStructs.h @@ -50,6 +50,9 @@ struct GroupSessionData std::string sender_claimed_ed25519_key; std::vector<std::string> forwarding_curve25519_key_chain; + //! map from index to event_id to check for replay attacks + std::map<uint32_t, std::string> indices; + // who has access to this session. // Rotate, when a user leaves the room and share, when a user gets added. SharedWithUsers currently; diff --git a/src/CacheStructs.h b/src/CacheStructs.h index f274d70f..4a5c5c76 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -113,6 +113,7 @@ struct RoomSearchResult struct ImagePackInfo { - std::string packname; - std::map<std::string, mtx::events::msc2545::PackImage> images; + mtx::events::msc2545::ImagePack pack; + std::string source_room; + std::string state_key; }; diff --git a/src/Cache_p.h b/src/Cache_p.h index 13fbc371..30c365a6 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -48,7 +48,8 @@ public: // user cache stores user keys std::optional<UserKeyCache> userKeys(const std::string &user_id); std::map<std::string, std::optional<UserKeyCache>> getMembersWithKeys( - const std::string &room_id); + const std::string &room_id, + bool verified_only); void updateUserKeys(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery); void markUserKeysOutOfDate(lmdb::txn &txn, @@ -97,6 +98,12 @@ public: return getStateEvent<T>(txn, room_id, state_key); } + //! retrieve a specific event from account data + //! pass empty room_id for global account data + std::optional<mtx::events::collections::RoomAccountDataEvents> getAccountData( + mtx::events::EventType type, + const std::string &room_id = ""); + //! Retrieve member info from a room. std::vector<RoomMember> getMembers(const std::string &room_id, std::size_t startIndex = 0, @@ -225,7 +232,8 @@ public: std::vector<std::string> getParentRoomIds(const std::string &room_id); std::vector<std::string> getChildRoomIds(const std::string &room_id); - std::vector<ImagePackInfo> getImagePacks(const std::string &room_id, bool stickers); + std::vector<ImagePackInfo> getImagePacks(const std::string &room_id, + std::optional<bool> stickers); //! Mark a room that uses e2e encryption. void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id); @@ -278,20 +286,14 @@ public: void saveOlmAccount(const std::string &pickled); std::string restoreOlmAccount(); - void storeSecret(const std::string &name, const std::string &secret); - void deleteSecret(const std::string &name); - std::optional<std::string> secret(const std::string &name); + void storeSecret(const std::string name, const std::string secret); + void deleteSecret(const std::string name); + std::optional<std::string> secret(const std::string name); template<class T> - static constexpr bool isStateEvent(const mtx::events::StateEvent<T> &) - { - return true; - } - template<class T> - static constexpr bool isStateEvent(const mtx::events::Event<T> &) - { - return false; - } + constexpr static bool isStateEvent_ = + std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, + mtx::events::StateEvent<decltype(std::declval<T>().content)>>; static int compare_state_key(const MDB_val *a, const MDB_val *b) { @@ -408,11 +410,27 @@ private: } std::visit( - [&txn, &statesdb, &stateskeydb, &eventsDb](auto e) { - if constexpr (isStateEvent(e)) { + [&txn, &statesdb, &stateskeydb, &eventsDb, &membersdb](const auto &e) { + if constexpr (isStateEvent_<decltype(e)>) { eventsDb.put(txn, e.event_id, json(e).dump()); - if (e.type != EventType::Unsupported) { + if (std::is_same_v< + std::remove_cv_t<std::remove_reference_t<decltype(e)>>, + StateEvent<mtx::events::msg::Redacted>>) { + if (e.type == EventType::RoomMember) + membersdb.del(txn, e.state_key, ""); + else if (e.state_key.empty()) + statesdb.del(txn, to_string(e.type)); + else + stateskeydb.del( + txn, + to_string(e.type), + json::object({ + {"key", e.state_key}, + {"id", e.event_id}, + }) + .dump()); + } else if (e.type != EventType::Unsupported) { if (e.state_key.empty()) statesdb.put( txn, to_string(e.type), json(e).dump()); @@ -682,6 +700,8 @@ private: lmdb::dbi outboundMegolmSessionDb_; lmdb::dbi megolmSessionDataDb_; + lmdb::dbi encryptedRooms_; + QString localUserId_; QString cacheDirectory_; diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 10a91557..42e3bc7b 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -31,7 +31,6 @@ #include "notifications/Manager.h" -#include "dialogs/ReadReceipts.h" #include "timeline/TimelineViewManager.h" #include "blurhash.hpp" @@ -116,29 +115,31 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent) connect(this, &ChatPage::loggedOut, this, &ChatPage::logout); - connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList users) { - const auto room_id = currentRoom().toStdString(); - - for (int ii = 0; ii < users.size(); ++ii) { - QTimer::singleShot(ii * 500, this, [this, room_id, ii, users]() { - const auto user = users.at(ii); - - http::client()->invite_user( - room_id, - user.toStdString(), - [this, user](const mtx::responses::RoomInvite &, - mtx::http::RequestErr err) { - if (err) { - emit showNotification( - tr("Failed to invite user: %1").arg(user)); - return; - } - - emit showNotification(tr("Invited user: %1").arg(user)); - }); - }); - } - }); + connect( + view_manager_, + &TimelineViewManager::inviteUsers, + this, + [this](QString roomId, QStringList users) { + for (int ii = 0; ii < users.size(); ++ii) { + QTimer::singleShot(ii * 500, this, [this, roomId, ii, users]() { + const auto user = users.at(ii); + + http::client()->invite_user( + roomId.toStdString(), + user.toStdString(), + [this, user](const mtx::responses::RoomInvite &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification( + tr("Failed to invite user: %1").arg(user)); + return; + } + + emit showNotification(tr("Invited user: %1").arg(user)); + }); + }); + } + }); connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom); connect(this, &ChatPage::newRoom, this, &ChatPage::changeRoom, Qt::QueuedConnection); @@ -927,31 +928,33 @@ ChatPage::currentPresence() const void ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts) { - for (const auto &entry : counts) { - if (entry.second < MAX_ONETIME_KEYS) { - const int nkeys = MAX_ONETIME_KEYS - entry.second; + uint16_t count = 0; + if (auto c = counts.find(mtx::crypto::SIGNED_CURVE25519); c != counts.end()) + count = c->second; - nhlog::crypto()->info("uploading {} {} keys", nkeys, entry.first); - olm::client()->generate_one_time_keys(nkeys); + if (count < MAX_ONETIME_KEYS) { + const int nkeys = MAX_ONETIME_KEYS - count; - http::client()->upload_keys( - olm::client()->create_upload_keys_request(), - [](const mtx::responses::UploadKeys &, mtx::http::RequestErr err) { - if (err) { - nhlog::crypto()->warn( - "failed to update one-time keys: {} {} {}", - err->matrix_error.error, - static_cast<int>(err->status_code), - static_cast<int>(err->error_code)); + nhlog::crypto()->info( + "uploading {} {} keys", nkeys, mtx::crypto::SIGNED_CURVE25519); + olm::client()->generate_one_time_keys(nkeys); - if (err->status_code < 400 || err->status_code >= 500) - return; - } + http::client()->upload_keys( + olm::client()->create_upload_keys_request(), + [](const mtx::responses::UploadKeys &, mtx::http::RequestErr err) { + if (err) { + nhlog::crypto()->warn("failed to update one-time keys: {} {} {}", + err->matrix_error.error, + static_cast<int>(err->status_code), + static_cast<int>(err->error_code)); - // mark as published anyway, otherwise we may end up in a loop. - olm::mark_keys_as_published(); - }); - } + if (err->status_code < 400 || err->status_code >= 500) + return; + } + + // mark as published anyway, otherwise we may end up in a loop. + olm::mark_keys_as_published(); + }); } } @@ -1024,8 +1027,15 @@ ChatPage::decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescriptio auto decryptionKey = mtx::crypto::key_from_recoverykey(text.toStdString(), keyDesc); - if (!decryptionKey) - decryptionKey = mtx::crypto::key_from_passphrase(text.toStdString(), keyDesc); + if (!decryptionKey && keyDesc.passphrase) { + try { + decryptionKey = + mtx::crypto::key_from_passphrase(text.toStdString(), keyDesc); + } catch (std::exception &e) { + nhlog::crypto()->error("Failed to derive secret key from passphrase: {}", + e.what()); + } + } if (!decryptionKey) { QMessageBox::information( diff --git a/src/ImagePackModel.cpp b/src/CombinedImagePackModel.cpp index 9b0dca8d..341a34ec 100644 --- a/src/ImagePackModel.cpp +++ b/src/CombinedImagePackModel.cpp @@ -2,21 +2,24 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -#include "ImagePackModel.h" +#include "CombinedImagePackModel.h" #include "Cache_p.h" #include "CompletionModelRoles.h" -ImagePackModel::ImagePackModel(const std::string &roomId, bool stickers, QObject *parent) +CombinedImagePackModel::CombinedImagePackModel(const std::string &roomId, + bool stickers, + QObject *parent) : QAbstractListModel(parent) , room_id(roomId) { auto packs = cache::client()->getImagePacks(room_id, stickers); for (const auto &pack : packs) { - QString packname = QString::fromStdString(pack.packname); + QString packname = + pack.pack.pack ? QString::fromStdString(pack.pack.pack->display_name) : ""; - for (const auto &img : pack.images) { + for (const auto &img : pack.pack.images) { ImageDesc i{}; i.shortcode = QString::fromStdString(img.first); i.packname = packname; @@ -27,13 +30,13 @@ ImagePackModel::ImagePackModel(const std::string &roomId, bool stickers, QObject } int -ImagePackModel::rowCount(const QModelIndex &) const +CombinedImagePackModel::rowCount(const QModelIndex &) const { return (int)images.size(); } QHash<int, QByteArray> -ImagePackModel::roleNames() const +CombinedImagePackModel::roleNames() const { return { {CompletionModel::CompletionRole, "completionRole"}, @@ -48,7 +51,7 @@ ImagePackModel::roleNames() const } QVariant -ImagePackModel::data(const QModelIndex &index, int role) const +CombinedImagePackModel::data(const QModelIndex &index, int role) const { if (hasIndex(index.row(), index.column(), index.parent())) { switch (role) { diff --git a/src/ImagePackModel.h b/src/CombinedImagePackModel.h index 937014ec..f0f69799 100644 --- a/src/ImagePackModel.h +++ b/src/CombinedImagePackModel.h @@ -8,7 +8,7 @@ #include <mtx/events/mscs/image_packs.hpp> -class ImagePackModel : public QAbstractListModel +class CombinedImagePackModel : public QAbstractListModel { Q_OBJECT public: @@ -21,7 +21,7 @@ public: OriginalRow, }; - ImagePackModel(const std::string &roomId, bool stickers, QObject *parent = nullptr); + CombinedImagePackModel(const std::string &roomId, bool stickers, QObject *parent = nullptr); QHash<int, QByteArray> roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; diff --git a/src/ImagePackListModel.cpp b/src/ImagePackListModel.cpp new file mode 100644 index 00000000..6392de22 --- /dev/null +++ b/src/ImagePackListModel.cpp @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ImagePackListModel.h" + +#include <QQmlEngine> + +#include "Cache_p.h" +#include "SingleImagePackModel.h" + +ImagePackListModel::ImagePackListModel(const std::string &roomId, QObject *parent) + : QAbstractListModel(parent) + , room_id(roomId) +{ + auto packs_ = cache::client()->getImagePacks(room_id, std::nullopt); + + for (const auto &pack : packs_) { + packs.push_back( + QSharedPointer<SingleImagePackModel>(new SingleImagePackModel(pack))); + } +} + +int +ImagePackListModel::rowCount(const QModelIndex &) const +{ + return (int)packs.size(); +} + +QHash<int, QByteArray> +ImagePackListModel::roleNames() const +{ + return { + {Roles::DisplayName, "displayName"}, + {Roles::AvatarUrl, "avatarUrl"}, + {Roles::FromAccountData, "fromAccountData"}, + {Roles::FromCurrentRoom, "fromCurrentRoom"}, + {Roles::StateKey, "statekey"}, + {Roles::RoomId, "roomid"}, + }; +} + +QVariant +ImagePackListModel::data(const QModelIndex &index, int role) const +{ + if (hasIndex(index.row(), index.column(), index.parent())) { + const auto &pack = packs.at(index.row()); + switch (role) { + case Roles::DisplayName: + return pack->packname(); + case Roles::AvatarUrl: + return pack->avatarUrl(); + case Roles::FromAccountData: + return pack->roomid().isEmpty(); + case Roles::FromCurrentRoom: + return pack->roomid().toStdString() == this->room_id; + case Roles::StateKey: + return pack->statekey(); + case Roles::RoomId: + return pack->roomid(); + default: + return {}; + } + } + return {}; +} + +SingleImagePackModel * +ImagePackListModel::packAt(int row) +{ + if (row < 0 || static_cast<size_t>(row) >= packs.size()) + return {}; + auto e = packs.at(row).get(); + QQmlEngine::setObjectOwnership(e, QQmlEngine::CppOwnership); + return e; +} + +SingleImagePackModel * +ImagePackListModel::newPack(bool inRoom) +{ + ImagePackInfo info{}; + if (inRoom) + info.source_room = room_id; + return new SingleImagePackModel(info); +} + +bool +ImagePackListModel::containsAccountPack() const +{ + for (const auto &p : packs) + if (p->roomid().isEmpty()) + return true; + return false; +} diff --git a/src/ImagePackListModel.h b/src/ImagePackListModel.h new file mode 100644 index 00000000..2aa5abb2 --- /dev/null +++ b/src/ImagePackListModel.h @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> +#include <QQmlEngine> +#include <QSharedPointer> + +class SingleImagePackModel; +class ImagePackListModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool containsAccountPack READ containsAccountPack CONSTANT) +public: + enum Roles + { + DisplayName = Qt::UserRole, + AvatarUrl, + FromAccountData, + FromCurrentRoom, + StateKey, + RoomId, + }; + + ImagePackListModel(const std::string &roomId, QObject *parent = nullptr); + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + + Q_INVOKABLE SingleImagePackModel *packAt(int row); + Q_INVOKABLE SingleImagePackModel *newPack(bool inRoom); + + bool containsAccountPack() const; + +private: + std::string room_id; + + std::vector<QSharedPointer<SingleImagePackModel>> packs; +}; diff --git a/src/InviteeItem.cpp b/src/InviteeItem.cpp deleted file mode 100644 index 27f02560..00000000 --- a/src/InviteeItem.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QHBoxLayout> -#include <QLabel> -#include <QPushButton> - -#include "InviteeItem.h" - -constexpr int SidePadding = 10; - -InviteeItem::InviteeItem(mtx::identifiers::User user, QWidget *parent) - : QWidget{parent} - , user_{QString::fromStdString(user.to_string())} -{ - auto topLayout_ = new QHBoxLayout(this); - topLayout_->setSpacing(0); - topLayout_->setContentsMargins(SidePadding, 0, 3 * SidePadding, 0); - - name_ = new QLabel(user_, this); - removeUserBtn_ = new QPushButton(tr("Remove"), this); - - topLayout_->addWidget(name_); - topLayout_->addWidget(removeUserBtn_, 0, Qt::AlignRight); - - connect(removeUserBtn_, &QPushButton::clicked, this, &InviteeItem::removeItem); -} diff --git a/src/InviteeItem.h b/src/InviteeItem.h deleted file mode 100644 index 014541ea..00000000 --- a/src/InviteeItem.h +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QWidget> - -#include <mtx/identifiers.hpp> - -class QPushButton; -class QLabel; - -class InviteeItem : public QWidget -{ - Q_OBJECT - -public: - InviteeItem(mtx::identifiers::User user, QWidget *parent = nullptr); - - QString userID() { return user_; } - -signals: - void removeItem(); - -private: - QString user_; - - QLabel *name_; - QPushButton *removeUserBtn_; -}; diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp new file mode 100644 index 00000000..27b2116f --- /dev/null +++ b/src/InviteesModel.cpp @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "InviteesModel.h" + +#include "Cache.h" +#include "Logging.h" +#include "MatrixClient.h" +#include "mtx/responses/profile.hpp" + +InviteesModel::InviteesModel(QObject *parent) + : QAbstractListModel{parent} +{} + +void +InviteesModel::addUser(QString mxid) +{ + beginInsertRows(QModelIndex(), invitees_.count(), invitees_.count()); + + auto invitee = new Invitee{mxid, this}; + auto indexOfInvitee = invitees_.count(); + connect(invitee, &Invitee::userInfoLoaded, this, [this, indexOfInvitee]() { + emit dataChanged(index(indexOfInvitee), index(indexOfInvitee)); + }); + + invitees_.push_back(invitee); + + endInsertRows(); + emit countChanged(); +} + +QHash<int, QByteArray> +InviteesModel::roleNames() const +{ + return {{Mxid, "mxid"}, {DisplayName, "displayName"}, {AvatarUrl, "avatarUrl"}}; +} + +QVariant +InviteesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)invitees_.size() || index.row() < 0) + return {}; + + switch (role) { + case Mxid: + return invitees_[index.row()]->mxid_; + case DisplayName: + return invitees_[index.row()]->displayName_; + case AvatarUrl: + return invitees_[index.row()]->avatarUrl_; + default: + return {}; + } +} + +QStringList +InviteesModel::mxids() +{ + QStringList mxidList; + for (int i = 0; i < invitees_.length(); ++i) + mxidList.push_back(invitees_[i]->mxid_); + return mxidList; +} + +Invitee::Invitee(const QString &mxid, QObject *parent) + : QObject{parent} + , mxid_{mxid} +{ + http::client()->get_profile( + mxid_.toStdString(), + [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve profile info"); + emit userInfoLoaded(); + return; + } + + displayName_ = QString::fromStdString(res.display_name); + avatarUrl_ = QString::fromStdString(res.avatar_url); + + emit userInfoLoaded(); + }); +} diff --git a/src/InviteesModel.h b/src/InviteesModel.h new file mode 100644 index 00000000..a4e19ebb --- /dev/null +++ b/src/InviteesModel.h @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef INVITEESMODEL_H +#define INVITEESMODEL_H + +#include <QAbstractListModel> +#include <QVector> + +class Invitee : public QObject +{ + Q_OBJECT + +public: + Invitee(const QString &mxid, QObject *parent = nullptr); + +signals: + void userInfoLoaded(); + +private: + const QString mxid_; + QString displayName_; + QString avatarUrl_; + + friend class InviteesModel; +}; + +class InviteesModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + +public: + enum Roles + { + Mxid, + DisplayName, + AvatarUrl, + }; + + InviteesModel(QObject *parent = nullptr); + + Q_INVOKABLE void addUser(QString mxid); + + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex & = QModelIndex()) const override + { + return (int)invitees_.size(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QStringList mxids(); + +signals: + void accept(); + void countChanged(); + +private: + QVector<Invitee *> invitees_; +}; + +#endif // INVITEESMODEL_H diff --git a/src/Logging.cpp b/src/Logging.cpp index 642e8957..67bcaf7a 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -30,19 +30,11 @@ qmlMessageHandler(QtMsgType type, const QMessageLogContext &context, const QStri const char *function = context.function ? context.function : ""; if ( - // Surpress binding wrning for now, as we can't set restore mode to keep compat with - // qt 5.10 - msg.contains(QStringLiteral( - "QML Binding: Not restoring previous value because restoreMode has not been set.")) || // The default style has the point size set. If you use pixel size anywhere, you get // that warning, which is useless, since sometimes you need the pixel size to match the // text to the size of the outer element for example. This is done in the avatar and // without that you get one warning for every Avatar displayed, which is stupid! - msg.endsWith(QStringLiteral("Both point size and pixel size set. Using pixel size.")) || - // The new syntax breaks rebinding on Qt < 5.15. Until we can drop that, we still need it. - msg.endsWith(QStringLiteral( - "QML Connections: Implicitly defined onFoo properties in Connections are " - "deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }"))) + msg.endsWith(QStringLiteral("Both point size and pixel size set. Using pixel size."))) return; switch (type) { diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index ed337ca4..8bc90f29 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -21,6 +21,7 @@ #include "LoginPage.h" #include "MainWindow.h" #include "MatrixClient.h" +#include "MemberList.h" #include "RegisterPage.h" #include "TrayIcon.h" #include "UserSettingsPage.h" @@ -32,12 +33,9 @@ #include "ui/SnackBar.h" #include "dialogs/CreateRoom.h" -#include "dialogs/InviteUsers.h" #include "dialogs/JoinRoom.h" #include "dialogs/LeaveRoom.h" #include "dialogs/Logout.h" -#include "dialogs/MemberList.h" -#include "dialogs/ReadReceipts.h" MainWindow *MainWindow::instance_ = nullptr; @@ -311,14 +309,6 @@ MainWindow::hasActiveUser() } void -MainWindow::openMemberListDialog(const QString &room_id) -{ - auto dialog = new dialogs::MemberList(room_id, this); - - showDialog(dialog); -} - -void MainWindow::openLeaveRoomDialog(const QString &room_id) { auto dialog = new dialogs::LeaveRoom(this); @@ -342,18 +332,6 @@ MainWindow::showOverlayProgressBar() } void -MainWindow::openInviteUsersDialog(std::function<void(const QStringList &invitees)> callback) -{ - auto dialog = new dialogs::InviteUsers(this); - connect(dialog, &dialogs::InviteUsers::sendInvites, this, [callback](QStringList invitees) { - if (!invitees.isEmpty()) - callback(invitees); - }); - - showDialog(dialog); -} - -void MainWindow::openJoinRoomDialog(std::function<void(const QString &room_id)> callback) { auto dialog = new dialogs::JoinRoom(this); @@ -419,27 +397,6 @@ MainWindow::openLogoutDialog() showDialog(dialog); } -void -MainWindow::openReadReceiptsDialog(const QString &event_id) -{ - auto dialog = new dialogs::ReadReceipts(this); - - const auto room_id = chat_page_->currentRoom(); - - try { - dialog->addUsers(cache::readReceipts(event_id, room_id)); - } catch (const lmdb::error &) { - nhlog::db()->warn("failed to retrieve read receipts for {} {}", - event_id.toStdString(), - chat_page_->currentRoom().toStdString()); - dialog->deleteLater(); - - return; - } - - showDialog(dialog); -} - bool MainWindow::hasActiveDialogs() const { diff --git a/src/MainWindow.h b/src/MainWindow.h index 3571f079..d423af9f 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -65,8 +65,6 @@ public: std::function<void(const mtx::requests::CreateRoom &request)> callback); void openJoinRoomDialog(std::function<void(const QString &room_id)> callback); void openLogoutDialog(); - void openMemberListDialog(const QString &room_id); - void openReadReceiptsDialog(const QString &event_id); void hideOverlay(); void showSolidOverlayModal(QWidget *content, diff --git a/src/MemberList.cpp b/src/MemberList.cpp new file mode 100644 index 00000000..196647fe --- /dev/null +++ b/src/MemberList.cpp @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "MemberList.h" + +#include "Cache.h" +#include "ChatPage.h" +#include "Config.h" +#include "Logging.h" +#include "Utils.h" +#include "timeline/TimelineViewManager.h" + +MemberList::MemberList(const QString &room_id, QObject *parent) + : QAbstractListModel{parent} + , room_id_{room_id} +{ + try { + info_ = cache::singleRoomInfo(room_id_.toStdString()); + } catch (const lmdb::error &) { + nhlog::db()->warn("failed to retrieve room info from cache: {}", + room_id_.toStdString()); + } + + try { + auto members = cache::getMembers(room_id_.toStdString()); + addUsers(members); + numUsersLoaded_ = members.size(); + } catch (const lmdb::error &e) { + nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); + } +} + +void +MemberList::addUsers(const std::vector<RoomMember> &members) +{ + beginInsertRows( + QModelIndex{}, m_memberList.count(), m_memberList.count() + members.size() - 1); + + for (const auto &member : members) + m_memberList.push_back( + {member, + ChatPage::instance()->timelineManager()->rooms()->currentRoom()->avatarUrl( + member.user_id)}); + + endInsertRows(); +} + +QHash<int, QByteArray> +MemberList::roleNames() const +{ + return { + {Mxid, "mxid"}, + {DisplayName, "displayName"}, + {AvatarUrl, "avatarUrl"}, + }; +} + +QVariant +MemberList::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)m_memberList.size() || index.row() < 0) + return {}; + + switch (role) { + case Mxid: + return m_memberList[index.row()].first.user_id; + case DisplayName: + return m_memberList[index.row()].first.display_name; + case AvatarUrl: + return m_memberList[index.row()].second; + default: + return {}; + } +} + +bool +MemberList::canFetchMore(const QModelIndex &) const +{ + const size_t numMembers = rowCount(); + if (numMembers > 1 && numMembers < info_.member_count) + return true; + else + return false; +} + +void +MemberList::fetchMore(const QModelIndex &) +{ + loadingMoreMembers_ = true; + emit loadingMoreMembersChanged(); + + auto members = cache::getMembers(room_id_.toStdString(), rowCount()); + addUsers(members); + numUsersLoaded_ += members.size(); + emit numUsersLoadedChanged(); + + loadingMoreMembers_ = false; + emit loadingMoreMembersChanged(); +} diff --git a/src/MemberList.h b/src/MemberList.h new file mode 100644 index 00000000..e6522694 --- /dev/null +++ b/src/MemberList.h @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> + +#include "CacheStructs.h" + +class MemberList : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(int memberCount READ memberCount NOTIFY memberCountChanged) + Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY(QString roomId READ roomId NOTIFY roomIdChanged) + Q_PROPERTY(int numUsersLoaded READ numUsersLoaded NOTIFY numUsersLoadedChanged) + Q_PROPERTY(bool loadingMoreMembers READ loadingMoreMembers NOTIFY loadingMoreMembersChanged) + +public: + enum Roles + { + Mxid, + DisplayName, + AvatarUrl, + }; + MemberList(const QString &room_id, QObject *parent = nullptr); + + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + Q_UNUSED(parent) + return static_cast<int>(m_memberList.size()); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + QString roomName() const { return QString::fromStdString(info_.name); } + int memberCount() const { return info_.member_count; } + QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); } + QString roomId() const { return room_id_; } + int numUsersLoaded() const { return numUsersLoaded_; } + bool loadingMoreMembers() const { return loadingMoreMembers_; } + +signals: + void roomNameChanged(); + void memberCountChanged(); + void avatarUrlChanged(); + void roomIdChanged(); + void numUsersLoadedChanged(); + void loadingMoreMembersChanged(); + +public slots: + void addUsers(const std::vector<RoomMember> &users); + +protected: + bool canFetchMore(const QModelIndex &) const override; + void fetchMore(const QModelIndex &) override; + +private: + QVector<QPair<RoomMember, QString>> m_memberList; + QString room_id_; + RoomInfo info_; + int numUsersLoaded_{0}; + bool loadingMoreMembers_{false}; +}; diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index ab6540a4..b8648269 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -22,7 +22,14 @@ QHash<QString, mtx::crypto::EncryptedFile> infos; QQuickImageResponse * MxcImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) { - MxcImageResponse *response = new MxcImageResponse(id, requestedSize); + auto id_ = id; + bool crop = true; + if (id.endsWith("?scale")) { + crop = false; + id_.remove("?scale"); + } + + MxcImageResponse *response = new MxcImageResponse(id_, crop, requestedSize); pool.start(response); return response; } @@ -36,20 +43,24 @@ void MxcImageResponse::run() { MxcImageProvider::download( - m_id, m_requestedSize, [this](QString, QSize, QImage image, QString) { + m_id, + m_requestedSize, + [this](QString, QSize, QImage image, QString) { if (image.isNull()) { m_error = "Failed to download image."; } else { m_image = image; } emit finished(); - }); + }, + m_crop); } void MxcImageProvider::download(const QString &id, const QSize &requestedSize, - std::function<void(QString, QSize, QImage, QString)> then) + std::function<void(QString, QSize, QImage, QString)> then, + bool crop) { std::optional<mtx::crypto::EncryptedFile> encryptionInfo; auto temp = infos.find("mxc://" + id); @@ -58,11 +69,12 @@ MxcImageProvider::download(const QString &id, if (requestedSize.isValid() && !encryptionInfo) { QString fileName = - QString("%1_%2x%3_crop") + QString("%1_%2x%3_%4") .arg(QString::fromUtf8(id.toUtf8().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))) .arg(requestedSize.width()) - .arg(requestedSize.height()); + .arg(requestedSize.height()) + .arg(crop ? "crop" : "scale"); QFileInfo fileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/media_cache", fileName); @@ -85,7 +97,7 @@ MxcImageProvider::download(const QString &id, opts.mxc_url = "mxc://" + id.toStdString(); opts.width = requestedSize.width() > 0 ? requestedSize.width() : -1; opts.height = requestedSize.height() > 0 ? requestedSize.height() : -1; - opts.method = "crop"; + opts.method = crop ? "crop" : "scale"; http::client()->get_thumbnail( opts, [fileInfo, requestedSize, then, id](const std::string &res, @@ -196,7 +208,6 @@ MxcImageProvider::download(const QString &id, image.setText("original filename", QString::fromStdString(originalFilename)); image.setText("mxc url", "mxc://" + id); - image.save(fileInfo.absoluteFilePath()); then(id, requestedSize, image, fileInfo.absoluteFilePath()); }); } catch (std::exception &e) { diff --git a/src/MxcImageProvider.h b/src/MxcImageProvider.h index 7b960836..61d82852 100644 --- a/src/MxcImageProvider.h +++ b/src/MxcImageProvider.h @@ -19,9 +19,10 @@ class MxcImageResponse , public QRunnable { public: - MxcImageResponse(const QString &id, const QSize &requestedSize) + MxcImageResponse(const QString &id, bool crop, const QSize &requestedSize) : m_id(id) , m_requestedSize(requestedSize) + , m_crop(crop) { setAutoDelete(false); } @@ -37,6 +38,7 @@ public: QString m_id, m_error; QSize m_requestedSize; QImage m_image; + bool m_crop; }; class MxcImageProvider @@ -51,7 +53,8 @@ public slots: static void addEncryptionInfo(mtx::crypto::EncryptedFile info); static void download(const QString &id, const QSize &requestedSize, - std::function<void(QString, QSize, QImage, QString)> then); + std::function<void(QString, QSize, QImage, QString)> then, + bool crop = true); private: QThreadPool pool; diff --git a/src/Olm.cpp b/src/Olm.cpp index 18e2ddcf..e4ab0aa1 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp @@ -212,14 +212,21 @@ handle_olm_message(const OlmMessage &msg, const UserKeyCache &otherUserDeviceKey nhlog::crypto()->info("sender : {}", msg.sender); nhlog::crypto()->info("sender_key: {}", msg.sender_key); + if (msg.sender_key == olm::client()->identity_keys().ed25519) { + nhlog::crypto()->warn("Ignoring olm message from ourselves!"); + return; + } + const auto my_key = olm::client()->identity_keys().curve25519; + bool failed_decryption = false; + for (const auto &cipher : msg.ciphertext) { // We skip messages not meant for the current device. if (cipher.first != my_key) { nhlog::crypto()->debug( "Skipping message for {} since we are {}.", cipher.first, my_key); - return; + continue; } const auto type = cipher.second.type; @@ -234,6 +241,7 @@ handle_olm_message(const OlmMessage &msg, const UserKeyCache &otherUserDeviceKey msg.sender, msg.sender_key, cipher.second); } else { nhlog::crypto()->error("Undecryptable olm message!"); + failed_decryption = true; continue; } } @@ -278,11 +286,17 @@ handle_olm_message(const OlmMessage &msg, const UserKeyCache &otherUserDeviceKey bool from_their_device = false; for (auto [device_id, key] : otherUserDeviceKeys.device_keys) { - if (key.keys.at("curve25519:" + device_id) == msg.sender_key) { - if (key.keys.at("ed25519:" + device_id) == sender_ed25519) { - from_their_device = true; - break; - } + auto c_key = key.keys.find("curve25519:" + device_id); + auto e_key = key.keys.find("ed25519:" + device_id); + + if (c_key == key.keys.end() || e_key == key.keys.end()) { + nhlog::crypto()->warn( + "Skipping device {} as we have no keys for it.", + device_id); + } else if (c_key->second == msg.sender_key && + e_key->second == sender_ed25519) { + from_their_device = true; + break; } } if (!from_their_device) { @@ -423,22 +437,28 @@ handle_olm_message(const OlmMessage &msg, const UserKeyCache &otherUserDeviceKey } return; + } else { + failed_decryption = true; } } - try { - std::map<std::string, std::vector<std::string>> targets; - for (auto [device_id, key] : otherUserDeviceKeys.device_keys) { - if (key.keys.at("curve25519:" + device_id) == msg.sender_key) - targets[msg.sender].push_back(device_id); - } + if (failed_decryption) { + try { + std::map<std::string, std::vector<std::string>> targets; + for (auto [device_id, key] : otherUserDeviceKeys.device_keys) { + if (key.keys.at("curve25519:" + device_id) == msg.sender_key) + targets[msg.sender].push_back(device_id); + } - send_encrypted_to_device_messages( - targets, mtx::events::DeviceEvent<mtx::events::msg::Dummy>{}, true); - nhlog::crypto()->info( - "Recovering from broken olm channel with {}:{}", msg.sender, msg.sender_key); - } catch (std::exception &e) { - nhlog::crypto()->error("Failed to recover from broken olm sessions: {}", e.what()); + send_encrypted_to_device_messages( + targets, mtx::events::DeviceEvent<mtx::events::msg::Dummy>{}, true); + nhlog::crypto()->info("Recovering from broken olm channel with {}:{}", + msg.sender, + msg.sender_key); + } catch (std::exception &e) { + nhlog::crypto()->error("Failed to recover from broken olm sessions: {}", + e.what()); + } } } @@ -504,7 +524,8 @@ encrypt_group_message(const std::string &room_id, const std::string &device_id, auto own_user_id = http::client()->user_id().to_string(); - auto members = cache::client()->getMembersWithKeys(room_id); + auto members = cache::client()->getMembersWithKeys( + room_id, UserSettings::instance()->onlyShareKeysWithVerifiedUsers()); std::map<std::string, std::vector<std::string>> sendSessionTo; mtx::crypto::OutboundGroupSessionPtr session = nullptr; @@ -955,13 +976,12 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR } } - if (!verifiedDevice && !shouldSeeKeys && - !utils::respondsToKeyRequests(req.content.room_id)) { + if (!verifiedDevice && !shouldSeeKeys) { nhlog::crypto()->debug("ignoring key request for room {}", req.content.room_id); return; } - if (verifiedDevice || utils::respondsToKeyRequests(req.content.room_id)) { + if (verifiedDevice) { // share the minimum index we have minimumIndex = -1; } @@ -1008,7 +1028,8 @@ send_megolm_key_to_device(const std::string &user_id, DecryptionResult decryptEvent(const MegolmSessionIndex &index, - const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &event) + const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &event, + bool dont_write_db) { try { if (!cache::client()->inboundMegolmSessionExists(index)) { @@ -1023,10 +1044,26 @@ decryptEvent(const MegolmSessionIndex &index, std::string msg_str; try { auto session = cache::client()->getInboundMegolmSession(index); + auto sessionData = + cache::client()->getMegolmSessionData(index).value_or(GroupSessionData{}); auto res = olm::client()->decrypt_group_message(session.get(), event.content.ciphertext); msg_str = std::string((char *)res.data.data(), res.data.size()); + + if (!event.event_id.empty() && event.event_id[0] == '$') { + auto oldIdx = sessionData.indices.find(res.message_index); + if (oldIdx != sessionData.indices.end()) { + if (oldIdx->second != event.event_id) + return {DecryptionErrorCode::ReplayAttack, + std::nullopt, + std::nullopt}; + } else if (!dont_write_db) { + sessionData.indices[res.message_index] = event.event_id; + cache::client()->saveInboundMegolmSession( + index, std::move(session), sessionData); + } + } } catch (const lmdb::error &e) { return {DecryptionErrorCode::DbError, e.what(), std::nullopt}; } catch (const mtx::crypto::olm_exception &e) { @@ -1035,24 +1072,24 @@ decryptEvent(const MegolmSessionIndex &index, return {DecryptionErrorCode::DecryptionFailed, e.what(), std::nullopt}; } - // Add missing fields for the event. - json body = json::parse(msg_str); - body["event_id"] = event.event_id; - body["sender"] = event.sender; - body["origin_server_ts"] = event.origin_server_ts; - body["unsigned"] = event.unsigned_data; + try { + // Add missing fields for the event. + json body = json::parse(msg_str); + body["event_id"] = event.event_id; + body["sender"] = event.sender; + body["origin_server_ts"] = event.origin_server_ts; + body["unsigned"] = event.unsigned_data; - // relations are unencrypted in content... - mtx::common::add_relations(body["content"], event.content.relations); + // relations are unencrypted in content... + mtx::common::add_relations(body["content"], event.content.relations); - mtx::events::collections::TimelineEvent te; - try { + mtx::events::collections::TimelineEvent te; mtx::events::collections::from_json(body, te); + + return {DecryptionErrorCode::NoError, std::nullopt, std::move(te.data)}; } catch (std::exception &e) { return {DecryptionErrorCode::ParsingFailed, e.what(), std::nullopt}; } - - return {std::nullopt, std::nullopt, std::move(te.data)}; } crypto::Trust @@ -1081,6 +1118,8 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s messages; std::map<std::string, std::map<std::string, DevicePublicKeys>> pks; + auto our_curve = olm::client()->identity_keys().curve25519; + for (const auto &[user, devices] : targets) { auto deviceKeys = cache::client()->userKeys(user); @@ -1114,12 +1153,32 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s continue; } - auto session = - cache::getLatestOlmSession(d.keys.at("curve25519:" + device)); + auto device_curve = d.keys.at("curve25519:" + device); + if (device_curve == our_curve) { + nhlog::crypto()->warn("Skipping our own device, since sending " + "ourselves olm messages makes no sense."); + continue; + } + + auto session = cache::getLatestOlmSession(device_curve); if (!session || force_new_session) { - claims.one_time_keys[user][device] = mtx::crypto::SIGNED_CURVE25519; - pks[user][device].ed25519 = d.keys.at("ed25519:" + device); - pks[user][device].curve25519 = d.keys.at("curve25519:" + device); + static QMap<QPair<std::string, std::string>, qint64> rateLimit; + auto currentTime = QDateTime::currentSecsSinceEpoch(); + if (rateLimit.value(QPair(user, device)) + 60 * 60 * 10 < + currentTime) { + claims.one_time_keys[user][device] = + mtx::crypto::SIGNED_CURVE25519; + pks[user][device].ed25519 = d.keys.at("ed25519:" + device); + pks[user][device].curve25519 = + d.keys.at("curve25519:" + device); + + rateLimit.insert(QPair(user, device), currentTime); + } else { + nhlog::crypto()->warn("Not creating new session with {}:{} " + "because of rate limit", + user, + device); + } continue; } @@ -1129,7 +1188,7 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s ev_json, UserId(user), d.keys.at("ed25519:" + device), - d.keys.at("curve25519:" + device)) + device_curve) .get<mtx::events::msg::OlmEncrypted>(); try { @@ -1187,22 +1246,40 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s continue; } - // TODO: Verify signatures auto otk = rd.second.begin()->at("key"); - auto id_key = pks.at(user_id).at(device_id).curve25519; + auto sign_key = pks.at(user_id).at(device_id).ed25519; + auto id_key = pks.at(user_id).at(device_id).curve25519; + + // Verify signature + { + auto signedKey = *rd.second.begin(); + std::string signature = + signedKey["signatures"][user_id].value( + "ed25519:" + device_id, ""); + + if (signature.empty() || + !mtx::crypto::ed25519_verify_signature( + sign_key, signedKey, signature)) { + nhlog::net()->warn( + "Skipping device {} as its one time key " + "has an invalid signature.", + device_id); + continue; + } + } + auto session = olm::client()->create_outbound_session(id_key, otk); messages[mtx::identifiers::parse<mtx::identifiers::User>( user_id)][device_id] = olm::client() - ->create_olm_encrypted_content( - session.get(), - ev_json, - UserId(user_id), - pks.at(user_id).at(device_id).ed25519, - id_key) + ->create_olm_encrypted_content(session.get(), + ev_json, + UserId(user_id), + sign_key, + id_key) .get<mtx::events::msg::OlmEncrypted>(); try { @@ -1248,8 +1325,8 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s req.device_keys = keysToQuery; http::client()->query_keys( req, - [ev_json, BindPks](const mtx::responses::QueryKeys &res, - mtx::http::RequestErr err) { + [ev_json, BindPks, our_curve](const mtx::responses::QueryKeys &res, + mtx::http::RequestErr err) { if (err) { nhlog::net()->warn("failed to query device keys: {} {}", err->matrix_error.error, @@ -1291,6 +1368,13 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s pks.ed25519 = device_keys.at(edKey); pks.curve25519 = device_keys.at(curveKey); + if (pks.curve25519 == our_curve) { + nhlog::crypto()->warn( + "Skipping our own device, since sending " + "ourselves olm messages makes no sense."); + continue; + } + try { if (!mtx::crypto::verify_identity_signature( dev.second, device_id, user_id)) { @@ -1360,9 +1444,12 @@ request_cross_signing_keys() body, [request_id = secretRequest.request_id, secretName](mtx::http::RequestErr err) { if (err) { - request_id_to_secret_name.erase(request_id); nhlog::net()->error("Failed to send request for secrect '{}'", secretName); + // Cancel request on UI thread + QTimer::singleShot(1, cache::client(), [request_id]() { + request_id_to_secret_name.erase(request_id); + }); return; } }); diff --git a/src/Olm.h b/src/Olm.h index a18cbbfb..ab86ca00 100644 --- a/src/Olm.h +++ b/src/Olm.h @@ -14,9 +14,11 @@ constexpr auto OLM_ALGO = "m.olm.v1.curve25519-aes-sha2"; namespace olm { +Q_NAMESPACE -enum class DecryptionErrorCode +enum DecryptionErrorCode { + NoError, MissingSession, // Session was not found, retrieve from backup or request from other devices // and try again MissingSessionIndex, // Session was found, but it does not reach back enough to this index, @@ -25,14 +27,13 @@ enum class DecryptionErrorCode DecryptionFailed, // libolm error ParsingFailed, // Failed to parse the actual event ReplayAttack, // Megolm index reused - UnknownFingerprint, // Unknown device Fingerprint }; +Q_ENUM_NS(DecryptionErrorCode) struct DecryptionResult { - std::optional<DecryptionErrorCode> error; + DecryptionErrorCode error; std::optional<std::string> error_message; - std::optional<mtx::events::collections::TimelineEvents> event; }; @@ -80,9 +81,11 @@ encrypt_group_message(const std::string &room_id, const std::string &device_id, nlohmann::json body); +//! Decrypt an event. Use dont_write_db to prevent db writes when already in a write transaction. DecryptionResult decryptEvent(const MegolmSessionIndex &index, - const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &event); + const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &event, + bool dont_write_db = false); crypto::Trust calculate_trust(const std::string &user_id, const std::string &curve25519); diff --git a/src/ReadReceiptsModel.cpp b/src/ReadReceiptsModel.cpp new file mode 100644 index 00000000..25262c59 --- /dev/null +++ b/src/ReadReceiptsModel.cpp @@ -0,0 +1,131 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ReadReceiptsModel.h" + +#include <QLocale> + +#include "Cache.h" +#include "Cache_p.h" +#include "Logging.h" +#include "Utils.h" + +ReadReceiptsModel::ReadReceiptsModel(QString event_id, QString room_id, QObject *parent) + : QAbstractListModel{parent} + , event_id_{event_id} + , room_id_{room_id} +{ + try { + addUsers(cache::readReceipts(event_id_, room_id_)); + } catch (const lmdb::error &) { + nhlog::db()->warn("failed to retrieve read receipts for {} {}", + event_id_.toStdString(), + room_id_.toStdString()); + + return; + } + + connect(cache::client(), &Cache::newReadReceipts, this, &ReadReceiptsModel::update); +} + +void +ReadReceiptsModel::update() +{ + try { + addUsers(cache::readReceipts(event_id_, room_id_)); + } catch (const lmdb::error &) { + nhlog::db()->warn("failed to retrieve read receipts for {} {}", + event_id_.toStdString(), + room_id_.toStdString()); + + return; + } +} + +QHash<int, QByteArray> +ReadReceiptsModel::roleNames() const +{ + // Note: RawTimestamp is purposely not included here + return { + {Mxid, "mxid"}, + {DisplayName, "displayName"}, + {AvatarUrl, "avatarUrl"}, + {Timestamp, "timestamp"}, + }; +} + +QVariant +ReadReceiptsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)readReceipts_.size() || index.row() < 0) + return {}; + + switch (role) { + case Mxid: + return readReceipts_[index.row()].first; + case DisplayName: + return cache::displayName(room_id_, readReceipts_[index.row()].first); + case AvatarUrl: + return cache::avatarUrl(room_id_, readReceipts_[index.row()].first); + case Timestamp: + return dateFormat(readReceipts_[index.row()].second); + case RawTimestamp: + return readReceipts_[index.row()].second; + default: + return {}; + } +} + +void +ReadReceiptsModel::addUsers( + const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &users) +{ + auto newReceipts = users.size() - readReceipts_.size(); + + if (newReceipts > 0) { + beginInsertRows( + QModelIndex{}, readReceipts_.size(), readReceipts_.size() + newReceipts - 1); + + for (const auto &user : users) { + QPair<QString, QDateTime> item = { + QString::fromStdString(user.second), + QDateTime::fromMSecsSinceEpoch(user.first)}; + if (!readReceipts_.contains(item)) + readReceipts_.push_back(item); + } + + endInsertRows(); + } +} + +QString +ReadReceiptsModel::dateFormat(const QDateTime &then) const +{ + auto now = QDateTime::currentDateTime(); + auto days = then.daysTo(now); + + if (days == 0) + return QLocale::system().toString(then.time(), QLocale::ShortFormat); + else if (days < 2) + return tr("Yesterday, %1") + .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); + else if (days < 7) + //: %1 is the name of the current day, %2 is the time the read receipt was read. The + //: result may look like this: Monday, 7:15 + return QString("%1, %2") + .arg(then.toString("dddd")) + .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); + + return QLocale::system().toString(then.time(), QLocale::ShortFormat); +} + +ReadReceiptsProxy::ReadReceiptsProxy(QString event_id, QString room_id, QObject *parent) + : QSortFilterProxyModel{parent} + , model_{event_id, room_id, this} +{ + setSourceModel(&model_); + setSortRole(ReadReceiptsModel::RawTimestamp); + sort(0, Qt::DescendingOrder); + setDynamicSortFilter(true); +} diff --git a/src/ReadReceiptsModel.h b/src/ReadReceiptsModel.h new file mode 100644 index 00000000..3b45716c --- /dev/null +++ b/src/ReadReceiptsModel.h @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef READRECEIPTSMODEL_H +#define READRECEIPTSMODEL_H + +#include <QAbstractListModel> +#include <QDateTime> +#include <QObject> +#include <QSortFilterProxyModel> +#include <QString> + +class ReadReceiptsModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum Roles + { + Mxid, + DisplayName, + AvatarUrl, + Timestamp, + RawTimestamp, + }; + + explicit ReadReceiptsModel(QString event_id, QString room_id, QObject *parent = nullptr); + + QString eventId() const { return event_id_; } + QString roomId() const { return room_id_; } + + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent) const override + { + Q_UNUSED(parent) + return readReceipts_.size(); + } + QVariant data(const QModelIndex &index, int role) const override; + +public slots: + void addUsers(const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &users); + void update(); + +private: + QString dateFormat(const QDateTime &then) const; + + QString event_id_; + QString room_id_; + QVector<QPair<QString, QDateTime>> readReceipts_; +}; + +class ReadReceiptsProxy : public QSortFilterProxyModel +{ + Q_OBJECT + + Q_PROPERTY(QString eventId READ eventId CONSTANT) + Q_PROPERTY(QString roomId READ roomId CONSTANT) + +public: + explicit ReadReceiptsProxy(QString event_id, QString room_id, QObject *parent = nullptr); + + QString eventId() const { return event_id_; } + QString roomId() const { return room_id_; } + +private: + QString event_id_; + QString room_id_; + + ReadReceiptsModel model_; +}; + +#endif // READRECEIPTSMODEL_H diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index 1588d07d..bae24df0 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -12,6 +12,7 @@ #include <mtx/responses/register.hpp> #include <mtx/responses/well-known.hpp> +#include <mtxclient/http/client.hpp> #include "Config.h" #include "Logging.h" @@ -93,6 +94,7 @@ RegisterPage::RegisterPage(QWidget *parent) server_input_ = new TextField(); server_input_->setLabel(tr("Homeserver")); + server_input_->setRegexp(QRegularExpression(".+")); server_input_->setToolTip( tr("A server that allows registration. Since matrix is decentralized, you need to first " "find a server you can register on or host your own.")); @@ -145,178 +147,39 @@ RegisterPage::RegisterPage(QWidget *parent) top_layout_->addLayout(button_layout_); top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter); top_layout_->addStretch(1); - - connect( - this, - &RegisterPage::versionErrorCb, - this, - [this](const QString &msg) { - error_server_label_->show(); - server_input_->setValid(false); - showError(error_server_label_, msg); - }, - Qt::QueuedConnection); + setLayout(top_layout_); connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked())); connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked())); connect(username_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); - connect(username_input_, &TextField::editingFinished, this, &RegisterPage::checkFields); + connect(username_input_, &TextField::editingFinished, this, &RegisterPage::checkUsername); connect(password_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); - connect(password_input_, &TextField::editingFinished, this, &RegisterPage::checkFields); + connect(password_input_, &TextField::editingFinished, this, &RegisterPage::checkPassword); connect(password_confirmation_, SIGNAL(returnPressed()), register_button_, SLOT(click())); - connect( - password_confirmation_, &TextField::editingFinished, this, &RegisterPage::checkFields); + connect(password_confirmation_, + &TextField::editingFinished, + this, + &RegisterPage::checkPasswordConfirmation); connect(server_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); - connect(server_input_, &TextField::editingFinished, this, &RegisterPage::checkFields); - connect(this, &RegisterPage::registerErrorCb, this, [this](const QString &msg) { - showError(msg); - }); - connect( - this, - &RegisterPage::registrationFlow, - this, - [this](const std::string &user, - const std::string &pass, - const mtx::user_interactive::Unauthorized &unauthorized) { - auto completed_stages = unauthorized.completed; - auto flows = unauthorized.flows; - auto session = unauthorized.session.empty() ? http::client()->generate_txn_id() - : unauthorized.session; - - nhlog::ui()->info("Completed stages: {}", completed_stages.size()); - - if (!completed_stages.empty()) - flows.erase(std::remove_if( - flows.begin(), - flows.end(), - [completed_stages](auto flow) { - if (completed_stages.size() > flow.stages.size()) - return true; - for (size_t f = 0; f < completed_stages.size(); f++) - if (completed_stages[f] != flow.stages[f]) - return true; - return false; - }), - flows.end()); - - if (flows.empty()) { - nhlog::net()->error("No available registration flows!"); - emit registerErrorCb(tr("No supported registration flows!")); - return; - } - - auto current_stage = flows.front().stages.at(completed_stages.size()); - - if (current_stage == mtx::user_interactive::auth_types::recaptcha) { - auto captchaDialog = - new dialogs::ReCaptcha(QString::fromStdString(session), this); - - connect(captchaDialog, - &dialogs::ReCaptcha::confirmation, - this, - [this, user, pass, session, captchaDialog]() { - captchaDialog->close(); - captchaDialog->deleteLater(); - - emit registerAuth( - user, - pass, - mtx::user_interactive::Auth{ - session, mtx::user_interactive::auth::Fallback{}}); - }); - connect(captchaDialog, - &dialogs::ReCaptcha::cancel, - this, - &RegisterPage::errorOccurred); - - QTimer::singleShot( - 1000, this, [captchaDialog]() { captchaDialog->show(); }); - } else if (current_stage == mtx::user_interactive::auth_types::dummy) { - emit registerAuth(user, - pass, - mtx::user_interactive::Auth{ - session, mtx::user_interactive::auth::Dummy{}}); - } else { - // use fallback - auto dialog = - new dialogs::FallbackAuth(QString::fromStdString(current_stage), - QString::fromStdString(session), - this); - - connect(dialog, - &dialogs::FallbackAuth::confirmation, - this, - [this, user, pass, session, dialog]() { - dialog->close(); - dialog->deleteLater(); - - emit registerAuth( - user, - pass, - mtx::user_interactive::Auth{ - session, mtx::user_interactive::auth::Fallback{}}); - }); - connect(dialog, - &dialogs::FallbackAuth::cancel, - this, - &RegisterPage::errorOccurred); - - dialog->show(); - } - }); + connect(server_input_, &TextField::editingFinished, this, &RegisterPage::checkServer); connect( this, - &RegisterPage::registerAuth, + &RegisterPage::serverError, this, - [this](const std::string &user, - const std::string &pass, - const mtx::user_interactive::Auth &auth) { - http::client()->registration( - user, - pass, - auth, - [this, user, pass](const mtx::responses::Register &res, - mtx::http::RequestErr err) { - if (!err) { - http::client()->set_user(res.user_id); - http::client()->set_access_token(res.access_token); - http::client()->set_device_id(res.device_id); - - emit registerOk(); - return; - } - - // The server requires registration flows. - if (err->status_code == 401) { - if (err->matrix_error.unauthorized.flows.empty()) { - nhlog::net()->warn( - "failed to retrieve registration flows: ({}) " - "{}", - static_cast<int>(err->status_code), - err->matrix_error.error); - emit registerErrorCb( - QString::fromStdString(err->matrix_error.error)); - return; - } - - emit registrationFlow( - user, pass, err->matrix_error.unauthorized); - return; - } - - nhlog::net()->warn("failed to register: status_code ({}), " - "matrix_error: ({}), parser error ({})", - static_cast<int>(err->status_code), - err->matrix_error.error, - err->parse_error); - - emit registerErrorCb(QString::fromStdString(err->matrix_error.error)); - }); - }); + [this](const QString &msg) { + server_input_->setValid(false); + showError(error_server_label_, msg); + }, + Qt::QueuedConnection); - setLayout(top_layout_); + connect(this, &RegisterPage::wellKnownLookup, this, &RegisterPage::doWellKnownLookup); + connect(this, &RegisterPage::versionsCheck, this, &RegisterPage::doVersionsCheck); + connect(this, &RegisterPage::registration, this, &RegisterPage::doRegistration); + connect(this, &RegisterPage::UIA, this, &RegisterPage::doUIA); + connect( + this, &RegisterPage::registrationWithAuth, this, &RegisterPage::doRegistrationWithAuth); } void @@ -345,192 +208,299 @@ RegisterPage::showError(QLabel *label, const QString &msg) int height = rect.height(); label->setFixedHeight((int)qCeil(width / 200.0) * height); label->setText(msg); + label->show(); } bool RegisterPage::checkOneField(QLabel *label, const TextField *t_field, const QString &msg) { if (t_field->isValid()) { - label->setText(""); label->hide(); return true; } else { - label->show(); showError(label, msg); return false; } } bool -RegisterPage::checkFields() +RegisterPage::checkUsername() { - error_label_->setText(""); - error_username_label_->setText(""); - error_password_label_->setText(""); - error_password_confirmation_label_->setText(""); - error_server_label_->setText(""); + return checkOneField(error_username_label_, + username_input_, + tr("The username must not be empty, and must contain only the " + "characters a-z, 0-9, ., _, =, -, and /.")); +} - error_username_label_->hide(); - error_password_label_->hide(); - error_password_confirmation_label_->hide(); - error_server_label_->hide(); +bool +RegisterPage::checkPassword() +{ + return checkOneField( + error_password_label_, password_input_, tr("Password is not long enough (min 8 chars)")); +} - password_confirmation_->setValid(true); - server_input_->setValid(true); - - bool all_fields_good = true; - if (username_input_->isModified() && - !checkOneField(error_username_label_, - username_input_, - tr("The username must not be empty, and must contain only the " - "characters a-z, 0-9, ., _, =, -, and /."))) { - all_fields_good = false; - } else if (password_input_->isModified() && - !checkOneField(error_password_label_, - password_input_, - tr("Password is not long enough (min 8 chars)"))) { - all_fields_good = false; - } else if (password_confirmation_->isModified() && - password_input_->text() != password_confirmation_->text()) { - error_password_confirmation_label_->show(); +bool +RegisterPage::checkPasswordConfirmation() +{ + if (password_input_->text() == password_confirmation_->text()) { + error_password_confirmation_label_->hide(); + password_confirmation_->setValid(true); + return true; + } else { showError(error_password_confirmation_label_, tr("Passwords don't match")); password_confirmation_->setValid(false); - all_fields_good = false; - } else if (server_input_->isModified() && - (!server_input_->hasAcceptableInput() || server_input_->text().isEmpty())) { - error_server_label_->show(); - showError(error_server_label_, tr("Invalid server name")); - server_input_->setValid(false); - all_fields_good = false; - } - if (!username_input_->isModified() || !password_input_->isModified() || - !password_confirmation_->isModified() || !server_input_->isModified()) { - all_fields_good = false; + return false; } - return all_fields_good; +} + +bool +RegisterPage::checkServer() +{ + // This doesn't check that the server is reachable, + // just that the input is not obviously wrong. + return checkOneField(error_server_label_, server_input_, tr("Invalid server name")); } void RegisterPage::onRegisterButtonClicked() { - if (!checkFields()) { - showError(error_label_, - tr("One or more fields have invalid inputs. Please correct those issues " - "and try again.")); - return; - } else { - auto username = username_input_->text().toStdString(); - auto password = password_input_->text().toStdString(); - auto server = server_input_->text().toStdString(); + if (checkUsername() && checkPassword() && checkPasswordConfirmation() && checkServer()) { + auto server = server_input_->text().toStdString(); http::client()->set_server(server); http::client()->verify_certificates( !UserSettings::instance()->disableCertificateValidation()); - http::client()->well_known( - [this, username, password](const mtx::responses::WellKnown &res, - mtx::http::RequestErr err) { - if (err) { - if (err->status_code == 404) { - nhlog::net()->info("Autodiscovery: No .well-known."); - checkVersionAndRegister(username, password); - return; - } - - if (!err->parse_error.empty()) { - emit versionErrorCb(tr( - "Autodiscovery failed. Received malformed response.")); - nhlog::net()->error( - "Autodiscovery failed. Received malformed response."); - return; - } - - emit versionErrorCb(tr("Autodiscovery failed. Unknown error when " - "requesting .well-known.")); - nhlog::net()->error("Autodiscovery failed. Unknown error when " - "requesting .well-known. {} {}", - err->status_code, - err->error_code); + // This starts a chain of `emit`s which ends up doing the + // registration. Signals are used rather than normal function + // calls so that the dialogs used in UIA work correctly. + // + // The sequence of events looks something like this: + // + // dowellKnownLookup + // v + // doVersionsCheck + // v + // doRegistration + // v + // doUIA <-----------------+ + // v | More auth required + // doRegistrationWithAuth -+ + // | Success + // v + // registering + + emit wellKnownLookup(); + + emit registering(); + } +} + +void +RegisterPage::doWellKnownLookup() +{ + http::client()->well_known( + [this](const mtx::responses::WellKnown &res, mtx::http::RequestErr err) { + if (err) { + if (err->status_code == 404) { + nhlog::net()->info("Autodiscovery: No .well-known."); + // Check that the homeserver can be reached + emit versionsCheck(); return; } - nhlog::net()->info("Autodiscovery: Discovered '" + - res.homeserver.base_url + "'"); - http::client()->set_server(res.homeserver.base_url); - checkVersionAndRegister(username, password); - }); + if (!err->parse_error.empty()) { + emit serverError( + tr("Autodiscovery failed. Received malformed response.")); + nhlog::net()->error( + "Autodiscovery failed. Received malformed response."); + return; + } - emit registering(); - } + emit serverError(tr("Autodiscovery failed. Unknown error when " + "requesting .well-known.")); + nhlog::net()->error("Autodiscovery failed. Unknown error when " + "requesting .well-known. {} {}", + err->status_code, + err->error_code); + return; + } + + nhlog::net()->info("Autodiscovery: Discovered '" + res.homeserver.base_url + "'"); + http::client()->set_server(res.homeserver.base_url); + // Check that the homeserver can be reached + emit versionsCheck(); + }); } void -RegisterPage::checkVersionAndRegister(const std::string &username, const std::string &password) +RegisterPage::doVersionsCheck() { + // Make a request to /_matrix/client/versions to check the address + // given is a Matrix homeserver. http::client()->versions( - [this, username, password](const mtx::responses::Versions &, mtx::http::RequestErr err) { + [this](const mtx::responses::Versions &, mtx::http::RequestErr err) { if (err) { if (err->status_code == 404) { - emit versionErrorCb(tr("The required endpoints were not found. " - "Possibly not a Matrix server.")); + emit serverError( + tr("The required endpoints were not found. Possibly " + "not a Matrix server.")); return; } if (!err->parse_error.empty()) { - emit versionErrorCb(tr("Received malformed response. Make sure " - "the homeserver domain is valid.")); + emit serverError( + tr("Received malformed response. Make sure the homeserver " + "domain is valid.")); return; } - emit versionErrorCb(tr( - "An unknown error occured. Make sure the homeserver domain is valid.")); + emit serverError(tr("An unknown error occured. Make sure the " + "homeserver domain is valid.")); return; } - http::client()->registration( - username, - password, - [this, username, password](const mtx::responses::Register &res, - mtx::http::RequestErr err) { - if (!err) { - http::client()->set_user(res.user_id); - http::client()->set_access_token(res.access_token); - - emit registerOk(); - return; - } - - // The server requires registration flows. - if (err->status_code == 401) { - if (err->matrix_error.unauthorized.flows.empty()) { - nhlog::net()->warn( - "failed to retrieve registration flows1: ({}) " - "{}", - static_cast<int>(err->status_code), - err->matrix_error.error); - emit errorOccurred(); - emit registerErrorCb( - QString::fromStdString(err->matrix_error.error)); - return; - } - - emit registrationFlow( - username, password, err->matrix_error.unauthorized); - return; - } - - nhlog::net()->error( - "failed to register: status_code ({}), matrix_error({})", - static_cast<int>(err->status_code), - err->matrix_error.error); - - emit registerErrorCb(QString::fromStdString(err->matrix_error.error)); - emit errorOccurred(); - }); + // Attempt registration without an `auth` dict + emit registration(); }); } void +RegisterPage::doRegistration() +{ + // These inputs should still be alright, but check just in case + if (checkUsername() && checkPassword() && checkPasswordConfirmation()) { + auto username = username_input_->text().toStdString(); + auto password = password_input_->text().toStdString(); + http::client()->registration(username, password, registrationCb()); + } +} + +void +RegisterPage::doRegistrationWithAuth(const mtx::user_interactive::Auth &auth) +{ + // These inputs should still be alright, but check just in case + if (checkUsername() && checkPassword() && checkPasswordConfirmation()) { + auto username = username_input_->text().toStdString(); + auto password = password_input_->text().toStdString(); + http::client()->registration(username, password, auth, registrationCb()); + } +} + +mtx::http::Callback<mtx::responses::Register> +RegisterPage::registrationCb() +{ + // Return a function to be used as the callback when an attempt at + // registration is made. + return [this](const mtx::responses::Register &res, mtx::http::RequestErr err) { + if (!err) { + http::client()->set_user(res.user_id); + http::client()->set_access_token(res.access_token); + emit registerOk(); + return; + } + + // The server requires registration flows. + if (err->status_code == 401) { + if (err->matrix_error.unauthorized.flows.empty()) { + nhlog::net()->warn("failed to retrieve registration flows: " + "status_code({}), matrix_error({}) ", + static_cast<int>(err->status_code), + err->matrix_error.error); + showError(QString::fromStdString(err->matrix_error.error)); + return; + } + + // Attempt to complete a UIA stage + emit UIA(err->matrix_error.unauthorized); + return; + } + + nhlog::net()->error("failed to register: status_code ({}), matrix_error({})", + static_cast<int>(err->status_code), + err->matrix_error.error); + + showError(QString::fromStdString(err->matrix_error.error)); + }; +} + +void +RegisterPage::doUIA(const mtx::user_interactive::Unauthorized &unauthorized) +{ + auto completed_stages = unauthorized.completed; + auto flows = unauthorized.flows; + auto session = + unauthorized.session.empty() ? http::client()->generate_txn_id() : unauthorized.session; + + nhlog::ui()->info("Completed stages: {}", completed_stages.size()); + + if (!completed_stages.empty()) { + // Get rid of all flows which don't start with the sequence of + // stages that have already been completed. + flows.erase( + std::remove_if(flows.begin(), + flows.end(), + [completed_stages](auto flow) { + if (completed_stages.size() > flow.stages.size()) + return true; + for (size_t f = 0; f < completed_stages.size(); f++) + if (completed_stages[f] != flow.stages[f]) + return true; + return false; + }), + flows.end()); + } + + if (flows.empty()) { + nhlog::ui()->error("No available registration flows!"); + showError(tr("No supported registration flows!")); + return; + } + + auto current_stage = flows.front().stages.at(completed_stages.size()); + + if (current_stage == mtx::user_interactive::auth_types::recaptcha) { + auto captchaDialog = new dialogs::ReCaptcha(QString::fromStdString(session), this); + + connect(captchaDialog, + &dialogs::ReCaptcha::confirmation, + this, + [this, session, captchaDialog]() { + captchaDialog->close(); + captchaDialog->deleteLater(); + doRegistrationWithAuth(mtx::user_interactive::Auth{ + session, mtx::user_interactive::auth::Fallback{}}); + }); + + connect( + captchaDialog, &dialogs::ReCaptcha::cancel, this, &RegisterPage::errorOccurred); + + QTimer::singleShot(1000, this, [captchaDialog]() { captchaDialog->show(); }); + + } else if (current_stage == mtx::user_interactive::auth_types::dummy) { + doRegistrationWithAuth( + mtx::user_interactive::Auth{session, mtx::user_interactive::auth::Dummy{}}); + + } else { + // use fallback + auto dialog = new dialogs::FallbackAuth( + QString::fromStdString(current_stage), QString::fromStdString(session), this); + + connect( + dialog, &dialogs::FallbackAuth::confirmation, this, [this, session, dialog]() { + dialog->close(); + dialog->deleteLater(); + emit registrationWithAuth(mtx::user_interactive::Auth{ + session, mtx::user_interactive::auth::Fallback{}}); + }); + + connect(dialog, &dialogs::FallbackAuth::cancel, this, &RegisterPage::errorOccurred); + + dialog->show(); + } +} + +void RegisterPage::paintEvent(QPaintEvent *) { QStyleOption opt; diff --git a/src/RegisterPage.h b/src/RegisterPage.h index 0e4a45d0..42ea00cb 100644 --- a/src/RegisterPage.h +++ b/src/RegisterPage.h @@ -10,6 +10,7 @@ #include <memory> #include <mtx/user_interactive.hpp> +#include <mtxclient/http/client.hpp> class FlatButton; class RaisedButton; @@ -33,17 +34,16 @@ signals: void errorOccurred(); //! Used to trigger the corresponding slot outside of the main thread. - void versionErrorCb(const QString &err); + void serverError(const QString &err); + + void wellKnownLookup(); + void versionsCheck(); + void registration(); + void UIA(const mtx::user_interactive::Unauthorized &unauthorized); + void registrationWithAuth(const mtx::user_interactive::Auth &auth); void registering(); void registerOk(); - void registerErrorCb(const QString &msg); - void registrationFlow(const std::string &user, - const std::string &pass, - const mtx::user_interactive::Unauthorized &unauthorized); - void registerAuth(const std::string &user, - const std::string &pass, - const mtx::user_interactive::Auth &auth); private slots: void onBackButtonClicked(); @@ -51,12 +51,22 @@ private slots: // function for showing different errors void showError(const QString &msg); + void showError(QLabel *label, const QString &msg); -private: bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg); - bool checkFields(); - void showError(QLabel *label, const QString &msg); - void checkVersionAndRegister(const std::string &username, const std::string &password); + bool checkUsername(); + bool checkPassword(); + bool checkPasswordConfirmation(); + bool checkServer(); + + void doWellKnownLookup(); + void doVersionsCheck(); + void doRegistration(); + void doUIA(const mtx::user_interactive::Unauthorized &unauthorized); + void doRegistrationWithAuth(const mtx::user_interactive::Auth &auth); + mtx::http::Callback<mtx::responses::Register> registrationCb(); + +private: QVBoxLayout *top_layout_; QHBoxLayout *back_layout_; @@ -69,6 +79,7 @@ private: QLabel *error_password_label_; QLabel *error_password_confirmation_label_; QLabel *error_server_label_; + QLabel *error_registration_token_label_; FlatButton *back_button_; RaisedButton *register_button_; @@ -81,4 +92,5 @@ private: TextField *password_input_; TextField *password_confirmation_; TextField *server_input_; + TextField *registration_token_input_; }; diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp new file mode 100644 index 00000000..7bf55617 --- /dev/null +++ b/src/SingleImagePackModel.cpp @@ -0,0 +1,350 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "SingleImagePackModel.h" + +#include <QFile> +#include <QMimeDatabase> + +#include "Cache_p.h" +#include "ChatPage.h" +#include "Logging.h" +#include "MatrixClient.h" +#include "Utils.h" +#include "timeline/Permissions.h" +#include "timeline/TimelineModel.h" + +Q_DECLARE_METATYPE(mtx::common::ImageInfo) + +SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) + : QAbstractListModel(parent) + , roomid_(std::move(pack_.source_room)) + , statekey_(std::move(pack_.state_key)) + , old_statekey_(statekey_) + , pack(std::move(pack_.pack)) +{ + [[maybe_unused]] static auto imageInfoType = qRegisterMetaType<mtx::common::ImageInfo>(); + + if (!pack.pack) + pack.pack = mtx::events::msc2545::ImagePack::PackDescription{}; + + for (const auto &e : pack.images) + shortcodes.push_back(e.first); + + connect(this, &SingleImagePackModel::addImage, this, &SingleImagePackModel::addImageCb); +} + +int +SingleImagePackModel::rowCount(const QModelIndex &) const +{ + return (int)shortcodes.size(); +} + +QHash<int, QByteArray> +SingleImagePackModel::roleNames() const +{ + return { + {Roles::Url, "url"}, + {Roles::ShortCode, "shortCode"}, + {Roles::Body, "body"}, + {Roles::IsEmote, "isEmote"}, + {Roles::IsSticker, "isSticker"}, + }; +} + +QVariant +SingleImagePackModel::data(const QModelIndex &index, int role) const +{ + if (hasIndex(index.row(), index.column(), index.parent())) { + const auto &img = pack.images.at(shortcodes.at(index.row())); + switch (role) { + case Url: + return QString::fromStdString(img.url); + case ShortCode: + return QString::fromStdString(shortcodes.at(index.row())); + case Body: + return QString::fromStdString(img.body); + case IsEmote: + return img.overrides_usage() ? img.is_emoji() : pack.pack->is_emoji(); + case IsSticker: + return img.overrides_usage() ? img.is_sticker() : pack.pack->is_sticker(); + default: + return {}; + } + } + return {}; +} + +bool +SingleImagePackModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + using mtx::events::msc2545::PackUsage; + + if (hasIndex(index.row(), index.column(), index.parent())) { + auto &img = pack.images.at(shortcodes.at(index.row())); + switch (role) { + case ShortCode: { + auto newCode = value.toString().toStdString(); + + // otherwise we delete this by accident + if (pack.images.count(newCode)) + return false; + + auto tmp = img; + auto oldCode = shortcodes.at(index.row()); + pack.images.erase(oldCode); + shortcodes[index.row()] = newCode; + pack.images.insert({newCode, tmp}); + + emit dataChanged( + this->index(index.row()), this->index(index.row()), {Roles::ShortCode}); + return true; + } + case Body: + img.body = value.toString().toStdString(); + emit dataChanged( + this->index(index.row()), this->index(index.row()), {Roles::Body}); + return true; + case IsEmote: { + bool isEmote = value.toBool(); + bool isSticker = + img.overrides_usage() ? img.is_sticker() : pack.pack->is_sticker(); + + img.usage.set(PackUsage::Emoji, isEmote); + img.usage.set(PackUsage::Sticker, isSticker); + + if (img.usage == pack.pack->usage) + img.usage.reset(); + + emit dataChanged( + this->index(index.row()), this->index(index.row()), {Roles::IsEmote}); + + return true; + } + case IsSticker: { + bool isEmote = + img.overrides_usage() ? img.is_emoji() : pack.pack->is_emoji(); + bool isSticker = value.toBool(); + + img.usage.set(PackUsage::Emoji, isEmote); + img.usage.set(PackUsage::Sticker, isSticker); + + if (img.usage == pack.pack->usage) + img.usage.reset(); + + emit dataChanged( + this->index(index.row()), this->index(index.row()), {Roles::IsSticker}); + + return true; + } + } + } + return false; +} + +bool +SingleImagePackModel::isGloballyEnabled() const +{ + if (auto roomPacks = + cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) { + if (auto tmp = std::get_if< + mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePackRooms>>( + &*roomPacks)) { + if (tmp->content.rooms.count(roomid_) && + tmp->content.rooms.at(roomid_).count(statekey_)) + return true; + } + } + return false; +} +void +SingleImagePackModel::setGloballyEnabled(bool enabled) +{ + mtx::events::msc2545::ImagePackRooms content{}; + if (auto roomPacks = + cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) { + if (auto tmp = std::get_if< + mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePackRooms>>( + &*roomPacks)) { + content = tmp->content; + } + } + + if (enabled) + content.rooms[roomid_][statekey_] = {}; + else + content.rooms[roomid_].erase(statekey_); + + http::client()->put_account_data(content, [](mtx::http::RequestErr) { + // emit this->globallyEnabledChanged(); + }); +} + +bool +SingleImagePackModel::canEdit() const +{ + if (roomid_.empty()) + return true; + else + return Permissions(QString::fromStdString(roomid_)) + .canChange(qml_mtx_events::ImagePackInRoom); +} + +void +SingleImagePackModel::setPackname(QString val) +{ + auto val_ = val.toStdString(); + if (val_ != this->pack.pack->display_name) { + this->pack.pack->display_name = val_; + emit packnameChanged(); + } +} + +void +SingleImagePackModel::setAttribution(QString val) +{ + auto val_ = val.toStdString(); + if (val_ != this->pack.pack->attribution) { + this->pack.pack->attribution = val_; + emit attributionChanged(); + } +} + +void +SingleImagePackModel::setAvatarUrl(QString val) +{ + auto val_ = val.toStdString(); + if (val_ != this->pack.pack->avatar_url) { + this->pack.pack->avatar_url = val_; + emit avatarUrlChanged(); + } +} + +void +SingleImagePackModel::setStatekey(QString val) +{ + auto val_ = val.toStdString(); + if (val_ != statekey_) { + statekey_ = val_; + emit statekeyChanged(); + } +} + +void +SingleImagePackModel::setIsStickerPack(bool val) +{ + using mtx::events::msc2545::PackUsage; + if (val != pack.pack->is_sticker()) { + pack.pack->usage.set(PackUsage::Sticker, val); + emit isStickerPackChanged(); + } +} + +void +SingleImagePackModel::setIsEmotePack(bool val) +{ + using mtx::events::msc2545::PackUsage; + if (val != pack.pack->is_emoji()) { + pack.pack->usage.set(PackUsage::Emoji, val); + emit isEmotePackChanged(); + } +} + +void +SingleImagePackModel::save() +{ + if (roomid_.empty()) { + http::client()->put_account_data(pack, [](mtx::http::RequestErr e) { + if (e) + ChatPage::instance()->showNotification( + tr("Failed to update image pack: {}") + .arg(QString::fromStdString(e->matrix_error.error))); + }); + } else { + if (old_statekey_ != statekey_) { + http::client()->send_state_event( + roomid_, + to_string(mtx::events::EventType::ImagePackInRoom), + old_statekey_, + nlohmann::json::object(), + [](const mtx::responses::EventId &, mtx::http::RequestErr e) { + if (e) + ChatPage::instance()->showNotification( + tr("Failed to delete old image pack: {}") + .arg(QString::fromStdString(e->matrix_error.error))); + }); + } + + http::client()->send_state_event( + roomid_, + statekey_, + pack, + [this](const mtx::responses::EventId &, mtx::http::RequestErr e) { + if (e) + ChatPage::instance()->showNotification( + tr("Failed to update image pack: {}") + .arg(QString::fromStdString(e->matrix_error.error))); + + nhlog::net()->info("Uploaded image pack: {}", statekey_); + }); + } +} + +void +SingleImagePackModel::addStickers(QList<QUrl> files) +{ + for (const auto &f : files) { + auto file = QFile(f.toLocalFile()); + if (!file.open(QFile::ReadOnly)) { + ChatPage::instance()->showNotification( + tr("Failed to open image: {}").arg(f.toLocalFile())); + return; + } + + auto bytes = file.readAll(); + auto img = utils::readImage(bytes); + + mtx::common::ImageInfo info{}; + + auto sz = img.size() / 2; + if (sz.width() > 512 || sz.height() > 512) { + sz.scale(512, 512, Qt::AspectRatioMode::KeepAspectRatio); + } + + info.h = sz.height(); + info.w = sz.width(); + info.size = bytes.size(); + + auto filename = f.fileName().toStdString(); + http::client()->upload( + bytes.toStdString(), + QMimeDatabase().mimeTypeForFile(f.toLocalFile()).name().toStdString(), + filename, + [this, filename, info](const mtx::responses::ContentURI &uri, + mtx::http::RequestErr e) { + if (e) { + ChatPage::instance()->showNotification( + tr("Failed to upload image: {}") + .arg(QString::fromStdString(e->matrix_error.error))); + return; + } + + emit addImage(uri.content_uri, filename, info); + }); + } +} +void +SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info) +{ + mtx::events::msc2545::PackImage img{}; + img.url = uri; + img.info = info; + beginInsertRows( + QModelIndex(), static_cast<int>(shortcodes.size()), static_cast<int>(shortcodes.size())); + + pack.images[filename] = img; + shortcodes.push_back(filename); + + endInsertRows(); +} diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h new file mode 100644 index 00000000..cd38b3b6 --- /dev/null +++ b/src/SingleImagePackModel.h @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> +#include <QList> +#include <QUrl> + +#include <mtx/events/mscs/image_packs.hpp> + +#include "CacheStructs.h" + +class SingleImagePackModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(QString roomid READ roomid CONSTANT) + Q_PROPERTY(QString statekey READ statekey WRITE setStatekey NOTIFY statekeyChanged) + Q_PROPERTY( + QString attribution READ attribution WRITE setAttribution NOTIFY attributionChanged) + Q_PROPERTY(QString packname READ packname WRITE setPackname NOTIFY packnameChanged) + Q_PROPERTY(QString avatarUrl READ avatarUrl WRITE setAvatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY( + bool isStickerPack READ isStickerPack WRITE setIsStickerPack NOTIFY isStickerPackChanged) + Q_PROPERTY(bool isEmotePack READ isEmotePack WRITE setIsEmotePack NOTIFY isEmotePackChanged) + Q_PROPERTY(bool isGloballyEnabled READ isGloballyEnabled WRITE setGloballyEnabled NOTIFY + globallyEnabledChanged) + Q_PROPERTY(bool canEdit READ canEdit CONSTANT) + +public: + enum Roles + { + Url = Qt::UserRole, + ShortCode, + Body, + IsEmote, + IsSticker, + }; + Q_ENUM(Roles); + + SingleImagePackModel(ImagePackInfo pack_, QObject *parent = nullptr); + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, + const QVariant &value, + int role = Qt::EditRole) override; + + QString roomid() const { return QString::fromStdString(roomid_); } + QString statekey() const { return QString::fromStdString(statekey_); } + QString packname() const { return QString::fromStdString(pack.pack->display_name); } + QString attribution() const { return QString::fromStdString(pack.pack->attribution); } + QString avatarUrl() const { return QString::fromStdString(pack.pack->avatar_url); } + bool isStickerPack() const { return pack.pack->is_sticker(); } + bool isEmotePack() const { return pack.pack->is_emoji(); } + + bool isGloballyEnabled() const; + bool canEdit() const; + void setGloballyEnabled(bool enabled); + + void setPackname(QString val); + void setAttribution(QString val); + void setAvatarUrl(QString val); + void setStatekey(QString val); + void setIsStickerPack(bool val); + void setIsEmotePack(bool val); + + Q_INVOKABLE void save(); + Q_INVOKABLE void addStickers(QList<QUrl> files); + +signals: + void globallyEnabledChanged(); + void statekeyChanged(); + void attributionChanged(); + void packnameChanged(); + void avatarUrlChanged(); + void isEmotePackChanged(); + void isStickerPackChanged(); + + void addImage(std::string uri, std::string filename, mtx::common::ImageInfo info); + +private slots: + void addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info); + +private: + std::string roomid_; + std::string statekey_, old_statekey_; + + mtx::events::msc2545::ImagePack pack; + std::vector<std::string> shortcodes; +}; diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index ffaebe61..ab6ac492 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -90,13 +90,11 @@ UserSettings::load(std::optional<QString> profile) decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool(); privacyScreen_ = settings.value("user/privacy_screen", false).toBool(); privacyScreenTimeout_ = settings.value("user/privacy_screen_timeout", 0).toInt(); - shareKeysWithTrustedUsers_ = - settings.value("user/automatically_share_keys_with_trusted_users", false).toBool(); - mobileMode_ = settings.value("user/mobile_mode", false).toBool(); - emojiFont_ = settings.value("user/emoji_font_family", "default").toString(); - baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble(); - auto tempPresence = settings.value("user/presence", "").toString().toStdString(); - auto presenceValue = QMetaEnum::fromType<Presence>().keyToValue(tempPresence.c_str()); + mobileMode_ = settings.value("user/mobile_mode", false).toBool(); + emojiFont_ = settings.value("user/emoji_font_family", "default").toString(); + baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble(); + auto tempPresence = settings.value("user/presence", "").toString().toStdString(); + auto presenceValue = QMetaEnum::fromType<Presence>().keyToValue(tempPresence.c_str()); if (presenceValue < 0) presenceValue = 0; presence_ = static_cast<Presence>(presenceValue); @@ -123,6 +121,12 @@ UserSettings::load(std::optional<QString> profile) userId_ = settings.value(prefix + "auth/user_id", "").toString(); deviceId_ = settings.value(prefix + "auth/device_id", "").toString(); + shareKeysWithTrustedUsers_ = + settings.value(prefix + "user/automatically_share_keys_with_trusted_users", false) + .toBool(); + onlyShareKeysWithVerifiedUsers_ = + settings.value(prefix + "user/only_share_keys_with_verified_users", false).toBool(); + disableCertificateValidation_ = settings.value("disable_certificate_validation", false).toBool(); @@ -402,6 +406,17 @@ UserSettings::setUseStunServer(bool useStunServer) } void +UserSettings::setOnlyShareKeysWithVerifiedUsers(bool shareKeys) +{ + if (shareKeys == onlyShareKeysWithVerifiedUsers_) + return; + + onlyShareKeysWithVerifiedUsers_ = shareKeys; + emit onlyShareKeysWithVerifiedUsersChanged(shareKeys); + save(); +} + +void UserSettings::setShareKeysWithTrustedUsers(bool shareKeys) { if (shareKeys == shareKeysWithTrustedUsers_) @@ -610,8 +625,6 @@ UserSettings::save() settings.setValue("decrypt_sidebar", decryptSidebar_); settings.setValue("privacy_screen", privacyScreen_); settings.setValue("privacy_screen_timeout", privacyScreenTimeout_); - settings.setValue("automatically_share_keys_with_trusted_users", - shareKeysWithTrustedUsers_); settings.setValue("mobile_mode", mobileMode_); settings.setValue("font_size", baseFontSize_); settings.setValue("typing_notifications", typingNotifications_); @@ -650,6 +663,11 @@ UserSettings::save() settings.setValue(prefix + "auth/user_id", userId_); settings.setValue(prefix + "auth/device_id", deviceId_); + settings.setValue(prefix + "user/automatically_share_keys_with_trusted_users", + shareKeysWithTrustedUsers_); + settings.setValue(prefix + "user/only_share_keys_with_verified_users", + onlyShareKeysWithVerifiedUsers_); + settings.setValue("disable_certificate_validation", disableCertificateValidation_); settings.sync(); @@ -703,41 +721,43 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge general_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); general_->setFont(font); - trayToggle_ = new Toggle{this}; - startInTrayToggle_ = new Toggle{this}; - avatarCircles_ = new Toggle{this}; - decryptSidebar_ = new Toggle(this); - privacyScreen_ = new Toggle{this}; - shareKeysWithTrustedUsers_ = new Toggle(this); - groupViewToggle_ = new Toggle{this}; - timelineButtonsToggle_ = new Toggle{this}; - typingNotifications_ = new Toggle{this}; - messageHoverHighlight_ = new Toggle{this}; - enlargeEmojiOnlyMessages_ = new Toggle{this}; - sortByImportance_ = new Toggle{this}; - readReceipts_ = new Toggle{this}; - markdown_ = new Toggle{this}; - desktopNotifications_ = new Toggle{this}; - alertOnNotification_ = new Toggle{this}; - useStunServer_ = new Toggle{this}; - mobileMode_ = new Toggle{this}; - scaleFactorCombo_ = new QComboBox{this}; - fontSizeCombo_ = new QComboBox{this}; - fontSelectionCombo_ = new QFontComboBox{this}; - emojiFontSelectionCombo_ = new QComboBox{this}; - ringtoneCombo_ = new QComboBox{this}; - microphoneCombo_ = new QComboBox{this}; - cameraCombo_ = new QComboBox{this}; - cameraResolutionCombo_ = new QComboBox{this}; - cameraFrameRateCombo_ = new QComboBox{this}; - timelineMaxWidthSpin_ = new QSpinBox{this}; - privacyScreenTimeout_ = new QSpinBox{this}; + trayToggle_ = new Toggle{this}; + startInTrayToggle_ = new Toggle{this}; + avatarCircles_ = new Toggle{this}; + decryptSidebar_ = new Toggle(this); + privacyScreen_ = new Toggle{this}; + onlyShareKeysWithVerifiedUsers_ = new Toggle(this); + shareKeysWithTrustedUsers_ = new Toggle(this); + groupViewToggle_ = new Toggle{this}; + timelineButtonsToggle_ = new Toggle{this}; + typingNotifications_ = new Toggle{this}; + messageHoverHighlight_ = new Toggle{this}; + enlargeEmojiOnlyMessages_ = new Toggle{this}; + sortByImportance_ = new Toggle{this}; + readReceipts_ = new Toggle{this}; + markdown_ = new Toggle{this}; + desktopNotifications_ = new Toggle{this}; + alertOnNotification_ = new Toggle{this}; + useStunServer_ = new Toggle{this}; + mobileMode_ = new Toggle{this}; + scaleFactorCombo_ = new QComboBox{this}; + fontSizeCombo_ = new QComboBox{this}; + fontSelectionCombo_ = new QFontComboBox{this}; + emojiFontSelectionCombo_ = new QComboBox{this}; + ringtoneCombo_ = new QComboBox{this}; + microphoneCombo_ = new QComboBox{this}; + cameraCombo_ = new QComboBox{this}; + cameraResolutionCombo_ = new QComboBox{this}; + cameraFrameRateCombo_ = new QComboBox{this}; + timelineMaxWidthSpin_ = new QSpinBox{this}; + privacyScreenTimeout_ = new QSpinBox{this}; trayToggle_->setChecked(settings_->tray()); startInTrayToggle_->setChecked(settings_->startInTray()); avatarCircles_->setChecked(settings_->avatarCircles()); decryptSidebar_->setChecked(settings_->decryptSidebar()); privacyScreen_->setChecked(settings_->privacyScreen()); + onlyShareKeysWithVerifiedUsers_->setChecked(settings_->onlyShareKeysWithVerifiedUsers()); shareKeysWithTrustedUsers_->setChecked(settings_->shareKeysWithTrustedUsers()); groupViewToggle_->setChecked(settings_->groupView()); timelineButtonsToggle_->setChecked(settings_->buttonsInTimeline()); @@ -1008,10 +1028,14 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge formLayout_->addRow(new HorizontalLine{this}); boxWrap(tr("Device ID"), deviceIdValue_); boxWrap(tr("Device Fingerprint"), deviceFingerprintValue_); - boxWrap( - tr("Share keys with verified users and devices"), - shareKeysWithTrustedUsers_, - tr("Automatically replies to key requests from other users, if they are verified.")); + boxWrap(tr("Send encrypted messages to verified users only"), + onlyShareKeysWithVerifiedUsers_, + tr("Requires a user to be verified to send encrypted messages to them. This " + "improves safety but makes E2EE more tedious.")); + boxWrap(tr("Share keys with verified users and devices"), + shareKeysWithTrustedUsers_, + tr("Automatically replies to key requests from other users, if they are verified, " + "even if that device shouldn't have access to those keys otherwise.")); formLayout_->addRow(new HorizontalLine{this}); formLayout_->addRow(sessionKeysLabel, sessionKeysLayout); formLayout_->addRow(crossSigningKeysLabel, crossSigningKeysLayout); @@ -1179,6 +1203,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge } }); + connect(onlyShareKeysWithVerifiedUsers_, &Toggle::toggled, this, [this](bool enabled) { + settings_->setOnlyShareKeysWithVerifiedUsers(enabled); + }); + connect(shareKeysWithTrustedUsers_, &Toggle::toggled, this, [this](bool enabled) { settings_->setShareKeysWithTrustedUsers(enabled); }); @@ -1271,6 +1299,7 @@ UserSettingsPage::showEvent(QShowEvent *) groupViewToggle_->setState(settings_->groupView()); decryptSidebar_->setState(settings_->decryptSidebar()); privacyScreen_->setState(settings_->privacyScreen()); + onlyShareKeysWithVerifiedUsers_->setState(settings_->onlyShareKeysWithVerifiedUsers()); shareKeysWithTrustedUsers_->setState(settings_->shareKeysWithTrustedUsers()); avatarCircles_->setState(settings_->avatarCircles()); typingNotifications_->setState(settings_->typingNotifications()); @@ -1399,7 +1428,7 @@ UserSettingsPage::exportSessionKeys() QString suffix("-----END MEGOLM SESSION DATA-----"); QString newline("\n"); QTextStream out(&file); - out << prefix << newline << b64 << newline << suffix; + out << prefix << newline << b64 << newline << suffix << newline; file.close(); } catch (const std::exception &e) { QMessageBox::warning(this, tr("Error"), e.what()); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index acb08569..096aab81 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -88,6 +88,8 @@ class UserSettings : public QObject setScreenShareHideCursor NOTIFY screenShareHideCursorChanged) Q_PROPERTY( bool useStunServer READ useStunServer WRITE setUseStunServer NOTIFY useStunServerChanged) + Q_PROPERTY(bool onlyShareKeysWithVerifiedUsers READ onlyShareKeysWithVerifiedUsers WRITE + setOnlyShareKeysWithVerifiedUsers NOTIFY onlyShareKeysWithVerifiedUsersChanged) Q_PROPERTY(bool shareKeysWithTrustedUsers READ shareKeysWithTrustedUsers WRITE setShareKeysWithTrustedUsers NOTIFY shareKeysWithTrustedUsersChanged) Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged) @@ -152,6 +154,7 @@ public: void setScreenShareRemoteVideo(bool state); void setScreenShareHideCursor(bool state); void setUseStunServer(bool state); + void setOnlyShareKeysWithVerifiedUsers(bool state); void setShareKeysWithTrustedUsers(bool state); void setProfile(QString profile); void setUserId(QString userId); @@ -208,6 +211,7 @@ public: bool screenShareHideCursor() const { return screenShareHideCursor_; } bool useStunServer() const { return useStunServer_; } bool shareKeysWithTrustedUsers() const { return shareKeysWithTrustedUsers_; } + bool onlyShareKeysWithVerifiedUsers() const { return onlyShareKeysWithVerifiedUsers_; } QString profile() const { return profile_; } QString userId() const { return userId_; } QString accessToken() const { return accessToken_; } @@ -252,6 +256,7 @@ signals: void screenShareRemoteVideoChanged(bool state); void screenShareHideCursorChanged(bool state); void useStunServerChanged(bool state); + void onlyShareKeysWithVerifiedUsersChanged(bool state); void shareKeysWithTrustedUsersChanged(bool state); void profileChanged(QString profile); void userIdChanged(QString userId); @@ -284,6 +289,7 @@ private: bool privacyScreen_; int privacyScreenTimeout_; bool shareKeysWithTrustedUsers_; + bool onlyShareKeysWithVerifiedUsers_; bool mobileMode_; int timelineMaxWidth_; int roomListWidth_; @@ -372,6 +378,7 @@ private: Toggle *privacyScreen_; QSpinBox *privacyScreenTimeout_; Toggle *shareKeysWithTrustedUsers_; + Toggle *onlyShareKeysWithVerifiedUsers_; Toggle *mobileMode_; QLabel *deviceFingerprintValue_; QLabel *deviceIdValue_; diff --git a/src/Utils.cpp b/src/Utils.cpp index 8d5ae4a9..41013e39 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -172,32 +172,6 @@ utils::scaleFactor() return settings.value("settings/scale_factor", -1).toFloat(); } -bool -utils::respondsToKeyRequests(const std::string &roomId) -{ - return respondsToKeyRequests(QString::fromStdString(roomId)); -} - -bool -utils::respondsToKeyRequests(const QString &roomId) -{ - if (roomId.isEmpty()) - return false; - - QSettings settings; - return settings.value("rooms/respond_to_key_requests/" + roomId, false).toBool(); -} - -void -utils::setKeyRequestsPreference(QString roomId, bool value) -{ - if (roomId.isEmpty()) - return; - - QSettings settings; - settings.setValue("rooms/respond_to_key_requests/" + roomId, value); -} - QString utils::descriptiveTime(const QDateTime &then) { @@ -556,7 +530,7 @@ utils::markdownToHtml(const QString &text, bool rainbowify) // Use colors as described here: // https://shark.comfsm.fm/~dleeling/cis/hsl_rainbow.html auto color = - QColor::fromHslF((charIdx - 1.0) / textLen * (5. / 6.), 1.0, 0.5); + QColor::fromHslF((charIdx - 1.0) / textLen * (5. / 6.), 0.9, 0.5); // format color for HTML auto colorString = color.name(QColor::NameFormat::HexRgb); // create HTML element for current char diff --git a/src/Utils.h b/src/Utils.h index 1d48e2c7..8f37a574 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -67,15 +67,6 @@ scaleFactor(); void setScaleFactor(float factor); -//! Whether or not we should respond to key requests for the given room. -bool -respondsToKeyRequests(const QString &roomId); -bool -respondsToKeyRequests(const std::string &roomId); - -void -setKeyRequestsPreference(QString roomId, bool value); - //! Human friendly timestamp representation. QString descriptiveTime(const QDateTime &then); diff --git a/src/dialogs/InviteUsers.cpp b/src/dialogs/InviteUsers.cpp deleted file mode 100644 index 9dd6085f..00000000 --- a/src/dialogs/InviteUsers.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QDebug> -#include <QIcon> -#include <QLabel> -#include <QListWidget> -#include <QListWidgetItem> -#include <QPushButton> -#include <QStyleOption> -#include <QTimer> -#include <QVBoxLayout> - -#include "dialogs/InviteUsers.h" - -#include "Config.h" -#include "InviteeItem.h" -#include "ui/TextField.h" - -#include <mtx/identifiers.hpp> - -using namespace dialogs; - -InviteUsers::InviteUsers(QWidget *parent) - : QFrame(parent) -{ - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose, true); - - setMinimumWidth(conf::window::minModalWidth); - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(conf::modals::WIDGET_SPACING); - layout->setMargin(conf::modals::WIDGET_MARGIN); - - auto buttonLayout = new QHBoxLayout(); - buttonLayout->setSpacing(0); - buttonLayout->setMargin(0); - - confirmBtn_ = new QPushButton("Invite", this); - confirmBtn_->setDefault(true); - cancelBtn_ = new QPushButton(tr("Cancel"), this); - - buttonLayout->addStretch(1); - buttonLayout->setSpacing(15); - buttonLayout->addWidget(cancelBtn_); - buttonLayout->addWidget(confirmBtn_); - - inviteeInput_ = new TextField(this); - inviteeInput_->setLabel(tr("User ID to invite")); - - inviteeList_ = new QListWidget; - inviteeList_->setFrameStyle(QFrame::NoFrame); - inviteeList_->setSelectionMode(QAbstractItemView::NoSelection); - inviteeList_->setAttribute(Qt::WA_MacShowFocusRect, 0); - inviteeList_->setSpacing(5); - - errorLabel_ = new QLabel(this); - errorLabel_->setAlignment(Qt::AlignCenter); - - layout->addWidget(inviteeInput_); - layout->addWidget(errorLabel_); - layout->addWidget(inviteeList_); - layout->addLayout(buttonLayout); - - connect(inviteeInput_, &TextField::returnPressed, this, &InviteUsers::addUser); - connect(confirmBtn_, &QPushButton::clicked, [this]() { - if (!inviteeInput_->text().trimmed().isEmpty()) { - addUser(); - } - - emit sendInvites(invitedUsers()); - - inviteeInput_->clear(); - inviteeList_->clear(); - errorLabel_->hide(); - - emit close(); - }); - - connect(cancelBtn_, &QPushButton::clicked, [this]() { - inviteeInput_->clear(); - inviteeList_->clear(); - errorLabel_->hide(); - - emit close(); - }); -} - -void -InviteUsers::addUser() -{ - auto user_id = inviteeInput_->text(); - - try { - namespace ids = mtx::identifiers; - auto user = ids::parse<ids::User>(user_id.toStdString()); - - auto item = new QListWidgetItem(inviteeList_); - auto invitee = new InviteeItem(user, this); - - item->setSizeHint(invitee->minimumSizeHint()); - item->setFlags(Qt::NoItemFlags); - item->setTextAlignment(Qt::AlignCenter); - - inviteeList_->setItemWidget(item, invitee); - - connect(invitee, &InviteeItem::removeItem, this, [this, item]() { - emit removeInvitee(item); - }); - - errorLabel_->hide(); - inviteeInput_->clear(); - } catch (std::exception &e) { - errorLabel_->setText(e.what()); - errorLabel_->show(); - } -} - -void -InviteUsers::removeInvitee(QListWidgetItem *item) -{ - int row = inviteeList_->row(item); - auto widget = inviteeList_->takeItem(row); - - inviteeList_->removeItemWidget(widget); -} - -QStringList -InviteUsers::invitedUsers() const -{ - QStringList users; - - for (int ii = 0; ii < inviteeList_->count(); ++ii) { - auto item = inviteeList_->item(ii); - auto widget = inviteeList_->itemWidget(item); - auto invitee = qobject_cast<InviteeItem *>(widget); - - if (invitee) - users << invitee->userID(); - else - qDebug() << "Cast InviteeItem failed"; - } - - return users; -} - -void -InviteUsers::showEvent(QShowEvent *event) -{ - inviteeInput_->setFocus(); - - QFrame::showEvent(event); -} diff --git a/src/dialogs/InviteUsers.h b/src/dialogs/InviteUsers.h deleted file mode 100644 index e40183c1..00000000 --- a/src/dialogs/InviteUsers.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QFrame> -#include <QStringList> - -class QPushButton; -class QLabel; -class TextField; -class QListWidget; -class QListWidgetItem; - -namespace dialogs { - -class InviteUsers : public QFrame -{ - Q_OBJECT -public: - explicit InviteUsers(QWidget *parent = nullptr); - -protected: - void showEvent(QShowEvent *event) override; - -signals: - void sendInvites(QStringList invitees); - -private slots: - void removeInvitee(QListWidgetItem *item); - -private: - void addUser(); - QStringList invitedUsers() const; - - QPushButton *confirmBtn_; - QPushButton *cancelBtn_; - - TextField *inviteeInput_; - QLabel *errorLabel_; - - QListWidget *inviteeList_; -}; -} // dialogs diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp deleted file mode 100644 index 21eb72b0..00000000 --- a/src/dialogs/MemberList.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QAbstractSlider> -#include <QLabel> -#include <QListWidgetItem> -#include <QPainter> -#include <QPushButton> -#include <QScrollBar> -#include <QShortcut> -#include <QStyleOption> -#include <QVBoxLayout> - -#include "dialogs/MemberList.h" - -#include "Cache.h" -#include "ChatPage.h" -#include "Config.h" -#include "Logging.h" -#include "Utils.h" -#include "ui/Avatar.h" - -using namespace dialogs; - -MemberItem::MemberItem(const RoomMember &member, QWidget *parent) - : QWidget(parent) -{ - topLayout_ = new QHBoxLayout(this); - topLayout_->setMargin(0); - - textLayout_ = new QVBoxLayout; - textLayout_->setMargin(0); - textLayout_->setSpacing(0); - - avatar_ = new Avatar(this, 44); - avatar_->setLetter(utils::firstChar(member.display_name)); - - avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id); - - QFont nameFont; - nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); - - userId_ = new QLabel(member.user_id, this); - userName_ = new QLabel(member.display_name, this); - userName_->setFont(nameFont); - - textLayout_->addWidget(userName_); - textLayout_->addWidget(userId_); - - topLayout_->addWidget(avatar_); - topLayout_->addLayout(textLayout_, 1); -} - -void -MemberItem::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -MemberList::MemberList(const QString &room_id, QWidget *parent) - : QFrame(parent) - , room_id_{room_id} -{ - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose, true); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(conf::modals::WIDGET_SPACING); - layout->setMargin(conf::modals::WIDGET_MARGIN); - - list_ = new QListWidget; - list_->setFrameStyle(QFrame::NoFrame); - list_->setSelectionMode(QAbstractItemView::NoSelection); - list_->setSpacing(5); - - QFont largeFont; - largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5); - - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - setMinimumHeight(list_->sizeHint().height() * 2); - setMinimumWidth(std::max(list_->sizeHint().width() + 4 * conf::modals::WIDGET_MARGIN, - QFontMetrics(largeFont).averageCharWidth() * 30 - - 2 * conf::modals::WIDGET_MARGIN)); - - QFont font; - font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO); - - topLabel_ = new QLabel(tr("Room members"), this); - topLabel_->setAlignment(Qt::AlignCenter); - topLabel_->setFont(font); - - auto okBtn = new QPushButton(tr("OK"), this); - - auto buttonLayout = new QHBoxLayout(); - buttonLayout->setSpacing(15); - buttonLayout->addStretch(1); - buttonLayout->addWidget(okBtn); - - layout->addWidget(topLabel_); - layout->addWidget(list_); - layout->addLayout(buttonLayout); - - list_->clear(); - - connect(list_->verticalScrollBar(), &QAbstractSlider::valueChanged, this, [this](int pos) { - if (pos != list_->verticalScrollBar()->maximum()) - return; - - const size_t numMembers = list_->count() - 1; - - if (numMembers > 0) - addUsers(cache::getMembers(room_id_.toStdString(), numMembers)); - }); - - try { - addUsers(cache::getMembers(room_id_.toStdString())); - } catch (const lmdb::error &e) { - nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); - } - - auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); - connect(closeShortcut, &QShortcut::activated, this, &MemberList::close); - connect(okBtn, &QPushButton::clicked, this, &MemberList::close); -} - -void -MemberList::addUsers(const std::vector<RoomMember> &members) -{ - for (const auto &member : members) { - auto user = new MemberItem(member, this); - auto item = new QListWidgetItem; - - item->setSizeHint(user->minimumSizeHint()); - item->setFlags(Qt::NoItemFlags); - item->setTextAlignment(Qt::AlignCenter); - - list_->insertItem(list_->count() - 1, item); - list_->setItemWidget(item, user); - } -} diff --git a/src/dialogs/MemberList.h b/src/dialogs/MemberList.h deleted file mode 100644 index b822eec8..00000000 --- a/src/dialogs/MemberList.h +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QFrame> -#include <QListWidget> - -class Avatar; -class QPushButton; -class QHBoxLayout; -class QLabel; -class QVBoxLayout; - -struct RoomMember; - -template<class T> -class QSharedPointer; - -namespace dialogs { - -class MemberItem : public QWidget -{ - Q_OBJECT - -public: - MemberItem(const RoomMember &member, QWidget *parent); - -protected: - void paintEvent(QPaintEvent *) override; - -private: - QHBoxLayout *topLayout_; - QVBoxLayout *textLayout_; - - Avatar *avatar_; - - QLabel *userName_; - QLabel *userId_; -}; - -class MemberList : public QFrame -{ - Q_OBJECT -public: - MemberList(const QString &room_id, QWidget *parent = nullptr); - -public slots: - void addUsers(const std::vector<RoomMember> &users); - -private: - QString room_id_; - QLabel *topLabel_; - QListWidget *list_; -}; -} // dialogs diff --git a/src/dialogs/RawMessage.h b/src/dialogs/RawMessage.h deleted file mode 100644 index e95f675c..00000000 --- a/src/dialogs/RawMessage.h +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QFont> -#include <QFontDatabase> -#include <QTextBrowser> -#include <QVBoxLayout> -#include <QWidget> - -#include "nlohmann/json.hpp" - -#include "Logging.h" -#include "MainWindow.h" -#include "ui/FlatButton.h" - -namespace dialogs { - -class RawMessage : public QWidget -{ - Q_OBJECT -public: - RawMessage(QString msg, QWidget *parent = nullptr) - : QWidget{parent} - { - QFont monospaceFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); - - auto layout = new QVBoxLayout{this}; - auto viewer = new QTextBrowser{this}; - viewer->setFont(monospaceFont); - viewer->setText(msg); - - layout->setSpacing(0); - layout->setMargin(0); - layout->addWidget(viewer); - - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setAttribute(Qt::WA_DeleteOnClose, true); - - QSize winsize; - QPoint center; - - auto window = MainWindow::instance(); - if (window) { - winsize = window->frameGeometry().size(); - center = window->frameGeometry().center(); - - move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); - } else { - nhlog::ui()->warn("unable to retrieve MainWindow's size"); - } - - raise(); - show(); - } -}; -} // namespace dialogs diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp deleted file mode 100644 index fa7132fd..00000000 --- a/src/dialogs/ReadReceipts.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QDebug> -#include <QIcon> -#include <QLabel> -#include <QListWidgetItem> -#include <QPainter> -#include <QPushButton> -#include <QShortcut> -#include <QStyleOption> -#include <QTimer> -#include <QVBoxLayout> - -#include "dialogs/ReadReceipts.h" - -#include "AvatarProvider.h" -#include "Cache.h" -#include "ChatPage.h" -#include "Config.h" -#include "Utils.h" -#include "ui/Avatar.h" - -using namespace dialogs; - -ReceiptItem::ReceiptItem(QWidget *parent, - const QString &user_id, - uint64_t timestamp, - const QString &room_id) - : QWidget(parent) -{ - topLayout_ = new QHBoxLayout(this); - topLayout_->setMargin(0); - - textLayout_ = new QVBoxLayout; - textLayout_->setMargin(0); - textLayout_->setSpacing(conf::modals::TEXT_SPACING); - - QFont nameFont; - nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); - - auto displayName = cache::displayName(room_id, user_id); - - avatar_ = new Avatar(this, 44); - avatar_->setLetter(utils::firstChar(displayName)); - - // If it's a matrix id we use the second letter. - if (displayName.size() > 1 && displayName.at(0) == '@') - avatar_->setLetter(QChar(displayName.at(1))); - - userName_ = new QLabel(displayName, this); - userName_->setFont(nameFont); - - timestamp_ = new QLabel(dateFormat(QDateTime::fromMSecsSinceEpoch(timestamp)), this); - - textLayout_->addWidget(userName_); - textLayout_->addWidget(timestamp_); - - topLayout_->addWidget(avatar_); - topLayout_->addLayout(textLayout_, 1); - - avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); -} - -void -ReceiptItem::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -QString -ReceiptItem::dateFormat(const QDateTime &then) const -{ - auto now = QDateTime::currentDateTime(); - auto days = then.daysTo(now); - - if (days == 0) - return tr("Today %1") - .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); - else if (days < 2) - return tr("Yesterday %1") - .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); - else if (days < 7) - return QString("%1 %2") - .arg(then.toString("dddd")) - .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); - - return QLocale::system().toString(then.time(), QLocale::ShortFormat); -} - -ReadReceipts::ReadReceipts(QWidget *parent) - : QFrame(parent) -{ - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose, true); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(conf::modals::WIDGET_SPACING); - layout->setMargin(conf::modals::WIDGET_MARGIN); - - userList_ = new QListWidget; - userList_->setFrameStyle(QFrame::NoFrame); - userList_->setSelectionMode(QAbstractItemView::NoSelection); - userList_->setSpacing(conf::modals::TEXT_SPACING); - - QFont largeFont; - largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5); - - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - setMinimumHeight(userList_->sizeHint().height() * 2); - setMinimumWidth(std::max(userList_->sizeHint().width() + 4 * conf::modals::WIDGET_MARGIN, - QFontMetrics(largeFont).averageCharWidth() * 30 - - 2 * conf::modals::WIDGET_MARGIN)); - - QFont font; - font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO); - - topLabel_ = new QLabel(tr("Read receipts"), this); - topLabel_->setAlignment(Qt::AlignCenter); - topLabel_->setFont(font); - - auto okBtn = new QPushButton(tr("Close"), this); - - auto buttonLayout = new QHBoxLayout(); - buttonLayout->setSpacing(15); - buttonLayout->addStretch(1); - buttonLayout->addWidget(okBtn); - - layout->addWidget(topLabel_); - layout->addWidget(userList_); - layout->addLayout(buttonLayout); - - auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); - connect(closeShortcut, &QShortcut::activated, this, &ReadReceipts::close); - connect(okBtn, &QPushButton::clicked, this, &ReadReceipts::close); -} - -void -ReadReceipts::addUsers(const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &receipts) -{ - // We want to remove any previous items that have been set. - userList_->clear(); - - for (const auto &receipt : receipts) { - auto user = new ReceiptItem(this, - QString::fromStdString(receipt.second), - receipt.first, - ChatPage::instance()->currentRoom()); - auto item = new QListWidgetItem(userList_); - - item->setSizeHint(user->minimumSizeHint()); - item->setFlags(Qt::NoItemFlags); - item->setTextAlignment(Qt::AlignCenter); - - userList_->setItemWidget(item, user); - } -} - -void -ReadReceipts::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void -ReadReceipts::hideEvent(QHideEvent *event) -{ - userList_->clear(); - QFrame::hideEvent(event); -} diff --git a/src/dialogs/ReadReceipts.h b/src/dialogs/ReadReceipts.h deleted file mode 100644 index 5c6c5d2b..00000000 --- a/src/dialogs/ReadReceipts.h +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QDateTime> -#include <QFrame> - -class Avatar; -class QLabel; -class QListWidget; -class QHBoxLayout; -class QVBoxLayout; - -namespace dialogs { - -class ReceiptItem : public QWidget -{ - Q_OBJECT - -public: - ReceiptItem(QWidget *parent, - const QString &user_id, - uint64_t timestamp, - const QString &room_id); - -protected: - void paintEvent(QPaintEvent *) override; - -private: - QString dateFormat(const QDateTime &then) const; - - QHBoxLayout *topLayout_; - QVBoxLayout *textLayout_; - - Avatar *avatar_; - - QLabel *userName_; - QLabel *timestamp_; -}; - -class ReadReceipts : public QFrame -{ - Q_OBJECT -public: - explicit ReadReceipts(QWidget *parent = nullptr); - -public slots: - void addUsers(const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &users); - -protected: - void paintEvent(QPaintEvent *event) override; - void hideEvent(QHideEvent *event) override; - -private: - QLabel *topLabel_; - - QListWidget *userList_; -}; -} // dialogs diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp index 598b2bd0..2809de87 100644 --- a/src/notifications/ManagerLinux.cpp +++ b/src/notifications/ManagerLinux.cpp @@ -295,12 +295,9 @@ operator<<(QDBusArgument &arg, const QImage &image) int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3); arg << i.depth() / channels; arg << channels; -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - arg << QByteArray(reinterpret_cast<const char *>(i.bits()), i.byteCount()); -#else arg << QByteArray(reinterpret_cast<const char *>(i.bits()), i.sizeInBytes()); -#endif arg.endStructure(); + return arg; } diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index 9a91ff79..742f8dbb 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -20,8 +20,7 @@ Q_DECLARE_METATYPE(Reaction) -QCache<EventStore::IdIndex, mtx::events::collections::TimelineEvents> EventStore::decryptedEvents_{ - 1000}; +QCache<EventStore::IdIndex, olm::DecryptionResult> EventStore::decryptedEvents_{1000}; QCache<EventStore::IdIndex, mtx::events::collections::TimelineEvents> EventStore::events_by_id_{ 1000}; QCache<EventStore::Index, mtx::events::collections::TimelineEvents> EventStore::events_{1000}; @@ -144,12 +143,16 @@ EventStore::EventStore(std::string room_id, QObject *) mtx::events::msg::Encrypted>) { auto event = decryptEvent({room_id_, e.event_id}, e); - if (auto dec = - std::get_if<mtx::events::RoomEvent< - mtx::events::msg:: - KeyVerificationRequest>>(event)) { - emit updateFlowEventId( - event_id.event_id.to_string()); + if (event->event) { + if (auto dec = std::get_if< + mtx::events::RoomEvent< + mtx::events::msg:: + KeyVerificationRequest>>( + &event->event.value())) { + emit updateFlowEventId( + event_id.event_id + .to_string()); + } } } }); @@ -393,12 +396,12 @@ EventStore::handleSync(const mtx::responses::Timeline &events) if (auto encrypted = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( &event)) { - mtx::events::collections::TimelineEvents *d_event = - decryptEvent({room_id_, encrypted->event_id}, *encrypted); - if (std::visit( + auto d_event = decryptEvent({room_id_, encrypted->event_id}, *encrypted); + if (d_event->event && + std::visit( [](auto e) { return (e.sender != utils::localUser().toStdString()); }, - *d_event)) { - handle_room_verification(*d_event); + *d_event->event)) { + handle_room_verification(*d_event->event); } } } @@ -599,11 +602,15 @@ EventStore::get(int idx, bool decrypt) events_.insert(index, event_ptr); } - if (decrypt) + if (decrypt) { if (auto encrypted = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( - event_ptr)) - return decryptEvent({room_id_, encrypted->event_id}, *encrypted); + event_ptr)) { + auto decrypted = decryptEvent({room_id_, encrypted->event_id}, *encrypted); + if (decrypted->event) + return &*decrypted->event; + } + } return event_ptr; } @@ -629,7 +636,7 @@ EventStore::indexToId(int idx) const return cache::client()->getTimelineEventId(room_id_, toInternalIdx(idx)); } -mtx::events::collections::TimelineEvents * +olm::DecryptionResult * EventStore::decryptEvent(const IdIndex &idx, const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e) { @@ -641,57 +648,24 @@ EventStore::decryptEvent(const IdIndex &idx, index.session_id = e.content.session_id; index.sender_key = e.content.sender_key; - auto asCacheEntry = [&idx](mtx::events::collections::TimelineEvents &&event) { - auto event_ptr = new mtx::events::collections::TimelineEvents(std::move(event)); + auto asCacheEntry = [&idx](olm::DecryptionResult &&event) { + auto event_ptr = new olm::DecryptionResult(std::move(event)); decryptedEvents_.insert(idx, event_ptr); return event_ptr; }; auto decryptionResult = olm::decryptEvent(index, e); - mtx::events::RoomEvent<mtx::events::msg::Notice> dummy; - dummy.origin_server_ts = e.origin_server_ts; - dummy.event_id = e.event_id; - dummy.sender = e.sender; - if (decryptionResult.error) { - switch (*decryptionResult.error) { + switch (decryptionResult.error) { case olm::DecryptionErrorCode::MissingSession: case olm::DecryptionErrorCode::MissingSessionIndex: { - if (decryptionResult.error == olm::DecryptionErrorCode::MissingSession) - dummy.content.body = - tr("-- Encrypted Event (No keys found for decryption) --", - "Placeholder, when the message was not decrypted yet or can't " - "be " - "decrypted.") - .toStdString(); - else - dummy.content.body = - tr("-- Encrypted Event (Key not valid for this index) --", - "Placeholder, when the message can't be decrypted with this " - "key since it is not valid for this index ") - .toStdString(); nhlog::crypto()->info("Could not find inbound megolm session ({}, {}, {})", index.room_id, index.session_id, e.sender); - // we may not want to request keys during initial sync and such - if (suppressKeyRequests) - break; - // TODO: Check if this actually works and look in key backup - auto copy = e; - copy.room_id = room_id_; - if (pending_key_requests.count(e.content.session_id)) { - pending_key_requests.at(e.content.session_id) - .events.push_back(copy); - } else { - PendingKeyRequests request; - request.request_id = - "key_request." + http::client()->generate_txn_id(); - request.events.push_back(copy); - olm::send_key_request_for(copy, request.request_id); - pending_key_requests[e.content.session_id] = request; - } + + requestSession(e, false); break; } case olm::DecryptionErrorCode::DbError: @@ -701,12 +675,6 @@ EventStore::decryptEvent(const IdIndex &idx, index.session_id, index.sender_key, decryptionResult.error_message.value_or("")); - dummy.content.body = - tr("-- Decryption Error (failed to retrieve megolm keys from db) --", - "Placeholder, when the message can't be decrypted, because the DB " - "access " - "failed.") - .toStdString(); break; case olm::DecryptionErrorCode::DecryptionFailed: nhlog::crypto()->critical( @@ -715,22 +683,8 @@ EventStore::decryptEvent(const IdIndex &idx, index.session_id, index.sender_key, decryptionResult.error_message.value_or("")); - dummy.content.body = - tr("-- Decryption Error (%1) --", - "Placeholder, when the message can't be decrypted. In this case, the " - "Olm " - "decrytion returned an error, which is passed as %1.") - .arg( - QString::fromStdString(decryptionResult.error_message.value_or(""))) - .toStdString(); break; case olm::DecryptionErrorCode::ParsingFailed: - dummy.content.body = - tr("-- Encrypted Event (Unknown event type) --", - "Placeholder, when the message was decrypted, but we couldn't parse " - "it, because " - "Nheko/mtxclient don't support that event type yet.") - .toStdString(); break; case olm::DecryptionErrorCode::ReplayAttack: nhlog::crypto()->critical( @@ -738,85 +692,50 @@ EventStore::decryptEvent(const IdIndex &idx, e.event_id, room_id_, index.sender_key); - dummy.content.body = - tr("-- Replay attack! This message index was reused! --").toStdString(); break; - case olm::DecryptionErrorCode::UnknownFingerprint: - // TODO: don't fail, just show in UI. - nhlog::crypto()->critical("Message by unverified fingerprint {}", - index.sender_key); - dummy.content.body = - tr("-- Message by unverified device! --").toStdString(); + case olm::DecryptionErrorCode::NoError: + // unreachable break; } - return asCacheEntry(std::move(dummy)); - } - - std::string msg_str; - try { - auto session = cache::client()->getInboundMegolmSession(index); - auto res = - olm::client()->decrypt_group_message(session.get(), e.content.ciphertext); - msg_str = std::string((char *)res.data.data(), res.data.size()); - } catch (const lmdb::error &e) { - nhlog::db()->critical("failed to retrieve megolm session with index ({}, {}, {})", - index.room_id, - index.session_id, - index.sender_key, - e.what()); - dummy.content.body = - tr("-- Decryption Error (failed to retrieve megolm keys from db) --", - "Placeholder, when the message can't be decrypted, because the DB " - "access " - "failed.") - .toStdString(); - return asCacheEntry(std::move(dummy)); - } catch (const mtx::crypto::olm_exception &e) { - nhlog::crypto()->critical("failed to decrypt message with index ({}, {}, {}): {}", - index.room_id, - index.session_id, - index.sender_key, - e.what()); - dummy.content.body = - tr("-- Decryption Error (%1) --", - "Placeholder, when the message can't be decrypted. In this case, the " - "Olm " - "decrytion returned an error, which is passed as %1.") - .arg(e.what()) - .toStdString(); - return asCacheEntry(std::move(dummy)); - } - - // Add missing fields for the event. - json body = json::parse(msg_str); - body["event_id"] = e.event_id; - body["sender"] = e.sender; - body["origin_server_ts"] = e.origin_server_ts; - body["unsigned"] = e.unsigned_data; - - // relations are unencrypted in content... - mtx::common::add_relations(body["content"], e.content.relations); - - json event_array = json::array(); - event_array.push_back(body); - - std::vector<mtx::events::collections::TimelineEvents> temp_events; - mtx::responses::utils::parse_timeline_events(event_array, temp_events); - - if (temp_events.size() == 1) { - auto encInfo = mtx::accessors::file(temp_events[0]); - - if (encInfo) - emit newEncryptedImage(encInfo.value()); - - return asCacheEntry(std::move(temp_events[0])); + return asCacheEntry(std::move(decryptionResult)); } auto encInfo = mtx::accessors::file(decryptionResult.event.value()); if (encInfo) emit newEncryptedImage(encInfo.value()); - return asCacheEntry(std::move(decryptionResult.event.value())); + return asCacheEntry(std::move(decryptionResult)); +} + +void +EventStore::requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &ev, + bool manual) +{ + // we may not want to request keys during initial sync and such + if (suppressKeyRequests) + return; + + // TODO: Look in key backup + auto copy = ev; + copy.room_id = room_id_; + if (pending_key_requests.count(ev.content.session_id)) { + auto &r = pending_key_requests.at(ev.content.session_id); + r.events.push_back(copy); + + // automatically request once every 10 min, manually every 1 min + qint64 delay = manual ? 60 : (60 * 10); + if (r.requested_at + delay < QDateTime::currentSecsSinceEpoch()) { + r.requested_at = QDateTime::currentSecsSinceEpoch(); + olm::send_key_request_for(copy, r.request_id); + } + } else { + PendingKeyRequests request; + request.request_id = "key_request." + http::client()->generate_txn_id(); + request.requested_at = QDateTime::currentSecsSinceEpoch(); + request.events.push_back(copy); + olm::send_key_request_for(copy, request.request_id); + pending_key_requests[ev.content.session_id] = request; + } } void @@ -877,15 +796,56 @@ EventStore::get(std::string id, std::string_view related_to, bool decrypt, bool events_by_id_.insert(index, event_ptr); } - if (decrypt) + if (decrypt) { if (auto encrypted = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( - event_ptr)) - return decryptEvent(index, *encrypted); + event_ptr)) { + auto decrypted = decryptEvent(index, *encrypted); + if (decrypted->event) + return &*decrypted->event; + } + } return event_ptr; } +olm::DecryptionErrorCode +EventStore::decryptionError(std::string id) +{ + if (this->thread() != QThread::currentThread()) + nhlog::db()->warn("{} called from a different thread!", __func__); + + if (id.empty()) + return olm::DecryptionErrorCode::NoError; + + IdIndex index{room_id_, std::move(id)}; + auto edits_ = edits(index.id); + if (!edits_.empty()) { + index.id = mtx::accessors::event_id(edits_.back()); + auto event_ptr = + new mtx::events::collections::TimelineEvents(std::move(edits_.back())); + events_by_id_.insert(index, event_ptr); + } + + auto event_ptr = events_by_id_.object(index); + if (!event_ptr) { + auto event = cache::client()->getEvent(room_id_, index.id); + if (!event) { + return olm::DecryptionErrorCode::NoError; + } + event_ptr = new mtx::events::collections::TimelineEvents(std::move(event->data)); + events_by_id_.insert(index, event_ptr); + } + + if (auto encrypted = + std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(event_ptr)) { + auto decrypted = decryptEvent(index, *encrypted); + return decrypted->error; + } + + return olm::DecryptionErrorCode::NoError; +} + void EventStore::fetchMore() { diff --git a/src/timeline/EventStore.h b/src/timeline/EventStore.h index 7c404102..59c1c7c0 100644 --- a/src/timeline/EventStore.h +++ b/src/timeline/EventStore.h @@ -15,6 +15,7 @@ #include <mtx/responses/messages.hpp> #include <mtx/responses/sync.hpp> +#include "Olm.h" #include "Reaction.h" class EventStore : public QObject @@ -78,6 +79,9 @@ public: mtx::events::collections::TimelineEvents *get(int idx, bool decrypt = true); QVariantList reactions(const std::string &event_id); + olm::DecryptionErrorCode decryptionError(std::string id); + void requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &ev, + bool manual); int size() const { @@ -119,7 +123,7 @@ public slots: private: std::vector<mtx::events::collections::TimelineEvents> edits(const std::string &event_id); - mtx::events::collections::TimelineEvents *decryptEvent( + olm::DecryptionResult *decryptEvent( const IdIndex &idx, const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e); void handle_room_verification(mtx::events::collections::TimelineEvents event); @@ -129,7 +133,7 @@ private: uint64_t first = std::numeric_limits<uint64_t>::max(), last = std::numeric_limits<uint64_t>::max(); - static QCache<IdIndex, mtx::events::collections::TimelineEvents> decryptedEvents_; + static QCache<IdIndex, olm::DecryptionResult> decryptedEvents_; static QCache<Index, mtx::events::collections::TimelineEvents> events_; static QCache<IdIndex, mtx::events::collections::TimelineEvents> events_by_id_; @@ -137,6 +141,7 @@ private: { std::string request_id; std::vector<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>> events; + qint64 requested_at; }; std::map<std::string, PendingKeyRequests> pending_key_requests; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index 56d0d1ce..f17081e5 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -19,9 +19,9 @@ #include "Cache.h" #include "ChatPage.h" +#include "CombinedImagePackModel.h" #include "CompletionProxyModel.h" #include "Config.h" -#include "ImagePackModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" @@ -503,7 +503,7 @@ InputBar::video(const QString &filename, } void -InputBar::sticker(ImagePackModel *model, int row) +InputBar::sticker(CombinedImagePackModel *model, int row) { if (!model || row < 0) return; diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index acedceb7..2e6fb5c0 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -12,7 +12,7 @@ #include <mtx/responses/messages.hpp> class TimelineModel; -class ImagePackModel; +class CombinedImagePackModel; class QMimeData; class QDropEvent; class QStringList; @@ -58,7 +58,7 @@ public slots: MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED, bool rainbowify = false); void reaction(const QString &reactedEvent, const QString &reactionKey); - void sticker(ImagePackModel *model, int row); + void sticker(CombinedImagePackModel *model, int row); private slots: void startTyping(); diff --git a/src/timeline/Permissions.cpp b/src/timeline/Permissions.cpp index 1eaab468..e4957045 100644 --- a/src/timeline/Permissions.cpp +++ b/src/timeline/Permissions.cpp @@ -8,9 +8,9 @@ #include "MatrixClient.h" #include "TimelineModel.h" -Permissions::Permissions(TimelineModel *parent) +Permissions::Permissions(QString roomId, QObject *parent) : QObject(parent) - , room(parent) + , roomId_(roomId) { invalidate(); } @@ -19,7 +19,7 @@ void Permissions::invalidate() { pl = cache::client() - ->getStateEvent<mtx::events::state::PowerLevels>(room->roomId().toStdString()) + ->getStateEvent<mtx::events::state::PowerLevels>(roomId_.toStdString()) .value_or(mtx::events::StateEvent<mtx::events::state::PowerLevels>{}) .content; } diff --git a/src/timeline/Permissions.h b/src/timeline/Permissions.h index f7e6f389..7aab1ddb 100644 --- a/src/timeline/Permissions.h +++ b/src/timeline/Permissions.h @@ -15,7 +15,7 @@ class Permissions : public QObject Q_OBJECT public: - Permissions(TimelineModel *parent); + Permissions(QString roomId, QObject *parent = nullptr); Q_INVOKABLE bool canInvite(); Q_INVOKABLE bool canBan(); @@ -28,6 +28,6 @@ public: void invalidate(); private: - TimelineModel *room; + QString roomId_; mtx::events::state::PowerLevels pl; }; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index f7f377fb..f4c927ac 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -533,6 +533,8 @@ RoomlistModel::initializeRooms() for (const auto &id : cache::client()->roomIds()) addRoom(id, true); + nhlog::db()->info("Restored {} rooms from cache", rowCount()); + endResetModel(); } diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index abfe28a9..99e00a67 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -25,11 +25,12 @@ #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" +#include "MemberList.h" #include "MxcImageProvider.h" #include "Olm.h" +#include "ReadReceiptsModel.h" #include "TimelineViewManager.h" #include "Utils.h" -#include "dialogs/RawMessage.h" Q_DECLARE_METATYPE(QModelIndex) @@ -307,6 +308,15 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t) case qml_mtx_events::KeyVerificationDone: case qml_mtx_events::KeyVerificationReady: return mtx::events::EventType::RoomMessage; + //! m.image_pack, currently im.ponies.room_emotes + case qml_mtx_events::ImagePackInRoom: + return mtx::events::EventType::ImagePackRooms; + //! m.image_pack, currently im.ponies.user_emotes + case qml_mtx_events::ImagePackInAccountData: + return mtx::events::EventType::ImagePackInAccountData; + //! m.image_pack.rooms, currently im.ponies.emote_rooms + case qml_mtx_events::ImagePackRooms: + return mtx::events::EventType::ImagePackRooms; default: return mtx::events::EventType::Unsupported; }; @@ -317,6 +327,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj , events(room_id.toStdString(), this) , room_id_(room_id) , manager_(manager) + , permissions_{room_id} { lastMessage_.timestamp = 0; @@ -325,6 +336,10 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj this->isSpace_ = create->content.type == mtx::events::state::room_type::space; this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); + // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it + // needs to be + connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged); + connect( this, &TimelineModel::redactionFailed, @@ -344,6 +359,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj &EventStore::dataChanged, this, [this](int from, int to) { + relatedEventCacheBuster++; nhlog::ui()->debug( "data changed {} to {}", events.size() - to - 1, events.size() - from - 1); emit dataChanged(index(events.size() - to - 1, 0), @@ -436,6 +452,7 @@ TimelineModel::roleNames() const {IsEditable, "isEditable"}, {IsEncrypted, "isEncrypted"}, {Trustlevel, "trustlevel"}, + {EncryptionError, "encryptionError"}, {ReplyTo, "replyTo"}, {Reactions, "reactions"}, {RoomId, "roomId"}, @@ -443,6 +460,7 @@ TimelineModel::roleNames() const {RoomTopic, "roomTopic"}, {CallType, "callType"}, {Dump, "dump"}, + {RelatedEventCacheBuster, "relatedEventCacheBuster"}, }; } int @@ -622,6 +640,9 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r return crypto::Trust::Unverified; } + case EncryptionError: + return events.decryptionError(event_id(event)); + case ReplyTo: return QVariant(QString::fromStdString(relations(event).reply_to().value_or(""))); case Reactions: { @@ -673,9 +694,12 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r m.insert(names[RoomName], data(event, static_cast<int>(RoomName))); m.insert(names[RoomTopic], data(event, static_cast<int>(RoomTopic))); m.insert(names[CallType], data(event, static_cast<int>(CallType))); + m.insert(names[EncryptionError], data(event, static_cast<int>(EncryptionError))); return QVariant(m); } + case RelatedEventCacheBuster: + return relatedEventCacheBuster; default: return QVariant(); } @@ -1015,14 +1039,13 @@ TimelineModel::formatDateSeparator(QDate date) const } void -TimelineModel::viewRawMessage(QString id) const +TimelineModel::viewRawMessage(QString id) { auto e = events.get(id.toStdString(), "", false); if (!e) return; std::string ev = mtx::accessors::serialize_event(*e).dump(4); - auto dialog = new dialogs::RawMessage(QString::fromStdString(ev)); - Q_UNUSED(dialog); + emit showRawMessageDialog(QString::fromStdString(ev)); } void @@ -1036,15 +1059,14 @@ TimelineModel::forwardMessage(QString eventId, QString roomId) } void -TimelineModel::viewDecryptedRawMessage(QString id) const +TimelineModel::viewDecryptedRawMessage(QString id) { auto e = events.get(id.toStdString(), ""); if (!e) return; std::string ev = mtx::accessors::serialize_event(*e).dump(4); - auto dialog = new dialogs::RawMessage(QString::fromStdString(ev)); - Q_UNUSED(dialog); + emit showRawMessageDialog(QString::fromStdString(ev)); } void @@ -1057,14 +1079,6 @@ TimelineModel::openUserProfile(QString userid) } void -TimelineModel::openRoomSettings() -{ - RoomSettings *settings = new RoomSettings(roomId(), this); - connect(this, &TimelineModel::roomAvatarUrlChanged, settings, &RoomSettings::avatarChanged); - openRoomSettingsDialog(settings); -} - -void TimelineModel::replyAction(QString id) { setReply(id); @@ -1087,9 +1101,9 @@ TimelineModel::relatedInfo(QString id) } void -TimelineModel::readReceiptsAction(QString id) const +TimelineModel::showReadReceipts(QString id) { - MainWindow::instance()->openReadReceiptsDialog(id); + emit openReadReceiptsDialog(new ReadReceiptsProxy{id, roomId(), this}); } void @@ -1543,6 +1557,17 @@ TimelineModel::scrollTimerEvent() } void +TimelineModel::requestKeyForEvent(QString id) +{ + auto encrypted_event = events.get(id.toStdString(), "", false); + if (encrypted_event) { + if (auto ev = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( + encrypted_event)) + events.requestSession(*ev, true); + } +} + +void TimelineModel::copyLinkToEvent(QString eventId) const { QStringList vias; diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0e2895d4..ad7cfbbb 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -17,7 +17,10 @@ #include "CacheStructs.h" #include "EventStore.h" #include "InputBar.h" +#include "InviteesModel.h" +#include "MemberList.h" #include "Permissions.h" +#include "ReadReceiptsModel.h" #include "ui/RoomSettings.h" #include "ui/UserProfile.h" @@ -104,7 +107,13 @@ enum EventType KeyVerificationCancel, KeyVerificationKey, KeyVerificationDone, - KeyVerificationReady + KeyVerificationReady, + //! m.image_pack, currently im.ponies.room_emotes + ImagePackInRoom, + //! m.image_pack, currently im.ponies.user_emotes + ImagePackInAccountData, + //! m.image_pack.rooms, currently im.ponies.emote_rooms + ImagePackRooms, }; Q_ENUM_NS(EventType) mtx::events::EventType fromRoomEventType(qml_mtx_events::EventType); @@ -158,7 +167,9 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString edit READ edit WRITE setEdit NOTIFY editChanged RESET resetEdit) Q_PROPERTY( bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) + Q_PROPERTY(QString roomId READ roomId CONSTANT) Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY plainRoomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) @@ -201,6 +212,7 @@ public: IsEditable, IsEncrypted, Trustlevel, + EncryptionError, ReplyTo, Reactions, RoomId, @@ -208,6 +220,7 @@ public: RoomTopic, CallType, Dump, + RelatedEventCacheBuster, }; Q_ENUM(Roles); @@ -230,14 +243,13 @@ public: Q_INVOKABLE QString formatGuestAccessEvent(QString id); Q_INVOKABLE QString formatPowerLevelEvent(QString id); - Q_INVOKABLE void viewRawMessage(QString id) const; + Q_INVOKABLE void viewRawMessage(QString id); Q_INVOKABLE void forwardMessage(QString eventId, QString roomId); - Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; + Q_INVOKABLE void viewDecryptedRawMessage(QString id); Q_INVOKABLE void openUserProfile(QString userid); - Q_INVOKABLE void openRoomSettings(); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); - Q_INVOKABLE void readReceiptsAction(QString id) const; + Q_INVOKABLE void showReadReceipts(QString id); Q_INVOKABLE void redactEvent(QString id); Q_INVOKABLE int idToIndex(QString id) const; Q_INVOKABLE QString indexToId(int index) const; @@ -253,6 +265,8 @@ public: endResetModel(); } + Q_INVOKABLE void requestKeyForEvent(QString id); + std::vector<::Reaction> reactions(const std::string &event_id) { auto list = events.reactions(event_id); @@ -344,6 +358,8 @@ signals: void typingUsersChanged(std::vector<QString> users); void replyChanged(QString reply); void editChanged(QString reply); + void openReadReceiptsDialog(ReadReceiptsProxy *rr); + void showRawMessageDialog(QString rawMessage); void paginationInProgressChanged(const bool); void newCallEvent(const mtx::events::collections::TimelineEvents &event); void scrollToIndex(int index); @@ -351,14 +367,13 @@ signals: void lastMessageChanged(); void notificationsChanged(); - void openRoomSettingsDialog(RoomSettings *settings); - void newMessageToSend(mtx::events::collections::TimelineEvents event); void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void updateFlowEventId(std::string event_id); void encryptionChanged(); void roomNameChanged(); + void plainRoomNameChanged(); void roomTopicChanged(); void roomAvatarUrlChanged(); void roomMemberCountChanged(); @@ -388,7 +403,7 @@ private: TimelineViewManager *manager_; InputBar input_{this}; - Permissions permissions_{this}; + Permissions permissions_; QTimer showEventTimer{this}; QString eventIdToShow; @@ -400,6 +415,8 @@ private: int notification_count = 0, highlight_count = 0; + unsigned int relatedEventCacheBuster = 0; + bool decryptDescription = true; bool m_paginationInProgress = false; bool isSpace_ = false; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 3e69f92b..b23ed278 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -15,16 +15,20 @@ #include "ChatPage.h" #include "Clipboard.h" #include "ColorImageProvider.h" +#include "CombinedImagePackModel.h" #include "CompletionProxyModel.h" #include "DelegateChooser.h" #include "DeviceVerificationFlow.h" #include "EventAccessors.h" -#include "ImagePackModel.h" +#include "ImagePackListModel.h" +#include "InviteesModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" +#include "ReadReceiptsModel.h" #include "RoomsModel.h" +#include "SingleImagePackModel.h" #include "UserSettingsPage.h" #include "UsersModel.h" #include "dialogs/ImageOverlay.h" @@ -145,7 +149,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par qRegisterMetaType<mtx::events::msg::KeyVerificationReady>(); qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>(); qRegisterMetaType<mtx::events::msg::KeyVerificationStart>(); - qRegisterMetaType<ImagePackModel *>(); + qRegisterMetaType<CombinedImagePackModel *>(); qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, "im.nheko", @@ -154,6 +158,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "MtxEvent", "Can't instantiate enum!"); qmlRegisterUncreatableMetaObject( + olm::staticMetaObject, "im.nheko", 1, 0, "Olm", "Can't instantiate enum!"); + qmlRegisterUncreatableMetaObject( crypto::staticMetaObject, "im.nheko", 1, 0, "Crypto", "Can't instantiate enum!"); qmlRegisterUncreatableMetaObject(verification::staticMetaObject, "im.nheko", @@ -174,6 +180,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par 0, "UserProfileModel", "UserProfile needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType<MemberList>( + "im.nheko", 1, 0, "MemberList", "MemberList needs to be instantiated on the C++ side"); qmlRegisterUncreatableType<RoomSettings>( "im.nheko", 1, @@ -182,6 +190,30 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "Room Settings needs to be instantiated on the C++ side"); qmlRegisterUncreatableType<TimelineModel>( "im.nheko", 1, 0, "Room", "Room needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType<ImagePackListModel>( + "im.nheko", + 1, + 0, + "ImagePackListModel", + "ImagePackListModel needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType<SingleImagePackModel>( + "im.nheko", + 1, + 0, + "SingleImagePackModel", + "SingleImagePackModel needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType<InviteesModel>( + "im.nheko", + 1, + 0, + "InviteesModel", + "InviteesModel needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType<ReadReceiptsProxy>( + "im.nheko", + 1, + 0, + "ReadReceiptsProxy", + "ReadReceiptsProxy needs to be instantiated on the C++ side"); static auto self = this; qmlRegisterSingletonType<MainWindow>( @@ -343,6 +375,41 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par } void +TimelineViewManager::openRoomMembers(QString room_id) +{ + MemberList *memberList = new MemberList(room_id, this); + emit openRoomMembersDialog(memberList); +} + +void +TimelineViewManager::openRoomSettings(QString room_id) +{ + RoomSettings *settings = new RoomSettings(room_id, this); + connect(rooms_->getRoomById(room_id).data(), + &TimelineModel::roomAvatarUrlChanged, + settings, + &RoomSettings::avatarChanged); + emit openRoomSettingsDialog(settings); +} + +void +TimelineViewManager::openInviteUsers(QString roomId) +{ + InviteesModel *model = new InviteesModel{this}; + connect(model, &InviteesModel::accept, this, [this, model, roomId]() { + emit inviteUsers(roomId, model->mxids()); + }); + emit openInviteUsersDialog(model); +} + +void +TimelineViewManager::openGlobalUserProfile(QString userId) +{ + UserProfile *profile = new UserProfile{QString{}, userId, this}; + emit openProfile(profile); +} + +void TimelineViewManager::setVideoCallItem() { WebRTCSession::instance().setVideoItem( @@ -400,6 +467,12 @@ TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) } void +TimelineViewManager::openImagePackSettings(QString roomid) +{ + emit showImagePackSettings(new ImagePackListModel(roomid.toStdString(), this)); +} + +void TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) { auto pixmap = QPixmap::fromImage(img); @@ -422,17 +495,6 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) } void -TimelineViewManager::openInviteUsersDialog() -{ - MainWindow::instance()->openInviteUsersDialog( - [this](const QStringList &invitees) { emit inviteUsers(invitees); }); -} -void -TimelineViewManager::openMemberListDialog(QString roomid) const -{ - MainWindow::instance()->openMemberListDialog(roomid); -} -void TimelineViewManager::openLeaveRoomDialog(QString roomid) const { MainWindow::instance()->openLeaveRoomDialog(roomid); @@ -596,7 +658,7 @@ TimelineViewManager::completerFor(QString completerName, QString roomId) roomModel->setParent(proxy); return proxy; } else if (completerName == "stickers") { - auto stickerModel = new ImagePackModel(roomId.toStdString(), true); + auto stickerModel = new CombinedImagePackModel(roomId.toStdString(), true); auto proxy = new CompletionProxyModel(stickerModel, 1, static_cast<size_t>(-1) / 4); stickerModel->setParent(proxy); return proxy; diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 15b4f523..54e3a935 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -33,6 +33,7 @@ class ColorImageProvider; class UserSettings; class ChatPage; class DeviceVerificationFlow; +class ImagePackListModel; class TimelineViewManager : public QObject { @@ -57,6 +58,7 @@ public: Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } bool isWindowFocused() const { return isWindowFocused_; } Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId); + Q_INVOKABLE void openImagePackSettings(QString roomid); Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString htmlEscape(QString str) const { return str.toHtmlEscaped(); } @@ -64,9 +66,12 @@ public: Q_INVOKABLE QString userPresence(QString id) const; Q_INVOKABLE QString userStatus(QString id) const; + Q_INVOKABLE void openRoomMembers(QString room_id); + Q_INVOKABLE void openRoomSettings(QString room_id); + Q_INVOKABLE void openInviteUsers(QString roomId); + Q_INVOKABLE void openGlobalUserProfile(QString userId); + Q_INVOKABLE void focusMessageInput(); - Q_INVOKABLE void openInviteUsersDialog(); - Q_INVOKABLE void openMemberListDialog(QString roomid) const; Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); @@ -81,11 +86,17 @@ signals: void replyingEventChanged(QString replyingEvent); void replyClosed(); void newDeviceVerificationRequest(DeviceVerificationFlow *flow); - void inviteUsers(QStringList users); + void inviteUsers(QString roomId, QStringList users); + void showRoomList(); + void narrowViewChanged(); void focusChanged(); void focusInput(); void openImageOverlayInternalCb(QString eventId, QImage img); + void openRoomMembersDialog(MemberList *members); + void openRoomSettingsDialog(RoomSettings *settings); + void openInviteUsersDialog(InviteesModel *invitees); void openProfile(UserProfile *profile); + void showImagePackSettings(ImagePackListModel *packlist); public slots: void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids); diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp deleted file mode 100644 index 154a0e2c..00000000 --- a/src/ui/Avatar.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QPainter> -#include <QPainterPath> -#include <QSettings> - -#include "AvatarProvider.h" -#include "Utils.h" -#include "ui/Avatar.h" - -Avatar::Avatar(QWidget *parent, int size) - : QWidget(parent) - , size_(size) -{ - type_ = ui::AvatarType::Letter; - letter_ = "A"; - - QFont _font(font()); - _font.setPointSizeF(ui::FontSize); - setFont(_font); - - QSizePolicy policy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - setSizePolicy(policy); -} - -QColor -Avatar::textColor() const -{ - if (!text_color_.isValid()) - return QColor("black"); - - return text_color_; -} - -QColor -Avatar::backgroundColor() const -{ - if (!text_color_.isValid()) - return QColor("white"); - - return background_color_; -} - -QSize -Avatar::sizeHint() const -{ - return QSize(size_ + 2, size_ + 2); -} - -void -Avatar::setTextColor(const QColor &color) -{ - text_color_ = color; -} - -void -Avatar::setBackgroundColor(const QColor &color) -{ - background_color_ = color; -} - -void -Avatar::setLetter(const QString &letter) -{ - letter_ = letter; - type_ = ui::AvatarType::Letter; - update(); -} - -void -Avatar::setImage(const QString &avatar_url) -{ - avatar_url_ = avatar_url; - AvatarProvider::resolve(avatar_url, - static_cast<int>(size_ * pixmap_.devicePixelRatio()), - this, - [this, requestedRatio = pixmap_.devicePixelRatio()](QPixmap pm) { - if (pm.isNull()) - return; - type_ = ui::AvatarType::Image; - pixmap_ = pm; - pixmap_.setDevicePixelRatio(requestedRatio); - update(); - }); -} - -void -Avatar::setImage(const QString &room, const QString &user) -{ - room_ = room; - user_ = user; - AvatarProvider::resolve(room, - user, - static_cast<int>(size_ * pixmap_.devicePixelRatio()), - this, - [this, requestedRatio = pixmap_.devicePixelRatio()](QPixmap pm) { - if (pm.isNull()) - return; - type_ = ui::AvatarType::Image; - pixmap_ = pm; - pixmap_.setDevicePixelRatio(requestedRatio); - update(); - }); -} - -void -Avatar::setDevicePixelRatio(double ratio) -{ - if (type_ == ui::AvatarType::Image && abs(pixmap_.devicePixelRatio() - ratio) > 0.01) { - pixmap_ = pixmap_.scaled(QSize(size_, size_) * ratio); - pixmap_.setDevicePixelRatio(ratio); - - if (!avatar_url_.isEmpty()) - setImage(avatar_url_); - else - setImage(room_, user_); - } -} - -void -Avatar::paintEvent(QPaintEvent *) -{ - bool rounded = QSettings().value(QStringLiteral("user/avatar_circles"), true).toBool(); - - QPainter painter(this); - - painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | - QPainter::TextAntialiasing); - - QRectF r = rect(); - const int hs = size_ / 2; - - if (type_ != ui::AvatarType::Image) { - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(backgroundColor()); - - painter.setPen(Qt::NoPen); - painter.setBrush(brush); - rounded ? painter.drawEllipse(r) : painter.drawRoundedRect(r, 3, 3); - } else if (painter.isActive()) { - setDevicePixelRatio(painter.device()->devicePixelRatioF()); - } - - switch (type_) { - case ui::AvatarType::Image: { - QPainterPath ppath; - - rounded ? ppath.addEllipse(width() / 2 - hs, height() / 2 - hs, size_, size_) - : ppath.addRoundedRect(r, 3, 3); - - painter.setClipPath(ppath); - painter.drawPixmap(QRect(width() / 2 - hs, height() / 2 - hs, size_, size_), - pixmap_); - break; - } - case ui::AvatarType::Letter: { - painter.setPen(textColor()); - painter.setBrush(Qt::NoBrush); - painter.drawText(r.translated(0, -1), Qt::AlignCenter, letter_); - break; - } - default: - break; - } -} diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h deleted file mode 100644 index bbf05be3..00000000 --- a/src/ui/Avatar.h +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QImage> -#include <QPixmap> -#include <QWidget> - -#include "Theme.h" - -class Avatar : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - -public: - explicit Avatar(QWidget *parent = nullptr, int size = ui::AvatarSize); - - void setBackgroundColor(const QColor &color); - void setImage(const QString &avatar_url); - void setImage(const QString &room, const QString &user); - void setLetter(const QString &letter); - void setTextColor(const QColor &color); - void setDevicePixelRatio(double ratio); - - QColor backgroundColor() const; - QColor textColor() const; - - QSize sizeHint() const override; - -protected: - void paintEvent(QPaintEvent *event) override; - -private: - void init(); - - ui::AvatarType type_; - QString letter_; - QString avatar_url_, room_, user_; - QColor background_color_; - QColor text_color_; - QPixmap pixmap_; - int size_; -}; diff --git a/src/ui/InfoMessage.cpp b/src/ui/InfoMessage.cpp index fb3b306a..ebe0e63f 100644 --- a/src/ui/InfoMessage.cpp +++ b/src/ui/InfoMessage.cpp @@ -29,13 +29,7 @@ InfoMessage::InfoMessage(QString msg, QWidget *parent) initFont(); QFontMetrics fm{font()}; -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - // width deprecated in 5.13 - width_ = fm.width(msg_) + HPadding * 2; -#else - width_ = fm.horizontalAdvance(msg_) + HPadding * 2; -#endif - + width_ = fm.horizontalAdvance(msg_) + HPadding * 2; height_ = fm.ascent() + 2 * VPadding; setFixedHeight(height_ + 2 * HMargin); @@ -77,12 +71,7 @@ DateSeparator::DateSeparator(QDateTime datetime, QWidget *parent) msg_ = datetime.date().toString(fmt); QFontMetrics fm{font()}; -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - // width deprecated in 5.13 - width_ = fm.width(msg_) + HPadding * 2; -#else - width_ = fm.horizontalAdvance(msg_) + HPadding * 2; -#endif + width_ = fm.horizontalAdvance(msg_) + HPadding * 2; height_ = fm.ascent() + 2 * VPadding; setFixedHeight(height_ + 2 * HMargin); diff --git a/src/ui/NhekoGlobalObject.cpp b/src/ui/NhekoGlobalObject.cpp index fea10839..9e0d706b 100644 --- a/src/ui/NhekoGlobalObject.cpp +++ b/src/ui/NhekoGlobalObject.cpp @@ -6,6 +6,7 @@ #include <QDesktopServices> #include <QUrl> +#include <QWindow> #include "Cache_p.h" #include "ChatPage.h" @@ -140,3 +141,9 @@ Nheko::openJoinRoomDialog() const MainWindow::instance()->openJoinRoomDialog( [](const QString &room_id) { ChatPage::instance()->joinRoom(room_id); }); } + +void +Nheko::reparent(QWindow *win) const +{ + win->setTransientParent(MainWindow::instance()->windowHandle()); +} diff --git a/src/ui/NhekoGlobalObject.h b/src/ui/NhekoGlobalObject.h index 14135fd1..d4d119dc 100644 --- a/src/ui/NhekoGlobalObject.h +++ b/src/ui/NhekoGlobalObject.h @@ -4,12 +4,15 @@ #pragma once +#include <QFontDatabase> #include <QObject> #include <QPalette> #include "Theme.h" #include "UserProfile.h" +class QWindow; + class Nheko : public QObject { Q_OBJECT @@ -38,12 +41,17 @@ public: int paddingLarge() const { return 20; } UserProfile *currentUser() const; + Q_INVOKABLE QFont monospaceFont() const + { + return QFontDatabase::systemFont(QFontDatabase::FixedFont); + } Q_INVOKABLE void openLink(QString link) const; Q_INVOKABLE void setStatusMessage(QString msg) const; Q_INVOKABLE void showUserSettingsPage() const; Q_INVOKABLE void openLogoutDialog() const; Q_INVOKABLE void openCreateRoomDialog() const; Q_INVOKABLE void openJoinRoomDialog() const; + Q_INVOKABLE void reparent(QWindow *win) const; public slots: void updateUserProfile(); diff --git a/src/ui/Painter.h b/src/ui/Painter.h index 3353f0c7..9f974116 100644 --- a/src/ui/Painter.h +++ b/src/ui/Painter.h @@ -27,12 +27,7 @@ public: { QFontMetrics m(fontMetrics()); if (textWidth < 0) { -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - // deprecated in 5.13: - textWidth = m.width(text); -#else textWidth = m.horizontalAdvance(text); -#endif } drawText((outerw - x - textWidth), y + m.ascent(), text); } diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp index f78ef09b..fcba8205 100644 --- a/src/ui/RoomSettings.cpp +++ b/src/ui/RoomSettings.cpp @@ -291,19 +291,6 @@ RoomSettings::accessJoinRules() return accessRules_; } -bool -RoomSettings::respondsToKeyRequests() -{ - return usesEncryption_ && utils::respondsToKeyRequests(roomid_); -} - -void -RoomSettings::changeKeyRequestsPreference(bool isOn) -{ - utils::setKeyRequestsPreference(roomid_, isOn); - emit keyRequestsChanged(); -} - void RoomSettings::enableEncryption() { diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h index 367f3111..1c8b47d6 100644 --- a/src/ui/RoomSettings.h +++ b/src/ui/RoomSettings.h @@ -78,7 +78,6 @@ class RoomSettings : public QObject Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT) Q_PROPERTY(bool canChangeNameAndTopic READ canChangeNameAndTopic CONSTANT) Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged) - Q_PROPERTY(bool respondsToKeyRequests READ respondsToKeyRequests NOTIFY keyRequestsChanged) public: RoomSettings(QString roomid, QObject *parent = nullptr); @@ -91,7 +90,6 @@ public: int memberCount() const; int notifications(); int accessJoinRules(); - bool respondsToKeyRequests(); bool isLoading() const; //! Whether the user has enough power level to send m.room.join_rules events. bool canChangeJoinRules() const; @@ -106,7 +104,6 @@ public: Q_INVOKABLE void openEditModal(); Q_INVOKABLE void changeAccessRules(int index); Q_INVOKABLE void changeNotifications(int currentIndex); - Q_INVOKABLE void changeKeyRequestsPreference(bool isOn); signals: void loadingChanged(); @@ -114,7 +111,6 @@ signals: void roomTopicChanged(); void avatarUrlChanged(); void encryptionChanged(); - void keyRequestsChanged(); void notificationsChanged(); void accessJoinRulesChanged(); void displayError(const QString &errorMessage); @@ -136,4 +132,4 @@ private: RoomInfo info_; int notifications_ = 0; int accessRules_ = 0; -}; \ No newline at end of file +}; |