diff --git a/CMakeLists.txt b/CMakeLists.txt index 47f08657..bdfc7798 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,7 +305,6 @@ set(SRC_FILES src/SideBarActions.cpp src/Splitter.cpp src/TextInputWidget.cpp - src/TopRoomBar.cpp src/TrayIcon.cpp src/UserInfoWidget.cpp src/UserSettingsPage.cpp @@ -514,7 +513,6 @@ qt5_wrap_cpp(MOC_HEADERS src/SideBarActions.h src/Splitter.h src/TextInputWidget.h - src/TopRoomBar.h src/TrayIcon.h src/UserInfoWidget.h src/UserSettingsPage.h diff --git a/README.md b/README.md index fb0167c8..2d24165c 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ Nheko can use bundled version for most of those libraries automatically, if the To use them, you can enable the hunter integration by passing `-DHUNTER_ENABLED=ON`. It is probably wise to link those dependencies statically by passing `-DBUILD_SHARED_LIBS=OFF` You can select which bundled dependencies you want to use py passing various `-DUSE_BUNDLED_*` flags. By default all dependencies are bundled *if* you enable hunter. +If you experience build issues and you are trying to link `mtxclient` library without hunter, make sure the library version(commit) as mentioned in the `CMakeList.txt` is used. Sometimes we have to make breaking changes in `mtxclient` and for that period the master branch of both repos may not be compatible. The bundle flags are currently: diff --git a/resources/langs/nheko_cs.ts b/resources/langs/nheko_cs.ts new file mode 100644 index 00000000..38443412 --- /dev/null +++ b/resources/langs/nheko_cs.ts @@ -0,0 +1,1995 @@ + + + + + Cache + + + You joined this room. + + + + + ChatPage + + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. + + + + + Room %1 created. + + + + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + + Failed to invite %1 to %2: %3 + + + + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + + Failed to upload media. Please try again. + + + + + Cache migration failed! + + + + + Incompatible cache version + + + + + The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. + + + + + Failed to restore OLM account. Please login again. + + + + + Failed to restore save data. Please login again. + + + + + Failed to setup encryption keys. Server response: %1 %2. Please try again later. + + + + + + Please try to login again: %1 + + + + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + + Room creation failed: %1 + + + + + Failed to leave room: %1 + + + + + CommunitiesListItem + + + All rooms + + + + + Favourite rooms + + + + + Low priority rooms + + + + + Server Notices + Tag translation for m.server_notice + + + + + + (tag) + + + + + (community) + + + + + EditModal + + + Apply + + + + + Cancel + + + + + Name + + + + + Topic + + + + + EmojiPicker + + + + Search + + + + + People + + + + + Nature + + + + + Food + + + + + Activity + + + + + Travel + + + + + Objects + + + + + Symbols + + + + + Flags + + + + + EncryptionIndicator + + + Encrypted + + + + + This message is not encrypted! + + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + + + InviteeItem + + + Remove + + + + + LoginPage + + + Matrix ID + + + + + e.g @joe:matrix.org + + + + + Your login name. A mxid should start with @ followed by the user id. After the user id you need to include your server name after a :. +You can also put your homeserver address there, if your server doesn't support .well-known lookup. +Example: @user:server.my +If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. + + + + + Password + + + + + Device name + + + + + A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. + + + + + The address that can be used to contact you homeservers client API. +Example: https://server.my:8787 + + + + + + LOGIN + + + + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + + SSO LOGIN + + + + + Empty password + + + + + SSO login failed + + + + + MemberList + + + Room members + + + + + OK + + + + + MessageDelegate + + + + redacted + + + + + Encryption enabled + + + + + room name changed to: %1 + + + + + removed room name + + + + + topic changed to: %1 + + + + + removed topic + + + + + %1 created and configured room: %2 + + + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + Negotiating call... + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Placeholder + + + unimplemented event: + + + + + QuickSwitcher + + + Search for a room... + + + + + RegisterPage + + + Username + + + + + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. + + + + + Password + + + + + Please choose a secure password. The exact requirements for password strength may depend on your server. + + + + + Password confirmation + + + + + Homeserver + + + + + A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. + + + + + REGISTER + + + + + No supported registration flows! + + + + + Invalid username + + + + + Password is not long enough (min 8 chars) + + + + + Passwords don't match + + + + + Invalid server name + + + + + RoomInfo + + + no version stored + + + + + RoomInfoListItem + + + Leave room + + + + + Tag room as: + + + + + Favourite + Standard matrix tag for favourites + + + + + Low Priority + Standard matrix tag for low priority rooms + + + + + Server Notice + Standard matrix tag for server notices + + + + + Adds or removes the specified tag. + WhatsThis hint for tag menu actions + + + + + New tag... + Add a new tag to the room + + + + + New Tag + Tag name prompt title + + + + + Tag: + Tag name prompt + + + + + Accept + + + + + Decline + + + + + SideBarActions + + + User settings + + + + + Create new room + + + + + Join a room + + + + + Start a new chat + + + + + Room directory + + + + + StatusIndicator + + + Failed + + + + + Sent + + + + + Received + + + + + Read + + + + + TextInputWidget + + + Send a file + + + + + + Write a message... + + + + + Send a message + + + + + Emoji + + + + + Select a file + + + + + All Files (*) + + + + + Place a call + + + + + Hang up + + + + + Connection lost. Nheko is trying to re-connect... + + + + + TimelineModel + + + Message redaction failed: %1 + + + + + + + + Failed to encrypt event, sending aborted! + + + + + Save image + + + + + Save video + + + + + Save audio + + + + + Save file + + + + + %1 and %2 are typing. + Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) + + + + + + + + + %1 opened the room to the public. + + + + + %1 made this room require and invitation to join. + + + + + %1 made the room open to guests. + + + + + %1 has closed the room to guest access. + + + + + %1 made the room history world readable. Events may be now read by non-joined people. + + + + + %1 set the room history visible to members from this point on. + + + + + %1 set the room history visible to members since they were invited. + + + + + %1 set the room history visible to members since they joined the room. + + + + + %1 has changed the room's permissions. + + + + + %1 was invited. + + + + + %1 changed their display name and avatar. + + + + + %1 changed their display name. + + + + + %1 changed their avatar. + + + + + %1 changed some profile info. + + + + + %1 joined. + + + + + %1 rejected their invite. + + + + + Revoked the invite to %1. + + + + + %1 left the room. + + + + + Kicked %1. + + + + + Unbanned %1. + + + + + %1 was banned. + + + + + %1 redacted their knock. + + + + + You joined this room. + + + + + Rejected the knock from %1. + + + + + %1 left after having already left! + This is a leave event after the user already left and shouldn't happen apart from state resets + + + + + Reason: %1 + + + + + %1 knocked. + + + + + TimelineRow + + + React + + + + + Reply + + + + + Options + + + + + TimelineView + + + React + + + + + Reply + + + + + Read receipts + + + + + Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Redact message + + + + + Save as + + + + + No room open + + + + + Back to room list + + + + + + No room selected + + + + + Room options + + + + + Invite users + + + + + Members + + + + + Leave room + + + + + Settings + + + + + Close + + + + + TrayIcon + + + Show + + + + + Quit + + + + + UserInfoWidget + + + Logout + + + + + Set custom status message + + + + + Custom status message + + + + + Status: + + + + + Set presence automatically + + + + + Online + + + + + Unavailable + + + + + Offline + + + + + UserSettingsPage + + + Minimize to tray + + + + + Start in tray + + + + + Group's sidebar + + + + + Circular Avatars + + + + + CALLS + + + + + Keep the application running in the background after closing the client window. + + + + + Start the application in the background without showing the client window. + + + + + Change the appearance of user avatars in chats. +OFF - square, ON - Circle. + + + + + Show a column containing groups and tags next to the room list. + + + + + Decrypt messages in sidebar + + + + + Decrypt the messages shown in the sidebar. +Only affects messages in encrypted chats. + + + + + Show buttons in timeline + + + + + Show buttons to quickly reply, react or access additional options next to each message. + + + + + Limit width of timeline + + + + + Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised + + + + + Typing notifications + + + + + Show who is typing in a room. +This will also enable or disable sending typing notifications to others. + + + + + Sort rooms by unreads + + + + + Display rooms with new messages first. +If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. +If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. + + + + + Read receipts + + + + + Show if your message was read. +Status is displayed next to timestamps. + + + + + Send messages as Markdown + + + + + Allow using markdown in messages. +When disabled, all messages are sent as a plain text. + + + + + Desktop notifications + + + + + Notify about received message when the client is not currently focused. + + + + + Alert on notification + + + + + Show an alert when a message is received. +This usually causes the application icon in the task bar to animate in some fashion. + + + + + Highlight message on hover + + + + + Change the background color of messages when you hover over them. + + + + + Large Emoji in timeline + + + + + Make font size larger if messages with only a few emojis are displayed. + + + + + Scale factor + + + + + Change the scale factor of the whole user interface. + + + + + Font size + + + + + Font Family + + + + + Theme + + + + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + + Device ID + + + + + Device Fingerprint + + + + + Session Keys + + + + + IMPORT + + + + + EXPORT + + + + + ENCRYPTION + + + + + GENERAL + + + + + INTERFACE + + + + + Emoji Font Family + + + + + Open Sessions File + + + + + + + + + + + + + + Error + + + + + + File Password + + + + + Enter the passphrase to decrypt the file: + + + + + + The password cannot be empty + + + + + Enter passphrase to encrypt your session keys: + + + + + File to save the exported session keys + + + + + WelcomePage + + + Welcome to nheko! The desktop client for the Matrix protocol. + + + + + Enjoy your stay! + + + + + REGISTER + + + + + LOGIN + + + + + descriptiveTime + + + Yesterday + + + + + dialogs::AcceptCall + + + Accept + + + + + Reject + + + + + dialogs::CreateRoom + + + Create room + + + + + Cancel + + + + + Name + + + + + Topic + + + + + Alias + + + + + Room Visibility + + + + + Room Preset + + + + + Direct Chat + + + + + dialogs::FallbackAuth + + + Open Fallback in Browser + + + + + Cancel + + + + + Confirm + + + + + Open the fallback, follow the steps and confirm after completing them. + + + + + dialogs::InviteUsers + + + Cancel + + + + + User ID to invite + + + + + dialogs::JoinRoom + + + Join + + + + + Cancel + + + + + Room ID or alias + + + + + dialogs::LeaveRoom + + + Cancel + + + + + Are you sure you want to leave? + + + + + dialogs::Logout + + + Cancel + + + + + Logout. Are you sure? + + + + + dialogs::PlaceCall + + + Voice + + + + + Cancel + + + + + dialogs::PreviewUploadOverlay + + + Upload + + + + + Cancel + + + + + Media type: %1 +Media size: %2 + + + + + + dialogs::ReCaptcha + + + Cancel + + + + + Confirm + + + + + Solve the reCAPTCHA and press the confirm button + + + + + dialogs::ReadReceipts + + + Read receipts + + + + + Close + + + + + dialogs::ReceiptItem + + + Today %1 + + + + + Yesterday %1 + + + + + dialogs::RoomSettings + + + Settings + + + + + Info + + + + + Internal ID + + + + + Room Version + + + + + Notifications + + + + + Muted + + + + + Mentions only + + + + + All messages + + + + + Room access + + + + + Anyone and guests + + + + + Anyone + + + + + Invited users + + + + + Encryption + + + + + End-to-End Encryption + + + + + Encryption is currently experimental and things might break unexpectedly. <br>Please take note that it can't be disabled afterwards. + + + + + Respond to key requests + + + + + 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. + + + + + %n member(s) + + + + + + + + + Failed to enable encryption: %1 + + + + + Select an avatar + + + + + All Files (*) + + + + + The selected file is not an image + + + + + Error while reading file: %1 + + + + + + Failed to upload image: %s + + + + + dialogs::UserProfile + + + Ban the user from the room + + + + + Ignore messages from this user + + + + + Kick the user from the room + + + + + Start a conversation + + + + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + + Devices + + + + + emoji::Panel + + + Smileys & People + + + + + Animals & Nature + + + + + Food & Drink + + + + + Activity + + + + + Travel & Places + + + + + Objects + + + + + Symbols + + + + + Flags + + + + + message-description sent: + + + You sent an audio clip + + + + + %1 sent an audio clip + + + + + You sent an image + + + + + %1 sent an image + + + + + You sent a file + + + + + %1 sent a file + + + + + You sent a video + + + + + %1 sent a video + + + + + You sent a sticker + + + + + %1 sent a sticker + + + + + You sent a notification + + + + + %1 sent a notification + + + + + You: %1 + + + + + %1: %2 + + + + + You sent an encrypted message + + + + + %1 sent an encrypted message + + + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + + + + popups::UserMentions + + + This Room + + + + + All Rooms + + + + + utils + + + Unknown Message Type + + + + diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index 1ba57370..0958017f 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. Du bist dem Raum beigetreten. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 Nutzer konnte nicht eingeladen werden: %1 - + Invited user: %1 Eingeladener Benutzer: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - Migrieren des Caches auf die aktuelle Version fehlgeschlagen. Das kann verschiedene Gründe als Ursache haben. Bitte lege einen Bugreport an und verwende in der Zwischenzeit eine ältere Version. Alternativ kannst du das Cache manuell entfernen. + Das Migrieren des Caches auf die aktuelle Version ist fehlgeschlagen. Das kann verschiedene Gründe als Ursache haben. Bitte melde den Fehler und verwende in der Zwischenzeit eine ältere Version. Alternativ kannst du das Cache manuell löschen. - + Room %1 created. Raum %1 erzeugt. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 Einladung von %1 in Raum %2 fehlgeschlagen: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 %1 konnte nicht aus %2 gekickt werden: %3 @@ -48,7 +68,17 @@ %1 wurde gekickt. - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 %1 konnte nicht aus %2 verbannt werden: %3 @@ -58,7 +88,17 @@ %1 wurde gebannt. - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 Verbannung von %1 aus %2 konnte nicht aufgehoben werden: %3 @@ -68,12 +108,12 @@ Verbannung von %1 wurde aufgehoben. - + Failed to upload media. Please try again. Medienupload fehlgeschlagen. Bitte versuche es erneut. - + Cache migration failed! Cache migration fehlgeschlagen! @@ -85,31 +125,31 @@ The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - Das Cache auf der Festplatte wurde mit einer neueren Nheko version angelegt. Bitte aktualisiere Nheko oder entferne das Cache. + Der Cache auf der Festplatte wurde mit einer neueren Nheko - Version angelegt. Bitte aktualisiere Nheko oder entferne den Cache. - + Failed to restore OLM account. Please login again. Wiederherstellung des OLM Accounts fehlgeschlagen. Bitte logge dich erneut ein. - + Failed to restore save data. Please login again. Gespeicherte Nachrichten konnten nicht wiederhergestellt werden. Bitte melde Dich erneut an. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Fehler beim Setup der Verschlüsselungsschlüssel. Servermeldung: %1 %2. Bitte versuche es später erneut. - - + + Please try to login again: %1 Bitte melde dich erneut an: %1 - + Failed to join room: %1 Konnte Raum nicht betreten: %1 @@ -198,22 +238,22 @@ Search - + Suche People - + Leute Nature - + Natur Food - + Essen @@ -223,7 +263,7 @@ Travel - + Reisen @@ -251,7 +291,44 @@ This message is not encrypted! - Diese Nachricht ist nicht verschlüsselt! + Diese Nachricht ist unverschlüsselt! + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Verschlüsseltes Event (keine Schlüssel zur Entschlüsselung gefunden) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Entschlüsselungsfehler (Fehler bei Suche nach megolm Schlüsseln in Datenbank) -- + + + + -- 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. + -- Entschlüsselungsfehler (%1) -- + + + + -- 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. + -- Verschlüsseltes Event (Unbekannter Eventtyp) -- + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + @@ -371,6 +448,7 @@ Beispiel: https://mein.server:8787 MessageDelegate + redacted gelöscht @@ -404,6 +482,36 @@ Beispiel: https://mein.server:8787 %1 created and configured room: %2 %1 hat den Raum erstellt: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + %1 hat den Anruf angenommen. + + + + %1 ended the call. + %1 hat den Anruf beendet. + + + + Negotiating call... + + Placeholder @@ -492,7 +600,7 @@ Beispiel: https://mein.server:8787 RoomInfo - + no version stored keine Version gespeichert @@ -616,13 +724,13 @@ Beispiel: https://mein.server:8787 TextInputWidget - + Send a file Versende Datei - + Write a message... Schreibe eine Nachricht… @@ -637,7 +745,7 @@ Beispiel: https://mein.server:8787 Emoji - + Select a file Datei auswählen @@ -646,6 +754,16 @@ Beispiel: https://mein.server:8787 All Files (*) Alle Dateien (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -655,30 +773,20 @@ Beispiel: https://mein.server:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - -- Entschlüsselungsfehler (Fehler bei Kommunikation mit Datenbank) -- - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - -- Entschlüsselungsfehler (Fehler bei Suche nach megolm Schlüsseln in Datenbank) -- - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - -- Entschlüsselungsfehler (%1) -- - - - + Message redaction failed: %1 Nachricht zurückziehen fehlgeschlagen: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Bild speichern @@ -697,20 +805,8 @@ Beispiel: https://mein.server:8787 Save file Datei speichern - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Verschlüsseltes Event (keine Schlüssel zur Entschlüsselung gefunden) -- - - - - -- 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. - -- Verschlüsseltes Event (Unbekannter Eventtyp) -- - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -764,7 +860,7 @@ Beispiel: https://mein.server:8787 %1 hat die Berechtigungen dieses Raums bearbeitet. - + %1 was invited. %1 wurde eingeladen. @@ -829,12 +925,12 @@ Beispiel: https://mein.server:8787 %1 hat das Anklopfen zurückgezogen. - + You joined this room. Du bist dem Raum beigetreten. - + Rejected the knock from %1. Hat das Anklopfen von %1 abgewiesen. @@ -858,12 +954,12 @@ Beispiel: https://mein.server:8787 TimelineRow - + React - + Reply Antworten @@ -876,7 +972,7 @@ Beispiel: https://mein.server:8787 TimelineView - + React @@ -916,49 +1012,52 @@ Beispiel: https://mein.server:8787 Speichern unter... - + No room open Kein Raum geöffnet - + + Back to room list + + + + + + No room selected + + + + + Room options + Raumoptionen + + + + Invite users + Benutzer einladen + + + + Members + Teilnehmer + + + + Leave room + Raum verlassen + + + + Settings + Einstellungen + + + Close Schließen - - TopRoomBar - - - Room options - Raumoptionen - - - - Mentions - Erwähnungen - - - - Invite users - Benutzer einladen - - - - Members - Teilnehmer - - - - Leave room - Raum verlassen - - - - Settings - Einstellungen - - TrayIcon @@ -1018,7 +1117,7 @@ Beispiel: https://mein.server:8787 UserSettingsPage - + Minimize to tray Ins Benachrichtigungsfeld minimieren @@ -1038,7 +1137,12 @@ Beispiel: https://mein.server:8787 Runde Profilbilder - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1201,7 +1305,17 @@ This usually causes the application icon in the task bar to animate in some fash Erscheinungsbild - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID Geräte-ID @@ -1211,7 +1325,7 @@ This usually causes the application icon in the task bar to animate in some fash Gerätefingerabdruck - + Session Keys Sitzungsschlüssel @@ -1231,22 +1345,22 @@ This usually causes the application icon in the task bar to animate in some fash VERSCHLÜSSELUNG - + GENERAL ALLGEMEINES - + INTERFACE OBERFLÄCHE - + Emoji Font Family Emojischriftart - + Open Sessions File Öffne Sessions Datei @@ -1318,11 +1432,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Gestern + + dialogs::AcceptCall + + + Accept + Akzeptieren + + + + Reject + + + dialogs::CreateRoom @@ -1446,6 +1573,19 @@ This usually causes the application icon in the task bar to animate in some fash Willst du dich wirklich abmelden? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Abbrechen + + dialogs::PreviewUploadOverlay @@ -1644,7 +1784,7 @@ Medien-Größe: %2 dialogs::UserProfile - + Ban the user from the room Banne den Nutzer aus diesem Raum @@ -1664,7 +1804,17 @@ Medien-Größe: %2 Gespräch beginnen - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices Geräte @@ -1715,7 +1865,7 @@ Medien-Größe: %2 message-description sent: - + You sent an audio clip Du hast eine Audiodatei gesendet. @@ -1794,6 +1944,36 @@ Medien-Größe: %2 %1 sent an encrypted message %1 hat eine verschlüsselte Nachricht gesendet. + + + You placed a call + Du hast angerufen + + + + %1 placed a call + %1 hat angerufen + + + + You answered a call + Du hast einen Anruf angenommen + + + + %1 answered a call + %1 hat einen Anruf angenommen + + + + You ended a call + Du hast einen Anruf beendet + + + + %1 ended a call + %1 hat einen Anruf beendet + popups::UserMentions diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index 47405976..d0a46653 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. - + Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file - + Write a message... Γράψε ένα μήνυμα... @@ -633,7 +741,7 @@ Example: https://server.my:8787 - + Select a file Διάλεξε ένα αρχείο @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) Όλα τα αρχεία (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Αποθήκευση Εικόνας @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -760,7 +856,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -825,12 +921,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -854,12 +950,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -872,7 +968,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -912,47 +1008,50 @@ Example: https://server.my:8787 - + No room open - - Close + + Back to room list - - - TopRoomBar - + + + No room selected + + + + Room options - - Mentions - - - - + Invite users - Προσκάλεσε χρήστες + Προσκάλεσε χρήστες - + Members - Μέλη + Μέλη - + Leave room - Βγές από τη συνομιλία + Βγές - + Settings - Ρυθμίσεις + Ρυθμίσεις + + + + Close + @@ -1014,7 +1113,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Ελαχιστοποίηση @@ -1034,7 +1133,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1197,7 +1301,17 @@ This usually causes the application icon in the task bar to animate in some fash Φόντο - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID @@ -1207,7 +1321,7 @@ This usually causes the application icon in the task bar to animate in some fash - + Session Keys @@ -1227,22 +1341,22 @@ This usually causes the application icon in the task bar to animate in some fash - + GENERAL ΓΕΝΙΚΑ - + INTERFACE - + Emoji Font Family - + Open Sessions File @@ -1314,11 +1428,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + Αποδοχή + + + + Reject + + + dialogs::CreateRoom @@ -1442,6 +1569,19 @@ This usually causes the application icon in the task bar to animate in some fash Αποσύνδεση. Είστε σίγουροι; + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Άκυρο + + dialogs::PreviewUploadOverlay @@ -1638,7 +1778,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room @@ -1658,7 +1798,17 @@ Media size: %2 - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices @@ -1709,7 +1859,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1788,6 +1938,36 @@ Media size: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 1e9128d0..bfbbd987 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 Failed to invite user: %1 - + Invited user: %1 Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. Room %1 created. - + + Confirm invite + Confirm invite + + + + Do you really want to invite %1 (%2)? + Do you really want to invite %1 (%2)? + + + Failed to invite %1 to %2: %3 Failed to invite %1 to %2: %3 - + + Confirm kick + Confirm kick + + + + Do you really want to kick %1 (%2)? + Do you really want to kick %1 (%2)? + + + Failed to kick %1 to %2: %3 Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ Kicked user: %1 - + + Confirm ban + Confirm ban + + + + Do you really want to ban %1 (%2)? + Do you really want to ban %1 (%2)? + + + Failed to ban %1 in %2: %3 Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ Banned user: %1 - + + Confirm unban + Confirm unban + + + + Do you really want to unban %1 (%2)? + Do you really want to unban %1 (%2)? + + + Failed to unban %1 in %2: %3 Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ Unbanned user: %1 - + Failed to upload media. Please try again. Failed to upload media. Please try again. - + Cache migration failed! Cache migration failed! @@ -88,28 +128,28 @@ The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - + Failed to restore OLM account. Please login again. Failed to restore OLM account. Please login again. - + Failed to restore save data. Please login again. Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 Please try to login again: %1 - + Failed to join room: %1 Failed to join room: %1 @@ -155,7 +195,7 @@ Server Notices Tag translation for m.server_notice - + Server Notices @@ -203,42 +243,42 @@ People - + People Nature - + Nature Food - + Food Activity - Activity + Activity Travel - + Travel Objects - Objects + Objects Symbols - Symbols + Symbols Flags - Flags + Flags @@ -251,7 +291,44 @@ This message is not encrypted! - + This message is not encrypted! + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Encrypted Event (No keys found for decryption) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Decryption Error (failed to retrieve megolm keys from db) -- + + + + -- 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. + -- Decryption Error (%1) -- + + + + -- 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. + -- Encrypted Event (Unknown event type) -- + + + + -- Replay attack! This message index was reused! -- + -- Replay attack! This message index was reused! -- + + + + -- Message by unverified device! -- + -- Message by unverified device! -- @@ -298,7 +375,7 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. - + A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. @@ -371,6 +448,7 @@ Example: https://server.my:8787 MessageDelegate + redacted redacted @@ -405,12 +483,27 @@ Example: https://server.my:8787 %1 created and configured room: %2 - - %1 placed a %2 call. - %1 placed a %2 call. + + %1 placed a voice call. + %1 placed a voice call. - + + %1 placed a video call. + %1 placed a video call. + + + + %1 placed a call. + %1 placed a call. + + + + Negotiating call... + Negotiating call… + + + %1 answered the call. %1 answered the call. @@ -507,7 +600,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored no version stored @@ -522,49 +615,49 @@ Example: https://server.my:8787 Tag room as: - + Tag room as: Favourite Standard matrix tag for favourites - + Favourite Low Priority Standard matrix tag for low priority rooms - + Low Priority Server Notice Standard matrix tag for server notices - + Server Notice Adds or removes the specified tag. WhatsThis hint for tag menu actions - + Adds or removes the specified tag. New tag... Add a new tag to the room - + New tag… New Tag Tag name prompt title - + New Tag Tag: Tag name prompt - + Tag: @@ -631,13 +724,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file Send a file - + Write a message... Write a message… @@ -652,7 +745,7 @@ Example: https://server.my:8787 Emoji - + Select a file Select a file @@ -661,6 +754,16 @@ Example: https://server.my:8787 All Files (*) All Files (*) + + + Place a call + Place a call + + + + Hang up + Hang up + Connection lost. Nheko is trying to re-connect... @@ -670,30 +773,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - -- Decryption Error (failed to communicate with DB) -- - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - -- Decryption Error (failed to retrieve megolm keys from db) -- - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - -- Decryption Error (%1) -- - - - + Message redaction failed: %1 Message redaction failed: %1 - + + + + + Failed to encrypt event, sending aborted! + Failed to encrypt event, sending aborted! + + + Save image Save image @@ -712,20 +805,8 @@ Example: https://server.my:8787 Save file Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Encrypted Event (No keys found for decryption) -- - - - - -- 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. - -- Encrypted Event (Unknown event type) -- - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -779,7 +860,7 @@ Example: https://server.my:8787 %1 has changed the room's permissions. - + %1 was invited. %1 was invited. @@ -801,7 +882,7 @@ Example: https://server.my:8787 %1 changed some profile info. - + %1 changed some profile info. @@ -844,12 +925,12 @@ Example: https://server.my:8787 %1 redacted their knock. - + You joined this room. You joined this room. - + Rejected the knock from %1. Rejected the knock from %1. @@ -873,12 +954,12 @@ Example: https://server.my:8787 TimelineRow - + React - + React - + Reply Reply @@ -891,9 +972,9 @@ Example: https://server.my:8787 TimelineView - + React - + React @@ -931,48 +1012,51 @@ Example: https://server.my:8787 Save as - + No room open No room open - - Close - Close + + Back to room list + Back to room list - - - TopRoomBar - + + + No room selected + No room selected + + + Room options Room options - - Mentions - Mentions - - - + Invite users Invite users - + Members Members - + Leave room Leave room - + Settings Settings + + + Close + Close + TrayIcon @@ -997,43 +1081,43 @@ Example: https://server.my:8787 Set custom status message - + Set custom status message Custom status message - + Custom status message Status: - + Status: Set presence automatically - + Set presence automatically Online - + Online Unavailable - + Unavailable Offline - + Offline UserSettingsPage - + Minimize to tray Minimize to tray @@ -1053,25 +1137,31 @@ Example: https://server.my:8787 Circular Avatars - + + CALLS + CALLS + + + Keep the application running in the background after closing the client window. - + Keep the application running in the background after closing the client window. Start the application in the background without showing the client window. - + Start the application in the background without showing the client window. Change the appearance of user avatars in chats. OFF - square, ON - Circle. - + Change the appearance of user avatars in chats. +OFF - square, ON - Circle. Show a column containing groups and tags next to the room list. - + Show a column containing groups and tags next to the room list. @@ -1082,7 +1172,8 @@ OFF - square, ON - Circle. Decrypt the messages shown in the sidebar. Only affects messages in encrypted chats. - + Decrypt the messages shown in the sidebar. +Only affects messages in encrypted chats. @@ -1092,17 +1183,17 @@ Only affects messages in encrypted chats. Show buttons to quickly reply, react or access additional options next to each message. - + Show buttons to quickly reply, react or access additional options next to each message. Limit width of timeline - + Limit width of timeline Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised - + Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised. @@ -1113,7 +1204,8 @@ Only affects messages in encrypted chats. Show who is typing in a room. This will also enable or disable sending typing notifications to others. - + Show who is typing in a room. +This will also enable or disable sending typing notifications to others. @@ -1125,7 +1217,9 @@ This will also enable or disable sending typing notifications to others.Display rooms with new messages first. If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. - + Display rooms with new messages first. +If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. +If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. @@ -1136,7 +1230,8 @@ If this is on, rooms which have active notifications (the small circle with a nu Show if your message was read. Status is displayed next to timestamps. - + Show if your message was read. +Status is displayed next to timestamps. @@ -1147,7 +1242,8 @@ Status is displayed next to timestamps. Allow using markdown in messages. When disabled, all messages are sent as a plain text. - + Allow using markdown in messages. +When disabled, all messages are sent as a plain text. @@ -1157,38 +1253,39 @@ When disabled, all messages are sent as a plain text. Notify about received message when the client is not currently focused. - + Notify about received message when the client is not currently focused. Alert on notification - + Alert on notification Show an alert when a message is received. This usually causes the application icon in the task bar to animate in some fashion. - + Show an alert when a message is received. +This usually causes the application icon in the task bar to animate in some fashion. Highlight message on hover - + Highlight message on hover Change the background color of messages when you hover over them. - + Change the background color of messages when you hover over them. Large Emoji in timeline - + Large Emoji in timeline Make font size larger if messages with only a few emojis are displayed. - + Make font size larger if messages with only a few emojis are displayed. @@ -1198,7 +1295,7 @@ This usually causes the application icon in the task bar to animate in some fash Change the scale factor of the whole user interface. - + Change the scale factor of the whole user interface. @@ -1216,7 +1313,17 @@ This usually causes the application icon in the task bar to animate in some fash Theme - + + Allow fallback call assist server + Allow fallback call assist server + + + + Will use turn.matrix.org as assist when your home server does not offer one. + Will use turn.matrix.org as assist when your home server does not offer one. + + + Device ID Device ID @@ -1226,7 +1333,7 @@ This usually causes the application icon in the task bar to animate in some fash Device Fingerprint - + Session Keys Session Keys @@ -1246,22 +1353,22 @@ This usually causes the application icon in the task bar to animate in some fash ENCRYPTION - + GENERAL GENERAL - + INTERFACE INTERFACE - + Emoji Font Family Emoji Font Family - + Open Sessions File Open Sessions File @@ -1333,11 +1440,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Yesterday + + dialogs::AcceptCall + + + Accept + Accept + + + + Reject + Reject + + dialogs::CreateRoom @@ -1461,6 +1581,19 @@ This usually causes the application icon in the task bar to animate in some fash Logout. Are you sure? + + dialogs::PlaceCall + + + Voice + Voice + + + + Cancel + Cancel + + dialogs::PreviewUploadOverlay @@ -1661,7 +1794,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room Ban the user from the room @@ -1681,7 +1814,17 @@ Media size: %2 Start a conversation - + + Confirm DM + Confirm DM + + + + Do you really want to invite %1 (%2) to a direct chat? + Do you really want to invite %1 (%2) to a direct chat? + + + Devices Devices @@ -1732,7 +1875,7 @@ Media size: %2 message-description sent: - + You sent an audio clip You sent an audio clip diff --git a/resources/langs/nheko_et.ts b/resources/langs/nheko_et.ts new file mode 100644 index 00000000..f3a51bb9 --- /dev/null +++ b/resources/langs/nheko_et.ts @@ -0,0 +1,2009 @@ + + + + + Cache + + + You joined this room. + Sa liitusid selle jututoaga. + + + + ChatPage + + + Failed to invite user: %1 + Kutse saatmine kasutajale ei õnnestunud: %1 + + + + + Invited user: %1 + Kutsutud kasutaja: %1 + + + + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. + Puhverdatud andmete muutmine sobivaks rakenduse praeguse versiooniga ei õnnestunud. Sellel võib olla erinevaid põhjuseid. Palun saada meile veateade ja seni kasuta vanemat rakenduse versiooni. Aga kui sa soovid proovida, siis kustuta puhverdatud andmed käsitsi. + + + + Room %1 created. + %1 jututuba on loodud. + + + + Confirm invite + Kinnita kutse + + + + Do you really want to invite %1 (%2)? + Kas sa tõesti soovid saata kutset kasutajale %1 (%2)? + + + + Failed to invite %1 to %2: %3 + Kasutaja %1 kutsumine %2 jututuppa ei õnnestunud: %3 + + + + Confirm kick + Kinnita väljamüksamine + + + + Do you really want to kick %1 (%2)? + Kas sa tõesti soovid müksata kasutaja %1 (%2) jututoast välja? + + + + Failed to kick %1 to %2: %3 + Kasutaja %1 välja müksamine %2 jututoast ei õnnestunud: %3 + + + + Kicked user: %1 + Väljamüksatud kasutaja: %1 + + + + Confirm ban + Kinnita suhtluskeeld + + + + Do you really want to ban %1 (%2)? + Kas sa tõesti soovid kasutajale %1 (%2) seada suhtluskeeldu? + + + + Failed to ban %1 in %2: %3 + Kasutajale %1 suhtluskeelu seadmine %2 jututoas ei õnnestunud: %3 + + + + Banned user: %1 + Suhtluskeeld kasutajale: %1 + + + + Confirm unban + Kinnita suhtluskeelu eemaldamine + + + + Do you really want to unban %1 (%2)? + Kas sa tõesti soovid kasutajalt %1 (%2) eemaldada suhtluskeelu? + + + + Failed to unban %1 in %2: %3 + Kasutajalt %1 suhtluskeelu eemaldamine %2 jututoas ei õnnestunud: %3 + + + + Unbanned user: %1 + Suhtluskeeld eemaldatud: %1 + + + + Failed to upload media. Please try again. + Meediafailide üleslaadimine ei õnnestunud. Palun proovi uuesti. + + + + Cache migration failed! + Puhvri versiooniuuendus ebaõnnestus! + + + + Incompatible cache version + Mitteühilduv puhvri versioon + + + + The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. + Sinu andmekandjale salvestatud puhvri versioon on uuem, kui käesolev Nheko versioon kasutada oskab. Palun tee Nheko uuendus või kustuta puhverdatud andmed. + + + + Failed to restore OLM account. Please login again. + OLM konto taastamine ei õnnestunud. Palun logi uuesti sisse. + + + + Failed to restore save data. Please login again. + Salvestatud andmete taastamine ei õnnestunud. Palun logi uuesti sisse. + + + + Failed to setup encryption keys. Server response: %1 %2. Please try again later. + Krüptovõtmete kasutusele võtmine ei õnnestunud. Koduserveri vastus päringule: %1 %2. Palun proovi hiljem uuesti. + + + + + Please try to login again: %1 + Palun proovi uuesti sisse logida: %1 + + + + Failed to join room: %1 + Jututoaga liitumine ei õnnestunud: %1 + + + + You joined the room + Sa liitusid selle jututoaga + + + + Failed to remove invite: %1 + Kutse tagasivõtmine ei õnnestunud: %1 + + + + Room creation failed: %1 + Jututoa loomine ei õnnestunud: %1 + + + + Failed to leave room: %1 + Jututoast lahkumine ei õnnestunud: %1 + + + + CommunitiesListItem + + + All rooms + Kõik jututoad + + + + Favourite rooms + Eelistatud jututoad + + + + Low priority rooms + Vähetähtsad jututoad + + + + Server Notices + Tag translation for m.server_notice + Serveriteated + + + + + (tag) + (silt) + + + + (community) + (kogukond) + + + + EditModal + + + Apply + Rakenda + + + + Cancel + Tühista + + + + Name + Nimi + + + + Topic + Teema + + + + EmojiPicker + + + + Search + Otsi + + + + People + Inimesed + + + + Nature + Loodus + + + + Food + Toit + + + + Activity + Tegevused + + + + Travel + Reisimine + + + + Objects + Esemed + + + + Symbols + Sümbolid + + + + Flags + Lipud + + + + EncryptionIndicator + + + Encrypted + Krüptitud + + + + This message is not encrypted! + See sõnum on krüptimata! + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Krüptitud sündmus (Dekrüptimisvõtmeid ei leidunud) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Dekrüptimise viga (megolm'i võtmete laadimine andmebaasist ei õnnestunud) -- + + + + -- 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. + -- Dekrüptimise viga (%1) -- + + + + -- 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. + -- Krüptitud sündmus (Tundmatu sündmuse tüüp) -- + + + + -- Replay attack! This message index was reused! -- + -- Kordusel põhinev rünne! Selle sõnumi indeksit on uuesti kasutatud! -- + + + + -- Message by unverified device! -- + -- Sõnum verifitseerimata seadmest! -- + + + + InviteeItem + + + Remove + Eemalda + + + + LoginPage + + + Matrix ID + Matrix'i kasutajatunnus + + + + e.g @joe:matrix.org + näiteks @kadri:matrix.org + + + + Your login name. A mxid should start with @ followed by the user id. After the user id you need to include your server name after a :. +You can also put your homeserver address there, if your server doesn't support .well-known lookup. +Example: @user:server.my +If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. + Sinu kasutajanimi sisselogimiseks. Matrix'i kasutajatunnus algab @ märgiga ning sellele järgneb kasutajanimi. Seejärel peale koolonit +on sinu koduserveri nimi. Kui sinu koduserver ei toeta .well-known nimelahendust, siis sa võid lisada ka koduserveri aadressi. +Näiteks @kadri:server.minu +Kui Nheko ei suuda tuvastada sinu koduserverit, siis ta kuvab sulle andmevälja selle sisestamiseks. + + + + Password + Salasõna + + + + Device name + Seadme nimi + + + + A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. + Selle seadme nimi, mida näidetakse verifitseerimise ajal teisele kasutajatele. Kui sa ise nime ei pane, siis kasutame automaatselt pandud nime. + + + + The address that can be used to contact you homeservers client API. +Example: https://server.my:8787 + Aadress, mida sinu koduserveri kliendipoole API kasutab. +Näiteks: https://server.minu:8787 + + + + + LOGIN + LOGI SISSE + + + + Autodiscovery failed. Received malformed response. + Koduserveri automaatne tuvastamine ei õnnestunud: päringuvastus oli vigane. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Koduserveri automaatne tuvastamine ei õnnestunud: tundmatu viga .well-known päringu tegemisel. + + + + The required endpoints were not found. Possibly not a Matrix server. + Protokolli järgi nõutavaid lõpppunkte ei leidunud. Ilmselt pole tegemist Matrix'i serveriga. + + + + Received malformed response. Make sure the homeserver domain is valid. + Päringule sain tagasi vigase vastuse. Palun kontrolli, et koduserveri domeen oleks õige. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Tekkis teadmata viga. Palun kontrolli, et koduserveri domeen on õige. + + + + SSO LOGIN + ÜHEKORDNE SISSELOGIMINE + + + + Empty password + Tühi salasõna + + + + SSO login failed + Ühekordne sisselogimine ei õnnestunud + + + + MemberList + + + Room members + Jututoa liikmed + + + + OK + Sobib + + + + MessageDelegate + + + + redacted + muudetud + + + + Encryption enabled + Krüptimine on kasutusel + + + + room name changed to: %1 + jututoa uus nimi on: %1 + + + + removed room name + eemaldas jututoa nime + + + + topic changed to: %1 + jututoa uus teema on: %1 + + + + removed topic + teema on eemaldatud + + + + %1 created and configured room: %2 + %1 lõi ja seadistas jututoa: %2 + + + + %1 placed a voice call. + %1 helistas. + + + + %1 placed a video call. + %1 alustas videokõnet. + + + + %1 placed a call. + %1 helistas. + + + + Negotiating call... + Ühendan kõnet… + + + + %1 answered the call. + %1 vastas kõnele. + + + + %1 ended the call. + %1 lõpetas kõne. + + + + Placeholder + + + unimplemented event: + implementeerimata sündmus: + + + + QuickSwitcher + + + Search for a room... + Otsi jututuba… + + + + RegisterPage + + + Username + Kasutajanimi + + + + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. + Kasutajanimi ei tohi olla tühi ning võib sisaldada vaid a-z, 0-9, ., _, =, -, / tähemärke. + + + + Password + Salasõna + + + + Please choose a secure password. The exact requirements for password strength may depend on your server. + Palun vali tutvaline salasõna. Täpsemad nõuded salasõnale sõltuvad sinu koduserveri seadistustest. + + + + Password confirmation + Korda salasõna + + + + Homeserver + Koduserver + + + + A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. + See on server, kus sa oma kasutajakonto registreerid. Kuna Matrix on hajutatud suhtlusvõrk, siis esmalt pead leidma sulle sobiliku koduserveri või panema püsti täitsa oma enda koduserveri. + + + + REGISTER + REGISTREERI + + + + No supported registration flows! + Selline registreerimise töövoog pole toetatud! + + + + Invalid username + Vigane kasutajanimi + + + + Password is not long enough (min 8 chars) + Salasõna pole piisavalt pikk (vähemalt 8 tähemärki) + + + + Passwords don't match + Salasõnad ei klapi omavahel + + + + Invalid server name + Vigane koduserveri nimi + + + + RoomInfo + + + no version stored + salvestatud versiooni ei leidu + + + + RoomInfoListItem + + + Leave room + Lahku jututoast + + + + Tag room as: + Lisa jututoale silt: + + + + Favourite + Standard matrix tag for favourites + Lemmik + + + + Low Priority + Standard matrix tag for low priority rooms + Vähetähtis + + + + Server Notice + Standard matrix tag for server notices + Serveriteade + + + + Adds or removes the specified tag. + WhatsThis hint for tag menu actions + Lisab või eemaldab selle sildi. + + + + New tag... + Add a new tag to the room + Uus silt… + + + + New Tag + Tag name prompt title + Uus silt + + + + Tag: + Tag name prompt + Silt: + + + + Accept + Nõustu + + + + Decline + Ei nõustu + + + + SideBarActions + + + User settings + Kasutaja seadistused + + + + Create new room + Loo uus jututuba + + + + Join a room + Liitu jututoaga + + + + Start a new chat + Alusta uut vestlust + + + + Room directory + Jututubade loend + + + + StatusIndicator + + + Failed + Ebaõnnestus + + + + Sent + Saadetud + + + + Received + Vastuvõetud + + + + Read + Loetud + + + + TextInputWidget + + + Send a file + Saada fail + + + + + Write a message... + Kirjuta sõnum… + + + + Send a message + Saada sõnum + + + + Emoji + Emoji + + + + Select a file + Vali fail + + + + All Files (*) + Kõik failid (*) + + + + Place a call + Helista + + + + Hang up + Lõpeta kõne + + + + Connection lost. Nheko is trying to re-connect... + Ühendus serveriga on katkenud. Nheko proovib uuesti ühendust luua… + + + + TimelineModel + + + Message redaction failed: %1 + Sõnumi ümbersõnastamine ebaõnnestus: %1 + + + + + + + Failed to encrypt event, sending aborted! + Sündmuse krüptimine ei õnnestunud, katkestame saatmise! + + + + Save image + Salvesta pilt + + + + Save video + Salvesta video + + + + Save audio + Salvesta helifail + + + + Save file + Salvesta fail + + + + %1 and %2 are typing. + Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) + + %1%2 kirjutab. + %1 and %2 kirjutavad. + + + + + %1 opened the room to the public. + %1 tegi jututoa avalikuks. + + + + %1 made this room require and invitation to join. + %1 seadistas, et selle jututoaga liitumine eeldab kutset. + + + + %1 made the room open to guests. + %1 muutis selle jututoa külalistele ligipääsetavaks. + + + + %1 has closed the room to guest access. + %1 eemaldas sellest jututoast külaliste ligipääsu. + + + + %1 made the room history world readable. Events may be now read by non-joined people. + %1 muutis, et kogu maailm saab selle jututoa ajalugu lugeda. Kõiki sündmusi saavad lugeda ka need, kes ei ole liitunud jututoaga. + + + + %1 set the room history visible to members from this point on. + %1 muutis, et selle jututoa ajalugu saavad lugeda kõik liikmed alates praegusest ajahetkest. + + + + %1 set the room history visible to members since they were invited. + %1 muutis, et selle jututoa ajalugu saavad lugeda kõik liikmed alates oma kutse saatmisest. + + + + %1 set the room history visible to members since they joined the room. + %1 muutis, et selle jututoa ajalugu saavad lugeda kõik liikmed alates jututoaga liitumise hetkest. + + + + %1 has changed the room's permissions. + %1 muutis selle jututoa õigusi. + + + + %1 was invited. + %1 sai kutse. + + + + %1 changed their display name and avatar. + %1 muutis oma kuvatavat nime ja tunnuspilti. + + + + %1 changed their display name. + %1 muutis oma kuvatavat nime. + + + + %1 changed their avatar. + %1 muutis oma tunnuspilti. + + + + %1 changed some profile info. + %1 muutis oma profiili. + + + + %1 joined. + %1 liitus jututoaga. + + + + %1 rejected their invite. + %1 lükkas liitumiskutse tagasi. + + + + Revoked the invite to %1. + Tühistas %1 kutse. + + + + %1 left the room. + %1 lahkus jututoast. + + + + Kicked %1. + Müksas kasutaja %1 välja. + + + + Unbanned %1. + Eemaldas kasutaja %1 suhtluskeelu. + + + + %1 was banned. + Kasutaja %1 sai suhtluskeelu. + + + + %1 redacted their knock. + %1 muutis oma koputust jututoa uksele. + + + + You joined this room. + Sa liitusid jututoaga. + + + + Rejected the knock from %1. + Lükkas tagasi %1 koputuse jututoa uksele. + + + + %1 left after having already left! + This is a leave event after the user already left and shouldn't happen apart from state resets + %1 lahkus jututoast peale seda, kui ta juba oli lahkunud! + + + + Reason: %1 + Põhjus: %1 + + + + %1 knocked. + %1 müksati välja. + + + + TimelineRow + + + React + Reageeri + + + + Reply + Vasta + + + + Options + Valikud + + + + TimelineView + + + React + Reageeri + + + + Reply + Vasta + + + + Read receipts + Lugemisteatised + + + + Mark as read + Märgi loetuks + + + + View raw message + Näita sõnumi lähtekoodi + + + + View decrypted raw message + Näita sõnumi dekrüptitud lähtekoodi + + + + Redact message + Muuda sõnumit + + + + Save as + Salvesta kui + + + + No room open + Ühtegi jututuba pole avatud + + + + Back to room list + Tagasi jututubade loendisse + + + + + No room selected + Jututuba on valimata + + + + Room options + Jututoa valikud + + + + Invite users + Kutsu kasutajaid + + + + Members + Liikmed + + + + Leave room + Lahku jututoast + + + + Settings + Seadistused + + + + Close + Sulge + + + + TrayIcon + + + Show + Näita + + + + Quit + Lõpeta töö + + + + UserInfoWidget + + + Logout + Logi välja + + + + Set custom status message + Kirjuta kohandatud olekuteade + + + + Custom status message + Kohandatud olekuteade + + + + Status: + Olek: + + + + Set presence automatically + Määra oma võrguolek automaatselt + + + + Online + Võrgus + + + + Unavailable + Pole kättesaadav + + + + Offline + Pole võrgus + + + + UserSettingsPage + + + Minimize to tray + Vähenda tegumiribale + + + + Start in tray + Käivita tegumiribalt + + + + Group's sidebar + Rühmade küljepaan + + + + Circular Avatars + Ümmargused tunnuspildid + + + + CALLS + KÕNED + + + + Keep the application running in the background after closing the client window. + Peale akna sulgemist jäta rakendus taustal tööle. + + + + Start the application in the background without showing the client window. + Käivita rakendus taustal ilma kliendiakna kuvamiseta. + + + + Change the appearance of user avatars in chats. +OFF - square, ON - Circle. + Muuda vestlustes kuvatavate tunnuspiltide kuju. +Väljalülitatuna - ruut, sisselülitatuna - ümmargune. + + + + Show a column containing groups and tags next to the room list. + Näita jututubade loendi kõrval veergu rühmade ja siltidega. + + + + Decrypt messages in sidebar + Dekrüpti sõnumid külgribal + + + + Decrypt the messages shown in the sidebar. +Only affects messages in encrypted chats. + Dekrüpti külgpaanis kuvatavaid sõnumeid. +Kehtib vaid läbivalt krüptitud vestluste puhul. + + + + Show buttons in timeline + Näita ajajoonel nuppe + + + + Show buttons to quickly reply, react or access additional options next to each message. + Näita iga sõnumi kõrval nuppe, mis võimaldavad kiiresti vastata, reageerida või teha sõnumiga muid toiminguid. + + + + Limit width of timeline + Piira ajajoone laiust + + + + Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised + Seadista sõnumite suurim laius pikslites ajajoonel. See parandab loetavust suurel ekraanil, kui Nheko on avatud täisvaates. + + + + Typing notifications + Kirjutamisteatised + + + + Show who is typing in a room. +This will also enable or disable sending typing notifications to others. + Näita, kes jututoas parasjagu kirjutab. +Samaga lülitatakse sisse või välja ka sinu kirjutamisteatiste saatmine teistele kasutajatele. + + + + Sort rooms by unreads + Järjesta jututoad lugemata tubade alusel + + + + Display rooms with new messages first. +If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. +If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. + Kuva uute sõnumitega jututoad esimesena. +Kui see valik on välja lülitatud, siis jututoad järjestatakse viimati saanunud sõnumi ajatempli alusel. +Kui see valik on sisse lülitatud, siis teavitustega jututoad (pisike ümmargune numbrifa ikoon) järjestatakse esimesena. Sinu poolt summutatud jututoad järjestatakse ikkagi ajatempli alusel, sest sa ei pea neid teistega võrreldes piisavalt tähtsaks. + + + + Read receipts + Lugemisteatised + + + + Show if your message was read. +Status is displayed next to timestamps. + Näita, kas sinu sõnum sai loetud. +Lugemise olekut kuvatakse ajatempli kõrval. + + + + Send messages as Markdown + Saada sõnumid Markdown-vormindusena + + + + Allow using markdown in messages. +When disabled, all messages are sent as a plain text. + Luba Markdown-vormingu kasutamine sõnumite koostamisel. +Kui Markdown ei ole kasutusel, siis saadetakse kõik sõnumid vormindamata tekstina. + + + + Desktop notifications + Töölauakeskkonna teavitused + + + + Notify about received message when the client is not currently focused. + Näita saabunud sõnumi teavitust, kui Nheko ei ole parasjagu fookuses. + + + + Alert on notification + Anna teavitustest märku + + + + Show an alert when a message is received. +This usually causes the application icon in the task bar to animate in some fashion. + Sõnumi saabumisel näita teavitust. +See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti animatsiooniga sulle märku. + + + + Highlight message on hover + Üle sõnumi liikumisel too ta esile + + + + Change the background color of messages when you hover over them. + Üle sõnumite liikudes muuda nende taustavärvi. + + + + Large Emoji in timeline + Suured emojid ajajoonel + + + + Make font size larger if messages with only a few emojis are displayed. + Tee sõnumi font suuremaks, kui sõnumis on vaid mõned emojid. + + + + Scale factor + Mastaabitegur + + + + Change the scale factor of the whole user interface. + Muuda kogu kasutajaliidese suurust. + + + + Font size + Fondi suurus + + + + Font Family + Fondiperekond + + + + Theme + Teema + + + + Allow fallback call assist server + Luba kõnehõlbustusserveri kasutamist + + + + Will use turn.matrix.org as assist when your home server does not offer one. + Kui sinu koduserver ei paku välja sobilikku kõnehõlbustusserverit, siis kasuta turn.matrix.org teenust. + + + + Device ID + Seadme tunnus + + + + Device Fingerprint + Seadme sõrmejälg + + + + Session Keys + Sessioonivõtmed + + + + IMPORT + IMPORDI + + + + EXPORT + EKSPORDI + + + + ENCRYPTION + KRÜPTIMINE + + + + GENERAL + ÜLDISED SEADISTUSED + + + + INTERFACE + LIIDES + + + + Emoji Font Family + Fondiperekond emojide jaoks + + + + Open Sessions File + Ava sessioonide fail + + + + + + + + + + + + + Error + Viga + + + + + File Password + Faili salasõna + + + + Enter the passphrase to decrypt the file: + Faili dekrüptimiseks sisesta salafraas: + + + + + The password cannot be empty + Salasõna ei saa olla tühi + + + + Enter passphrase to encrypt your session keys: + Oma sessioonivõtmete krüptimiseks sisesta salafraas: + + + + File to save the exported session keys + Fail, kuhu salvestad eksporditavad sessiooni krüptovõtmed + + + + WelcomePage + + + Welcome to nheko! The desktop client for the Matrix protocol. + Tere tulemast nheko kasutajaks! Töölauarakendus Matrix'i protokolli jaoks. + + + + Enjoy your stay! + Head suhtlemist! + + + + REGISTER + REGISTREERU + + + + LOGIN + LOGI SISSE + + + + descriptiveTime + + + Yesterday + Eile + + + + dialogs::AcceptCall + + + Accept + Nõustu + + + + Reject + Ära võta vastu + + + + dialogs::CreateRoom + + + Create room + Loo jututuba + + + + Cancel + Tühista + + + + Name + Nimi + + + + Topic + Teema + + + + Alias + Alias + + + + Room Visibility + Jututoa nähtavus + + + + Room Preset + Jututoa tüüp + + + + Direct Chat + Otsevestlus + + + + dialogs::FallbackAuth + + + Open Fallback in Browser + Ava kasutaja registreerimise tagavaravariant veebibrauseris + + + + Cancel + Katkesta + + + + Confirm + Kinnita + + + + Open the fallback, follow the steps and confirm after completing them. + Ava kasutaja registreerimise tagavaravariant, läbi kõik sammud ja kinnita seda, kui kõik valmis on. + + + + dialogs::InviteUsers + + + Cancel + Tühista + + + + User ID to invite + Kasutajatunnus, kellele soovid kutset saata + + + + dialogs::JoinRoom + + + Join + Liitu + + + + Cancel + Tühista + + + + Room ID or alias + Jututoa tunnus või alias + + + + dialogs::LeaveRoom + + + Cancel + Tühista + + + + Are you sure you want to leave? + Kas sa oled kindel, et soovid lahkuda? + + + + dialogs::Logout + + + Cancel + Tühista + + + + Logout. Are you sure? + Logime nüüd välja. Kas sa oled kindel? + + + + dialogs::PlaceCall + + + Voice + Häälkõne + + + + Cancel + Loobu + + + + dialogs::PreviewUploadOverlay + + + Upload + Lae üles + + + + Cancel + Tühista + + + + Media type: %1 +Media size: %2 + + Meedia tüüp: %1 +Meedia suurus: %2 + + + + + dialogs::ReCaptcha + + + Cancel + Tühista + + + + Confirm + Kinnita + + + + Solve the reCAPTCHA and press the confirm button + Vasta reCAPTCHA küsimustele ja vajuta kinnita-nuppu + + + + dialogs::ReadReceipts + + + Read receipts + Lugemisteatised + + + + Close + Sulge + + + + dialogs::ReceiptItem + + + Today %1 + Täna %1 + + + + Yesterday %1 + Eile %1 + + + + dialogs::RoomSettings + + + Settings + Seadistused + + + + Info + Teave + + + + Internal ID + Sisemine tunnus + + + + Room Version + Jututoa versioon + + + + Notifications + Teavitused + + + + Muted + Summutatud + + + + Mentions only + Vaid mainimised + + + + All messages + Kõik sõnumid + + + + Room access + Ligipääs jututuppa + + + + Anyone and guests + Kõik (sealhulgas külalised) + + + + Anyone + Kõik, kes teavad jututoa aadressi (aga mitte külalised) + + + + Invited users + Kutsutud kasutajad + + + + Encryption + Krüptimine + + + + End-to-End Encryption + Läbiv krüptimine + + + + Encryption is currently experimental and things might break unexpectedly. <br>Please take note that it can't be disabled afterwards. + 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. + + + + Respond to key requests + Vasta krüptovõtmete päringutele + + + + 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. + 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. + + + + %n member(s) + + %n kasutaja + %n kasutajat + + + + + Failed to enable encryption: %1 + Krüptimise kasutuselevõtmine ei õnnestunud: %1 + + + + Select an avatar + Vali tunnuspilt + + + + All Files (*) + Kõik failid (*) + + + + The selected file is not an image + Valitud fail ei ole pildifail + + + + Error while reading file: %1 + Viga faili lugemisel: %1 + + + + + Failed to upload image: %s + Viga faili üleslaadimisel: %1 + + + + dialogs::UserProfile + + + Ban the user from the room + Sea kasutajale siin jututoas suhtluskeeld + + + + Ignore messages from this user + Eira selle kasutaja sõnumeid + + + + Kick the user from the room + Müksa see kasutaja jututoast välja + + + + Start a conversation + Alusta vestlust + + + + Confirm DM + Kinnita otsevestlus + + + + Do you really want to invite %1 (%2) to a direct chat? + Kas sa tõesti soovid saata otsevestluse kutset kasutajale %1 (%2)? + + + + Devices + Seadmed + + + + emoji::Panel + + + Smileys & People + Vigurnäod ja inimesed + + + + Animals & Nature + Loomad ja loodus + + + + Food & Drink + Toit ja jook + + + + Activity + Tegevused + + + + Travel & Places + Reisimine ja kohad + + + + Objects + Esemed + + + + Symbols + Sümbolid + + + + Flags + Lipud + + + + message-description sent: + + + You sent an audio clip + Sa saatsid helifaili + + + + %1 sent an audio clip + %1 saatis helifaili + + + + You sent an image + Sa saatsid pildi + + + + %1 sent an image + %1 saatis pildi + + + + You sent a file + Sa saatsid faili + + + + %1 sent a file + %1 saatis faili + + + + You sent a video + Sa saatsid video + + + + %1 sent a video + %1 saatis video + + + + You sent a sticker + Sa saatsid kleepsu + + + + %1 sent a sticker + %1 saatis kleepsu + + + + You sent a notification + Sa saatsid teavituse + + + + %1 sent a notification + %1 saatis teavituse + + + + You: %1 + Sina: %1 + + + + %1: %2 + %1: %2 + + + + You sent an encrypted message + Sa saatsid krüptitud sõnumi + + + + %1 sent an encrypted message + %1 saatis krüptitud sõnumi + + + + You placed a call + Sa helistasid + + + + %1 placed a call + %1 helistas + + + + You answered a call + Sa vastasid kõnele + + + + %1 answered a call + %1 vastas kõnele + + + + You ended a call + Sa lõpetasid kõne + + + + %1 ended a call + %1 lõpetas kõne + + + + popups::UserMentions + + + This Room + See jututuba + + + + All Rooms + Kõik jututoad + + + + utils + + + Unknown Message Type + Tundmatu sõnumitüüp + + + diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index 9e95ed62..192c07b2 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. OLM-tilin palauttaminen epäonnistui. Ole hyvä ja kirjaudu sisään uudelleen. - + Failed to restore save data. Please login again. Tallennettujen tietojen palauttaminen epäonnistui. Ole hyvä ja kirjaudu sisään uudelleen. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Salausavainten lähetys epäonnistui. Palvelimen vastaus: %1 %2. Ole hyvä ja yritä uudelleen myöhemmin. - - + + Please try to login again: %1 Ole hyvä ja yritä kirjautua sisään uudelleen: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Salattu viesti (salauksen purkuavaimia ei löydetty) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Virhe purkaessa salausta (megolm-avaimien hakeminen tietokannasta epäonnistui) -- + + + + -- 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. + -- Virhe purkaessa salausta (%1) -- + + + + -- 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. + -- Salattu viesti (tuntematon viestityyppi) -- + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored ei tallennettua versiota @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file Lähetä tiedosto - + Write a message... Kirjoita viesti… @@ -633,7 +741,7 @@ Example: https://server.my:8787 Emoji - + Select a file Valitse tiedosto @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) Kaikki tiedostot (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - -- Virhe purkaessa salausta (tietokannan kanssa kommunikointi epäonnistui) -- - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - -- Virhe purkaessa salausta (megolm-avaimien hakeminen tietokannasta epäonnistui) -- - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - -- Virhe purkaessa salausta (%1) -- - - - + Message redaction failed: %1 Viestin poisto epäonnistui: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Tallenna kuva @@ -693,25 +801,13 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Salattu viesti (salauksen purkuavaimia ei löydetty) -- - - - - -- 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. - -- Salattu viesti (tuntematon viestityyppi) -- - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) - %1%2 kirjoittaa - %1 ja %2 kirjoittavat + %1%2 kirjoittaa. + %1 ja %2 kirjoittavat. @@ -760,7 +856,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -825,12 +921,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -854,12 +950,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -872,7 +968,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -912,49 +1008,52 @@ Example: https://server.my:8787 - + No room open - + + Back to room list + + + + + + No room selected + + + + + Room options + Huonevaihtoehdot + + + + Invite users + Kutsu käyttäjiä + + + + Members + Jäsenet + + + + Leave room + Poistu huoneesta + + + + Settings + Asetukset + + + Close Sulje - - TopRoomBar - - - Room options - Huonevaihtoehdot - - - - Mentions - Maininnat - - - - Invite users - Kutsu käyttäjiä - - - - Members - Jäsenet - - - - Leave room - Poistu huoneesta - - - - Settings - Asetukset - - TrayIcon @@ -1014,7 +1113,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Pienennä ilmoitusalueelle @@ -1034,7 +1133,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1197,7 +1301,17 @@ This usually causes the application icon in the task bar to animate in some fash Teema - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID Laitteen tunnus @@ -1207,7 +1321,7 @@ This usually causes the application icon in the task bar to animate in some fash Laitteen sormenjälki - + Session Keys Istunnon avaimet @@ -1227,22 +1341,22 @@ This usually causes the application icon in the task bar to animate in some fash SALAUS - + GENERAL YLEISET ASETUKSET - + INTERFACE - + Emoji Font Family - + Open Sessions File Avaa Istuntoavaintiedosto @@ -1314,11 +1428,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Eilen + + dialogs::AcceptCall + + + Accept + Hyväksy + + + + Reject + + + dialogs::CreateRoom @@ -1442,6 +1569,19 @@ This usually causes the application icon in the task bar to animate in some fash Kirjaudutaan ulos. Oletko varma? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Peruuta + + dialogs::PreviewUploadOverlay @@ -1642,7 +1782,7 @@ Median koko: %2 dialogs::UserProfile - + Ban the user from the room Anna käyttäjälle porttikielto huoneesta @@ -1662,7 +1802,17 @@ Median koko: %2 Aloita keskustelu - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices Laitteet @@ -1713,7 +1863,7 @@ Median koko: %2 message-description sent: - + You sent an audio clip @@ -1792,6 +1942,36 @@ Median koko: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index bf9b36f6..48047e32 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -4,134 +4,174 @@ Cache - + You joined this room. - + Vous avez rejoint ce salon. ChatPage - + Failed to invite user: %1 - + Échec lors de l'invitation de %1 - + Invited user: %1 - + %1 a été invité(e) - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + La migration du cache vers la version actuelle a échoué. Cela peut arriver pour différentes raisons. Signalez le problème et essayez d'utiliser une ancienne version en attendant. Vous pouvez également supprimer le cache manuellement. - + Room %1 created. - + Salon %1 créé. - + + Confirm invite + Confirmer l'invitation + + + + Do you really want to invite %1 (%2)? + Voulez-vous vraiment inviter %1 (%2) ? + + + Failed to invite %1 to %2: %3 - + Échec de l'invitation de %1 dans %2 : %3 - + + Confirm kick + Confirmer l'expulsion + + + + Do you really want to kick %1 (%2)? + Voulez-vous vraiment expulser %1 (%2) ? + + + Failed to kick %1 to %2: %3 - + %1 n'a pas pu être expulsé de %2 : %3 Kicked user: %1 - + L'utilisateur %1 a été expulsé. - + + Confirm ban + Confirmer le bannissement + + + + Do you really want to ban %1 (%2)? + Voulez-vous vraiment bannir %1 (%2) ? + + + Failed to ban %1 in %2: %3 - + L'utilisateur %1 n'a pas pu être banni de %2 : %3 Banned user: %1 - + L'utilisateur %1 a été banni. - + + Confirm unban + Confirmer l'annulation du bannissement + + + + Do you really want to unban %1 (%2)? + Voulez-vous vraiment annuler le bannissement de %1 (%2) ? + + + Failed to unban %1 in %2: %3 - + Échec de l'annulation du bannissement de %1 dans %2 : %3 Unbanned user: %1 - + %1 n'est plus banni(e) - + Failed to upload media. Please try again. - + Échec de l'envoi du média. Veuillez réessayer. - + Cache migration failed! - + Échec de la migration du cache ! Incompatible cache version - + Version du cache incompatible The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - + Le cache sur votre disque est plus récent que cette version de Nheko ne supporte. Veuillez mettre à jour ou supprimer votre cache. - + Failed to restore OLM account. Please login again. - + Échec de la restauration du compte OLM. Veuillez vous reconnecter. - + Failed to restore save data. Please login again. - + Échec de la restauration des données sauvegardées. Veuillez vous reconnecter. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Échec de la configuration des clés de chiffrement. Réponse du serveur : %1 %2. Veuillez réessayer plus tard. - - + + Please try to login again: %1 - + Veuillez vous reconnecter : %1 - + Failed to join room: %1 - + Impossible de rejoindre le salon : %1 You joined the room - + Vous avez rejoint le salon Failed to remove invite: %1 - + Impossible de supprimer l'invitation : %1 Room creation failed: %1 - + Échec de la création du salon : %1 Failed to leave room: %1 - + Impossible de quitter le salon : %1 @@ -139,34 +179,34 @@ All rooms - + Tous les salons Favourite rooms - + Salons favoris Low priority rooms - + Salons basse priorité Server Notices Tag translation for m.server_notice - + Notifications du serveur (tag) - + (étiquette) (community) - + (communauté) @@ -174,12 +214,12 @@ Apply - + Appliquer Cancel - Annuler + Annuler @@ -198,47 +238,47 @@ Search - + Chercher People - + Personnes Nature - + Nature Food - + Nourriture Activity - Activités + Activités Travel - + Voyage Objects - Objets + Objets Symbols - Symboles + Symboles Flags - Drapeaux + Drapeaux @@ -246,12 +286,49 @@ Encrypted - + Chiffré This message is not encrypted! - + Ce message n'est pas chiffré ! + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Évènement chiffré (pas de clé trouvé pour le déchiffrement) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Échec du déchiffrement (échec de la récupération des clés megolm depuis la base de données) -- + + + + -- 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. + -- Erreur de déchiffrement (%1) -- + + + + -- 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. + -- Évènement chiffré (type d'évènement inconnu) -- + + + + -- Replay attack! This message index was reused! -- + -- Attaque par rejeu (replay attack) ! Cet index de message a été réutilisé ! -- + + + + -- Message by unverified device! -- + -- Message d'un appareil non vérifié  -- @@ -259,7 +336,7 @@ Remove - + Retirer @@ -280,7 +357,10 @@ You can also put your homeserver address there, if your server doesn't support .well-known lookup. Example: @user:server.my If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. - + Votre nom de connexion. Un mxid doit commencer par un « @ » suivi de l'identifiant. L'identifiant doit être suivi du nom de serveur, séparé de celui-ci par « : ». +Vous pouvez également spécifier l'adresse de votre serveur ici, si votre serveur ne supporte pas l'identification .well-known. +Exemple : @utilisateur :monserveur.example.com +Si Nheko n'arrive pas à trouver votre serveur, il vous proposera de l'indiquer manuellement. @@ -290,18 +370,19 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th Device name - + Nom de l'appareil A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. - + Un nom pour cet appareil, qui sera montré aux autres utilisateurs lorsque ceux-ci le vérifieront. Si aucun n'est fourni, un nom par défaut est utilisé. The address that can be used to contact you homeservers client API. Example: https://server.my:8787 - + L'adresse qui peut être utilisée pour joindre l'API client de votre serveur. +Exemple : https ://monserveur.example.com :8787 @@ -312,32 +393,32 @@ Example: https://server.my:8787 Autodiscovery failed. Received malformed response. - + Échec de la découverte automatique. Réponse mal formatée reçue. Autodiscovery failed. Unknown error when requesting .well-known. - + Échec de la découverte automatique. Erreur inconnue lors de la demande de .well-known. The required endpoints were not found. Possibly not a Matrix server. - + Les chemins requis n'ont pas été trouvés. Possible qu'il ne s'agisse pas d'un serveur Matrix. Received malformed response. Make sure the homeserver domain is valid. - + Réponse mal formée reçue. Vérifiez que le nom de domaine du serveur est valide. An unknown error occured. Make sure the homeserver domain is valid. - + Une erreur inconnue est survenue. Vérifiez que le nom de domaine du serveur est valide. SSO LOGIN - + CONNEXION SSO @@ -347,7 +428,7 @@ Example: https://server.my:8787 SSO login failed - + Échec de la connexion SSO @@ -360,45 +441,76 @@ Example: https://server.my:8787 OK - + OK MessageDelegate + redacted - + effacé Encryption enabled - + Chiffrement activé room name changed to: %1 - + nom du salon changé en : %1 removed room name - + nom du salon retiré topic changed to: %1 - + sujet changé pour : %1 removed topic - + sujet retiré %1 created and configured room: %2 - + %1 a créé et configuré le salon : %2 + + + + %1 placed a voice call. + %1 a effectué un appel vocal. + + + + %1 placed a video call. + %1 a effectué un appel vidéo. + + + + %1 placed a call. + %1 a appelé. + + + + %1 answered the call. + %1 a répondu à l'appel. + + + + %1 ended the call. + 1% a terminé l'appel. + + + + Negotiating call... + Négociation de l'appel… @@ -406,7 +518,7 @@ Example: https://server.my:8787 unimplemented event: - + Évènement non implémenté : @@ -427,7 +539,7 @@ Example: https://server.my:8787 The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Le nom d'utilisateur ne doit pas être vide, et ne peut contenir que les caractères a à z, 0 à 9, et « . _ = - / ». @@ -437,7 +549,7 @@ Example: https://server.my:8787 Please choose a secure password. The exact requirements for password strength may depend on your server. - + Veuillez choisir un mot de passe fort. Les demandes exactes sur la robustesse du mot de passe peuvent dépendre de votre serveur. @@ -447,12 +559,12 @@ Example: https://server.my:8787 Homeserver - + Serveur A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. - + Un serveur qui autorise les créations de compte. Matrix étant décentralisé, vous devez tout d'abord trouver un serveur sur lequel vous pouvez vous inscrire, ou bien héberger le vôtre. @@ -462,7 +574,7 @@ Example: https://server.my:8787 No supported registration flows! - + Pas de méthode d'inscription supportée ! @@ -488,9 +600,9 @@ Example: https://server.my:8787 RoomInfo - + no version stored - + pas de version enregistrée @@ -503,49 +615,49 @@ Example: https://server.my:8787 Tag room as: - + Étiqueter le salon comme : Favourite Standard matrix tag for favourites - + Favori Low Priority Standard matrix tag for low priority rooms - + Basse priorité Server Notice Standard matrix tag for server notices - + Notification du serveur Adds or removes the specified tag. WhatsThis hint for tag menu actions - + Ajoute ou retire l'étiquette spécifiée. New tag... Add a new tag to the room - + Nouvelle étiquette… New Tag Tag name prompt title - + Nouvelle étiquette Tag: Tag name prompt - + Étiquette : @@ -563,7 +675,7 @@ Example: https://server.my:8787 User settings - + Paramètres utilisateur @@ -578,12 +690,12 @@ Example: https://server.my:8787 Start a new chat - + Commencer une discussion Room directory - + Annuaire des salons @@ -591,49 +703,49 @@ Example: https://server.my:8787 Failed - + Échec Sent - + Envoyé Received - + Reçu Read - + Lu TextInputWidget - + Send a file - + Envoyer un fichier - + Write a message... - Écrivez un message... + Écrivez un message… Send a message - + Envoyer un message Emoji - + Emoji - + Select a file Sélectionnez un fichier @@ -642,318 +754,309 @@ Example: https://server.my:8787 All Files (*) Tous les types de fichiers (*) + + + Place a call + Appeler + + + + Hang up + Raccrocher + Connection lost. Nheko is trying to re-connect... - + Connexion perdue. Nheko essaye de se reconnecter… TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 - + Échec de la suppression du message : %1 - + + + + + Failed to encrypt event, sending aborted! + Échec du chiffrement de l'évènement, envoi abandonné ! + + + Save image - Enregistrer l'image + Enregistrer l'image Save video - + Enregistrer la vidéo Save audio - + Enregistrer l'audio Save file - - - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - + Enregistrer le fichier - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) - - - + + %1%2 est en train d'écrire. + %1 et %2 sont en train d'écrire. %1 opened the room to the public. - + %1 a rendu le salon ouvert au public. %1 made this room require and invitation to join. - + %1 a rendu le rendu le salon joignable uniquement sur invitation. %1 made the room open to guests. - + %1 a rendu le salon ouvert aux invités. %1 has closed the room to guest access. - + %1 a fermé le salon aux invités. %1 made the room history world readable. Events may be now read by non-joined people. - + %1 a rendu l'historique du salon lisible par tout le monde. Les évènement peuvent maintenant être lus par des personnes externes au salon. %1 set the room history visible to members from this point on. - + %1 a rendu l'historique du salon visible aux membre à partir de cet instant. %1 set the room history visible to members since they were invited. - + %1 a rendu l'historique visible aux membres à partir de leur invitation. %1 set the room history visible to members since they joined the room. - + %1 a rendu l'historique du salon visible à partir de l'instant où un membre le rejoint. %1 has changed the room's permissions. - + %1 a changé les permissions du salon. - + %1 was invited. - + %1 a été invité(e). %1 changed their display name and avatar. - + %1 a changé son nom et avatar. %1 changed their display name. - + %1 a changé son nom. %1 changed their avatar. - + %1 a changé son avatar. %1 changed some profile info. - + %1 a changé ses informations de profil. %1 joined. - + %1 a rejoint le salon. %1 rejected their invite. - + %1 a rejeté son invitation. Revoked the invite to %1. - + %1 n'est plus invité. %1 left the room. - + %1 a quitté le salon. Kicked %1. - + %1 a été expulsé. Unbanned %1. - + %1 n'est plus banni. %1 was banned. - + %1 a été banni. %1 redacted their knock. - + %1 ne frappe plus au salon. - + You joined this room. - + Vous avez rejoint ce salon. - + Rejected the knock from %1. - + %1 a été rejeté après avoir frappé au salon. %1 left after having already left! This is a leave event after the user already left and shouldn't happen apart from state resets - + %1 a quitté le salon après l'avoir déjà quitté ! Reason: %1 - + Raison : %1 %1 knocked. - + %1 a frappé au salon. TimelineRow - + React - + Réagir - + Reply - + Répondre Options - + Options TimelineView - + React - + Réagir Reply - + Réponse Read receipts - Accusés de lecture + Accusés de lecture Mark as read - + Marquer comme lu View raw message - + Voir le message brut View decrypted raw message - + Voir le message déchiffré brut Redact message - + Effacer le message Save as - + Enregistrer sous - + No room open - + Aucun salon ouvert - - Close - + + Back to room list + Revenir à la liste des salons - - - TopRoomBar - + + + No room selected + Pas de salon sélectionné + + + Room options - + Options du salon - - Mentions - - - - + Invite users Inviter des utilisateurs - + Members Membres - + Leave room Quitter le salon - + Settings Paramètres + + + Close + Fermer + TrayIcon @@ -973,48 +1076,48 @@ Example: https://server.my:8787 Logout - + Se déconnecter Set custom status message - + Choisir un message de statut personnalisé Custom status message - + Message de statut personnalisé Status: - + Statut : Set presence automatically - + Changer la présence automatiquement Online - + En ligne Unavailable - + Non disponible Offline - + Hors ligne UserSettingsPage - + Minimize to tray Réduire à la barre des tâches @@ -1031,59 +1134,66 @@ Example: https://server.my:8787 Circular Avatars - + Avatars circulaires - + + CALLS + APPELS + + + Keep the application running in the background after closing the client window. - + Conserver l'application en arrière plan après la fermeture de la fenêtre du client. Start the application in the background without showing the client window. - + Démarrer l'application en arrière plan sans montrer la fenêtre du client. Change the appearance of user avatars in chats. OFF - square, ON - Circle. - + Change l'apparence des avatars des utilisateurs dans les discussions. +OFF – carré, ON – cercle. Show a column containing groups and tags next to the room list. - + Affiche une colonne contenant les groupes et tags à côté de la liste des salons. Decrypt messages in sidebar - + Déchiffrer les messages dans la liste des salons Decrypt the messages shown in the sidebar. Only affects messages in encrypted chats. - + Déchiffre les messages montrés dans la liste des salons. +Cela n'affecte que les messages des salons chiffrés. Show buttons in timeline - + Montrer les boutons dans la discussion Show buttons to quickly reply, react or access additional options next to each message. - + Montre les boutons de réponse, réaction ou options additionnelles près de chaque message. Limit width of timeline - + Limiter la largeur de l'historique Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised - + Règle la largeur maximale des messages dans la discussion (en pixels). Cela peut aider la lisibilité sur les écrans larges, quand Nheko est maximisé. @@ -1094,19 +1204,23 @@ Only affects messages in encrypted chats. Show who is typing in a room. This will also enable or disable sending typing notifications to others. - + Montre qui écrit un message dans un salon. +Ceci activera ou désactivera également l'envoi de notifications similaires de votre part. Sort rooms by unreads - + Trier les salons par statut de lecture Display rooms with new messages first. If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. - + Montre les salons qui contiennent de nouveaux messages en premier. +Si non activé, la liste des salons sera uniquement trié en fonction de la date du dernier message. +Si activé, les salons qui ont des notifications actives (le petit cercle avec un chiffre dedans) seront affichés en premier. +Les salons que vous avez rendu silencieux seront toujours triés par date du dernier message, car ceux-ci sont considérés comme moins importants. @@ -1117,79 +1231,82 @@ If this is on, rooms which have active notifications (the small circle with a nu Show if your message was read. Status is displayed next to timestamps. - + Montre si votre message a été lu. +Le statut est montré près de la date des messages. Send messages as Markdown - + Composer les messages au format Markdown Allow using markdown in messages. When disabled, all messages are sent as a plain text. - + Autorise l'utilisation de markdown dans les messages. +Lorsque désactivé, tous les messages sont envoyés en texte brut. Desktop notifications - + Notifier sur le bureau Notify about received message when the client is not currently focused. - + Notifie des messages reçus lorsque la fenêtre du client n'est pas focalisée. Alert on notification - + Alerter sur notification Show an alert when a message is received. This usually causes the application icon in the task bar to animate in some fashion. - + Alerte lorsqu'un message est reçu. +Cela met l'application en évidence dans la barre des tâches. Highlight message on hover - + Surligner les messages survolés Change the background color of messages when you hover over them. - + Change l'arrière plan des messages lorsqu'ils sont survolés avec la souris. Large Emoji in timeline - + Grandes émoticônes dans la discussion Make font size larger if messages with only a few emojis are displayed. - + Augmente la taille de la police lors de l'affichage de messages contenant uniquement quelques emojis. Scale factor - + Facteur d'échelle Change the scale factor of the whole user interface. - + Agrandit l'interface entière de ce facteur. Font size - + Taille de police Font Family - + Nom de police @@ -1197,54 +1314,64 @@ This usually causes the application icon in the task bar to animate in some fash Thème - + + Allow fallback call assist server + Autoriser le serveur de secours pour les appels + + + + Will use turn.matrix.org as assist when your home server does not offer one. + Cela utilisera le serveur turn.matrix.org pour vous aider à rejoindre les appels si votre serveur ne propose pas de fonctionnalité TURN afin de traverser les pare-feu et NAT restrictifs. + + + Device ID - + Identifiant de l'appareil Device Fingerprint - + Empreinte de l'appareil - + Session Keys - + Clés de session IMPORT - + IMPORTER EXPORT - + EXPORTER ENCRYPTION - + CHIFFREMENT - + GENERAL GÉNÉRAL - + INTERFACE - + INTERFACE - + Emoji Font Family - + Nom de Police Emoji - + Open Sessions File - + Ouvrir fichier de sessions @@ -1258,34 +1385,34 @@ This usually causes the application icon in the task bar to animate in some fash Error - + Erreur File Password - + Mot de passe du fichier Enter the passphrase to decrypt the file: - + Entrez la clé secrète pour déchiffrer le fichier  : The password cannot be empty - + Le mot de passe ne peut être vide Enter passphrase to encrypt your session keys: - + Entrez une clé secrète pour chiffrer vos clés de session  : File to save the exported session keys - + Fichier où sauvegarder les clés de session exportées @@ -1314,9 +1441,22 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday - + Hier + + + + dialogs::AcceptCall + + + Accept + Accepter + + + + Reject + Rejeter @@ -1324,12 +1464,12 @@ This usually causes the application icon in the task bar to animate in some fash Create room - + Créer un salon Cancel - Annuler + Annuler @@ -1367,22 +1507,22 @@ This usually causes the application icon in the task bar to animate in some fash Open Fallback in Browser - + Ouvrir la solution de repli dans le navigateur Cancel - Annuler + Annuler Confirm - + Confirmer Open the fallback, follow the steps and confirm after completing them. - + Ouvrez la solution de repli, suivez les étapes et confirmez après les avoir terminées. @@ -1390,7 +1530,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - Annuler + Annuler @@ -1403,12 +1543,12 @@ This usually causes the application icon in the task bar to animate in some fash Join - + Rejoindre Cancel - Annuler + Annuler @@ -1421,7 +1561,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - Annuler + Annuler @@ -1434,7 +1574,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - Annuler + Annuler @@ -1442,6 +1582,19 @@ This usually causes the application icon in the task bar to animate in some fash Déconnexion. Êtes-vous sûr·e ? + + dialogs::PlaceCall + + + Voice + Voix + + + + Cancel + Annuler + + dialogs::PreviewUploadOverlay @@ -1469,12 +1622,12 @@ Taille du média : %2 Cancel - Annuler + Annuler Confirm - + Confirmer @@ -1492,7 +1645,7 @@ Taille du média : %2 Close - + Fermer @@ -1500,12 +1653,12 @@ Taille du média : %2 Today %1 - + Aujourd'hui %1 Yesterday %1 - + Hier %1 @@ -1513,22 +1666,22 @@ Taille du média : %2 Settings - Paramètres + Paramètres Info - + Info Internal ID - + Identifiant interne Room Version - + Version de salon @@ -1573,96 +1726,110 @@ Taille du média : %2 Encryption - + Chiffrement End-to-End Encryption - + Chiffrement bout-à-bout Encryption is currently experimental and things might break unexpectedly. <br>Please take note that it can't be disabled afterwards. - + Le chiffrement est actuellement expérimental, et des choses inattendues peuvent se produire. +Veuillez noter qu'il n'est pas possible de le désactiver ultérieurement. Respond to key requests - + Répondre aux requêtes de clés 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. - + Choisit si le client doit répondre automatiquement ou non avec les clés de session +lorsqu'elles lui sont demandées. Utiliser avec précaution, il s'agit d'une mesure +temporaire pour valider l'implémentation du chiffrement de bout en bout en +attendant que la vérification des appareils soit opérationnelle. %n member(s) - - - + + %n membre + %n membres Failed to enable encryption: %1 - + Échec de l'activation du chiffrement  : %1 Select an avatar - + Sélectionner un avatar All Files (*) - Tous les types de fichiers (*) + Tous les types de fichiers (*) The selected file is not an image - + Le fichier sélectionné n'est pas une image Error while reading file: %1 - + Erreur lors de la lecture du fichier  : %1 Failed to upload image: %s - + Échec de l'envoi de l'image  : %s dialogs::UserProfile - + Ban the user from the room - + Bannir l'utilisateur du salon Ignore messages from this user - + Ignorer les messages de cet utilisateur Kick the user from the room - + Expulser l'utilisateur de ce salon Start a conversation - + Démarrer une conversation - + + Confirm DM + Confirmer message privé + + + + Do you really want to invite %1 (%2) to a direct chat? + Voulez-vous vraiment inviter %1 (%2) dans un chat privé  ? + + + Devices - + Appareils @@ -1711,84 +1878,114 @@ Taille du média : %2 message-description sent: - + You sent an audio clip - + Vous avez envoyé un message audio %1 sent an audio clip - + %1 a envoyé un message audio You sent an image - + Vous avez envoyé une image %1 sent an image - + %1 a envoyé une image You sent a file - + Vous avez envoyé un fichier %1 sent a file - + %1 a envoyé un fichier You sent a video - + Vous avez envoyé une vidéo %1 sent a video - + %1 a envoyé une vidéo You sent a sticker - + Vous avez envoyé un autocollant %1 sent a sticker - + %1 a envoyé un autocollant You sent a notification - + Vous avez envoyé une notification %1 sent a notification - + %1 a envoyé une notification You: %1 - + Vous  : %1 %1: %2 - + %1  : %2 You sent an encrypted message - + Vous avez envoyé un message chiffré %1 sent an encrypted message - + %1 a envoyé un message chiffré + + + + You placed a call + Vous avez appelé + + + + %1 placed a call + %1 a appelé + + + + You answered a call + Vous avez répondu à un appel + + + + %1 answered a call + %1 a répondu à un appel + + + + You ended a call + Vous avez terminé un appel + + + + %1 ended a call + %1 a terminé un appel @@ -1796,12 +1993,12 @@ Taille du média : %2 This Room - + Ce salon All Rooms - + Tous les salons @@ -1809,7 +2006,7 @@ Taille du média : %2 Unknown Message Type - + Type du message inconnu diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts index b5026408..4b9c32d4 100644 --- a/resources/langs/nheko_it.ts +++ b/resources/langs/nheko_it.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. Sei entrato in questa stanza. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 Impossibile invitare l'utente: %1 - + Invited user: %1 Invitato utente: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Migrazione della cache alla versione corrente fallita. Questo può avere diverse cause. Per favore apri una issue e nel frattempo prova ad usare una versione più vecchia. In alternativa puoi provare a cancellare la cache manualmente. - + Room %1 created. Stanza %1 creata. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 Impossibile invitare %1 a %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 Impossibile scacciare %1 a %2: %3 @@ -48,7 +68,17 @@ Scacciato utente: %1 - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 Impossibile bannare %1 in %2: %3 @@ -58,7 +88,17 @@ Utente bannato: %1 - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 Impossibile rimuovere il ban di %1 in %2: %3 @@ -68,12 +108,12 @@ Rimosso il ban dall'utente: %1 - + Failed to upload media. Please try again. Impossibile inviare il file multimediale. Per favore riprova. - + Cache migration failed! Migrazione della cache fallita! @@ -88,28 +128,28 @@ La cache sul tuo disco è più nuova di quella supportata da questa versione di Nheko. Per favore aggiorna o pulisci la tua cache. - + Failed to restore OLM account. Please login again. Impossibile ripristinare l'account OLM. Per favore accedi nuovamente. - + Failed to restore save data. Please login again. Impossibile ripristinare i dati salvati. Per favore accedi nuovamente. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Impossibile configurare le chiavi crittografiche. Risposta del server: %1 %2. Per favore riprova in seguito. - - + + Please try to login again: %1 Per favore prova ad accedere nuovamente: %1 - + Failed to join room: %1 Impossibile accedere alla stanza: %1 @@ -254,6 +294,43 @@ Questo messaggio è in chiaro! + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- Evento Criptato (Chiavi per la decriptazione non trovate) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- Errore di Decrittazione (impossibile recuperare le chiavi megolm dal DB) -- + + + + -- 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. + -- Errore di Decrittazione (%1) -- + + + + -- 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. + -- Evento Criptato (Tipo di evento ignoto) -- + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -371,6 +448,7 @@ Esempio: https://server.mio:8787 MessageDelegate + redacted oscurato @@ -404,6 +482,36 @@ Esempio: https://server.mio:8787 %1 created and configured room: %2 %1 creato e configurata stanza: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -492,7 +600,7 @@ Esempio: https://server.mio:8787 RoomInfo - + no version stored nessuna versione memorizzata @@ -616,13 +724,13 @@ Esempio: https://server.mio:8787 TextInputWidget - + Send a file Invia un file - + Write a message... Scrivi un messaggio… @@ -637,7 +745,7 @@ Esempio: https://server.mio:8787 Emoji - + Select a file Seleziona un file @@ -646,6 +754,16 @@ Esempio: https://server.mio:8787 All Files (*) Tutti i file (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -655,30 +773,20 @@ Esempio: https://server.mio:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - -- Errore di Decriptazione (impossibile comunicare con il DB) -- - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - -- Errore di Decrittazione (impossibile recuperare le chiavi megolm dal DB) -- - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - -- Errore di Decrittazione (%1) -- - - - + Message redaction failed: %1 Oscuramento del messaggio fallito: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Salva immagine @@ -697,20 +805,8 @@ Esempio: https://server.mio:8787 Save file Salva file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Evento Criptato (Chiavi per la decriptazione non trovate) -- - - - - -- 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. - -- Evento Criptato (Tipo di evento ignoto) -- - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -764,7 +860,7 @@ Esempio: https://server.mio:8787 %1 ha cambiato i permessi della stanza. - + %1 was invited. %1 è stato invitato. @@ -829,12 +925,12 @@ Esempio: https://server.mio:8787 %1 ha oscurato la sua bussata. - + You joined this room. Sei entrato in questa stanza. - + Rejected the knock from %1. Rifiutata la bussata di %1. @@ -858,12 +954,12 @@ Esempio: https://server.mio:8787 TimelineRow - + React - + Reply Rispondi @@ -876,7 +972,7 @@ Esempio: https://server.mio:8787 TimelineView - + React @@ -916,49 +1012,52 @@ Esempio: https://server.mio:8787 Salva come - + No room open Nessuna stanza aperta - + + Back to room list + + + + + + No room selected + + + + + Room options + Opzioni della stanza + + + + Invite users + Invita utenti + + + + Members + Membri + + + + Leave room + Lascia la stanza + + + + Settings + Impostazioni + + + Close Chiudi - - TopRoomBar - - - Room options - Opzioni della stanza - - - - Mentions - Menzioni - - - - Invite users - Invita utenti - - - - Members - Membri - - - - Leave room - Lascia la stanza - - - - Settings - Impostazioni - - TrayIcon @@ -1018,7 +1117,7 @@ Esempio: https://server.mio:8787 UserSettingsPage - + Minimize to tray Minimizza nella tray @@ -1038,7 +1137,12 @@ Esempio: https://server.mio:8787 Avatar Circolari - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1201,7 +1305,17 @@ This usually causes the application icon in the task bar to animate in some fash Tema - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID ID Dispositivo @@ -1211,7 +1325,7 @@ This usually causes the application icon in the task bar to animate in some fash Impronta digitale del dispositivo - + Session Keys Chiavi di Sessione @@ -1231,22 +1345,22 @@ This usually causes the application icon in the task bar to animate in some fash CRITTOGRAFIA - + GENERAL GENERALE - + INTERFACE INTERFACCIA - + Emoji Font Family Famiglia dei caratteri delle Emoji - + Open Sessions File Apri File delle Sessioni @@ -1318,11 +1432,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Ieri + + dialogs::AcceptCall + + + Accept + Accetta + + + + Reject + + + dialogs::CreateRoom @@ -1446,6 +1573,19 @@ This usually causes the application icon in the task bar to animate in some fash Uscita. Ne sei certo? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Annulla + + dialogs::PreviewUploadOverlay @@ -1646,7 +1786,7 @@ Peso media: %2 dialogs::UserProfile - + Ban the user from the room Banna l'utente dalla stanza @@ -1666,7 +1806,17 @@ Peso media: %2 Inizia una conversazione - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices Dispositivi @@ -1717,7 +1867,7 @@ Peso media: %2 message-description sent: - + You sent an audio clip Hai inviato una clip audio @@ -1796,6 +1946,36 @@ Peso media: %2 %1 sent an encrypted message %1 ha inviato un messaggio criptato + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_ja.ts b/resources/langs/nheko_ja.ts index a806031b..79fdd9a4 100644 --- a/resources/langs/nheko_ja.ts +++ b/resources/langs/nheko_ja.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 ユーザーを招待できませんでした: %1 - + Invited user: %1 招待されたユーザー: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 %2に%1を招待できませんでした: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 %2に%1を一時的に追放できませんでした: %3 @@ -48,7 +68,17 @@ 一時的に追放されたユーザー: %1 - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 %2で%1を永久追放できませんでした: %3 @@ -58,7 +88,17 @@ 永久追放されたユーザー: %1 - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 %2で%1の永久追放を解除できませんでした: %3 @@ -68,12 +108,12 @@ 永久追放を解除されたユーザー: %1 - + Failed to upload media. Please try again. メディアをアップロードできませんでした。やり直して下さい。 - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. OLMアカウントを復元できませんでした。もう一度ログインして下さい。 - + Failed to restore save data. Please login again. セーブデータを復元できませんでした。もう一度ログインして下さい。 - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. 暗号化鍵を設定できませんでした。サーバーの応答: %1 %2. 後でやり直して下さい。 - - + + Please try to login again: %1 もう一度ログインしてみて下さい: %1 - + Failed to join room: %1 部屋に参加できませんでした: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + -- 暗号化イベント (復号鍵が見つかりません) -- + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + -- 復号エラー (データベースからmegolm鍵を取得できませんでした) -- + + + + -- 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. + -- 復号エラー (%1) -- + + + + -- 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. + -- 暗号化イベント (不明なイベント型です) -- + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted 編集済み @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored バージョンが保存されていません @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file ファイルを送信 - + Write a message... メッセージを書く... @@ -633,7 +741,7 @@ Example: https://server.my:8787 絵文字 - + Select a file ファイルを選択 @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) 全てのファイル (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - -- 復号エラー (データベースと通信できませんでした) -- - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - -- 復号エラー (データベースからmegolm鍵を取得できませんでした) -- - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - -- 復号エラー (%1) -- - - - + Message redaction failed: %1 メッセージを編集できませんでした: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image 画像を保存 @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file ファイルを保存 - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - -- 暗号化イベント (復号鍵が見つかりません) -- - - - - -- 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. - -- 暗号化イベント (不明なイベント型です) -- - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -759,7 +855,7 @@ Example: https://server.my:8787 - + %1 was invited. %1が招待されました。 @@ -824,12 +920,12 @@ Example: https://server.my:8787 %1がノックを編集しました。 - + You joined this room. - + Rejected the knock from %1. %1からのノックを拒否しました。 @@ -853,12 +949,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply 返信 @@ -871,7 +967,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -911,49 +1007,52 @@ Example: https://server.my:8787 名前を付けて保存 - + No room open 部屋が開いていません - + + Back to room list + + + + + + No room selected + + + + + Room options + 部屋のオプション + + + + Invite users + ユーザーを招待 + + + + Members + メンバー + + + + Leave room + 部屋を出る + + + + Settings + 設定 + + + Close 閉じる - - TopRoomBar - - - Room options - 部屋のオプション - - - - Mentions - メンション - - - - Invite users - ユーザーを招待 - - - - Members - メンバー - - - - Leave room - 退室する - - - - Settings - 設定 - - TrayIcon @@ -1013,7 +1112,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray トレイへ最小化 @@ -1033,7 +1132,12 @@ Example: https://server.my:8787 円形アバター - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1196,7 +1300,17 @@ This usually causes the application icon in the task bar to animate in some fash テーマ - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID デバイスID @@ -1206,7 +1320,7 @@ This usually causes the application icon in the task bar to animate in some fash デバイスの指紋 - + Session Keys セッション鍵 @@ -1226,22 +1340,22 @@ This usually causes the application icon in the task bar to animate in some fash 暗号化 - + GENERAL 全般 - + INTERFACE - + Emoji Font Family - + Open Sessions File セッションファイルを開く @@ -1313,11 +1427,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday 昨日 + + dialogs::AcceptCall + + + Accept + 容認 + + + + Reject + + + dialogs::CreateRoom @@ -1441,6 +1568,19 @@ This usually causes the application icon in the task bar to animate in some fash 本当にログアウトしますか? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + キャンセル + + dialogs::PreviewUploadOverlay @@ -1640,7 +1780,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room ユーザーを部屋から永久追放する @@ -1660,7 +1800,17 @@ Media size: %2 会話を始める - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices デバイス @@ -1711,7 +1861,7 @@ Media size: %2 message-description sent: - + You sent an audio clip 音声データを送信しました @@ -1790,6 +1940,36 @@ Media size: %2 %1 sent an encrypted message %1が暗号化されたメッセージを送信しました + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 8d6a9f68..e957c578 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. - + Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file - + Write a message... Typ een bericht... @@ -633,7 +741,7 @@ Example: https://server.my:8787 - + Select a file Kies een bestand @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) Alle bestanden (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Afbeelding opslaan @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -760,7 +856,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -825,12 +921,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -854,12 +950,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -872,7 +968,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -912,47 +1008,50 @@ Example: https://server.my:8787 - + No room open - - Close + + Back to room list - - - TopRoomBar - + + + No room selected + + + + Room options - - Mentions - - - - + Invite users - Gebruikers uitnodigen + Gebruikers uitnodigen - + Members - Leden + Leden - + Leave room - Kamer verlaten + Kamer verlaten - + Settings - Instellingen + Instellingen + + + + Close + @@ -1014,7 +1113,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Minimaliseren naar systeemvak @@ -1034,7 +1133,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1197,7 +1301,17 @@ This usually causes the application icon in the task bar to animate in some fash Thema - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID @@ -1207,7 +1321,7 @@ This usually causes the application icon in the task bar to animate in some fash - + Session Keys @@ -1227,22 +1341,22 @@ This usually causes the application icon in the task bar to animate in some fash - + GENERAL ALGEMEEN - + INTERFACE - + Emoji Font Family - + Open Sessions File @@ -1314,11 +1428,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + Accepteren + + + + Reject + + + dialogs::CreateRoom @@ -1442,6 +1569,19 @@ This usually causes the application icon in the task bar to animate in some fash Uitloggen. Weet je het zeker? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Annuleren + + dialogs::PreviewUploadOverlay @@ -1640,7 +1780,7 @@ Mediagrootte: %2 dialogs::UserProfile - + Ban the user from the room @@ -1660,7 +1800,17 @@ Mediagrootte: %2 - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices @@ -1711,7 +1861,7 @@ Mediagrootte: %2 message-description sent: - + You sent an audio clip @@ -1790,6 +1940,36 @@ Mediagrootte: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 934221a2..fd4657d7 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. Nie udało się przywrócić konta OLM. Spróbuj zalogować się ponownie. - + Failed to restore save data. Please login again. Nie udało się przywrócić zapisanych danych. Spróbuj zalogować się ponownie. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 Spróbuj zalogować się ponownie: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file Wyślij plik - + Write a message... Napisz wiadomość… @@ -633,7 +741,7 @@ Example: https://server.my:8787 Emoji - + Select a file Wybierz plik @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) Wszystkie pliki (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 Redagowanie wiadomości nie powiodło się: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Zapisz obraz @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -761,7 +857,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -826,12 +922,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -855,12 +951,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -873,7 +969,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -913,49 +1009,52 @@ Example: https://server.my:8787 - + No room open - + + Back to room list + + + + + + No room selected + + + + + Room options + Ustawienia pokoju + + + + Invite users + Zaproś użytkowników + + + + Members + Członkowie + + + + Leave room + Opuść pokój + + + + Settings + Ustawienia + + + Close - - TopRoomBar - - - Room options - Ustawienia pokoju - - - - Mentions - - - - - Invite users - Zaproś użytkowników - - - - Members - Członkowie - - - - Leave room - Opuść pokój - - - - Settings - Ustawienia - - TrayIcon @@ -1015,7 +1114,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Zminimalizuj do paska zadań @@ -1035,7 +1134,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1198,7 +1302,17 @@ This usually causes the application icon in the task bar to animate in some fash Motyw - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID ID urządzenia @@ -1208,7 +1322,7 @@ This usually causes the application icon in the task bar to animate in some fash Odcisk palca urządzenia - + Session Keys @@ -1228,22 +1342,22 @@ This usually causes the application icon in the task bar to animate in some fash SZYFROWANIE - + GENERAL OGÓLNE - + INTERFACE - + Emoji Font Family - + Open Sessions File @@ -1315,11 +1429,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + Akceptuj + + + + Reject + + + dialogs::CreateRoom @@ -1443,6 +1570,19 @@ This usually causes the application icon in the task bar to animate in some fash Czy na pewno chcesz wylogować się? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + Anuluj + + dialogs::PreviewUploadOverlay @@ -1644,7 +1784,7 @@ Rozmiar multimediów: %2 dialogs::UserProfile - + Ban the user from the room Zablokuj użytkownika w tym pokoju @@ -1664,7 +1804,17 @@ Rozmiar multimediów: %2 Rozpocznij rozmowę - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices Urządzenia @@ -1715,7 +1865,7 @@ Rozmiar multimediów: %2 message-description sent: - + You sent an audio clip @@ -1794,6 +1944,36 @@ Rozmiar multimediów: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_ro.ts b/resources/langs/nheko_ro.ts index 659c8f6c..9468bb28 100644 --- a/resources/langs/nheko_ro.ts +++ b/resources/langs/nheko_ro.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. - + Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file - + Write a message... @@ -633,7 +741,7 @@ Example: https://server.my:8787 - + Select a file @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -761,7 +857,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -826,12 +922,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -855,12 +951,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -873,7 +969,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -913,48 +1009,51 @@ Example: https://server.my:8787 - + No room open - - Close + + Back to room list - - - TopRoomBar - + + + No room selected + + + + Room options - - Mentions - - - - + Invite users - + Members - + Leave room - + Settings + + + Close + + TrayIcon @@ -1015,7 +1114,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -1035,7 +1134,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1198,7 +1302,17 @@ This usually causes the application icon in the task bar to animate in some fash - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID @@ -1208,7 +1322,7 @@ This usually causes the application icon in the task bar to animate in some fash - + Session Keys @@ -1228,22 +1342,22 @@ This usually causes the application icon in the task bar to animate in some fash - + GENERAL - + INTERFACE - + Emoji Font Family - + Open Sessions File @@ -1315,11 +1429,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + + + + + Reject + + + dialogs::CreateRoom @@ -1443,6 +1570,19 @@ This usually causes the application icon in the task bar to animate in some fash + + dialogs::PlaceCall + + + Voice + + + + + Cancel + + + dialogs::PreviewUploadOverlay @@ -1640,7 +1780,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room @@ -1660,7 +1800,17 @@ Media size: %2 - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices @@ -1711,7 +1861,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1790,6 +1940,36 @@ Media size: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 541b0df9..95cef767 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. Не удалось восстановить учетную запись OLM. Пожалуйста, войдите снова. - + Failed to restore save data. Please login again. Не удалось восстановить сохраненные данные. Пожалуйста, войдите снова. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Не удалось настроить ключи шифрования. Ответ сервера:%1 %2. Пожалуйста, попробуйте позже. - - + + Please try to login again: %1 Повторите попытку входа: %1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file Отправить файл - + Write a message... Написать сообщение... @@ -633,7 +741,7 @@ Example: https://server.my:8787 - + Select a file Выберите файл @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) Все файлы (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 Ошибка редактирования сообщения: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image Сохранить изображение @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -761,7 +857,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -826,12 +922,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -855,12 +951,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -873,7 +969,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -913,47 +1009,50 @@ Example: https://server.my:8787 - + No room open - - Close - Закрыть - - - - TopRoomBar - - - Room options - Настройки комнаты - - - - Mentions + + Back to room list - + + + No room selected + + + + + Room options + Настройки комнаты + + + Invite users - Пригласить пользователей + Пригласить пользователей - + Members - Участники + Участники - + Leave room - Покинуть комнату + Покинуть комнату - + Settings - Настройки + Настройки + + + + Close + Закрыть @@ -1015,7 +1114,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Сворачивать в системную панель @@ -1035,7 +1134,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1198,7 +1302,17 @@ This usually causes the application icon in the task bar to animate in some fash Тема - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID ID устройства @@ -1208,7 +1322,7 @@ This usually causes the application icon in the task bar to animate in some fash Отпечаток устройства - + Session Keys Ключи сеанса @@ -1228,22 +1342,22 @@ This usually causes the application icon in the task bar to animate in some fash ШИФРОВАНИЕ - + GENERAL ГЛАВНОЕ - + INTERFACE - + Emoji Font Family - + Open Sessions File Открыть файл сеансов @@ -1316,11 +1430,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + Принять + + + + Reject + + + dialogs::CreateRoom @@ -1444,6 +1571,19 @@ This usually causes the application icon in the task bar to animate in some fash Выйти из учётной записи. Вы уверены? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + + + dialogs::PreviewUploadOverlay @@ -1643,7 +1783,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room Заблокировать пользователя в комнате @@ -1663,7 +1803,17 @@ Media size: %2 Начать разговор - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices Устройства @@ -1714,7 +1864,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1793,6 +1943,36 @@ Media size: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_si.ts b/resources/langs/nheko_si.ts index 2f405ca2..d490b4d1 100644 --- a/resources/langs/nheko_si.ts +++ b/resources/langs/nheko_si.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. - + Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 - + Failed to join room: %1 @@ -151,6 +191,12 @@ Low priority rooms + + + Server Notices + Tag translation for m.server_notice + + @@ -166,7 +212,7 @@ EditModal - + Apply @@ -186,6 +232,55 @@ + + EmojiPicker + + + + Search + + + + + People + + + + + Nature + + + + + Food + + + + + Activity + + + + + Travel + + + + + Objects + + + + + Symbols + + + + + Flags + + + EncryptionIndicator @@ -199,10 +294,47 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem - + Remove @@ -210,7 +342,7 @@ LoginPage - + Matrix ID @@ -239,7 +371,7 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th - A name for this device, which will be shown to others, when verifying your devices. If none is provided, a random string is used for privacy purposes. + A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. @@ -250,7 +382,7 @@ Example: https://server.my:8787 - + LOGIN @@ -312,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -345,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -365,7 +528,7 @@ Example: https://server.my:8787 RegisterPage - + Username @@ -433,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -451,7 +614,7 @@ Example: https://server.my:8787 - + Favourite Standard matrix tag for favourites @@ -469,7 +632,7 @@ Example: https://server.my:8787 - + Adds or removes the specified tag. WhatsThis hint for tag menu actions @@ -481,14 +644,15 @@ Example: https://server.my:8787 - + New Tag Tag name prompt title - + Tag: + Tag name prompt @@ -505,7 +669,7 @@ Example: https://server.my:8787 SideBarActions - + User settings @@ -556,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file - + Write a message... @@ -577,7 +741,7 @@ Example: https://server.my:8787 - + Select a file @@ -586,6 +750,16 @@ Example: https://server.my:8787 All Files (*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -595,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image @@ -637,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -704,7 +856,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -723,6 +875,11 @@ Example: https://server.my:8787 %1 changed their avatar. + + + %1 changed some profile info. + + %1 joined. @@ -764,12 +921,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -793,7 +950,12 @@ Example: https://server.my:8787 TimelineRow - + + React + + + + Reply @@ -806,7 +968,12 @@ Example: https://server.my:8787 TimelineView - + + React + + + + Reply @@ -841,48 +1008,51 @@ Example: https://server.my:8787 - + No room open - - Close + + Back to room list - - - TopRoomBar - + + + No room selected + + + + Room options - - Mentions - - - - + Invite users - + Members - + Leave room - + Settings + + + Close + + TrayIcon @@ -900,78 +1070,221 @@ Example: https://server.my:8787 UserInfoWidget - + Logout + + + Set custom status message + + + + + Custom status message + + + + + Status: + + + + + Set presence automatically + + + + + Online + + + + + Unavailable + + + + + Offline + + UserSettingsPage - + Minimize to tray - + Start in tray - + Group's sidebar - + Circular Avatars - + + CALLS + + + + + Keep the application running in the background after closing the client window. + + + + + Start the application in the background without showing the client window. + + + + + Change the appearance of user avatars in chats. +OFF - square, ON - Circle. + + + + + Show a column containing groups and tags next to the room list. + + + + Decrypt messages in sidebar - + + Decrypt the messages shown in the sidebar. +Only affects messages in encrypted chats. + + + + Show buttons in timeline - + + Show buttons to quickly reply, react or access additional options next to each message. + + + + + Limit width of timeline + + + + + Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised + + + + Typing notifications - + + Show who is typing in a room. +This will also enable or disable sending typing notifications to others. + + + + Sort rooms by unreads + Display rooms with new messages first. +If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. +If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. + + + + Read receipts - + + Show if your message was read. +Status is displayed next to timestamps. + + + + Send messages as Markdown - + + Allow using markdown in messages. +When disabled, all messages are sent as a plain text. + + + + Desktop notifications + + + Notify about received message when the client is not currently focused. + + + Alert on notification + + + + + Show an alert when a message is received. +This usually causes the application icon in the task bar to animate in some fashion. + + + + Highlight message on hover + + + Change the background color of messages when you hover over them. + + + + + Large Emoji in timeline + + + + + Make font size larger if messages with only a few emojis are displayed. + + Scale factor + + + Change the scale factor of the whole user interface. + + Font size @@ -988,7 +1301,17 @@ Example: https://server.my:8787 - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID @@ -998,7 +1321,7 @@ Example: https://server.my:8787 - + Session Keys @@ -1018,22 +1341,22 @@ Example: https://server.my:8787 - + GENERAL - + INTERFACE - + Emoji Font Family - + Open Sessions File @@ -1105,11 +1428,24 @@ Example: https://server.my:8787 descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + + + + + Reject + + + dialogs::CreateRoom @@ -1179,7 +1515,7 @@ Example: https://server.my:8787 dialogs::InviteUsers - + Cancel @@ -1233,6 +1569,19 @@ Example: https://server.my:8787 + + dialogs::PlaceCall + + + Voice + + + + + Cancel + + + dialogs::PreviewUploadOverlay @@ -1274,7 +1623,7 @@ Media size: %2 dialogs::ReadReceipts - + Read receipts @@ -1287,12 +1636,12 @@ Media size: %2 dialogs::ReceiptItem - + Today %1 - + Yesterday %1 @@ -1300,7 +1649,7 @@ Media size: %2 dialogs::RoomSettings - + Settings @@ -1429,7 +1778,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room @@ -1449,7 +1798,17 @@ Media size: %2 - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices @@ -1500,7 +1859,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1579,6 +1938,36 @@ Media size: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index 545e098b..e4927ff6 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -4,7 +4,7 @@ Cache - + You joined this room. @@ -12,33 +12,53 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Room %1 created. - + + Confirm invite + + + + + Do you really want to invite %1 (%2)? + + + + Failed to invite %1 to %2: %3 - + + Confirm kick + + + + + Do you really want to kick %1 (%2)? + + + + Failed to kick %1 to %2: %3 @@ -48,7 +68,17 @@ - + + Confirm ban + + + + + Do you really want to ban %1 (%2)? + + + + Failed to ban %1 in %2: %3 @@ -58,7 +88,17 @@ - + + Confirm unban + + + + + Do you really want to unban %1 (%2)? + + + + Failed to unban %1 in %2: %3 @@ -68,12 +108,12 @@ - + Failed to upload media. Please try again. - + Cache migration failed! @@ -88,28 +128,28 @@ - + Failed to restore OLM account. Please login again. 恢复 OLM 账户失败。请重新登录。 - + Failed to restore save data. Please login again. 恢复保存的数据失败。请重新登录。 - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - - + + Please try to login again: %1 请尝试再次登录:%1 - + Failed to join room: %1 @@ -254,6 +294,43 @@ + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- 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. + + + + + -- 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. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + InviteeItem @@ -367,6 +444,7 @@ Example: https://server.my:8787 MessageDelegate + redacted @@ -400,6 +478,36 @@ Example: https://server.my:8787 %1 created and configured room: %2 + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + %1 answered the call. + + + + + %1 ended the call. + + + + + Negotiating call... + + Placeholder @@ -488,7 +596,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -612,13 +720,13 @@ Example: https://server.my:8787 TextInputWidget - + Send a file 发送一个文件 - + Write a message... 写一条消息... @@ -633,7 +741,7 @@ Example: https://server.my:8787 - + Select a file 选择一个文件 @@ -642,6 +750,16 @@ Example: https://server.my:8787 All Files (*) 所有文件(*) + + + Place a call + + + + + Hang up + + Connection lost. Nheko is trying to re-connect... @@ -651,30 +769,20 @@ Example: https://server.my:8787 TimelineModel - - -- Decryption Error (failed to communicate with DB) -- - Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - - - - - -- Decryption Error (failed to retrieve megolm keys from db) -- - Placeholder, when the message can't be decrypted, because the DB access failed. - - - - - -- Decryption Error (%1) -- - Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - - - - + Message redaction failed: %1 删除消息失败:%1 - + + + + + Failed to encrypt event, sending aborted! + + + + Save image 保存图像 @@ -693,20 +801,8 @@ Example: https://server.my:8787 Save file - - - -- Encrypted Event (No keys found for decryption) -- - Placeholder, when the message was not decrypted yet or can't be decrypted. - - - - - -- 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. - - - + %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) @@ -759,7 +855,7 @@ Example: https://server.my:8787 - + %1 was invited. @@ -824,12 +920,12 @@ Example: https://server.my:8787 - + You joined this room. - + Rejected the knock from %1. @@ -853,12 +949,12 @@ Example: https://server.my:8787 TimelineRow - + React - + Reply @@ -871,7 +967,7 @@ Example: https://server.my:8787 TimelineView - + React @@ -911,49 +1007,52 @@ Example: https://server.my:8787 - + No room open - + + Back to room list + + + + + + No room selected + + + + + Room options + 聊天室选项 + + + + Invite users + 邀请用户 + + + + Members + 成员 + + + + Leave room + 离开聊天室 + + + + Settings + 设置 + + + Close - - TopRoomBar - - - Room options - 聊天室选项 - - - - Mentions - - - - - Invite users - 邀请用户 - - - - Members - 成员 - - - - Leave room - 离开聊天室 - - - - Settings - 设置 - - TrayIcon @@ -1013,7 +1112,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray 最小化至托盘 @@ -1033,7 +1132,12 @@ Example: https://server.my:8787 - + + CALLS + + + + Keep the application running in the background after closing the client window. @@ -1196,7 +1300,17 @@ This usually causes the application icon in the task bar to animate in some fash 主题 - + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + Device ID 设备 ID @@ -1206,7 +1320,7 @@ This usually causes the application icon in the task bar to animate in some fash 设备指纹 - + Session Keys 会话密钥 @@ -1226,22 +1340,22 @@ This usually causes the application icon in the task bar to animate in some fash 加密 - + GENERAL 通用 - + INTERFACE - + Emoji Font Family - + Open Sessions File 打开会话文件 @@ -1313,11 +1427,24 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday + + dialogs::AcceptCall + + + Accept + 接受 + + + + Reject + + + dialogs::CreateRoom @@ -1441,6 +1568,19 @@ This usually causes the application icon in the task bar to animate in some fash 登出。确定吗? + + dialogs::PlaceCall + + + Voice + + + + + Cancel + 取消 + + dialogs::PreviewUploadOverlay @@ -1640,7 +1780,7 @@ Media size: %2 dialogs::UserProfile - + Ban the user from the room 在这个聊天室封禁这个用户 @@ -1660,7 +1800,17 @@ Media size: %2 开始一个聊天 - + + Confirm DM + + + + + Do you really want to invite %1 (%2) to a direct chat? + + + + Devices 设备 @@ -1719,7 +1869,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1798,6 +1948,36 @@ Media size: %2 %1 sent an encrypted message + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + popups::UserMentions diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml index e687e170..67c3e008 100644 --- a/resources/qml/Avatar.qml +++ b/resources/qml/Avatar.qml @@ -16,7 +16,7 @@ Rectangle { Label { anchors.fill: parent - text: chat.model.escapeEmoji(String.fromCodePoint(displayName.codePointAt(0))) + text: TimelineManager.escapeEmoji(String.fromCodePoint(displayName.codePointAt(0))) textFormat: Text.RichText font.pixelSize: avatar.height/2 verticalAlignment: Text.AlignVCenter @@ -52,6 +52,8 @@ Rectangle { anchors.bottom: avatar.bottom anchors.right: avatar.right + visible: !!userid + height: avatar.height / 6 width: height radius: Settings.avatarCircles ? height / 2 : height / 4 diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 30158e3a..e6562211 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -147,6 +147,130 @@ Page { z: 3 } + ColumnLayout { + anchors.fill: parent + Rectangle { + id: topBar + + Layout.fillWidth: true + implicitHeight: topLayout.height + 16 + z: 3 + + color: colors.base + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings(); + } + + GridLayout { + id: topLayout + + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 8 + anchors.verticalCenter: parent.verticalCenter + + //Layout.margins: 8 + + ImageButton { + id: backToRoomsButton + + Layout.column: 0 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + + visible: TimelineManager.isNarrowView + + image: ":/icons/icons/ui/angle-pointing-to-left.png" + + ToolTip.visible: hovered + ToolTip.text: qsTr("Back to room list") + + onClicked: TimelineManager.backToRooms() + } + + Avatar { + Layout.column: 1 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + + width: avatarSize + height: avatarSize + + url: chat.model ? chat.model.roomAvatarUrl.replace("mxc://", "image://MxcImage/") : "" + displayName: chat.model ? chat.model.roomName : qsTr("No room selected") + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings(); + } + } + + Label { + Layout.fillWidth: true + Layout.column: 2 + Layout.row: 0 + + font.pointSize: fontMetrics.font.pointSize * 1.1 + + text: chat.model ? chat.model.roomName : qsTr("No room selected") + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings(); + } + } + MatrixText { + Layout.fillWidth: true + Layout.column: 2 + Layout.row: 1 + Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines + clip: true + + text: chat.model ? chat.model.roomTopic : "" + } + + ImageButton { + id: roomOptionsButton + + Layout.column: 3 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + + image: ":/icons/icons/ui/vertical-ellipsis.png" + + ToolTip.visible: hovered + ToolTip.text: qsTr("Room options") + + onClicked: roomOptionsMenu.popup(roomOptionsButton) + + Menu { + id: roomOptionsMenu + MenuItem { + text: qsTr("Invite users") + onTriggered: TimelineManager.openInviteUsersDialog(); + } + MenuItem { + text: qsTr("Members") + onTriggered: TimelineManager.openMemberListDialog(); + } + MenuItem { + text: qsTr("Leave room") + onTriggered: TimelineManager.openLeaveRoomDialog(); + } + MenuItem { + text: qsTr("Settings") + onTriggered: TimelineManager.openRoomSettings(); + } + } + } + } + } + ListView { id: chat @@ -154,13 +278,8 @@ Page { cacheBuffer: 400 - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.bottom: chatFooter.top - width: parent.width - - anchors.leftMargin: 4 - anchors.rightMargin: scrollbar.width + Layout.fillWidth: true + Layout.fillHeight: true model: TimelineManager.timeline @@ -199,10 +318,6 @@ Page { ScrollBar.vertical: ScrollBar { id: scrollbar - parent: chat.parent - anchors.top: chat.top - anchors.right: chat.right - anchors.bottom: chat.bottom } spacing: 4 @@ -210,9 +325,9 @@ Page { onCountChanged: if (atYEnd) model.currentIndex = 0 // Mark last event as read, since we are at the bottom - property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > 32) ? Settings.timelineMaxWidth : (parent.width - 32) + property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > scrollbar.width*2) ? Settings.timelineMaxWidth : (parent.width - scrollbar.width*2) - delegate: Rectangle { + delegate: Item { // This would normally be previousSection, but our model's order is inverted. property bool sectionBoundary: (ListView.nextSection != "" && ListView.nextSection !== ListView.section) || model.index === chat.count - 1 @@ -221,7 +336,6 @@ Page { anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined width: chat.delegateMaxWidth height: section ? section.height + timelinerow.height : timelinerow.height - color: "transparent" TimelineRow { id: timelinerow @@ -314,7 +428,7 @@ Page { Label { id: userName - text: chat.model.escapeEmoji(modelData.userName) + text: TimelineManager.escapeEmoji(modelData.userName) color: TimelineManager.userColor(modelData.userId, colors.window) textFormat: Text.RichText @@ -339,33 +453,35 @@ Page { } } - Rectangle { + Item { id: chatFooter - height: Math.max(fontMetrics.height * 1.2, footerContent.height) - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom + implicitHeight: Math.max(fontMetrics.height * 1.2, footerContent.height) + Layout.fillWidth: true z: 3 - color: "transparent" - Column { id: footerContent anchors.left: parent.left anchors.right: parent.right - - Label { - id: typingDisplay - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 10 - anchors.rightMargin: 10 - - color: colors.text - text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, colors.window) : "" - textFormat: Text.RichText - } + anchors.bottom: parent.bottom + Rectangle { + id: typingRect + anchors.left: parent.left + anchors.right: parent.right + color: (chat.model && chat.model.typingUsers.length > 0) ? colors.window : "transparent" + height: typingDisplay.height + Label { + id: typingDisplay + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 10 + color: colors.text + text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, colors.window) : "" + textFormat: Text.RichText + } + } Rectangle { anchors.left: parent.left @@ -412,4 +528,5 @@ Page { } } } + } } diff --git a/resources/qml/delegates/FileMessage.qml b/resources/qml/delegates/FileMessage.qml index 158daf45..7a2588f3 100644 --- a/resources/qml/delegates/FileMessage.qml +++ b/resources/qml/delegates/FileMessage.qml @@ -41,7 +41,7 @@ Item { Text { id: filename Layout.fillWidth: true - text: model.data.body + text: model.data.filename textFormat: Text.PlainText elide: Text.ElideRight color: colors.text diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index ff025730..a5cb2ae7 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -36,7 +36,7 @@ Item { DelegateChoice { roleValue: MtxEvent.EmoteMessage NoticeMessage { - formatted: chat.model.escapeEmoji(modelData.userName) + " " + model.data.formattedBody + formatted: TimelineManager.escapeEmoji(modelData.userName) + " " + model.data.formattedBody color: TimelineManager.userColor(modelData.userId, colors.window) } } @@ -99,7 +99,11 @@ Item { DelegateChoice { roleValue: MtxEvent.CallInvite NoticeMessage { - text: qsTr("%1 placed a %2 call.").arg(model.data.userName).arg(model.data.callType) + text: switch(model.data.callType) { + case "voice": return qsTr("%1 placed a voice call.").arg(model.data.userName) + case "video": return qsTr("%1 placed a video call.").arg(model.data.userName) + default: return qsTr("%1 placed a call.").arg(model.data.userName) + } } } DelegateChoice { diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index d4fffb06..43fc2814 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -39,7 +39,7 @@ Item { Text { id: userName - text: chat.model ? chat.model.escapeEmoji(reply.modelData.userName) : "" + text: TimelineManager.escapeEmoji(reply.modelData.userName) color: replyComponent.userColor textFormat: Text.RichText diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index 603bb71a..b1751c33 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp @@ -34,10 +34,12 @@ resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback ca { const auto cacheKey = QString("%1_size_%2").arg(avatarUrl).arg(size); - if (avatarUrl.isEmpty()) - return; - QPixmap pixmap; + if (avatarUrl.isEmpty()) { + callback(pixmap); + return; + } + if (avatar_cache.find(cacheKey, &pixmap)) { callback(pixmap); return; @@ -75,11 +77,10 @@ resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback ca opts.mxc_url, mtx::errors::to_string(err->matrix_error.errcode), err->matrix_error.error); - return; + } else { + cache::saveImage(cacheKey.toStdString(), res); } - cache::saveImage(cacheKey.toStdString(), res); - emit proxy->avatarDownloaded(QByteArray(res.data(), res.size())); }); } diff --git a/src/Cache.cpp b/src/Cache.cpp index 07d01819..667506c5 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -96,8 +96,10 @@ namespace { std::unique_ptr instance_ = nullptr; } -static bool -isHiddenEvent(mtx::events::collections::TimelineEvents e, const std::string &room_id) +bool +Cache::isHiddenEvent(lmdb::txn &txn, + mtx::events::collections::TimelineEvents e, + const std::string &room_id) { using namespace mtx::events; if (auto encryptedEvent = std::get_if>(&e)) { @@ -111,13 +113,27 @@ isHiddenEvent(mtx::events::collections::TimelineEvents e, const std::string &roo e = result.event.value(); } - static constexpr std::initializer_list hiddenEvents = { + mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents; + hiddenEvents.hidden_event_types = { EventType::Reaction, EventType::CallCandidates, EventType::Unsupported}; + if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, "")) + hiddenEvents = std::move( + std::get< + mtx::events::Event>( + *temp) + .content); + if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, room_id)) + hiddenEvents = std::move( + std::get< + mtx::events::Event>( + *temp) + .content); + return std::visit( - [](const auto &ev) { - return std::any_of(hiddenEvents.begin(), - hiddenEvents.end(), + [hiddenEvents](const auto &ev) { + return std::any_of(hiddenEvents.hidden_event_types.begin(), + hiddenEvents.hidden_event_types.end(), [ev](EventType type) { return type == ev.type; }); }, e); @@ -646,6 +662,7 @@ Cache::removeRoom(lmdb::txn &txn, const std::string &roomid) { lmdb::dbi_del(txn, roomsDb_, lmdb::val(roomid), nullptr); lmdb::dbi_drop(txn, getStatesDb(txn, roomid), true); + lmdb::dbi_drop(txn, getAccountDataDb(txn, roomid), true); lmdb::dbi_drop(txn, getMembersDb(txn, roomid), true); } @@ -1004,6 +1021,19 @@ Cache::saveState(const mtx::responses::Sync &res) setNextBatchToken(txn, res.next_batch); + if (!res.account_data.events.empty()) { + auto accountDataDb = getAccountDataDb(txn, ""); + for (const auto &ev : res.account_data.events) + std::visit( + [&txn, &accountDataDb](const auto &event) { + lmdb::dbi_put(txn, + accountDataDb, + lmdb::val(to_string(event.type)), + lmdb::val(json(event).dump())); + }, + ev); + } + // Save joined rooms for (const auto &room : res.rooms.join) { auto statesdb = getStatesDb(txn, room.first); @@ -1023,30 +1053,43 @@ Cache::saveState(const mtx::responses::Sync &res) updatedInfo.version = getRoomVersion(txn, statesdb).toStdString(); // Process the account_data associated with this room - bool has_new_tags = false; - for (const auto &evt : room.second.account_data.events) { - // for now only fetch tag events - if (std::holds_alternative>(evt)) { - auto tags_evt = std::get>(evt); - has_new_tags = true; - for (const auto &tag : tags_evt.content.tags) { - updatedInfo.tags.push_back(tag.first); + if (!room.second.account_data.events.empty()) { + auto accountDataDb = getAccountDataDb(txn, room.first); + + bool has_new_tags = false; + for (const auto &evt : room.second.account_data.events) { + std::visit( + [&txn, &accountDataDb](const auto &event) { + lmdb::dbi_put(txn, + accountDataDb, + lmdb::val(to_string(event.type)), + lmdb::val(json(event).dump())); + }, + evt); + + // for tag events + if (std::holds_alternative>(evt)) { + auto tags_evt = std::get>(evt); + has_new_tags = true; + for (const auto &tag : tags_evt.content.tags) { + updatedInfo.tags.push_back(tag.first); + } } } - } - if (!has_new_tags) { - // retrieve the old tags, they haven't changed - lmdb::val data; - if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room.first), data)) { - try { - RoomInfo tmp = - json::parse(std::string_view(data.data(), data.size())); - updatedInfo.tags = tmp.tags; - } catch (const json::exception &e) { - nhlog::db()->warn( - "failed to parse room info: room_id ({}), {}", - room.first, - std::string(data.data(), data.size())); + if (!has_new_tags) { + // retrieve the old tags, they haven't changed + lmdb::val data; + if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room.first), data)) { + try { + RoomInfo tmp = json::parse( + std::string_view(data.data(), data.size())); + updatedInfo.tags = tmp.tags; + } catch (const json::exception &e) { + nhlog::db()->warn( + "failed to parse room info: room_id ({}), {}", + room.first, + std::string(data.data(), data.size())); + } } } } @@ -2463,7 +2506,7 @@ Cache::saveTimelineMessages(lmdb::txn &txn, lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index))); // TODO(Nico): Allow blacklisting more event types in UI - if (!isHiddenEvent(e, room_id)) { + if (!isHiddenEvent(txn, e, room_id)) { ++msgIndex; lmdb::cursor_put(msgCursor.handle(), lmdb::val(&msgIndex, sizeof(msgIndex)), @@ -2546,7 +2589,7 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index))); // TODO(Nico): Allow blacklisting more event types in UI - if (!isHiddenEvent(e, room_id)) { + if (!isHiddenEvent(txn, e, room_id)) { --msgIndex; lmdb::dbi_put( txn, order2msgDb, lmdb::val(&msgIndex, sizeof(msgIndex)), event_id); @@ -2864,6 +2907,24 @@ Cache::deleteOldData() noexcept } } +std::optional +Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id) +{ + try { + auto db = getAccountDataDb(txn, room_id); + + lmdb::val data; + if (lmdb::dbi_get(txn, db, lmdb::val(to_string(type)), data)) { + mtx::responses::utils::RoomAccountDataEvents events; + mtx::responses::utils::parse_room_account_data_events( + std::string_view(data.data(), data.size()), events); + return events.front(); + } + } catch (...) { + } + return std::nullopt; +} + bool Cache::hasEnoughPowerLevel(const std::vector &eventTypes, const std::string &room_id, diff --git a/src/Cache_p.h b/src/Cache_p.h index 7d7b70e6..ce6414ab 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -301,6 +301,14 @@ private: const std::string &room_id, const mtx::responses::Timeline &res); + //! retrieve a specific event from account data + //! pass empty room_id for global account data + std::optional + getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id); + bool isHiddenEvent(lmdb::txn &txn, + mtx::events::collections::TimelineEvents e, + const std::string &room_id); + //! Remove a room from the cache. // void removeLeftRoom(lmdb::txn &txn, const std::string &room_id); template @@ -510,6 +518,12 @@ private: return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE); } + lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id) + { + return lmdb::dbi::open( + txn, std::string(room_id + "/account_data").c_str(), MDB_CREATE); + } + lmdb::dbi getMembersDb(lmdb::txn &txn, const std::string &room_id) { return lmdb::dbi::open(txn, std::string(room_id + "/members").c_str(), MDB_CREATE); diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 704543b5..c6978a59 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -38,7 +38,6 @@ #include "SideBarActions.h" #include "Splitter.h" #include "TextInputWidget.h" -#include "TopRoomBar.h" #include "UserInfoWidget.h" #include "UserSettingsPage.h" #include "Utils.h" @@ -127,10 +126,8 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) contentLayout_->setSpacing(0); contentLayout_->setMargin(0); - top_bar_ = new TopRoomBar(this); view_manager_ = new TimelineViewManager(userSettings_, &callManager_, this); - contentLayout_->addWidget(top_bar_); contentLayout_->addWidget(view_manager_->getWidget()); activeCallBar_ = new ActiveCallBar(this); @@ -182,30 +179,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) room_list_->previousRoom(); }); - connect(top_bar_, &TopRoomBar::mentionsClicked, this, [this](const QPoint &mentionsPos) { - if (user_mentions_popup_->isVisible()) { - user_mentions_popup_->hide(); - } else { - showNotificationsDialog(mentionsPos); - http::client()->notifications( - 1000, - "", - "highlight", - [this, mentionsPos](const mtx::responses::Notifications &res, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to retrieve notifications: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit highlightedNotifsRetrieved(std::move(res), mentionsPos); - }); - } - }); - connectivityTimer_.setInterval(CHECK_CONNECTIVITY_INTERVAL); connect(&connectivityTimer_, &QTimer::timeout, this, [=]() { if (http::client()->access_token().empty()) { @@ -227,8 +200,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::loggedOut, this, &ChatPage::logout); - connect(top_bar_, &TopRoomBar::showRoomList, splitter, &Splitter::showFullRoomList); - connect(top_bar_, &TopRoomBar::inviteUsers, this, [this](QStringList users) { + connect( + view_manager_, &TimelineViewManager::showRoomList, splitter, &Splitter::showFullRoomList); + connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList users) { const auto room_id = current_room_.toStdString(); for (int ii = 0; ii < users.size(); ++ii) { @@ -252,8 +226,10 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) } }); + connect(room_list_, &RoomList::roomChanged, this, [this](QString room_id) { + this->current_room_ = room_id; + }); connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::stopTyping); - connect(room_list_, &RoomList::roomChanged, this, &ChatPage::changeTopRoomInfo); connect(room_list_, &RoomList::roomChanged, splitter, &Splitter::showChatView); connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::focusLineEdit); connect( @@ -488,8 +464,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) } }); - connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar); - connect( this, &ChatPage::updateGroupsInfo, communitiesList_, &CommunitiesList::setCommunities); @@ -589,11 +563,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) }); connect(this, &ChatPage::syncRoomlist, room_list_, &RoomList::sync); connect(this, &ChatPage::syncTags, communitiesList_, &CommunitiesList::syncTags); - connect( - this, &ChatPage::syncTopBar, this, [this](const std::map &updates) { - if (updates.find(currentRoom()) != updates.end()) - changeTopRoomInfo(currentRoom()); - }); // Callbacks to update the user info (top left corner of the page). connect(this, &ChatPage::setUserAvatar, user_info_widget_, &UserInfoWidget::setAvatar); @@ -658,7 +627,6 @@ void ChatPage::resetUI() { room_list_->clear(); - top_bar_->reset(); user_info_widget_->reset(); view_manager_->clearAll(); @@ -787,46 +755,6 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) tryInitialSync(); } -void -ChatPage::updateTopBarAvatar(const QString &roomid, const QString &img) -{ - if (current_room_ != roomid) - return; - - top_bar_->updateRoomAvatar(img); -} - -void -ChatPage::changeTopRoomInfo(const QString &room_id) -{ - if (room_id.isEmpty()) { - nhlog::ui()->warn("cannot switch to empty room_id"); - return; - } - - try { - auto room_info = cache::getRoomInfo({room_id.toStdString()}); - - if (room_info.find(room_id) == room_info.end()) - return; - - const auto name = QString::fromStdString(room_info[room_id].name); - const auto avatar_url = QString::fromStdString(room_info[room_id].avatar_url); - - top_bar_->updateRoomName(name); - top_bar_->updateRoomTopic(QString::fromStdString(room_info[room_id].topic)); - - top_bar_->updateRoomAvatarFromName(name); - if (!avatar_url.isEmpty()) - top_bar_->updateRoomAvatar(avatar_url); - - } catch (const lmdb::error &e) { - nhlog::ui()->error("failed to change top bar room info: {}", e.what()); - } - - current_room_ = room_id; -} - void ChatPage::showUnreadMessageNotification(int count) { @@ -968,14 +896,22 @@ ChatPage::sendNotifications(const mtx::responses::Notifications &res) } if (userSettings_->hasDesktopNotifications()) { - notificationsManager.postNotification( - room_id, - QString::fromStdString(event_id), - QString::fromStdString( - cache::singleRoomInfo(item.room_id).name), - cache::displayName(room_id, user_id), - utils::event_body(item.event), - cache::getRoomAvatar(room_id)); + auto info = cache::singleRoomInfo(item.room_id); + + AvatarProvider::resolve( + QString::fromStdString(info.avatar_url), + 96, + this, + [this, room_id, event_id, item, user_id, info]( + QPixmap image) { + notificationsManager.postNotification( + room_id, + QString::fromStdString(event_id), + QString::fromStdString(info.name), + cache::displayName(room_id, user_id), + utils::event_body(item.event), + image.toImage()); + }); } } } catch (const lmdb::error &e) { @@ -1071,7 +1007,6 @@ ChatPage::handleSyncResponse(mtx::responses::Sync res) auto updates = cache::roomUpdates(res); - emit syncTopBar(updates); emit syncRoomlist(updates); emit syncUI(res.rooms); @@ -1482,9 +1417,12 @@ ChatPage::getProfileInfo() void ChatPage::hideSideBars() { - communitiesList_->hide(); - sideBar_->hide(); - top_bar_->enableBackButton(); + // Don't hide side bar, if we are currently only showing the side bar! + if (view_manager_->getWidget()->isVisible()) { + communitiesList_->hide(); + sideBar_->hide(); + } + view_manager_->enableBackButton(); } void @@ -1494,23 +1432,19 @@ ChatPage::showSideBars() communitiesList_->show(); sideBar_->show(); - top_bar_->disableBackButton(); + view_manager_->disableBackButton(); + content_->show(); } uint64_t ChatPage::timelineWidth() { - int sidebarWidth = sideBar_->size().width(); - sidebarWidth += communitiesList_->size().width(); + int sidebarWidth = sideBar_->minimumSize().width(); + sidebarWidth += communitiesList_->minimumSize().width(); + nhlog::ui()->info("timelineWidth: {}", size().width() - sidebarWidth); return size().width() - sidebarWidth; } -bool -ChatPage::isSideBarExpanded() -{ - const auto sz = splitter::calculateSidebarSizes(QFont{}); - return sideBar_->size().width() > sz.normal; -} void ChatPage::initiateLogout() diff --git a/src/ChatPage.h b/src/ChatPage.h index de4cb4ca..9d8abb24 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -50,7 +50,6 @@ class SideBarActions; class Splitter; class TextInputWidget; class TimelineViewManager; -class TopRoomBar; class UserInfoWidget; class UserSettings; class NotificationsManager; @@ -85,7 +84,6 @@ public: //! Calculate the width of the message timeline. uint64_t timelineWidth(); - bool isSideBarExpanded(); //! Hide the room & group list (if it was visible). void hideSideBars(); //! Show the room/group list (if it was visible). @@ -156,7 +154,6 @@ signals: void syncUI(const mtx::responses::Rooms &rooms); void syncRoomlist(const std::map &updates); void syncTags(const std::map &updates); - void syncTopBar(const std::map &updates); void dropToLoginPageCb(const QString &msg); void notifyMessage(const QString &roomid, @@ -191,8 +188,6 @@ signals: private slots: void showUnreadMessageNotification(int count); - void updateTopBarAvatar(const QString &roomid, const QString &img); - void changeTopRoomInfo(const QString &room_id); void logout(); void removeRoom(const QString &room_id); void dropToLoginPage(const QString &msg); @@ -263,7 +258,6 @@ private: TimelineViewManager *view_manager_; SideBarActions *sidebarActions_; - TopRoomBar *top_bar_; TextInputWidget *text_input_; ActiveCallBar *activeCallBar_; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 59557bff..63722372 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -200,7 +200,8 @@ MainWindow::adjustSideBars() const uint64_t timelineWidth = chat_page_->timelineWidth(); const uint64_t minAvailableWidth = sz.collapsePoint + sz.groups; - if (timelineWidth < minAvailableWidth && !chat_page_->isSideBarExpanded()) { + nhlog::ui()->info("timelineWidth: {}, min {}", timelineWidth, minAvailableWidth); + if (timelineWidth < minAvailableWidth) { chat_page_->hideSideBars(); } else { chat_page_->showSideBars(); @@ -330,9 +331,7 @@ MainWindow::hasActiveUser() void MainWindow::openRoomSettings(const QString &room_id) { - const auto roomToSearch = room_id.isEmpty() ? chat_page_->currentRoom() : ""; - - auto dialog = new dialogs::RoomSettings(roomToSearch, this); + auto dialog = new dialogs::RoomSettings(room_id, this); showDialog(dialog); } @@ -340,8 +339,7 @@ MainWindow::openRoomSettings(const QString &room_id) void MainWindow::openMemberListDialog(const QString &room_id) { - const auto roomToSearch = room_id.isEmpty() ? chat_page_->currentRoom() : ""; - auto dialog = new dialogs::MemberList(roomToSearch, this); + auto dialog = new dialogs::MemberList(room_id, this); showDialog(dialog); } @@ -349,11 +347,9 @@ MainWindow::openMemberListDialog(const QString &room_id) void MainWindow::openLeaveRoomDialog(const QString &room_id) { - auto roomToLeave = room_id.isEmpty() ? chat_page_->currentRoom() : room_id; - auto dialog = new dialogs::LeaveRoom(this); - connect(dialog, &dialogs::LeaveRoom::leaving, this, [this, roomToLeave]() { - chat_page_->leaveRoom(roomToLeave); + connect(dialog, &dialogs::LeaveRoom::leaving, this, [this, room_id]() { + chat_page_->leaveRoom(room_id); }); showDialog(dialog); diff --git a/src/MainWindow.h b/src/MainWindow.h index 2fc2d00f..e66f299f 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -67,14 +67,14 @@ public: static MainWindow *instance() { return instance_; }; void saveCurrentWindowSize(); - void openLeaveRoomDialog(const QString &room_id = ""); + void openLeaveRoomDialog(const QString &room_id); void openInviteUsersDialog(std::function callback); void openCreateRoomDialog( std::function callback); void openJoinRoomDialog(std::function callback); void openLogoutDialog(); - void openRoomSettings(const QString &room_id = ""); - void openMemberListDialog(const QString &room_id = ""); + void openRoomSettings(const QString &room_id); + void openMemberListDialog(const QString &room_id); void openReadReceiptsDialog(const QString &event_id); void hideOverlay(); diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index a197e4aa..b59fdff8 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -17,13 +17,16 @@ MxcImageResponse::run() auto data = cache::image(fileName); if (!data.isNull()) { m_image = utils::readImage(&data); - m_image = m_image.scaled( - m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - m_image.setText("mxc url", "mxc://" + m_id); if (!m_image.isNull()) { - emit finished(); - return; + m_image = m_image.scaled( + m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + m_image.setText("mxc url", "mxc://" + m_id); + + if (!m_image.isNull()) { + emit finished(); + return; + } } } @@ -34,7 +37,7 @@ MxcImageResponse::run() opts.method = "crop"; http::client()->get_thumbnail( opts, [this, fileName](const std::string &res, mtx::http::RequestErr err) { - if (err) { + if (err || res.empty()) { nhlog::net()->error("Failed to download image {}", m_id.toStdString()); m_error = "Failed download"; @@ -46,6 +49,10 @@ MxcImageResponse::run() auto data = QByteArray(res.data(), res.size()); cache::saveImage(fileName, data); m_image = utils::readImage(&data); + if (!m_image.isNull()) { + m_image = m_image.scaled( + m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } m_image.setText("mxc url", "mxc://" + m_id); emit finished(); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 6d57a5f1..4a25c4cf 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -246,7 +246,8 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event) } case Qt::Key_Colon: { QTextEdit::keyPressEvent(event); - trigger_pos_ = textCursor().position() - 1; + trigger_pos_ = textCursor().position() - 1; + emoji_completion_model_->setFilterRegExp(""); emoji_popup_open_ = true; break; } diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp deleted file mode 100644 index a45a751e..00000000 --- a/src/TopRoomBar.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * nheko Copyright (C) 2017 Konstantinos Sideris - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Config.h" -#include "MainWindow.h" -#include "TopRoomBar.h" -#include "Utils.h" -#include "ui/Avatar.h" -#include "ui/FlatButton.h" -#include "ui/Menu.h" -#include "ui/OverlayModal.h" -#include "ui/TextLabel.h" - -TopRoomBar::TopRoomBar(QWidget *parent) - : QWidget(parent) - , buttonSize_{32} -{ - QFont f; - f.setPointSizeF(f.pointSizeF()); - - const int fontHeight = QFontMetrics(f).height(); - const int widgetMargin = fontHeight / 3; - const int contentHeight = fontHeight * 3; - - setFixedHeight(contentHeight + widgetMargin); - - topLayout_ = new QHBoxLayout(this); - topLayout_->setSpacing(widgetMargin); - topLayout_->setContentsMargins( - 2 * widgetMargin, widgetMargin, 2 * widgetMargin, widgetMargin); - - avatar_ = new Avatar(this, fontHeight * 2); - avatar_->setLetter(""); - - textLayout_ = new QVBoxLayout(); - textLayout_->setSpacing(0); - textLayout_->setMargin(0); - - QFont roomFont; - roomFont.setPointSizeF(roomFont.pointSizeF() * 1.1); - roomFont.setWeight(QFont::Medium); - - nameLabel_ = new QLabel(this); - nameLabel_->setFont(roomFont); - nameLabel_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - - QFont descriptionFont; - - topicLabel_ = new TextLabel(this); - topicLabel_->setLineWrapMode(QTextEdit::NoWrap); - topicLabel_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - topicLabel_->setFont(descriptionFont); - topicLabel_->setTextInteractionFlags(Qt::TextBrowserInteraction); - topicLabel_->setOpenExternalLinks(true); - topicLabel_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - - textLayout_->addWidget(nameLabel_); - textLayout_->addWidget(topicLabel_); - - settingsBtn_ = new FlatButton(this); - settingsBtn_->setToolTip(tr("Room options")); - settingsBtn_->setFixedSize(buttonSize_, buttonSize_); - settingsBtn_->setCornerRadius(buttonSize_ / 2); - - mentionsBtn_ = new FlatButton(this); - mentionsBtn_->setToolTip(tr("Mentions")); - mentionsBtn_->setFixedSize(buttonSize_, buttonSize_); - mentionsBtn_->setCornerRadius(buttonSize_ / 2); - - QIcon settings_icon; - settings_icon.addFile(":/icons/icons/ui/vertical-ellipsis.png"); - settingsBtn_->setIcon(settings_icon); - settingsBtn_->setIconSize(QSize(buttonSize_ / 2, buttonSize_ / 2)); - - QIcon mentions_icon; - mentions_icon.addFile(":/icons/icons/ui/at-solid.svg"); - mentionsBtn_->setIcon(mentions_icon); - mentionsBtn_->setIconSize(QSize(buttonSize_ / 2, buttonSize_ / 2)); - - backBtn_ = new FlatButton(this); - backBtn_->setFixedSize(buttonSize_, buttonSize_); - backBtn_->setCornerRadius(buttonSize_ / 2); - - QIcon backIcon; - backIcon.addFile(":/icons/icons/ui/angle-pointing-to-left.png"); - backBtn_->setIcon(backIcon); - backBtn_->setIconSize(QSize(buttonSize_ / 2, buttonSize_ / 2)); - backBtn_->hide(); - - connect(backBtn_, &QPushButton::clicked, this, &TopRoomBar::showRoomList); - - topLayout_->addWidget(avatar_); - topLayout_->addWidget(backBtn_); - topLayout_->addLayout(textLayout_, 1); - topLayout_->addWidget(mentionsBtn_, 0, Qt::AlignRight); - topLayout_->addWidget(settingsBtn_, 0, Qt::AlignRight); - - menu_ = new Menu(this); - - inviteUsers_ = new QAction(tr("Invite users"), this); - connect(inviteUsers_, &QAction::triggered, this, [this]() { - MainWindow::instance()->openInviteUsersDialog( - [this](const QStringList &invitees) { emit inviteUsers(invitees); }); - }); - - roomMembers_ = new QAction(tr("Members"), this); - connect(roomMembers_, &QAction::triggered, this, []() { - MainWindow::instance()->openMemberListDialog(); - }); - - leaveRoom_ = new QAction(tr("Leave room"), this); - connect(leaveRoom_, &QAction::triggered, this, []() { - MainWindow::instance()->openLeaveRoomDialog(); - }); - - roomSettings_ = new QAction(tr("Settings"), this); - connect(roomSettings_, &QAction::triggered, this, []() { - MainWindow::instance()->openRoomSettings(); - }); - - menu_->addAction(inviteUsers_); - menu_->addAction(roomMembers_); - menu_->addAction(leaveRoom_); - menu_->addAction(roomSettings_); - - connect(settingsBtn_, &QPushButton::clicked, this, [this]() { - auto pos = mapToGlobal(settingsBtn_->pos()); - menu_->popup( - QPoint(pos.x() + buttonSize_ - menu_->sizeHint().width(), pos.y() + buttonSize_)); - }); - - connect(mentionsBtn_, &QPushButton::clicked, this, [this]() { - auto pos = mapToGlobal(mentionsBtn_->pos()); - emit mentionsClicked(pos); - }); -} - -void -TopRoomBar::enableBackButton() -{ - avatar_->hide(); - backBtn_->show(); -} - -void -TopRoomBar::disableBackButton() -{ - avatar_->show(); - backBtn_->hide(); -} - -void -TopRoomBar::updateRoomAvatarFromName(const QString &name) -{ - avatar_->setLetter(utils::firstChar(name)); - update(); -} - -void -TopRoomBar::reset() -{ - nameLabel_->setText(""); - topicLabel_->setText(""); - avatar_->setLetter(""); -} - -void -TopRoomBar::updateRoomAvatar(const QString &avatar_image) -{ - avatar_->setImage(avatar_image); - update(); -} - -void -TopRoomBar::updateRoomName(const QString &name) -{ - nameLabel_->setText(name); - update(); -} - -void -TopRoomBar::updateRoomTopic(QString topic) -{ - topic.replace(conf::strings::url_regex, conf::strings::url_html); - topicLabel_->clearLinks(); - topicLabel_->setHtml(topic); - update(); -} - -void -TopRoomBar::mousePressEvent(QMouseEvent *) -{ - if (roomSettings_ != nullptr) - roomSettings_->trigger(); -} - -void -TopRoomBar::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h deleted file mode 100644 index 0c33c1e0..00000000 --- a/src/TopRoomBar.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * nheko Copyright (C) 2017 Konstantinos Sideris - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include -#include - -class Avatar; -class FlatButton; -class Menu; -class TextLabel; -class OverlayModal; - -class QLabel; -class QHBoxLayout; -class QVBoxLayout; - -class TopRoomBar : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) - -public: - TopRoomBar(QWidget *parent = nullptr); - - void updateRoomAvatar(const QString &avatar_image); - void updateRoomName(const QString &name); - void updateRoomTopic(QString topic); - void updateRoomAvatarFromName(const QString &name); - - void reset(); - - QColor borderColor() const { return borderColor_; } - void setBorderColor(QColor &color) { borderColor_ = color; } - -public slots: - //! Add a "back-arrow" button that can switch to roomlist only view. - void enableBackButton(); - //! Replace the "back-arrow" button with the avatar of the room. - void disableBackButton(); - -signals: - void inviteUsers(QStringList users); - void showRoomList(); - void mentionsClicked(const QPoint &pos); - -protected: - void mousePressEvent(QMouseEvent *) override; - void paintEvent(QPaintEvent *) override; - -private: - QHBoxLayout *topLayout_ = nullptr; - QVBoxLayout *textLayout_ = nullptr; - - QLabel *nameLabel_ = nullptr; - TextLabel *topicLabel_ = nullptr; - - Menu *menu_; - QAction *leaveRoom_ = nullptr; - QAction *roomMembers_ = nullptr; - QAction *roomSettings_ = nullptr; - QAction *inviteUsers_ = nullptr; - - FlatButton *settingsBtn_; - FlatButton *mentionsBtn_; - FlatButton *backBtn_; - - Avatar *avatar_; - - int buttonSize_; - - QColor borderColor_; -}; diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index ab5658a4..f1542ec5 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -513,9 +513,6 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge callsLabel->setFont(font); useStunServer_ = new Toggle{this}; - defaultAudioSourceValue_ = new QLabel(this); - defaultAudioSourceValue_->setFont(font); - auto encryptionLabel_ = new QLabel{tr("ENCRYPTION"), this}; encryptionLabel_->setFixedHeight(encryptionLabel_->minimumHeight() + LayoutTopMargin); encryptionLabel_->setAlignment(Qt::AlignBottom); @@ -652,7 +649,6 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge boxWrap(tr("Allow fallback call assist server"), useStunServer_, tr("Will use turn.matrix.org as assist when your home server does not offer one.")); - boxWrap(tr("Default audio source device"), defaultAudioSourceValue_); formLayout_->addRow(encryptionLabel_); formLayout_->addRow(new HorizontalLine{this}); @@ -813,7 +809,6 @@ UserSettingsPage::showEvent(QShowEvent *) deviceIdValue_->setText(QString::fromStdString(http::client()->device_id())); timelineMaxWidthSpin_->setValue(settings_->timelineMaxWidth()); useStunServer_->setState(!settings_->useStunServer()); - defaultAudioSourceValue_->setText(settings_->defaultAudioSource()); deviceFingerprintValue_->setText( utils::humanReadableFingerprint(olm::client()->identity_keys().ed25519)); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 52ff9466..e947bfae 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -250,7 +250,6 @@ private: Toggle *decryptSidebar_; QLabel *deviceFingerprintValue_; QLabel *deviceIdValue_; - QLabel *defaultAudioSourceValue_; QComboBox *themeCombo_; QComboBox *scaleFactorCombo_; diff --git a/src/WebRTCSession.cpp b/src/WebRTCSession.cpp index 64172e61..30a27b60 100644 --- a/src/WebRTCSession.cpp +++ b/src/WebRTCSession.cpp @@ -21,6 +21,7 @@ WebRTCSession::WebRTCSession() { qRegisterMetaType(); connect(this, &WebRTCSession::stateChanged, this, &WebRTCSession::setState); + init(); } bool @@ -78,7 +79,11 @@ WebRTCSession::init(std::string *errorMessage) gst_object_unref(plugin); } - if (!initialised_) { + if (initialised_) { +#if GST_CHECK_VERSION(1, 18, 0) + startDeviceMonitor(); +#endif + } else { nhlog::ui()->error(strError); if (errorMessage) *errorMessage = strError; @@ -95,12 +100,65 @@ namespace { bool isoffering_; std::string localsdp_; std::vector localcandidates_; +std::vector> audioSources_; + +void +addDevice(GstDevice *device) +{ + if (device) { + gchar *name = gst_device_get_display_name(device); + nhlog::ui()->debug("WebRTC: device added: {}", name); + audioSources_.push_back({name, device}); + g_free(name); + } +} + +#if GST_CHECK_VERSION(1, 18, 0) +void +removeDevice(GstDevice *device, bool changed) +{ + if (device) { + if (auto it = std::find_if(audioSources_.begin(), + audioSources_.end(), + [device](const auto &s) { return s.second == device; }); + it != audioSources_.end()) { + nhlog::ui()->debug(std::string("WebRTC: device ") + + (changed ? "changed: " : "removed: ") + "{}", + it->first); + gst_object_unref(device); + audioSources_.erase(it); + } + } +} +#endif gboolean newBusMessage(GstBus *bus G_GNUC_UNUSED, GstMessage *msg, gpointer user_data) { WebRTCSession *session = static_cast(user_data); switch (GST_MESSAGE_TYPE(msg)) { +#if GST_CHECK_VERSION(1, 18, 0) + case GST_MESSAGE_DEVICE_ADDED: { + GstDevice *device; + gst_message_parse_device_added(msg, &device); + addDevice(device); + break; + } + case GST_MESSAGE_DEVICE_REMOVED: { + GstDevice *device; + gst_message_parse_device_removed(msg, &device); + removeDevice(device, false); + break; + } + case GST_MESSAGE_DEVICE_CHANGED: { + GstDevice *device; + GstDevice *oldDevice; + gst_message_parse_device_changed(msg, &device, &oldDevice); + removeDevice(oldDevice, true); + addDevice(device); + break; + } +#endif case GST_MESSAGE_EOS: nhlog::ui()->error("WebRTC: end of stream"); session->end(); @@ -176,7 +234,7 @@ createAnswer(GstPromise *promise, gpointer webrtc) g_signal_emit_by_name(webrtc, "create-answer", nullptr, promise); } -#if GST_CHECK_VERSION(1, 17, 0) +#if GST_CHECK_VERSION(1, 18, 0) void iceGatheringStateChanged(GstElement *webrtc, GParamSpec *pspec G_GNUC_UNUSED, @@ -223,7 +281,7 @@ addLocalICECandidate(GstElement *webrtc G_GNUC_UNUSED, { nhlog::ui()->debug("WebRTC: local candidate: (m-line:{}):{}", mlineIndex, candidate); -#if GST_CHECK_VERSION(1, 17, 0) +#if GST_CHECK_VERSION(1, 18, 0) localcandidates_.push_back({"audio", (uint16_t)mlineIndex, candidate}); return; #else @@ -233,8 +291,10 @@ addLocalICECandidate(GstElement *webrtc G_GNUC_UNUSED, return; } + localcandidates_.push_back({"audio", (uint16_t)mlineIndex, candidate}); + // GStreamer v1.16: webrtcbin's notify::ice-gathering-state triggers - // GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE too early. Fixed in v1.17. + // GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE too early. Fixed in v1.18. // Use a 100ms timeout in the meantime static guint timerid = 0; if (timerid) @@ -423,8 +483,12 @@ WebRTCSession::acceptICECandidates( for (const auto &c : candidates) { nhlog::ui()->debug( "WebRTC: remote candidate: (m-line:{}):{}", c.sdpMLineIndex, c.candidate); - g_signal_emit_by_name( - webrtc_, "add-ice-candidate", c.sdpMLineIndex, c.candidate.c_str()); + if (!c.candidate.empty()) { + g_signal_emit_by_name(webrtc_, + "add-ice-candidate", + c.sdpMLineIndex, + c.candidate.c_str()); + } } } } @@ -471,7 +535,7 @@ WebRTCSession::startPipeline(int opusPayloadType) gst_element_set_state(pipe_, GST_STATE_READY); g_signal_connect(webrtc_, "pad-added", G_CALLBACK(addDecodeBin), pipe_); -#if GST_CHECK_VERSION(1, 17, 0) +#if GST_CHECK_VERSION(1, 18, 0) // capture ICE gathering completion g_signal_connect( webrtc_, "notify::ice-gathering-state", G_CALLBACK(iceGatheringStateChanged), nullptr); @@ -488,7 +552,7 @@ WebRTCSession::startPipeline(int opusPayloadType) } GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipe_)); - gst_bus_add_watch(bus, newBusMessage, this); + busWatchId_ = gst_bus_add_watch(bus, newBusMessage, this); gst_object_unref(bus); emit stateChanged(State::INITIATED); return true; @@ -497,19 +561,18 @@ WebRTCSession::startPipeline(int opusPayloadType) bool WebRTCSession::createPipeline(int opusPayloadType) { - int nSources = audioSources_ ? g_list_length(audioSources_) : 0; - if (nSources == 0) { + if (audioSources_.empty()) { nhlog::ui()->error("WebRTC: no audio sources"); return false; } - if (audioSourceIndex_ < 0 || audioSourceIndex_ >= nSources) { + if (audioSourceIndex_ < 0 || (size_t)audioSourceIndex_ >= audioSources_.size()) { nhlog::ui()->error("WebRTC: invalid audio source index"); return false; } - GstElement *source = gst_device_create_element( - GST_DEVICE_CAST(g_list_nth_data(audioSources_, audioSourceIndex_)), nullptr); + GstElement *source = + gst_device_create_element(audioSources_[audioSourceIndex_].second, nullptr); GstElement *volume = gst_element_factory_make("volume", "srclevel"); GstElement *convert = gst_element_factory_make("audioconvert", nullptr); GstElement *resample = gst_element_factory_make("audioresample", nullptr); @@ -594,12 +657,40 @@ WebRTCSession::end() gst_element_set_state(pipe_, GST_STATE_NULL); gst_object_unref(pipe_); pipe_ = nullptr; + g_source_remove(busWatchId_); + busWatchId_ = 0; } webrtc_ = nullptr; if (state_ != State::DISCONNECTED) emit stateChanged(State::DISCONNECTED); } +#if GST_CHECK_VERSION(1, 18, 0) +void +WebRTCSession::startDeviceMonitor() +{ + if (!initialised_) + return; + + static GstDeviceMonitor *monitor = nullptr; + if (!monitor) { + monitor = gst_device_monitor_new(); + GstCaps *caps = gst_caps_new_empty_simple("audio/x-raw"); + gst_device_monitor_add_filter(monitor, "Audio/Source", caps); + gst_caps_unref(caps); + + GstBus *bus = gst_device_monitor_get_bus(monitor); + gst_bus_add_watch(bus, newBusMessage, nullptr); + gst_object_unref(bus); + if (!gst_device_monitor_start(monitor)) { + nhlog::ui()->error("WebRTC: failed to start device monitor"); + return; + } + } +} + +#else + void WebRTCSession::refreshDevices() { @@ -613,31 +704,42 @@ WebRTCSession::refreshDevices() gst_device_monitor_add_filter(monitor, "Audio/Source", caps); gst_caps_unref(caps); } - g_list_free_full(audioSources_, g_object_unref); - audioSources_ = gst_device_monitor_get_devices(monitor); + + std::for_each(audioSources_.begin(), audioSources_.end(), [](const auto &s) { + gst_object_unref(s.second); + }); + audioSources_.clear(); + GList *devices = gst_device_monitor_get_devices(monitor); + if (devices) { + audioSources_.reserve(g_list_length(devices)); + for (GList *l = devices; l != nullptr; l = l->next) + addDevice(GST_DEVICE_CAST(l->data)); + g_list_free(devices); + } } +#endif std::vector WebRTCSession::getAudioSourceNames(const std::string &defaultDevice) { - if (!initialised_) - return {}; - +#if !GST_CHECK_VERSION(1, 18, 0) refreshDevices(); +#endif + // move default device to top of the list + if (auto it = std::find_if(audioSources_.begin(), + audioSources_.end(), + [&](const auto &s) { return s.first == defaultDevice; }); + it != audioSources_.end()) + std::swap(audioSources_.front(), *it); + std::vector ret; - ret.reserve(g_list_length(audioSources_)); - for (GList *l = audioSources_; l != nullptr; l = l->next) { - gchar *name = gst_device_get_display_name(GST_DEVICE_CAST(l->data)); - ret.emplace_back(name); - g_free(name); - if (ret.back() == defaultDevice) { - // move default device to top of the list - std::swap(audioSources_->data, l->data); - std::swap(ret.front(), ret.back()); - } - } + ret.reserve(audioSources_.size()); + std::for_each(audioSources_.cbegin(), audioSources_.cend(), [&](const auto &s) { + ret.push_back(s.first); + }); return ret; } + #else bool @@ -688,6 +790,10 @@ void WebRTCSession::refreshDevices() {} +void +WebRTCSession::startDeviceMonitor() +{} + std::vector WebRTCSession::getAudioSourceNames(const std::string &) { diff --git a/src/WebRTCSession.h b/src/WebRTCSession.h index 56d76fa8..653ec2cf 100644 --- a/src/WebRTCSession.h +++ b/src/WebRTCSession.h @@ -7,7 +7,6 @@ #include "mtx/events/voip.hpp" -typedef struct _GList GList; typedef struct _GstElement GstElement; class WebRTCSession : public QObject @@ -64,18 +63,19 @@ private slots: private: WebRTCSession(); - bool initialised_ = false; - State state_ = State::DISCONNECTED; - GstElement *pipe_ = nullptr; - GstElement *webrtc_ = nullptr; + bool initialised_ = false; + State state_ = State::DISCONNECTED; + GstElement *pipe_ = nullptr; + GstElement *webrtc_ = nullptr; + unsigned int busWatchId_ = 0; std::string stunServer_; std::vector turnServers_; - GList *audioSources_ = nullptr; int audioSourceIndex_ = -1; bool startPipeline(int opusPayloadType); bool createPipeline(int opusPayloadType); void refreshDevices(); + void startDeviceMonitor(); public: WebRTCSession(WebRTCSession const &) = delete; diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index af1f7b23..298e0d18 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -573,7 +573,7 @@ EventStore::decryptEvent(const IdIndex &idx, room_id_, index.sender_key); dummy.content.body = - tr("-- Reply attack! This message index was reused! --").toStdString(); + tr("-- Replay attack! This message index was reused! --").toStdString(); break; case olm::DecryptionErrorCode::UnknownFingerprint: // TODO: don't fail, just show in UI. diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index ddd238b9..af26a543 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -565,6 +565,25 @@ TimelineModel::fetchMore(const QModelIndex &) events.fetchMore(); } +void +TimelineModel::syncState(const mtx::responses::State &s) +{ + using namespace mtx::events; + + for (const auto &e : s.events) { + if (std::holds_alternative>(e)) + emit roomAvatarUrlChanged(); + else if (std::holds_alternative>(e)) + emit roomNameChanged(); + else if (std::holds_alternative>(e)) + emit roomTopicChanged(); + else if (std::holds_alternative>(e)) { + emit roomAvatarUrlChanged(); + emit roomNameChanged(); + } + } +} + void TimelineModel::addEvents(const mtx::responses::Timeline &timeline) { @@ -574,6 +593,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) events.handleSync(timeline); using namespace mtx::events; + for (auto e : timeline.events) { if (auto encryptedEvent = std::get_if>(&e)) { MegolmSessionIndex index; @@ -597,6 +617,16 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) emit newCallEvent(event); }, e); + else if (std::holds_alternative>(e)) + emit roomAvatarUrlChanged(); + else if (std::holds_alternative>(e)) + emit roomNameChanged(); + else if (std::holds_alternative>(e)) + emit roomTopicChanged(); + else if (std::holds_alternative>(e)) { + emit roomAvatarUrlChanged(); + emit roomNameChanged(); + } } updateLastMessage(); } @@ -737,12 +767,6 @@ TimelineModel::formatDateSeparator(QDate date) const return date.toString(fmt); } -QString -TimelineModel::escapeEmoji(QString str) const -{ - return utils::replaceEmoji(str); -} - void TimelineModel::viewRawMessage(QString id) const { @@ -1440,7 +1464,7 @@ TimelineModel::formatTypingUsers(const std::vector &users, QColor bg) QStringList uidWithoutLast; auto formatUser = [this, bg](const QString &user_id) -> QString { - auto uncoloredUsername = escapeEmoji(displayName(user_id)); + auto uncoloredUsername = utils::replaceEmoji(displayName(user_id)); QString prefix = QString("").arg(manager_->userColor(user_id, bg).name()); @@ -1490,7 +1514,7 @@ TimelineModel::formatJoinRuleEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.join_rule) { case mtx::events::state::JoinRule::Public: @@ -1515,7 +1539,7 @@ TimelineModel::formatGuestAccessEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.guest_access) { case mtx::events::state::AccessState::CanJoin: @@ -1540,7 +1564,7 @@ TimelineModel::formatHistoryVisibilityEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.history_visibility) { case mtx::events::state::Visibility::WorldReadable: @@ -1573,7 +1597,7 @@ TimelineModel::formatPowerLevelEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); // TODO: power levels rendering is actually a bit complex. work on this later. return tr("%1 has changed the room's permissions.").arg(name); @@ -1602,7 +1626,7 @@ TimelineModel::formatMemberEvent(QString id) } QString user = QString::fromStdString(event->state_key); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); QString rendered; // see table https://matrix.org/docs/spec/client_server/latest#m-room-member @@ -1675,3 +1699,37 @@ TimelineModel::formatMemberEvent(QString id) return rendered; } + +QString +TimelineModel::roomName() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return QString::fromStdString(info[room_id_].name); +} + +QString +TimelineModel::roomAvatarUrl() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return QString::fromStdString(info[room_id_].avatar_url); +} + +QString +TimelineModel::roomTopic() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return utils::replaceEmoji(utils::linkifyMessage( + utils::escapeBlacklistedHtml(QString::fromStdString(info[room_id_].topic)))); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 61d00df9..3234a20c 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -146,6 +146,9 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply) Q_PROPERTY( bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) + Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) + Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) public: explicit TimelineModel(TimelineViewManager *manager, @@ -203,7 +206,6 @@ public: Q_INVOKABLE QString formatGuestAccessEvent(QString id); Q_INVOKABLE QString formatPowerLevelEvent(QString id); - Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE void viewRawMessage(QString id) const; Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; Q_INVOKABLE void openUserProfile(QString userid); @@ -226,6 +228,7 @@ public: void updateLastMessage(); void addEvents(const mtx::responses::Timeline &events); + void syncState(const mtx::responses::State &state); template void sendMessageEvent(const T &content, mtx::events::EventType eventType); RelatedInfo relatedInfo(QString id); @@ -262,6 +265,11 @@ public slots: void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; } void clearTimeline() { events.clearTimeline(); } + QString roomName() const; + QString roomTopic() const; + QString roomAvatarUrl() const; + QString roomId() const { return room_id_; } + private slots: void addPendingMessage(mtx::events::collections::TimelineEvents event); @@ -282,6 +290,10 @@ signals: void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void updateFlowEventId(std::string event_id); + void roomNameChanged(); + void roomTopicChanged(); + void roomAvatarUrlChanged(); + private: template void sendEncryptedMessage(mtx::events::RoomEvent msg, mtx::events::EventType eventType); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 97c119bf..03dd4773 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -13,6 +13,7 @@ #include "ColorImageProvider.h" #include "DelegateChooser.h" #include "Logging.h" +#include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" #include "UserSettingsPage.h" @@ -102,7 +103,7 @@ TimelineViewManager::userStatus(QString id) const TimelineViewManager::TimelineViewManager(QSharedPointer userSettings, CallManager *callManager, - QWidget *parent) + ChatPage *parent) : imgProvider(new MxcImageProvider()) , colorImgProvider(new ColorImageProvider()) , blurhashProvider(new BlurhashProvider()) @@ -189,11 +190,8 @@ TimelineViewManager::TimelineViewManager(QSharedPointer userSettin view->engine()->addImageProvider("blurhash", blurhashProvider); view->setSource(QUrl("qrc:///qml/TimelineView.qml")); - connect(dynamic_cast(parent), - &ChatPage::themeChanged, - this, - &TimelineViewManager::updateColorPalette); - connect(dynamic_cast(parent), + connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette); + connect(parent, &ChatPage::decryptSidebarChanged, this, &TimelineViewManager::updateEncryptedDescriptions); @@ -295,7 +293,7 @@ TimelineViewManager::TimelineViewManager(QSharedPointer userSettin } } }); - connect(dynamic_cast(parent), &ChatPage::loggedOut, this, [this]() { + connect(parent, &ChatPage::loggedOut, this, [this]() { isInitialSync_ = true; emit initialSyncChanged(true); }); @@ -313,6 +311,7 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms) &TimelineModel::newCallEvent, callManager_, &CallManager::syncEvent); + room_model->syncState(room.state); room_model->addEvents(room.timeline); if (!isInitialSync_) disconnect(room_model.data(), @@ -363,6 +362,12 @@ TimelineViewManager::setHistoryView(const QString &room_id) } } +QString +TimelineViewManager::escapeEmoji(QString str) const +{ + return utils::replaceEmoji(str); +} + void TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const { @@ -401,6 +406,28 @@ TimelineViewManager::openLink(QString link) const QDesktopServices::openUrl(link); } +void +TimelineViewManager::openInviteUsersDialog() +{ + MainWindow::instance()->openInviteUsersDialog( + [this](const QStringList &invitees) { emit inviteUsers(invitees); }); +} +void +TimelineViewManager::openMemberListDialog() const +{ + MainWindow::instance()->openMemberListDialog(timeline_->roomId()); +} +void +TimelineViewManager::openLeaveRoomDialog() const +{ + MainWindow::instance()->openLeaveRoomDialog(timeline_->roomId()); +} +void +TimelineViewManager::openRoomSettings() const +{ + MainWindow::instance()->openRoomSettings(timeline_->roomId()); +} + void TimelineViewManager::updateReadReceipts(const QString &room_id, const std::vector &event_ids) diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 19406872..4779d3cd 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -22,6 +22,7 @@ class BlurhashProvider; class CallManager; class ColorImageProvider; class UserSettings; +class ChatPage; class DeviceVerificationList : public QObject { @@ -45,11 +46,13 @@ class TimelineViewManager : public QObject TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged) Q_PROPERTY( bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) + Q_PROPERTY( + bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged) public: TimelineViewManager(QSharedPointer userSettings, CallManager *callManager, - QWidget *parent = nullptr); + ChatPage *parent = nullptr); QWidget *getWidget() const { return container; } void sync(const mtx::responses::Rooms &rooms); @@ -59,14 +62,21 @@ public: Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } + bool isNarrowView() const { return isNarrowView_; } Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const; Q_INVOKABLE QColor userColor(QString id, QColor background); + Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString userPresence(QString id) const; Q_INVOKABLE QString userStatus(QString id) const; Q_INVOKABLE void openLink(QString link) const; + Q_INVOKABLE void openInviteUsersDialog(); + Q_INVOKABLE void openMemberListDialog() const; + Q_INVOKABLE void openLeaveRoomDialog() const; + Q_INVOKABLE void openRoomSettings() const; + signals: void clearRoomMessageCount(QString roomid); void updateRoomsLastMessage(QString roomid, const DescInfo &info); @@ -79,6 +89,9 @@ signals: QString userId, QString deviceId, bool isRequest = false); + void inviteUsers(QStringList users); + void showRoomList(); + void narrowViewChanged(); public slots: void updateReadReceipts(const QString &room_id, const std::vector &event_ids); @@ -128,6 +141,23 @@ public slots: timeline_->clearTimeline(); } + void enableBackButton() + { + if (isNarrowView_) + return; + isNarrowView_ = true; + emit narrowViewChanged(); + } + void disableBackButton() + { + if (!isNarrowView_) + return; + isNarrowView_ = false; + emit narrowViewChanged(); + } + + void backToRooms() { emit showRoomList(); } + private: #ifdef USE_QUICK_VIEW QQuickView *view; @@ -145,6 +175,7 @@ private: CallManager *callManager_ = nullptr; bool isInitialSync_ = true; + bool isNarrowView_ = false; QSharedPointer settings; QHash userColors; diff --git a/third_party/blurhash/blurhash.cpp b/third_party/blurhash/blurhash.cpp index cd0a18a4..a4adf89f 100644 --- a/third_party/blurhash/blurhash.cpp +++ b/third_party/blurhash/blurhash.cpp @@ -260,6 +260,7 @@ decode(std::string_view blurhash, size_t width, size_t height, size_t bytesPerPi Components components{}; std::vector values; + values.reserve(blurhash.size() / 2); try { components = unpackComponents(decode83(blurhash.substr(0, 1))); @@ -277,7 +278,7 @@ decode(std::string_view blurhash, size_t width, size_t height, size_t bytesPerPi return {}; } - i.image.reserve(height * width * 3); + i.image.reserve(height * width * bytesPerPixel); for (size_t y = 0; y < height; y++) { for (size_t x = 0; x < width; x++) { @@ -344,7 +345,7 @@ encode(unsigned char *image, size_t width, size_t height, int components_x, int } int quantisedMaximumValue = encodeMaxAC(actualMaximumValue); - maximumValue = ((float)quantisedMaximumValue + 1) / 166; + maximumValue = ((float)quantisedMaximumValue + 1) / 166; h += leftPad(encode83(quantisedMaximumValue), 1); } else { maximumValue = 1; @@ -406,7 +407,7 @@ TEST_CASE("AC") { auto h = "00%#MwS|WCWEM{R*bbWBbH"sv; for (size_t i = 0; i < h.size(); i += 2) { - auto s = h.substr(i, 2); + auto s = h.substr(i, 2); const auto maxAC = 0.289157f; CHECK(leftPad(encode83(encodeAC(decodeAC(decode83(s), maxAC), maxAC)), 2) == s); }