Make error screens more visually consistent (#2951)
This commit is contained in:
@@ -27,7 +27,9 @@
|
|||||||
"settings": "Nastavení",
|
"settings": "Nastavení",
|
||||||
"username": "Uživatelské jméno"
|
"username": "Uživatelské jméno"
|
||||||
},
|
},
|
||||||
"full_screen_view_description": "<0>Odeslání ladících záznamů nám pomůže diagnostikovat problém.</0>",
|
"error": {
|
||||||
|
"generic_description": "Odeslání ladících záznamů nám pomůže diagnostikovat problém."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Oops, něco se pokazilo.</0>",
|
"full_screen_view_h1": "<0>Oops, něco se pokazilo.</0>",
|
||||||
"header_label": "Domov Element Call",
|
"header_label": "Domov Element Call",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
"browser_media_e2ee_unsupported": "Dein Webbrowser unterstützt keine Medien-Ende-zu-Ende-Verschlüsselung. Unterstützte Browser sind Chrome, Safari, Firefox >=117",
|
"browser_media_e2ee_unsupported": "Dein Webbrowser unterstützt keine Medien-Ende-zu-Ende-Verschlüsselung. Unterstützte Browser sind Chrome, Safari, Firefox >=117",
|
||||||
"browser_media_e2ee_unsupported_heading": "Inkompatibler Browser",
|
"browser_media_e2ee_unsupported_heading": "Inkompatibler Browser",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Deine Verbindung wurde getrennt",
|
|
||||||
"create_account_button": "Konto erstellen",
|
"create_account_button": "Konto erstellen",
|
||||||
"create_account_prompt": "<0>Warum vergibst du nicht abschließend ein Passwort, um dein Konto zu erhalten?</0><1>Du kannst deinen Namen behalten und ein Profilbild für zukünftige Anrufe festlegen.</1>",
|
"create_account_prompt": "<0>Warum vergibst du nicht abschließend ein Passwort, um dein Konto zu erhalten?</0><1>Du kannst deinen Namen behalten und ein Profilbild für zukünftige Anrufe festlegen.</1>",
|
||||||
"feedback_done": "<0>Danke für deine Rückmeldung!</0>",
|
"feedback_done": "<0>Danke für deine Rückmeldung!</0>",
|
||||||
@@ -76,7 +75,10 @@
|
|||||||
"matrix_id": "Matrix-ID: {{id}}"
|
"matrix_id": "Matrix-ID: {{id}}"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Die Verbindung zum Server wurde getrennt.",
|
"disconnected_banner": "Die Verbindung zum Server wurde getrennt.",
|
||||||
"full_screen_view_description": "<0>Übermittelte Problemberichte helfen uns, Fehler zu beheben.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Deine Verbindung wurde getrennt",
|
||||||
|
"generic_description": "Übermittelte Problemberichte helfen uns, Fehler zu beheben."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Hoppla, etwas ist schiefgelaufen.</0>",
|
"full_screen_view_h1": "<0>Hoppla, etwas ist schiefgelaufen.</0>",
|
||||||
"group_call_loader": {
|
"group_call_loader": {
|
||||||
"banned_body": "Du wurdest aus dem Raum verbannt.",
|
"banned_body": "Du wurdest aus dem Raum verbannt.",
|
||||||
|
|||||||
@@ -35,7 +35,9 @@
|
|||||||
"username": "Όνομα χρήστη",
|
"username": "Όνομα χρήστη",
|
||||||
"video": "Βίντεο"
|
"video": "Βίντεο"
|
||||||
},
|
},
|
||||||
"full_screen_view_description": "<0>Η υποβολή αρχείων καταγραφής σφαλμάτων θα μας βοηθήσει να εντοπίσουμε το πρόβλημα.</0>",
|
"error": {
|
||||||
|
"generic_description": "Η υποβολή αρχείων καταγραφής σφαλμάτων θα μας βοηθήσει να εντοπίσουμε το πρόβλημα."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ωχ, κάτι πήγε στραβά.</0>",
|
"full_screen_view_h1": "<0>Ωχ, κάτι πήγε στραβά.</0>",
|
||||||
"header_label": "Element Κεντρική Οθόνη Κλήσεων",
|
"header_label": "Element Κεντρική Οθόνη Κλήσεων",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
|
|||||||
@@ -28,11 +28,7 @@
|
|||||||
"text": "Ready to join?",
|
"text": "Ready to join?",
|
||||||
"title": "Select app"
|
"title": "Select app"
|
||||||
},
|
},
|
||||||
"application_opened_another_tab": "This application has been opened in another tab.",
|
|
||||||
"browser_media_e2ee_unsupported": "Your web browser does not support media end-to-end encryption. Supported Browsers are Chrome, Safari, Firefox >=117",
|
|
||||||
"browser_media_e2ee_unsupported_heading": "Incompatible Browser",
|
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "You were disconnected from the call",
|
|
||||||
"create_account_button": "Create account",
|
"create_account_button": "Create account",
|
||||||
"create_account_prompt": "<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>",
|
"create_account_prompt": "<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>",
|
||||||
"feedback_done": "<0>Thanks for your feedback!</0>",
|
"feedback_done": "<0>Thanks for your feedback!</0>",
|
||||||
@@ -50,7 +46,6 @@
|
|||||||
"back": "Back",
|
"back": "Back",
|
||||||
"display_name": "Display name",
|
"display_name": "Display name",
|
||||||
"encrypted": "Encrypted",
|
"encrypted": "Encrypted",
|
||||||
"error": "Error",
|
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"loading": "Loading…",
|
"loading": "Loading…",
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
@@ -61,7 +56,6 @@
|
|||||||
"reaction": "Reaction",
|
"reaction": "Reaction",
|
||||||
"reactions": "Reactions",
|
"reactions": "Reactions",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"something_went_wrong": "Something went wrong",
|
|
||||||
"unencrypted": "Not encrypted",
|
"unencrypted": "Not encrypted",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"video": "Video"
|
"video": "Video"
|
||||||
@@ -77,18 +71,26 @@
|
|||||||
"show_non_member_tiles": "Show tiles for non-member media"
|
"show_non_member_tiles": "Show tiles for non-member media"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Connectivity to the server has been lost.",
|
"disconnected_banner": "Connectivity to the server has been lost.",
|
||||||
"full_screen_view_description": "<0>Submitting debug logs will help us track down the problem.</0>",
|
"error": {
|
||||||
"full_screen_view_h1": "<0>Oops, something's gone wrong.</0>",
|
"call_not_found": "Call not found",
|
||||||
|
"call_not_found_description": "<0>That link doesn't appear to belong to any existing call. Check that you have the right link, or <1>create a new one</1>.</0>",
|
||||||
|
"connection_lost": "Connection lost",
|
||||||
|
"connection_lost_description": "You were disconnected from the call.",
|
||||||
|
"e2ee_unsupported": "Incompatible browser",
|
||||||
|
"e2ee_unsupported_description": "Your web browser does not support encrypted calls. Supported browsers include Chrome, Safari, and Firefox 117+.",
|
||||||
|
"generic": "Something went wrong",
|
||||||
|
"generic_description": "Submitting debug logs will help us track down the problem.",
|
||||||
|
"open_elsewhere": "Opened in another tab",
|
||||||
|
"open_elsewhere_description": "{{brand}} has been opened in another tab. If that doesn't sound right, try reloading the page."
|
||||||
|
},
|
||||||
"group_call_loader": {
|
"group_call_loader": {
|
||||||
"banned_body": "You have been banned from the room.",
|
"banned_body": "You have been banned from the room.",
|
||||||
"banned_heading": "Banned",
|
"banned_heading": "Banned",
|
||||||
"call_ended_body": "You have been removed from the call.",
|
"call_ended_body": "You have been removed from the call.",
|
||||||
"call_ended_heading": "Call ended",
|
"call_ended_heading": "Call ended",
|
||||||
"failed_heading": "Failed to join",
|
|
||||||
"failed_text": "Call not found or is not accessible.",
|
|
||||||
"knock_reject_body": "Your request to join was declined.",
|
"knock_reject_body": "Your request to join was declined.",
|
||||||
"knock_reject_heading": "Access denied",
|
"knock_reject_heading": "Access denied",
|
||||||
"reason": "Reason"
|
"reason": "Reason: {{reason}}"
|
||||||
},
|
},
|
||||||
"hangup_button_label": "End call",
|
"hangup_button_label": "End call",
|
||||||
"header_label": "Element Call Home",
|
"header_label": "Element Call Home",
|
||||||
|
|||||||
@@ -32,7 +32,9 @@
|
|||||||
"settings": "Ajustes",
|
"settings": "Ajustes",
|
||||||
"username": "Nombre de usuario"
|
"username": "Nombre de usuario"
|
||||||
},
|
},
|
||||||
"full_screen_view_description": "<0>Subir los registros de depuración nos ayudará a encontrar el problema.</0>",
|
"error": {
|
||||||
|
"generic_description": "Subir los registros de depuración nos ayudará a encontrar el problema."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ups, algo ha salido mal.</0>",
|
"full_screen_view_h1": "<0>Ups, algo ha salido mal.</0>",
|
||||||
"header_label": "Inicio de Element Call",
|
"header_label": "Inicio de Element Call",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Sinu veebibrauser ei toeta meedia läbivat krüptimist. Toetatud brauserid on Chrome, Chromium, Safari ja Firefox >=117",
|
"browser_media_e2ee_unsupported": "Sinu veebibrauser ei toeta meedia läbivat krüptimist. Toetatud brauserid on Chrome, Chromium, Safari ja Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Sinu ühendus kõnega katkes",
|
|
||||||
"create_account_button": "Loo konto",
|
"create_account_button": "Loo konto",
|
||||||
"create_account_prompt": "<0>Kas soovid salasõna seadistada ja sellega oma kasutajakonto alles jätta?</0><1>Nii saad säilitada oma nime ja määrata profiilipildi, mida saad kasutada tulevastes kõnedes</1>",
|
"create_account_prompt": "<0>Kas soovid salasõna seadistada ja sellega oma kasutajakonto alles jätta?</0><1>Nii saad säilitada oma nime ja määrata profiilipildi, mida saad kasutada tulevastes kõnedes</1>",
|
||||||
"feedback_done": "<0>Täname Sind tagasiside eest!</0>",
|
"feedback_done": "<0>Täname Sind tagasiside eest!</0>",
|
||||||
@@ -50,7 +49,10 @@
|
|||||||
"username": "Kasutajanimi"
|
"username": "Kasutajanimi"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Võrguühendus serveriga on katkenud.",
|
"disconnected_banner": "Võrguühendus serveriga on katkenud.",
|
||||||
"full_screen_view_description": "<0>Kui saadad meile vealogid, siis on lihtsam vea põhjust otsida.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Sinu ühendus kõnega katkes",
|
||||||
|
"generic_description": "Kui saadad meile vealogid, siis on lihtsam vea põhjust otsida."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ohoo, midagi on nüüd katki.</0>",
|
"full_screen_view_h1": "<0>Ohoo, midagi on nüüd katki.</0>",
|
||||||
"hangup_button_label": "Lõpeta kõne",
|
"hangup_button_label": "Lõpeta kõne",
|
||||||
"header_participants_label": "Osalejad",
|
"header_participants_label": "Osalejad",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Votre navigateur web ne prend pas en charge le chiffrement de bout-en-bout des médias. Les navigateurs pris en charge sont Chrome, Safari, Firefox >= 117",
|
"browser_media_e2ee_unsupported": "Votre navigateur web ne prend pas en charge le chiffrement de bout-en-bout des médias. Les navigateurs pris en charge sont Chrome, Safari, Firefox >= 117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Vous avez été déconnecté de l’appel",
|
|
||||||
"create_account_button": "Créer un compte",
|
"create_account_button": "Créer un compte",
|
||||||
"create_account_prompt": "<0>Pourquoi ne pas créer un mot de passe pour conserver votre compte ?</0><1>Vous pourrez garder votre nom et définir un avatar pour vos futurs appels</1>",
|
"create_account_prompt": "<0>Pourquoi ne pas créer un mot de passe pour conserver votre compte ?</0><1>Vous pourrez garder votre nom et définir un avatar pour vos futurs appels</1>",
|
||||||
"feedback_done": "<0>Merci pour votre commentaire !</0>",
|
"feedback_done": "<0>Merci pour votre commentaire !</0>",
|
||||||
@@ -48,7 +47,10 @@
|
|||||||
"video": "Vidéo"
|
"video": "Vidéo"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "La connexion avec le serveur a été perdue.",
|
"disconnected_banner": "La connexion avec le serveur a été perdue.",
|
||||||
"full_screen_view_description": "<0>Soumettre les journaux de débogage nous aidera à déterminer le problème.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Vous avez été déconnecté de l’appel",
|
||||||
|
"generic_description": "Soumettre les journaux de débogage nous aidera à déterminer le problème."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Oups, quelque chose s’est mal passé.</0>",
|
"full_screen_view_h1": "<0>Oups, quelque chose s’est mal passé.</0>",
|
||||||
"hangup_button_label": "Terminer l’appel",
|
"hangup_button_label": "Terminer l’appel",
|
||||||
"header_label": "Accueil Element Call",
|
"header_label": "Accueil Element Call",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Peramban web Anda tidak mendukung enkripsi media ujung ke ujung. Peramban yang didukung adalah Chrome, Safari, dan Firefox >=117",
|
"browser_media_e2ee_unsupported": "Peramban web Anda tidak mendukung enkripsi media ujung ke ujung. Peramban yang didukung adalah Chrome, Safari, dan Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Anda terputus dari panggilan",
|
|
||||||
"create_account_button": "Buat akun",
|
"create_account_button": "Buat akun",
|
||||||
"create_account_prompt": "<0>Kenapa tidak selesaikan dengan mengatur sebuah kata sandi untuk menjaga akun Anda?</0><1>Anda akan dapat tetap menggunakan nama Anda dan atur sebuah avatar untuk digunakan dalam panggilan di masa mendatang</1>",
|
"create_account_prompt": "<0>Kenapa tidak selesaikan dengan mengatur sebuah kata sandi untuk menjaga akun Anda?</0><1>Anda akan dapat tetap menggunakan nama Anda dan atur sebuah avatar untuk digunakan dalam panggilan di masa mendatang</1>",
|
||||||
"feedback_done": "<0>Terima kasih atas masukan Anda!</0>",
|
"feedback_done": "<0>Terima kasih atas masukan Anda!</0>",
|
||||||
@@ -48,7 +47,10 @@
|
|||||||
"username": "Nama pengguna"
|
"username": "Nama pengguna"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Koneksi ke server telah hilang.",
|
"disconnected_banner": "Koneksi ke server telah hilang.",
|
||||||
"full_screen_view_description": "<0>Mengirim catatan pengawakutuan akan membantu kami melacak masalahnya.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Anda terputus dari panggilan",
|
||||||
|
"generic_description": "Mengirim catatan pengawakutuan akan membantu kami melacak masalahnya."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Aduh, ada yang salah.</0>",
|
"full_screen_view_h1": "<0>Aduh, ada yang salah.</0>",
|
||||||
"hangup_button_label": "Akhiri panggilan",
|
"hangup_button_label": "Akhiri panggilan",
|
||||||
"header_label": "Beranda Element Call",
|
"header_label": "Beranda Element Call",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Il tuo browser non supporta la crittografia end-to-end dei media. I browser supportati sono Chrome, Safari, Firefox >=117",
|
"browser_media_e2ee_unsupported": "Il tuo browser non supporta la crittografia end-to-end dei media. I browser supportati sono Chrome, Safari, Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Sei stato disconnesso dalla chiamata",
|
|
||||||
"create_account_button": "Crea profilo",
|
"create_account_button": "Crea profilo",
|
||||||
"create_account_prompt": "<0>Ti va di terminare impostando una password per mantenere il profilo?</0><1>Potrai mantenere il tuo nome e impostare un avatar da usare in chiamate future</1>",
|
"create_account_prompt": "<0>Ti va di terminare impostando una password per mantenere il profilo?</0><1>Potrai mantenere il tuo nome e impostare un avatar da usare in chiamate future</1>",
|
||||||
"feedback_done": "<0>Grazie per la tua opinione!</0>",
|
"feedback_done": "<0>Grazie per la tua opinione!</0>",
|
||||||
@@ -46,7 +45,10 @@
|
|||||||
"username": "Nome utente"
|
"username": "Nome utente"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "La connessione al server è stata persa.",
|
"disconnected_banner": "La connessione al server è stata persa.",
|
||||||
"full_screen_view_description": "<0>L'invio di registri di debug ci aiuterà ad individuare il problema.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Sei stato disconnesso dalla chiamata",
|
||||||
|
"generic_description": "L'invio di registri di debug ci aiuterà ad individuare il problema."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ops, qualcosa è andato storto.</0>",
|
"full_screen_view_h1": "<0>Ops, qualcosa è andato storto.</0>",
|
||||||
"hangup_button_label": "Termina chiamata",
|
"hangup_button_label": "Termina chiamata",
|
||||||
"header_label": "Inizio di Element Call",
|
"header_label": "Inizio di Element Call",
|
||||||
|
|||||||
@@ -28,7 +28,9 @@
|
|||||||
"username": "ユーザー名",
|
"username": "ユーザー名",
|
||||||
"video": "ビデオ"
|
"video": "ビデオ"
|
||||||
},
|
},
|
||||||
"full_screen_view_h1": "<0>何かがうまく行きませんでした。</0>",
|
"error": {
|
||||||
|
"generic_description": "何かがうまく行きませんでした。"
|
||||||
|
},
|
||||||
"header_label": "Element Call ホーム",
|
"header_label": "Element Call ホーム",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
"join_button": "はい、通話に参加",
|
"join_button": "はい、通話に参加",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
},
|
},
|
||||||
"analytics_notice": "Piedalīšanās šajā beta apliecina piekrišanu anonīmu datu ievākšanai, ko mēs izmantojam, lai uzlabotu izstrādājumu. Vairāk informācijas par datiem, ko mēs ievācam, var atrast mūsu <2>privātuma nosacījumos</2> un <5>sīkdatņu nosacījumos</5>.",
|
"analytics_notice": "Piedalīšanās šajā beta apliecina piekrišanu anonīmu datu ievākšanai, ko mēs izmantojam, lai uzlabotu izstrādājumu. Vairāk informācijas par datiem, ko mēs ievācam, var atrast mūsu <2>privātuma nosacījumos</2> un <5>sīkdatņu nosacījumos</5>.",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Tu tiki atvienots no zvana",
|
|
||||||
"create_account_button": "Izveidot kontu",
|
"create_account_button": "Izveidot kontu",
|
||||||
"create_account_prompt": "<0>Kādēļ nepabeigt ar paroles iestatīšanu, lai paturētu savu kontu?</0><1>Būs iespējams paturēt savu vārdu un iestatīt attēlu izmantošanai turpmākajos zvanos</1>",
|
"create_account_prompt": "<0>Kādēļ nepabeigt ar paroles iestatīšanu, lai paturētu savu kontu?</0><1>Būs iespējams paturēt savu vārdu un iestatīt attēlu izmantošanai turpmākajos zvanos</1>",
|
||||||
"feedback_done": "<0>Paldies par atsauksmi!</0>",
|
"feedback_done": "<0>Paldies par atsauksmi!</0>",
|
||||||
@@ -38,7 +37,10 @@
|
|||||||
"username": "Lietotājvārds"
|
"username": "Lietotājvārds"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Ir zaudēts savienojums ar serveri.",
|
"disconnected_banner": "Ir zaudēts savienojums ar serveri.",
|
||||||
"full_screen_view_description": "<0>Atkļūdošanas žurnāla ierakstu iesūtīšana palīdzēs mums atklāt nepilnību.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Tu tiki atvienots no zvana",
|
||||||
|
"generic_description": "Atkļūdošanas žurnāla ierakstu iesūtīšana palīdzēs mums atklāt nepilnību."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ak vai, kaut kas nogāja greizi!</0>",
|
"full_screen_view_h1": "<0>Ak vai, kaut kas nogāja greizi!</0>",
|
||||||
"header_label": "Element Call sākums",
|
"header_label": "Element Call sākums",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Twoja przeglądarka nie wspiera szyfrowania end-to-end. Wspierane przeglądarki to Chrome, Safari, Firefox >=117",
|
"browser_media_e2ee_unsupported": "Twoja przeglądarka nie wspiera szyfrowania end-to-end. Wspierane przeglądarki to Chrome, Safari, Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Rozłączono Cię z połączenia",
|
|
||||||
"create_account_button": "Utwórz konto",
|
"create_account_button": "Utwórz konto",
|
||||||
"create_account_prompt": "<0>Może zechcesz ustawić hasło, aby zachować swoje konto?</0><1>Będziesz w stanie utrzymać swoją nazwę i ustawić awatar do wyświetlania podczas połączeń w przyszłości</1>",
|
"create_account_prompt": "<0>Może zechcesz ustawić hasło, aby zachować swoje konto?</0><1>Będziesz w stanie utrzymać swoją nazwę i ustawić awatar do wyświetlania podczas połączeń w przyszłości</1>",
|
||||||
"feedback_done": "<0>Dziękujemy za Twoją opinię!</0>",
|
"feedback_done": "<0>Dziękujemy za Twoją opinię!</0>",
|
||||||
@@ -51,7 +50,10 @@
|
|||||||
"video": "Wideo"
|
"video": "Wideo"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Utracono połączenie z serwerem.",
|
"disconnected_banner": "Utracono połączenie z serwerem.",
|
||||||
"full_screen_view_description": "<0>Wysłanie dzienników debuggowania pomoże nam ustalić przyczynę problemu.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Rozłączono Cię z połączenia",
|
||||||
|
"generic_description": "Wysłanie dzienników debuggowania pomoże nam ustalić przyczynę problemu."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ojej, coś poszło nie tak.</0>",
|
"full_screen_view_h1": "<0>Ojej, coś poszło nie tak.</0>",
|
||||||
"hangup_button_label": "Zakończ połączenie",
|
"hangup_button_label": "Zakończ połączenie",
|
||||||
"header_label": "Strona główna Element Call",
|
"header_label": "Strona główna Element Call",
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
"browser_media_e2ee_unsupported": "Browserul dvs. web nu acceptă criptarea media end-to-end. Browserele acceptate sunt Chrome, Safari, Firefox > = 117",
|
"browser_media_e2ee_unsupported": "Browserul dvs. web nu acceptă criptarea media end-to-end. Browserele acceptate sunt Chrome, Safari, Firefox > = 117",
|
||||||
"browser_media_e2ee_unsupported_heading": "Browser incompatibil",
|
"browser_media_e2ee_unsupported_heading": "Browser incompatibil",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Ai fost deconectat de la apel",
|
|
||||||
"create_account_button": "Creează cont",
|
"create_account_button": "Creează cont",
|
||||||
"create_account_prompt": "<0>De ce să nu terminați prin configurarea unei parole pentru a vă păstra contul? </0><1>Veți putea să vă păstrați numele și să setați un avatar pentru a fi utilizat la apelurile viitoare </1>",
|
"create_account_prompt": "<0>De ce să nu terminați prin configurarea unei parole pentru a vă păstra contul? </0><1>Veți putea să vă păstrați numele și să setați un avatar pentru a fi utilizat la apelurile viitoare </1>",
|
||||||
"feedback_done": "<0>Vă mulțumim pentru feedback! </0>",
|
"feedback_done": "<0>Vă mulțumim pentru feedback! </0>",
|
||||||
@@ -76,7 +75,10 @@
|
|||||||
"matrix_id": "ID-ul matricei: {{id}}"
|
"matrix_id": "ID-ul matricei: {{id}}"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Conectivitatea la server a fost pierdută.",
|
"disconnected_banner": "Conectivitatea la server a fost pierdută.",
|
||||||
"full_screen_view_description": "<0>Trimiterea jurnalelor de depanare ne va ajuta să urmărim problema. </0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Ai fost deconectat de la apel",
|
||||||
|
"generic_description": "Trimiterea jurnalelor de depanare ne va ajuta să urmărim problema."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Hopa, ceva nu a mers bine. </0>",
|
"full_screen_view_h1": "<0>Hopa, ceva nu a mers bine. </0>",
|
||||||
"group_call_loader": {
|
"group_call_loader": {
|
||||||
"banned_body": "Ai fost interzis să ieși din cameră.",
|
"banned_body": "Ai fost interzis să ieși din cameră.",
|
||||||
|
|||||||
@@ -36,7 +36,9 @@
|
|||||||
"username": "Имя пользователя",
|
"username": "Имя пользователя",
|
||||||
"video": "Видео"
|
"video": "Видео"
|
||||||
},
|
},
|
||||||
"full_screen_view_description": "<0>Отправка журналов поможет нам найти и устранить проблему.</0>",
|
"error": {
|
||||||
|
"generic_description": "Отправка журналов поможет нам найти и устранить проблему."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Упс, что-то пошло не так.</0>",
|
"full_screen_view_h1": "<0>Упс, что-то пошло не так.</0>",
|
||||||
"header_label": "Главная Element Call",
|
"header_label": "Главная Element Call",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Váš webový prehliadač nepodporuje end-to-end šifrovanie médií. Podporované prehliadače sú Chrome, Safari, Firefox >=117",
|
"browser_media_e2ee_unsupported": "Váš webový prehliadač nepodporuje end-to-end šifrovanie médií. Podporované prehliadače sú Chrome, Safari, Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Boli ste odpojení z hovoru",
|
|
||||||
"create_account_button": "Vytvoriť účet",
|
"create_account_button": "Vytvoriť účet",
|
||||||
"create_account_prompt": "<0>Prečo neskončiť nastavením hesla, aby ste si zachovali svoj účet? </0><1>Budete si môcť ponechať svoje meno a nastaviť obrázok, ktorý sa bude používať pri budúcich hovoroch</1>",
|
"create_account_prompt": "<0>Prečo neskončiť nastavením hesla, aby ste si zachovali svoj účet? </0><1>Budete si môcť ponechať svoje meno a nastaviť obrázok, ktorý sa bude používať pri budúcich hovoroch</1>",
|
||||||
"feedback_done": "<0> Ďakujeme za vašu spätnú väzbu!</0>",
|
"feedback_done": "<0> Ďakujeme za vašu spätnú väzbu!</0>",
|
||||||
@@ -49,7 +48,10 @@
|
|||||||
"username": "Meno používateľa"
|
"username": "Meno používateľa"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Spojenie so serverom sa stratilo.",
|
"disconnected_banner": "Spojenie so serverom sa stratilo.",
|
||||||
"full_screen_view_description": "<0>Odoslanie záznamov ladenia nám pomôže nájsť problém.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Boli ste odpojení z hovoru",
|
||||||
|
"generic_description": "Odoslanie záznamov ladenia nám pomôže nájsť problém."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Hups, niečo sa pokazilo.</0>",
|
"full_screen_view_h1": "<0>Hups, niečo sa pokazilo.</0>",
|
||||||
"hangup_button_label": "Ukončiť hovor",
|
"hangup_button_label": "Ukončiť hovor",
|
||||||
"header_label": "Domov Element Call",
|
"header_label": "Domov Element Call",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
},
|
},
|
||||||
"browser_media_e2ee_unsupported": "Ваш браузер не підтримує наскрізне шифрування мультимедійних даних. Підтримувані браузери: Chrome, Safari, Firefox >=117",
|
"browser_media_e2ee_unsupported": "Ваш браузер не підтримує наскрізне шифрування мультимедійних даних. Підтримувані браузери: Chrome, Safari, Firefox >=117",
|
||||||
"call_ended_view": {
|
"call_ended_view": {
|
||||||
"body": "Вас від'єднано від виклику",
|
|
||||||
"create_account_button": "Створити обліковий запис",
|
"create_account_button": "Створити обліковий запис",
|
||||||
"create_account_prompt": "<0>Чому б не завершити, налаштувавши пароль для збереження свого облікового запису?</0><1>Ви зможете зберегти своє ім'я та встановити аватарку для подальшого користування під час майбутніх викликів</1>",
|
"create_account_prompt": "<0>Чому б не завершити, налаштувавши пароль для збереження свого облікового запису?</0><1>Ви зможете зберегти своє ім'я та встановити аватарку для подальшого користування під час майбутніх викликів</1>",
|
||||||
"feedback_done": "<0>Дякуємо за ваш відгук!</0>",
|
"feedback_done": "<0>Дякуємо за ваш відгук!</0>",
|
||||||
@@ -51,7 +50,10 @@
|
|||||||
"video": "Відео"
|
"video": "Відео"
|
||||||
},
|
},
|
||||||
"disconnected_banner": "Втрачено зв'язок з сервером.",
|
"disconnected_banner": "Втрачено зв'язок з сервером.",
|
||||||
"full_screen_view_description": "<0>Надсилання журналів налагодження допоможе нам виявити проблему.</0>",
|
"error": {
|
||||||
|
"connection_lost_description": "Вас від'єднано від виклику",
|
||||||
|
"generic_description": "Надсилання журналів налагодження допоможе нам виявити проблему."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Йой, щось пішло не за планом.</0>",
|
"full_screen_view_h1": "<0>Йой, щось пішло не за планом.</0>",
|
||||||
"hangup_button_label": "Завершити виклик",
|
"hangup_button_label": "Завершити виклик",
|
||||||
"header_label": "Домівка Element Call",
|
"header_label": "Домівка Element Call",
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
"username": "Tên người dùng",
|
"username": "Tên người dùng",
|
||||||
"video": "Truyền hình"
|
"video": "Truyền hình"
|
||||||
},
|
},
|
||||||
"full_screen_view_description": "<0>Gửi nhật ký gỡ lỗi sẽ giúp chúng tôi theo dõi vấn đề.</0>",
|
"error": {
|
||||||
|
"generic_description": "Gửi nhật ký gỡ lỗi sẽ giúp chúng tôi theo dõi vấn đề."
|
||||||
|
},
|
||||||
"full_screen_view_h1": "<0>Ối, có cái gì đó sai.</0>",
|
"full_screen_view_h1": "<0>Ối, có cái gì đó sai.</0>",
|
||||||
"join_existing_call_modal": {
|
"join_existing_call_modal": {
|
||||||
"join_button": "Vâng, tham gia cuộc gọi",
|
"join_button": "Vâng, tham gia cuộc gọi",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { LoginPage } from "./auth/LoginPage";
|
|||||||
import { RegisterPage } from "./auth/RegisterPage";
|
import { RegisterPage } from "./auth/RegisterPage";
|
||||||
import { RoomPage } from "./room/RoomPage";
|
import { RoomPage } from "./room/RoomPage";
|
||||||
import { ClientProvider } from "./ClientContext";
|
import { ClientProvider } from "./ClientContext";
|
||||||
import { CrashView, LoadingView } from "./FullScreenView";
|
import { ErrorPage, LoadingPage } from "./FullScreenView";
|
||||||
import { DisconnectedBanner } from "./DisconnectedBanner";
|
import { DisconnectedBanner } from "./DisconnectedBanner";
|
||||||
import { Initializer } from "./initializer";
|
import { Initializer } from "./initializer";
|
||||||
import { MediaDevicesProvider } from "./livekit/MediaDevicesContext";
|
import { MediaDevicesProvider } from "./livekit/MediaDevicesContext";
|
||||||
@@ -61,8 +61,6 @@ export const App: FC = () => {
|
|||||||
.catch(logger.error);
|
.catch(logger.error);
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorPage = <CrashView />;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -74,7 +72,7 @@ export const App: FC = () => {
|
|||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<ClientProvider>
|
<ClientProvider>
|
||||||
<MediaDevicesProvider>
|
<MediaDevicesProvider>
|
||||||
<Sentry.ErrorBoundary fallback={errorPage}>
|
<Sentry.ErrorBoundary fallback={ErrorPage}>
|
||||||
<DisconnectedBanner />
|
<DisconnectedBanner />
|
||||||
<Routes>
|
<Routes>
|
||||||
<SentryRoute path="/" element={<HomePage />} />
|
<SentryRoute path="/" element={<HomePage />} />
|
||||||
@@ -90,7 +88,7 @@ export const App: FC = () => {
|
|||||||
</ClientProvider>
|
</ClientProvider>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : (
|
) : (
|
||||||
<LoadingView />
|
<LoadingPage />
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
@@ -18,19 +18,18 @@ import {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/src/sync";
|
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/src/sync";
|
||||||
import { ClientEvent, type MatrixClient } from "matrix-js-sdk/src/client";
|
import { ClientEvent, type MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
|
|
||||||
import type { WidgetApi } from "matrix-widget-api";
|
import type { WidgetApi } from "matrix-widget-api";
|
||||||
import { ErrorView } from "./FullScreenView";
|
import { ErrorPage } from "./FullScreenView";
|
||||||
import { widget } from "./widget";
|
import { widget } from "./widget";
|
||||||
import {
|
import {
|
||||||
PosthogAnalytics,
|
PosthogAnalytics,
|
||||||
RegistrationType,
|
RegistrationType,
|
||||||
} from "./analytics/PosthogAnalytics";
|
} from "./analytics/PosthogAnalytics";
|
||||||
import { translatedError } from "./TranslatedError";
|
|
||||||
import { useEventTarget } from "./useEvents";
|
import { useEventTarget } from "./useEvents";
|
||||||
|
import { OpenElsewhereError } from "./RichError";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -233,8 +232,6 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
|||||||
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Guest);
|
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Guest);
|
||||||
}, [navigate, initClientState?.client]);
|
}, [navigate, initClientState?.client]);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
// To protect against multiple sessions writing to the same storage
|
// To protect against multiple sessions writing to the same storage
|
||||||
// simultaneously, we send a broadcast message that shuts down all other
|
// simultaneously, we send a broadcast message that shuts down all other
|
||||||
// running instances of the app. This isn't necessary if the app is running in
|
// running instances of the app. This isn't necessary if the app is running in
|
||||||
@@ -251,8 +248,8 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
|||||||
"message",
|
"message",
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
initClientState?.client.stopClient();
|
initClientState?.client.stopClient();
|
||||||
setAlreadyOpenedErr(translatedError("application_opened_another_tab", t));
|
setAlreadyOpenedErr(new OpenElsewhereError());
|
||||||
}, [initClientState?.client, setAlreadyOpenedErr, t]),
|
}, [initClientState?.client, setAlreadyOpenedErr]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [isDisconnected, setIsDisconnected] = useState(false);
|
const [isDisconnected, setIsDisconnected] = useState(false);
|
||||||
@@ -354,7 +351,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
|||||||
}, [initClientState, onSync]);
|
}, [initClientState, onSync]);
|
||||||
|
|
||||||
if (alreadyOpenedErr) {
|
if (alreadyOpenedErr) {
|
||||||
return <ErrorView error={alreadyOpenedErr} />;
|
return <ErrorPage error={alreadyOpenedErr} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
21
src/ErrorView.module.css
Normal file
21
src/ErrorView.module.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.error {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--cpd-space-2x);
|
||||||
|
max-inline-size: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-block-end: var(--cpd-space-4x);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error > h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error > p {
|
||||||
|
font: var(--cpd-font-body-lg-regular);
|
||||||
|
color: var(--cpd-color-text-secondary);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
82
src/ErrorView.tsx
Normal file
82
src/ErrorView.tsx
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2025 New Vector Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { BigIcon, Button, Heading } from "@vector-im/compound-web";
|
||||||
|
import {
|
||||||
|
useCallback,
|
||||||
|
type ComponentType,
|
||||||
|
type FC,
|
||||||
|
type ReactNode,
|
||||||
|
type SVGAttributes,
|
||||||
|
} from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { RageshakeButton } from "./settings/RageshakeButton";
|
||||||
|
import styles from "./ErrorView.module.css";
|
||||||
|
import { useUrlParams } from "./UrlParams";
|
||||||
|
import { LinkButton } from "./button";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
Icon: ComponentType<SVGAttributes<SVGElement>>;
|
||||||
|
title: string;
|
||||||
|
/**
|
||||||
|
* Show an option to submit a rageshake.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
rageshake?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether the error is considered fatal, i.e. non-recoverable. Causes the app
|
||||||
|
* to fully reload when clicking 'return to home'.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
fatal?: boolean;
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ErrorView: FC<Props> = ({
|
||||||
|
Icon,
|
||||||
|
title,
|
||||||
|
rageshake,
|
||||||
|
fatal,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { confineToRoom } = useUrlParams();
|
||||||
|
|
||||||
|
const onReload = useCallback(() => {
|
||||||
|
window.location.href = "/";
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.error}>
|
||||||
|
<BigIcon className={styles.icon}>
|
||||||
|
<Icon />
|
||||||
|
</BigIcon>
|
||||||
|
<Heading as="h1" weight="semibold" size="md">
|
||||||
|
{title}
|
||||||
|
</Heading>
|
||||||
|
{children}
|
||||||
|
{rageshake && (
|
||||||
|
<RageshakeButton description={`***Error View***: ${title}`} />
|
||||||
|
)}
|
||||||
|
{!confineToRoom &&
|
||||||
|
(fatal || location.pathname === "/" ? (
|
||||||
|
<Button
|
||||||
|
kind="tertiary"
|
||||||
|
className={styles.homeLink}
|
||||||
|
onClick={onReload}
|
||||||
|
>
|
||||||
|
{t("return_home_button")}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<LinkButton kind="tertiary" className={styles.homeLink} to="/">
|
||||||
|
{t("return_home_button")}
|
||||||
|
</LinkButton>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -5,21 +5,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { type FC, type ReactNode, useCallback, useEffect } from "react";
|
import { type FC, type ReactElement, type ReactNode, useEffect } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import * as Sentry from "@sentry/react";
|
import * as Sentry from "@sentry/react";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { Button } from "@vector-im/compound-web";
|
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
|
|
||||||
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
|
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
|
||||||
import { LinkButton } from "./button";
|
|
||||||
import styles from "./FullScreenView.module.css";
|
import styles from "./FullScreenView.module.css";
|
||||||
import { TranslatedError } from "./TranslatedError";
|
|
||||||
import { Config } from "./config/Config";
|
|
||||||
import { RageshakeButton } from "./settings/RageshakeButton";
|
|
||||||
import { useUrlParams } from "./UrlParams";
|
import { useUrlParams } from "./UrlParams";
|
||||||
|
import { RichError } from "./RichError";
|
||||||
|
import { ErrorView } from "./ErrorView";
|
||||||
|
|
||||||
interface FullScreenViewProps {
|
interface FullScreenViewProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -44,74 +41,33 @@ export const FullScreenView: FC<FullScreenViewProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ErrorViewProps {
|
interface ErrorPageProps {
|
||||||
error: Error;
|
error: Error | unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ErrorView: FC<ErrorViewProps> = ({ error }) => {
|
// Due to this component being used as the crash fallback for Sentry, which has
|
||||||
const location = useLocation();
|
// weird type requirements, we can't just give this a type of FC<ErrorPageProps>
|
||||||
const { confineToRoom } = useUrlParams();
|
export const ErrorPage = ({ error }: ErrorPageProps): ReactElement => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
}, [error]);
|
}, [error]);
|
||||||
|
|
||||||
const onReload = useCallback(() => {
|
|
||||||
window.location.href = "/";
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<h1>{t("common.error")}</h1>
|
{error instanceof RichError ? (
|
||||||
<p>
|
error.richMessage
|
||||||
{error instanceof TranslatedError
|
) : (
|
||||||
? error.translatedMessage
|
<ErrorView Icon={ErrorIcon} title={t("error.generic")} rageshake fatal>
|
||||||
: error.message}
|
<p>{t("error.generic_description")}</p>
|
||||||
</p>
|
</ErrorView>
|
||||||
<RageshakeButton description={`***Error View***: ${error.message}`} />
|
|
||||||
{!confineToRoom &&
|
|
||||||
(location.pathname === "/" ? (
|
|
||||||
<Button className={styles.homeLink} onClick={onReload}>
|
|
||||||
{t("return_home_button")}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<LinkButton className={styles.homeLink} to="/">
|
|
||||||
{t("return_home_button")}
|
|
||||||
</LinkButton>
|
|
||||||
))}
|
|
||||||
</FullScreenView>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CrashView: FC = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const onReload = useCallback(() => {
|
|
||||||
window.location.href = "/";
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FullScreenView>
|
|
||||||
<Trans i18nKey="full_screen_view_h1">
|
|
||||||
<h1>Oops, something's gone wrong.</h1>
|
|
||||||
</Trans>
|
|
||||||
{Config.get().rageshake?.submit_url && (
|
|
||||||
<Trans i18nKey="full_screen_view_description">
|
|
||||||
<p>Submitting debug logs will help us track down the problem.</p>
|
|
||||||
</Trans>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<RageshakeButton description="***Soft Crash***" />
|
|
||||||
<Button className={styles.wideButton} onClick={onReload}>
|
|
||||||
{t("return_home_button")}
|
|
||||||
</Button>
|
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingView: FC = () => {
|
export const LoadingPage: FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
48
src/RichError.tsx
Normal file
48
src/RichError.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2025 New Vector Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { type FC, type ReactNode } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { PopOutIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
|
|
||||||
|
import { ErrorView } from "./ErrorView";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An error consisting of a terse message to be logged to the console and a
|
||||||
|
* richer message to be shown to the user, as a full-screen page.
|
||||||
|
*/
|
||||||
|
export class RichError extends Error {
|
||||||
|
public constructor(
|
||||||
|
message: string,
|
||||||
|
/**
|
||||||
|
* The pretty, more helpful message to be shown on the error screen.
|
||||||
|
*/
|
||||||
|
public readonly richMessage: ReactNode,
|
||||||
|
) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenElsewhere: FC = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ErrorView Icon={PopOutIcon} title={t("error.open_elsewhere")}>
|
||||||
|
<p>
|
||||||
|
{t("error.open_elsewhere_description", {
|
||||||
|
brand: import.meta.env.VITE_PRODUCT_NAME || "Element Call",
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</ErrorView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export class OpenElsewhereError extends RichError {
|
||||||
|
public constructor() {
|
||||||
|
super("App opened in another tab", <OpenElsewhere />);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,9 @@ import type { DefaultNamespace, ParseKeys, TFunction, TOptions } from "i18next";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An error with messages in both English and the user's preferred language.
|
* An error with messages in both English and the user's preferred language.
|
||||||
|
* Use this for errors that need to be displayed inline within another
|
||||||
|
* component. For errors that could be given their own screen, prefer
|
||||||
|
* {@link RichError}.
|
||||||
*/
|
*/
|
||||||
// Abstract to force consumers to use the function below rather than calling the
|
// Abstract to force consumers to use the function below rather than calling the
|
||||||
// constructor directly
|
// constructor directly
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { useClientLegacy } from "../ClientContext";
|
|||||||
import { useInteractiveRegistration } from "./useInteractiveRegistration";
|
import { useInteractiveRegistration } from "./useInteractiveRegistration";
|
||||||
import styles from "./LoginPage.module.css";
|
import styles from "./LoginPage.module.css";
|
||||||
import Logo from "../icons/LogoLarge.svg?react";
|
import Logo from "../icons/LogoLarge.svg?react";
|
||||||
import { LoadingView } from "../FullScreenView";
|
import { LoadingPage } from "../FullScreenView";
|
||||||
import { useRecaptcha } from "./useRecaptcha";
|
import { useRecaptcha } from "./useRecaptcha";
|
||||||
import { usePageTitle } from "../usePageTitle";
|
import { usePageTitle } from "../usePageTitle";
|
||||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||||
@@ -148,7 +148,7 @@ export const RegisterPage: FC = () => {
|
|||||||
}, [loading, navigate, authenticated, passwordlessUser, registering]);
|
}, [loading, navigate, authenticated, passwordlessUser, registering]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <LoadingView />;
|
return <LoadingPage />;
|
||||||
} else {
|
} else {
|
||||||
PosthogAnalytics.instance.eventSignup.cacheSignupStart(new Date());
|
PosthogAnalytics.instance.eventSignup.cacheSignupStart(new Date());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export function ReactionPopupMenu({
|
|||||||
<Alert
|
<Alert
|
||||||
className={styles.alert}
|
className={styles.alert}
|
||||||
type="critical"
|
type="critical"
|
||||||
title={t("common.something_went_wrong")}
|
title={t("error.generic")}
|
||||||
>
|
>
|
||||||
{errorText}
|
{errorText}
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { type FC } from "react";
|
import { type FC } from "react";
|
||||||
|
|
||||||
import { useClientState } from "../ClientContext";
|
import { useClientState } from "../ClientContext";
|
||||||
import { ErrorView, LoadingView } from "../FullScreenView";
|
import { ErrorPage, LoadingPage } from "../FullScreenView";
|
||||||
import { UnauthenticatedView } from "./UnauthenticatedView";
|
import { UnauthenticatedView } from "./UnauthenticatedView";
|
||||||
import { RegisteredView } from "./RegisteredView";
|
import { RegisteredView } from "./RegisteredView";
|
||||||
import { usePageTitle } from "../usePageTitle";
|
import { usePageTitle } from "../usePageTitle";
|
||||||
@@ -21,9 +21,9 @@ export const HomePage: FC = () => {
|
|||||||
const clientState = useClientState();
|
const clientState = useClientState();
|
||||||
|
|
||||||
if (!clientState) {
|
if (!clientState) {
|
||||||
return <LoadingView />;
|
return <LoadingPage />;
|
||||||
} else if (clientState.state === "error") {
|
} else if (clientState.state === "error") {
|
||||||
return <ErrorView error={clientState.error} />;
|
return <ErrorPage error={clientState.error} />;
|
||||||
} else {
|
} else {
|
||||||
return clientState.authenticated ? (
|
return clientState.authenticated ? (
|
||||||
<RegisteredView client={clientState.authenticated.client} />
|
<RegisteredView client={clientState.authenticated.client} />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { type MatrixClient } from "matrix-js-sdk/src/client";
|
import { type MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { Button, Heading, Text } from "@vector-im/compound-web";
|
import { Button, Heading, Text } from "@vector-im/compound-web";
|
||||||
|
import { OfflineIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
@@ -25,9 +26,9 @@ import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
|
|||||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||||
import { FieldRow, InputField } from "../input/Input";
|
import { FieldRow, InputField } from "../input/Input";
|
||||||
import { StarRatingInput } from "../input/StarRatingInput";
|
import { StarRatingInput } from "../input/StarRatingInput";
|
||||||
import { RageshakeButton } from "../settings/RageshakeButton";
|
|
||||||
import { Link } from "../button/Link";
|
import { Link } from "../button/Link";
|
||||||
import { LinkButton } from "../button";
|
import { LinkButton } from "../button";
|
||||||
|
import { ErrorView } from "../ErrorView";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
client: MatrixClient;
|
client: MatrixClient;
|
||||||
@@ -147,25 +148,17 @@ export const CallEndedView: FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<Heading size="xl" weight="semibold" className={styles.headline}>
|
<ErrorView
|
||||||
<Trans i18nKey="call_ended_view.body">
|
Icon={OfflineIcon}
|
||||||
You were disconnected from the call
|
title={t("error.connection_lost")}
|
||||||
</Trans>
|
rageshake
|
||||||
</Heading>
|
>
|
||||||
<div className={styles.disconnectedButtons}>
|
<p>{t("error.connection_lost_description")}</p>
|
||||||
<Button onClick={reconnect}>
|
<Button onClick={reconnect}>
|
||||||
{t("call_ended_view.reconnect_button")}
|
{t("call_ended_view.reconnect_button")}
|
||||||
</Button>
|
</Button>
|
||||||
<div className={styles.rageshakeButton}>
|
</ErrorView>
|
||||||
<RageshakeButton description="***Call disconnected***" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
{!confineToRoom && (
|
|
||||||
<Text className={styles.footer}>
|
|
||||||
<Link to="/"> {t("return_home_button")} </Link>
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||||
import { JoinRule } from "matrix-js-sdk/src/matrix";
|
import { JoinRule } from "matrix-js-sdk/src/matrix";
|
||||||
import { Heading, Text } from "@vector-im/compound-web";
|
import { WebBrowserIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
@@ -54,11 +54,11 @@ import { useJoinRule } from "./useJoinRule";
|
|||||||
import { InviteModal } from "./InviteModal";
|
import { InviteModal } from "./InviteModal";
|
||||||
import { useUrlParams } from "../UrlParams";
|
import { useUrlParams } from "../UrlParams";
|
||||||
import { E2eeType } from "../e2ee/e2eeType";
|
import { E2eeType } from "../e2ee/e2eeType";
|
||||||
import { Link } from "../button/Link";
|
|
||||||
import { useAudioContext } from "../useAudioContext";
|
import { useAudioContext } from "../useAudioContext";
|
||||||
import { callEventAudioSounds } from "./CallEventAudioRenderer";
|
import { callEventAudioSounds } from "./CallEventAudioRenderer";
|
||||||
import { useLatest } from "../useLatest";
|
import { useLatest } from "../useLatest";
|
||||||
import { usePageTitle } from "../usePageTitle";
|
import { usePageTitle } from "../usePageTitle";
|
||||||
|
import { ErrorView } from "../ErrorView";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -331,9 +331,9 @@ export const GroupCallView: FC<Props> = ({
|
|||||||
// If we have a encryption system but the browser does not support it.
|
// If we have a encryption system but the browser does not support it.
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<Heading>{t("browser_media_e2ee_unsupported_heading")}</Heading>
|
<ErrorView Icon={WebBrowserIcon} title={t("error.e2ee_unsupported")}>
|
||||||
<Text>{t("browser_media_e2ee_unsupported")}</Text>
|
<p>{t("error.e2ee_unsupported_description")}</p>
|
||||||
<Link to="/">{t("common.home")}</Link>
|
</ErrorView>
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ import {
|
|||||||
type JSX,
|
type JSX,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
UnknownSolidIcon,
|
||||||
|
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
import { type MatrixError } from "matrix-js-sdk/src/http-api";
|
import { type MatrixError } from "matrix-js-sdk/src/http-api";
|
||||||
import { Heading, Text } from "@vector-im/compound-web";
|
|
||||||
|
|
||||||
import { useClientLegacy } from "../ClientContext";
|
import { useClientLegacy } from "../ClientContext";
|
||||||
import { ErrorView, FullScreenView, LoadingView } from "../FullScreenView";
|
import { ErrorPage, FullScreenView, LoadingPage } from "../FullScreenView";
|
||||||
import { RoomAuthView } from "./RoomAuthView";
|
import { RoomAuthView } from "./RoomAuthView";
|
||||||
import { GroupCallView } from "./GroupCallView";
|
import { GroupCallView } from "./GroupCallView";
|
||||||
import { useRoomIdentifier, useUrlParams } from "../UrlParams";
|
import { useRoomIdentifier, useUrlParams } from "../UrlParams";
|
||||||
@@ -37,6 +39,7 @@ import { useMuteStates } from "./MuteStates";
|
|||||||
import { useOptInAnalytics } from "../settings/settings";
|
import { useOptInAnalytics } from "../settings/settings";
|
||||||
import { Config } from "../config/Config";
|
import { Config } from "../config/Config";
|
||||||
import { Link } from "../button/Link";
|
import { Link } from "../button/Link";
|
||||||
|
import { ErrorView } from "../ErrorView";
|
||||||
|
|
||||||
export const RoomPage: FC = () => {
|
export const RoomPage: FC = () => {
|
||||||
const {
|
const {
|
||||||
@@ -171,29 +174,40 @@ export const RoomPage: FC = () => {
|
|||||||
if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") {
|
if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") {
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<Heading>{t("group_call_loader.failed_heading")}</Heading>
|
<ErrorView
|
||||||
<Text>{t("group_call_loader.failed_text")}</Text>
|
Icon={UnknownSolidIcon}
|
||||||
{/* XXX: A 'create it for me' button would be the obvious UX here. Two screens already have
|
title={t("error.call_not_found")}
|
||||||
dupes of this flow, let's make a common component and put it here. */}
|
>
|
||||||
<Link to="/">{t("common.home")}</Link>
|
<Trans i18nKey="error.call_not_found_description">
|
||||||
|
<p>
|
||||||
|
That link doesn't appear to belong to any existing call.
|
||||||
|
Check that you have the right link, or{" "}
|
||||||
|
<Link to="/">create a new one</Link>.
|
||||||
|
</p>
|
||||||
|
</Trans>
|
||||||
|
</ErrorView>
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
} else if (groupCallState.error instanceof CallTerminatedMessage) {
|
} else if (groupCallState.error instanceof CallTerminatedMessage) {
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<Heading>{groupCallState.error.message}</Heading>
|
<ErrorView
|
||||||
<Text>{groupCallState.error.messageBody}</Text>
|
Icon={groupCallState.error.icon}
|
||||||
{groupCallState.error.reason && (
|
title={groupCallState.error.message}
|
||||||
<>
|
>
|
||||||
{t("group_call_loader.reason")}:
|
<p>{groupCallState.error.messageBody}</p>
|
||||||
<Text size="sm">"{groupCallState.error.reason}"</Text>
|
{groupCallState.error.reason && (
|
||||||
</>
|
<p>
|
||||||
)}
|
{t("group_call_loader.reason", {
|
||||||
<Link to="/">{t("common.home")}</Link>
|
reason: groupCallState.error.reason,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</ErrorView>
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return <ErrorView error={groupCallState.error} />;
|
return <ErrorPage error={groupCallState.error} />;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return <> </>;
|
return <> </>;
|
||||||
@@ -202,9 +216,9 @@ export const RoomPage: FC = () => {
|
|||||||
|
|
||||||
let content: ReactNode;
|
let content: ReactNode;
|
||||||
if (loading || isRegistering) {
|
if (loading || isRegistering) {
|
||||||
content = <LoadingView />;
|
content = <LoadingPage />;
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
content = <ErrorView error={error} />;
|
content = <ErrorPage error={error} />;
|
||||||
} else if (!client) {
|
} else if (!client) {
|
||||||
content = <RoomAuthView />;
|
content = <RoomAuthView />;
|
||||||
} else if (!roomIdOrAlias) {
|
} else if (!roomIdOrAlias) {
|
||||||
|
|||||||
@@ -5,7 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useCallback } from "react";
|
import {
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useCallback,
|
||||||
|
type ComponentType,
|
||||||
|
type SVGAttributes,
|
||||||
|
} from "react";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
import {
|
import {
|
||||||
@@ -19,6 +26,11 @@ import { RoomEvent, type Room } from "matrix-js-sdk/src/models/room";
|
|||||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||||
import { JoinRule, MatrixError } from "matrix-js-sdk/src/matrix";
|
import { JoinRule, MatrixError } from "matrix-js-sdk/src/matrix";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import {
|
||||||
|
AdminIcon,
|
||||||
|
CloseIcon,
|
||||||
|
EndCallIcon,
|
||||||
|
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
|
|
||||||
import { widget } from "../widget";
|
import { widget } from "../widget";
|
||||||
|
|
||||||
@@ -92,27 +104,25 @@ async function joinRoomAfterInvite(
|
|||||||
|
|
||||||
export class CallTerminatedMessage extends Error {
|
export class CallTerminatedMessage extends Error {
|
||||||
/**
|
/**
|
||||||
* @param messageBody The message explaining the kind of termination (kick, ban, knock reject, etc.) (translated)
|
|
||||||
*/
|
|
||||||
public messageBody: string;
|
|
||||||
/**
|
|
||||||
* @param reason The user provided reason for the termination (kick/ban)
|
|
||||||
*/
|
|
||||||
public reason?: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param messageTitle The title of the call ended screen message (translated)
|
* @param messageTitle The title of the call ended screen message (translated)
|
||||||
* @param messageBody The message explaining the kind of termination (kick, ban, knock reject, etc.) (translated)
|
|
||||||
* @param reason The user provided reason for the termination (kick/ban)
|
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
|
/**
|
||||||
|
* The icon to display with the message.
|
||||||
|
*/
|
||||||
|
public readonly icon: ComponentType<SVGAttributes<SVGElement>>,
|
||||||
messageTitle: string,
|
messageTitle: string,
|
||||||
messageBody: string,
|
/**
|
||||||
reason?: string,
|
* The message explaining the kind of termination (kick, ban, knock reject,
|
||||||
|
* etc.) (translated)
|
||||||
|
*/
|
||||||
|
public readonly messageBody: string,
|
||||||
|
/**
|
||||||
|
* The user-provided reason for the termination (kick/ban)
|
||||||
|
*/
|
||||||
|
public readonly reason?: string,
|
||||||
) {
|
) {
|
||||||
super(messageTitle);
|
super(messageTitle);
|
||||||
this.messageBody = messageBody;
|
|
||||||
this.reason = reason;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +138,7 @@ export const useLoadGroupCall = (
|
|||||||
const bannedError = useCallback(
|
const bannedError = useCallback(
|
||||||
(): CallTerminatedMessage =>
|
(): CallTerminatedMessage =>
|
||||||
new CallTerminatedMessage(
|
new CallTerminatedMessage(
|
||||||
|
AdminIcon,
|
||||||
t("group_call_loader.banned_heading"),
|
t("group_call_loader.banned_heading"),
|
||||||
t("group_call_loader.banned_body"),
|
t("group_call_loader.banned_body"),
|
||||||
leaveReason(),
|
leaveReason(),
|
||||||
@@ -137,6 +148,7 @@ export const useLoadGroupCall = (
|
|||||||
const knockRejectError = useCallback(
|
const knockRejectError = useCallback(
|
||||||
(): CallTerminatedMessage =>
|
(): CallTerminatedMessage =>
|
||||||
new CallTerminatedMessage(
|
new CallTerminatedMessage(
|
||||||
|
CloseIcon,
|
||||||
t("group_call_loader.knock_reject_heading"),
|
t("group_call_loader.knock_reject_heading"),
|
||||||
t("group_call_loader.knock_reject_body"),
|
t("group_call_loader.knock_reject_body"),
|
||||||
leaveReason(),
|
leaveReason(),
|
||||||
@@ -146,6 +158,7 @@ export const useLoadGroupCall = (
|
|||||||
const removeNoticeError = useCallback(
|
const removeNoticeError = useCallback(
|
||||||
(): CallTerminatedMessage =>
|
(): CallTerminatedMessage =>
|
||||||
new CallTerminatedMessage(
|
new CallTerminatedMessage(
|
||||||
|
EndCallIcon,
|
||||||
t("group_call_loader.call_ended_heading"),
|
t("group_call_loader.call_ended_heading"),
|
||||||
t("group_call_loader.call_ended_body"),
|
t("group_call_loader.call_ended_body"),
|
||||||
leaveReason(),
|
leaveReason(),
|
||||||
|
|||||||
Reference in New Issue
Block a user