diff --git a/CMakeLists.txt b/CMakeLists.txt index 7871bb6a..4ef6f378 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,7 +242,6 @@ set(SRC_FILES src/TextInputWidget.cpp src/TopRoomBar.cpp src/TrayIcon.cpp - src/TypingDisplay.cpp src/Utils.cpp src/UserInfoWidget.cpp src/UserSettingsPage.cpp @@ -379,7 +378,6 @@ qt5_wrap_cpp(MOC_HEADERS src/TextInputWidget.h src/TopRoomBar.h src/TrayIcon.h - src/TypingDisplay.h src/UserInfoWidget.h src/UserSettingsPage.h src/WelcomePage.h diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index fbc2aa4f..a6d0e98d 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. Medienupload fehlgeschlagen. Bitte versuche es erneut. - + Failed to restore OLM account. Please login again. Wiederherstellung des OLM Accounts fehlgeschlagen. Bitte logge dich erneut ein. @@ -19,7 +19,7 @@ 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. @@ -72,7 +72,7 @@ EditModal - + Apply Anwenden @@ -182,7 +182,7 @@ MessageDelegate - + redacted gelöscht @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Raum suchen… @@ -279,7 +279,7 @@ ReplyPopup - + Logout Abmelden @@ -287,7 +287,7 @@ RoomInfo - + no version stored keine Version gespeichert @@ -300,12 +300,12 @@ Raum verlassen - + Accept Akzeptieren - + Decline Ablehnen @@ -364,13 +364,13 @@ TextInputWidget - + Send a file Versende Datei - + Write a message... Schreibe eine Nachricht… @@ -385,7 +385,7 @@ Emoji - + Select a file Datei auswählen @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted -- verschlüsselter Event (keine Schlüssel zur Entschlüsselung gefunden) -- @@ -427,18 +427,18 @@ -- 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üsselter Event (Unbekannter Eventtyp) -- - + Message redaction failed: %1 Nachricht zurückziehen fehlgeschlagen: %1 - + Save image Bild speichern @@ -457,11 +457,20 @@ Save file Datei speichern + + + %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 tippt + %1 und %2 tippen + + TimelineRow - + Reply Antworten @@ -550,18 +559,6 @@ Schließen - - TypingDisplay - - - %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 tippt - %1 und %2 tippen - - - UserInfoWidget @@ -573,7 +570,7 @@ UserSettingsPage - + Minimize to tray Ins Benachrichtigungsfeld minimieren @@ -740,7 +737,7 @@ descriptiveTime - + Yesterday Gestern @@ -1014,7 +1011,7 @@ Medien-Größe: %2 Aktivierung der Verschlüsselung fehlgeschlagen: %1 - + Select an avatar Wähle einen Avatar @@ -1114,7 +1111,7 @@ Medien-Größe: %2 message-description sent: - + You sent an audio clip Du hast eine Audiodatei gesendet. @@ -1210,7 +1207,7 @@ Medien-Größe: %2 utils - + sent a file. diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index 1d9720ee..35fdeb80 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. @@ -19,7 +19,7 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. @@ -72,7 +72,7 @@ EditModal - + Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Αναζήτηση συνομιλίας... @@ -279,7 +279,7 @@ ReplyPopup - + Logout @@ -287,7 +287,7 @@ RoomInfo - + no version stored @@ -300,12 +300,12 @@ Βγές - + Accept Αποδοχή - + Decline Απόρριψη @@ -364,13 +364,13 @@ TextInputWidget - + Send a file - + Write a message... Γράψε ένα μήνυμα... @@ -385,7 +385,7 @@ - + Select a file Διάλεξε ένα αρχείο @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -427,18 +427,18 @@ - + -- 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 - + Message redaction failed: %1 - + Save image Αποθήκευση Εικόνας @@ -457,11 +457,20 @@ 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.) + + + + + TimelineRow - + Reply @@ -550,18 +559,6 @@ Έξοδος - - TypingDisplay - - - %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.) - - - - - - UserInfoWidget @@ -573,7 +570,7 @@ UserSettingsPage - + Minimize to tray Ελαχιστοποίηση @@ -740,7 +737,7 @@ descriptiveTime - + Yesterday @@ -1012,7 +1009,7 @@ Media size: %2 - + Select an avatar @@ -1112,7 +1109,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1208,7 +1205,7 @@ Media size: %2 utils - + sent a file. diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index fd8b4b25..40b6f09b 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. Failed to restore OLM account. Please login again. @@ -19,7 +19,7 @@ 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. @@ -72,7 +72,7 @@ EditModal - + Apply Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Search for a room… @@ -279,7 +279,7 @@ ReplyPopup - + Logout Logout @@ -287,7 +287,7 @@ RoomInfo - + no version stored no version stored @@ -300,12 +300,12 @@ Leave room - + Accept Accept - + Decline Decline @@ -364,13 +364,13 @@ TextInputWidget - + Send a file Send a file - + Write a message... Write a message… @@ -385,7 +385,7 @@ Emoji - + Select a file Select a file @@ -403,7 +403,7 @@ TimelineModel - + -- 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) -- @@ -427,18 +427,18 @@ -- 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) -- - + Message redaction failed: %1 Message redaction failed: %1 - + Save image Save image @@ -457,11 +457,20 @@ 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%2 is typing + %1 and %2 are typing + + TimelineRow - + Reply @@ -550,18 +559,6 @@ Quit - - TypingDisplay - - - %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 is typing - %1 and %2 are typing - - - UserInfoWidget @@ -573,7 +570,7 @@ UserSettingsPage - + Minimize to tray Minimize to tray @@ -740,7 +737,7 @@ descriptiveTime - + Yesterday Yesterday @@ -1016,7 +1013,7 @@ Media size: %2 Failed to enable encryption: %1 - + Select an avatar Select an avatar @@ -1116,7 +1113,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1212,7 +1209,7 @@ Media size: %2 utils - + sent a file. sent a file. diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index d851b879..cae5a109 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. OLM-tilin palauttaminen epäonnistui. Ole hyvä ja kirjaudu sisään uudelleen. @@ -19,7 +19,7 @@ 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. @@ -72,7 +72,7 @@ EditModal - + Apply Tallenna @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Etsi huonetta… @@ -279,7 +279,7 @@ ReplyPopup - + Logout Kirjaudu ulos @@ -287,7 +287,7 @@ RoomInfo - + no version stored ei tallennettua versiota @@ -300,12 +300,12 @@ Poistu huoneesta - + Accept Hyväksy - + Decline Hylkää @@ -364,13 +364,13 @@ TextInputWidget - + Send a file Lähetä tiedosto - + Write a message... Kirjoita viesti… @@ -385,7 +385,7 @@ Emoji - + Select a file Valitse tiedosto @@ -403,7 +403,7 @@ TimelineModel - + -- 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) -- @@ -427,18 +427,18 @@ -- 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) -- - + Message redaction failed: %1 Viestin poisto epäonnistui: %1 - + Save image Tallenna kuva @@ -457,11 +457,20 @@ 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%2 kirjoittaa + %1 ja %2 kirjoittavat + + TimelineRow - + Reply @@ -550,18 +559,6 @@ Lopeta - - TypingDisplay - - - %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 - - - UserInfoWidget @@ -573,7 +570,7 @@ UserSettingsPage - + Minimize to tray Pienennä ilmoitusalueelle @@ -740,7 +737,7 @@ descriptiveTime - + Yesterday Eilen @@ -1016,7 +1013,7 @@ Median koko: %2 Salauksen aktivointi epäonnistui: %1 - + Select an avatar Valitse profiilikuva @@ -1116,7 +1113,7 @@ Median koko: %2 message-description sent: - + You sent an audio clip @@ -1212,7 +1209,7 @@ Median koko: %2 utils - + sent a file. diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index 15494953..3646d061 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. @@ -19,7 +19,7 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. @@ -72,7 +72,7 @@ EditModal - + Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Chercher un salon… @@ -280,7 +280,7 @@ ReplyPopup - + Logout @@ -288,7 +288,7 @@ RoomInfo - + no version stored @@ -301,12 +301,12 @@ Quitter le salon - + Accept Accepter - + Decline Décliner @@ -365,13 +365,13 @@ TextInputWidget - + Send a file - + Write a message... Écrivez un message... @@ -386,7 +386,7 @@ - + Select a file Sélectionnez un fichier @@ -404,7 +404,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -428,18 +428,18 @@ - + -- 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 - + Message redaction failed: %1 - + Save image Enregistrer l'image @@ -458,11 +458,20 @@ 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.) + + + + + TimelineRow - + Reply @@ -551,18 +560,6 @@ Quitter - - TypingDisplay - - - %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.) - - - - - - UserInfoWidget @@ -574,7 +571,7 @@ UserSettingsPage - + Minimize to tray Réduire à la barre des tâches @@ -741,7 +738,7 @@ descriptiveTime - + Yesterday @@ -1015,7 +1012,7 @@ Taille du média : %2 - + Select an avatar @@ -1115,7 +1112,7 @@ Taille du média : %2 message-description sent: - + You sent an audio clip @@ -1211,7 +1208,7 @@ Taille du média : %2 utils - + sent a file. diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 8ff6d5d8..960feb6e 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. @@ -19,7 +19,7 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. @@ -72,7 +72,7 @@ EditModal - + Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Zoek een kamer... @@ -279,7 +279,7 @@ ReplyPopup - + Logout @@ -287,7 +287,7 @@ RoomInfo - + no version stored @@ -300,12 +300,12 @@ Kamer verlaten - + Accept Accepteren - + Decline Afwijzen @@ -364,13 +364,13 @@ TextInputWidget - + Send a file - + Write a message... Typ een bericht... @@ -385,7 +385,7 @@ - + Select a file Kies een bestand @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -427,18 +427,18 @@ - + -- 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 - + Message redaction failed: %1 - + Save image Afbeelding opslaan @@ -457,11 +457,20 @@ 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.) + + + + + TimelineRow - + Reply @@ -550,18 +559,6 @@ Afsluiten - - TypingDisplay - - - %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.) - - - - - - UserInfoWidget @@ -573,7 +570,7 @@ UserSettingsPage - + Minimize to tray Minimaliseren naar systeemvak @@ -740,7 +737,7 @@ descriptiveTime - + Yesterday @@ -1014,7 +1011,7 @@ Mediagrootte: %2 - + Select an avatar @@ -1114,7 +1111,7 @@ Mediagrootte: %2 message-description sent: - + You sent an audio clip @@ -1210,7 +1207,7 @@ Mediagrootte: %2 utils - + sent a file. diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index cb628fa6..a94ab30e 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. Nie udało się przywrócić konta OLM. Spróbuj zalogować się ponownie. @@ -19,7 +19,7 @@ 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. @@ -72,7 +72,7 @@ EditModal - + Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Wyszukaj pokoju… @@ -279,7 +279,7 @@ ReplyPopup - + Logout Wyloguj @@ -287,7 +287,7 @@ RoomInfo - + no version stored @@ -300,12 +300,12 @@ Opuść pokój - + Accept Akceptuj - + Decline Odrzuć @@ -364,13 +364,13 @@ TextInputWidget - + Send a file Wyślij plik - + Write a message... Napisz wiadomość… @@ -385,7 +385,7 @@ Emoji - + Select a file Wybierz plik @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -427,18 +427,18 @@ - + -- 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 - + Message redaction failed: %1 Redagowanie wiadomości nie powiodło się: %1 - + Save image Zapisz obraz @@ -457,11 +457,21 @@ 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.) + + + + + + TimelineRow - + Reply @@ -550,19 +560,6 @@ Zakończ - - TypingDisplay - - - %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.) - - - - - - - UserInfoWidget @@ -574,7 +571,7 @@ UserSettingsPage - + Minimize to tray Zminimalizuj do paska zadań @@ -741,7 +738,7 @@ descriptiveTime - + Yesterday @@ -1018,7 +1015,7 @@ Rozmiar multimediów: %2 Nie udało się włączyć szyfrowania: %1 - + Select an avatar Wybierz awatar @@ -1118,7 +1115,7 @@ Rozmiar multimediów: %2 message-description sent: - + You sent an audio clip @@ -1214,7 +1211,7 @@ Rozmiar multimediów: %2 utils - + sent a file. diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 12b9873e..e8c7a4e8 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. Не удалось восстановить учетную запись OLM. Пожалуйста, войдите снова. @@ -19,7 +19,7 @@ Не удалось восстановить сохраненные данные. Пожалуйста, войдите снова. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Не удалось настроить ключи шифрования. Ответ сервера:%1 %2. Пожалуйста, попробуйте позже. @@ -72,7 +72,7 @@ EditModal - + Apply Применить @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... Поиск комнаты... @@ -279,7 +279,7 @@ ReplyPopup - + Logout Выйти @@ -287,7 +287,7 @@ RoomInfo - + no version stored @@ -300,12 +300,12 @@ Покинуть комнату - + Accept Принять - + Decline Отказаться @@ -364,13 +364,13 @@ TextInputWidget - + Send a file Отправить файл - + Write a message... Написать сообщение... @@ -385,7 +385,7 @@ - + Select a file Выберите файл @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -427,18 +427,18 @@ - + -- 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 - + Message redaction failed: %1 Ошибка редактирования сообщения: %1 - + Save image Сохранить изображение @@ -457,11 +457,21 @@ 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.) + + + + + + TimelineRow - + Reply @@ -550,19 +560,6 @@ Выйти - - TypingDisplay - - - %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.) - - - - - - - UserInfoWidget @@ -574,7 +571,7 @@ UserSettingsPage - + Minimize to tray Сворачивать в системную панель @@ -742,7 +739,7 @@ descriptiveTime - + Yesterday @@ -1017,7 +1014,7 @@ Media size: %2 Не удалось включить шифрование: %1 - + Select an avatar Выберите аватар @@ -1117,7 +1114,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1213,7 +1210,7 @@ Media size: %2 utils - + sent a file. diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index 799a534d..718bcb55 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -4,12 +4,12 @@ ChatPage - + Failed to upload media. Please try again. - + Failed to restore OLM account. Please login again. 恢复 OLM 账户失败。请重新登录。 @@ -19,7 +19,7 @@ 恢复保存的数据失败。请重新登录。 - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. @@ -72,7 +72,7 @@ EditModal - + Apply @@ -182,7 +182,7 @@ MessageDelegate - + redacted @@ -223,7 +223,7 @@ QuickSwitcher - + Search for a room... 寻找一个聊天室... @@ -279,7 +279,7 @@ ReplyPopup - + Logout 登出 @@ -287,7 +287,7 @@ RoomInfo - + no version stored @@ -300,12 +300,12 @@ 离开聊天室 - + Accept 接受 - + Decline 拒绝 @@ -364,13 +364,13 @@ TextInputWidget - + Send a file 发送一个文件 - + Write a message... 写一条消息... @@ -385,7 +385,7 @@ - + Select a file 选择一个文件 @@ -403,7 +403,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -427,18 +427,18 @@ - + -- 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 - + Message redaction failed: %1 删除消息失败:%1 - + Save image 保存图像 @@ -457,11 +457,19 @@ 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.) + + + + TimelineRow - + Reply @@ -550,17 +558,6 @@ 退出 - - TypingDisplay - - - %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.) - - - - - UserInfoWidget @@ -572,7 +569,7 @@ UserSettingsPage - + Minimize to tray 最小化至托盘 @@ -739,7 +736,7 @@ descriptiveTime - + Yesterday @@ -1014,7 +1011,7 @@ Media size: %2 启用加密失败:%1 - + Select an avatar 选择一个头像 @@ -1122,7 +1119,7 @@ Media size: %2 message-description sent: - + You sent an audio clip @@ -1218,7 +1215,7 @@ Media size: %2 utils - + sent a file. diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index bfea79ee..60a8e6c1 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -38,7 +38,11 @@ Item { id: chat visible: timelineManager.timeline != null - anchors.fill: parent + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: chatFooter.top anchors.leftMargin: 4 anchors.rightMargin: scrollbar.width @@ -179,6 +183,31 @@ Item { } } } + + } + + Rectangle { + id: chatFooter + + height: Math.max(16, typingDisplay.height) + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + z: 3 + + color: colors.window + + Text { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.leftMargin: 10 + anchors.rightMargin: 10 + + id: typingDisplay + text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, chatFooter.color) : "" + color: colors.windowText + } } } } diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 777709be..125e229a 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -34,7 +34,6 @@ #include "Splitter.h" #include "TextInputWidget.h" #include "TopRoomBar.h" -#include "TypingDisplay.h" #include "UserInfoWidget.h" #include "UserSettingsPage.h" #include "Utils.h" @@ -130,11 +129,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) text_input_ = new TextInputWidget(this); contentLayout_->addWidget(text_input_); - typingDisplay_ = new TypingDisplay(content_); - typingDisplay_->hide(); - connect( - text_input_, &TextInputWidget::heightChanged, typingDisplay_, &TypingDisplay::setOffset); - typingRefresher_ = new QTimer(this); typingRefresher_->setInterval(TYPING_REFRESH_TIMEOUT); @@ -225,19 +219,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) } }); - connect(room_list_, &RoomList::roomChanged, this, [this](const QString &roomid) { - QStringList users; - - if (!userSettings_->isTypingNotificationsEnabled()) { - typingDisplay_->setUsers(users); - return; - } - - if (typingUsers_.find(roomid) != typingUsers_.end()) - users = typingUsers_[roomid]; - - typingDisplay_->setUsers(users); - }); 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); @@ -472,8 +453,6 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) bool hasNotifications = false; for (const auto &room : rooms.join) { auto room_id = QString::fromStdString(room.first); - - updateTypingUsers(room_id, room.second.ephemeral.typing); updateRoomNotificationCount( room_id, room.second.unread_notifications.notification_count, @@ -786,38 +765,6 @@ ChatPage::removeRoom(const QString &room_id) room_list_->removeRoom(room_id, room_id == current_room_); } -void -ChatPage::updateTypingUsers(const QString &roomid, const std::vector &user_ids) -{ - if (!userSettings_->isTypingNotificationsEnabled()) - return; - - typingUsers_[roomid] = generateTypingUsers(roomid, user_ids); - - if (current_room_ == roomid) - typingDisplay_->setUsers(typingUsers_[roomid]); -} - -QStringList -ChatPage::generateTypingUsers(const QString &room_id, const std::vector &typing_users) -{ - QStringList users; - auto local_user = utils::localUser(); - - for (const auto &uid : typing_users) { - const auto remote_user = QString::fromStdString(uid); - - if (remote_user == local_user) - continue; - - users.append(cache::displayName(room_id, remote_user)); - } - - users.sort(); - - return users; -} - void ChatPage::removeLeftRooms(const std::map &rooms) { diff --git a/src/ChatPage.h b/src/ChatPage.h index e4c0ef16..354a21f3 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -48,7 +48,6 @@ class Splitter; class TextInputWidget; class TimelineViewManager; class TopRoomBar; -class TypingDisplay; class UserInfoWidget; class UserSettings; class NotificationsManager; @@ -187,8 +186,6 @@ private: using LeftRooms = std::map; void removeLeftRooms(const LeftRooms &rooms); - void updateTypingUsers(const QString &roomid, const std::vector &user_ids); - void loadStateFromCache(); void resetUI(); //! Decides whether or not to hide the group's sidebar. @@ -206,9 +203,6 @@ private: void showNotificationsDialog(const QPoint &point); - QStringList generateTypingUsers(const QString &room_id, - const std::vector &typing_users); - QHBoxLayout *topLayout_; Splitter *splitter; @@ -228,7 +222,6 @@ private: TopRoomBar *top_bar_; TextInputWidget *text_input_; - TypingDisplay *typingDisplay_; QTimer connectivityTimer_; std::atomic_bool isConnected_; @@ -240,8 +233,6 @@ private: popups::UserMentions *user_mentions_popup_; - // Keeps track of the users currently typing on each room. - std::map> typingUsers_; QTimer *typingRefresher_; // Global user settings. diff --git a/src/TypingDisplay.cpp b/src/TypingDisplay.cpp deleted file mode 100644 index 43fabcd8..00000000 --- a/src/TypingDisplay.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include -#include - -#include "Config.h" -#include "TypingDisplay.h" -#include "ui/Painter.h" - -constexpr int LEFT_PADDING = 24; -constexpr int RECT_PADDING = 2; - -TypingDisplay::TypingDisplay(QWidget *parent) - : OverlayWidget(parent) - , offset_{conf::textInput::height} -{ - setFixedHeight(QFontMetrics(font()).height() + RECT_PADDING); - setAttribute(Qt::WA_TransparentForMouseEvents); -} - -void -TypingDisplay::setOffset(int margin) -{ - offset_ = margin; - move(0, parentWidget()->height() - offset_ - height()); -} - -void -TypingDisplay::setUsers(const QStringList &uid) -{ - move(0, parentWidget()->height() - offset_ - height()); - - text_.clear(); - - QString temp = text_ += - tr("%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.)", - uid.size()); - - if (uid.isEmpty()) { - hide(); - update(); - - return; - } - - QStringList uidWithoutLast = uid; - uidWithoutLast.pop_back(); - text_ = temp.arg(uidWithoutLast.join(", ")).arg(uid.back()); - - show(); - update(); -} - -void -TypingDisplay::paintEvent(QPaintEvent *) -{ - Painter p(this); - PainterHighQualityEnabler hq(p); - - QFont f; - f.setPointSizeF(f.pointSizeF() * 0.9); - - p.setFont(f); - p.setPen(QPen(textColor())); - - QRect region = rect(); - region.translate(LEFT_PADDING, 0); - - QFontMetrics fm(f); - text_ = fm.elidedText(text_, Qt::ElideRight, (double)(width() * 0.75)); - - QPainterPath path; -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - path.addRoundedRect(QRectF(0, 0, fm.width(text_) + 2 * LEFT_PADDING, height()), 3, 3); -#else - path.addRoundedRect( - QRectF(0, 0, fm.horizontalAdvance(text_) + 2 * LEFT_PADDING, height()), 3, 3); -#endif - p.fillPath(path, backgroundColor()); - p.drawText(region, Qt::AlignVCenter, text_); -} diff --git a/src/TypingDisplay.h b/src/TypingDisplay.h deleted file mode 100644 index 332d9c66..00000000 --- a/src/TypingDisplay.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "ui/OverlayWidget.h" - -class QPaintEvent; - -class TypingDisplay : public OverlayWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - -public: - TypingDisplay(QWidget *parent = nullptr); - - void setUsers(const QStringList &user_ids); - - void setTextColor(const QColor &color) { textColor_ = color; }; - QColor textColor() const { return textColor_; }; - - void setBackgroundColor(const QColor &color) { bgColor_ = color; }; - QColor backgroundColor() const { return bgColor_; }; - -public slots: - void setOffset(int margin); - -protected: - void paintEvent(QPaintEvent *event) override; - -private: - int offset_; - QColor textColor_; - QColor bgColor_; - QString text_; -}; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 08c29927..2fd4b6d4 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1388,3 +1388,33 @@ TimelineModel::cacheMedia(QString eventId) emit mediaCached(mxcUrl, filename.filePath()); }); } + +QString +TimelineModel::formatTypingUsers(const std::vector &users, QColor bg) +{ + QString temp = + tr("%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.)", + users.size()); + + if (users.empty()) { + return ""; + } + + QStringList uidWithoutLast; + + auto formatUser = [this, bg](const QString &user_id) -> QString { + return QString("%2") + .arg(userColor(user_id, bg).name()) + .arg(escapeEmoji(displayName(user_id).toHtmlEscaped())); + }; + + for (size_t i = 0; i + 1 < users.size(); i++) { + uidWithoutLast.append(formatUser(users[i])); + } + + return temp.arg(uidWithoutLast.join(", ")).arg(formatUser(users.back())); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index ae505c17..6d351359 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -120,6 +120,8 @@ class TimelineModel : public QAbstractListModel Q_OBJECT Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(std::vector typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY + typingUsersChanged) public: explicit TimelineModel(TimelineViewManager *manager, QString room_id, QObject *parent = 0); @@ -162,6 +164,7 @@ public: Q_INVOKABLE QString displayName(QString id) const; Q_INVOKABLE QString avatarUrl(QString id) const; Q_INVOKABLE QString formatDateSeparator(QDate date) const; + Q_INVOKABLE QString formatTypingUsers(const std::vector &users, QColor bg); Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE void viewRawMessage(QString id) const; @@ -183,6 +186,14 @@ public slots: int currentIndex() const { return idToIndex(currentId); } void markEventsAsRead(const std::vector &event_ids); QVariantMap getDump(QString eventId) const; + void updateTypingUsers(const std::vector &users) + { + if (this->typingUsers_ != users) { + this->typingUsers_ = users; + emit typingUsersChanged(typingUsers_); + } + } + std::vector typingUsers() const { return typingUsers_; } private slots: // Add old events at the top of the timeline. @@ -202,6 +213,7 @@ signals: void mediaCached(QString mxcUrl, QString cacheUrl); void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo); void replyFetched(QString requestingEvent, mtx::events::collections::TimelineEvents event); + void typingUsersChanged(std::vector users); private: DecryptionResult decryptEvent( @@ -232,6 +244,7 @@ private: QHash userColors; QString currentId; + std::vector typingUsers_; TimelineViewManager *manager_; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index ddbc6af8..c7a4e50e 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -8,6 +8,7 @@ #include "ColorImageProvider.h" #include "DelegateChooser.h" #include "Logging.h" +#include "MatrixClient.h" #include "MxcImageProvider.h" #include "UserSettingsPage.h" #include "dialogs/ImageOverlay.h" @@ -92,10 +93,21 @@ TimelineViewManager::TimelineViewManager(QWidget *parent) void TimelineViewManager::sync(const mtx::responses::Rooms &rooms) { - for (auto it = rooms.join.cbegin(); it != rooms.join.cend(); ++it) { + for (const auto &[room_id, room] : rooms.join) { // addRoom will only add the room, if it doesn't exist - addRoom(QString::fromStdString(it->first)); - models.value(QString::fromStdString(it->first))->addEvents(it->second.timeline); + addRoom(QString::fromStdString(room_id)); + const auto &room_model = models.value(QString::fromStdString(room_id)); + room_model->addEvents(room.timeline); + + if (ChatPage::instance()->userSettings()->isTypingNotificationsEnabled()) { + std::vector typing; + typing.reserve(room.ephemeral.typing.size()); + for (const auto &user : room.ephemeral.typing) { + if (user != http::client()->user_id().to_string()) + typing.push_back(QString::fromStdString(user)); + } + room_model->updateTypingUsers(typing); + } } this->isInitialSync_ = false;