From 440f52416745c439c30f2c7b0fe38a83cbc752cb Mon Sep 17 00:00:00 2001 From: Walter Date: Fri, 23 Jun 2017 19:36:41 +0000 Subject: [PATCH 001/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a666de60aa..09273ae06a 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -4,7 +4,7 @@ "accepted the invitation for": "принял приглашение на", "Account": "Аккаунт", "Add email address": "Добавить email адрес", - "Add phone number": "Добавить телефонный номер", + "Add phone number": "Добавить тел. номер", "Admin": "Админ", "Advanced": "Дополнительно", "Algorithm": "Алгоритм", @@ -967,5 +967,7 @@ "Ignore request": "Игнорировать запрос", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Вы добавили новое устройство '%(displayName)s', который запрашивает ключи шифрования.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваше непроверенное устройство '%(displayName)s' запрашивает ключи шифрования.", - "Encryption key request": "Запрос ключа шифрования" + "Encryption key request": "Запрос ключа шифрования", + "Updates": "Обновления", + "Check for update": "Проверить обновление" } From ef32c9ce963aed529b3662dc5946a8c973e15b27 Mon Sep 17 00:00:00 2001 From: Walter Date: Fri, 23 Jun 2017 19:43:37 +0000 Subject: [PATCH 002/164] Translated using Weblate (Ukrainian) Currently translated at 18.7% (172 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index fab2148c47..3cdec9f633 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -166,5 +166,9 @@ "Add phone number": "Добавити телефонний номер", "Admin": "Адмін", "Admin tools": "Адмін утиліта", - "And %(count)s more...": "І %(count)s більше..." + "And %(count)s more...": "І %(count)s більше...", + "VoIP": "VoIP", + "Missing Media Permissions, click here to request.": "Відсутьне розрішення, натисніть для запиту.", + "No Microphones detected": "Мікрофони не виявлено", + "No Webcams detected": "Веб-камера не виявленна" } From af0effabc2b6b93310d181d602677dc635330501 Mon Sep 17 00:00:00 2001 From: bldrzzy Date: Sun, 25 Jun 2017 21:02:28 +0000 Subject: [PATCH 003/164] Translated using Weblate (Polish) Currently translated at 16.3% (150 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 153 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 9e26dfeeb6..8835708c87 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -1 +1,152 @@ -{} \ No newline at end of file +{ + "Ignore request": "Zignoruj żądanie", + "Start verification": "Rozpocznij weryfikacje", + "Skip": "Pomiń", + "This will allow you to reset your password and receive notifications.": "To pozwoli Ci zresetować Twoje hasło i otrzymać powiadomienia.", + "Your browser does not support the required cryptography extensions": "Twoja przeglądarka nie wspiera wymaganych rozszerzeń kryptograficznych", + "Something went wrong!": "Coś poszło nie tak!", + "Username not available": "Nazwa użytkownika niedostępna", + "Username available": "Nazwa użytkownika dostępna", + "Click on the button below to start chatting!": "Kliknij na przycisk poniżej aby rozpocząć rozmowę!", + "Start chatting": "Rozpocznij konwersację", + "Start Chatting": "Rozpocznij Konwersację", + "Updates": "Aktualizacje", + "This image cannot be displayed.": "Ten obrazek nie może zostać wyświetlony.", + "Default server": "Domyślny serwer", + "A text message has been sent to": "Wiadomość tekstowa została wysłana do", + "Add User": "Dodaj Użytkownika", + "Verify...": "Zweryfikuj...", + "Unknown Address": "Nieznany Adres", + "Unknown devices": "Nieznane urządzenia", + "Verify device": "Zweryfikuj urządzenie", + "Device key": "Klucz urządzenia", + "Device Name": "Nazwa Urządzenia", + "Device name": "Nazwa urządzenia", + "To continue, please enter your password.": "Aby kontynuować, proszę wprowadzić swoje hasło.", + "Incorrect password": "Nieprawidłowe hasło", + "Unknown error": "Nieznany błąd", + "Start new chat": "Rozpocznij nową konwersację", + "Options": "Opcje", + "New Password": "Nowe Hasło", + "Room directory": "Spis pokojów", + "Start chat": "Rozpocznij rozmowę", + "Welcome page": "Strona powitalna", + "Create new room": "Utwórz nowy pokój", + "Sunday": "Niedziela", + "Wednesday": "Środa", + "Thursday": "Czwartek", + "Friday": "Piątek", + "Saturday": "Sobota", + "Monday": "Poniedziałek", + "Tuesday": "Wtorek", + "or": "lub", + "Cancel": "Anuluj", + "Room": "Pokój", + "Topic": "Temat", + "Jan": "Sty", + "Feb": "Lut", + "Mar": "Mar", + "Apr": "Kwi", + "May": "Maj", + "Jun": "Cze", + "Jul": "Lip", + "Aug": "Sie", + "Sep": "Wrz", + "Oct": "Paź", + "Nov": "Lis", + "Dec": "Gru", + "Mon": "Pon", + "Tue": "Wt", + "Wed": "Śr", + "Thu": "Czw", + "Fri": "Pt", + "Sat": "Sob", + "Sun": "Nd", + "Who can read history?": "Kto może czytać historię?", + "Warning!": "Uwaga!", + "User": "Użytkownik", + "Users": "Użytkownicy", + "User name": "Nazwa użytkownika", + "User ID": "ID Użytkownika", + "User Interface": "Interfejs Użytkownika", + "Usage": "Użycie", + "Upload file": "Prześlij plik", + "Unban": "Odbanuj", + "en": "Angielski", + "fi": "Fiński", + "fr": "Francuski", + "he": "Hebrajski", + "hu": "Węgierski", + "it": "Włoski", + "ja": "Japoński", + "no": "Norweski", + "pl": "Polski", + "ru": "Rosyjski", + "sq": "Albański", + "sr": "Serbski", + "th": "Tajski", + "uk": "Ukraiński", + "vi": "Wietnamski", + "Accept": "Akceptuj", + "Account": "Konto", + "Add": "Dodaj", + "Add phone number": "Dodaj numer telefonu", + "Microphone": "Mikrofon", + "Camera": "Kamera", + "Algorithm": "Algorytm", + "Hide removed messages": "Ukryj usunięte wiadomości", + "and": "i", + "Are you sure?": "Czy jesteś pewien?", + "Attachment": "Załącznik", + "Banned users": "Zbanowani użytkownicy", + "Change Password": "Zmień Hasło", + "Close": "Zamknij", + "Confirm password": "Potwierdź hasło", + "Confirm your new password": "Potwierdź swoje nowe hasło", + "Continue": "Kontynuuj", + "Create Room": "Stwórz Pokój", + "Cryptography": "Kryptografia", + "Current password": "Aktualne hasło", + "Create an account": "Stwórz konto", + "Delete": "Usuń", + "Devices": "Urządzenia", + "Direct Chat": "Rozmowa bezpośrednia", + "Drop here %(toAction)s": "Upuść tutaj %(toAction)s", + "Error": "Błąd", + "Notifications": "Powiadomienia", + "Operation failed": "Operacja nieudana", + "Remove": "Usuń", + "Search": "Szukaj", + "Settings": "Ustawienia", + "unknown error code": "nieznany kod błędu", + "OK": "OK", + "Custom Server Options": "Niestandardowe opcje serwera", + "Dismiss": "Zdymisjonować", + "Failed to forget room %(errCode)s": "Nie mogłem zapomnieć o pokoju %(errCode)s", + "Failed to join the room": "Nie udało się dołączyć do pokoju", + "Favourite": "Ulubiony", + "Mute": "Wycisz", + "Please Register": "Proszę się zarejestrować", + "powered by Matrix": "napędzany przez Matrix", + "Failed to change password. Is your password correct?": "Zmiana hasła nie powiodła się. Czy Twoje hasło jest poprawne?", + "be": "Białoruski", + "bg": "Bułgarski", + "cs": "Czeski", + "da": "Duński", + "de": "Niemiecki", + "el": "Grecki", + "et": "Estoński", + "ga": "Irlandzki", + "hr": "Chorwacki", + "is": "Islandzki", + "hi": "Hindi", + "lt": "Litewski", + "lv": "Łotewski", + "nl": "Holenderski", + "pt": "Portugalski", + "sl": "Słoweński", + "sk": "Słowacki", + "sv": "Szwedzki", + "tr": "Turecki", + "Add a topic": "Dodaj temat" +} From a0afb915a2f17d846bc019234a5c04d228b50508 Mon Sep 17 00:00:00 2001 From: IMIN <2reeseenmin@gmail.com> Date: Sun, 25 Jun 2017 22:55:19 +0000 Subject: [PATCH 004/164] Translated using Weblate (Korean) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 88 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 93cd72e8d9..547fe4e1fb 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -240,7 +240,7 @@ "Bulk Options": "대규모 설정", "Call Timeout": "전화 대기 시간 초과", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "홈 서버에 연결할 수 없어요 - 연결을 확인해주시고, 홈 서버의 SSL 인증서가 믿을 수 있는지 확인하시고, 브라우저 확장기능이 요청을 차단하고 있는지 확인해주세요.", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "주소창에 HTTPS 주소가 있을 때는 HTTP로 홈 서버를 연결할 수 없어요. HTTPS를 쓰거나 안전하지 않은 스크립트를 허용해주세요.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "주소창에 HTTPS URL이 있을 때는 HTTP로 홈 서버를 연결할 수 없어요. HTTPS를 쓰거나 안전하지 않은 스크립트를 허용해주세요.", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s님이 별명을 %(oldDisplayName)s에서 %(displayName)s로 바꾸셨어요.", "%(senderName)s changed their profile picture.": "%(senderName)s님이 자기 소개 사진을 바꾸셨어요.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s님이 %(powerLevelDiffText)s의 권한 등급을 바꾸셨어요.", @@ -284,7 +284,7 @@ "Device ID:": "장치 ID:", "Device key:": "장치 키:", "Devices will not yet be able to decrypt history from before they joined the room": "방에 들어가기 전에는 장치에서 기록을 해독할 수 없어요", - "Disable inline URL previews by default": "기본적으로 인라인 주소 미리보기를 끄기", + "Disable inline URL previews by default": "기본적으로 인라인 URL 미리보기를 끄기", "Disable markdown formatting": "마크다운 형식 끄기", "Disinvite": "초대 취소", "Displays action": "활동 보이기", @@ -317,7 +317,7 @@ "Failed to ban user": "사용자를 차단하지 못했어요", "Failed to change power level": "권한 등급을 바꾸지 못했어요", "Failed to delete device": "장치를 지우지 못했어요", - "Failed to fetch avatar URL": "아바타 주소를 불러오지 못했어요", + "Failed to fetch avatar URL": "아바타 URL을 불러오지 못했어요", "Failed to join room": "방에 들어가지 못했어요", "Failed to kick": "내쫓지 못했어요", "Failed to leave room": "방을 떠나지 못했어요", @@ -672,8 +672,8 @@ "You have been invited to join this room by %(inviterName)s": "%(inviterName)s님이 이 방에 초대하셨어요", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s님이 %(roomName)s에서 추방하셨어요.", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "모든 장치에서 로그아웃되었고 더 이상 알림을 받지 않으실 거에요. 다시 알림을 받으시려면, 각 장치에 로그인해주세요", - "You have disabled URL previews by default.": "사이트 미리보기 쓰지 않기를 기본으로 하셨어요.", - "You have enabled URL previews by default.": "사이트 미리보기 쓰기를 기본으로 하셨어요.", + "You have disabled URL previews by default.": "URL 미리보기 쓰지 않기를 기본으로 하셨어요.", + "You have enabled URL previews by default.": "URL 미리보기 쓰기를 기본으로 하셨어요.", "You have entered an invalid contact. Try using their Matrix ID or email address.": "잘못된 연락처를 입력하셨어요. 매트릭스 ID나 이메일 주소를 써보세요.", "You have no visible notifications": "보여드릴 알림이 없어요", "You may wish to login with a different account, or add this email to this account.": "다른 계정으로 로그인하거나, 이 이메일을 이 계정에 추가할 수도 있어요.", @@ -840,5 +840,81 @@ "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "이전에 더 최근 버전의 라이엇을 쓰셨다면, 이 버전과 맞지 않을 거에요. 창을 닫고 더 최근 버전으로 돌아가세요.", "Continue anyway": "무시하고 계속하기", "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "별명은 방에서 말할 때 다른 사람에게 보일 이름을 정하는 거에요. 어떤 게 좋으세요?", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "현재 인증하지 않은 장치를 요주의로 지정하셨어요. 이 장치들에 메시지를 보내려면 인증을 해야 해요." + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "현재 인증하지 않은 장치를 요주의로 지정하셨어요. 이 장치들에 메시지를 보내려면 인증을 해야 해요.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "각 장치가 알맞은 소유자에게 속해 있는지 인증 과정을 거치길 추천하지만, 원하신다면 그러지 않고 메시지를 다시 보내실 수 있어요.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\"에 본 적 없는 장치가 있어요.", + "Unknown devices": "알 수 없는 장치", + "Unknown Address": "알 수 없는 주소", + "Unblacklist": "요주의 취소", + "Blacklist": "요주의", + "Unverify": "확인 취소", + "Verify...": "확인...", + "ex. @bob:example.com": "예. @bob:example.com", + "Add User": "사용자 추가", + "This Home Server would like to make sure you are not a robot": "이 홈 서버는 당신이 로봇이 아닌지 확인하고 싶다네요", + "Sign in with CAS": "CAS로 로그인 하기", + "Please check your email to continue registration.": "등록하시려면 이메일을 확인해주세요.", + "Token incorrect": "토큰이 안 맞아요", + "A text message has been sent to": "문자 메시지를 보냈어요", + "Please enter the code it contains:": "들어있던 코드를 입력해주세요:", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "이메일 주소를 정하지 않으시면, 비밀번호를 다시 설정하실 수 없어요. 괜찮으신가요?", + "You are registering with %(SelectedTeamName)s": "%(SelectedTeamName)s로 등록할게요", + "Default server": "기본 서버", + "What does this mean?": "무슨 뜻인가요?", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "사용자 지정 서버 설정에서 다른 홈 서버 URL을 지정해 다른 매트릭스 서버에 로그인 할 수 있어요.", + "This allows you to use this app with an existing Matrix account on a different home server.": "이를 통해 이 앱과 다른 홈 서버의 기존 매트릭스 계정을 함께 쓸 수 있죠.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "사용자 지정 ID 서버를 설정할 수도 있지만 보통 그런 경우엔 이메일 주소를 기반으로 한 사용자와 상호작용이 막힐 거에요.", + "Custom server": "사용자 지정 서버", + "Home server URL": "홈 서버 URL", + "Identity server URL": "ID 서버 URL", + "Error decrypting audio": "음성 해독 오류", + "Error decrypting image": "사진 해독 오류", + "Image '%(Body)s' cannot be displayed.": "'%(Body)s' 사진을 보여드릴 수 없어요.", + "This image cannot be displayed.": "이 사진을 보여드릴 수 없어요.", + "Error decrypting video": "영상 해독 오류", + "Add an Integration": "통합 추가", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "타사 사이트로 이동하는데 %(integrationsUrl)s에서 쓰도록 계정을 인증할 수 있어요. 계속하시겠어요?", + "Removed or unknown message type": "지웠거나 알 수 없는 메시지 유형", + "Disable URL previews by default for participants in this room": "이 방에 있는 사용자의 URL 미리보기를 기본적으로 끄기", + "Disable URL previews for this room (affects only you)": "이 방의 URL 미리보기를 기본적으로 끄기 (자신만)", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "이 방에 있는 사용자의 URL 미리보기는 기본적으로 %(globalDisableUrlPreview)s.", + "URL Previews": "URL 미리보기", + "Enable URL previews for this room (affects only you)": "이 방의 URL 미리보기를 켜기 (자신만)", + "Drop file here to upload": "올릴 파일을 여기에 놓으세요", + " (unsupported)": " (지원하지 않음)", + "Ongoing conference call%(supportedText)s.": "진행중인 전화 회의%(supportedText)s.", + "for %(amount)ss": "%(amount)ss 동안", + "for %(amount)sm": "%(amount)sm 동안", + "for %(amount)sh": "%(amount)sh 동안", + "for %(amount)sd": "%(amount)sd 동안", + "Online": "접속 중", + "Idle": "쉬는 중", + "Offline": "미접속", + "Updates": "업데이트", + "Check for update": "업데이트 확인", + "Start chatting": "이야기하기", + "Start Chatting": "이야기하기", + "Click on the button below to start chatting!": "이야기하려면 아래 버튼을 누르세요!", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName님이 방 아바타를 로 바꾸셨어요", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s님이 방 아바타를 지우셨어요.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s가 %(roomName)s 방의 아바타를 바꾸셨어요", + "Username available": "쓸 수 있는 사용자 이름", + "Username not available": "쓸 수 없는 사용자 이름", + "Something went wrong!": "문제가 생겼어요!", + "This will be your account name on the homeserver, or you can pick a different server.": "이건 홈 서버의 계정 이름이에요, 다른 서버를 고를 수도 있다는 거죠.", + "If you already have a Matrix account you can log in instead.": "매트릭스 계정을 가지고 계시면 로그인하실 수도 있죠.", + "Your browser does not support the required cryptography extensions": "브라우저가 필요한 암호화 확장 기능을 지원하지 않아요", + "Not a valid Riot keyfile": "올바른 라이엇 키 파일이 아니에요", + "Authentication check failed: incorrect password?": "인증 확인 실패: 비밀번호를 틀리셨나요?", + "Disable Peer-to-Peer for 1:1 calls": "1:1 통화는 P2P 끄기", + "Do you want to set an email address?": "이메일 주소를 설정하시겠어요?", + "This will allow you to reset your password and receive notifications.": "이렇게 하면 비밀번호를 다시 설정하고 알림을 받으실 수 있어요.", + "To return to your account in future you need to set a password": "나중에 계정으로 돌아가려면 비밀번호를 설정하셔야 해요", + "Skip": "건너뛰기", + "Start verification": "인증 시작", + "Share without verifying": "인증하지 않고 공유하기", + "Ignore request": "요청 무시하기", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "새 장치 '%(displayName)s'를 추가했고 암호화 키를 요청하고 있어요.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "인증하지 않은 장치 '%(displayName)s'가 암호화 키를 요청하고 있어요.", + "Encryption key request": "암호화 키 요청" } From d5594c883ef26f78b7fc41131e341ee83ecfe175 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Sat, 24 Jun 2017 22:16:32 +0000 Subject: [PATCH 005/164] Translated using Weblate (German) Currently translated at 99.7% (914 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 8231040a45..ddd922992b 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -143,7 +143,7 @@ "joined and left": "hat den Raum betreten und wieder verlassen", "joined": "hat den Raum betreten", "joined the room": "trat dem Raum bei", - "Leave room": "Verlasse Raum", + "Leave room": "Raum verlassen", "left and rejoined": "ging(en) und trat(en) erneut bei", "left": "hat den Raum verlassen", "left the room": "verließ den Raum", @@ -215,7 +215,7 @@ "their invitations": "ihre Einladungen", "their invitation": "ihre Einladung", "These are experimental features that may break in unexpected ways. Use with caution": "Dies sind experimentelle Funktionen die in unerwarteter Weise Fehler verursachen können. Mit Vorsicht benutzen", - "The visibility of existing history will be unchanged": "Die Sichtbarkeit der bereits vorhandenen Chat-Historie bleibt unverändert", + "The visibility of existing history will be unchanged": "Die Sichtbarkeit des bereits vorhandenen Chatverlaufs bleibt unverändert", "This doesn't appear to be a valid email address": "Dies scheint keine gültige E-Mail-Adresse zu sein", "this invitation?": "diese Einladung?", "This is a preview of this room. Room interactions have been disabled": "Dies ist eine Vorschau dieses Raumes. Raum-Interaktionen wurden deaktiviert", @@ -266,16 +266,16 @@ "was unbanned": "wurde vom dauerhaften Ausschluss aus dem Raum befreit", "was": "wurde", "Who can access this room?": "Wer hat Zugang zu diesem Raum?", - "Who can read history?": "Wer kann die Chat-Historie lesen?", + "Who can read history?": "Wer kann den bisherigen Chatverlauf lesen?", "Who would you like to add to this room?": "Wen möchtest du zu diesem Raum hinzufügen?", "Who would you like to communicate with?": "Mit wem möchtest du kommunizieren?", "Would you like to": "Möchtest du", "You do not have permission to post to this room": "Du hast keine Berechtigung, in diesem Raum etwas zu senden", "You have been invited to join this room by %(inviterName)s": "%(inviterName)s hat dich in diesen Raum eingeladen", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Du wurdest auf allen Geräten abgemeldet und wirst keine Push-Benachrichtigungen mehr erhalten. Um die Benachrichtigungen zu reaktivieren, musst du dich auf jedem Gerät neu anmelden", - "you must be a": "nötige Rolle", + "you must be a": "Berechtigungslevel", "Your password has been reset": "Dein Passwort wurde zurückgesetzt", - "You should not yet trust it to secure data": "Du solltest nicht darauf vertrauen um deine Daten abzusichern", + "You should not yet trust it to secure data": "Du solltest aktuell noch nicht darauf vertrauen, dass deine Daten zuverlässig verschlüsselt werden", "removed their profile picture": "löschte das eigene Profilbild", "times": "mal", "Bulk Options": "Bulk-Optionen", @@ -677,8 +677,8 @@ "were invited %(repeats)s times": "wurden %(repeats)s mal eingeladen", "was invited %(repeats)s times": "wurde %(repeats)s mal eingeladen", "were invited": "wurden eingeladen", - "were banned %(repeats)s times": "wurden %(repeats)s mal dauerhaft aus dem Raum ausgeschlossen", - "was banned %(repeats)s times": "wurde %(repeats)s mal aus dem Raum ausgeschlossen", + "were banned %(repeats)s times": "wurden %(repeats)s-mal dauerhaft aus dem Raum ausgeschlossen", + "was banned %(repeats)s times": "wurde %(repeats)s-mal aus dem Raum ausgeschlossen", "were banned": "wurden dauerhaft aus dem Raum ausgeschlossen", "were unbanned %(repeats)s times": "wurden %(repeats)s mal vom dauerhaften Ausschluss aus dem Raum befreit", "was unbanned %(repeats)s times": "wurde %(repeats)s mal vom dauerhaften Ausschluss aus dem Raum befreit", @@ -736,7 +736,7 @@ "Start new Chat": "Starte neuen Chat", "Guest users can't invite users. Please register.": "Gäste können keine Benutzer einladen. Bitte registrieren.", "Failed to invite": "Einladen fehlgeschlagen", - "Failed to invite user": "Einladen des Nutzers fehlgeschlagen", + "Failed to invite user": "Einladen des Nutzers ist fehlgeschlagen", "Confirm Removal": "Entfernen bestätigen", "Unknown error": "Unbekannter Fehler", "Incorrect password": "Ungültiges Passwort", @@ -928,7 +928,7 @@ "Incoming voice call from %(name)s": "Eingehender Sprach-Anruf von %(name)s", "Join as voice or video.": "Per Sprachanruf oder Videoanruf beitreten.", "Last seen": "Zuletzt gesehen", - "Level:": "Level:", + "Level:": "Berechtigungslevel:", "No display name": "Kein Anzeigename", "Otherwise, click here to send a bug report.": "Alternativ hier klicken, um einen Fehlerbericht zu senden.", "Private Chat": "Privater Chat", @@ -945,7 +945,7 @@ "Start authentication": "Authentifizierung beginnen", "Show Text Formatting Toolbar": "Text-Formatierungs-Werkzeugleiste anzeigen", "This invitation was sent to an email address which is not associated with this account:": "Diese Einledung wurde an eine E-Mail-Adresse gesendet, die nicht mit diesem Konto verknüpft ist:", - "This room": "Dieser Raum", + "This room": "In diesem Raum", "To link to a room it must have an address.": "Um einen Raum zu verlinken, muss er eine Adresse haben.", "Undecryptable": "Nicht entschlüsselbar", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Kann nicht feststellen, ob die Adresse an die diese Einladung gesendet wurde mit einer übereinstimmt, die zu deinem Konto gehört.", @@ -965,7 +965,7 @@ "(~%(count)s results).one": "(~%(count)s Ergebnis)", "(~%(count)s results).other": "(~%(count)s Ergebnis)", "Device Name": "Geräte-Name", - "(could not connect media)": "(Medienverbindung nicht herstellbar)", + "(could not connect media)": "(Medienverbindung konnte nicht hergestellt werden)", "(no answer)": "(keine Antwort)", "(unknown failure: %(reason)s)": "(Unbekannter Fehler: %(reason)s)", "Your browser does not support the required cryptography extensions": "Dein Browser unterstützt die benötigten Kryptografie-Erweiterungen nicht", @@ -973,15 +973,15 @@ "Authentication check failed: incorrect password?": "Authentifizierung fehlgeschlagen: Falsches Passwort?", "Disable Peer-to-Peer for 1:1 calls": "Peer-to-Peer-Verbindung für 1-zu-1-Anrufe deaktivieren", "Do you want to set an email address?": "Möchtest du eine E-Mail-Adresse setzen?", - "This will allow you to reset your password and receive notifications.": "Dies erlaubt dir dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen.", - "Press to start a chat with someone": "Klicke auf um einen Chat mit jemanden zu starten", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Du bist bisher in keinem Raum! Klicke auf um einen Raum zu erstellen oder um das Verzeichnis zu durchsuchen", - "To return to your account in future you need to set a password": "Um in Zukunft zu deinem Konto zurückzukehren, musst du ein Passwort setzen", + "This will allow you to reset your password and receive notifications.": "Dies ermöglicht es dir, dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen.", + "Press to start a chat with someone": "Auf klicken, um einen Chat zu beginnen", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Du bist bislang keinem Raum beigetreten! Auf klicken, um einen Raum zu erstellen, oder auf klicken, um das Raum-Verzeichnis zu durchsuchen", + "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort einrichten", "Skip": "Überspringen", "Start verification": "Verifikation starten", - "Share without verifying": "Teile ohne Verifizierung", + "Share without verifying": "Ohne Verifizierung teilen", "Ignore request": "Anfrage ignorieren", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Du hast das neue Gerät '%(displayName)s' hinzugefügt, welches nun Verschlüsselungs-Schlüssel anfragt.", "Encryption key request": "Verschlüsselungs-Schlüssel-Anfrage", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Dein nicht verifiziertes Gerät '%(displayName)s' fragt nach Verschlüsselungs-Schlüsseln." + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Dein nicht verifiziertes Gerät '%(displayName)s' fordert Verschlüsselungs-Schlüssel an." } From 0771987e3953492bf1c936167457a852626be75d Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 26 Jun 2017 10:29:41 +0000 Subject: [PATCH 006/164] Translated using Weblate (German) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index ddd922992b..aa1edeffb8 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -983,5 +983,7 @@ "Ignore request": "Anfrage ignorieren", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Du hast das neue Gerät '%(displayName)s' hinzugefügt, welches nun Verschlüsselungs-Schlüssel anfragt.", "Encryption key request": "Verschlüsselungs-Schlüssel-Anfrage", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Dein nicht verifiziertes Gerät '%(displayName)s' fordert Verschlüsselungs-Schlüssel an." + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Dein nicht verifiziertes Gerät '%(displayName)s' fordert Verschlüsselungs-Schlüssel an.", + "Updates": "Updates", + "Check for update": "Suche nach Updates" } From 5d5d4bcc5730d84a414b5eae1ed611479b364746 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 26 Jun 2017 10:30:48 +0000 Subject: [PATCH 007/164] Added translation using Weblate (Persian) --- src/i18n/strings/fa.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/fa.json diff --git a/src/i18n/strings/fa.json b/src/i18n/strings/fa.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/fa.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 5e857afd5e4e97cf916b23f184108bb306938e97 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 26 Jun 2017 15:26:41 +0000 Subject: [PATCH 008/164] Translated using Weblate (French) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 3c86349cfb..bc7a47029f 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -924,5 +924,15 @@ "Do you want to set an email address?": "Souhaitez-vous configurer une adresse e-mail ?", "This will allow you to reset your password and receive notifications.": "Ceci va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications.", "Press to start a chat with someone": "Cliquez sur pour entamer une discussion avec quelqu'un", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salle ! Cliquez sur pour créer une salle ou sur pour explorer l'annuaire" + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salle ! Cliquez sur pour créer une salle ou sur pour explorer l'annuaire", + "To return to your account in future you need to set a password": "Pour pouvoir accéder à votre compte dans le futur, vous devez enregistrer un mot de passe", + "Skip": "Passer", + "Start verification": "Commencer la vérification", + "Share without verifying": "Partager sans vérifier", + "Ignore request": "Ignorer la requête", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Vous avez ajouté un nouvel appareil, '%(displayName)s', qui demande des clés de chiffrement.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Votre appareil non vérifié '%(displayName)s' demande des clés de chiffrements", + "Encryption key request": "Requête de clé de chiffrement", + "Updates": "Mises à jour", + "Check for update": "Rechercher une mise à jour" } From 8222a4972f60121ef4c74667782bfe4e070c375b Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 27 Jun 2017 02:37:52 +0000 Subject: [PATCH 009/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 672 +++++++++++++++++++-------------------- 1 file changed, 336 insertions(+), 336 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 09273ae06a..a0db062ddf 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -3,9 +3,9 @@ "accepted an invitation": "принял приглашение", "accepted the invitation for": "принял приглашение на", "Account": "Аккаунт", - "Add email address": "Добавить email адрес", - "Add phone number": "Добавить тел. номер", - "Admin": "Админ", + "Add email address": "Добавить адрес электронной почты", + "Add phone number": "Добавить номер телефона", + "Admin": "Администратор", "Advanced": "Дополнительно", "Algorithm": "Алгоритм", "all room members": "все участники комнаты", @@ -20,14 +20,14 @@ "Anyone who knows the room's link, apart from guests": "Любой, кто знает ссылку на комнату, кроме гостей", "Anyone who knows the room's link, including guests": "Любой, кто знает ссылку комнаты, включая гостей", "Are you sure you want to reject the invitation?": "Вы уверены что вы хотите отклонить приглашение?", - "Are you sure you want to upload the following files?": "Вы уверены что вы хотите закачать следующий файл?", + "Are you sure you want to upload the following files?": "Вы уверены что вы хотите загрузить следующие файлы?", "banned": "banned", "Banned users": "Запрещенный пользователь", "Bans user with given id": "Запретить пользователя с определенным id", - "Blacklisted": "В черный список", - "Bug Report": "Отчет ошибок", - "Bulk Options": "Объемные параметры", - "Can't load user settings": "Не может загрузить настройки пользователя", + "Blacklisted": "В черном списке", + "Bug Report": "Отчет об ошибке", + "Bulk Options": "Групповые параметры", + "Can't load user settings": "Невозможно загрузить пользовательские настройки", "changed avatar": "изменен аватар", "changed name": "измененное имя", "changed their display name from": "changed their display name from", @@ -35,114 +35,114 @@ "changed the power level of": "changed the power level of", "changed the room name to": "changed the room name to", "changed the topic to": "changed the topic to", - "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут только относиться к будущим сообщениям в этой комнате", - "Changes your display nickname": "Изменяет Ваш псевдоним", - "Claimed Ed25519 fingerprint key": "Требуемый Ed25519 ключ цифрового отпечатка", + "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", + "Changes your display nickname": "Изменяет ваш псевдоним", + "Claimed Ed25519 fingerprint key": "Требуемый ключ цифрового отпечатка Ed25519", "Clear Cache and Reload": "Очистить кэш и перезагрузить", "Clear Cache": "Очистить кэш", "Click here": "Нажать здесь", - "Click here to fix": "Нажать здесь для фиксации", + "Click here to fix": "Щелкните здесь, чтобы исправить", "Commands": "Команды", - "Confirm your new password": "Подтвердите ваш новый пароль", + "Confirm your new password": "Подтвердите новый пароль", "Continue": "Продолжить", - "Could not connect to the integration server": "Не может подключится к серверу интеграции", - "Create an account": "Создайте учётную запись", - "Create Room": "Создайте Комнату", - "Cryptography": "Шифрование", - "Curve25519 identity key": "Curve25519 идентификационный ключ", - "Deactivate Account": "Деактивировать учётную запись", - "Deactivate my account": "Деактивировать мою учётную запись", + "Could not connect to the integration server": "Не удалось подключиться к серверу интеграции", + "Create an account": "Создать учетную запись", + "Create Room": "Создать комнату", + "Cryptography": "Криптография", + "Curve25519 identity key": "Ключ идентификации Curve25519", + "Deactivate Account": "Деактивировать учетную запись", + "Deactivate my account": "Деактивировать мою учетную запись", "decline": "отказаться", - "Decryption error": "Ошибка дешифрования", - "Default": "Стандарт", - "demote": "понижать", - "Deops user with given id": "Deops пользователь с данным id", - "Device ID": "Устройство ID", - "Devices will not yet be able to decrypt history from before they joined the room": "Устройство еще не будет в состоянии дешифровать историю, до присоединения к комнате", - "Direct Chat": "Приватный чат", - "Disable inline URL previews by default": "Отключить встроенные предварительные просмотры URL по умолчанию", + "Decryption error": "Ошибка расшифровки", + "Default": "По умолчанию", + "demote": "понизить уровень авторизации", + "Deops user with given id": "Удалить пользователь с данным id", + "Device ID": "ID устройства", + "Devices will not yet be able to decrypt history from before they joined the room": "Устройства не смогут дешифровать историю, пока они не войдут в комнату", + "Direct Chat": "Прямой чат", + "Disable inline URL previews by default": "Отключить предварительный просмотр URL-адресов по умолчанию", "Display name": "Отображаемое имя", "Displays action": "Отображение действий", - "Ed25519 fingerprint": "Ed25519 fingerprint", + "Ed25519 fingerprint": "Ed25519 отпечаток", "Email Address": "Email адрес", "Email, name or matrix ID": "Email, имя или matrix ID", "Emoji": "Смайлы", - "Encrypted messages will not be visible on clients that do not yet implement encryption": "Зашифрованные сообщения не будут видимы в клиентах, которые еще не подключили шифрование", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Зашифрованные сообщения не будут видны в клиентах, которые еще не подключили шифрование", "Encrypted room": "Зашифрованная комната", "ended the call.": "ended the call.", - "End-to-end encryption information": "Информация сквозного шифрования (e2e)", - "End-to-end encryption is in beta and may not be reliable": "Сквозное шифрование (e2e) в бета-версии и не может быть надежным", + "End-to-end encryption information": "Сведения о сквозном шифровании", + "End-to-end encryption is in beta and may not be reliable": "Сквозное шифрование находится в бета-версии и может быть ненадежным", "Error": "Ошибка", - "Event information": "Event information", - "Export E2E room keys": "Экспорт E2E ключей комнаты", + "Event information": "Информация о событии", + "Export E2E room keys": "Экспорт ключей E2E", "Failed to change password. Is your password correct?": "Не удалось сменить пароль. Вы правильно ввели текущий пароль?", "Failed to forget room": "Не удалось забыть комнату", "Failed to leave room": "Не удалось выйти из комнаты", "Failed to reject invitation": "Не удалось отклонить приглашение", - "Failed to send email": "Не удалось отослать email", - "Failed to unban": "Не удалось отменить запрет", - "Failed to upload file": "Не удалось закачать файл", + "Failed to send email": "Ошибка отправки электронной почты", + "Failed to unban": "Не удалось разблокировать", + "Failed to upload file": "Не удалось выгрузить файл", "Favourite": "Избранное", - "favourite": "Избранное", - "Favourites": "Избранное", - "Filter room members": "Поиск участников комнаты", + "favourite": "избранный", + "Favourites": "Избранные", + "Filter room members": "Фильтр участников комнаты", "Forget room": "Забыть комнату", - "Forgot your password?": "Вы забыли пароль?", - "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности эта сессия была завершена. Войдите в систему еще раз.", + "Forgot your password?": "Забыли пароль?", + "For security, this session has been signed out. Please sign in again.": "По соображениям безопасности, эта сессия была прекращена. Пожалуйста, войдите снова.", "Found a bug?": "Нашли ошибку?", - "had": "имеет", - "Hangup": "Отключение", - "Historical": "История", - "Homeserver is": "Домашний сервер является", - "Identity Server is": "Регистрационный сервер", - "I have verified my email address": "Я проверил мой адрес электронной почты", - "Import E2E room keys": "Импортировать E2E ключ комнаты", - "Invalid Email Address": "Недействительный адрес электронной почты", + "had": "был", + "Hangup": "Закончить", + "Historical": "Архив", + "Homeserver is": "Домашний сервер это", + "Identity Server is": "Идентификационный сервер это", + "I have verified my email address": "Я подтвердил свой адрес электронной почты", + "Import E2E room keys": "Импортировать E2E-ключи комнаты", + "Invalid Email Address": "Недопустимый адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", "Invites": "Приглашает", "Invites user with given id to current room": "Приглашает пользователя с этим ID в текущую комнату", "is a": "является", - "Sign in with": "Я хочу регистрироваться с", - "joined and left": "зашёл и ушёл", - "joined": "зашёл", + "Sign in with": "Войти с помощью", + "joined and left": "вошел и вышел", + "joined": "вошел", "joined the room": "joined the room", - "Joins room with given alias": "зашёл в комнату с этим именем", - "Kicks user with given id": "Выгнать пользователя с заданным id", + "Joins room with given alias": "Вошел в комнату с этим псевдонимом", + "Kicks user with given id": "Удаляет пользователя с заданным id", "Labs": "Лаборатория", - "Leave room": "Выйти из комнаты", - "left and rejoined": "Покинуть и пере подключится", - "left": "покинуть", + "Leave room": "Покинуть комнату", + "left and rejoined": "вышел и вернулся", + "left": "вышел", "left the room": "left the room", "Logged in as": "Зарегистрированный как", - "Login as guest": "Вход в систему как гость", + "Login as guest": "Войти как гость", "Logout": "Выйти", "Low priority": "Низкий приоритет", "made future room history visible to": "made future room history visible to", - "Manage Integrations": "Управление Интеграциями", + "Manage Integrations": "Управление интеграциями", "Members only": "Только участники", "Mobile phone number": "Номер мобильного телефона", - "Moderator": "Ведущий", + "Moderator": "Модератор", "my Matrix ID": "мой Matrix ID", "Name": "Имя", - "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на не верифицированные устройства с этого устройства", - "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправляйте зашифрованные сообщения на непроверенные устройства в этой комнате из вашего устройства", + "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства с этого устройства", + "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства в этой комнате с этого устройства", "New password": "Новый пароль", "New passwords must match each other.": "Новые пароли должны совпадать.", "none": "никто", "Notifications": "Уведомления", " (not supported by this browser)": " (not supported by this browser)", - "": "<не поддерживаемый>", - "NOT verified": "НЕ проверенный", - "No users have specific privileges in this room": "Ни у каких пользователей нет специальных полномочий в этой комнате", + "": "<не поддерживается>", + "NOT verified": "НЕ проверено", + "No users have specific privileges in this room": "Ни один пользователь не имеет специальных полномочий в этой комнате", "olm version": "olm версия", - "Once encryption is enabled for a room it cannot be turned off again (for now)": "Как только шифрование включено для комнаты, оно не может быть выключено снова (на данный момент)", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "После включения шифрования в комнате, оно не может быть деактивировано (на данный момент)", "or": "или", "other": "другой", "others": "другие", "Password": "Пароль", "People": "Люди", - "Permissions": "Разрешение", + "Permissions": "Разрешения", "Phone": "Телефон", "placed a": "placed a", "Please Register": "Пожалуйста, зарегистрируйтесь", @@ -151,8 +151,8 @@ "removed their profile picture": "removed their profile picture", "Remove": "Удалить", "requested a VoIP conference": "requested a VoIP conference", - "Return to login screen": "Return to login screen", - "Send Reset Email": "Send Reset Email", + "Return to login screen": "Вернуться к экрану входа", + "Send Reset Email": "Отправить письмо со ссылкой для сброса пароля", "sent an image": "отправил изображение", "sent an invitation to": "sent an invitation to", "set a profile picture": "set a profile picture", @@ -162,36 +162,36 @@ "Start Chat": "Начать чат", "tag as": "tag as", "These are experimental features that may break in unexpected ways. Use with caution": "These are experimental features that may break in unexpected ways. Use with caution", - "To send events of type": "Для отправки типа событий", - "To send messages": "Отправить сообщения", + "To send events of type": "Чтобы отправить тип события", + "To send messages": "Чтобы отправить сообщения", "turned on end-to-end encryption (algorithm": "turned on end-to-end encryption (algorithm", - "Unable to add email address": "Невозможно добавить email адрес", - "Unable to remove contact information": "Невозможно удалить контактную информацию", - "Unable to verify email address.": "Невозможно проверить адрес электронной почты.", - "Unban": "Отменить запрет", + "Unable to add email address": "Не удается добавить адрес электронной почты", + "Unable to remove contact information": "Не удалось удалить контактную информацию", + "Unable to verify email address.": "Не удалось проверить адрес электронной почты.", + "Unban": "Разблокировать", "Unencrypted room": "Незашифрованная комната", - "unencrypted": "незашифровано", + "unencrypted": "без шифрования", "unknown device": "неизвестное устройство", - "unknown error code": "неизвестная ошибка", - "unknown": "неизвестно", + "unknown error code": "неизвестный код ошибки", + "unknown": "неизвестный", "Upload avatar": "Загрузить аватар", - "uploaded a file": "загруженный файл", - "Upload Files": "Загрузка файлов", - "Upload file": "Загрузка файла", + "uploaded a file": "отправленный файл", + "Upload Files": "Отправка файлов", + "Upload file": "Отправка файла", "User ID": "ID пользователя", "User Interface": "Пользовательский интерфейс", "User name": "Имя пользователя", "Users": "Пользователи", "User": "Пользователь", - "Verification Pending": "Ожидание проверки", - "Verification": "Проверка", + "Verification Pending": "В ожидании подтверждения", + "Verification": "Подтверждение", "verified": "проверенный", - "Video call": "Видио вызов", + "Video call": "Видеозвонок", "Voice call": "Голосовой вызов", - "VoIP conference finished.": "VoIP конференция закончилась.", - "VoIP conference started.": "VoIP конференция началась.", - "(warning: cannot be disabled again!)": "(предупреждение: не может быть отключено!)", - "Warning!": "Предупреждение!", + "VoIP conference finished.": "VoIP-конференция закончилась.", + "VoIP conference started.": "VoIP-конференция началась.", + "(warning: cannot be disabled again!)": "(предупреждение: отключить будет невозможно!)", + "Warning!": "Внимание!", "was banned": "запрещен", "was invited": "был приглашён", "was kicked": "выброшен", @@ -200,19 +200,19 @@ "were": "быть", "Who can access this room?": "Кто может получить доступ к этой комнате?", "Who can read history?": "Кто может читать историю?", - "Who would you like to add to this room?": "Кого бы вы хотели пригласить в эту комнату?", - "Who would you like to communicate with?": "С кем хотели бы Вы связываться?", + "Who would you like to add to this room?": "Кого бы вы хотели добавить в эту комнату?", + "Who would you like to communicate with?": "С кем бы вы хотели связаться?", "withdrawn": "уходить", "Would you like to": "Хотели бы Вы", - "You do not have permission to post to this room": "У Вас нет разрешения писать в эту комнату", - "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Вы вышли из всех устройств и не будет больше получать push-уведомления. Чтобы повторно включить уведомления, войдите в систему еще раз для каждого устройства", - "You have no visible notifications": "У Вас нет видимых уведомлений", - "you must be a": "Вы должны быть", - "Your password has been reset": "Ваш пароль был изменен", - "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Ваш пароль был успешно изменен. Вы не будете получать Push-уведомления о других устройствах, пока не войдете обратно на них", - "You should not yet trust it to secure data": "Вы еще не должны доверять этому защиту данных", + "You do not have permission to post to this room": "Вы не можете писать в эту комнату", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Вы вышли из всех устройств и больше не будете получать push-уведомления. Чтобы повторно активировать уведомления, войдите снова на каждом из устройств", + "You have no visible notifications": "Нет видимых уведомлений", + "you must be a": "уровень доступа", + "Your password has been reset": "Ваш пароль был сброшен", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Пароль успешно изменен. До повторной авторизации вы не будете получать push-уведомления на других устройствах", + "You should not yet trust it to secure data": "На сегодняшний день не следует полностью полагаться на то, что ваши данные будут надежно зашифрованы", "en": "Английский", - "pt-br": "Португальский Бразилия", + "pt-br": "Португальский (Бразилия)", "de": "Немецкий", "da": "Датский", "ru": "Русский", @@ -220,48 +220,48 @@ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", "Resend all": "Переслать снова всем", "cancel all": "отменить всем", - "Active call": "Активный звонок", + "Active call": "Активный вызов", "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатает", "%(names)s and one other are typing": "%(names)s и другой печатают", "%(names)s and %(count)s others are typing": "%(names)s и %(count)s другие печатают", "%(senderName)s answered the call.": "%(senderName)s ответил на звонок.", - "%(senderName)s banned %(targetName)s.": "%(senderName)s запрещенный %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s запрещен %(targetName)s.", "Call Timeout": "Время ожидания вызова", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s изменено с %(oldDisplayName)s на %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s изменил фото профиля.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s уровень мощности изменен на %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s имя комнаты изменено на %(roomName)s.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s измененная тема на %(topic)s.", - "Conference call failed.": "Конференц-вызов прервался.", - "Conference calling is in development and may not be reliable.": "Конференц-вызов находится в процессе и может не быть надежным.", - "Conference calls are not supported in encrypted rooms": "Конференц-вызовы не поддерживаются в зашифрованных комнатах", - "Conference calls are not supported in this client": "Конференц-вызовы не поддерживаются в этом клиенте", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил тему на %(topic)s.", + "Conference call failed.": "Не удалось выполнить групповой вызов.", + "Conference calling is in development and may not be reliable.": "Групповые вызовы находятся в разработке и могут быть нестабильны.", + "Conference calls are not supported in encrypted rooms": "Групповые вызовы не поддерживаются в зашифрованных комнатах", + "Conference calls are not supported in this client": "Групповые вызовы в этом клиенте не поддерживаются", "/ddg is not a command": "/ddg не команда", - "Drop here %(toAction)s": "Вставить сюда: %(toAction)s", - "Drop here to tag %(section)s": "Вставить здесь для тега %(section)s", - "%(senderName)s ended the call.": "%(senderName)s прекратил звонок.", - "Existing Call": "Существующий вызов", + "Drop here %(toAction)s": "Перетащить сюда: %(toAction)s", + "Drop here to tag %(section)s": "Перетащите сюда для тега %(section)s", + "%(senderName)s ended the call.": "%(senderName)s завершил звонок.", + "Existing Call": "Текущий вызов", "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", - "Failed to send request.": "Не удалось выслать запрос.", - "Failed to set up conference call": "Не удалось установить конференц-вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось подтвердить email-адрес: убедитесь что вы щелкнули по ссылке электронной почты", + "Failed to send request.": "Не удалось отправить запрос.", + "Failed to set up conference call": "Не удалось настроить групповой вызов", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес электронной почты: убедитесь что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", - "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s изменил %(fromPowerLevel)s на %(toPowerLevel)s", - "Guest users can't create new rooms. Please register to create room and start a chat.": "Гостевые пользователи не могут создавать новые комнаты. Зарегистрируйтесь для создания комнаты и чата.", - "click to reveal": "нажать для открытия", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s до %(toPowerLevel)s", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Гости не могут создавать новые комнаты. Зарегистрируйтесь, чтобы создать комнату и начать чат.", + "click to reveal": "нажмите для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", - "%(displayName)s is typing": "%(displayName)s вводит текст", - "%(targetName)s joined the room.": "%(targetName)s вошёл в комнату.", + "%(displayName)s is typing": "%(displayName)s печатает", + "%(targetName)s joined the room.": "%(targetName)s вошел в комнату.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s выкинул %(targetName)s.", "%(targetName)s left the room.": "%(targetName)s покинул комнату.", - "%(senderName)s made future room history visible to": "%(senderName)s сделал видимой для всех будущую историю комнаты", + "%(senderName)s made future room history visible to": "%(senderName)s сделал будущую историю комнаты видимой", "Missing room_id in request": "Отсутствует room_id в запросе", "Missing user_id in request": "Отсутствует user_id в запросе", - "Must be viewing a room": "Посмотреть комнату", - "New Composer & Autocomplete": "Новый автор & Автозаполнение", - "(not supported by this browser)": "(не поддерживаемый этим браузером)", + "Must be viewing a room": "Необходимо посмотреть комнату", + "New Composer & Autocomplete": "Новый текстовый редактор и автозаполнение", + "(not supported by this browser)": "(не поддерживается этим браузером)", "af": "Африкаанс", - "ar-ae": "Арабский (О.А.Е)", + "ar-ae": "Арабский (ОАЭ)", "ar-bh": "Арабский (Бахрейн)", "ar-dz": "Арабский (Алжир)", "ar-eg": "Арабский (Египет)", @@ -289,20 +289,20 @@ "en-au": "Английский (Австралия)", "en-bz": "Английский (Белиз)", "en-ca": "Английский (Канада)", - "en-gb": "Английский (UK)", + "en-gb": "Английский (Великобритания)", "en-ie": "Английский (Ирландия)", "en-jm": "Английский (Ямайка)", "en-nz": "Английский (Новая Зеландия)", "en-tt": "Английский (Тринидад)", - "en-us": "Английский (US)", + "en-us": "Английский (США)", "en-za": "Английский (Южная Африка)", "es-ar": "Испанский (Аргентина)", "es-bo": "Испанский (Боливия)", "es-cl": "Испанский (Чили)", "es-co": "Испанский (Колумбия)", "es-cr": "Испанский (Коста Рика)", - "es-do": "Испанский (Дом. Республика)", - "es-ec": "Испанский (Еквадор)", + "es-do": "Испанский (Доминиканская Республика)", + "es-ec": "Испанский (Эквадор)", "es-gt": "Испанский (Гватемала)", "es-hn": "Испанский (Гондурас)", "es-mx": "Испанский (Мексика)", @@ -316,37 +316,37 @@ "ja": "Японский", "pl": "Польский", "pt": "Португальский", - "ru-mo": "Русский (Молдавская Республика)", + "ru-mo": "Русский (Республика Молдова)", "ro": "Румынский", "uk": "Украинский", "now. You can also select individual messages to resend or cancel.": "теперь. Вы можете также выбрать отдельные сообщения, чтобы снова послать или отменить.", - "Auto-complete": "Авто-заполнение", + "Auto-complete": "Автозаполнение", "Error changing language": "Ошибка изменения языка", "Riot was unable to find the correct Data for the selected Language.": "Riot был неспособен найти правельные данные для выбранного языка.", - "Connectivity to the server has been lost.": "Связь с сервером была потеряна.", - "Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут храниться, пока Ваше соединение не возобновиться.", - "There are no visible files in this room": "В этой комнате нет никаких видимых файлов", + "Connectivity to the server has been lost.": "Связь с сервером потеряна.", + "Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут сохранены, пока соединение не восстановится.", + "There are no visible files in this room": "В этой комнате нет видимых файлов", "This doesn't look like a valid phone number.": "Это не похоже на допустимый телефонный номер.", - "Missing password.": "Пароль отсутствует.", - "Set a display name:": "Настроить отображаемое имя:", + "Missing password.": "Отсутствует пароль.", + "Set a display name:": "Введите отображаемое имя:", "Passwords don't match.": "Пароли не совпадают.", - "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Пароль слишком короткий (min %(MIN_PASSWORD_LENGTH)s).", - "This doesn't look like a valid email address.": "Это не похоже на допустимый email адрес.", - "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию с телефонным номером.", - "User names may only contain letters, numbers, dots, hyphens and underscores.": "Имена пользователей могут только содержать буквы, числа, точки, дефисы и подчеркивания.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Пароль слишком короткий (мин. %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Это не похоже на допустимый адрес электронной почты.", + "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию с помощью номера телефона.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Имена пользователей могут содержать только буквы, цифры, точки, дефисы и символы подчеркивания.", "An unknown error occurred.": "Произошла неизвестная ошибка.", - "I already have an account": "У меня уже есть учетная запись", + "I already have an account": "У меня есть аккаунт", "An error occurred: %(error_string)s": "Произошла ошибка: %(error_string)s", "Topic": "Тема", - "Make this room private": "Сделать эту комнату частной", - "Share message history with new users": "Поделись историей сообщений с новыми учасниками", - "Encrypt room": "Зашифровать комнату", + "Make this room private": "Сделать эту комнату приватной", + "Share message history with new users": "Разрешить доступ к истории сообщений новым пользователям", + "Encrypt room": "Шифрование комнаты", "es-pe": "Испанский (Перу)", "hu": "Венгерский", "nl": "Датский", "no": "Норвежский", "sv": "Шведский", - "th": "Тайландский", + "th": "Тайский", "vi": "Ветнамский", "Monday": "Понедельник", "Tuesday": "Вторник", @@ -358,13 +358,13 @@ "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "Upload an avatar:": "Загрузите аватар:", "You need to be logged in.": "Вы должны быть авторизованы.", - "You need to be able to invite users to do that.": "Вам необходимо пригласить пользователей чтобы сделать это.", - "You cannot place VoIP calls in this browser.": "Вы не можете сделать вызовы VoIP с этим браузером.", - "You are already in a call.": "Связь уже установлена.", + "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", + "You cannot place VoIP calls in this browser.": "VoIP звонки не поддерживаются в этом браузере.", + "You are already in a call.": "Вы уже совершаете вызов.", "You're not in any rooms yet! Press": "Вы еще не находитесь ни в каких комнатах! Нажать", "You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ к %(roomName)s.", - "You cannot place a call with yourself.": "Вы не можете позвонить самим себе.", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отменил %(targetName)s's приглашение.", + "You cannot place a call with yourself.": "Вы не можете сделать вызов самому себе.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал %(targetName)s's приглашение.", "Sep": "Сен.", "Jan": "Янв.", "Feb": "Фев.", @@ -383,20 +383,20 @@ "Tue": "Вт", "Wed": "Ср", "Thu": "Чт", - "Fri": "Пя", + "Fri": "Пт", "Sat": "Сб", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес электронной почты, кажется, не связан с Matrix ID на этом Homeserver.", - "to start a chat with someone": "Начать чат с кем-то", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес электронной почты, кажется, не связан с Matrix ID на этом домашнем сервере.", + "to start a chat with someone": "чтобы начать чат с кем-то", "to tag direct chat": "отметить прямой чат", - "To use it, just wait for autocomplete results to load and tab through them.": "Для его использования просто подождите загрузки результатов авто-заполнения и нажимайте Tab для навигации.", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включил сквозное шифрование (algorithm %(algorithm)s).", - "Unable to restore previous session": "Невозможно восстановить предыдущий сеанс", - "%(senderName)s unbanned %(targetName)s.": "%(senderName)s запрет отменен %(targetName)s.", - "Unable to capture screen": "Невозможно записать снимок экрана", - "Unable to enable Notifications": "Невозможно включить уведомления", - "Upload Failed": "Неудавшаяся загрузка", + "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включено сквозное шифрование (algorithm %(algorithm)s).", + "Unable to restore previous session": "Не удалось восстановить предыдущий сеанс", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s разблокировал %(targetName)s.", + "Unable to capture screen": "Не удается сделать снимок экрана", + "Unable to enable Notifications": "Не удалось включить уведомления", + "Upload Failed": "Сбой при отправке", "Usage": "Использование", - "Use with caution": "Использовать осторожно", + "Use with caution": "Использовать с осторожностью", "VoIP is unsupported": "VoIP не поддерживается", "es-pr": "Испанский (Пуэрто-Рико)", "es-py": "Испанский язык (Парагвай)", @@ -405,7 +405,7 @@ "es-uy": "Испанский (Уругвай)", "es-ve": "Испанский (Венесуэла)", "fa": "Фарси", - "fo": "Фарезский", + "fo": "Фарерский", "fr-be": "Французский (Бельгия)", "fr-ca": "Французский (Канада)", "fr-ch": "Французский (Швейцария)", @@ -415,117 +415,117 @@ "id": "Индонезийский", "is": "Исландский", "ji": "Идиш", - "lt": "Литовкий", + "lt": "Литовский", "lv": "Латвийский", - "ms": "Малайцы", + "ms": "Малазийский", "mt": "Мальтийский", "nl-be": "Голландский (Бельгия)", "rm": "Ретороманский", - "sb": "Вендский", + "sb": "Лужицкий", "sk": "Словацкий", "sl": "Словенский", "sq": "Албанский", "sr": "Сербский", "sv-fi": "Шведский (Финляндия)", - "sz": "Саами (лопарский)", + "sz": "Сами (Саамы)", "tn": "Тсвана", "tr": "Турецкий", "ts": "Тсонга", "ur": "Урду", "ve": "Венда", - "xh": "Коса", - "zh-cn": "Китайский (PRC)", + "xh": "Кхоса", + "zh-cn": "Китайский (КНР)", "zh-sg": "Китайский (Сингапур)", "zh-tw": "Китайский (Тайвань)", "zu": "Зулусский", "eu": "Баскский", "fr-lu": "Французский (Люксембург)", - "gd": "Гэльский (Шотландия)", + "gd": "Гаэльский (Шотландия)", "it-ch": "Итальянский (Швейцария)", "ko": "Корейский", - "mk": "Македонский (FYROM)", + "mk": "Македонский (БЮРМ)", "ro-mo": "Румынский (Республика Молдова)", "sx": "Суту", "zh-hk": "Китайский (Гонконг)", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "На +%(msisdn)s было отправлено текстовое сообщение. Пожалуйста, введите проверочный код из него", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код, который оно содержит", "and %(overflowCount)s others...": "и %(overflowCount)s других...", "Are you sure?": "Вы уверены?", - "Autoplay GIFs and videos": "Проигрывать GIF и видео автоматически", + "Autoplay GIFs and videos": "Автовоспроизведение GIF и видео", "Can't connect to homeserver - please check your connectivity and ensure your homeserver's SSL certificate is trusted.": "Невозможно соединиться с домашним сервером - проверьте своё соединение и убедитесь, что SSL-сертификат вашего домашнего сервера включён в доверяемые.", "changing room on a RoomView is not supported": "изменение комнаты в RoomView не поддерживается", - "Click to mute audio": "Выключить звук", - "Click to mute video": "Выключить звук у видео", - "Click to unmute video": "Включить звук у видео", - "Click to unmute audio": "Включить звук", + "Click to mute audio": "Щелкните, чтобы выключить звук", + "Click to mute video": "Щелкните, чтобы выключить видео", + "Click to unmute video": "Щелкните, чтобы включить видео", + "Click to unmute audio": "Щелкните, чтобы включить звук", "Decrypt %(text)s": "Расшифровать %(text)s", "Delete": "Удалить", "Devices": "Устройства", - "Direct chats": "Личные чаты", + "Direct chats": "Прямые чаты", "Disinvite": "Отозвать приглашение", "Don't send typing notifications": "Не оповещать, когда я печатаю", "Download %(text)s": "Загрузить %(text)s", "Enable encryption": "Включить шифрование", "Enter Code": "Ввести код", - "Failed to ban user": "Не удалось забанить пользователя", + "Failed to ban user": "Не удалось заблокировать пользователя", "Failed to change power level": "Не удалось изменить уровень привилегий", "Failed to delete device": "Не удалось удалить устройство", "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", - "Failed to join room": "Не удалось присоединиться к комнате", - "Failed to join the room": "Не удалось войти в комнату", + "Failed to join room": "Не удалось войти в комнату", + "Failed to join the room": "Не удалось войти в эту комнату", "Access Token:": "Токен:", - "Always show message timestamps": "Всегда показывать время сообщения", + "Always show message timestamps": "Всегда показывать временные метки сообщений", "Authentication": "Авторизация", "olm version:": "Версия olm:", "%(items)s and %(remaining)s others": "%(items)s и другие %(remaining)s", - "%(items)s and one other": "%(items)s и ещё один", + "%(items)s and one other": "%(items)s и еще один", "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", - "and one other...": "и ещё один...", + "and one other...": "и еще один...", "An error has occurred.": "Произошла ошибка.", "Attachment": "Вложение", "Ban": "Запретить", "Change Password": "Сменить пароль", "Command error": "Ошибка команды", - "Confirm password": "Подтвердить пароль", + "Confirm password": "Подтвердите пароль", "Current password": "Текущий пароль", "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", - "Failed to load timeline position": "Не удалось загрузить позицию графика", - "Failed to mute user": "Не удалось заглушить", + "Failed to load timeline position": "Не удалось загрузить хронологию", + "Failed to mute user": "Не удалось заглушить пользователя", "Failed to reject invite": "Не удалось отклонить приглашение", "Failed to save settings": "Не удалось сохранить настройки", - "Failed to set display name": "Не удалось установить отображаемое имя", + "Failed to set display name": "Не удалось задать отображаемое имя", "Failed to toggle moderator status": "Не удалось изменить статус модератора", "Fill screen": "Заполнить экран", - "Guest users can't upload files. Please register to upload.": "Гости не могут посылать файлы. Пожалуйста, зарегистрируйтесь для отправки.", + "Guest users can't upload files. Please register to upload.": "Гости не могут посылать файлы. Зарегистрируйтесь для отправки.", "Hide read receipts": "Скрыть отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", "Incorrect verification code": "Неверный код подтверждения", "Interface Language": "Язык интерфейса", - "Invalid alias format": "Неверный формат привязки", - "Invalid address format": "Неверный формат адреса", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' неверный формат для адреса", - "'%(alias)s' is not a valid format for an alias": "'%(alias)s' неверный формат для привязки", + "Invalid alias format": "Недопустимый формат псевдонима", + "Invalid address format": "Недопустимый формат адреса", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' недопустимый формат адреса", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' недопустимый формат псевдонима", "Join Room": "Войти в комнату", "Kick": "Выгнать", "Level": "Уровень", - "Local addresses for this room:": "Местный адрес этой комнаты:", + "Local addresses for this room:": "Локальный адрес этой комнаты:", "Markdown is disabled": "Markdown отключен", "Markdown is enabled": "Markdown включен", "matrix-react-sdk version:": "версия matrix-react-sdk:", - "Never send encrypted messages to unverified devices in this room": "Никогда не отправлять зашифрованные сообщения непроверенным устройствам в этой комнате", + "Never send encrypted messages to unverified devices in this room": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства в этой комнате", "New address (e.g. #foo:%(localDomain)s)": "Новый адрес (например, #foo:%(localDomain)s)", - "New passwords don't match": "Пароли не совпадают", - "not set": "не установлено", - "not specified": "не указано", + "New passwords don't match": "Новые пароли не совпадают", + "not set": "не задано", + "not specified": "не определено", "No devices with registered encryption keys": "Нет устройств с зарегистрированными ключами шифрования", - "No more results": "Нет больше результатов", + "No more results": "Больше никаких результатов", "No results": "Нет результатов", - "OK": "ОК", - "Only people who have been invited": "Только приглашённые люди", - "Passwords can't be empty": "Поля паролей не могут быть пустыми", + "OK": "OK", + "Only people who have been invited": "Только приглашенные люди", + "Passwords can't be empty": "Пароли не могут быть пустыми", "%(senderName)s placed a %(callType)s call.": "%(senderName)s выполнил %(callType)s вызов.", - "Please check your email and click on the link it contains. Once this is done, click continue.": "Пожалуйста, проверьте вашу электронную почту и нажмите в ней ссылку. По завершении нажмите продолжить.", - "Power level must be positive integer.": "Уровень силы должен быть положительным числом.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверьте свою электронную почту и нажмите на содержащуюся ссылку. После этого нажмите кнопку Продолжить.", + "Power level must be positive integer.": "Уровень авторизации должен быть положительным целым числом.", "Press": "Нажать", "Profile": "Профиль", "Reason": "Причина", @@ -533,22 +533,22 @@ "%(targetName)s rejected the invitation.": "%(targetName)s отклонил приглашение.", "Reject invitation": "Отклонить приглашение", "Remove Contact Information?": "Удалить контактную информацию?", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s убрал своё отображаемое имя (%(oldDisplayName)s).", - "%(senderName)s removed their profile picture.": "%(senderName)s убрал своё изображение.", - "%(senderName)s requested a VoIP conference.": "%(senderName)s запросил голосовую конференц-связь.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", "Report it": "Сообщить об этом", - "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "На данный момент сброс пароля сбросит все ключи шифрования на всех устройствах, зашифрованная история общения будет не читаема, если вы сперва не скачаете ваши ключи от комнаты и не загрузите их после. В будущем это будет улучшено.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованный историю чатов нечитаемой. Вы можете избежать этого экспортировав ключи комнаты и затем повторно их импортировав в настройках. В будущем это будет улучшено.", "restore": "восстановить", "Return to app": "Вернуться в приложение", - "Riot does not have permission to send you notifications - please check your browser settings": "Riot не имеет права для отправки вам уведомлений, пожалуйста, проверьте настройки вашего браузера", - "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение для отправки уведомлений, пожалуйста, попробуйте снова", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot не имеет разрешение на отправку уведомлений, проверьте параметры своего браузера", + "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", "riot-web version:": "версия riot-web:", "Room %(roomId)s not visible": "Комната %(roomId)s невидима", "Room Colour": "Цвет комнаты", "Room name (optional)": "Имя комнаты (необязательно)", "Rooms": "Комнаты", - "Scroll to bottom of page": "Прокрутить вниз страницы", - "Scroll to unread messages": "Прокрутить к непрочитанным сообщениям", + "Scroll to bottom of page": "Перейти к нижней части страницы", + "Scroll to unread messages": "Прокрутка к непрочитанным сообщениям", "Search": "Поиск", "Search failed": "Поиск не удался", "Send a message (unencrypted)": "Отправить сообщение (не зашифровано)", @@ -564,50 +564,50 @@ "since the point in time of selecting this option": "с момента выбора этой настройки", "since they joined": "с момента входа", "since they were invited": "с момента приглашения", - "Some of your messages have not been sent.": "Некоторые из ваших сообщений не были отправлены.", + "Some of your messages have not been sent.": "Некоторые сообщения не были отправлены.", "Someone": "Кто-то", "Submit": "Отправить", "Success": "Успех", - "tag as %(tagName)s": "отметить как %(tagName)s", - "tag direct chat": "отметить прямое общение", + "tag as %(tagName)s": "пометить как %(tagName)s", + "tag direct chat": "Тег прямого чата", "The default role for new room members is": "Роль по умолчанию для новых участников комнаты", "The main address for this room is": "Основной адрес для этой комнаты", - "This action cannot be performed by a guest user. Please register to be able to do this.": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь для этого.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь, чтобы получить возможность сделать то что вы хотите.", "This email address is already in use": "Этот адрес электронной почты уже используется", "This email address was not found": "Этот адрес электронной почты не найден", - "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учётной записью.", + "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось загрузить файл '%(fileName)s'", - "The remote side failed to pick up": "Удалённая сторона не смогла ответить", - "This room has no local addresses": "Эта комната не имеет местного адреса", + "The remote side failed to pick up": "Вызываемый абонент не ответил", + "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", - "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут неожиданным образом вызывать ошибки", - "This doesn't appear to be a valid email address": "Не похоже, что это правильный адрес электронной почты", - "This is a preview of this room. Room interactions have been disabled": "Это просмотр данной комнаты. Взаимодействия с ней были отключены", - "This phone number is already in use": "Этот телефонный номер уже используется", + "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", + "This doesn't appear to be a valid email address": "Похоже это недействительный адрес электронной почты", + "This is a preview of this room. Room interactions have been disabled": "Это предварительный просмотр комнаты. Взаимодействие с комнатой отключено", + "This phone number is already in use": "Этот номер телефона уже используется", "This room's internal ID is": "Внутренний ID этой комнаты", "times": "раз", - "to demote": "для понижения", + "to demote": "для понижения уровня доступа", "to favourite": "для избранного", "to restore": "восстановить", "Turn Markdown off": "Выключить Markdown", "Turn Markdown on": "Включить Markdown", "Unknown command": "Неизвестная команда", "Unknown room %(roomId)s": "Неизвестная комната %(roomId)s", - "You have been invited to join this room by %(inviterName)s": "Вы были приглашены войти в эту комнату от %(inviterName)s", - "You seem to be uploading files, are you sure you want to quit?": "Похоже вы передаёте файлы, вы уверены, что хотите выйти?", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в комнату", + "You seem to be uploading files, are you sure you want to quit?": "Похоже вы отправляете файлы, вы уверены, что хотите выйти?", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", "Make Moderator": "Сделать модератором", "Room": "Комната", "Cancel": "Отмена", "bold": "жирный", - "italic": "наклонный", - "strike": "перечёркнутый", - "underline": "подчёркнутый", + "italic": "курсивный", + "strike": "перечеркнутый", + "underline": "подчеркнутый", "code": "код", "quote": "цитата", - "bullet": "пункт", - "numbullet": "нумерация", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sвошли %(repeats)s раз", + "bullet": "список", + "numbullet": "нумерованный список", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s вошли %(repeats)s раз", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sвошёл %(repeats)s раз", "%(severalUsers)sjoined": "%(severalUsers)sвошли", "%(oneUser)sjoined": "%(oneUser)sвошёл", @@ -647,16 +647,16 @@ "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sизменил своё изображение %(repeats)s раз", "%(severalUsers)schanged their avatar": "%(severalUsers)sизменили своё изображение", "%(oneUser)schanged their avatar": "%(oneUser)sизменил своё изображение", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не возможно подключиться к серверу через HTTP, когда в строке браузера HTTPS. Используйте HTTPS или включив небезопасные скрипты.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отказ", "Custom Server Options": "Собственные настройки сервера", "Mute": "Беззвучный", - "Operation failed": "Действие не удалось", + "Operation failed": "Не удалось выполнить операцию", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", - "Show timestamps in 12 hour format (e.g. 2:30pm)": "Время отображать в 12 часовом формате (напр. 2:30pm)", - "Use compact timeline layout": "Компактное отображение", - "Hide removed messages": "Скрыть удаленное сообщение", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30pm)", + "Use compact timeline layout": "Использовать компактный макет временной шкалы", + "Hide removed messages": "Скрыть удаленные сообщения", "No Microphones detected": "Микрофоны не обнаружены", "Unknown devices": "Незнакомое устройство", "Camera": "Камера", @@ -666,56 +666,56 @@ "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, чтобы улучшить эту программу.", "Opt out of analytics": "Подтвердить отказ передачи аналитических данных", - "Logged in as:": "Зарегистрирован как:", - "Default Device": "Стандартное устройство", + "Logged in as:": "Вы вошли как:", + "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", "VoIP": "VoIP", - "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Для обеспечения безопасности выход из системы удалит все ключи шифрования из этого браузера. Если вы хотите иметь возможность расшифровать переписку в будущем - вы должны экспортировать ключи вручную.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Для обеспечения безопасности при выходе из этого браузера удалятся все ключи шифрования. Если вы хотите иметь возможность расшифровать переписку в будущем, необходимо экспортировать ключи вручную.", "Guest access is disabled on this Home Server.": "Гостевой доступ отключен на этом сервере.", - "Guests can't set avatars. Please register.": "Гости не могут устанавливать аватар. Пожалуйста, зарегистрируйтесь.", + "Guests can't set avatars. Please register.": "Гости не могут устанавливать аватары. Пожалуйста, зарегистрируйтесь.", "Guests can't use labs features. Please register.": "Гости не могут использовать экспериментальные возможности. Пожалуйста, зарегистрируйтесь.", - "Guests cannot join this room even if explicitly invited.": "Гости не могут заходить в эту комнату если не были приглашены.", + "Guests cannot join this room even if explicitly invited.": "Гости не могут присоединиться к этой комнате, даже если они приглашены.", "Missing Media Permissions, click here to request.": "Отсутствуют разрешения, нажмите для запроса.", - "No media permissions": "Нет разрешённых носителей", + "No media permissions": "Нет разрешенных носителей", "You may need to manually permit Riot to access your microphone/webcam": "Вам необходимо предоставить Riot доступ к микрофону или веб-камере вручную", "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил имя комнаты.", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля также сбросит все ключи шифрования на всех устройствах, сделав зашифрованную историю недоступной, если только вы сначала не экспортируете ключи шифрования и не импортируете их потом. В будущем это будет исправлено.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля также сбросит ключи шифрования на всех устройствах, сделав зашифрованную историю чата недоступной. Чтобы этого не произошло, экспортируйте ключи шифрования и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже верифицировано!", "Device ID:": "ID устройства:", "device id: ": "ID устройства: ", "Device key:": "Ключ устройства:", "disabled": "отключено", - "Disable markdown formatting": "Отключить форматирование Markdown", - "Email address": "Адрес email", - "Email address (optional)": "Адрес email (не обязательно)", + "Disable markdown formatting": "Отключить Markdown-форматирование", + "Email address": "Адрес электронной почты", + "Email address (optional)": "Адрес электронной почты (необязательно)", "enabled": "включено", - "Error decrypting attachment": "Ошибка расшифровки файла", + "Error decrypting attachment": "Ошибка при расшифровке вложения", "Export": "Экспорт", - "Failed to register as guest:": "Ошибка регистрации как гостя:", + "Failed to register as guest:": "Не удалось зарегистрироваться в качестве гостя:", "Failed to set avatar.": "Не удалось установить аватар.", "Import": "Импорт", "Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.", - "Invalid file%(extra)s": "Неправильный файл%(extra)s", - "Invited": "Приглашён", + "Invalid file%(extra)s": "Недопустимый файл%(extra)s", + "Invited": "Приглашен", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", "List this room in %(domain)s's room directory?": "Показывать эту комнату в списке комнат %(domain)s?", - "Message not sent due to unknown devices being present": "Сообщение не было отправлено из-за присутствия неизвестного устройства", + "Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств", "Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)", - "Once you've followed the link it contains, click below": "Как только вы пройдете по ссылке, нажмите на кнопку ниже", + "Once you've followed the link it contains, click below": "После перехода по ссылке, нажмите на кнопку ниже", "Password:": "Пароль:", - "Privacy warning": "Предупреждение приватности", + "Privacy warning": "Предупреждение о конфиденциальности", "Privileged Users": "Привилегированные пользователи", - "Revoke Moderator": "Снять права Модератора", + "Revoke Moderator": "Отозвать права модератора", "Refer a friend to Riot:": "Расскажите другу о Riot:", "Register": "Регистрация", "Remote addresses for this room:": "Удаленные адреса для этой комнаты:", "Remove %(threePid)s?": "Удалить %(threePid)s?", "Results from DuckDuckGo": "Результаты от DuckDuckGo", "Save": "Сохранить", - "Searches DuckDuckGo for results": "Ищет результаты через DuckDuckGo", + "Searches DuckDuckGo for results": "Для поиска используется DuckDuckGo", "Server error": "Ошибка сервера", "Server may be unavailable or overloaded": "Сервер может быть недоступен или перегружен", "Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(", @@ -724,46 +724,46 @@ "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", "Session ID": "ID сессии", "%(senderName)s set a profile picture.": "%(senderName)s установил картинку профиля.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s установил отображаемое имя %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил отображаемое имя на %(displayName)s.", "Signed Out": "Вышли", - "Sorry, this homeserver is using a login which is not recognised ": "Извините, этот Home Server использует логин, который не удалось распознать ", + "Sorry, this homeserver is using a login which is not recognised ": "К сожалению, этот домашний сервер использует неизвестный метод авторизации ", "Tagged as: ": "Теги: ", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Ключ, предоставленный вами, совпадает с ключем, полученным от устройства %(userId)s с ID %(deviceId)s. Устройство помечено как верифицированное.", - "%(actionVerb)s this person?": "%(actionVerb)s этого пользователя?", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает ограничение размера загрузок на этом Home Server'е", - "This Home Server does not support login using email address.": "Этот Home Server не поддерживает вход по адресу email.", - "There was a problem logging in.": "Возникла проблема входа в учетную запись.", - "The visibility of existing history will be unchanged": "Видимость текущей истории не будет изменена", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ соответствует ключу подписи, полученному от %(userId)s с ID %(deviceId)s. Устройство помечено как проверенное.", + "%(actionVerb)s this person?": "%(actionVerb)s этот человек?", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер для этого домашнего сервера для загрузки", + "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса электронной почты.", + "There was a problem logging in.": "Возникла проблема при авторизации.", + "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "this invitation?": "это приглашение?", - "This room is not accessible by remote Matrix servers": "Это комната закрыта для других серверов Matrix", - "To ban users": "Забанить пользователей", - "to browse the directory": "просматривать директорию", - "To configure the room": "Настроить комнату", - "To invite users into the room": "Приглашать пользователей в комнату", + "This room is not accessible by remote Matrix servers": "Это комната недоступна с удаленных серверов Matrix", + "To ban users": "Для блокировки пользователей", + "to browse the directory": "для просмотра каталога", + "To configure the room": "для настройки комнаты", + "To invite users into the room": "Чтобы приглашать пользователей в комнату", "to join the discussion": "присоединиться к дискуссии", - "To kick users": "Выгонять пользователей", + "To kick users": "Чтобы удалять пользователей", "To link to a room it must have": "Для создания ссылки на комнату она должна иметь", - "to make a room or": "создать комнату или", - "To remove other users' messages": "Удалять сообщения других пользователей", - "To reset your password, enter the email address linked to your account": "Чтобы сбросить ваш пароль введите адрес email, который используется аккаунтом", - "to tag as %(tagName)s": "отметить как %(tagName)s", - "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Ошибка загрузки истории комнаты: недостаточно прав.", - "Tried to load a specific point in this room's timeline, but was unable to find it.": "Ошибка загрузки истории комнаты: запрошенный элемент не найден.", - "Unable to load device list": "Невозможно загрузить список устройств", - "Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:", - "Unmute": "Вкл. звук", - "Unrecognised command:": "Неизвестная команда:", - "Unrecognised room alias:": "Неизвестный псевдоним комнаты:", - "Verified key": "Верифицированный ключ", + "to make a room or": "чтобы создать комнату или", + "To remove other users' messages": "Чтобы удалить сообщения других пользователей", + "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес электронной почты, связанный с вашей учетной записью", + "to tag as %(tagName)s": "пометить как %(tagName)s", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", + "Unable to load device list": "Не удалось загрузить список устройств", + "Unknown (user, device) pair:": "Неизвестная пара (пользователь, устройство):", + "Unmute": "Включить звук", + "Unrecognised command:": "Нераспознанная команда:", + "Unrecognised room alias:": "Нераспознанный псевдоним комнаты:", + "Verified key": "Проверенный ключ", "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было верифицировано, однако ключи НЕ СОВПАДАЮТ!", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ВЕРИФИКАЦИИ КЛЮЧЕЙ! Ключ для подписки устройства %(deviceId)s пользователя %(userId)s: \"%(fprint)s\", однако он не совпадает с предоставленным ключем \"%(fingerprint)s\". Это может означать перехват вашего канала коммуникации!", - "You have disabled URL previews by default.": "Предпросмотр ссылок отключен по-умолчанию.", - "You have enabled URL previews by default.": "Предпросмотр ссылок включен по-умолчанию.", - "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели неправильный адрес. Попробуйте использовать Matrix ID или адрес email.", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ВЕРИФИКАЦИИ КЛЮЧЕЙ! Ключ подписи для пользователя %(userId)s и устройства %(deviceId)s - \"%(fprint)s\" не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваши сообщения перехватываются!", + "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", + "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес электронной почты.", "You need to enter a user name.": "Необходимо ввести имя пользователя.", "You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?", - "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это действие, так как даете пользователю такой же уровень доступа, как и у вас.", - "Set a Display Name": "Установить отображаемое имя", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.", + "Set a Display Name": "Указать отображаемое имя", "(~%(searchCount)s results)": "(~%(searchCount)s результатов)", "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)s отозвали свои приглашения %(repeats)s раз", "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s отозвал свои приглашения %(repeats)s раз", @@ -774,7 +774,7 @@ "Passphrases must match": "Пароли должны совпадать", "Passphrase must not be empty": "Пароль не должен быть пустым", "Export room keys": "Экспортировать ключи", - "Enter passphrase": "Введите пароль", + "Enter passphrase": "Введите парольную фразу", "Confirm passphrase": "Подтвердите пароль", "Import room keys": "Импортировать ключи", "File to import": "Файл для импорта", @@ -867,22 +867,22 @@ "Add": "Добавить", "%(count)s new messages.one": "%(count)s новое сообщение", "%(count)s new messages.other": "%(count)s новых сообщений", - "Error: Problem communicating with the given homeserver.": "Ошибка: проблема связи с указанным сервером.", - "Failed to fetch avatar URL": "Ошибка получения аватара", - "The phone number entered looks invalid": "Введенный номер телефона выглядит неправильным", - "Uploading %(filename)s and %(count)s others.zero": "Загрузка %(filename)s", - "Uploading %(filename)s and %(count)s others.one": "Загрузка %(filename)s и %(count)s другой файл", - "Uploading %(filename)s and %(count)s others.other": "Загрузка %(filename)s и %(count)s других файлов", + "Error: Problem communicating with the given homeserver.": "Ошибка: проблема связи с данным сервером.", + "Failed to fetch avatar URL": "Не удалось извлечь URL-адрес аватара", + "The phone number entered looks invalid": "Введенный номер телефона недействителен", + "Uploading %(filename)s and %(count)s others.zero": "Отправка %(filename)s", + "Uploading %(filename)s and %(count)s others.one": "Отправка %(filename)s и %(count)s другой", + "Uploading %(filename)s and %(count)s others.other": "Отправка %(filename)s и %(count)s других", "Username invalid: %(errMessage)s": "Неверное имя пользователя: %(errMessage)s", - "Searching known users": "Искать известных пользователей", - "You must register to use this functionality": "Вы должны зарегистрироваться для использования этой функции", - "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Отослать снова или отменить отправку. Вы также можете выбрать на отправку или отмену отдельные сообщения.", + "Searching known users": "Поиск известных пользователей", + "You must register to use this functionality": "Вы должны зарегистрироваться, чтобы использовать эту функцию", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Отправить все или отменить отправку. Также можно выбрать отдельные сообщения для повторной отправки или отмены.", "New Password": "Новый пароль", "Start chatting": "Начать общение", "Start Chatting": "Начать общение", "Click on the button below to start chatting!": "Нажмите на кнопку ниже для того, чтобы начать общение!", - "Create a new chat or reuse an existing one": "Создать новый чат или использовать уже существующий", - "You already have existing direct chats with this user:": "У вас уже есть существующие приватные чаты с этим пользователем:", + "Create a new chat or reuse an existing one": "Создайте новый чат или используйте существующий", + "You already have existing direct chats with this user:": "У вас уже есть прямые чаты с этим пользователем:", "Username available": "Имя пользователя доступно", "Username not available": "Имя пользователя недоступно", "Something went wrong!": "Что-то пошло не так!", @@ -892,64 +892,64 @@ "a room": "комната", "Accept": "Принять", "Active call (%(roomName)s)": "Активный вызов (%(roomName)s)", - "Admin tools": "Админ утилита", + "Admin tools": "Инструменты администратора", "And %(count)s more...": "И %(count)s больше...", "Alias (optional)": "Псевдоним (опционально)", "Click here to join the discussion!": "Нажмите здесь, чтобы присоединиться к обсуждению!", "Close": "Закрыть", - "Disable Notifications": "Отключить оповещение", - "Drop File Here": "Вставить сюда файл", - "Enable Notifications": "Включить оповещение", - "Encrypted by a verified device": "Шифрование с помощью проверенных устройств", - "Encrypted by an unverified device": "Шифрование с помощью не проверенных устройств", + "Disable Notifications": "Отключить уведомления", + "Drop File Here": "Перетащите файл сюда", + "Enable Notifications": "Включить оповещения", + "Encrypted by a verified device": "Зашифровано проверенным устройством", + "Encrypted by an unverified device": "Зашифровано непроверенным устройством", "Encryption is enabled in this room": "Шифрование в этой комнате включено", "Encryption is not enabled in this room": "Шифрование в этой комнате не включено", - "Failed to upload profile picture!": "Не удалось загрузить фото профиля!", + "Failed to upload profile picture!": "Не удалось выгрузить фотографию профиля!", "Incoming call from %(name)s": "Входящий вызов от %(name)s", - "Incoming video call from %(name)s": "Входящий видио вызов от %(name)s", + "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", "Join as voice or video.": "Войти как голос или видео.", - "Last seen": "В последний раз видели", + "Last seen": "Последний визит", "Level:": "Уровень:", - "No display name": "Нет отображаемое имя", - "Otherwise, click here to send a bug report.": "Иначе , нажать 2 чтоб отослать отчет о ошибке.", - "Private Chat": "Частный чат", - "Public Chat": "Общественный чат", + "No display name": "Нет отображаемого имени", + "Otherwise, click here to send a bug report.": "В противном случае, нажмите 2 для отправки отчета об ошибке.", + "Private Chat": "Приватный чат", + "Public Chat": "Публичный чат", "Reason: %(reasonText)s": "Причина: %(reasonText)s", - "Rejoin": "Пере-соединиться", - "Set": "Вводить", - "Start authentication": "Начать идентификацию", - "This room": "Эта комната", - "(~%(count)s results).other": "(~%(count) найдено)", + "Rejoin": "Войти повторно", + "Set": "Установить", + "Start authentication": "Начать проверку подлинности", + "This room": "В этой комнате", + "(~%(count)s results).other": "(~%(count)s результаты)", "Device Name": "Имя устройства", - "Custom": "Пользователь", + "Custom": "Пользовательские", "Decline": "Отклонить", - "Room contains unknown devices": "Комната содержит неизвестное устройство", + "Room contains unknown devices": "Комната содержит непроверенные устройства", "%(roomName)s does not exist.": "%(roomName)s не существует.", - "%(roomName)s is not accessible at this time.": "%(roomName)s в данный момент не доступна.", - "Seen by %(userName)s at %(dateTime)s": "Отослать от %(userName)s в %(dateTime)s", + "%(roomName)s is not accessible at this time.": "%(roomName)s на данный момент недоступна.", + "Seen by %(userName)s at %(dateTime)s": "Видели %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", - "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес электронной почты, который не связан с этой учетной записью:", - "To link to a room it must have an address.": "Для ссылки на комнату необходим адрес.", - "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить, что адрес на который было отправлено это приглашение соответствует вашей учетной записи.", + "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес электронной почты, не связанный с этой учетной записью:", + "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", - "Unencrypted message": "Незашифрованое послание", - "unknown caller": "Звонящий неизвестен", + "Unencrypted message": "Незашифрованное сообщение", + "unknown caller": "неизвестный абонент", "Unnamed Room": "Комната без имени", - "Unverified": "Непроверенно", - "Upload new:": "Загрузить новый:", + "Unverified": "Не проверено", + "Upload new:": "Отправить новый:", "%(user)s is a": "%(user)s является", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", - "Verified": "Подтверждён", - "Would you like to accept or decline this invitation?": "Хотели бы вы подтвердить это приглашение или отклонить?", - "(~%(count)s results).one": "(~%(count)s Результат)", - "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш сертификат SSL homeserver's SSL certificate действителен, и расширение браузера не блокирует запросы.", - "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s забанил Вас в %(roomName)s.", - "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал Вас из %(roomName)s.", - "You may wish to login with a different account, or add this email to this account.": "Вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", + "Verified": "Подтвержден", + "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", + "(~%(count)s results).one": "(~%(count)s результат)", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш SSL-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", + "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес электронной почты в эту учетную запись.", "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", - "(could not connect media)": "(не удается подключиться к медиа)", + "(could not connect media)": "(подключение к СМИ не может быть установлено)", "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", @@ -958,8 +958,8 @@ "Authentication check failed: incorrect password?": "Ошибка авторизации: неверный пароль?", "Do you want to set an email address?": "Вы хотите указать адрес электронной почты?", "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления.", - "Press to start a chat with someone": "Нажмите для начала чата с кем либо", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или , чтобы просмотреть каталог", + "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или для просмотра каталога", "To return to your account in future you need to set a password": "Чтобы в будущем к этой учётной записи вернутся, вы должны ввести пароль", "Skip": "Пропуск", "Start verification": "Запуск проверки", From 3b527bc2c768f0f3900d889324b7c54eb5bed50d Mon Sep 17 00:00:00 2001 From: Tom Tryfonidis Date: Tue, 27 Jun 2017 07:50:40 +0000 Subject: [PATCH 010/164] Translated using Weblate (Greek) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/el/ --- src/i18n/strings/el.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index f776d50ee3..9cf7fa8781 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -923,5 +923,7 @@ "Ignore request": "Παράβλεψη αιτήματος", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Έχετε προσθέσει μια νέα συσκευή '%(displayName)s', η οποία ζητά κλειδιά κρυπτογράφησης.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Η ανεπιβεβαίωτη συσκευή σας '%(displayName)s' ζητά κλειδιά κρυπτογράφησης.", - "Encryption key request": "Αίτημα κλειδιού κρυπτογράφησης" + "Encryption key request": "Αίτημα κλειδιού κρυπτογράφησης", + "Updates": "Ενημερώσεις", + "Check for update": "Έλεγχος για ενημέρωση" } From 37f920d0b98c85bc6d3943fe64d88ebe1506f312 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 26 Jun 2017 19:33:17 +0000 Subject: [PATCH 011/164] Translated using Weblate (German) Currently translated at 99.8% (915 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index aa1edeffb8..b9f30877c8 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -654,7 +654,7 @@ "%(oneUser)sjoined %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal betreten", "%(severalUsers)sjoined": "%(severalUsers)shaben den Raum betreten", "%(oneUser)sjoined": "%(oneUser)shat den Raum betreten", - "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)shaben %(repeats)s mal den Raum verlassen", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)shaben %(repeats)s-mal den Raum verlassen", "%(oneUser)sleft %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal verlassen", "%(severalUsers)sleft": "%(severalUsers)shaben den Raum verlassen", "%(oneUser)sleft": "%(oneUser)shat den Raum verlassen", From 7245ca88a4691e2a3ecb4f46930422bb0e21c8e9 Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 27 Jun 2017 16:23:16 +0000 Subject: [PATCH 012/164] Translated using Weblate (German) Currently translated at 99.8% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index b9f30877c8..cd4ce1ac6c 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -650,7 +650,7 @@ "%(items)s and %(remaining)s others": "%(items)s und %(remaining)s weitere", "%(items)s and one other": "%(items)s und ein(e) weitere(r)", "%(items)s and %(lastItem)s": "%(items)s und %(lastItem)s", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)ssind dem Raum %(repeats)s mal beigetreten", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s sind dem Raum %(repeats)s mal beigetreten", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal betreten", "%(severalUsers)sjoined": "%(severalUsers)shaben den Raum betreten", "%(oneUser)sjoined": "%(oneUser)shat den Raum betreten", From 2ef97e16896583b92831c537284b1154e7b52bc6 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 1 Jul 2017 18:55:03 +0000 Subject: [PATCH 013/164] Translated using Weblate (Hungarian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 92cc8b66ff..7c91079e72 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -913,5 +913,7 @@ "Ignore request": "Kérés figyelmen kívül hagyása", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Hozzáadtál egy új eszközt '%(displayName)s', ami titkosítási kulcsokat kér.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Az ellenőrizetlen eszközöd '%(displayName)s' titkosítási kulcsokat kér.", - "Encryption key request": "Titkosítási kulcs kérés" + "Encryption key request": "Titkosítási kulcs kérés", + "Updates": "Frissítések", + "Check for update": "Frissítések keresése" } From 16c33c0c53d4d48be6b32fff82e5a847b3b24c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B4=A8=E0=B4=BF=E0=B4=A6=E0=B4=B0=E0=B5=8D=E2=80=8D?= =?UTF-8?q?=E0=B4=B6=E0=B5=8D?= Date: Mon, 3 Jul 2017 15:41:01 +0000 Subject: [PATCH 014/164] Translated using Weblate (Malayalam) Currently translated at 3.6% (33 of 915 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ml/ --- src/i18n/strings/ml.json | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 2c63c08510..1612115f2b 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -1,2 +1,35 @@ { + "Cancel": "റദ്ദാക്കുക", + "Close": "അടയ്ക്കുക", + "Create new room": "പുതിയ റൂം സൃഷ്ടിക്കുക", + "Custom Server Options": "കസ്റ്റം സെര്‍വര്‍ ഓപ്ഷനുകള്‍", + "Direct Chat": "നേരിട്ടുള്ള ചാറ്റ്", + "Dismiss": "ഒഴിവാക്കുക", + "Drop here %(toAction)s": "ഇവിടെ നിക്ഷേപിക്കുക %(toAction)", + "Error": "എറര്‍", + "Failed to forget room %(errCode)s": "%(errCode) റൂം ഫോര്‍ഗെറ്റ് ചെയ്യുവാന്‍ സാധിച്ചില്ല", + "Failed to join the room": "റൂമില്‍ അംഗമാകുവാന്‍ സാധിച്ചില്ല", + "Favourite": "പ്രിയപ്പെട്ടവ", + "Mute": "നിശ്ശബ്ദം", + "Notifications": "നോട്ടിഫിക്കേഷനുകള്‍", + "Operation failed": "ശ്രമം പരാജയപ്പെട്ടു", + "Please Register": "ദയവായി രെജിസ്റ്റര്‍ ചെയ്യുക", + "powered by Matrix": "മാട്രിക്സില്‍ പ്രവര്‍ത്തിക്കുന്നു", + "Remove": "നീക്കം ചെയ്യുക", + "Room directory": "റൂം ഡയറക്ടറി", + "Search": "തിരയുക", + "Settings": "സജ്ജീകരണങ്ങള്‍", + "Start chat": "ചാറ്റ് തുടങ്ങുക", + "unknown error code": "അപരിചിത എറര്‍ കോഡ്", + "Sunday": "ഞായര്‍", + "Monday": "തിങ്കള്‍", + "Tuesday": "ചൊവ്വ", + "Wednesday": "ബുധന്‍", + "Thursday": "വ്യാഴം", + "Friday": "വെള്ളി", + "Saturday": "ശനി", + "OK": "ശരി", + "Welcome page": "സ്വാഗതം", + "Failed to change password. Is your password correct?": "രഹസ്യവാക്ക് മാറ്റാന്‍ സാധിച്ചില്ല. രഹസ്യവാക്ക് ശരിയാണോ ?", + "Continue": "മുന്നോട്ട്" } From b414db06e03f1b716fefe4d77a5ec0f0ca04e6bf Mon Sep 17 00:00:00 2001 From: Bamstam Date: Fri, 7 Jul 2017 07:08:34 +0000 Subject: [PATCH 015/164] Translated using Weblate (German) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index cd4ce1ac6c..cddf4a5055 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -49,7 +49,7 @@ "Send an encrypted message": "Verschlüsselte Nachricht senden", "Send a message (unencrypted)": "Nachricht senden (unverschlüsselt)", "Warning!": "Warnung!", - "Direct Chat": "Privater Chat", + "Direct Chat": "Direkt-Chat", "Error": "Fehler", "accept": "akzeptiere", "accepted an invitation": "Einladung akzeptieren", @@ -61,7 +61,7 @@ "An email has been sent to": "Eine E-Mail wurde gesendet an", "anyone": "Jeder", "Anyone who knows the room's link, apart from guests": "Alle, denen der Raum-Link bekannt ist, ausgenommen Gäste", - "Anyone who knows the room's link, including guests": "Jeder der den Raum-Link kennt - auch Gäste", + "Anyone who knows the room's link, including guests": "Alle, die den Raum-Link kennen (auch Gäste)", "Are you sure you want to leave the room?": "Bist du sicher, dass du den Raum verlassen willst?", "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", @@ -326,7 +326,7 @@ "Nov": "Nov", "Dec": "Dez", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s. %(monthName)s %(time)s", - "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s %(time)s": "%(weekDayName)s, %(time)s", "Set a display name:": "Anzeigename eingeben:", "Upload an avatar:": "Profilbild hochladen:", "This server does not support authentication with a phone number.": "Dieser Server unterstützt keine Authentifizierung mittels Telefonnummer.", @@ -347,8 +347,8 @@ "%(names)s and %(lastPerson)s are typing": "%(names)s und %(lastPerson)s schreiben", "%(targetName)s accepted an invitation.": "%(targetName)s hat eine Einladung angenommen.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s akzeptierte die Einladung für %(displayName)s.", - "%(names)s and one other are typing": "%(names)s und eine weitere Person tippen", - "%(names)s and %(count)s others are typing": "%(names)s und %(count)s weitere Personen schreiben", + "%(names)s and one other are typing": "%(names)s und ein weiteres Raum-Mitglied schreiben", + "%(names)s and %(count)s others are typing": "%(names)s und %(count)s weitere Raum-Mitglieder schreiben", "%(senderName)s answered the call.": "%(senderName)s hat den Anruf angenommen.", "%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s dauerhaft aus dem Raum ausgeschlossen.", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von \"%(oldDisplayName)s\" auf \"%(displayName)s\" geändert.", @@ -683,8 +683,8 @@ "were unbanned %(repeats)s times": "wurden %(repeats)s mal vom dauerhaften Ausschluss aus dem Raum befreit", "was unbanned %(repeats)s times": "wurde %(repeats)s mal vom dauerhaften Ausschluss aus dem Raum befreit", "were unbanned": "wurden vom dauerhaften Ausschluss aus dem Raum befreit", - "were kicked %(repeats)s times": "wurden %(repeats)s mal aus dem Raum entfernt", - "was kicked %(repeats)s times": "wurde %(repeats)s mal aus dem Raum entfernt", + "were kicked %(repeats)s times": "wurden %(repeats)s-mal aus dem Raum entfernt", + "was kicked %(repeats)s times": "wurde %(repeats)s-mal aus dem Raum entfernt", "were kicked": "wurden aus dem Raum entfernt", "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)shaben ihren Namen %(repeats)s mal geändert", "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)shat den Namen %(repeats)s mal geändert", @@ -913,7 +913,7 @@ "And %(count)s more...": "Und %(count)s weitere...", "Alias (optional)": "Alias (optional)", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Verbindung zum Heimserver fehlgeschlagen - bitte prüfe deine Verbindung, stelle sicher, dass dem SSL-Zertifikat deines Heimservers vertraut wird und keine Browser-Erweiterung Anfragen blockiert.", - "Click here to join the discussion!": "Klicke hier um der Diskussion beizuwohnen!", + "Click here to join the discussion!": "Hier klicken, um an der Diskussion teilzunehmen!", "Close": "Schließen", "Custom": "Erweitert", "Decline": "Ablehnen", From 82ee0d410601fd8fb956ec6363843d4522c0eaf2 Mon Sep 17 00:00:00 2001 From: Sri Lakshmi Date: Fri, 7 Jul 2017 14:02:54 +0000 Subject: [PATCH 016/164] Translated using Weblate (Telugu) Currently translated at 12.5% (115 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/te/ --- src/i18n/strings/te.json | 116 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index 201c013bc7..d92f55ab66 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -1,3 +1,117 @@ { - "was invited": "తనని ఆహ్వానించారు" + "was invited": "తనని ఆహ్వానించారు", + "ar-iq": "అరబిక్ (ఇరాక్)", + "ar-jo": "అరబిక్ (జోర్డాన్)", + "ar-kw": "అరబిక్ (కువైట్)", + "ar-lb": "అరబిక్ (లెబనాన్)", + "ar-ly": "అరబిక్ (లిబియా)", + "ar-ma": "అరబిక్ (మొరాకో)", + "ar-om": "అరబిక్ (ఒమన్)", + "ar-qa": "అరబిక్ (కతర్)", + "ar-sa": "అరబిక్ (సౌదీ అరేబియా)", + "ar-sy": "అరబిక్ (సిరియా)", + "ar-tn": "అరబిక్ (ట్యునీషియా)", + "ar-ye": "అరబిక్ (యెమెన్)", + "bg": "బల్గేరియన్", + "da": "డానిష్", + "de-at": "జర్మన్ (ఆస్ట్రియా)", + "de-ch": "జర్మన్ (స్విట్జర్లాండ్)", + "de": "జర్మన్", + "de-li": "జర్మన్ (లిక్టెన్స్టీన్)", + "de-lu": "జర్మన్ (లక్సెంబర్గ్)", + "el": "గ్రీకు", + "en-au": "ఆంగ్లము (ఆస్ట్రేలియా)", + "en-bz": "ఇంగ్లీష్ (బెలిజ్)", + "en-ca": "ఇంగ్లీష్ (కెనడా)", + "en": "ఇంగ్లీష్", + "en-gb": "ఇంగ్లీష్ (యునైటెడ్ కింగ్డమ్)", + "en-ie": "ఇంగ్లీష్ (ఐర్లాండ్)", + "en-jm": "ఇంగ్లీష్ (జమైకా)", + "en-nz": "ఇంగ్లీష్ (న్యూజిలాండ్)", + "en-tt": "ఇంగ్లీష్ (ట్రినిడాడ్)", + "en-us": "ఇంగ్లీష్ (యునైటెడ్ స్టేట్స్)", + "en-za": "ఇంగ్లీష్ (దక్షిణ ఆఫ్రికా)", + "es-ar": "స్పానిష్ (అర్జెంటీనా)", + "es-bo": "స్పానిష్ (బొలీవియా)", + "es-cl": "స్పానిష్ (చిలీ)", + "es-co": "స్పానిష్ (కొలంబియా)", + "es-cr": "స్పానిష్ (కోస్టా రికా)", + "af": "ఆఫ్రికాన్స్", + "ar-ae": "అరబిక్ (యు.ఏ.ఈ.)", + "ar-bh": "అరబిక్ (బహ్రెయిన్)", + "ar-dz": "అరబిక్ (అల్జీరియా)", + "ar-eg": "అరబిక్ (ఈజిప్ట్)", + "be": "భెలరుసీన్", + "ca": "కతలన్", + "cs": "ఛ్జెచ్", + "es-do": "స్పానిష్ (డొమినికన్ రిపబ్లిక్)", + "lt": "లిథూనీన్", + "lv": "లత్వీన్", + "mk": "మాసిడోనియన్ (ఫ్య్ఋఓం)", + "ms": "మలేషియన్", + "mt": "మాల్టీస్", + "nl-be": "డచ్ (బెల్జియం)", + "nl": "డచ్", + "no": "నార్వేజియన్", + "pl": "పోలిష్", + "pt-br": "బ్రెజిలియన్ పోర్చుగీస్", + "pt": "పోర్చుగీస్", + "rm": "ర్హెతో-రొమనిచ్", + "ro-mo": "రోమేనియా (మోల్డోవా రిపబ్లిక్)", + "ro": "రొమనీన్", + "ru-mo": "రష్యన్ (మోల్డోవా రిపబ్లిక్)", + "ru": "రష్యన్", + "sb": "సోర్బియన్", + "sk": "శ్లొవక్", + "sl": "స్లోవేనియాన్", + "sq": "ఆల్బనీన్", + "sr": "సెర్బియన్", + "sv-fi": "స్వీడిష్ (ఫిన్లాండ్)", + "sv": "స్వీడిష్", + "sx": "శుతు", + "sz": "సామీ (లప్పీష్)", + "th": "థాయ్", + "tn": "సెటస్వానా", + "tr": "టుర్కిష్", + "ts": "సోంగా", + "uk": "ఉక్రేనియన్", + "ur": "ఉర్దూ", + "ve": "వెండా", + "vi": "వియత్నమెసె", + "xh": "షోసా", + "zh-cn": "చైనీస్ (ప్ ర్ సీ)", + "zh-hk": "చైనీస్ (హాంకాంగ్ స్ఎఅర్)", + "zh-sg": "చైనీస్ (సింగపూర్)", + "zh-tw": "చైనీస్ (తైవాన్)", + "zu": "జూలూ", + "a room": "ఓ గది", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "ఒక టెక్స్ట్ సందేశం +%(msisdn)s కు పంపబడింది. దయచేసి దీనిలో ఉన్న ధృవీకరణ కోడ్ను నమోదు చేయండి", + "Accept": "అంగీకరించు", + "%(targetName)s accepted an invitation.": "% (టర్గెట్పెరు) s ఆహ్వానాన్ని అంగీకరించింది.", + "Account": "ఖాతా", + "Access Token:": "యాక్సెస్ టోకెన్:", + "Add": "చేర్చు", + "Add a topic": "అంశాన్ని జోడించండి", + "Add email address": "ఇమెయిల్ చిరునామాను జోడించండి", + "Add phone number": "ఫోన్ నంబర్ను జోడించండి", + "Admin": "అడ్మిన్", + "Admin tools": "నిర్వాహక ఉపకరణాలు", + "VoIP": "విఒఐపి", + "Missing Media Permissions, click here to request.": "మీడియా అనుమతులు మిస్ అయయి, అభ్యర్థించడానికి ఇక్కడ క్లిక్ చేయండి.", + "No Microphones detected": "మైక్రోఫోన్లు కనుగొనబడలేదు", + "No Webcams detected": "వెబ్కామ్లు కనుగొనబడలేదు", + "No media permissions": "మీడియా అనుమతులు లేవు", + "You may need to manually permit Riot to access your microphone/webcam": "రియోట్ను ను మీరు మాన్యువల్ గా మీ మైక్రోఫోన్ / వెబ్క్యామ్ను ప్రాప్యత చేయడానికి అనుమతించాలి", + "Default Device": "డిఫాల్ట్ పరికరం", + "Microphone": "మైక్రోఫోన్", + "Camera": "కెమెరా", + "Advanced": "ఆధునిక", + "Algorithm": "అల్గారిథం", + "Hide removed messages": "తీసివేసిన సందేశాలను దాచండి", + "Always show message timestamps": "ఎల్లప్పుడూ సందేశాల సమయ ముద్రలు చూపించు", + "Authentication": "ప్రామాణీకరణ", + "Alias (optional)": "అలియాస్ (ఇవచు ఇవకపపోవచు)", + "all room members": "అన్ని గదుల సభ్యులు", + "You do not have permission to post to this room": "మీకు ఈ గదికి పోస్ట్ చేయడానికి అనుమతి లేదు", + "You have been invited to join this room by %(inviterName)s": "% (InviterName) లు ఈ గదిలో చేరడానికి మీరు ఆహ్వానించబడ్డారు" } From ea68cca233b6b4ccebdc3e3972b588352bddafa6 Mon Sep 17 00:00:00 2001 From: zottel Date: Fri, 7 Jul 2017 07:33:42 +0000 Subject: [PATCH 017/164] Translated using Weblate (German) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index cddf4a5055..1f79616a0f 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -358,7 +358,7 @@ "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s hat das Thema geändert in \"%(topic)s\".", "/ddg is not a command": "/ddg ist kein Kommando", "%(senderName)s ended the call.": "%(senderName)s hat den Anruf beendet.", - "Failed to lookup current room": "Aktuellen Raum nachzuschlagen schlug fehl", + "Failed to lookup current room": "Fehler beim Nachschlagen des Raums", "Failed to send request.": "Anfrage konnte nicht gesendet werden.", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s von %(fromPowerLevel)s zu %(toPowerLevel)s", "%(senderName)s invited %(targetName)s.": "%(senderName)s hat %(targetName)s eingeladen.", @@ -865,7 +865,7 @@ "Remote addresses for this room:": "Remote-Adressen für diesen Raum:", "Unrecognised command:": "Unbekannter Befehl:", "Unrecognised room alias:": "Unbekannter Raum-Alias:", - "Use compact timeline layout": "Nutze kompaktes Zeitstrahl-Layout", + "Use compact timeline layout": "Kompaktes Layout", "Verified key": "Verifizierter Schlüssel", "WARNING: Device already verified, but keys do NOT MATCH!": "WARNUNG: Gerät bereits verifiziert, aber Schlüssel sind NICHT GLEICH!", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und Gerät %(deviceId)s ist \"%(fprint)s\" welche nicht dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmen. Dies kann bedeuten, dass deine Kommunikation abgefangen wird!", From 0061757c9199d32fc0f6487fbaad33bd326bfdbb Mon Sep 17 00:00:00 2001 From: Kelvin Date: Mon, 3 Jul 2017 18:28:33 +0000 Subject: [PATCH 018/164] Translated using Weblate (Malayalam) Currently translated at 3.6% (33 of 915 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ml/ --- src/i18n/strings/ml.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 1612115f2b..022494b252 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -13,7 +13,7 @@ "Mute": "നിശ്ശബ്ദം", "Notifications": "നോട്ടിഫിക്കേഷനുകള്‍", "Operation failed": "ശ്രമം പരാജയപ്പെട്ടു", - "Please Register": "ദയവായി രെജിസ്റ്റര്‍ ചെയ്യുക", + "Please Register": "ദയവായി റെജിസ്റ്റർ ചെയ്യുക", "powered by Matrix": "മാട്രിക്സില്‍ പ്രവര്‍ത്തിക്കുന്നു", "Remove": "നീക്കം ചെയ്യുക", "Room directory": "റൂം ഡയറക്ടറി", From c7e818d1c5f520c158ec428b13ff5597da15db65 Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Fri, 7 Jul 2017 20:09:19 +0000 Subject: [PATCH 019/164] Translated using Weblate (Dutch) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 371 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 369 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 95c5e0ee78..38eb5172b3 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -162,7 +162,7 @@ "Ban": "Verban", "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met de gegeven id", - "Blacklisted": "Op de zwarte lijst", + "Blacklisted": "Buitengesloten", "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", @@ -552,5 +552,372 @@ "Server may be unavailable, overloaded, or the file too big": "De server is misschien onbereikbaar, overbelast of het bestand is te groot", "Server may be unavailable, overloaded, or you hit a bug.": "De server is misschien onbereikbaar, overbelast of je bent tegen een fout aangelopen.", "Server unavailable, overloaded, or something else went wrong.": "De server is onbereikbaar, overbelast of iets anders ging fout.", - "Session ID": "Sessie ID" + "Session ID": "Sessie ID", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s heeft %(targetName)s de ruimte uitgestuurd.", + "Kick": "Er uit sturen", + "Kicks user with given id": "Stuurt de gebruiker met het gegeven id er uit", + "%(senderName)s set a profile picture.": "%(senderName)s heeft een profielfoto ingesteld.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s heeft zijn of haar weergavenaam naar %(displayName)s veranderd.", + "Set": "Instellen", + "Show panel": "Paneel weergeven", + "Show Text Formatting Toolbar": "Tekst Opmaak Werkbalk Weergeven", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Laat de tijd in twaalf uur formaat zien (bijv. 2:30pm)", + "Signed Out": "Uitgelogd", + "Sign in": "Inloggen", + "Sign out": "Uitloggen", + "since the point in time of selecting this option": "sinds het punt in tijd dat deze optie geselecteerd wordt", + "since they joined": "sinds ze zijn toegetreden", + "since they were invited": "sinds ze zijn uitgenodigd", + "Some of your messages have not been sent.": "Een paar van je berichten zijn niet verstuurd.", + "Someone": "Iemand", + "Sorry, this homeserver is using a login which is not recognised ": "Sorry, deze thuisserver gebruikt een inlog methode die niet wordt herkend. ", + "The default role for new room members is": "De standaard rol voor nieuwe ruimteleden is", + "The main address for this room is": "Het hoofdadres voor deze ruimte is", + "The phone number entered looks invalid": "Het telefoonnummer dat ingevoerd is ziet er ongeldig uit", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "De versleutelingssleutel die je hebt verstrekt komt overeen met de versleutelingssleutel die je hebt ontvangen van %(userId)s's apparaat %(deviceId)s. Apparaat is gemarkeerd als geverifieerd.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Deze actie kan niet door een gastaccount worden uitgevoerd. Registreer je om deze actie uit te kunnen voeren.", + "This email address is already in use": "Dit e-mailadres is al in gebruik", + "This email address was not found": "Dit e-mailadres was niet gevonden", + "%(actionVerb)s this person?": "%(actionVerb)s deze persoon?", + "The email address linked to your account must be entered.": "Het e-mailadres dat met je account verbonden is moet worden ingevoerd.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Het bestand '%(fileName)s' overtreft de maximale bestandsgrootte voor uploads van deze thuisserver", + "The file '%(fileName)s' failed to upload": "Het is niet gelukt om het bestand '%(fileName)s' te uploaden", + "The remote side failed to pick up": "De andere kant heeft niet opgenomen", + "This Home Server does not support login using email address.": "Deze Thuisserver ondersteunt het inloggen met een e-mailadres niet.", + "This invitation was sent to an email address which is not associated with this account:": "Deze uitnodiging was naar een e-mailadres gestuurd die niet geassocieerd is met dit account:", + "There was a problem logging in.": "Er was een probleem met het inloggen.", + "This room has no local addresses": "Deze ruimte heeft geen lokale adressen", + "This room is not recognised.": "Deze ruimte wordt niet herkend.", + "These are experimental features that may break in unexpected ways": "Dit zijn experimentele functies die misschien kunnen breken op onverwachte manieren", + "The visibility of existing history will be unchanged": "De zichtbaarheid van de bestaande geschiedenis zal onveranderd blijven", + "This doesn't appear to be a valid email address": "Het ziet er niet naar uit dat dit een geldig e-mailadres is", + "This is a preview of this room. Room interactions have been disabled": "Dit is een voorvertoning van de ruimte. Ruimte interacties zijn uitgeschakeld", + "This phone number is already in use": "Dit telefoonnummer is al in gebruik", + "This room": "Deze ruimte", + "This room is not accessible by remote Matrix servers": "Deze ruimte is niet toegankelijk voor afgelegen Matrix servers", + "This room's internal ID is": "Het interne ID van deze ruimte is", + "times": "keer", + "To ban users": "om gebruikers te verbannen", + "to browse the directory": "om de catalogus door te bladeren", + "To configure the room": "Om de ruimte te configureren", + "to demote": "om te degraderen", + "to favourite": "om aan favorieten toe te voegen", + "To invite users into the room": "Om gebruikers in deze ruimte toe te voegen", + "To kick users": "Om gebruikers er uit te zetten", + "To link to a room it must have an address.": "Om naar een ruimte te linken moet het een adres hebben.", + "to make a room or": "om een ruimte te maken of", + "To remove other users' messages": "Om berichten van anderen gebruikers te verwijderen", + "To reset your password, enter the email address linked to your account": "Voer het e-mailadres dat met je account verbonden is in om je wachtwoord opnieuw in te stellen", + "to restore": "om te herstellen", + "To send events of type": "Om een bepaalde soort gebeurtenissen te sturen", + "To send messages": "Om berichten te versturen", + "to start a chat with someone": "om een gesprek met iemand te starten", + "to tag as %(tagName)s": "om als %(tagName)s te etiketteren", + "to tag direct chat": "als directe chat etiketteren", + "To use it, just wait for autocomplete results to load and tab through them.": "Om het te gebruiken, wacht voor de automatisch aanvullen resultaten om te laden en kijk er door heen.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Je probeerde een specifiek punt in de tijdlijn van deze ruimte te laden maar je hebt niet de permissie om de desbetreffende berichten te zien.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Het is niet gelukt om een specifiek punt in de tijdlijn van deze ruimte te laden.", + "Turn Markdown off": "Doe opmaak uit", + "Turn Markdown on": "Zet opmaak aan", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s heeft eind-tot-eind versleuteling aangezet (algoritme %(algorithm)s).", + "Unable to add email address": "Niet mogelijk om e-mailadres toe te voegen", + "Unable to remove contact information": "Niet mogelijk om contactinformatie te verwijderen", + "Unable to restore previous session": "Niet mogelijk om de vorige sessie te herstellen", + "Unable to verify email address.": "Niet mogelijk om het e-mailadres te verifiëren.", + "Unban": "Ontbannen", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s ontbande %(targetName)s.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Niet mogelijk om vast te stellen dat het adres waar deze uitnodiging naartoe was verstuurd overeenkomt met het adres dat is geassocieerd met je account.", + "Unable to capture screen": "Niet mogelijk om het scherm vast te leggen", + "Unable to enable Notifications": "Niet mogelijk om notificaties aan te zetten", + "Unable to load device list": "Niet mogelijk om de lijst met apparaten te laden", + "Undecryptable": "Niet ontsleutelbaar", + "Unencrypted room": "Ontsleutelde ruimte", + "unencrypted": "ontsleuteld", + "Unencrypted message": "Niet versleuteld bericht", + "unknown caller": "onbekende beller", + "Unknown command": "Onbekende commando", + "unknown device": "Onbekend apparaat", + "Unknown room %(roomId)s": "Onbekende ruimte %(roomId)s", + "Unknown (user, device) pair:": "Onbekend (gebruiker, apparaat) paar:", + "unknown": "onbekend", + "Unmute": "Niet dempen", + "Unnamed Room": "Naamloze Ruimte", + "Unrecognised command:": "Onbekende commando:", + "Unrecognised room alias:": "Onbekende ruimte alias:", + "Unverified": "Niet geverifieerd", + "Uploading %(filename)s and %(count)s others.zero": "Aan het uploaden %(filename)s", + "Uploading %(filename)s and %(count)s others.one": "%(filename)s en %(count)s andere aan het uploaden", + "Uploading %(filename)s and %(count)s others.other": "%(filename)s en %(count)s anderen aan het uploaden", + "uploaded a file": "Bestand geüpload", + "Upload avatar": "Avatar uploaden", + "Upload Failed": "Uploaden Mislukt", + "Upload Files": "Bestanden Uploaden", + "Upload file": "Bestand uploaden", + "Upload new:": "Nieuwe uploaden:", + "Usage": "Gebruik", + "Use compact timeline layout": "Gebruik een compacte tijdlijn indeling", + "Use with caution": "Gebruik met behoedzaamheid", + "User ID": "Gebruiker ID", + "User Interface": "Gebruiker Interface", + "%(user)s is a": "%(user)s is een", + "User name": "Gebruikersnaam", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (macht %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "Gebruikersnaam ongeldig: %(errMessage)s", + "Users": "Gebruikers", + "User": "Gebruiker", + "Verification Pending": "Verificatie Wachtend", + "Verification": "Verificatie", + "verified": "geverifieerd", + "Verified": "Geverifieerd", + "Verified key": "Geverifieerde sleutel", + "Video call": "Video-oproep", + "Voice call": "Spraakoproep", + "VoIP conference finished.": "VoIP vergadering beëindigd.", + "VoIP conference started.": "VoIP vergadering gestart.", + "VoIP is unsupported": "VoIP is niet ondersteund", + "(could not connect media)": "(kan media niet verbinden)", + "(no answer)": "(geen antwoord)", + "(unknown failure: %(reason)s)": "(onbekende fout: %(reason)s)", + "(warning: cannot be disabled again!)": "(waarschuwing: kan niet meer uitgezet worden!)", + "Warning!": "Waarschuwing!", + "WARNING: Device already verified, but keys do NOT MATCH!": "WAARSCHUWING: Apparaat al geverifieerd, maar de sleutels KOMEN NIET OVEREEN!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WAARSCHUWING: SLEUTEL VERIFICATIE IS MISLUKT! De ondertekende sleutel voor %(userId)s en apparaat %(deviceId)s is \"%(fprint)s\" wat niet overeenkomt met de verschafte sleutel \"%(fingerprints)s\". Dit kan betekenen dat je communicatie onderschept wordt!", + "Who can access this room?": "Wie heeft toegang tot deze ruimte?", + "Who can read history?": "Wie kan de geschiedenis lezen?", + "Who would you like to add to this room?": "Wie wil je aan deze ruimte toevoegen?", + "Who would you like to communicate with?": "Met wie zou je willen communiceren?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(sernderName)s trok %(targetName)s's uitnodiging terug.", + "Would you like to accept or decline this invitation?": "Wil je deze uitnodiging accepteren of afwijzen?", + "You already have existing direct chats with this user:": "Je hebt al bestaande privé gesprekken met deze gebruiker:", + "You are already in a call.": "Je bent al in gesprek.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Je zit nog niet in een ruimte! Druk op om een ruimte te maken of om door de catalogus te bladeren", + "You are trying to access %(roomName)s.": "Je probeert in %(roomName)s toe te treden.", + "You cannot place a call with yourself.": "Je kan geen spraakoproep met jezelf maken.", + "You cannot place VoIP calls in this browser.": "Je kan geen VoIP oproepen in deze browser doen.", + "You do not have permission to post to this room": "Je hebt geen permissie om in deze ruimte te praten", + "You have been banned from %(roomName)s by %(userName)s.": "Je bent verbannen van %(roomName)s door %(userName)s.", + "You have been invited to join this room by %(inviterName)s": "Je bent in deze ruimte uitgenodigd door %(inviterName)s", + "You have been kicked from %(roomName)s by %(userName)s.": "Je bent uit %(roomName)s gezet door %(userName)s.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Je bent op alle apparaten uitgelegd en je zal niet langer notificaties ontvangen. Om notificaties weer aan te zetten, log op elk apparaat opnieuw in", + "You have disabled URL previews by default.": "Je hebt URL voorvertoningen standaard uitgezet.", + "You have enabled URL previews by default.": "Je hebt URL voorvertoningen standaard aangezet.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Je hebt een ongeldig contact ingevoerd. Probeer zijn of haar Matrix ID of e-mailadres te gebruiken.", + "You have no visible notifications": "Je hebt geen zichtbare notificaties", + "You may wish to login with a different account, or add this email to this account.": "Je wilt misschien met een ander account inloggen of deze e-mail aan je account toevoegen.", + "you must be a": "wat je moet zijn is een", + "You must register to use this functionality": "Je moet je registreren om deze functionaliteit te gebruiken", + "You need to be able to invite users to do that.": "Je moet bevoegd zijn om gebruikers uit te nodigen om dat te doen.", + "You need to be logged in.": "Je moet ingelogd zijn.", + "You need to enter a user name.": "Je moet een gebruikersnaam invoeren.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Het ziet er naar uit dat je e-mailadres niet met een Matrix ID geassocieerd is op deze thuisserver.", + "Your password has been reset": "Je wachtwoord is gereset", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Je wachtwoord is succesvol veranderd. Je zal geen notificaties op andere apparaten ontvangen totdat je er opnieuw inlogd", + "You seem to be in a call, are you sure you want to quit?": "Het ziet er naar uit dat je in een gesprek zit, weet je zeker dat je wilt afsluiten?", + "You seem to be uploading files, are you sure you want to quit?": "Het ziet er naar uit dat je bestanden aan het uploaden bent, weet je zeker dat je wilt afsluiten?", + "You should not yet trust it to secure data": "Je moet het nog niet vertrouwen om gegevens te beveiligen", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Je zal deze verandering niet terug kunnen draaien omdat je de gebruiker naar hetzelfde machtsniveau als jezelf promoot.", + "Your home server does not support device management.": "Je thuisserver ondersteund geen apparaat beheer.", + "This server does not support authentication with a phone number.": "Deze server ondersteunt geen authenticatie met een telefoonnummer.", + "Missing password.": "Het wachtwoord mist.", + "Passwords don't match.": "De wachtwoorden komen niet overeen.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Het wachtwoord is te kort (min %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Dit ziet er niet uit als een geldig e-mailadres.", + "This doesn't look like a valid phone number.": "Dit zit er niet uit als een geldig telefoonnummer.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Gebruikersnamen mogen alleen letters, nummers, punten, afbreek- en lage streepjes bevatten.", + "An unknown error occurred.": "Een onbekende fout voorgevallen.", + "I already have an account": "Ik heb al een account", + "An error occurred: %(error_string)s": "Er is een fout voorgevallen: %(error_string)s", + "Topic": "Onderwerp", + "Make Moderator": "Moderator maken", + "Make this room private": "Deze ruimte privé maken", + "Share message history with new users": "Bericht geschiedenis met nieuwe gebruikers delen", + "Encrypt room": "Ruimte versleutelen", + "There are no visible files in this room": "Er zijn geen zichtbare bestanden in deze ruimte", + "Room": "Ruimte", + "Connectivity to the server has been lost.": "De connectiviteit naar de server is verloren.", + "Sent messages will be stored until your connection has returned.": "Verstuurde berichten zullen opgeslagen worden tot je connectie weer terug is.", + "Auto-complete": "Automatisch aanvullen", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Verstuur alle of annuleer alle nu. Je kan ook individuele berichten selecteren om te versturen of te annuleren.", + "(~%(count)s results).one": "(~%(count)s resultaat)", + "(~%(count)s results).other": "(~%(count)s resultaten)", + "or": "of", + "Active call": "Actief gesprek", + "bold": "vetgedrukt", + "italic": "schuingedrukt", + "strike": "doorgestreept", + "underline": "onderstreept", + "code": "code", + "quote": "citaat", + "bullet": "opsommingsteken", + "numbullet": "genummerd opsommingsteken", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s zijn %(repeats)s keer toegetreden", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s is %(repeats)s keer toegetreden", + "%(severalUsers)sjoined": "%(severalUsers)s zijn toegretreden", + "%(oneUser)sjoined": "%(oneUser)s is toegetreden", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s zijn %(repeats)s vertrokken", + "%(oneUser)sleft %(repeats)s times": "%(oneUser) is %(repeats)s vertrokken", + "%(severalUsers)sleft": "%(severalUsers)s zijn vertrokken", + "%(oneUser)sleft": "%(oneUser)s is vertrokken", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers) zijn %(repeats)s toegetreden en weer vertrokken", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s is %(repeats)s keer toegetreden en vertrokken", + "%(severalUsers)sjoined and left": "%(severalUsers)s zijn toegetreden en vertrokken", + "%(oneUser)sjoined and left": "%(oneUser)s is toegetreden en weer vertrokken", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s zijn %(repeats)s keer vertrokken en opnieuw toegetreden", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s is %(repeats)s keer vertrokken en opnieuw toegetreden", + "%(severalUsers)sleft and rejoined": "%(severalUsers) zijn vertrokken en opnieuw toegetreden", + "%(oneUser)sleft and rejoined": "%(oneUser)s is vertrokken en opnieuw toegetreden", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s hebben hun uitnodiging uitnodiging %(repeats)s keer afgewezen", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)s heeft zijn of haar uitnodiging %(repeats)s keer afgewezen", + "%(severalUsers)srejected their invitations": "%(severalUsers)s hebben hun uitnodiging afgewezen", + "%(oneUser)srejected their invitation": "%(oneUser)s heeft zijn of haar uitnodiging afgewezen", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers) hun uitnodiging is %(repeats)s keer terug getrokken", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s zijn of haar uitnodiging is %(repeats)s keer terug getrokken", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s hun uitnodiging is terug getrokken", + "%(oneUser)shad their invitation withdrawn": "%(oneUser) zijn of haar uitnodiging is terug getrokken", + "were invited %(repeats)s times": "is %(repeats)s keer uitgenodigd", + "was invited %(repeats)s times": "was %(repeats)s keer uitgenodigd", + "were invited": "waren uitgenodigd", + "was invited": "was uitgenodigd", + "were banned %(repeats)s times": "waren %(repeats)s keer verbannen", + "was banned %(repeats)s times": "was %(repeats)s keer verbannen", + "were banned": "waren verbannen", + "was banned": "was verbannen", + "were unbanned %(repeats)s times": "waren %(repeats)s keer ontbannen", + "was unbanned %(repeats)s times": "was %(repeats)s keer ontbannen", + "were unbanned": "waren ontbannen", + "was unbanned": "was ontbannen", + "were kicked %(repeats)s times": "waren er %(repeats)s keer uitgezet", + "was kicked %(repeats)s times": "was er %(repeats)s keer uitgezet", + "were kicked": "waren er uitgezet", + "was kicked": "was er uitgezet", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)s hebben hun naam %(repeats)s keer aangepast", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)s heeft zijn of haar naam %(repeats)s keer aangepast", + "%(severalUsers)schanged their name": "%(severalUsers)s hebben hun naam aangepast", + "%(oneUser)schanged their name": "%(oneUser)s heeft zijn of haar naam aangepast", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers) hebben hun avatar %(repeats)s keer aangepast", + "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)s heeft zijn of haar avatar %(repeats)s keer aangepast", + "%(severalUsers)schanged their avatar": "%(severalUsers)s hebben hun avatar aangepast", + "%(oneUser)schanged their avatar": "%(oneUser)s heeft zijn of haar avatar aangepast", + "Please select the destination room for this message": "Selecteer de destinatie ruimte voor dit bericht", + "New Password": "Nieuw wachtwoord", + "Start automatically after system login": "Start automatisch na systeem aanmelding", + "Desktop specific": "Desktop specifiek", + "Analytics": "Analisaties", + "Opt out of analytics": "Uitschrijven voor gegevens analisaties", + "Options": "Opties", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot verzameld anonieme analisaties dat het mogelijk maakt om de applicatie te verbeteren.", + "Passphrases must match": "Wachtzinnen moeten overeenkomen", + "Passphrase must not be empty": "Wachtzin mag niet leeg zijn", + "Export room keys": "Ruimtesleutels exporteren", + "Confirm passphrase": "Wachtzin bevestigen", + "Import room keys": "Ruimtesleutels importeren", + "File to import": "Bestand om te importeren", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Dit proces maakt het mogelijk om de sleutels van je ontvangen berichten in versleutelde ruimtes naar een lokaal bestand te exporteren. Je zal daarna in de toekomst het bestand in een ander Matrix programma kunnen importeren zodat dat programma ook deze berichten kan ontsleutelen.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Het geëxporteerde bestand zal het voor iedereen dat het kan lezen mogelijk maken om alle berichten die jij kan zien te ontsleutelen, je zal daarom voorzichtig moeten zijn en het veilig houden. Om hiermee te helpen zou je een wachtzin moeten invoeren hieronder, deze zal dan gebruikt worden om de geëxporteerde gegevens dte versleutelen. Het is dan alleen mogelijk om de gegevens te importeren met hetzelfde wachtwoord.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Dit proces maakt het mogelijk om versleutelingssleutels die je eerst had geëxporteerd vanaf een ander Matrix programma te importeren. Je zal daarna alle berichten kunnen ontsleutelen die het andere programma ook kon ontsleutelen.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Het te exporteren bestand zal beveiligd zijn met een wachtzin. Je moet hier een wachtzin invoeren om het bestand te ontsleutelen.", + "You must join the room to see its files": "Je moet tot een ruimte toetreden om de bestanden te zien", + "Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s uitnodigingen afslaan", + "Start new chat": "Nieuwe chat starten", + "Guest users can't invite users. Please register.": "Gast gebruikers kunnen geen gebruikers uitnodigen. Registreer je alsjeblieft.", + "Failed to invite": "Niet gelukt om uit te nodigen", + "Failed to invite user": "Niet gelukt om de gebruiker uit te nodigen", + "Failed to invite the following users to the %(roomName)s room:": "Niet gelukt om de volgende gebruikers voor de %(roomName)s ruimte uit te nodigen:", + "Confirm Removal": "Verwijdering Bevestigen", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Weet je zeker dat je deze gebeurtenis wilt verwijderen? Wees er wel van bewust dat als je een ruimtenaam of onderwerp verwijderd je de verandering ongedaan kunt maken.", + "Unknown error": "Onbekende fout", + "Incorrect password": "Incorrect wachtwoord", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dit zal je account permanent onbruikbaar maken. Je zal ook niet opnieuw kunnen registreren met hetzelfde gebruikers ID.", + "This action is irreversible.": "Deze actie is onomkeerbaar.", + "To continue, please enter your password.": "Om verder te gaan, voer je wachtwoord in.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Om te verifiëren dat dit apparaat vertrouwd kan worden, contacteer de eigenaar op een andere manier (bijv. persoonlijk of via een telefoontje) en vraag of de sleutel die ze zien in de Gebruikersinstellingen voor dit apparaat overeenkomt met de onderstaande sleutel:", + "Device name": "Apparaat naam", + "Device Name": "Apparaat Naam", + "Device key": "Apparaat sleutel", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Als het overeenkomt, druk op de verifiëren knop hieronder. Als het niet overeenkomt, dan is er iemand anders die dit apparaat onderschept en dan zal je waarschijnlijk in plaats daarvan op de 'buitensluiten' knop willen drukken.", + "Blacklist": "Buitensluiten", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Je bent momenteel geverifieerde apparaten aan het buitensluiten; om berichten naar deze apparaten te versturen moet je ze verifiëren.", + "Unblacklist": "Niet buitensluiten", + "In future this verification process will be more sophisticated.": "In de toekomst zal dit verificatie proces meer geraffineerd zijn.", + "Verify device": "Apparaat verifiëren", + "I verify that the keys match": "Ik verifieer dat de sleutels overeenkomen", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We ervaren een fout terwijl er wordt geprobeerd om de vorige sessie te herstellen. Als je doorgaat moet je opnieuw inloggen en versleutelde gespreksgeschiedenis zal onleesbaar zijn.", + "Unable to restore session": "Het is niet mogelijk om de sessie te herstellen", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Als je eerst gebruik hebt gemaakt van een recentere versie van Riot, dan is je sessie misschien onverenigbaar met deze versie. Sluit dit scherm en ga terug naar de recentere versie.", + "Continue anyway": "Toch doorgaan", + "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Je weergavenaam is hoe je voor anderen zal verschijnen terwijl je in ruimtes praat. Wat wil je dat het wordt?", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We raden je aan om door het verificatieproces van elk apparaat te gaan om te bevestigen dat ze tot de legitieme eigenaar behoren maar je kan het bericht versturen zonder te verifiëren als je dat liever doet.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" bevat apparaten die je nog niet eerder hebt gezien.", + "Unknown devices": "Onbekende apparaten", + "Unknown Address": "Onbekend Adres", + "Unverify": "Ontverifïeren", + "Verify...": "Verifiëren...", + "ex. @bob:example.com": "bijv. @bob:voorbeeld.com", + "Add User": "Gebruiker Toevoegen", + "This Home Server would like to make sure you are not a robot": "Deze thuisserver wil er zeker van zijn dat je geen robot bent", + "Sign in with CAS": "Inloggen met CAS", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Je kan de aangepaste server opties gebruiken om bij andere Matrix servers in te loggen door een andere thuisserver URL te specificeren.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Dit maakt het mogelijk om deze applicatie te gebruiken met een bestaand Matrix account op een andere thuisserver.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Je kan ook een aangepaste identiteitsserver instellen maar dit zal waarschijnlijk interactie met gebruikers gebaseerd op een e-mailadres voorkomen.", + "Please check your email to continue registration.": "Bekijk je e-mail om door te gaan met de registratie.", + "Token incorrect": "Bewijs incorrect", + "A text message has been sent to": "Een tekstbericht is verstuurd naar", + "Please enter the code it contains:": "Voer de code in die het bevat:", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Als je geen e-mailadres specificeert zal je niet je wachtwoord kunnen resetten. Weet je het zeker?", + "You are registering with %(SelectedTeamName)s": "Je registreert je met %(SelectedTeamName)s", + "Default server": "Standaard server", + "Custom server": "Aangepaste server", + "Home server URL": "Thuisserver URL", + "Identity server URL": "Identiteitsserver URL", + "What does this mean?": "Wat betekent dit?", + "Error decrypting audio": "Fout met het ontsleutelen van de audio", + "Error decrypting image": "Fout met het ontsleutelen van de afbeelding", + "Image '%(Body)s' cannot be displayed.": "Afbeelding '%(Body)s' kan niet worden weergeven.", + "This image cannot be displayed.": "Deze afbeelding kan niet worden weergeven.", + "Error decrypting video": "Fout met het ontsleutelen van de video", + "Add an Integration": "Voeg een integratie toe", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Je wordt zo naar een derde-partij website verbonden zodat je het account kan legitimeren voor gebruik met %(integrationsUrl)s. Wil je doorgaan?", + "Removed or unknown message type": "Verwijderd of onbekend bericht type", + "Disable URL previews by default for participants in this room": "Zet URL voorvertoningen standaard uit voor deelnemers aan deze ruimte", + "Disable URL previews for this room (affects only you)": "Zet URL voorvertoningen uit voor deze ruimte (heeft alleen effect op jou)", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URL voorvertoningen staan standaard %(globalDisableUrlPreview)s voor deelnemers aan deze ruimte.", + "URL Previews": "URL Voorvertoningen", + "Enable URL previews for this room (affects only you)": "URL voorvertoningen in deze ruimte aanzetten (heeft alleen effect op jou)", + "Drop file here to upload": "Bestand hier laten vallen om te uploaden", + " (unsupported)": " (niet ondersteund)", + "Ongoing conference call%(supportedText)s.": "Lopend vergaderingsgesprek %(supportedText)s.", + "for %(amount)ss": "voor %(amount)ss", + "for %(amount)sm": "voor %(amount)sm", + "for %(amount)sh": "voor %(amount)su", + "for %(amount)sd": "for %(amound)sd", + "Online": "Online", + "Idle": "Afwezig", + "Offline": "Offline", + "Updates": "Updates", + "Check for update": "Voor updates kijken", + "Start chatting": "Start met praten", + "Start Chatting": "Start Met Praten", + "Click on the button below to start chatting!": "Klik op de knop hieronder om te starten met praten!", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName heeft de ruimte avatar aangepast naar ", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s heeft de ruimte avatar verwijderd.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s veranderde de avatar voor %(roomName)s", + "Username available": "Gebruikersnaam beschikbaar", + "Username not available": "Gebruikersnaam niet beschikbaar", + "Something went wrong!": "Iets ging niet goed!", + "This will be your account name on the homeserver, or you can pick a different server.": "Dit zal je account naam worden op de thuisserver of je kan een verschillende server pakken.", + "If you already have a Matrix account you can log in instead.": "Als je al een Matrix account hebt kan je in plaats daarvan inloggen.", + "Your browser does not support the required cryptography extensions": "Je browser ondersteunt de benodigde cryptografie extensies niet", + "Not a valid Riot keyfile": "Niet een geldig Riot sleutelbestand", + "Authentication check failed: incorrect password?": "Authenticatie controle gefaald: incorrect wachtwoord?", + "Disable Peer-to-Peer for 1:1 calls": "Peer-to-Peer voor 1:1 oproepen uitschakelen", + "Do you want to set an email address?": "Wil je een e-mailadres instellen?", + "This will allow you to reset your password and receive notifications.": "Dit zal het mogelijk maken om je wachtwoord te resetten en notificaties te ontvangen.", + "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", + "Skip": "Overslaan", + "Start verification": "Verificatie starten", + "Share without verifying": "Delen zonder verificatie", + "Ignore request": "Verzoek negeren", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Je hebt een nieuwe apparaat '%(displayName)s' toegevoegd die om versleutelingssleutels vraagt.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Je niet geverifieerde apparaat '%(displayName)s' vraagt naar versleutelingssleutels.", + "Encryption key request": "Verzoek voor versleutelingssleutel" } From 3d0c71b1a2bd867371c6072440ab7c6d9b4f66c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B4=A8=E0=B4=BF=E0=B4=A6=E0=B4=B0=E0=B5=8D=E2=80=8D?= =?UTF-8?q?=E0=B4=B6=E0=B5=8D?= Date: Fri, 7 Jul 2017 19:29:06 +0000 Subject: [PATCH 020/164] Translated using Weblate (Malayalam) Currently translated at 3.6% (33 of 915 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ml/ --- src/i18n/strings/ml.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 022494b252..9e6e352637 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -5,9 +5,9 @@ "Custom Server Options": "കസ്റ്റം സെര്‍വര്‍ ഓപ്ഷനുകള്‍", "Direct Chat": "നേരിട്ടുള്ള ചാറ്റ്", "Dismiss": "ഒഴിവാക്കുക", - "Drop here %(toAction)s": "ഇവിടെ നിക്ഷേപിക്കുക %(toAction)", + "Drop here %(toAction)s": "ഇവിടെ നിക്ഷേപിക്കുക %(toAction)s", "Error": "എറര്‍", - "Failed to forget room %(errCode)s": "%(errCode) റൂം ഫോര്‍ഗെറ്റ് ചെയ്യുവാന്‍ സാധിച്ചില്ല", + "Failed to forget room %(errCode)s": "%(errCode)s റൂം ഫോര്‍ഗെറ്റ് ചെയ്യുവാന്‍ സാധിച്ചില്ല", "Failed to join the room": "റൂമില്‍ അംഗമാകുവാന്‍ സാധിച്ചില്ല", "Favourite": "പ്രിയപ്പെട്ടവ", "Mute": "നിശ്ശബ്ദം", From 997c1e269ad9e0d6d9004e848c11860440de5586 Mon Sep 17 00:00:00 2001 From: Alexandre Morignot Date: Sat, 8 Jul 2017 16:36:36 +0000 Subject: [PATCH 021/164] Translated using Weblate (French) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index bc7a47029f..785ff29be2 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -666,7 +666,7 @@ "was kicked %(repeats)s times": "a été expulsé(e) %(repeats)s fois", "were kicked": "ont été expulsé(e)s", "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)sont changé leur nom %(repeats)s fois", - "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sa changé son nom %(repeats)s times", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sa changé son nom %(repeats)s fois", "%(severalUsers)schanged their name": "%(severalUsers)sont changé leur nom", "%(oneUser)schanged their name": "%(oneUser)sa changé son nom", "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)sont changé leur photo de profil %(repeats)s fois", From d2ddb36203d393e7579bee47f70e71ea8a49eeb4 Mon Sep 17 00:00:00 2001 From: "Carlos A. Carnero Delgado" Date: Mon, 26 Jun 2017 03:25:25 +0000 Subject: [PATCH 022/164] Translated using Weblate (Spanish) Currently translated at 68.2% (625 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index f7506b946d..926f7a4f68 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -244,7 +244,7 @@ "Existing Call": "Llamada existente", "Export E2E room keys": "Exportar claves E2E de la sala", "Failed to ban user": "Bloqueo del usuario falló", - "Failed to change password. Is your password correct?": "Falló al cambiar la clave, ¿Está correcta tu clave?", + "Failed to change password. Is your password correct?": "No se pudo cambiar la contraseña. ¿Está usando la correcta?", "Failed to change power level": "Falló al cambiar de nivel de acceso", "Failed to delete device": "Falló al borrar el dispositivo", "Failed to forget room %(errCode)s": "Falló al olvidar la sala %(errCode)s", From 20672dde032479b4e0f29213396c7ff7d0678c63 Mon Sep 17 00:00:00 2001 From: Sri Lakshmi Date: Mon, 10 Jul 2017 07:04:18 +0000 Subject: [PATCH 023/164] Translated using Weblate (Telugu) Currently translated at 20.6% (189 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/te/ --- src/i18n/strings/te.json | 76 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index d92f55ab66..8744dff7da 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -113,5 +113,79 @@ "Alias (optional)": "అలియాస్ (ఇవచు ఇవకపపోవచు)", "all room members": "అన్ని గదుల సభ్యులు", "You do not have permission to post to this room": "మీకు ఈ గదికి పోస్ట్ చేయడానికి అనుమతి లేదు", - "You have been invited to join this room by %(inviterName)s": "% (InviterName) లు ఈ గదిలో చేరడానికి మీరు ఆహ్వానించబడ్డారు" + "You have been invited to join this room by %(inviterName)s": "% (InviterName) లు ఈ గదిలో చేరడానికి మీరు ఆహ్వానించబడ్డారు", + "es-ec": "స్పానిష్ (ఈక్వెడార్)", + "es-gt": "స్పానిష్ (గ్వాటెమాల)", + "es-hn": "స్పానిష్ (హోండురాస్)", + "es-mx": "స్పానిష్ (మెక్సికో)", + "es-ni": "స్పానిష్ (నికరాగువా)", + "es-pa": "స్పానిష్ (పనామా)", + "es-pe": "స్పానిష్ (పెరు)", + "es-pr": "స్పానిష్ (ఫ్యూర్టో రికో)", + "es-py": "స్పానిష్ (పరాగ్వే)", + "es": "స్పానిష్ (స్పెయిన్)", + "es-sv": "స్పానిష్ (ఎల్ సాల్వడార్)", + "es-uy": "స్పానిష్ (ఉరుగ్వే)", + "es-ve": "స్పానిష్ (వెనిజులా)", + "eu": "బాస్క్ (బాస్క్)", + "fa": "ఫార్సి", + "fi": "ముగించు", + "fo": "ఫెరోయెస్", + "fr-be": "ఫ్రెంచ్ (బెల్జియం)", + "fr-ca": "ఫ్రెంచ్ (కెనడా)", + "fr-ch": "ఫ్రెంచ్ (స్విట్జర్లాండ్)", + "fr": "ఫ్రెంచ్", + "fr-lu": "ఫ్రెంచ్ (లక్సెంబర్గ్)", + "ga": "ఐరిష్", + "gd": "గేలిక్ (స్కాట్లాండ్)", + "he": "హిబ్రూ", + "hi": "హిందీ", + "hu": "హంగేరియన్", + "id": "ఇండోనేషియన్", + "is": "ఐస్లాండిక్", + "it-ch": "ఇటాలియన్ (స్విట్జర్లాండ్)", + "it": "ఇటాలియన్", + "ja": "జపనీస్", + "ko": "కొరియన్", + "Active call (%(roomName)s)": "క్రియాశీల కాల్ల్ (% (రూంపెరు) స్)", + "And %(count)s more...": "మరియు% (మొత్తం)స్ ఇంకా ...", + "all room members, from the point they are invited": "అన్ని గది సభ్యులు, పాయింట్ నుండి వారు ఆహ్వానించబడ్డారు", + "all room members, from the point they joined": "అన్ని గది సభ్యులు, పాయింట్ నుండి వారు చేరారు", + "and": "మరియు", + "and one other...": "మరియు మరొకటి ...", + "%(names)s and one other are typing": "% (పేర్లు) లు మరియు మరొకటి టైప్ చేస్తున్నారు", + "%(names)s and %(count)s others are typing": "% (పేర్లు) లు మరియు% (లెక్క) లు ఇతరులు టైప్ చేస్తున్నారు", + "An email has been sent to": "ఒక ఇమెయిల్ పంపబడింది", + "A new password must be entered.": "కొత్త పాస్ వర్డ్ ను తప్పక నమోదు చేయాలి.", + "%(senderName)s answered the call.": "% (SenderName) s కు సమాధానం ఇచ్చారు.", + "anyone": "ఎవరైనా", + "An error has occurred.": "ఒక లోపము సంభవించినది.", + "Anyone": "ఎవరైనా", + "Anyone who knows the room's link, apart from guests": "అతిథులు కాకుండా గది యొక్క లింక్ తెలిసిన వారు ఎవరైనా", + "Anyone who knows the room's link, including guests": "అతిథులతో సహా, గది లింక్ తెలిసిన వారు ఎవరైనా", + "Are you sure?": "మీరు చెప్పేది నిజమా?", + "Are you sure you want to leave the room '%(roomName)s'?": "మీరు ఖచ్చితంగా గది '% (roomName) s' వదిలివేయాలనుకుంటున్నారా?", + "Are you sure you want to reject the invitation?": "మీరు ఖచ్చితంగా ఆహ్వానాన్ని తిరస్కరించాలనుకుంటున్నారా?", + "Are you sure you want to upload the following files?": "మీరు ఖచ్చితంగా ఈ క్రింది ఫైళ్ళను అప్లోడ్ చేయాలనుకుంటున్నారా?", + "Attachment": "జోడింపు", + "Autoplay GIFs and videos": "స్వీయ జిఐఫ్ లు మరియు వీడియోలు", + "Ban": "బాన్", + "Banned users": "నిషేధించిన వినియోగదారులు", + "Bans user with given id": "ఇచ్చిన ఐడి తో వినియోగదారుని నిషేధించారు", + "Blacklisted": "నిరోధిత జాబితాలోని", + "Bug Report": "బగ్ నివేదిక", + "Bulk Options": "సమూహ ఐచ్ఛికాలు", + "Call Timeout": "కాల్ గడువు ముగిసింది", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "గృహనిర్వాహకులకు కనెక్ట్ చేయలేరు - దయచేసి మీ కనెక్టివిటీని తనిఖీ చేయండి, మీ 1 హోమరుసు యొక్క ఎస్ఎస్ఎల్ సర్టిఫికేట్ 2 ని విశ్వసనీయపరుచుకొని, బ్రౌజర్ పొడిగింపు అభ్యర్థనలను నిరోధించబడదని నిర్ధారించుకోండి.", + "Can't load user settings": "వినియోగదారు సెట్టింగ్లను లోడ్ చేయలేరు", + "Change Password": "పాస్వర్డ్ మార్చండి", + "%(senderName)s changed their profile picture.": "% (SenderName) వారి ప్రొఫైల్ చిత్రాన్ని మార్చారు.", + "%(senderDisplayName)s removed the room name.": "% (SenderDisplayName) s గది పేరు తొలగించబడింది.", + "Changes to who can read history will only apply to future messages in this room": "చరిత్ర చదివేవారికి మార్పులు ఈ గదిలో భవిష్య సందేశాలకు మాత్రమే వర్తిస్తాయి", + "Changes your display nickname": "మీ ప్రదర్శన మారుపేరుని మారుస్తుంది", + "changing room on a RoomView is not supported": "ఒక రూమ్వ్యూలో గది మార్చుకునేకి మద్దతు లేదు", + "You cannot place a call with yourself.": "మీరు మీతో కాల్ చేయలేరు.", + "You are already in a call.": "మీరు ఇప్పటికే కాల్లో ఉన్నారు.", + "You are trying to access %(roomName)s.": "మీరు% (గధిపేరు) లను యాక్సెస్ చేయడానికి ప్రయత్నిస్తున్నారు.", + "You cannot place VoIP calls in this browser.": "మీరు ఈ బ్రౌజర్లో VoIP కాల్లను ఉంచలేరు." } From 33e56de5501dfc86ac377a6c47fb691ecc223cb0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jul 2017 15:05:50 +0000 Subject: [PATCH 024/164] Translated using Weblate (English (United States)) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/en_US/ --- src/i18n/strings/en_US.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index e060add84f..6e7c22189e 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -675,7 +675,7 @@ "quote": "quote", "bullet": "bullet", "numbullet": "numbullet", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sjoined %(repeats)s times", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s joined %(repeats)s times", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sjoined %(repeats)s times", "%(severalUsers)sjoined": "%(severalUsers)sjoined", "%(oneUser)sjoined": "%(oneUser)sjoined", @@ -918,5 +918,17 @@ "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Do you want to set an email address?": "Do you want to set an email address?", - "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications." + "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", + "Press to start a chat with someone": "Press to start a chat with someone", + "You're not in any rooms yet! Press to make a room or to browse the directory": "You're not in any rooms yet! Press to make a room or to browse the directory", + "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", + "Skip": "Skip", + "Start verification": "Start verification", + "Share without verifying": "Share without verifying", + "Ignore request": "Ignore request", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", + "Encryption key request": "Encryption key request", + "Updates": "Updates", + "Check for update": "Check for update" } From b830f82c65edbd6735e772599417db7613fae3a1 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 27 Jun 2017 14:38:53 +0000 Subject: [PATCH 025/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 224 +++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a0db062ddf..1d116761e2 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -192,10 +192,10 @@ "VoIP conference started.": "VoIP-конференция началась.", "(warning: cannot be disabled again!)": "(предупреждение: отключить будет невозможно!)", "Warning!": "Внимание!", - "was banned": "запрещен", - "was invited": "был приглашён", - "was kicked": "выброшен", - "was unbanned": "незапрещенный", + "was banned": "был заблокирован", + "was invited": "был приглашен", + "was kicked": "был выгнан", + "was unbanned": "был разблокирован", "was": "был", "were": "быть", "Who can access this room?": "Кто может получить доступ к этой комнате?", @@ -471,7 +471,7 @@ "Failed to delete device": "Не удалось удалить устройство", "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", - "Failed to join the room": "Не удалось войти в эту комнату", + "Failed to join the room": "Не удалось присоединиться к комнате", "Access Token:": "Токен:", "Always show message timestamps": "Всегда показывать временные метки сообщений", "Authentication": "Авторизация", @@ -607,65 +607,65 @@ "quote": "цитата", "bullet": "список", "numbullet": "нумерованный список", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s вошли %(repeats)s раз", - "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sвошёл %(repeats)s раз", - "%(severalUsers)sjoined": "%(severalUsers)sвошли", - "%(oneUser)sjoined": "%(oneUser)sвошёл", - "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sушли %(repeats)s раз", - "%(oneUser)sleft %(repeats)s times": "%(oneUser)sушли %(repeats)s раз", - "%(severalUsers)sleft": "%(severalUsers)sушли", - "%(oneUser)sleft": "%(oneUser)sушёл", - "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sвошли и ушли %(repeats)s раз", - "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sвошёл и ушёл %(repeats)s раз", - "%(severalUsers)sjoined and left": "%(severalUsers)sвошли и ушли", - "%(oneUser)sjoined and left": "%(oneUser)sвошёл и ушёл", - "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sушли и перезашли %(repeats)s раз", - "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s ушёл и перезашёл %(repeats)s раз", - "%(severalUsers)sleft and rejoined": "%(severalUsers)sушли и перезашли", - "%(oneUser)sleft and rejoined": "%(oneUser)sушёл и перезашёл", - "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)sотклонили приглашения %(repeats)s раз", - "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)sотклонил приглашения %(repeats)s раз", - "%(severalUsers)srejected their invitations": "%(severalUsers)sотклонили приглашения", - "%(oneUser)srejected their invitation": "%(oneUser)sотклонил приглашение", - "were invited %(repeats)s times": "были приглашёны %(repeats)s раз", - "was invited %(repeats)s times": "был приглашён %(repeats)s раз", - "were invited": "были приглашёны", - "were banned %(repeats)s times": "были запрещёны %(repeats)s раз", - "was banned %(repeats)s times": "был запрещён %(repeats)s раз", - "were banned": "были запрещёны", - "were unbanned %(repeats)s times": "были разрешены %(repeats)s раз", - "was unbanned %(repeats)s times": "был разрешён %(repeats)s раз", - "were unbanned": "были разрешены", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s присоединились %(repeats)s раз", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s присоединился %(repeats)s раз", + "%(severalUsers)sjoined": "%(severalUsers)s присоединились", + "%(oneUser)sjoined": "%(oneUser)s присоединился", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s покинули %(repeats)s раз", + "%(oneUser)sleft %(repeats)s times": "%(oneUser)s покинул %(repeats)s раз", + "%(severalUsers)sleft": "%(severalUsers)s покинули", + "%(oneUser)sleft": "%(oneUser)s покинул", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s присоединились и покинули %(repeats)s раз", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s присоединился и покинул %(repeats)s раз", + "%(severalUsers)sjoined and left": "%(severalUsers)s присоединились и покинули", + "%(oneUser)sjoined and left": "%(oneUser)s присоединился и покинул", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s покинули и снова присоединились %(repeats)s раз", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s покинул и снова присоединился %(repeats)s раз", + "%(severalUsers)sleft and rejoined": "%(severalUsers)s покинули и снова присоединились", + "%(oneUser)sleft and rejoined": "%(oneUser)s покинул и снова присоединился", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s отклонили приглашения %(repeats)s раз", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)s отклонил приглашения %(repeats)s раз", + "%(severalUsers)srejected their invitations": "%(severalUsers)s отклонили приглашения", + "%(oneUser)srejected their invitation": "%(oneUser)s отклонил приглашение", + "were invited %(repeats)s times": "были приглашены %(repeats)s раз", + "was invited %(repeats)s times": "был приглашен %(repeats)s раз", + "were invited": "были приглашены", + "were banned %(repeats)s times": "были заблокированы %(repeats)s раз", + "was banned %(repeats)s times": "был заблокирован %(repeats)s раз", + "were banned": "были заблокированы", + "were unbanned %(repeats)s times": "были разблокированы %(repeats)s раз", + "was unbanned %(repeats)s times": "были разблокирован %(repeats)s раз", + "were unbanned": "были разблокированы", "were kicked %(repeats)s times": "были выгнаны %(repeats)s раз", "was kicked %(repeats)s times": "был выгнан %(repeats)s раз", "were kicked": "были выгнаны", - "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)sизменили имена %(repeats)s раз", - "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sизменил имя %(repeats)s раз", - "%(severalUsers)schanged their name": "%(severalUsers)sизменили имя", - "%(oneUser)schanged their name": "%(oneUser)sизменил имя", - "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)sизменили своё изображение %(repeats)s раз", - "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sизменил своё изображение %(repeats)s раз", - "%(severalUsers)schanged their avatar": "%(severalUsers)sизменили своё изображение", - "%(oneUser)schanged their avatar": "%(oneUser)sизменил своё изображение", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)s изменили имена %(repeats)s раз", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)s изменил имя %(repeats)s раз", + "%(severalUsers)schanged their name": "%(severalUsers)s изменили имена", + "%(oneUser)schanged their name": "%(oneUser)s изменил имя", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)s изменили свои аватары %(repeats)s раз", + "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)s изменил свой аватар %(repeats)s раз", + "%(severalUsers)schanged their avatar": "%(severalUsers)s изменили свои аватары", + "%(oneUser)schanged their avatar": "%(oneUser)s изменил свой ававтар", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отказ", - "Custom Server Options": "Собственные настройки сервера", + "Custom Server Options": "Настраиваемые параметры сервера", "Mute": "Беззвучный", - "Operation failed": "Не удалось выполнить операцию", + "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30pm)", "Use compact timeline layout": "Использовать компактный макет временной шкалы", "Hide removed messages": "Скрыть удаленные сообщения", "No Microphones detected": "Микрофоны не обнаружены", - "Unknown devices": "Незнакомое устройство", + "Unknown devices": "Неизвестное устройство", "Camera": "Камера", "Microphone": "Микрофон", "Desktop specific": "Специфический десктоп", - "Start automatically after system login": "Автостарт после входа в систему", + "Start automatically after system login": "Автоматический запуск после подключения", "Analytics": "Аналитика", - "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, чтобы улучшить эту программу.", - "Opt out of analytics": "Подтвердить отказ передачи аналитических данных", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", + "Opt out of analytics": "Не собирать аналитические данные", "Logged in as:": "Вы вошли как:", "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", @@ -769,101 +769,101 @@ "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s отозвал свои приглашения %(repeats)s раз", "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s отозвали свои приглашения", "%(oneUser)shad their invitation withdrawn": "%(oneUser)s отозвал свое приглашение", - "Please select the destination room for this message": "Выберите комнату назначения для этого сообщения", + "Please select the destination room for this message": "Выберите комнату для отправки этого сообщения", "Options": "Настройки", - "Passphrases must match": "Пароли должны совпадать", - "Passphrase must not be empty": "Пароль не должен быть пустым", - "Export room keys": "Экспортировать ключи", + "Passphrases must match": "Парольные фразы должны совпадать", + "Passphrase must not be empty": "Парольная фраза не должна быть пустой", + "Export room keys": "Экспорт ключей комнаты", "Enter passphrase": "Введите парольную фразу", - "Confirm passphrase": "Подтвердите пароль", - "Import room keys": "Импортировать ключи", + "Confirm passphrase": "Подтвердите парольную фразу", + "Import room keys": "Импорт ключей комнаты", "File to import": "Файл для импорта", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Этот процесс позволяет вам экспортировать ключи для сообщений, которые вы получили в комнатах с шифрованием, в локальный файл. Вы сможете импортировать эти ключи в другой клиент Matrix чтобы расшифровать эти сообщения.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому вы должны ввести пароль, который будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная этот пароль.", - "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Этот процесс позволяем вам импортировать ключи шифрования, которые вы экспортировали ранее из клиента Matrix. После импорта вы сможете читать зашифрованную переписку и отправлять шифрованные сообщения.", - "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Экспортированный файл защищен паролем. Вы должны ввести этот пароль для расшифровки.", - "You must join the room to see its files": "Вы должны зайти в комнату для просмотра файлов", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому вы должны ввести парольную фразу ниже, которая будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная эту парольную фразу.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Этот процесс позволит вам импортировать ключи шифрования, которые вы экспортировали ранее из клиента Matrix. Это позволит вам расшифровать историю чата.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Файл экспорта будет защищен паролем. Для расшифровки файла необходимо ввести парольную фразу.", + "You must join the room to see its files": "Вы должны присоединиться к комнате, чтобы просмотреть файлы", "Reject all %(invitedRooms)s invites": "Отклонить все %(invitedRooms)s приглашения", "Start new chat": "Начать новый чат", "Guest users can't invite users. Please register.": "Гости не могут приглашать пользователей. Пожалуйста, зарегистрируйтесь.", - "Failed to invite": "Ошибка приглашения", - "Failed to invite user": "Ошибка приглашения пользователя", - "Failed to invite the following users to the %(roomName)s room:": "Ошибка приглашения следующих пользователей в %(roomName)s:", + "Failed to invite": "Пригласить не удалось", + "Failed to invite user": "Не удалось пригласить пользователя", + "Failed to invite the following users to the %(roomName)s room:": "Не удалось пригласить следующих пользователей в %(roomName)s:", "Confirm Removal": "Подтвердите удаление", - "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Вы уверены, что хотите удалить этот событие? Обратите внимание, что если это смена имени комнаты или топика, то удаление отменит это изменение.", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Вы действительно хотите удалить это событие? Обратите внимание, что если это смена названия комнаты или темы, то удаление отменит это изменение.", "Unknown error": "Неизвестная ошибка", - "Incorrect password": "Неправильный пароль", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Это сделает вашу учетную запись нерабочей. Вы не сможете зарегистрироваться снова с тем же ID.", + "Incorrect password": "Неверный пароль", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Таким образом, ваша учетная запись будет заблокирована навсегда. Вы не сможете зарегистрироваться снова с тем же идентификатором пользователя.", "This action is irreversible.": "Это действие необратимо.", "To continue, please enter your password.": "Для продолжения введите ваш пароль.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Для верификации устройства, пожалуйста, свяжитесь с владельцем используя другие методы коммуникации (например, лично или по телефону) и попросите его подтвердить, что он видит такой же ключ как написанный ниже:", "Device name": "Имя устройства", "Device key": "Ключ устройства", - "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, то кто-то перехватил это устройство или ключ и вы, скорее всего, захотите внести его в черный список.", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, то кто-то перехватил это устройство и вы, скорее всего, захотите внести его в черный список.", "In future this verification process will be more sophisticated.": "В будущем процесс верификации будет усложнен.", "Verify device": "Верифицировать устройство", - "I verify that the keys match": "Я верифицирую - ключи совпадают", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Обнаружена ошибка при восстановлении вашей предыдущей сессии. Вам необходимо зайти снова, шифрованные сообщения будут нечитаемы.", - "Unable to restore session": "Невозможно восстановить сессию", + "I verify that the keys match": "Я подтверждаю, что ключи совпадают", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Произошла ошибка при попытке восстановить предыдущий сеанс. Если продолжить, потребуется снова войти в систему, а зашифрованная история чата будет нечитаема.", + "Unable to restore session": "Восстановление сессии не удалось", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию Riot, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.", "Continue anyway": "Все равно продолжить", "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Отображаемое имя - это то, как вы отображаетесь в чате. Какое имя вы хотите?", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Пока что вы вносите неверифицированные устройства в черный список автоматически. Для отправки сообщений на эти устройства вам необходимо их верифицировать.", - "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Рекомендуется сначала верифицировать устройства для подтверждения их владения правильным пользователем, но вы можете отправить сообщение без верификации, если хотите.", - "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неизвестные прежде устройства.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Ваши текущие неверифицированные занесенные в черный список устройства; для отправки сообщений на эти устройства вам необходимо их верифицировать.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Мы рекомендуем вам выполнить процедуру проверки для каждого устройства, чтобы подтвердить, что они принадлежат их законному владельцу, но вы можете отправить сообщение без проверки, если хотите.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неподтвержденные устройства.", "Unknown Address": "Неизвестный адрес", "Unblacklist": "Удалить из черного списка", "Blacklist": "Черный список", - "Unverify": "Убрать верификацию", + "Unverify": "Отменить верификацию", "Verify...": "Верифицировать...", "ex. @bob:example.com": "например @bob:example.com", "Add User": "Добавить пользователя", - "This Home Server would like to make sure you are not a robot": "Этот Home Server хочет удостовериться что вы не робот", + "This Home Server would like to make sure you are not a robot": "Этот домашний сервер хочет убедиться, что вы не робот", "Sign in with CAS": "Войти с помощью CAS", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Вы можете использовать пользовательские настройки сервера для использования другого Home Server'а при помощи указания его URL.", - "This allows you to use this app with an existing Matrix account on a different home server.": "Это позволяет использовать это приложение с существующей учетной записью на другом Home Server'е.", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете указать пользовательский сервер идентификации, но это обычно ломает возможность общаться с пользователями с помощью адреса email.", - "Please check your email to continue registration.": "Проверьте свою почту для продолжения регистрации.", - "Token incorrect": "Неправильный токен", - "A text message has been sent to": "Текстовое сообщение было отправлено", - "Please enter the code it contains:": "Введите содержащийся код:", - "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если вы не укажете адрес email, то вы не сможете сбросить свой пароль в будущем. Вы уверены?", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Вы можете использовать настраиваемые параметры сервера для входа на другие серверы Matrix, указав другой URL-адрес домашнего сервера.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Это позволяет использовать это приложение с существующей учетной записью Matrix на другом домашнем сервере.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса электронной почты.", + "Please check your email to continue registration.": "Проверьте электронную почту, чтобы продолжить регистрацию.", + "Token incorrect": "Неверный токен", + "A text message has been sent to": "Текстовое сообщение отправлено", + "Please enter the code it contains:": "Введите полученный код:", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если адрес электронной почты не указан, сброс пароля будет невозможным. Уверены?", "You are registering with %(SelectedTeamName)s": "Вы регистрируетесь на %(SelectedTeamName)s", - "Default server": "Сервер по-умолчанию", + "Default server": "Сервер по умолчанию", "Custom server": "Пользовательский сервер", - "Home server URL": "URL Home Server'а", - "Identity server URL": "URL сервера идентификации", + "Home server URL": "URL-адрес домашнего сервера", + "Identity server URL": "URL-адрес сервера идентификации", "What does this mean?": "Что это значит?", "Error decrypting audio": "Ошибка расшифровки аудио", "Error decrypting image": "Ошибка расшифровки изображения", "Image '%(Body)s' cannot be displayed.": "Изображение '%(Body)s' не может быть отображено.", - "This image cannot be displayed.": "Это изображение не может быть отображено.", + "This image cannot be displayed.": "Не удается отобразить изображение.", "Error decrypting video": "Ошибка расшифровки видео", "Add an Integration": "Добавить интеграцию", - "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Вы будете перенаправлены на внешний сайт, где вы сможете аутентифицировать свою учетную запись для использования с %(integrationsUrl)s. Вы хотите продолжить?", - "Removed or unknown message type": "Удалено или тип сообщения неизвестен", - "Disable URL previews by default for participants in this room": "Отключить предпросмотр URL для участников этой комнаты по-умолчанию", - "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Предпросмотр URL %(globalDisableUrlPreview)s по-умолчанию для участников этой комнаты.", - "URL Previews": "Предпросмотр URL", - "Enable URL previews for this room (affects only you)": "Включить предпросмотр URL в этой комнате (только для вас)", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Вы будете пернаправлены на внешний сайт, где сможете аутентифицировать свою учетную запись для использования с %(integrationsUrl)s. Продолжить?", + "Removed or unknown message type": "Удалено или неизвестный тип сообщения", + "Disable URL previews by default for participants in this room": "Отключить предварительный просмотр URL-адресов по умолчанию для участников этой комнаты", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Предварительный просмотр URL-адресов %(globalDisableUrlPreview)s по умолчанию для участников этой комнаты.", + "URL Previews": "Предварительный просмотр URL-адресов", + "Enable URL previews for this room (affects only you)": "Включить предварительный просмотр URL-адресов для этой комнаты (влияет только на вас)", "Drop file here to upload": "Перетащите файл сюда для загрузки", " (unsupported)": " (не поддерживается)", - "Ongoing conference call%(supportedText)s.": "Идет конференц-звонок%(supportedText)s.", - "for %(amount)ss": "уже %(amount)sс", - "for %(amount)sm": "уже %(amount)sм", - "for %(amount)sh": "уже %(amount)sч", - "for %(amount)sd": "уже %(amount)sд", + "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", + "for %(amount)ss": "уже %(amount)sсек", + "for %(amount)sm": "уже %(amount)sмин", + "for %(amount)sh": "уже %(amount)sчас", + "for %(amount)sd": "уже %(amount)sдн", "Online": "В сети", - "Idle": "Отошел", + "Idle": "Неактивен", "Offline": "Не в сети", - "Disable URL previews for this room (affects only you)": "Отключить предпросмотр URL в этой комнате (только для вас)", + "Disable URL previews for this room (affects only you)": "Отключить предварительный просмотр URL-адресов для этой комнаты (влияет только на вас)", "$senderDisplayName changed the room avatar to ": "$senderDisplayName сменил аватар комнаты на ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s удалил аватар комнаты.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s сменил аватар для %(roomName)s", "Create new room": "Создать новую комнату", "Room directory": "Каталог комнат", "Start chat": "Начать чат", - "Welcome page": "Домашняя страница", + "Welcome page": "Страница приветствия", "Add": "Добавить", "%(count)s new messages.one": "%(count)s новое сообщение", "%(count)s new messages.other": "%(count)s новых сообщений", @@ -880,14 +880,14 @@ "New Password": "Новый пароль", "Start chatting": "Начать общение", "Start Chatting": "Начать общение", - "Click on the button below to start chatting!": "Нажмите на кнопку ниже для того, чтобы начать общение!", + "Click on the button below to start chatting!": "Нажмите на кнопку ниже, чтобы начать общение!", "Create a new chat or reuse an existing one": "Создайте новый чат или используйте существующий", "You already have existing direct chats with this user:": "У вас уже есть прямые чаты с этим пользователем:", "Username available": "Имя пользователя доступно", "Username not available": "Имя пользователя недоступно", "Something went wrong!": "Что-то пошло не так!", - "This will be your account name on the homeserver, or you can pick a different server.": "Это будет ваше имя пользователя на , или вы можете выбрать другой сервер.", - "If you already have a Matrix account you can log in instead.": "Если вы уже имеете учетную запись Matrix, то вы можете войти.", + "This will be your account name on the homeserver, or you can pick a different server.": "Это будет имя вашей учетной записи на домашнем сервере, или вы можете выбрать другой сервер.", + "If you already have a Matrix account you can log in instead.": "Если у вас уже есть учетная запись Matrix, вы можете войти.", "Home": "Старт", "a room": "комната", "Accept": "Принять", @@ -953,21 +953,21 @@ "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", - "Not a valid Riot keyfile": "Не действительный файл ключа Riot", - "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые расширения для криптографии", - "Authentication check failed: incorrect password?": "Ошибка авторизации: неверный пароль?", - "Do you want to set an email address?": "Вы хотите указать адрес электронной почты?", - "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления.", + "Not a valid Riot keyfile": "Недействительный ключевой файл Riot", + "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", + "Authentication check failed: incorrect password?": "Ошибка авторизации: неправильный пароль?", + "Do you want to set an email address?": "Хотите указать адрес электронной почты?", + "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или для просмотра каталога", - "To return to your account in future you need to set a password": "Чтобы в будущем к этой учётной записи вернутся, вы должны ввести пароль", - "Skip": "Пропуск", - "Start verification": "Запуск проверки", + "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", + "Skip": "Пропустить", + "Start verification": "Начать верификацию", "Share without verifying": "Поделиться без проверки", "Ignore request": "Игнорировать запрос", - "You added a new device '%(displayName)s', which is requesting encryption keys.": "Вы добавили новое устройство '%(displayName)s', который запрашивает ключи шифрования.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Вы добавили новое устройство '%(displayName)s', которое требует ключи шифрования.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваше непроверенное устройство '%(displayName)s' запрашивает ключи шифрования.", "Encryption key request": "Запрос ключа шифрования", "Updates": "Обновления", - "Check for update": "Проверить обновление" + "Check for update": "Проверить наличие обновлений" } From a05dbb1994f3c84b3ad0bb3a722ef25b8077edb4 Mon Sep 17 00:00:00 2001 From: Dreamwhite Date: Thu, 29 Jun 2017 10:53:02 +0000 Subject: [PATCH 026/164] Translated using Weblate (Italian) Currently translated at 1.0% (10 of 915 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 9e26dfeeb6..415761e2fa 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -1 +1,12 @@ -{} \ No newline at end of file +{ + "Failed to forget room %(errCode)s": "Errore nel dimenticare la stanza %(errCode)", + "Mute": "Muta", + "Notifications": "Notifiche", + "Operation failed": "Operazione fallita", + "Please Register": "Per favore registrati", + "powered by Matrix": "powered by Matrix", + "Remove": "Rimuovi", + "Search": "Cerca", + "Settings": "Impostazioni", + "Start chat": "Avvia una chat" +} From 9d56cbcf8f09401e57bb72adf3754cd5a410dd5b Mon Sep 17 00:00:00 2001 From: Sri Lakshmi Date: Wed, 12 Jul 2017 14:43:13 +0000 Subject: [PATCH 027/164] Translated using Weblate (Telugu) Currently translated at 25.7% (236 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/te/ --- src/i18n/strings/te.json | 49 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index 8744dff7da..2bde9341ac 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -187,5 +187,52 @@ "You cannot place a call with yourself.": "మీరు మీతో కాల్ చేయలేరు.", "You are already in a call.": "మీరు ఇప్పటికే కాల్లో ఉన్నారు.", "You are trying to access %(roomName)s.": "మీరు% (గధిపేరు) లను యాక్సెస్ చేయడానికి ప్రయత్నిస్తున్నారు.", - "You cannot place VoIP calls in this browser.": "మీరు ఈ బ్రౌజర్లో VoIP కాల్లను ఉంచలేరు." + "You cannot place VoIP calls in this browser.": "మీరు ఈ బ్రౌజర్లో VoIP కాల్లను ఉంచలేరు.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "మీరు అన్ని పరికరాల నుండి లాగ్ అవుట్ అయ్యారు మరియు ఇకపై పుష్ ఉండదు.\nప్రకటనలను నోటిఫికేషన్లను పునఃప్రారంభించడానికి, ప్రతి పరికరంలో మళ్లీ సైన్ ఇన్ చేయండి", + "You have no visible notifications": "మీకు కనిపించే నోటిఫికేషన్లు లేవు", + "you must be a": "మీరు తప్పక", + "You need to be able to invite users to do that.": "మీరు దీన్ని చేయడానికి వినియోగదారులను ఆహ్వానించగలరు.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "పాస్ వర్డ్ మార్చడం వల్ల ప్రస్తుతం అన్ని పరికరాల్లో ఏదైనా ఎండ్-టు-ఎండ్ ఎన్క్రిప్షన్ కీలను రీసెట్ చేస్తుంది, ఎన్క్రిప్టెడ్ చాట్ చరిత్రను చదవటానికి వీలెకుండ చెస్తుంది, మీరు మొదట మీ గది కీలను ఎగుమతి చేసి, తర్వాత వాటిని తిరిగి దిగుమతి చేసుకోకపోతే. భవిష్యత్తులో ఇది మెరుగవుతుంది.", + "Claimed Ed25519 fingerprint key": "ఎడ్25519 వేలిముద్ర కీ ని పేర్కొన్నారు", + "Clear Cache and Reload": "కాష్ ని క్లియర్ చెసి రీలోడ్ చెయండి", + "Clear Cache": "క్లియర్ కాష్", + "Click here to join the discussion!": "ఇక్కడ నొక్కండి చర్చలో చేరడానికి!", + "Click here to fix": "పరిష్కరించడానికి ఇక్కడ క్లిక్ చేయండి", + "Click to mute audio": "ఆడియోను మ్యూట్ చేయడానికి క్లిక్ చేయండి", + "Click to mute video": "వీడియో మ్యూట్ చేయడానికి క్లిక్ చేయండి", + "click to reveal": "బహిర్గతం చెయుటకు క్లిక్ చేయండి", + "Click to unmute video": "వీడియోను అన్మ్యూట్ చేయడానికి క్లిక్ చేయండి", + "Click to unmute audio": "ఆడియోని అన్మ్యూట్ చేయడానికి క్లిక్ చేయండి", + "Close": "ముసివెయండి", + "Command error": "కమాండ్ లోపం", + "Commands": "కమ్మండ్స్", + "Conference call failed.": "కాన్ఫరెన్స్ కాల్ విఫలమైంది.", + "Conference calling is in development and may not be reliable.": "కాన్ఫరెన్స్ కాలింగ్ అభివృద్ధిలో ఉండటం వల్ల విశ్వసనీయంగా ఉండకపోవచ్చు.", + "Conference calls are not supported in encrypted rooms": "గుప్తీకరించిన గదులలో కాన్ఫరెన్స్ కాల్లకు మద్దతు లేదు", + "Conference calls are not supported in this client": "ఈ క్లయింట్లో కాన్ఫరెన్స్ కాల్లకు మద్దతు లేదు", + "Confirm password": "పాస్వర్డ్ని నిర్ధారించండి", + "Confirm your new password": "మీ క్రొత్త పాస్వర్డ్ను నిర్ధారించండి", + "Continue": "కొనసాగించు", + "Could not connect to the integration server": "ఇంటిగ్రేషన్ సర్వర్కు కనెక్ట్ చేయడం సాధ్యం కాలేదు", + "%(count)s new messages.one": "% (లెక్కింపు) కొత్త సందేశం", + "%(count)s new messages.other": "% (లెక్కింపు) కొత్త సందేశాలు", + "Create a new chat or reuse an existing one": "క్రొత్త చాట్ ను సృష్టించుకోండి లేదా ఇప్పటికే ఉన్న ఒకదాన్ని తిరిగి ఉపయోగించండి", + "Create an account": "ఒక ఎకౌంటు ను సృష్టించండి", + "Create Room": "రూమ్ ని సృష్టించండి", + "Cryptography": "క్రిప్టోగ్రఫీ", + "Current password": "ప్రస్తుత పాస్వర్డ్", + "Curve25519 identity key": "Curve25519 గుర్తింపు కీ", + "Custom": "కస్టమ్", + "Custom level": "అనుకూల స్థాయి", + "/ddg is not a command": "/ ddg కమాండ్ కాదు", + "Deactivate Account": "ఖాతాను డీయాక్టివేట్ చేయండి", + "Deactivate my account": "నా ఖాతాను డీయాక్టివేట్ చేసుకోండి", + "Decline": "డిక్లైన్", + "Decryption error": "గుప్తలేఖన లోపం", + "Delete": "తొలగించు", + "demote": "స్థానానికి తగ్గించు", + "Deops user with given id": "ఇచ్చిన ID తో వినియోగదారుని విడదీస్తుంది", + "Default": "డిఫాల్ట్", + "Device already verified!": "పరికరం ఇప్పటికే ధృవీకరించబడింది!", + "Devices": "పరికరాలు" } From c668e754f143e205469dc2bcda956f529f77aa2f Mon Sep 17 00:00:00 2001 From: Alexey Murz Korepov Date: Wed, 12 Jul 2017 07:35:55 +0000 Subject: [PATCH 028/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 1d116761e2..1b9ed708aa 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -229,8 +229,8 @@ "Call Timeout": "Время ожидания вызова", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s изменено с %(oldDisplayName)s на %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s изменил фото профиля.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s уровень мощности изменен на %(powerLevelDiffText)s.", - "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s имя комнаты изменено на %(roomName)s.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровень доступа для %(powerLevelDiffText)s.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s изменил(а) название комнаты на %(roomName)s.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил тему на %(topic)s.", "Conference call failed.": "Не удалось выполнить групповой вызов.", "Conference calling is in development and may not be reliable.": "Групповые вызовы находятся в разработке и могут быть нестабильны.", @@ -246,7 +246,7 @@ "Failed to set up conference call": "Не удалось настроить групповой вызов", "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес электронной почты: убедитесь что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", - "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s до %(toPowerLevel)s", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "Guest users can't create new rooms. Please register to create room and start a chat.": "Гости не могут создавать новые комнаты. Зарегистрируйтесь, чтобы создать комнату и начать чат.", "click to reveal": "нажмите для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", @@ -661,7 +661,7 @@ "Unknown devices": "Неизвестное устройство", "Camera": "Камера", "Microphone": "Микрофон", - "Desktop specific": "Специфический десктоп", + "Desktop specific": "Локальные настройки", "Start automatically after system login": "Автоматический запуск после подключения", "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", @@ -927,7 +927,7 @@ "Room contains unknown devices": "Комната содержит непроверенные устройства", "%(roomName)s does not exist.": "%(roomName)s не существует.", "%(roomName)s is not accessible at this time.": "%(roomName)s на данный момент недоступна.", - "Seen by %(userName)s at %(dateTime)s": "Видели %(userName)s в %(dateTime)s", + "Seen by %(userName)s at %(dateTime)s": "Просмотрено %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес электронной почты, не связанный с этой учетной записью:", From 57be0cf23d5d75942bbb18dd789af0d61585eb2a Mon Sep 17 00:00:00 2001 From: Lauris Mierkalns Date: Mon, 17 Jul 2017 03:12:22 +0000 Subject: [PATCH 029/164] Added translation using Weblate (Latvian) --- src/i18n/strings/lv.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/lv.json diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/lv.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 206c771eb1967dfbabc72cbd0a730931e2c9d6cd Mon Sep 17 00:00:00 2001 From: LuPa Date: Mon, 10 Jul 2017 04:16:17 +0000 Subject: [PATCH 030/164] Translated using Weblate (Spanish) Currently translated at 68.2% (625 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 926f7a4f68..ca5ac15133 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -150,8 +150,8 @@ "%(senderName)s answered the call.": "%(senderName)s atendió la llamada.", "anyone": "nadie", "An error has occurred.": "Un error ha ocurrido.", - "Anyone who knows the room's link, apart from guests": "Nadie quien sepa el enlace de la sala, aparte de los invitados", - "Anyone who knows the room's link, including guests": "Nadie quien sepa del enlace de la sala, incluyendo los invitados", + "Anyone who knows the room's link, apart from guests": "Cualquiera que sepa el enlace de la sala, salvo invitados", + "Anyone who knows the room's link, including guests": "Cualquiera que sepa del enlace de la sala, incluyendo los invitados", "Are you sure?": "¿Estás seguro?", "Are you sure you want to reject the invitation?": "¿Estás seguro que quieres rechazar la invitación?", "Are you sure you want upload the following files?": "¿Estás seguro que quieres subir los siguientes archivos?", From 0cc890c02043445e077f8b6cba93a5ba431b071c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 20 Jul 2017 18:01:39 +0100 Subject: [PATCH 031/164] WIP store history as raw content state Not sure this solves any problems because we still have to convert from md and back --- src/ComposerHistoryManager.js | 32 +++++++++++-------- .../views/rooms/MessageComposerInput.js | 13 +++----- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/ComposerHistoryManager.js b/src/ComposerHistoryManager.js index 1ae836574b..ee2c748dc6 100644 --- a/src/ComposerHistoryManager.js +++ b/src/ComposerHistoryManager.js @@ -15,36 +15,40 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {ContentState} from 'draft-js'; +import {ContentState, convertToRaw, convertFromRaw} from 'draft-js'; import * as RichText from './RichText'; import Markdown from './Markdown'; -import _flow from 'lodash/flow'; import _clamp from 'lodash/clamp'; type MessageFormat = 'html' | 'markdown'; class HistoryItem { - message: string = ''; + + // Keeping message for backwards-compatibility + message: string; + rawContentState: RawDraftContentState; format: MessageFormat = 'html'; - constructor(message: string, format: MessageFormat) { - this.message = message; + constructor(contentState: ?ContentState, format: ?MessageFormat) { + this.rawContentState = contentState ? convertToRaw(contentState) : null; this.format = format; } - toContentState(format: MessageFormat): ContentState { - let {message} = this; - if (format === 'markdown') { + toContentState(outputFormat: MessageFormat): ContentState { + const contentState = convertFromRaw(this.rawContentState); + if (outputFormat === 'markdown') { if (this.format === 'html') { - message = _flow([RichText.htmlToContentState, RichText.stateToMarkdown])(message); + console.info(outputFormat, 'to other format'); + return ContentState.createFromText(RichText.stateToMarkdown(contentState)); } - return ContentState.createFromText(message); } else { if (this.format === 'markdown') { - message = new Markdown(message).toHTML(); + console.info(outputFormat, 'to other format'); + return RichText.htmlToContentState(new Markdown(contentState).toHTML()); } - return RichText.htmlToContentState(message); } + // history item has format === outputFormat + return contentState; } } @@ -67,8 +71,8 @@ export default class ComposerHistoryManager { this.lastIndex = this.currentIndex; } - addItem(message: string, format: MessageFormat) { - const item = new HistoryItem(message, format); + save(contentState: ContentState, format: MessageFormat) { + const item = new HistoryItem(contentState, format); this.history.push(item); this.currentIndex = this.lastIndex + 1; sessionStorage.setItem(`${this.prefix}[${this.lastIndex++}]`, JSON.stringify(item)); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3165765167..06c854a69f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -762,15 +762,10 @@ export default class MessageComposerInput extends React.Component { let sendHtmlFn = this.client.sendHtmlMessage; let sendTextFn = this.client.sendTextMessage; - if (this.state.isRichtextEnabled) { - this.historyManager.addItem( - contentHTML ? contentHTML : contentText, - contentHTML ? 'html' : 'markdown', - ); - } else { - // Always store MD input as input history - this.historyManager.addItem(contentText, 'markdown'); - } + this.historyManager.save( + contentState, + this.state.isRichtextEnabled ? 'html' : 'markdown', + ); if (contentText.startsWith('/me')) { contentText = contentText.substring(4); From 511ab7c9ea0bfe8b541b229160aea01318e54d5c Mon Sep 17 00:00:00 2001 From: Alexandre Morignot Date: Sat, 8 Jul 2017 16:38:47 +0000 Subject: [PATCH 032/164] Translated using Weblate (French) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 785ff29be2..20c28cdecc 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -931,7 +931,7 @@ "Share without verifying": "Partager sans vérifier", "Ignore request": "Ignorer la requête", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Vous avez ajouté un nouvel appareil, '%(displayName)s', qui demande des clés de chiffrement.", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Votre appareil non vérifié '%(displayName)s' demande des clés de chiffrements", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Votre appareil non vérifié '%(displayName)s' demande des clés de chiffrements.", "Encryption key request": "Requête de clé de chiffrement", "Updates": "Mises à jour", "Check for update": "Rechercher une mise à jour" From 3631870c969fc255717c28a358013ac1e374855c Mon Sep 17 00:00:00 2001 From: Lauris Mierkalns Date: Sat, 22 Jul 2017 03:04:49 +0000 Subject: [PATCH 033/164] Translated using Weblate (Latvian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 919 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 918 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 9e26dfeeb6..6d485a35dd 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -1 +1,918 @@ -{} \ No newline at end of file +{ + "af": "Afrikandu", + "ar-ae": "Arābu (A.A.E.)", + "ar-bh": "Arābu (Bahraina)", + "ar-dz": "Arābu (Alžīrija)", + "ar-eg": "Arābu (Ēģipte)", + "ar-iq": "Arābu (Irāka)", + "ar-jo": "Arābu (Jordāna)", + "ar-kw": "Arābu (Kuveita)", + "ar-lb": "Arābu (Lebanēna)", + "ar-ly": "Arābu (Lībija)", + "ar-ma": "Arābu (Maroka)", + "ar-om": "Arābu (Omāna)", + "ar-qa": "Arābu (Kvatara)", + "ar-sa": "Arābu (Saūda Arābija)", + "ar-sy": "Arābu (Sīrija)", + "ar-tn": "Arābu (Tunisija)", + "ar-ye": "Arābu (Jemena)", + "be": "Baltkrievu", + "bg": "Bulgāru", + "ca": "Katalāņu", + "cs": "Čehu", + "da": "Dāņu", + "de-at": "Vācu (Austrija)", + "de-ch": "Vācu (Šveice)", + "de": "Vācu", + "de-li": "Vācu (Lihtenšteina)", + "de-lu": "Vācu (Luksemburga)", + "el": "Grieķu", + "en-au": "Angļu (Austrālija)", + "en-bz": "Angļu (Beliza)", + "en-ca": "Angļu (Kanāda)", + "en": "Angļu", + "en-gb": "Angļu (Apvienotā Karaliste)", + "en-ie": "Angļu (Īrija)", + "en-jm": "Angļu (Jamaika)", + "en-nz": "Angļu (Jaunzēlande)", + "en-tt": "Angļu (Trinidāda)", + "en-us": "Angļu (ASV)", + "en-za": "Angļu (Dienvidāfrika)", + "es-ar": "Spāņu (Argentīna)", + "es-bo": "Spāņu (Bolīvija)", + "es-cl": "Spāņu (Čīle)", + "es-co": "Spāņu (Kolumbija)", + "es-cr": "Spāņu (Kostarika)", + "es-do": "Spāņu (Dominikānas Republika)", + "es-ec": "Spāņu (Ekvadora)", + "es-gt": "Spāņu (Gvatemala)", + "es-hn": "Spāņu (Hondurasa)", + "es-mx": "Spāņu (Meksika)", + "es-ni": "Spāņu (Nikaragva)", + "es-pa": "Spāņu (Panama)", + "es-pe": "Spāņu (Peru)", + "es-pr": "Spāņu (Puertoriko)", + "es-py": "Spāņu (Paragvaja)", + "es": "Spāņu (Spānija)", + "es-sv": "Spāņu (Salvadora)", + "es-uy": "Spāņu (Urugvaja)", + "es-ve": "Spāņu (Venecuēla)", + "et": "Igauņu", + "eu": "Basku (Basku Zeme)", + "fa": "Farsi", + "fi": "Somu", + "fo": "Fēriešu", + "fr-be": "Franču (Beļģija)", + "fr-ca": "Franču (Kanāda)", + "fr-ch": "Franču (Šveice)", + "fr": "Franču", + "fr-lu": "Franču (Luksemburga)", + "ga": "Īru", + "gd": "Gallu (Skotija)", + "he": "Ebreju", + "hi": "Hindi", + "hr": "Kroātu", + "hu": "Ungāru", + "id": "Indonēziešu", + "is": "Islandiešu", + "it-ch": "Itāļu (Šveice)", + "it": "Itāļu", + "ja": "Japāņu", + "ji": "Jidišs", + "ko": "Korejiešu", + "lt": "Lietuviešu", + "lv": "Latviešu", + "mk": "Maķedoniešu (FYROM)", + "ms": "Malaiziešu", + "mt": "Maltiešu", + "nl-be": "Nīderlandiešu (Beļģija)", + "nl": "Nīderlandiešu", + "no": "Norvēģu", + "pl": "Poļu", + "pt-br": "Brazīlijas portugāļu", + "pt": "Portugāļu", + "rm": "Rhaeto-Rumāņu", + "ro-mo": "Rumāņu (Moldovas Republika)", + "ro": "Rumāņu", + "ru-mo": "Krievu (Moldovas Republika)", + "ru": "Krievu", + "sb": "Sorbu", + "sk": "Slovāku", + "sl": "Slovēņu", + "sq": "Albāniešu", + "sr": "Serbu", + "sv-fi": "Zviedru (Somija)", + "sv": "Zviedru", + "sx": "Sutu", + "sz": "Sāmu (Lapu)", + "th": "Taju", + "tn": "Cvanu", + "tr": "Turku", + "ts": "Congu", + "uk": "Ukraiņu", + "ur": "Urdu", + "ve": "Vendu", + "vi": "Vjetnamiešu", + "xh": "Khosu", + "zh-cn": "Ķīniešu (ĶTR)", + "zh-hk": "Ķīniešu (Honkongas SAR)", + "zh-sg": "Ķīniešu (Singapūra)", + "zh-tw": "Ķīniešu (Taivāna)", + "zu": "Zulu", + "a room": "istaba", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Teksta ziņa tika nosūtīta +%(msisdn)s. Lūdzu ievadi tajā atrodamo verifikācijas kodu", + "Accept": "Apstiprināt", + "%(targetName)s accepted an invitation.": "%(targetName)s apstiprināja uzaicinājumu.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s apstiprināja uzaicinājumu no %(displayName)s.", + "Account": "Konts", + "Access Token:": "Pieejas atslēga:", + "Active call (%(roomName)s)": "Aktīvs zvans (%(roomName)s)", + "Add": "Pievienot", + "Add a topic": "Pievieno tematu", + "Add email address": "Pievieno Epasta adresi", + "Add phone number": "Pievieno tālruņa numuru", + "Admin": "Administrators", + "Admin tools": "Administratora rīki", + "And %(count)s more...": "Un vēl %(count)s citi...", + "VoIP": "VoIP", + "Missing Media Permissions, click here to request.": "Nav pieejas medija saturam. Klikšķini šeit, lai pieprasītu.", + "No Microphones detected": "Mikrofoni nav atrasti", + "No Webcams detected": "Webkameras nav atrastas", + "No media permissions": "Nav pieejas mediju saturam", + "You may need to manually permit Riot to access your microphone/webcam": "Tev varētu būt nepieciešams manuāli atļaut Riot pieslēgties tavam mikrofonam/webkamerai", + "Default Device": "Noklusējuma ierīce", + "Microphone": "Mikrofons", + "Camera": "Kamera", + "Advanced": "Īpašie", + "Algorithm": "Algoritms", + "Hide removed messages": "Slēpt dzēstos ziņojumus", + "Always show message timestamps": "Vienmēr rādīt ziņojumu laika zīmogu", + "Authentication": "Autentifikācija", + "Alias (optional)": "Aizstājējvārds (neobligāts)", + "all room members": "visi istabas biedri", + "all room members, from the point they are invited": "visi istabas biedri secībā, kādā tika uzaicināti", + "all room members, from the point they joined": "visi istabas biedri secībā, kādā ir pievienojušies", + "and": "un", + "%(items)s and %(remaining)s others": "%(items)s un %(remaining)s citi", + "%(items)s and one other": "%(items)s un viens cits", + "%(items)s and %(lastItem)s": "%(items)s un %(lastItem)s", + "and %(overflowCount)s others...": "un %(overflowCount)s citi...", + "and one other...": "un viens cits...", + "%(names)s and %(lastPerson)s are typing": "%(names)s un %(lastPerson)s raksta", + "%(names)s and one other are typing": "%(names)s un viens cits raksta", + "%(names)s and %(count)s others are typing": "%(names)s un %(count)s citi raksta", + "An email has been sent to": "Epasts tika nosūtīts", + "A new password must be entered.": "Nepieciešams ievadīt jauno paroli.", + "%(senderName)s answered the call.": "%(senderName)s atbildēja zvanam.", + "anyone": "ikviens", + "An error has occurred.": "Notikusi kļūda.", + "Anyone": "Ikviens", + "Anyone who knows the room's link, apart from guests": "Ikviens, kurš zina adreses saiti uz istabu, izņemot viesus", + "Anyone who knows the room's link, including guests": "Ikviens, kurš zina adreses saiti uz istabu, tai skaitā arī viesi", + "Are you sure?": "Esi pārliecināts/a?", + "Are you sure you want to leave the room '%(roomName)s'?": "Vai tiešām vēlies pamest istabas: '%(roomName)s'?", + "Are you sure you want to reject the invitation?": "Vai tiešām vēlies noraidīt šo uzaicinājumu?", + "Are you sure you want to upload the following files?": "Vai tiešām vēlies augšuplādēt sekojošos failus?", + "Attachment": "Pielikums", + "Autoplay GIFs and videos": "Automātiski atskaņot GIF animācijas un video", + "%(senderName)s banned %(targetName)s.": "%(senderName)s liedza pieeju %(targetName)s.", + "Ban": "Liegt pieeju (Bans)", + "Banned users": "Lietotāji, kuriem ir liegta pieeja (banotie)", + "Bans user with given id": "Liedz pieeju lietotājam pēc uzdotā ID (Bans)", + "Blacklisted": "Melnajā sarakstā iekļautie", + "Bug Report": "Paziņojums par kļūdu", + "Bulk Options": "Lielapjoma darbības", + "Call Timeout": "Zvana noilgums", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdevās savienoties ar serveri. Lūdzu pārbaudi savu tīkla savienējumu un pārliecinies, ka tava servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", + "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", + "Change Password": "Paroles maiņa", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s nomainīja redzamo vārdu no %(oldDisplayName)s uz %(displayName)s.", + "%(senderName)s changed their profile picture.": "%(senderName)s nomainīja profila attēlu.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s nomainīja statusa līmeni %(powerLevelDiffText)s.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s nomainīja istabas nosaukumu uz %(roomName)s.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s dzēsa istabas nosaukumu.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s nomainīja tēmas nosaukumu uz \"%(topic)s\".", + "Changes to who can read history will only apply to future messages in this room": "Izmaiņas attiecībā uz to, kurš varēs lasīt vēstures ziņas, stāsies spēkā tikai uz ziņām,kuras vēl tiks pievienotas šajā istabā", + "Changes your display nickname": "Nomaina tavu publisko segvārdu (niku)", + "changing room on a RoomView is not supported": "istabas maiņa nav iespējama, atrodoties istabu skata lapā", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Paroles maiņa dzēsīs pašreizējās šifrēšanas atslēgas visās savstarpēji saistītajās ierīcēs, padarot čata vēsturi neizlasāmu, ja vien vien istabas atslēgas nav tikušas iepriekš eksportētas un no jauna importētas atpakaļ. Nākotnē šo plānojam uzlabot.", + "Claimed Ed25519 fingerprint key": "Norādīta Ed25519 identificējošās zīmju virknes atslēga", + "Clear Cache and Reload": "Iztīri kešatmiņu un pārlādē", + "Clear Cache": "Iztīri kešatmiņu", + "Click here to join the discussion!": "Klikšķini šeit lai pievienotos diskusijai!", + "Click here to fix": "Klikšķini šeit, lai izlabotu", + "Click to mute audio": "Klikšķini, lai izslēgtu skaņu", + "Click to mute video": "Klikšķini, lai izslēgtu video skaņu", + "click to reveal": "Klikšķini, lai atvērtu", + "Click to unmute video": "Klikšķini, lai ieslēgtu video skaņu", + "Click to unmute audio": "Klikšķini, lai ieslēgtu audio skaņu", + "Close": "Aizvērt", + "Command error": "Komandas kļūda", + "Commands": "Komandas", + "Conference call failed.": "Konferences zvans neizdevās.", + "Conference calling is in development and may not be reliable.": "Konferences zvans šobrīd atrodas izstrādes stadijā un var būt nestabils.", + "Conference calls are not supported in encrypted rooms": "Konferences zvani nav iespējami istabās, kurās tiek izmantota šifrēšana", + "Conference calls are not supported in this client": "Konferences zvani netiek atbalstīti šajā programmā", + "Confirm password": "Apstiprini paroli", + "Confirm your new password": "Apstiprini jauno paroli", + "Continue": "Turpināt", + "Could not connect to the integration server": "Neizdevās savienoties ar integrācijas serveri", + "%(count)s new messages.one": "jaunu ziņu skaits: %(count)s", + "%(count)s new messages.other": "%(count)s jaunas ziņas", + "Create a new chat or reuse an existing one": "Izveidot jaunu čatu vai izmantot eksistējošu", + "Create an account": "Reģistrēt kontu", + "Create Room": "Izveidot istabu", + "Cryptography": "Kriptogrāfija", + "Current password": "Pašreizējā parole", + "Curve25519 identity key": "Curve25519 identifikācijas atslēga", + "Custom": "Pielāgots", + "Custom level": "Speciāls līmenis", + "/ddg is not a command": "/ddg nav komanda", + "Deactivate Account": "Deaktivizēt kontu", + "Deactivate my account": "Deaktivizēt manu kontu", + "Decline": "Noraidīt", + "Decrypt %(text)s": "Atšifrēt %(text)s", + "Decryption error": "Atšifrēšanas kļūda", + "Delete": "Dzēst", + "demote": "samazināt", + "Deops user with given id": "Noņemt operatora statusu lietotājam ar norādīto id", + "Default": "Noklusējuma", + "Device already verified!": "Ierīce ir jau verificēta!", + "Device ID": "Ierīces ID", + "Device ID:": "Ierīces ID:", + "device id: ": "ierīces id: ", + "Device key:": "Ierīces atslēga:", + "Devices": "Ierīces", + "Devices will not yet be able to decrypt history from before they joined the room": "Ierīces nevarēs atšifrēt to ziņu vēsturi, kuras ir tikušas pievienotas, pirms ierīce pieslēdzās istabai", + "Direct Chat": "Tiešais čats", + "Direct chats": "Tiešie čati", + "Disable Notifications": "Atslēgt paziņojumus", + "disabled": "atslēgts", + "Disable inline URL previews by default": "Pēc noklusējuma atslēgt saišu priekšskatījumu", + "Disable markdown formatting": "Atslēgt formatēšanas iespēju", + "Disinvite": "Atsaukt", + "Display name": "Redzamais vārds", + "Displays action": "Parāda darbību", + "Don't send typing notifications": "Nesūtīt paziņojumus", + "Download %(text)s": "Lejupielādēt tekstu: %(text)s", + "Drop File Here": "Ievelc failu šeit", + "Drop here %(toAction)s": "Ievelc šeit %(toAction)s", + "Drop here to tag %(section)s": "Ievelc šeit uz birkas %(section)s", + "Ed25519 fingerprint": "Ed25519 identificējošā zīmju virkne", + "Email": "Epasts", + "Email address": "Epasta adrese", + "Email address (optional)": "Epasta adrese (neobligāta)", + "Email, name or matrix ID": "Epasts, vārds vai Matrix identifikators (ID)", + "Emoji": "Emocijzīmes (Emoji)", + "Enable encryption": "Iespējot šifrēšanu", + "Enable Notifications": "Iespējot paziņojumus", + "enabled": "iespējots", + "Encrypted by a verified device": "Šifrēts ar verificētu ierīci", + "Encrypted by an unverified device": "Šifrēts ar neverificētu ierīci", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Šifrētas ziņas nebūs redzamas tajās klienta programmās, kuras neatbalsta šifrēšanu", + "Encrypted room": "Šifrēta istaba", + "Encryption is enabled in this room": "Šajā istabā ir iespējota šifrēšana", + "Encryption is not enabled in this room": "Šajā istabā nav iespējota šifrēšana", + "%(senderName)s ended the call.": "%(senderName)s beidza zvanu.", + "End-to-end encryption information": "Ierīce-ierīce šifrēšanas informācija", + "End-to-end encryption is in beta and may not be reliable": "Ierīce-ierīce šifrēšana šobrīd ir beta stadijā, un var nebūt stabila", + "Enter Code": "Ievadi kodu", + "Enter passphrase": "Ievadi paroles frāzi", + "Error": "Kļūda", + "Error decrypting attachment": "Kļūda atšifrējot pielikumu", + "Error: Problem communicating with the given homeserver.": "Kļūda: Radās komunikācijas problēma ar norādīto serveri.", + "Event information": "Notikuma informācija", + "Existing Call": "Eksistējošs zvans", + "Export": "Eksportēt", + "Export E2E room keys": "Eksportēt E2E istabas atslēgas", + "Failed to ban user": "Neizdevās liegt pieeju lietotājam", + "Failed to change password. Is your password correct?": "Neizdevās mainīt paroli. Vai tava parole ir pareiza?", + "Failed to change power level": "Neizdevās mainīt statusa līmeni", + "Power level must be positive integer.": "Statusa līmenim ir jābūt pozitīvam skaitlim.", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tu nevarēsi atcelt šo darbību, jo šim lietotājam piešķir tādu pašu statusa līmeni, kāds ir Tev.", + "Failed to delete device": "Neizdevās dzēst ierīci", + "Failed to fetch avatar URL": "Neizdevās noteikt avatara URL adresi", + "Failed to forget room %(errCode)s": "Neizdevās \"aizmirst\" istabu %(errCode)s", + "Failed to join room": "Neizdevās pievienoties istabai", + "Failed to join the room": "Neizdevās pievienoties istabai", + "Failed to kick": "Neizdevās veikt \"kick\" darbību", + "Failed to leave room": "Neizdevās pamest istabu", + "Failed to load timeline position": "Neizdevās ielādēt laikpaziņojumu pozīciju", + "Failed to lookup current room": "Neizdevās pārlūkot pašreizējo istabu", + "Failed to mute user": "Neizdevās apklusināt lietotāju", + "Failed to register as guest:": "Neizdevās reģistrēt kā viesi:", + "Failed to reject invite": "Neizdevās noraidīt uzaicinājumu", + "Failed to reject invitation": "Neizdevās noraidīt uzaicinājumu", + "Failed to save settings": "Neizdevās saglabāt uzstādījumus", + "Failed to send email": "Neizdevās nosūtīt epastu", + "Failed to send request.": "Neizdevās nosūtīt pieprasījumu.", + "Failed to set avatar.": "Neizdevās uzlikt attēlu (avataru).", + "Failed to set display name": "Neizdevās uzstādīt redzamo vārdu", + "Failed to set up conference call": "Neizdevās uzstādīt konferences zvanu", + "Failed to toggle moderator status": "Neizdevās pārslēgt moderatora statusu", + "Failed to unban": "Neizdevās atcelt pieejas liegumu (atbanot)", + "Failed to upload file": "Neizdevās augšuplādēt failu", + "Failed to upload profile picture!": "Neizdevās augšuplādēt profila attēlu!", + "Failed to verify email address: make sure you clicked the link in the email": "Neizdevās apstiprināt epasta adresi. Pārbaudi, vai Tu esi noklikšķinājis/usi saiti epasta ziņā", + "Failure to create room": "Neizdevās izveidot istabu", + "Favourite": "Favorīts", + "favourite": "favorīts", + "Favourites": "Favorīti", + "Fill screen": "Aizpildīt ekrānu", + "Filter room members": "Filtrēt istabas biedrus", + "Forget room": "\"Aizmirst\" istabu", + "Forgot your password?": "Aizmirsi savu paroli?", + "For security, this session has been signed out. Please sign in again.": "Drošības nolūkos, šī sesija ir beigusies. Lūdzu, pieraksties par jaunu.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", + "Found a bug?": "Pamanīji kļūdu?", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s no %(fromPowerLevel)s uz %(toPowerLevel)s", + "Guest access is disabled on this Home Server.": "Šajā serverī viesu pierakstīšanās nav iespējama.", + "Guests can't set avatars. Please register.": "Viesi nevar uzstādīt profila attēlus (avatarus). Lūdzu reģistrējies vai pieraksties.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Viesi nevar izveidot jaunas istabas. Lūdzu reģistrējies vai pieraksties, un uzsāc čatu.", + "Guest users can't upload files. Please register to upload.": "Viesi nevar augšuplādēt failus. Lūdzu reģistrējies vai pieraksties.", + "Guests can't use labs features. Please register.": "Viesi nevar izmantot laboratorijas funkcijas. Lūdzu reģistrējies vai pieraksties.", + "Guests cannot join this room even if explicitly invited.": "Viesi nevar pievienoties šai istabai pat ja ir uzaicināti.", + "had": "bija", + "Hangup": "Aizturēt", + "Hide read receipts": "Slēpt izlasītās receptes", + "Hide Text Formatting Toolbar": "Slēpt teksta formatēšanas rīkjoslu", + "Historical": "Vēsturiskais", + "Home": "Mājup", + "Homeserver is": "Serveris ir", + "Identity Server is": "Indentifikācijas serveris ir", + "I have verified my email address": "Mana epasta adrese ir verificēta", + "Import": "Importēt", + "Import E2E room keys": "Importēt E2E istabas atslēgas", + "Incoming call from %(name)s": "Ienākošs zvans no %(name)s", + "Incoming video call from %(name)s": "Ienākošs video zvans no %(name)s", + "Incoming voice call from %(name)s": "Ienākošs balss zvans no %(name)s", + "Incorrect username and/or password.": "Nepareizs lietotājvārds un/vai parole.", + "Incorrect verification code": "Nepareizs verifikācijas kods", + "Interface Language": "Saskarnes valoda", + "Invalid alias format": "Nepareizs aizstājējvārda formāts", + "Invalid address format": "Nepareizs adreses formāts", + "Invalid Email Address": "Nepareiza epasta adrese", + "Invalid file%(extra)s": "Nepareizs faila %(extra)s", + "%(senderName)s invited %(targetName)s.": "%(senderName)s uzaicināja %(targetName)s.", + "Invite new room members": "Uzaicināt jaunus istabas biedrus", + "Invited": "Uzaicināts/a", + "Invites": "Uzaicinājumi", + "Invites user with given id to current room": "Uzaicina lietotāju ar norādīto id uz pašreizējo istabu", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' nav pareizā adreses formātā", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' nav pareizā aizstājējvārda formātā", + "%(displayName)s is typing": "%(displayName)s šobrīd raksta", + "Sign in with": "Pierakstīties ar", + "Join as voice or video.": "Pievienoties kā balss vai video.", + "Join Room": "Pievienoties istabai", + "joined and left": "pievienojās un atstāja", + "joined": "pievienojās", + "%(targetName)s joined the room.": "%(targetName)s pievienojās istabai.", + "Joins room with given alias": "Pievieno istabai ar uzdoto aizstājējvārdu", + "Jump to first unread message.": "Pārlekt uz pirmo neizlasīto ziņu.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s iespēra (kick) %(targetName)s.", + "Kick": "Iespert (kick)", + "Kicks user with given id": "Iesper (kick) lietotājam pēc norādītā id", + "Labs": "Laboratorija", + "Last seen": "Pēdējo reizi redzēts/a", + "Leave room": "Pamest istabu", + "left and rejoined": "atstāja un pievienojās atkārtoti", + "left": "atstāja", + "%(targetName)s left the room.": "%(targetName)s atstāja istabu.", + "Level:": "Līmenis:", + "List this room in %(domain)s's room directory?": "Rādīt šo istabu %(domain)s kataloga sarakstā?", + "Local addresses for this room:": "Šīs istabas lokālās adreses:", + "Logged in as:": "Pierakstījās kā:", + "Login as guest": "Pierakstīties kā viesis", + "Logout": "Izrakstīties", + "Low priority": "Zema prioritāte", + "%(senderName)s made future room history visible to": "%(senderName)s uzstādīja nākotnes istabas ziņu vēsturi redzamu", + "Manage Integrations": "Pārvaldīt integrācijas", + "Markdown is disabled": "Formatēšanas iespēja ir atslēgta", + "Markdown is enabled": "Formatēšanas iespēja ir iespējota", + "Turn Markdown off": "Izslēgt formatēšanas iespēju", + "Turn Markdown on": "Ieslēgt formatēšanas iespēju", + "matrix-react-sdk version:": "matrix-react-sdk versija:", + "Members only": "Tikai biedriem", + "The default role for new room members is": "Noklusējuma loma jaunam istabas biedram ir", + "Message not sent due to unknown devices being present": "Ziņa nav nosūtīta, jo tika konstatēta nezināmu ierīču klātbūtne", + "Missing room_id in request": "Iztrūkstošs room_id pieprasījumā", + "Missing user_id in request": "Iztrūkstošs user_id pieprasījumā", + "Mobile phone number": "Mobilā telefona numurs", + "Mobile phone number (optional)": "Mobilā telefona numurs (nav obligāts)", + "Moderator": "Moderators", + "Must be viewing a room": "Jāapskata istaba", + "Mute": "Apklusināt", + "my Matrix ID": "mans Matrix ID", + "Name": "Vārds", + "Never send encrypted messages to unverified devices from this device": "Nekad nesūti no šīs ierīces šifrētas ziņas uz neverificētām ierīcēm", + "Never send encrypted messages to unverified devices in this room": "Nekad nesūti šifrētas ziņas uz neverificētām ierīcēm šajā istabā", + "Never send encrypted messages to unverified devices in this room from this device": "Nekad nesūti no šīs ierīces šifrētas ziņas neverificētām ierīcēm šajā istabā", + "New address (e.g. #foo:%(localDomain)s)": "Jauna adrese (piemēram #kautkas:%(localDomain)s)", + "New Composer & Autocomplete": "Jauns teksta izveidotājs & automātiskā aizpildīšana", + "New password": "Jauna parole", + "New passwords don't match": "Jaunās paroles nesakrīt", + "New passwords must match each other.": "Jaunajām parolēm ir jāsakrīt vienai ar otru.", + "none": "nekāds", + "not set": "nav uzstādījuma", + "not specified": "nav noteikts", + "Notifications": "Paziņojumi", + "(not supported by this browser)": "(netiek atbalstīts šajā pārlūkā)", + "": "", + "NOT verified": "NAV verificēts", + "No devices with registered encryption keys": "Nav ierīču ar reģistrētām šifrēšanas atslēgām", + "No display name": "Nav publiski redzamā vārda", + "No more results": "Nav tālāko rezultātu", + "No results": "Nav rezultātu", + "No users have specific privileges in this room": "Nav lietotāju ar īpašām privilēģijām šajā istabā", + "OK": "LABI", + "olm version:": "olm versija:", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Tiklīdz istabai tiks iespējota šifrēšana, tā vairs nebūs atslēdzama (pašlaik)", + "Once you've followed the link it contains, click below": "Tiklīdz sekoji saturā esošajai saitei, noklikšķini zemāk", + "Only people who have been invited": "Vienīgi personas, kuras ir tikušas uzaicinātas", + "Operation failed": "Darbība neizdevās", + "Otherwise, click here to send a bug report.": "pretējā gadījumā, klikšķini šeit, lai nosūtītu paziņojumu par kļūdu.", + "Password": "Parole", + "Password:": "Parole:", + "Passwords can't be empty": "Paroles nevar būt tukšas", + "People": "Personas", + "Permissions": "Atļaujas", + "Phone": "Telefons", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s nolika %(callType)s zvanu.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Lūdzu pārbaudi savu epastu un noklikšķini tajā esošo saiti. Tiklīdz tas ir izdarīts, klikšķini \"turpināt\".", + "Please Register": "Lūdzu reģistrējies", + "Press": "Nospied", + "Press to start a chat with someone": "Nospied , lai uzsāktu čatu ar kādu", + "Privacy warning": "Privātuma brīdinājums", + "Private Chat": "Privātais čats", + "Privileged Users": "Priviliģētie lietotāji", + "Profile": "Profils", + "Public Chat": "Publiskais čats", + "Reason": "Iemesls", + "Reason: %(reasonText)s": "Iemesls: %(reasonText)s", + "Revoke Moderator": "Atcelt moderatoru", + "Refer a friend to Riot:": "Nosūtīt draugu uz Riot:", + "Register": "Reģistrēties", + "rejected": "noraidīts", + "%(targetName)s rejected the invitation.": "%(targetName)s noraidīja uzaicinājumu.", + "Reject invitation": "Noraidīt uzaicinājumu", + "Rejoin": "Pievienoties atkārtoti", + "Remote addresses for this room:": "Attālinātā adrese šai istabai:", + "Remove Contact Information?": "Dzēst kontaktinformāciju?", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s dzēsa redzamo vārdu (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s dzēsa profila attēlu.", + "Remove": "Dzēst", + "Remove %(threePid)s?": "Dzēst %(threePid)s?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s vēlas VoIP konferenci.", + "Report it": "Ziņot par to", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Paroles atiestatīšana dzēsīs visas ierīce-ierīce šifrēšanas atslēgas visās ierīcēs, padarot čata šifrēto ziņu vēsturi nelasāmu, ja vien Tu pirms tam neesi eksportējis savas istabas atslēgas un atkārtoti importējis tās atpakaļ. Nākotnē šo ir plānots uzlabot.", + "restore": "atjaunot", + "Results from DuckDuckGo": "Rezultāti no DuckDuckGo", + "Return to app": "Atgriezties aplikācijā", + "Return to login screen": "Atgriezties uz pierakstīšanās lapu", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot nav atļauts nosūtīt Tev paziņojumus. Lūdzu pārbaudi sava pārlūka uzstādījumus", + "Riot was not given permission to send notifications - please try again": "Riot nav atļauts nosūtīt paziņojumus. Lūdzu mēģini vēlreiz.", + "riot-web version:": "riot-web versija:", + "Unable to enable Notifications": "Nav iespējams iespējot paziņojumus", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Tu izrakstījies no visām ierīcēm un vairs nesaņemsi pašpiegādes (push) paziņojumus. Lai iespējotu paziņojumus, pieraksties atkārtoti katrā no ierīcēm", + "You have no visible notifications": "Tev nav redzamo paziņojumu", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Tava parole tika veiksmīgi nomainīta. Tu vairs nesaņemsi pašpiegādes (push) paziņojumus citās ierīcēs kamēr tajās nebūs veikta atkārtota pierakstīšanās", + "This will allow you to reset your password and receive notifications.": "Tas atļaus Tev atiestatīt paroli un saņemt paziņojumus.", + "Room %(roomId)s not visible": "Istaba %(roomId)s nav redzama", + "%(roomName)s does not exist.": "%(roomName)s neeksistē.", + "%(roomName)s is not accessible at this time.": "%(roomName)s šobrīd nav pieejama.", + "Seen by %(userName)s at %(dateTime)s": "Redzams %(userName)s %(dateTime)s", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s nosūtīja attēlu.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s nosūtīja uzaicinājumu %(targetDisplayName)s pievienoties istabai.", + "%(senderName)s set a profile picture.": "%(senderName)s uzstādīja profila attēlu.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s uzstādīja redzamo vārdu uz: %(displayName)s.", + "tag as %(tagName)s": "birka kā %(tagName)s", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Tevis uzdotā pierakstīšanās atslēga sakrīt ar atslēgu, kuru Tu saņēmi no %(userId)s ierīces %(deviceId)s. Ierīce tika atzīmēta kā verificēta.", + "%(actionVerb)s this person?": "%(actionVerb)s šo personu?", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Faila '%(fileName)s' izmērs pārsniedz šī mājas servera augšupielādes lieluma ierobežojumu", + "The file '%(fileName)s' failed to upload": "Failu '%(fileName)s' neizdevās augšuplādēt", + "to tag as %(tagName)s": "uz birku kā %(tagName)s", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ieslēdza ierīce-ierīce šifrēšanu (algorithm %(algorithm)s).", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s atcēla pieejas ierobežojumu (atbanoja) %(targetName)s.", + "Unknown room %(roomId)s": "Nezināma istaba %(roomId)s", + "Uploading %(filename)s and %(count)s others.zero": "Tiek augšuplādēts %(filename)s", + "Uploading %(filename)s and %(count)s others.one": "Tiek augšuplādēts %(filename)s un %(count)s citi", + "Uploading %(filename)s and %(count)s others.other": "Tiek augšuplādēts %(filename)s un %(count)s citi", + "%(user)s is a": "%(user)s ir", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "Neatbilstošs lietotājvārds: %(errMessage)s", + "(unknown failure: %(reason)s)": "(nezināma kļūda: %(reason)s)", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "BRĪDINĀJUMS: NEIZDEVĀS VERIFICĒT ATSLĒGU! Pierakstīšanās atslēga priekš %(userId)s un ierīces %(deviceId)s ir \"%(fprint)s\", kura nesakrīt ar uzdoto atslēgu \"%(fingerprint)s\". Tas var nozīmēt, ka Tava saziņa var tikt pārtverta!", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s atsauca %(targetName)s uzaicinājumu.", + "You are trying to access %(roomName)s.": "Tu mēģini piekļūt %(roomName)s.", + "You have been banned from %(roomName)s by %(userName)s.": "Tev ir liegta pieeja istabai %(roomName)s no %(userName)s.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s Tevi uzaicināja pievienoties šai istabai", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s izmeta Tevi no %(roomName)s.", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Parole ir par īsu (jābūt vismaz %(MIN_PASSWORD_LENGTH)s zīmēm).", + "An error occurred: %(error_string)s": "Notikusi kļūda: %(error_string)s", + "(~%(count)s results).one": "(~%(count)s rezultāts)", + "(~%(count)s results).other": "(~%(count)s rezultāti)", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s pievienojās %(repeats)s reizes", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s pievienojās %(repeats)s reizes", + "%(severalUsers)sjoined": "%(severalUsers)s pievienojās", + "%(oneUser)sjoined": "%(oneUser)s pievienojās", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s atstāja %(repeats)s reizes", + "%(oneUser)sleft %(repeats)s times": "%(oneUser)s atstāja %(repeats)s reizes", + "%(severalUsers)sleft": "%(severalUsers)s atstāja", + "%(oneUser)sleft": "%(oneUser)s atstāja", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s pievienojās un atstāja %(repeats)s reizes", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s pievienojās un atstāja %(repeats)s reizes", + "%(severalUsers)sjoined and left": "%(severalUsers)s pievienojās un atstāja", + "%(oneUser)sjoined and left": "%(oneUser)s pievienojās un atstāja", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s atstāja un atkārtoti pievienojās %(repeats)s reizes", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s atstāja un atkārtoti pievienojās %(repeats)s reizes", + "%(severalUsers)sleft and rejoined": "%(severalUsers)s atstāja un atkārtoti pievienojās", + "%(oneUser)sleft and rejoined": "%(oneUser)s atstāja un atkārtoti pievienojās", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s noraidīja uzaicinājumus %(repeats)s reizes", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)s noraidīja uzaicinājumu %(repeats)s reizes", + "%(severalUsers)srejected their invitations": "%(severalUsers)s noraidīja uzaicinājumus", + "%(oneUser)srejected their invitation": "%(oneUser)s noraidīja uzaicinājumu", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)s atsauca uzaicinājumus %(repeats)s reizes", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s atsauca uzaicinājumus %(repeats)s reizes", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s atsauca uzaicinājumus", + "%(oneUser)shad their invitation withdrawn": "%(oneUser)s atsauca uzaicinājumus", + "were invited %(repeats)s times": "tika uzaicināts/a %(repeats)s reizes", + "was invited %(repeats)s times": "tika uzaicināts/a %(repeats)s reizes", + "were banned %(repeats)s times": "tika liegta pieeja (bans) %(repeats)s reizes", + "was banned %(repeats)s times": "tika liegta pieeja (bans) %(repeats)s reizes", + "were unbanned %(repeats)s times": "tika atcelts pieejas liegums (atbanošana) %(repeats)s reizes", + "was unbanned %(repeats)s times": "tika atcelts pieejas liegums (atbanošana) %(repeats)s reizes", + "were kicked %(repeats)s times": "tika izmests/a (kick) %(repeats)s reizes", + "was kicked %(repeats)s times": "tika izmests/a (kick) %(repeats)s reizes", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)s nomainīja vārdu %(repeats)s reizes", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)s nomainīja vārdu %(repeats)s reizes", + "%(severalUsers)schanged their name": "%(severalUsers)s nomainīja vārdu", + "%(oneUser)schanged their name": "%(oneUser)s nomainīja vārdu", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)s nomainīja profila attēlu %(repeats)s reizes", + "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)s nomainīja profila attēlu %(repeats)s reizes", + "%(severalUsers)schanged their avatar": "%(severalUsers)s nomainīja profila attēlu", + "%(oneUser)schanged their avatar": "%(oneUser)s nomainīja profila attēlu", + "Reject all %(invitedRooms)s invites": "Noraidīt visus %(invitedRooms)s uzaicinājumus", + "Failed to invite the following users to the %(roomName)s room:": "Neizdevās uzaicināt sekojošos lietotājus uz %(roomName)s istabu:", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" atrodas ierīces, kuras Tu neesi iepriekš redzējis/usi.", + "You are registering with %(SelectedTeamName)s": "Tu reģistrējies ar %(SelectedTeamName)s", + "Image '%(Body)s' cannot be displayed.": "Attēlu '%(Body)s' nav iespējams parādīt.", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Notiek tevis novirzīšana uz ārēju trešās puses vietni. Tu vari atļaut savam kontam piekļuvi ar %(integrationsUrl)s. Vai vēlies turpināt?", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URL adrešu priekškatījums %(globalDisableUrlPreview)s pēc noklusējuma šīs istabas dalībniekiem.", + "Ongoing conference call%(supportedText)s.": "Ienākošs konferences zvans %(supportedText)s.", + "for %(amount)ss": "priekš %(amount)ss", + "for %(amount)sm": "priekš %(amount)sm", + "for %(amount)sh": "priekš %(amount)sh", + "for %(amount)sd": "priekš %(amount)sd", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s dzēsa istabas attēlu.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s nomainīja istabas attēlu %(roomName)s", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Tu pievienoji jaunu ierīci '%(displayName)s', kas prasa šifrēšanas atslēgas.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Tava neverificētā ierīce '%(displayName)s' pieprasa šifrēšanas atslēgas.", + "Room Colour": "Istabas krāsa", + "Room contains unknown devices": "Istabā konstatētas nepārbaudītas ierīces", + "Room name (optional)": "Istabas nosaukums (nav obligāts)", + "Rooms": "Istabas", + "Save": "Saglabāt", + "Scroll to bottom of page": "Aizritināt uz lapas apakšu", + "Scroll to unread messages": "Aizritināt uz nelasītajām ziņām", + "Search": "Meklēt", + "Search failed": "Meklēšana neizdevās", + "Searches DuckDuckGo for results": "Meklē DuckDuckGo rezultātus", + "Searching known users": "Meklē zināmus lietotājus", + "Send a message (unencrypted)": "Nosūtīt ziņu (netiek šifrēta)", + "Send an encrypted message": "Nosūtīt šifrētu ziņu", + "Send anyway": "Nosūtīt jebkurā gadījumā", + "Sender device information": "Nosūtītāja ierīces informācija", + "Send Invites": "Nosūtīt uzaicinājumus", + "Send Reset Email": "Nosūtīt atiestatīšanas epastu", + "sent an image": "nosūtīja attēlu", + "sent a video": "nosūtīja video", + "Server error": "Servera kļūda", + "Server may be unavailable or overloaded": "Serveris var nebūt pieejams vai ir pārslogots", + "Server may be unavailable, overloaded, or search timed out :(": "Serveris var nebūt pieejams, ir pārslogots, vai arī meklēšana beidzās ar savienojuma noilgumu :(", + "Server may be unavailable, overloaded, or the file too big": "Serveris var nebūt pieejams, ir pārslogots, vai arī faila izmērs ir par lielu", + "Server may be unavailable, overloaded, or you hit a bug.": "Serveris var nebūt pieejams, ir pārslogots, vai arī sastapi neparedzētu kļūdu.", + "Server unavailable, overloaded, or something else went wrong.": "Serveris nav pieejams, ir pārslogots, vai arī ir notikusi cita, neparedzēta, kļūda.", + "Session ID": "Sesijas identifikators (ID)", + "Set": "Uzstādīt", + "Settings": "Uzstādījumi", + "Show panel": "Rādīt paneli", + "Show Text Formatting Toolbar": "Rādīt teksta formatēšanas rīkjoslu", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Rādīt laiku 12 stundu formātā (piemēram 2:30pm)", + "Signed Out": "Izrakstījās", + "Sign in": "Pierakstīties", + "Sign out": "Izrakstīties", + "since the point in time of selecting this option": "kopš šī uzstādījuma izvēles brīža", + "since they joined": "kopš tie pievienojās", + "since they were invited": "kopš tie tika uzaicināti", + "Some of your messages have not been sent.": "Dažas no tavām ziņām netika nosūtītas.", + "Someone": "Kāds", + "Sorry, this homeserver is using a login which is not recognised ": "Atvaino, šis serveris izmanto neatpazītu pierakstīšanās veidu ", + "Start a chat": "Sākt čatu", + "Start authentication": "Sākt autentifikāciju", + "Start Chat": "Sākt čatu", + "Submit": "Iesniegt", + "Success": "Veiksmīgi", + "tag direct chat": "atzīmēt tiešo čatu", + "Tagged as: ": "Atzīmēts,kā: ", + "The main address for this room is": "Galvenā šīs istabas adrese ir", + "The phone number entered looks invalid": "Ievadītais telefona numurs izskatās nepareizs", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Viesi nevar veikt šo darbību. Lūdzu reģistrējies vai pieraksties.", + "This email address is already in use": "Šī epasta adrese jau tiek izmantota", + "This email address was not found": "Šāda epasta adrese nav atrasta", + "The email address linked to your account must be entered.": "Ir jāievada tavam kontam piesaistītā epasta adrese.", + "The remote side failed to pick up": "Neizdevās uzņemt attālināto pusi", + "This Home Server does not support login using email address.": "Šis serveris neatbalsta pierakstīšanos ar epasta adresi.", + "This invitation was sent to an email address which is not associated with this account:": "Šis uzaicinājums tika nosūtīts uz epasta adresi, kura nav piesaistīta šim kontam:", + "There was a problem logging in.": "Radās problēma ar pierakstīšanos.", + "This room has no local addresses": "Šai istabai nav lokālo adrešu", + "This room is not recognised.": "Šī istaba netika atpazīta.", + "These are experimental features that may break in unexpected ways": "Šīs ir eksperimentālās iespējas, kuras var būt dažādos veidos nestrādājošas", + "The visibility of existing history will be unchanged": "Esošās ziņu vēstures redzamība paliks nemainīga", + "This doesn't appear to be a valid email address": "Šī neizskatās pēc derīgas epasta adreses", + "This is a preview of this room. Room interactions have been disabled": "Šis ir esošās istabas priekšskatījums. Istabas mijiedarbība ir atspējota", + "This phone number is already in use": "Šis telefona numurs jau tiek izmantots", + "This room": "Šī istaba", + "This room is not accessible by remote Matrix servers": "Šī istaba nav pieejama no attālinātajiem Matrix serveriem", + "This room's internal ID is": "Šīs istabas iekšējais ID ir", + "times": "reizes", + "To ban users": "lai banotu lietotājus", + "to browse the directory": "lai pārlūkotu katalogu", + "To configure the room": "Lai konfigurētu istabu", + "to demote": "lai samazinātu", + "to favourite": "lai pievienotu favorītiem", + "To invite users into the room": "Lai uzaicinātu lietotājus uz istabu", + "To kick users": "Lai \"iespertu\" (kicks) lietotājiem", + "To link to a room it must have an address.": "Lai ieliktu saiti uz istabu, tai ir jābūt piešķirtai adresei.", + "to make a room or": "lai izveidotu istabu vai", + "To remove other users' messages": "Lai dzēstu citu lietotāju ziņas", + "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi tavam kontam piesaistīto epasta adresi", + "to restore": "lai atjaunotu", + "To send events of type": "Lai sūtītu sekojošā tipa notikumus", + "To send messages": "Lai nosūtītu ziņas", + "to start a chat with someone": "lai uzstāktu čatu ar kādu", + "to tag direct chat": "lai pieliktu birku tiešajam čatam", + "To use it, just wait for autocomplete results to load and tab through them.": "Lai to izmantotu, vienkārši gaidi, kamēr ielādējas automātiski ieteiktie rezultāti, un pārvietojies caur tiem.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet Tev nav atļaujas skatīt šo ziņu.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet tā netika atrasta.", + "Unable to add email address": "Nav iespējams pievienot epasta adresi", + "Unable to remove contact information": "Nav iespējams dzēst kontaktinformāciju", + "Unable to restore previous session": "Nav iespējams atjaunot iepriekšējo sesiju", + "Unable to verify email address.": "Nav iespējams apstiprināt epasta adresi.", + "Unban": "Atbanot", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Nav iespējams pārliecināties, ka šis uzaicinājums tika nosūtīts uz to pašu adresi, kura ir piesaistīta tavam kontam.", + "Unable to capture screen": "Nav iespējams uzņemt ekrānattēlu", + "Unable to load device list": "Nav iespējams ielādēt ierīču sarakstu", + "Undecryptable": "Neatšifrējams", + "Unencrypted room": "Nešifrēta istaba", + "unencrypted": "nešifrēts", + "Unencrypted message": "Nešifrēta ziņa", + "unknown caller": "nezināms zvanītājs", + "Unknown command": "Nezināma komanda", + "unknown device": "nezināma ierīce", + "unknown error code": "nezināms kļūdas kods", + "Unknown (user, device) pair:": "Nezināms (lietotājs, ierīce) pāris:", + "unknown": "nezināms", + "Unmute": "Ieslēgt skaņu", + "Unnamed Room": "Istaba bez nosaukuma", + "Cancel": "Atcelt", + "Create new room": "Izveidot jaunu istabu", + "Custom Server Options": "Īpaši servera uzstādījumi", + "Dismiss": "Noņemt", + "You have enabled URL previews by default.": "Tev ir pēc noklusējuma iespējots URL adrešu priekšskatījums.", + "Enable URL previews for this room (affects only you)": "Iespējo URL priekšskatījumu šai istabai (attieksies tikai uz Tevi)", + "Unrecognised command:": "Neatpazīta komanda:", + "Unrecognised room alias:": "Neatpazīts istabas aizstājējvārds:", + "Unverified": "Neverificēts", + "uploaded a file": "augšuplādēja failu", + "Upload avatar": "Augšuplādē profila attēlu", + "Upload Failed": "Augšupielāde neizdevās", + "Upload Files": "Augšuplādē failus", + "Upload file": "Augšuplādē failu", + "Upload new:": "Augšuplādē jaunu:", + "Usage": "Lietojums", + "Use compact timeline layout": "Izmanto kompaktu laikpaziņojumu skatu", + "Use with caution": "Izmanto piesardzīgi", + "User ID": "Lietotāja ID", + "User Interface": "Lietotāja saskarne", + "User name": "Lietotāja vārds", + "Users": "Lietotāji", + "User": "Lietotājs", + "Verification Pending": "Gaida verifikāciju", + "Verification": "Verifikācija", + "verified": "verificēts", + "Verified": "Verificēts", + "Verified key": "Verificēta atslēga", + "WARNING: Device already verified, but keys do NOT MATCH!": "BRĪDINĀJUMS: Ierīce ir jau verificēta, bet NESAKRĪT atslēgas!", + "In future this verification process will be more sophisticated.": "Nākotnē šis verifikācijas process būs draudzīgāks.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Tu šobrīd esi iekļāvis/usi neverificētas ierīces melnajā sarakstā. Lai nosūtītu ziņas uz šādām ierīcēm, Tev viņas ir jāverificē.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Mēs rekomendējam Tev pārskatīt verifikācijas procesu katrai ierīcei, lai apstiprinātu tās piederību īstajam īpašniekam, bet Tu vari nosūtīt ziņu vēlreiz bez verificēšanas, ja vēlies.", + "Start verification": "Sākt verifikāciju", + "Video call": "Video zvans", + "Voice call": "Balss zvans", + "VoIP conference finished.": "VoIP konference ir beigusies.", + "VoIP conference started.": "VoIP konference ir sākusies.", + "VoIP is unsupported": "VoIP netiek atbalstīts", + "(could not connect media)": "(nav iespējams savienoties ar mediju)", + "(no answer)": "(nav atbildes)", + "(warning: cannot be disabled again!)": "(brīdinājums: nav iespējams atspējot atkārtoti!)", + "Warning!": "Brīdinājums!", + "Who can access this room?": "Kurš var piekļūt istabai?", + "Who can read history?": "Kurš var lasīt vēsturi?", + "Who would you like to add to this room?": "Kuru vēlies pievienot šai istabai?", + "Who would you like to communicate with?": "Ar kuru vēlies komunicēt?", + "Would you like to accept or decline this invitation?": "Vai vēlies apstiprināt vai noraidīt šo uzaicinājumu?", + "You already have existing direct chats with this user:": "Tev jau ir eksistējošs tiešais čats ar šo lietotāju:", + "You are already in a call.": "Tu jau šobrīd atrodies zvanā.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Šobrīd Tu vēl neatrodies nevienā istabā! Klikšķini lai izveidotu istabu, vai , lai skatītu istabu katalogu", + "You cannot place a call with yourself.": "Tu nevari veikt zvanu sev.", + "You cannot place VoIP calls in this browser.": "Tu nevari veikt VoIP zvanus šajā pārlūkā.", + "You do not have permission to post to this room": "Tev nav vajadzīgās atļaujas pievienot ziņas šajā istabā", + "You have disabled URL previews by default.": "URL priekšskatījums pēc noklusējuma Tev ir atspējots.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Tu ievadīji nepareizu kontaktu. Mēģini izmantot viņa Matrix ID vai epasta adresi.", + "You may wish to login with a different account, or add this email to this account.": "Tu varētu, iespējams, vēlēties pierakstīties no cita konta vai piesaistīt šo epastu šim kontam.", + "you must be a": "Tev ir jābūt", + "You must register to use this functionality": "Lai izmantotu šo funkcionalitāti, Tev ir jāreģistrējas", + "You need to be able to invite users to do that.": "Lai to darītu, Tev ir jāspēj uzaicināt lietotājus.", + "You need to be logged in.": "Tev ir jāpierakstās.", + "You need to enter a user name.": "Tev ir jāievada lietotāja vārds.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Tava epasta adrese nav piesaistīta pie Matrix ID šajā mājas serverī.", + "Your password has been reset": "Tava parole tika atiestatīta", + "You seem to be in a call, are you sure you want to quit?": "Izskatās, ka atrodies zvana režīmā. Vai tiešām vēlies iziet?", + "You seem to be uploading files, are you sure you want to quit?": "Izskatās, ka šobrīd augšuplādē failus. Vai tiešām vēlies iziet?", + "You should not yet trust it to secure data": "Tev nevajadzētu uz to vēl paļauties, lai saglabātu datu drošību", + "Your home server does not support device management.": "Tavs mājas serveris neatbalsta ierīču pārvaldīšanu.", + "Sun": "Sv.", + "Mon": "P.", + "Tue": "O.", + "Wed": "T.", + "Thu": "C.", + "Fri": "P.", + "Sat": "S.", + "Jan": "Jan.", + "Feb": "Feb.", + "Mar": "Mar.", + "Apr": "Apr.", + "May": "Maijs", + "Jun": "Jūn.", + "Jul": "Jūl.", + "Aug": "Aug.", + "Sep": "Sep.", + "Oct": "Okt.", + "Nov": "Nov.", + "Dec": "Dec.", + "Set a display name:": "Uzstādīt redzamo vārdu:", + "Set a Display Name": "Uzstādīt redzamo vārdu", + "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Tavs redzamais vārds ir tas,kurš parādās citiem, kad tu sarunājies vai atrodies istabās. Kas Tu vēlētos būt?", + "This image cannot be displayed.": "Šo attēlu nav iespējams parādīt.", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName nomainīja istabas attēlu uz ", + "Upload an avatar:": "Augšuplādē profila attēlu:", + "This server does not support authentication with a phone number.": "Šis serveris neatbalsta autentifikāciju pēc telefona numura.", + "Missing password.": "Trūkst parole.", + "Passwords don't match.": "Paroles nesakrīt.", + "This doesn't look like a valid email address.": "Šī neizskatās pēc derīgas epasta adreses.", + "This doesn't look like a valid phone number.": "Šis neizskatās pēc derīga telefona numura.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Lietotājvārdi drīkst saturēt vienīgi alfabēta burtus, skaitļus, punktus, defises un apakšsvītras.", + "An unknown error occurred.": "Notikusi neparedzēta kļūda.", + "I already have an account": "Man jau ir konts", + "Topic": "Tēma", + "Make Moderator": "Piešķirt moderatora līmeni", + "Make this room private": "Padarīt šo istabu privātu", + "Share message history with new users": "Kopīgot ziņu vēsturi ar jauniem lietotājiem", + "Encrypt room": "Šifrēt istabu", + "There are no visible files in this room": "Nav redzamu failu šajā istabā", + "Room": "Istaba", + "Connectivity to the server has been lost.": "Savienojums ar serveri tika zaudēts.", + "Sent messages will be stored until your connection has returned.": "Nosūtītās ziņas tiks saglabātas tiklīdz savienojums tiks atjaunots.", + "Auto-complete": "Automātiskā ieteikšana", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Sūtīt vēlreiz visas vai atcelt visas. Tu vari arī atlasīt atsevišķas ziņas, kuras sūtīt vai atcelt.", + "or": "vai", + "Active call": "Aktīvs zvans", + "Monday": "Pirmdiena", + "Tuesday": "Otrdiena", + "Wednesday": "Trešdiena", + "Thursday": "Ceturtdiena", + "Friday": "Piektdiena", + "Saturday": "Sestdiena", + "Sunday": "Svētdiena", + "bold": "trekns", + "italic": "itāļu", + "strike": "svītrots", + "underline": "pasvītrots", + "code": "kods", + "quote": "citāts", + "bullet": "lode", + "numbullet": "lode ar numuru", + "were invited": "kur uzaicināts/a", + "was invited": "tika uzaicināts/a", + "were banned": "kur liegta pieeja (bans)", + "was banned": "tika liegta pieeja (banots)", + "were unbanned": "kur atcelts pieejas liegums (atbanots)", + "was unbanned": "tika atcelts pieejas liegums (atbanots)", + "were kicked": "kur tika \"izsperts\" (kick)", + "was kicked": "tika izsperts/a (kick)", + "Please select the destination room for this message": "Lūdzu izvēlies šīs ziņas mērķa istabu", + "Welcome page": "\"Laipni lūdzam\" lapa", + "Room directory": "Istabu katalogs", + "Start chat": "Uzsākt čatu", + "New Password": "Jauna parole", + "Start automatically after system login": "Uzsākt automātiski pēc pierakstīšanās sistēmā", + "Desktop specific": "Darbvirsmai specifiski", + "Analytics": "Analītika", + "Opt out of analytics": "Atteikties no analītikas", + "Options": "Iespējas", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot ievāc anonīmus analītikas datus, lai varētu uzlabot aplikācijas darbību.", + "Passphrases must match": "Paroles frāzēm ir jāsakrīt", + "Passphrase must not be empty": "Paroles frāze nevar būt tukša", + "Export room keys": "Eksportēt istabas atslēgas", + "Confirm passphrase": "Apstiprināt paroles frāzi", + "Import room keys": "Importēt istabas atslēgas", + "File to import": "Importējamais fails", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība atļauj Tev eksportēt lokālā failā atslēgas tām ziņām, kuras Tu saņēmi šifrētās istabās. Pēc tam nākotnē Tu varēsi importēt šo failu citā Matrix klienta aplikācijā, lai tajā būtu iespējams atšifrēt šīs ziņas.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails atļaus ikvienam, kurš to ir nolasījis, atšifrēt jebkuras tev redzamās šifrētās ziņas, tāpēc ievēro piesardzību, un glabā šo failu drošā vietā. Lai palīdzētu to nodrošināt, Tev ir jāievada paroles frāze, kura tiks izmantota eksportēto datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu paroles frāzi.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļauj Tev importēt tās šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no citas Matrix klienta aplikācijas. Importētās atslēgas ļaus vajadzīgajā klienta aplikācijā lasīt atšifrētās ziņas.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar paroles frāzi. Tā ir jāievada šeit, lai atšifrētu failu.", + "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", + "Start new chat": "Uzsākt jaunu čatu", + "Guest users can't invite users. Please register.": "Viesi nevar uzaicināt lietotājus. Lūdzu reģistrējies.", + "Failed to invite": "Neizdevās uzaicināt", + "Failed to invite user": "Neizdevās uzaicināt lietotāju", + "Confirm Removal": "Apstiprini dzēšanu", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Vai tiešām vēlies dzēst šo notikumu? Ņem vērā, ka istabas nosaukuma vai tēmas nosaukuma maiņa var ietekmēt (atsaukt) izmaiņas.", + "Unknown error": "Nezināma kļūda", + "Incorrect password": "Nepareiza parole", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tas uz visiem laikiem padarīs tavu kontu neizmantojamu, un Tu vairs nevarēsi atkārtoti reģistrēt šo pašu lietotāja ID.", + "This action is irreversible.": "Šī darbība ir neatgriezeniska.", + "To continue, please enter your password.": "Lai turpinātu, ievadi savu paroli.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Lai verificētu šīs ierīces uzticamību, lūdzu sazinies ar tās īpašnieku, izmantojot citu saziņas veidu (piemēram, sazinoties personiski vai telefoniski) un pajautā, vai atslēga, kuru īpašnieks redz savos lietotāja uzstādījumos, sakrīt ar šo atslēgu:", + "Device name": "Ierīces nosaukums", + "Device Name": "Ierīces nosaukums", + "Device key": "Ierīces atslēga", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ja tā sakrīt, tad nospied zemāk esošo verifikācijas pogu . Ja nesakrīt, tad kāds cits ir piekļuvis šai ierīcei un šādā gadījumā Tu, iespējams, vēlies izmantot \"melnais saraksts\" iespēju.", + "Verify device": "Verificēt ierīci", + "I verify that the keys match": "Es pārbaudu, vai atslēgas sakrīt", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Mēs sastapāmies ar kļūdu, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, tev ir jāpierakstās par jaunu un šifrēta čata ziņu vēsture nebūs izlasāma.", + "Unable to restore session": "Nav iespējams atjaunot sesiju", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ja Tu iepriekš izmantoji jaunāku Riot versiju, tava sesija var nebūt saderīga ar šo versiju. Aizver šo logu un atgriezies jaunākajā versijā.", + "Continue anyway": "Turpināt jebkurā gadījumā", + "Unknown devices": "Nezināmas ierīces", + "Unknown Address": "Nezināma adrese", + "Unblacklist": "Atbloķēšanas saraksts", + "Blacklist": "Melnais saraksts", + "Unverify": "Atverificēt", + "Verify...": "Verificē...", + "ex. @bob:example.com": "piemēram, @janis:majaslapa.lv", + "Add User": "Pievienot lietotāju", + "This Home Server would like to make sure you are not a robot": "Šis mājas serveris vēlas pārliecināties, ka Tu neesi robots", + "Sign in with CAS": "Pierakstīties ar CAS", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Tu vari izmantot īpašos servera uzstādījumus, lai pierakstītos citos Matrix serveros, norādot citu mājas servera URL adresi.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Tas atļauj Tev izmantot šo aplikāciju ar eksistējošu Matrix kontu citā mājas serverī.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Tu vari arī norādīt īpašu identitātes serveri, bet tas parasti liedz iespēju mijiedarboties ar lietotājiem, kuri izmanto epasta adresi.", + "Please check your email to continue registration.": "Lūdzu pārbaudi savu epastu lai turpinātu reģistrāciju.", + "Token incorrect": "Nepareizs autentifikācijas kods", + "A text message has been sent to": "Teksta ziņa tika nosūtīta", + "Please enter the code it contains:": "Lūdzu ievadi tajā ietverto kodu:", + "powered by Matrix": "spēcināts ar Matrix", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ja Tu nenorādīsi epasta adresi, tev nebūs iespējams izmantot paroles atiestatīšanu. Vai esi pārliecināts/a?", + "Default server": "Noklusējuma serveris", + "Custom server": "Īpašs serveris", + "Home server URL": "Mājas servera URL adrese", + "Identity server URL": "Identitātes servera URL adrese", + "What does this mean?": "Ko tas nozīmē?", + "Error decrypting audio": "Kļūda atšifrējot audio", + "Error decrypting image": "Kļūda atšifrējot attēlu", + "Error decrypting video": "Kļūda atšifrējot video", + "Add an Integration": "Pievienot integrāciju", + "Removed or unknown message type": "Dzēsts vai nezināms ziņas veids", + "Disable URL previews by default for participants in this room": "Atspējot pēc noklusējuma URL adrešu priekšskatījumu istabas dalībniekiem", + "Disable URL previews for this room (affects only you)": "Atspējot URL adrešu priekšskatījumu šajā istabā (attiecas vienīgi uz tevi)", + "URL Previews": "URL adrešu priekšskatījumi", + "Drop file here to upload": "Ievelc failu šeit lai augšuplādētu", + " (unsupported)": " (netiek atbalstīts)", + "Online": "Tiešsaistē", + "Idle": "Dīkstāve", + "Offline": "Nav tiešsaistē", + "Updates": "Atjauninājumi", + "Check for update": "Pārbaudīt, vai ir atjauninājumi", + "Start chatting": "Sākt čatošanu", + "Start Chatting": "Sākt čatošanu", + "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čatošanu!", + "Username available": "Lietotājvārds ir pieejams", + "Username not available": "Lietotājvārds nav pieejams", + "Something went wrong!": "Kaut kas nogāja greizi!", + "This will be your account name on the homeserver, or you can pick a different server.": "Tas būs tava konta vārds mājas serverī, vai arī vari izvēlēties citu serveri.", + "If you already have a Matrix account you can log in instead.": "Vai arī, ja Tev jau ir Matrix konts, tu vari pierakstīties tajā.", + "Your browser does not support the required cryptography extensions": "Tavs pārlūks neatbalsta vajadzīgos kriptogrāfijas paplašinājumus", + "Not a valid Riot keyfile": "Nederīgs Riot atslēgfails", + "Authentication check failed: incorrect password?": "Autentifikācijas pārbaude neizdevās. Nepareiza parole?", + "Disable Peer-to-Peer for 1:1 calls": "Atspējot Peer-to-Peer iespēju 1:1 zvaniem", + "Do you want to set an email address?": "Vai vēlies iestatīt epasta adresi?", + "To return to your account in future you need to set a password": "Lai nākotnē atgrieztos savā kontā, tev ir nepieciešams iestatīt paroli", + "Skip": "Izlaist", + "Share without verifying": "Kopīgot bez verificēšanas", + "Ignore request": "Ignorēt pieprasījumu", + "Encryption key request": "Šifrēšanas atslēgas pieprasījums" +} From b15f3c08eac7615ab28c388568d9c14670cc85e7 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 20 Jul 2017 20:14:11 +0000 Subject: [PATCH 034/164] Translated using Weblate (French) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 20c28cdecc..7ea39e40cb 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -430,7 +430,7 @@ "Search failed": "Erreur lors de la recherche", "Searches DuckDuckGo for results": "Recherche des résultats dans DuckDuckGo", "Send a message (unencrypted)": "Envoyer un message (non-chiffré)", - "Send an encrypted message": "Envoyer un message non chiffré", + "Send an encrypted message": "Envoyer un message chiffré", "Sender device information": "Information de l'appareil de l'expéditeur", "Send Invites": "Envoyer les invitations", "Send Reset Email": "Envoyer l'e-mail de réinitialisation", @@ -900,8 +900,8 @@ "(~%(count)s results).one": "(~%(count)s résultat)", "(~%(count)s results).other": "(~%(count)s résultats)", "Device Name": "Nom de l'appareil", - "Encrypted by a verified device": "Chiffré par un appareil verifié", - "Encrypted by an unverified device": "Chiffré par un appareil non verifié", + "Encrypted by a verified device": "Chiffré par un appareil vérifié", + "Encrypted by an unverified device": "Chiffré par un appareil non vérifié", "Encryption is enabled in this room": "Le chiffrement est activée sur ce salon", "Encryption is not enabled in this room": "Le chiffrement n'est pas activée sur ce salon", "Home": "Accueil", From 35ce336c3566af94e2cd32f0cde6a0cd05e8aaeb Mon Sep 17 00:00:00 2001 From: Javier Quevedo Date: Thu, 20 Jul 2017 09:30:27 +0000 Subject: [PATCH 035/164] Translated using Weblate (Spanish) Currently translated at 69.2% (634 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index ca5ac15133..56dfd7ee1a 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -631,5 +631,14 @@ "Wednesday": "Miércoles", "Thursday": "Jueves", "Friday": "Viernes", - "Saturday": "Sábado" + "Saturday": "Sábado", + "New Composer & Autocomplete": "Nuevo compositor & Autocompletar", + "Start verification": "Comenzar la verificación", + "Skip": "Saltar", + "To return to your account in future you need to set a password": "Para volver a usar su cuenta en el futuro es necesario que establezca una contraseña", + "Share without verifying": "Compartir sin verificar", + "Ignore request": "Ignorar la solicitud", + "Do you want to set an email address?": "¿Quieres poner una dirección de correo electrónico?", + "This will allow you to reset your password and receive notifications.": "Esto te permitirá reiniciar tu contraseña y recibir notificaciones.", + "Authentication check failed: incorrect password?": "La verificación de la autentificación ha fallado: ¿El password es el correcto?" } From 6e7adedf1e1ca1c1ae7022ade818af02229f167e Mon Sep 17 00:00:00 2001 From: Andrei Shevchuk Date: Wed, 26 Jul 2017 21:12:14 +0000 Subject: [PATCH 036/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 1b9ed708aa..aca1c7c721 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -244,7 +244,7 @@ "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", "Failed to send request.": "Не удалось отправить запрос.", "Failed to set up conference call": "Не удалось настроить групповой вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес электронной почты: убедитесь что вы перешли по ссылке в письме", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес электронной почты: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "Guest users can't create new rooms. Please register to create room and start a chat.": "Гости не могут создавать новые комнаты. Зарегистрируйтесь, чтобы создать комнату и начать чат.", From bf98c0da7c09f1088fb7395e188ea171a9ff1c81 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 27 Jul 2017 17:19:18 +0100 Subject: [PATCH 037/164] un-i18n Modal Analytics Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Analytics.js | 25 ++++---- src/CallHandler.js | 20 +++--- src/ContentMessages.js | 2 +- src/KeyRequestHandler.js | 2 +- src/Lifecycle.js | 4 +- src/Modal.js | 13 +++- src/Notifier.js | 2 +- src/SlashCommands.js | 8 +-- src/UnknownDeviceErrorHandler.js | 2 +- src/components/structures/GroupView.js | 4 +- src/components/structures/MatrixChat.js | 20 +++--- src/components/structures/MyGroups.js | 2 +- src/components/structures/RoomView.js | 14 ++--- src/components/structures/TimelinePanel.js | 2 +- src/components/structures/UserSettings.js | 62 +++++++++---------- .../structures/login/ForgotPassword.js | 23 ++++--- .../views/dialogs/ChatInviteDialog.js | 10 +-- .../views/dialogs/DeactivateAccountDialog.js | 2 + src/components/views/dialogs/ErrorDialog.js | 2 +- .../views/dialogs/KeyShareDialog.js | 2 +- .../dialogs/SessionRestoreErrorDialog.js | 2 +- .../views/dialogs/SetEmailDialog.js | 10 +-- src/components/views/elements/AppTile.js | 2 +- .../views/elements/DeviceVerifyButtons.js | 2 +- .../views/login/RegistrationForm.js | 2 +- src/components/views/login/ServerConfig.js | 2 +- src/components/views/messages/MFileBody.js | 4 +- src/components/views/messages/TextualBody.js | 2 +- .../views/room_settings/AliasSettings.js | 4 +- src/components/views/rooms/AppsDrawer.js | 2 +- src/components/views/rooms/EventTile.js | 2 +- src/components/views/rooms/MemberInfo.js | 16 ++--- src/components/views/rooms/MessageComposer.js | 2 +- .../views/rooms/MessageComposerInput.js | 4 +- src/components/views/rooms/RoomHeader.js | 2 +- src/components/views/rooms/RoomSettings.js | 12 ++-- .../views/settings/AddPhoneNumber.js | 4 +- .../views/settings/ChangePassword.js | 20 +++--- .../views/settings/DevicesPanelEntry.js | 4 +- src/createRoom.js | 2 +- src/stores/RoomViewStore.js | 2 +- 41 files changed, 163 insertions(+), 160 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 92691da1ea..5831eb7f8d 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -15,7 +15,6 @@ */ import { getCurrentLanguage } from './languageHandler'; -import MatrixClientPeg from './MatrixClientPeg'; import PlatformPeg from './PlatformPeg'; import SdkConfig from './SdkConfig'; @@ -31,8 +30,17 @@ const customVariables = { 'User Type': 3, 'Chosen Language': 4, 'Instance': 5, + 'Homeserver URL': 6, + 'Identity Server URL': 7, }; +function whitelistRedact(whitelist, str) { + if (whitelist.includes(str)) return str; + return ''; +} + +const whitelistedHSUrls = ["https://matrix.org"]; +const whitelistedISUrls = ["https://vector.im"]; class Analytics { constructor() { @@ -76,7 +84,7 @@ class Analytics { this._paq.push(['trackAllContentImpressions']); this._paq.push(['discardHashTag', false]); this._paq.push(['enableHeartBeatTimer']); - this._paq.push(['enableLinkTracking', true]); + // this._paq.push(['enableLinkTracking', true]); const platform = PlatformPeg.get(); this._setVisitVariable('App Platform', platform.getHumanReadableName()); @@ -130,20 +138,15 @@ class Analytics { this._paq.push(['deleteCookies']); } - login() { // not used currently - const cli = MatrixClientPeg.get(); - if (this.disabled || !cli) return; - - this._paq.push(['setUserId', `@${cli.getUserIdLocalpart()}:${cli.getDomain()}`]); - } - _setVisitVariable(key, value) { this._paq.push(['setCustomVariable', customVariables[key], key, value, 'visit']); } - setGuest(guest) { + setLoggedIn(isGuest, homeserverUrl, identityServerUrl) { if (this.disabled) return; - this._setVisitVariable('User Type', guest ? 'Guest' : 'Logged In'); + this._setVisitVariable('User Type', isGuest ? 'Guest' : 'Logged In'); + this._setVisitVariable('Homeserver URL', whitelistRedact(whitelistedHSUrls, homeserverUrl)); + this._setVisitVariable('Identity Server URL', whitelistRedact(whitelistedISUrls, identityServerUrl)); } } diff --git a/src/CallHandler.js b/src/CallHandler.js index e3fbe9e5e3..8331d579df 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -143,7 +143,7 @@ function _setCallListeners(call) { pause("ringbackAudio"); play("busyAudio"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, { title: _t('Call Timeout'), description: _t('The remote side failed to pick up') + '.', }); @@ -205,7 +205,7 @@ function _onAction(payload) { _setCallState(undefined, newCall.roomId, "ended"); console.log("Can't capture screen: " + screenCapErrorString); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Unable to capture screen', ErrorDialog, { title: _t('Unable to capture screen'), description: screenCapErrorString, }); @@ -225,7 +225,7 @@ function _onAction(payload) { case 'place_call': if (module.exports.getAnyActiveCall()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Existing Call', ErrorDialog, { title: _t('Existing Call'), description: _t('You are already in a call.'), }); @@ -235,7 +235,7 @@ function _onAction(payload) { // if the runtime env doesn't do VoIP, whine. if (!MatrixClientPeg.get().supportsVoip()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, { title: _t('VoIP is unsupported'), description: _t('You cannot place VoIP calls in this browser.'), }); @@ -251,7 +251,7 @@ function _onAction(payload) { var members = room.getJoinedMembers(); if (members.length <= 1) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Cannot place call with self', ErrorDialog, { description: _t('You cannot place a call with yourself.'), }); return; @@ -277,13 +277,13 @@ function _onAction(payload) { console.log("Place conference call in %s", payload.room_id); if (!ConferenceHandler) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, { description: _t('Conference calls are not supported in this client'), }); } else if (!MatrixClientPeg.get().supportsVoip()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, { title: _t('VoIP is unsupported'), description: _t('You cannot place VoIP calls in this browser.'), }); @@ -296,13 +296,13 @@ function _onAction(payload) { // participant. // Therefore we disable conference calling in E2E rooms. const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, { description: _t('Conference calls are not supported in encrypted rooms'), }); } else { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, { title: _t('Warning!'), description: _t('Conference calling is in development and may not be reliable.'), onFinished: confirm=>{ @@ -314,7 +314,7 @@ function _onAction(payload) { }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Conference call failed: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Failed to set up conference call', ErrorDialog, { title: _t('Failed to set up conference call'), description: _t('Conference call failed.') + ' ' + ((err && err.message) ? err.message : ''), }); diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 9239de9d8f..1bd1332ab3 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -360,7 +360,7 @@ class ContentMessages { desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName}); } var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Upload failed', err.message, ErrorDialog, { title: _t('Upload Failed'), description: desc, }); diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js index 1da4922153..0b54d88e5f 100644 --- a/src/KeyRequestHandler.js +++ b/src/KeyRequestHandler.js @@ -125,7 +125,7 @@ export default class KeyRequestHandler { }; const KeyShareDialog = sdk.getComponent("dialogs.KeyShareDialog"); - Modal.createDialog(KeyShareDialog, { + Modal.createTrackedDialog('Key Share', 'Process Next Request', KeyShareDialog, { matrixClient: this._matrixClient, userId: userId, deviceId: deviceId, diff --git a/src/Lifecycle.js b/src/Lifecycle.js index eb2156e780..f4d1eeef08 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -240,7 +240,7 @@ function _handleRestoreFailure(e) { const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - Modal.createDialog(SessionRestoreErrorDialog, { + Modal.createTrackedDialog('Session Restore Error', e.message, SessionRestoreErrorDialog, { error: e.message, onFinished: (success) => { def.resolve(success); @@ -318,7 +318,7 @@ async function _doSetLoggedIn(credentials, clearStorage) { await _clearStorage(); } - Analytics.setGuest(credentials.guest); + Analytics.setLoggedIn(credentials.guest, credentials.homeserverUrl, credentials.identityServerUrl); // Resolves by default let teamPromise = Promise.resolve(null); diff --git a/src/Modal.js b/src/Modal.js index e100105a88..79fcaaefd1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -103,13 +103,20 @@ class ModalManager { return container; } + createTrackedDialog(analyticsAction, analyticsInfo, Element, props, className) { + Analytics.trackEvent('Modal', analyticsAction, analyticsInfo); + return this.createDialog(Element, props, className); + } + createDialog(Element, props, className) { - if (props && props.title) { - Analytics.trackEvent('Modal', props.title, 'createDialog'); - } return this.createDialogAsync((cb) => {cb(Element);}, props, className); } + createTrackedDialogAsync(analyticsId, loader, props, className) { + Analytics.trackEvent('Modal', analyticsId); + return this.createDialogAsync(loader, props, className); + } + /** * Open a modal view. * diff --git a/src/Notifier.js b/src/Notifier.js index 40a65d4106..1bb435307d 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -142,7 +142,7 @@ const Notifier = { ? _t('Riot does not have permission to send you notifications - please check your browser settings') : _t('Riot was not given permission to send notifications - please try again'); const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to enable Notifications', result, ErrorDialog, { title: _t('Unable to enable Notifications'), description, }); diff --git a/src/SlashCommands.js b/src/SlashCommands.js index dea3d27751..e5378d4347 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -68,7 +68,7 @@ const commands = { ddg: new Command("ddg", "", function(roomId, args) { const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); // TODO Don't explain this away, actually show a search UI here. - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Slash Commands', '/ddg is not a command', ErrorDialog, { title: _t('/ddg is not a command'), description: _t('To use it, just wait for autocomplete results to load and tab through them.'), }); @@ -326,13 +326,11 @@ const commands = { {deviceId: deviceId, fprint: fprint, userId: userId, fingerprint: fingerprint})); } - return MatrixClientPeg.get().setDeviceVerified( - userId, deviceId, true, - ); + return MatrixClientPeg.get().setDeviceVerified(userId, deviceId, true); }).then(() => { // Tell the user we verified everything const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Slash Commands', 'Verified key', QuestionDialog, { title: _t("Verified key"), description: (
diff --git a/src/UnknownDeviceErrorHandler.js b/src/UnknownDeviceErrorHandler.js index 2b1cf23380..e7d77b3b66 100644 --- a/src/UnknownDeviceErrorHandler.js +++ b/src/UnknownDeviceErrorHandler.js @@ -24,7 +24,7 @@ const onAction = function(payload) { if (payload.action === 'unknown_device_error' && !isDialogOpen) { const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog'); isDialogOpen = true; - Modal.createDialog(UnknownDeviceDialog, { + Modal.createTrackedDialog('Unknown Device Error', '', UnknownDeviceDialog, { devices: payload.err.devices, room: payload.room, onFinished: (r) => { diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5f7866773d..fff61b1c24 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -266,7 +266,7 @@ export default React.createClass({ this.setState({uploadingAvatar: false}); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload avatar image", e); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to upload image', e.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to upload image'), }); @@ -288,7 +288,7 @@ export default React.createClass({ }); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to save group profile", e); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to update group', e.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to update group'), }); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index b90cb53435..f042b41991 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -410,7 +410,7 @@ module.exports = React.createClass({ this._leaveRoom(payload.room_id); break; case 'reject_invite': - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, { title: _t('Reject invitation'), description: _t('Are you sure you want to reject the invitation?'), onFinished: (confirm) => { @@ -426,7 +426,7 @@ module.exports = React.createClass({ } }, (err) => { modal.close(); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invitation', err.toString(), ErrorDialog, { title: _t('Failed to reject invitation'), description: err.toString(), }); @@ -728,7 +728,7 @@ module.exports = React.createClass({ _setMxId: function(payload) { const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog'); - const close = Modal.createDialog(SetMxIdDialog, { + const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, { homeserverUrl: MatrixClientPeg.get().getHomeserverUrl(), onFinished: (submitted, credentials) => { if (!submitted) { @@ -767,7 +767,7 @@ module.exports = React.createClass({ return; } const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createDialog(ChatInviteDialog, { + Modal.createTrackedDialog('Start a chat', '', ChatInviteDialog, { title: _t('Start a chat'), description: _t("Who would you like to communicate with?"), placeholder: _t("Email, name or matrix ID"), @@ -787,7 +787,7 @@ module.exports = React.createClass({ return; } const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog"); - Modal.createDialog(TextInputDialog, { + Modal.createTrackedDialog('Create Room', '', TextInputDialog, { title: _t('Create Room'), description: _t('Room name (optional)'), button: _t('Create Room'), @@ -831,7 +831,7 @@ module.exports = React.createClass({ return; } - const close = Modal.createDialog(ChatCreateOrReuseDialog, { + const close = Modal.createTrackedDialog('Chat create or reuse', '', ChatCreateOrReuseDialog, { userId: userId, onFinished: (success) => { if (!success && goHomeOnCancel) { @@ -859,7 +859,7 @@ module.exports = React.createClass({ _invite: function(roomId) { const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createDialog(ChatInviteDialog, { + Modal.createTrackedDialog('Chat Invite', '', ChatInviteDialog, { title: _t('Invite new room members'), description: _t('Who would you like to add to this room?'), button: _t('Send Invites'), @@ -873,7 +873,7 @@ module.exports = React.createClass({ const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const roomToLeave = MatrixClientPeg.get().getRoom(roomId); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Leave room', '', QuestionDialog, { title: _t("Leave room"), description: ( @@ -896,7 +896,7 @@ module.exports = React.createClass({ }, (err) => { modal.close(); console.error("Failed to leave room " + roomId + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to leave room', err.toString(), ErrorDialog, { title: _t("Failed to leave room"), description: (err && err.message ? err.message : _t("Server may be unavailable, overloaded, or you hit a bug.")), @@ -1092,7 +1092,7 @@ module.exports = React.createClass({ }); cli.on('Session.logged_out', function(call) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Signed out', '', ErrorDialog, { title: _t('Signed Out'), description: _t('For security, this session has been signed out. Please sign in again.'), }); diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 3eb694acce..0b8055beda 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -63,7 +63,7 @@ export default withMatrixClient(React.createClass({ _onCreateGroupClick: function() { const CreateGroupDialog = sdk.getComponent("dialogs.CreateGroupDialog"); - Modal.createDialog(CreateGroupDialog); + Modal.createTrackedDialog('Create Group', '', CreateGroupDialog); }, _fetch: function() { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 094251f4c1..40dbc93071 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -544,7 +544,7 @@ module.exports = React.createClass({ } if (!userHasUsedEncryption) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('E2E Warning', '', QuestionDialog, { title: _t("Warning!"), hasCancelButton: false, description: ( @@ -820,7 +820,7 @@ module.exports = React.createClass({ }); const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog'); - const close = Modal.createDialog(SetMxIdDialog, { + const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, { homeserverUrl: cli.getHomeserverUrl(), onFinished: (submitted, credentials) => { if (submitted) { @@ -934,7 +934,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload file " + file + " " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to upload file', error.toString(), ErrorDialog, { title: _t('Failed to upload file'), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or the file too big")), }); @@ -1021,7 +1021,7 @@ module.exports = React.createClass({ }, function(error) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Search failed: " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Search failed', error.toString(), ErrorDialog, { title: _t("Search failed"), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or search timed out :(")), }); @@ -1148,7 +1148,7 @@ module.exports = React.createClass({ console.error(result.reason); }); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to save room settings', '', ErrorDialog, { title: _t("Failed to save settings"), description: fails.map(function(result) { return result.reason; }).join("\n"), }); @@ -1195,7 +1195,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t("unknown error code"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { title: _t("Error"), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); @@ -1217,7 +1217,7 @@ module.exports = React.createClass({ var msg = error.message ? error.message : JSON.stringify(error); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invite', error.toString(), ErrorDialog, { title: _t("Failed to reject invite"), description: msg, }); diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 0aee19545c..7cd67f3da8 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -923,7 +923,7 @@ var TimelinePanel = React.createClass({ var message = (error.errcode == 'M_FORBIDDEN') ? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.") : _t("Tried to load a specific point in this room's timeline, but was unable to find it."); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to load timeline position', error.toString(), ErrorDialog, { title: _t("Failed to load timeline position"), description: message, onFinished: onFinished, diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 1e0fcff445..9a0567ec30 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -331,7 +331,7 @@ module.exports = React.createClass({ }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to load user settings: " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Can\'t load user settings', error.toString(), ErrorDialog, { title: _t("Can't load user settings"), description: ((error && error.message) ? error.message : _t("Server may be unavailable or overloaded")), }); @@ -364,7 +364,7 @@ module.exports = React.createClass({ // const errMsg = (typeof err === "string") ? err : (err.error || ""); console.error("Failed to set avatar: " + err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { title: _t("Failed to set avatar."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -373,7 +373,7 @@ module.exports = React.createClass({ onLogoutClicked: function(ev) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Logout E2E Export', '', QuestionDialog, { title: _t("Sign out"), description:
@@ -409,7 +409,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change password: " + errMsg); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to change password', err.toString(), ErrorDialog, { title: _t("Error"), description: errMsg, }); @@ -417,7 +417,7 @@ module.exports = React.createClass({ onPasswordChanged: function() { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Password changed', '', ErrorDialog, { title: _t("Success"), description: _t( "Your password was successfully changed. You will not receive " + @@ -442,7 +442,7 @@ module.exports = React.createClass({ const emailAddress = this.refs.add_email_input.value; if (!Email.looksValid(emailAddress)) { - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid email address', '', ErrorDialog, { title: _t("Invalid Email Address"), description: _t("This doesn't appear to be a valid email address"), }); @@ -452,7 +452,7 @@ module.exports = React.createClass({ // we always bind emails when registering, so let's do the // same here. this._addThreepid.addEmailAddress(emailAddress, true).done(() => { - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( "Please check your email and click on the link it contains. Once this " + @@ -464,7 +464,7 @@ module.exports = React.createClass({ }, (err) => { this.setState({email_add_pending: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -475,7 +475,7 @@ module.exports = React.createClass({ onRemoveThreepidClicked: function(threepid) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Remove 3pid', '', QuestionDialog, { title: _t("Remove Contact Information?"), description: _t("Remove %(threePid)s?", { threePid: threepid.address }), button: _t('Remove'), @@ -489,7 +489,7 @@ module.exports = React.createClass({ }).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to remove contact information: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Remove 3pid failed', err.toString(), ErrorDialog, { title: _t("Unable to remove contact information"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -521,7 +521,7 @@ module.exports = React.createClass({ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const message = _t("Unable to verify email address.") + " " + _t("Please check your email and click on the link it contains. Once this is done, click continue."); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: message, button: _t('Continue'), @@ -530,7 +530,7 @@ module.exports = React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -540,7 +540,7 @@ module.exports = React.createClass({ _onDeactivateAccountClicked: function() { const DeactivateAccountDialog = sdk.getComponent("dialogs.DeactivateAccountDialog"); - Modal.createDialog(DeactivateAccountDialog, {}); + Modal.createTrackedDialog('Deactivate Account', '', DeactivateAccountDialog, {}); }, _onBugReportClicked: function() { @@ -548,7 +548,7 @@ module.exports = React.createClass({ if (!BugReportDialog) { return; } - Modal.createDialog(BugReportDialog, {}); + Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, {}); }, _onClearCacheClicked: function() { @@ -585,27 +585,23 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - }, - ); + Modal.createTrackedDialogAsync('Export E2E Keys', '', (cb) => { + require.ensure(['../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, _onImportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../async-components/views/dialogs/ImportE2eKeysDialog'], () => { - cb(require('../../async-components/views/dialogs/ImportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - }, - ); + Modal.createTrackedDialogAsync('Import E2E Keys', '', (cb) => { + require.ensure(['../../async-components/views/dialogs/ImportE2eKeysDialog'], () => { + cb(require('../../async-components/views/dialogs/ImportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, _renderReferral: function() { @@ -1004,7 +1000,7 @@ module.exports = React.createClass({ this._refreshMediaDevices, function() { const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('No media permissions', '', ErrorDialog, { title: _t('No media permissions'), description: _t('You may need to manually permit Riot to access your microphone/webcam'), }); diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 18a9dca5dd..2a6d5042dd 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -89,14 +89,14 @@ module.exports = React.createClass({ } else { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Forgot Password Warning', '', QuestionDialog, { title: _t('Warning!'), description:
{ _t( 'Resetting password will currently reset any ' + 'end-to-end encryption keys on all devices, ' + - 'making encrypted chat history unreadable, ' + + 'making encrypted chat history unreadable, ' + 'unless you first export your room keys and re-import ' + 'them afterwards. In future this will be improved.' ) } @@ -121,15 +121,13 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - } - ); + Modal.createTrackedDialogAsync('Export E2E Keys', 'Forgot Password', (cb) => { + require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, onInputChanged: function(stateKey, ev) { @@ -152,7 +150,8 @@ module.exports = React.createClass({ showErrorDialog: function(body, title) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + // TODO this will still lead to i18n in Analytics. + Modal.createTrackedDialog('Forgot Password Error', body, ErrorDialog, { title: title, description: body, }); diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index d3a208a785..156d493fee 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -103,7 +103,7 @@ module.exports = React.createClass({ const ChatCreateOrReuseDialog = sdk.getComponent( "views.dialogs.ChatCreateOrReuseDialog", ); - const close = Modal.createDialog(ChatCreateOrReuseDialog, { + const close = Modal.createTrackedDialog('Create or Reuse', '', ChatCreateOrReuseDialog, { userId: userId, onFinished: (success) => { this.props.onFinished(success); @@ -367,7 +367,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -380,7 +380,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite user', err.toString(), ErrorDialog, { title: _t("Failed to invite user"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -401,7 +401,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -448,7 +448,7 @@ module.exports = React.createClass({ if (errorList.length > 0) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), description: errorList.join(", "), }); diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index e3b7cca078..0ee264b69b 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; +import Analytics from '../../../Analytics'; import MatrixClientPeg from '../../../MatrixClientPeg'; import * as Lifecycle from '../../../Lifecycle'; import Velocity from 'velocity-vector'; @@ -54,6 +55,7 @@ export default class DeactivateAccountDialog extends React.Component { user: MatrixClientPeg.get().credentials.userId, password: this._passwordField.value, }).done(() => { + Analytics.trackEvent('Account', 'Deactivate Account'); Lifecycle.onLoggedOut(); this.props.onFinished(false); }, (err) => { diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index bf48d1757b..889549369d 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -16,7 +16,7 @@ limitations under the License. /* * Usage: - * Modal.createDialog(ErrorDialog, { + * Modal.createTrackedDialog('An Identifier', err.toString(), ErrorDialog, { * title: "some text", (default: "Error") * description: "some more text", * button: "Button Text", diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 61391d281c..aed8e6a5af 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -88,7 +88,7 @@ export default React.createClass({ const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); console.log("KeyShareDialog: Starting verify dialog"); - Modal.createDialog(DeviceVerifyDialog, { + Modal.createTrackedDialog('Key Share', 'Starting dialog', DeviceVerifyDialog, { userId: this.props.userId, device: this.state.deviceInfo, onFinished: (verified) => { diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index a3eb7c6962..010072e8c6 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,7 +31,7 @@ export default React.createClass({ _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); - Modal.createDialog(BugReportDialog, {}); + Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, _continueClicked: function() { diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 3c38064ee1..b5efbab8b7 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -55,7 +55,7 @@ export default React.createClass({ const emailAddress = this.state.emailAddress; if (!Email.looksValid(emailAddress)) { - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid Email Address', '', ErrorDialog, { title: _t("Invalid Email Address"), description: _t("This doesn't appear to be a valid email address"), }); @@ -65,7 +65,7 @@ export default React.createClass({ // we always bind emails when registering, so let's do the // same here. this._addThreepid.addEmailAddress(emailAddress, true).done(() => { - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( "Please check your email and click on the link it contains. Once this " + @@ -77,7 +77,7 @@ export default React.createClass({ }, (err) => { this.setState({emailBusy: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -106,7 +106,7 @@ export default React.createClass({ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const message = _t("Unable to verify email address.") + " " + _t("Please check your email and click on the link it contains. Once this is done, click continue."); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', 'M_THREEPID_AUTH_FAILED', QuestionDialog, { title: _t("Verification Pending"), description: message, button: _t('Continue'), @@ -115,7 +115,7 @@ export default React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 9573b9fd9f..76ab5ed989 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -95,7 +95,7 @@ export default React.createClass({ console.log("Edit widget ID ", this.props.id); const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = this._scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'type_' + this.props.type); - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); }, diff --git a/src/components/views/elements/DeviceVerifyButtons.js b/src/components/views/elements/DeviceVerifyButtons.js index dfca7e2600..bfe45905a1 100644 --- a/src/components/views/elements/DeviceVerifyButtons.js +++ b/src/components/views/elements/DeviceVerifyButtons.js @@ -52,7 +52,7 @@ export default React.createClass({ onVerifyClick: function() { const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); - Modal.createDialog(DeviceVerifyDialog, { + Modal.createTrackedDialog('Device Verify Dialog', '', DeviceVerifyDialog, { userId: this.props.userId, device: this.state.device, }); diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index ff07cd36e5..d5b7bcf46a 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -95,7 +95,7 @@ module.exports = React.createClass({ if (this.allFieldsValid()) { if (this.refs.email.value == '') { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, { title: _t("Warning!"), description:
diff --git a/src/components/views/login/ServerConfig.js b/src/components/views/login/ServerConfig.js index a63d02416c..0042ab5e9f 100644 --- a/src/components/views/login/ServerConfig.js +++ b/src/components/views/login/ServerConfig.js @@ -122,7 +122,7 @@ module.exports = React.createClass({ showHelpPopup: function() { var CustomServerDialog = sdk.getComponent('login.CustomServerDialog'); - Modal.createDialog(CustomServerDialog); + Modal.createTrackedDialog('Custom Server Dialog', '', CustomServerDialog); }, render: function() { diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index bccae923eb..b300e41e50 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -282,8 +282,8 @@ module.exports = React.createClass({ }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err); - Modal.createDialog(ErrorDialog, { - title: _t("Error"), + Modal.createTrackedDialog('Error decrypting attachment', err.toString(), ErrorDialog, { + title: _t("Error"), description: _t("Error decrypting attachment"), }); }).finally(() => { diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 6d4d01a196..740b0c10ca 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -299,7 +299,7 @@ module.exports = React.createClass({ let completeUrl = scalarClient.getStarterLink(starterLink); let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); let integrationsUrl = SdkConfig.get().integrations_ui_url; - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Add an integration', '', QuestionDialog, { title: _t("Add an Integration"), description:
diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index ba0663153e..f37bd4271a 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -154,7 +154,7 @@ module.exports = React.createClass({ } else { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid alias format', '', ErrorDialog, { title: _t('Invalid alias format'), description: _t('\'%(alias)s\' is not a valid format for an alias', { alias: alias }), }); @@ -170,7 +170,7 @@ module.exports = React.createClass({ } else { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid address format', '', ErrorDialog, { title: _t('Invalid address format'), description: _t('\'%(alias)s\' is not a valid format for an address', { alias: alias }), }); diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 3b8acc3f40..285d43ad6e 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -156,7 +156,7 @@ module.exports = React.createClass({ const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') : null; - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index b3831a7d0d..a2841e907f 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -367,7 +367,7 @@ module.exports = withMatrixClient(React.createClass({ onCryptoClicked: function(e) { var event = this.props.mxEvent; - Modal.createDialogAsync((cb) => { + Modal.createTrackedDialogAsync('Encrypted Event Dialog', '', (cb) => { require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb); }, { event: event, diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 290bd35483..23c5de2eaa 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -229,7 +229,7 @@ module.exports = withMatrixClient(React.createClass({ const membership = this.props.member.membership; const kickLabel = membership === "invite" ? _t("Disinvite") : _t("Kick"); const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onKick', ConfirmUserActionDialog, { member: this.props.member, action: kickLabel, askReason: membership == "join", @@ -248,7 +248,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Kick error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to kick', err.message, ErrorDialog, { title: _t("Failed to kick"), description: ((err && err.message) ? err.message : "Operation failed"), }); @@ -262,7 +262,7 @@ module.exports = withMatrixClient(React.createClass({ onBanOrUnban: function() { const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onBanOrUnban', ConfirmUserActionDialog, { member: this.props.member, action: this.props.member.membership == 'ban' ? _t("Unban") : _t("Ban"), askReason: this.props.member.membership != 'ban', @@ -290,7 +290,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Ban error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to ban user', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to ban user"), }); @@ -340,7 +340,7 @@ module.exports = withMatrixClient(React.createClass({ console.log("Mute toggle success"); }, function(err) { console.error("Mute error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to mute user', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to mute user"), }); @@ -385,7 +385,7 @@ module.exports = withMatrixClient(React.createClass({ dis.dispatch({action: 'view_set_mxid'}); } else { console.error("Toggle moderator error:" + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to toggle moderator status', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to toggle moderator status"), }); @@ -406,7 +406,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change power level " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to change power level', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to change power level"), }); @@ -435,7 +435,7 @@ module.exports = withMatrixClient(React.createClass({ var myPower = powerLevelEvent.getContent().users[this.props.matrixClient.credentials.userId]; if (parseInt(myPower) === parseInt(powerLevel)) { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, { title: _t("Warning!"), description:
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 14f52706ec..51b595eab0 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -99,7 +99,7 @@ export default class MessageComposer extends React.Component { ); } - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Upload Files confirmation', '', QuestionDialog, { title: _t('Upload Files'), description: (
diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index ba1673a9df..34e9e4a1e6 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -667,7 +667,7 @@ export default class MessageComposerInput extends React.Component { }, function(err) { console.error("Command failure: %s", err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Server error', err.toString(), ErrorDialog, { title: _t("Server error"), description: ((err && err.message) ? err.message : _t("Server unavailable, overloaded, or something else went wrong.")), }); @@ -675,7 +675,7 @@ export default class MessageComposerInput extends React.Component { } else if (cmd.error) { console.error(cmd.error); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Command error', cmd.error, ErrorDialog, { title: _t("Command error"), description: cmd.error, }); diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 85aedadf64..741d7085e6 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -119,7 +119,7 @@ module.exports = React.createClass({ const errMsg = (typeof err === "string") ? err : (err.error || ""); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to set avatar: " + errMsg); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { title: _t("Error"), description: _t("Failed to set avatar."), }); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index d6a973f648..b59ad1510c 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -46,7 +46,7 @@ const BannedUser = React.createClass({ _onUnbanClick: function() { const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onUnbanClick', ConfirmUserActionDialog, { member: this.props.member, action: _t('Unban'), danger: false, @@ -58,7 +58,7 @@ const BannedUser = React.createClass({ ).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to unban: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to unban', err.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to unban'), }); @@ -423,7 +423,7 @@ module.exports = React.createClass({ ev.preventDefault(); var value = ev.target.value; - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Privacy warning', '', QuestionDialog, { title: _t('Privacy warning'), description:
@@ -516,7 +516,7 @@ module.exports = React.createClass({ onManageIntegrations(ev) { ev.preventDefault(); var IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', 'onManageIntegrations', IntegrationsManager, { src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId) : null, @@ -549,7 +549,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t('unknown error code'); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { title: _t('Error'), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); @@ -560,7 +560,7 @@ module.exports = React.createClass({ if (!this.refs.encrypt.checked) return; var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('E2E Enable Warning', '', QuestionDialog, { title: _t('Warning!'), description: (
diff --git a/src/components/views/settings/AddPhoneNumber.js b/src/components/views/settings/AddPhoneNumber.js index 7bc551477e..bda488a412 100644 --- a/src/components/views/settings/AddPhoneNumber.js +++ b/src/components/views/settings/AddPhoneNumber.js @@ -82,7 +82,7 @@ export default withMatrixClient(React.createClass({ }).catch((err) => { console.error("Unable to add phone number: " + err); let msg = err.message; - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Add Phone Number Error', err.toString(), ErrorDialog, { title: _t("Error"), description: msg, }); @@ -107,7 +107,7 @@ export default withMatrixClient(React.createClass({ } msgElements.push(
{msg}
); } - Modal.createDialog(TextInputDialog, { + Modal.createTrackedDialog('Prompt for MSISDN Verification Code', '', TextInputDialog, { title: _t("Enter Code"), description:
{msgElements}
, button: _t("Submit"), diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 14ec9806b4..f3c0d9033c 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -104,7 +104,7 @@ module.exports = React.createClass({ } const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Change Password', '', QuestionDialog, { title: _t("Warning!"), description:
@@ -164,7 +164,7 @@ module.exports = React.createClass({ const deferred = Promise.defer(); // Ask for an email otherwise the user has no way to reset their password const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog"); - Modal.createDialog(SetEmailDialog, { + Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { title: _t('Do you want to set an email address?'), onFinished: (confirmed) => { // ignore confirmed, setting an email is optional @@ -175,15 +175,13 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - } - ); + Modal.createTrackedDialogAsync('Export E2E Keys', 'Change Password', (cb) => { + require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, onClickChange: function() { diff --git a/src/components/views/settings/DevicesPanelEntry.js b/src/components/views/settings/DevicesPanelEntry.js index f295a7c2d5..69534f09b1 100644 --- a/src/components/views/settings/DevicesPanelEntry.js +++ b/src/components/views/settings/DevicesPanelEntry.js @@ -71,8 +71,8 @@ export default class DevicesPanelEntry extends React.Component { // pop up an interactive auth dialog var InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); - Modal.createDialog(InteractiveAuthDialog, { - title: _t("Authentication"), + Modal.createTrackedDialog('Delete Device Dialog', InteractiveAuthDialog, { + title: _t("Authentication"), matrixClient: MatrixClientPeg.get(), authData: error.data, makeRequest: this._makeDeleteRequest, diff --git a/src/createRoom.js b/src/createRoom.js index 74e4b3c2fc..2ba3bd06ef 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -115,7 +115,7 @@ function createRoom(opts) { action: 'join_room_error', }); console.error("Failed to create room " + roomId + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failure to create room', err.message, ErrorDialog, { title: _t("Failure to create room"), description: _t("Server may be unavailable, overloaded, or you hit a bug."), }); diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 865caa8997..e4fe1068b7 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -221,7 +221,7 @@ class RoomViewStore extends Store { }); const msg = err.message ? err.message : JSON.stringify(err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to join room', err.toString(), ErrorDialog, { title: _t("Failed to join room"), description: msg, }); From 9bbe3871e7ea55d8348819757ee9dddcbaac15c8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 27 Jul 2017 13:17:10 +0000 Subject: [PATCH 038/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index aca1c7c721..be0aa170f9 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -472,7 +472,7 @@ "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", "Failed to join the room": "Не удалось присоединиться к комнате", - "Access Token:": "Токен:", + "Access Token:": "Токен доступа:", "Always show message timestamps": "Всегда показывать временные метки сообщений", "Authentication": "Авторизация", "olm version:": "Версия olm:", @@ -489,7 +489,7 @@ "Current password": "Текущий пароль", "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", - "Failed to load timeline position": "Не удалось загрузить хронологию", + "Failed to load timeline position": "Не удалось загрузить метку из хронологии", "Failed to mute user": "Не удалось заглушить пользователя", "Failed to reject invite": "Не удалось отклонить приглашение", "Failed to save settings": "Не удалось сохранить настройки", @@ -799,7 +799,7 @@ "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Для верификации устройства, пожалуйста, свяжитесь с владельцем используя другие методы коммуникации (например, лично или по телефону) и попросите его подтвердить, что он видит такой же ключ как написанный ниже:", "Device name": "Имя устройства", "Device key": "Ключ устройства", - "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, то кто-то перехватил это устройство и вы, скорее всего, захотите внести его в черный список.", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, значит кто-то перехватил это устройство и вы, скорее всего, захотите внести его в черный список.", "In future this verification process will be more sophisticated.": "В будущем процесс верификации будет усложнен.", "Verify device": "Верифицировать устройство", "I verify that the keys match": "Я подтверждаю, что ключи совпадают", @@ -815,7 +815,7 @@ "Unblacklist": "Удалить из черного списка", "Blacklist": "Черный список", "Unverify": "Отменить верификацию", - "Verify...": "Верифицировать...", + "Verify...": "Проверка...", "ex. @bob:example.com": "например @bob:example.com", "Add User": "Добавить пользователя", "This Home Server would like to make sure you are not a robot": "Этот домашний сервер хочет убедиться, что вы не робот", From c0d312af10bd7482ee159dff335f03ad655d62e1 Mon Sep 17 00:00:00 2001 From: Andrei Shevchuk Date: Fri, 28 Jul 2017 03:16:55 +0000 Subject: [PATCH 039/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 146 +++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index be0aa170f9..05fdbbc646 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -10,7 +10,7 @@ "Algorithm": "Алгоритм", "all room members": "все участники комнаты", "all room members, from the point they are invited": "все участники комнаты, с момента приглашения", - "all room members, from the point they joined": "все участники комнаты, с момента вступления", + "all room members, from the point they joined": "все участники комнаты, с момента входа", "an address": "адрес", "and": "и", "An email has been sent to": "Email был отправлен", @@ -20,10 +20,10 @@ "Anyone who knows the room's link, apart from guests": "Любой, кто знает ссылку на комнату, кроме гостей", "Anyone who knows the room's link, including guests": "Любой, кто знает ссылку комнаты, включая гостей", "Are you sure you want to reject the invitation?": "Вы уверены что вы хотите отклонить приглашение?", - "Are you sure you want to upload the following files?": "Вы уверены что вы хотите загрузить следующие файлы?", + "Are you sure you want to upload the following files?": "Вы уверены что вы хотите отправить следующие файлы?", "banned": "banned", - "Banned users": "Запрещенный пользователь", - "Bans user with given id": "Запретить пользователя с определенным id", + "Banned users": "Заблокированные пользователи", + "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", @@ -56,9 +56,9 @@ "Decryption error": "Ошибка расшифровки", "Default": "По умолчанию", "demote": "понизить уровень авторизации", - "Deops user with given id": "Удалить пользователь с данным id", + "Deops user with given id": "Снимает полномочия оператора с пользователя с заданным ID", "Device ID": "ID устройства", - "Devices will not yet be able to decrypt history from before they joined the room": "Устройства не смогут дешифровать историю, пока они не войдут в комнату", + "Devices will not yet be able to decrypt history from before they joined the room": "Устройства пока не могут дешифровать историю до их входа в комнату", "Direct Chat": "Прямой чат", "Disable inline URL previews by default": "Отключить предварительный просмотр URL-адресов по умолчанию", "Display name": "Отображаемое имя", @@ -74,14 +74,14 @@ "End-to-end encryption is in beta and may not be reliable": "Сквозное шифрование находится в бета-версии и может быть ненадежным", "Error": "Ошибка", "Event information": "Информация о событии", - "Export E2E room keys": "Экспорт ключей E2E", + "Export E2E room keys": "Экспорт ключей сквозного шифрования", "Failed to change password. Is your password correct?": "Не удалось сменить пароль. Вы правильно ввели текущий пароль?", "Failed to forget room": "Не удалось забыть комнату", "Failed to leave room": "Не удалось выйти из комнаты", "Failed to reject invitation": "Не удалось отклонить приглашение", "Failed to send email": "Ошибка отправки электронной почты", "Failed to unban": "Не удалось разблокировать", - "Failed to upload file": "Не удалось выгрузить файл", + "Failed to upload file": "Не удалось отправить файл", "Favourite": "Избранное", "favourite": "избранный", "Favourites": "Избранные", @@ -94,24 +94,24 @@ "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", - "Identity Server is": "Идентификационный сервер это", + "Identity Server is": "Сервер идентификации это", "I have verified my email address": "Я подтвердил свой адрес электронной почты", - "Import E2E room keys": "Импортировать E2E-ключи комнаты", + "Import E2E room keys": "Импортировать ключи сквозного шифрования комнаты", "Invalid Email Address": "Недопустимый адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", "Invites": "Приглашает", - "Invites user with given id to current room": "Приглашает пользователя с этим ID в текущую комнату", + "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "is a": "является", "Sign in with": "Войти с помощью", - "joined and left": "вошел и вышел", - "joined": "вошел", + "joined and left": "вошёл(ла) и вышел(ла)", + "joined": "вошёл(ла)", "joined the room": "joined the room", - "Joins room with given alias": "Вошел в комнату с этим псевдонимом", - "Kicks user with given id": "Удаляет пользователя с заданным id", + "Joins room with given alias": "Входит в комнату с заданным псевдонимом", + "Kicks user with given id": "Выкидывает пользователя с заданным ID", "Labs": "Лаборатория", "Leave room": "Покинуть комнату", - "left and rejoined": "вышел и вернулся", + "left and rejoined": "вышел(ла) и вернулся(ась)", "left": "вышел", "left the room": "left the room", "Logged in as": "Зарегистрированный как", @@ -125,8 +125,8 @@ "Moderator": "Модератор", "my Matrix ID": "мой Matrix ID", "Name": "Имя", - "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства с этого устройства", - "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства в этой комнате с этого устройства", + "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства с этого устройства", + "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате с этого устройства", "New password": "Новый пароль", "New passwords must match each other.": "Новые пароли должны совпадать.", "none": "никто", @@ -175,7 +175,7 @@ "unknown error code": "неизвестный код ошибки", "unknown": "неизвестный", "Upload avatar": "Загрузить аватар", - "uploaded a file": "отправленный файл", + "uploaded a file": "отправил(а) файл", "Upload Files": "Отправка файлов", "Upload file": "Отправка файла", "User ID": "ID пользователя", @@ -184,7 +184,7 @@ "Users": "Пользователи", "User": "Пользователь", "Verification Pending": "В ожидании подтверждения", - "Verification": "Подтверждение", + "Verification": "Проверка", "verified": "проверенный", "Video call": "Видеозвонок", "Voice call": "Голосовой вызов", @@ -192,10 +192,10 @@ "VoIP conference started.": "VoIP-конференция началась.", "(warning: cannot be disabled again!)": "(предупреждение: отключить будет невозможно!)", "Warning!": "Внимание!", - "was banned": "был заблокирован", + "was banned": "был(а) заблокирован(а)", "was invited": "был приглашен", "was kicked": "был выгнан", - "was unbanned": "был разблокирован", + "was unbanned": "был(а) разблокирован(а)", "was": "был", "were": "быть", "Who can access this room?": "Кто может получить доступ к этой комнате?", @@ -225,7 +225,7 @@ "%(names)s and one other are typing": "%(names)s и другой печатают", "%(names)s and %(count)s others are typing": "%(names)s и %(count)s другие печатают", "%(senderName)s answered the call.": "%(senderName)s ответил на звонок.", - "%(senderName)s banned %(targetName)s.": "%(senderName)s запрещен %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", "Call Timeout": "Время ожидания вызова", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s изменено с %(oldDisplayName)s на %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s изменил фото профиля.", @@ -391,7 +391,7 @@ "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включено сквозное шифрование (algorithm %(algorithm)s).", "Unable to restore previous session": "Не удалось восстановить предыдущий сеанс", - "%(senderName)s unbanned %(targetName)s.": "%(senderName)s разблокировал %(targetName)s.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s разблокировал(а) %(targetName)s.", "Unable to capture screen": "Не удается сделать снимок экрана", "Unable to enable Notifications": "Не удалось включить уведомления", "Upload Failed": "Сбой при отправке", @@ -471,10 +471,10 @@ "Failed to delete device": "Не удалось удалить устройство", "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", - "Failed to join the room": "Не удалось присоединиться к комнате", + "Failed to join the room": "Не удалось войти в комнату", "Access Token:": "Токен доступа:", "Always show message timestamps": "Всегда показывать временные метки сообщений", - "Authentication": "Авторизация", + "Authentication": "Аутентификация", "olm version:": "Версия olm:", "%(items)s and %(remaining)s others": "%(items)s и другие %(remaining)s", "%(items)s and one other": "%(items)s и еще один", @@ -482,7 +482,7 @@ "and one other...": "и еще один...", "An error has occurred.": "Произошла ошибка.", "Attachment": "Вложение", - "Ban": "Запретить", + "Ban": "Заблокировать", "Change Password": "Сменить пароль", "Command error": "Ошибка команды", "Confirm password": "Подтвердите пароль", @@ -496,7 +496,7 @@ "Failed to set display name": "Не удалось задать отображаемое имя", "Failed to toggle moderator status": "Не удалось изменить статус модератора", "Fill screen": "Заполнить экран", - "Guest users can't upload files. Please register to upload.": "Гости не могут посылать файлы. Зарегистрируйтесь для отправки.", + "Guest users can't upload files. Please register to upload.": "Гости не могут отправлять файлы. Зарегистрируйтесь для отправки.", "Hide read receipts": "Скрыть отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", "Incorrect verification code": "Неверный код подтверждения", @@ -512,7 +512,7 @@ "Markdown is disabled": "Markdown отключен", "Markdown is enabled": "Markdown включен", "matrix-react-sdk version:": "версия matrix-react-sdk:", - "Never send encrypted messages to unverified devices in this room": "Никогда не отправлять зашифрованные сообщения на неподтвержденные устройства в этой комнате", + "Never send encrypted messages to unverified devices in this room": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате", "New address (e.g. #foo:%(localDomain)s)": "Новый адрес (например, #foo:%(localDomain)s)", "New passwords don't match": "Новые пароли не совпадают", "not set": "не задано", @@ -537,7 +537,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", "Report it": "Сообщить об этом", - "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованный историю чатов нечитаемой. Вы можете избежать этого экспортировав ключи комнаты и затем повторно их импортировав в настройках. В будущем это будет улучшено.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "restore": "восстановить", "Return to app": "Вернуться в приложение", "Riot does not have permission to send you notifications - please check your browser settings": "Riot не имеет разрешение на отправку уведомлений, проверьте параметры своего браузера", @@ -556,7 +556,7 @@ "Sender device information": "Информация об устройстве отправителя", "Send Invites": "Отправить приглашения", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s отправил изображение.", - "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s отправил приглашение для %(targetDisplayName)s войти в комнату.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s отправил(а) приглашение для %(targetDisplayName)s войти в комнату.", "sent a video": "отправил видео", "Show panel": "Показать панель", "Sign in": "Войти", @@ -576,12 +576,12 @@ "This email address is already in use": "Этот адрес электронной почты уже используется", "This email address was not found": "Этот адрес электронной почты не найден", "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", - "The file '%(fileName)s' failed to upload": "Не удалось загрузить файл '%(fileName)s'", + "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", "The remote side failed to pick up": "Вызываемый абонент не ответил", "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", - "This doesn't appear to be a valid email address": "Похоже это недействительный адрес электронной почты", + "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес электронной почты", "This is a preview of this room. Room interactions have been disabled": "Это предварительный просмотр комнаты. Взаимодействие с комнатой отключено", "This phone number is already in use": "Этот номер телефона уже используется", "This room's internal ID is": "Внутренний ID этой комнаты", @@ -594,7 +594,7 @@ "Unknown command": "Неизвестная команда", "Unknown room %(roomId)s": "Неизвестная комната %(roomId)s", "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в комнату", - "You seem to be uploading files, are you sure you want to quit?": "Похоже вы отправляете файлы, вы уверены, что хотите выйти?", + "You seem to be uploading files, are you sure you want to quit?": "Похоже, вы отправляете файлы, вы уверены, что хотите выйти?", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", "Make Moderator": "Сделать модератором", "Room": "Комната", @@ -607,22 +607,22 @@ "quote": "цитата", "bullet": "список", "numbullet": "нумерованный список", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s присоединились %(repeats)s раз", - "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s присоединился %(repeats)s раз", - "%(severalUsers)sjoined": "%(severalUsers)s присоединились", - "%(oneUser)sjoined": "%(oneUser)s присоединился", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s вошли %(repeats)s раз", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s вошёл(ла) %(repeats)s раз", + "%(severalUsers)sjoined": "%(severalUsers)s вошли", + "%(oneUser)sjoined": "%(oneUser)s вошёл(ла)", "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s покинули %(repeats)s раз", "%(oneUser)sleft %(repeats)s times": "%(oneUser)s покинул %(repeats)s раз", "%(severalUsers)sleft": "%(severalUsers)s покинули", "%(oneUser)sleft": "%(oneUser)s покинул", - "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s присоединились и покинули %(repeats)s раз", - "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s присоединился и покинул %(repeats)s раз", - "%(severalUsers)sjoined and left": "%(severalUsers)s присоединились и покинули", - "%(oneUser)sjoined and left": "%(oneUser)s присоединился и покинул", - "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s покинули и снова присоединились %(repeats)s раз", - "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s покинул и снова присоединился %(repeats)s раз", - "%(severalUsers)sleft and rejoined": "%(severalUsers)s покинули и снова присоединились", - "%(oneUser)sleft and rejoined": "%(oneUser)s покинул и снова присоединился", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s вошли и вышли %(repeats)s раз", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s вошёл(ла) и вышел(ла) %(repeats)s раз", + "%(severalUsers)sjoined and left": "%(severalUsers)s вошли и вышли", + "%(oneUser)sjoined and left": "%(oneUser)s вошёл(ла) и вышел(ла)", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s вышли и вернулись %(repeats)s раз", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s вышел(ла) и вернулся(ась) %(repeats)s раз", + "%(severalUsers)sleft and rejoined": "%(severalUsers)s вышли и вернулись", + "%(oneUser)sleft and rejoined": "%(oneUser)s вышел(ла) и вернулся(ась)", "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s отклонили приглашения %(repeats)s раз", "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)s отклонил приглашения %(repeats)s раз", "%(severalUsers)srejected their invitations": "%(severalUsers)s отклонили приглашения", @@ -631,7 +631,7 @@ "was invited %(repeats)s times": "был приглашен %(repeats)s раз", "were invited": "были приглашены", "were banned %(repeats)s times": "были заблокированы %(repeats)s раз", - "was banned %(repeats)s times": "был заблокирован %(repeats)s раз", + "was banned %(repeats)s times": "был(а) заблокирован(а) %(repeats)s раз", "were banned": "были заблокированы", "were unbanned %(repeats)s times": "были разблокированы %(repeats)s раз", "was unbanned %(repeats)s times": "были разблокирован %(repeats)s раз", @@ -648,7 +648,7 @@ "%(severalUsers)schanged their avatar": "%(severalUsers)s изменили свои аватары", "%(oneUser)schanged their avatar": "%(oneUser)s изменил свой ававтар", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", - "Dismiss": "Отказ", + "Dismiss": "Отклонить", "Custom Server Options": "Настраиваемые параметры сервера", "Mute": "Беззвучный", "Operation failed": "Сбой операции", @@ -670,20 +670,20 @@ "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", "VoIP": "VoIP", - "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Для обеспечения безопасности при выходе из этого браузера удалятся все ключи шифрования. Если вы хотите иметь возможность расшифровать переписку в будущем, необходимо экспортировать ключи вручную.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Для обеспечения безопасности при выходе будут удалены все ключи сквозного шифрования из этого браузера. Если вы хотите иметь возможность расшифровать историю сообщений в будущем, необходимо экспортировать ключи комнат вручную.", "Guest access is disabled on this Home Server.": "Гостевой доступ отключен на этом сервере.", "Guests can't set avatars. Please register.": "Гости не могут устанавливать аватары. Пожалуйста, зарегистрируйтесь.", "Guests can't use labs features. Please register.": "Гости не могут использовать экспериментальные возможности. Пожалуйста, зарегистрируйтесь.", - "Guests cannot join this room even if explicitly invited.": "Гости не могут присоединиться к этой комнате, даже если они приглашены.", + "Guests cannot join this room even if explicitly invited.": "Гости не могут войти в эту комнату, даже если они приглашены.", "Missing Media Permissions, click here to request.": "Отсутствуют разрешения, нажмите для запроса.", "No media permissions": "Нет разрешенных носителей", "You may need to manually permit Riot to access your microphone/webcam": "Вам необходимо предоставить Riot доступ к микрофону или веб-камере вручную", "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил имя комнаты.", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля также сбросит ключи шифрования на всех устройствах, сделав зашифрованную историю чата недоступной. Чтобы этого не произошло, экспортируйте ключи шифрования и импортируйте их после смены пароля. В будущем это будет исправлено.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая зашифрованную историю чата нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", - "Device already verified!": "Устройство уже верифицировано!", + "Device already verified!": "Устройство уже проверено!", "Device ID:": "ID устройства:", "device id: ": "ID устройства: ", "Device key:": "Ключ устройства:", @@ -701,7 +701,7 @@ "Invalid file%(extra)s": "Недопустимый файл%(extra)s", "Invited": "Приглашен", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", - "List this room in %(domain)s's room directory?": "Показывать эту комнату в списке комнат %(domain)s?", + "List this room in %(domain)s's room directory?": "Показывать эту комнату в каталоге комнат %(domain)s?", "Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств", "Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)", "Once you've followed the link it contains, click below": "После перехода по ссылке, нажмите на кнопку ниже", @@ -728,9 +728,9 @@ "Signed Out": "Вышли", "Sorry, this homeserver is using a login which is not recognised ": "К сожалению, этот домашний сервер использует неизвестный метод авторизации ", "Tagged as: ": "Теги: ", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ соответствует ключу подписи, полученному от %(userId)s с ID %(deviceId)s. Устройство помечено как проверенное.", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ подписи соответствует ключу, полученному от %(userId)s с устройства %(deviceId)s. Устройство помечено как проверенное.", "%(actionVerb)s this person?": "%(actionVerb)s этот человек?", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер для этого домашнего сервера для загрузки", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер, допустимый к отправке на этом домашнем сервере", "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса электронной почты.", "There was a problem logging in.": "Возникла проблема при авторизации.", "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", @@ -755,8 +755,8 @@ "Unrecognised command:": "Нераспознанная команда:", "Unrecognised room alias:": "Нераспознанный псевдоним комнаты:", "Verified key": "Проверенный ключ", - "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было верифицировано, однако ключи НЕ СОВПАДАЮТ!", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ВЕРИФИКАЦИИ КЛЮЧЕЙ! Ключ подписи для пользователя %(userId)s и устройства %(deviceId)s - \"%(fprint)s\" не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваши сообщения перехватываются!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было проверено, однако ключи НЕ СОВПАДАЮТ!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!", "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес электронной почты.", @@ -782,7 +782,7 @@ "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому вы должны ввести парольную фразу ниже, которая будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная эту парольную фразу.", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Этот процесс позволит вам импортировать ключи шифрования, которые вы экспортировали ранее из клиента Matrix. Это позволит вам расшифровать историю чата.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Файл экспорта будет защищен паролем. Для расшифровки файла необходимо ввести парольную фразу.", - "You must join the room to see its files": "Вы должны присоединиться к комнате, чтобы просмотреть файлы", + "You must join the room to see its files": "Вы должны войти в комнату, чтобы просмотреть файлы", "Reject all %(invitedRooms)s invites": "Отклонить все %(invitedRooms)s приглашения", "Start new chat": "Начать новый чат", "Guest users can't invite users. Please register.": "Гости не могут приглашать пользователей. Пожалуйста, зарегистрируйтесь.", @@ -796,26 +796,26 @@ "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Таким образом, ваша учетная запись будет заблокирована навсегда. Вы не сможете зарегистрироваться снова с тем же идентификатором пользователя.", "This action is irreversible.": "Это действие необратимо.", "To continue, please enter your password.": "Для продолжения введите ваш пароль.", - "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Для верификации устройства, пожалуйста, свяжитесь с владельцем используя другие методы коммуникации (например, лично или по телефону) и попросите его подтвердить, что он видит такой же ключ как написанный ниже:", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Чтобы удостовериться, что этому устройству можно доверять, пожалуйста, свяжитесь с владельцем другим способом (например, лично или по телефону) и спросите его, совпадает ли ключ, указанный у него в настройках для этого устройства, с ключом ниже:", "Device name": "Имя устройства", "Device key": "Ключ устройства", - "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, значит кто-то перехватил это устройство и вы, скорее всего, захотите внести его в черный список.", - "In future this verification process will be more sophisticated.": "В будущем процесс верификации будет усложнен.", - "Verify device": "Верифицировать устройство", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, нажмите кнопку подтверждения ниже. Если нет — значит, кто-то перехватил это устройство, и вы, скорее всего, захотите внести его в чёрный список.", + "In future this verification process will be more sophisticated.": "В будущем процесс проверки будет усовершенствован.", + "Verify device": "Проверить устройство", "I verify that the keys match": "Я подтверждаю, что ключи совпадают", "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Произошла ошибка при попытке восстановить предыдущий сеанс. Если продолжить, потребуется снова войти в систему, а зашифрованная история чата будет нечитаема.", "Unable to restore session": "Восстановление сессии не удалось", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию Riot, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.", "Continue anyway": "Все равно продолжить", "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Отображаемое имя - это то, как вы отображаетесь в чате. Какое имя вы хотите?", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Ваши текущие неверифицированные занесенные в черный список устройства; для отправки сообщений на эти устройства вам необходимо их верифицировать.", - "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Мы рекомендуем вам выполнить процедуру проверки для каждого устройства, чтобы подтвердить, что они принадлежат их законному владельцу, но вы можете отправить сообщение без проверки, если хотите.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "У вас включено занесение непроверенных устройств в чёрный список. Для отправки сообщений на эти устройства вам необходимо их проверить.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Мы рекомендуем вам выполнить процедуру проверки каждого устройства, чтобы удостовериться, что они принадлежат их законному владельцу, но вы можете переотправить сообщение без проверки, если хотите.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неподтвержденные устройства.", "Unknown Address": "Неизвестный адрес", "Unblacklist": "Удалить из черного списка", "Blacklist": "Черный список", - "Unverify": "Отменить верификацию", - "Verify...": "Проверка...", + "Unverify": "Отозвать статус проверенного", + "Verify...": "Проверить...", "ex. @bob:example.com": "например @bob:example.com", "Add User": "Добавить пользователя", "This Home Server would like to make sure you are not a robot": "Этот домашний сервер хочет убедиться, что вы не робот", @@ -846,7 +846,7 @@ "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Предварительный просмотр URL-адресов %(globalDisableUrlPreview)s по умолчанию для участников этой комнаты.", "URL Previews": "Предварительный просмотр URL-адресов", "Enable URL previews for this room (affects only you)": "Включить предварительный просмотр URL-адресов для этой комнаты (влияет только на вас)", - "Drop file here to upload": "Перетащите файл сюда для загрузки", + "Drop file here to upload": "Перетащите файл сюда для отправки", " (unsupported)": " (не поддерживается)", "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", "for %(amount)ss": "уже %(amount)sсек", @@ -904,7 +904,7 @@ "Encrypted by an unverified device": "Зашифровано непроверенным устройством", "Encryption is enabled in this room": "Шифрование в этой комнате включено", "Encryption is not enabled in this room": "Шифрование в этой комнате не включено", - "Failed to upload profile picture!": "Не удалось выгрузить фотографию профиля!", + "Failed to upload profile picture!": "Не удалось отправить фотографию профиля!", "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", @@ -941,7 +941,7 @@ "Upload new:": "Отправить новый:", "%(user)s is a": "%(user)s является", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", - "Verified": "Подтвержден", + "Verified": "Проверено", "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", "(~%(count)s results).one": "(~%(count)s результат)", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш SSL-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", @@ -953,16 +953,16 @@ "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", - "Not a valid Riot keyfile": "Недействительный ключевой файл Riot", + "Not a valid Riot keyfile": "Недействительный файл ключа Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", - "Authentication check failed: incorrect password?": "Ошибка авторизации: неправильный пароль?", + "Authentication check failed: incorrect password?": "Ошибка аутентификации: неправильный пароль?", "Do you want to set an email address?": "Хотите указать адрес электронной почты?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или для просмотра каталога", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы ещё не находитесь ни в одной комнате! Нажмите , чтобы создать комнату или для просмотра каталога", "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", "Skip": "Пропустить", - "Start verification": "Начать верификацию", + "Start verification": "Начать проверку", "Share without verifying": "Поделиться без проверки", "Ignore request": "Игнорировать запрос", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Вы добавили новое устройство '%(displayName)s', которое требует ключи шифрования.", From f4f85d053d1bd6b2c02760161eed12c86963d3d2 Mon Sep 17 00:00:00 2001 From: Andrei Shevchuk Date: Fri, 28 Jul 2017 03:35:38 +0000 Subject: [PATCH 040/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 05fdbbc646..522fa75b90 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -661,8 +661,8 @@ "Unknown devices": "Неизвестное устройство", "Camera": "Камера", "Microphone": "Микрофон", - "Desktop specific": "Локальные настройки", - "Start automatically after system login": "Автоматический запуск после подключения", + "Desktop specific": "Специфичные для компьютера", + "Start automatically after system login": "Автозапуск при входе в систему", "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", "Opt out of analytics": "Не собирать аналитические данные", @@ -771,17 +771,17 @@ "%(oneUser)shad their invitation withdrawn": "%(oneUser)s отозвал свое приглашение", "Please select the destination room for this message": "Выберите комнату для отправки этого сообщения", "Options": "Настройки", - "Passphrases must match": "Парольные фразы должны совпадать", - "Passphrase must not be empty": "Парольная фраза не должна быть пустой", + "Passphrases must match": "Пароли должны совпадать", + "Passphrase must not be empty": "Пароль не должен быть пустым", "Export room keys": "Экспорт ключей комнаты", - "Enter passphrase": "Введите парольную фразу", - "Confirm passphrase": "Подтвердите парольную фразу", + "Enter passphrase": "Введите пароль", + "Confirm passphrase": "Подтвердите пароль", "Import room keys": "Импорт ключей комнаты", "File to import": "Файл для импорта", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Этот процесс позволяет вам экспортировать ключи для сообщений, которые вы получили в комнатах с шифрованием, в локальный файл. Вы сможете импортировать эти ключи в другой клиент Matrix чтобы расшифровать эти сообщения.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому вы должны ввести парольную фразу ниже, которая будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная эту парольную фразу.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому, ниже вы должны ввести пароль, который будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная этот пароль.", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Этот процесс позволит вам импортировать ключи шифрования, которые вы экспортировали ранее из клиента Matrix. Это позволит вам расшифровать историю чата.", - "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Файл экспорта будет защищен паролем. Для расшифровки файла необходимо ввести парольную фразу.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Файл экспорта будет защищен паролем. Для расшифровки файла необходимо ввести пароль.", "You must join the room to see its files": "Вы должны войти в комнату, чтобы просмотреть файлы", "Reject all %(invitedRooms)s invites": "Отклонить все %(invitedRooms)s приглашения", "Start new chat": "Начать новый чат", From 25d1d21d93c9508fd3ae92f458452385e4c1bb41 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 31 Jul 2017 13:28:43 +0100 Subject: [PATCH 041/164] copy logic from RegistrationForm to detect invalid localparts --- src/components/views/dialogs/SetMxIdDialog.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 4d4f672f2b..6c3b1516d0 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -106,6 +106,15 @@ export default React.createClass({ }, _doUsernameCheck: function() { + // XXX: SPEC-1 + // Check if username is valid + if (encodeURIComponent(this.state.username) !== this.state.username) { + this.setState({ + usernameError: _t('User names may only contain letters, numbers, dots, hyphens and underscores.'), + }); + return Promise.resolve(); + } + // Check if username is available return this._matrixClient.isUsernameAvailable(this.state.username).then( (isAvailable) => { From f310d4446ca36be243bb92c5cfcc442a5e58aca1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 31 Jul 2017 13:31:07 +0100 Subject: [PATCH 042/164] i18n the title of the set mxid dialog --- src/components/views/dialogs/SetMxIdDialog.js | 2 +- src/i18n/strings/en_EN.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 6c3b1516d0..2462f24a87 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -251,7 +251,7 @@ export default React.createClass({ return (
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7b027b6417..fd70a49311 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -571,6 +571,7 @@ "To configure the room": "To configure the room", "to demote": "to demote", "to favourite": "to favourite", + "To get started, please pick a username!": "To get started, please pick a username!", "To invite users into the room": "To invite users into the room", "To kick users": "To kick users", "To link to a room it must have an address.": "To link to a room it must have an address.", From 62af06104dd2492b0ac5a0cf1f20b64b1ceec19e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 31 Jul 2017 14:22:05 +0100 Subject: [PATCH 043/164] resolve -> reject because semantics. --- src/components/views/dialogs/SetMxIdDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 2462f24a87..9fb6b838b2 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -112,7 +112,7 @@ export default React.createClass({ this.setState({ usernameError: _t('User names may only contain letters, numbers, dots, hyphens and underscores.'), }); - return Promise.resolve(); + return Promise.reject(); } // Check if username is available From 435455c9f0e52812d27abb9a57cfddd19d688902 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 1 Aug 2017 15:29:58 +0000 Subject: [PATCH 044/164] Added translation using Weblate (Basque) --- src/i18n/strings/eu.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/eu.json diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/eu.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 2a822015515601f660fb2aa6352763257acd7e34 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 1 Aug 2017 16:06:46 +0000 Subject: [PATCH 045/164] Translated using Weblate (Basque) Currently translated at 17.1% (157 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 160 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 9e26dfeeb6..daca88e67b 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1 +1,159 @@ -{} \ No newline at end of file +{ + "af": "Afrikaans", + "ar-ae": "Arabiera (Arabiar Emirerri Batuak)", + "ar-bh": "Arabiera (Bahrain)", + "ar-dz": "Arabiera (Algeria)", + "ar-eg": "Arabiera (Egipto)", + "ar-iq": "Arabiera (Irak)", + "ar-jo": "Arabiera (Jordania)", + "ar-kw": "Arabiera (Kuwait)", + "ar-lb": "Arabiera (Libano)", + "ar-ly": "Arabiera (Libia)", + "ar-ma": "Arabiera (Maroko)", + "ar-om": "Arabiera (Oman)", + "ar-qa": "Arabiera (Qatar)", + "ar-sa": "Arabiera (Saudi Arabia)", + "Cancel": "Utzi", + "ar-sy": "Arabiera (Siria)", + "ar-tn": "Arabiera (Tunisia)", + "ar-ye": "Arabiera (Yemen)", + "be": "Bielorrusiera", + "bg": "Bulgariera", + "ca": "Katalana", + "cs": "Txekiera", + "da": "Daniera", + "de-at": "Alemana (Austria)", + "de-ch": "Alemana (Suitza)", + "de": "Alemana", + "de-li": "Alemana (Liechtenstein)", + "de-lu": "Alemana (Luxenburgo)", + "el": "Greziera", + "en-au": "Ingelesa (Australia)", + "en-bz": "Ingelesa (Belize)", + "en-ca": "Ingelesa (Kanada)", + "en": "Ingelesa", + "en-gb": "Ingelesa (Erresuma batua)", + "en-ie": "Ingelesa (Irlanda)", + "en-jm": "Ingelesa (Jamaika)", + "en-nz": "Ingelesa (Zeelanda Berria)", + "en-tt": "Ingelesa (Trinidad)", + "en-us": "Ingelesa (Estatu Batuak)", + "en-za": "Ingelesa (Hego Afrika)", + "es-ar": "Espainiera (Argentina)", + "es-bo": "Espainiera (Bolivia)", + "es-cl": "Espainiera (Txile)", + "es-co": "Espainiera (Kolonbia)", + "es-cr": "Espainiera (Costa Rica)", + "es-do": "Espainiera (Dominikar Errepublika)", + "es-ec": "Espainiera (Ekuador)", + "es-gt": "Espainiera (Guatemala)", + "es-hn": "Espainiera (Honduras)", + "es-mx": "Espainiera (Mexiko)", + "es-ni": "Espainiera (Nikaragua)", + "es-pa": "Espainiera (Panama)", + "es-pe": "Espainiera (Peru)", + "es-pr": "Espainiera (Puerto Rico)", + "es-py": "Espainiera (Paraguay)", + "es": "Espainiera (Espainia)", + "es-sv": "Espainiera (El Salvador)", + "es-uy": "Espainiera (Uruguai)", + "es-ve": "Espainiera (Venezuela)", + "et": "Estoniera", + "eu": "Euskara", + "fa": "Farsiera", + "fi": "Finlandiera", + "fo": "Faroera", + "fr-be": "Frantsesa (Belgika)", + "fr-ca": "Frantsesa (Kanada)", + "fr-ch": "Frantsesa (Suitza)", + "fr": "Frantsesa", + "fr-lu": "Frantsesa (Luxenburgo)", + "ga": "Irlandera", + "gd": "Gaelikoa (Eskozia)", + "he": "Hebreera", + "hi": "Hindi", + "hr": "Kroaziera", + "hu": "Hungariera", + "id": "Indonesiera", + "is": "Islandiera", + "it-ch": "Italiera (Suitza)", + "it": "Italiera", + "ja": "Japoniera", + "ji": "Yiddish", + "ko": "Korearra", + "lt": "Lituaniera", + "lv": "Letoniera", + "mk": "Mazedoniera (FYROM)", + "ms": "Malaysiera", + "mt": "Maltera", + "nl-be": "Nederlandera (Belgika)", + "nl": "Nederlandera", + "no": "Norvegiera", + "pl": "Poloniera", + "pt-br": "Brasilgo portugalera", + "pt": "Portugalera", + "rm": "Erretorromaniera", + "ro-mo": "Errumaniera (Moldavia)", + "ro": "Errumaniera", + "ru-mo": "Errusiera (Moldavia)", + "ru": "Errusiera", + "sb": "Sorbiera", + "sk": "Eslovakiera", + "sl": "Esloveniera", + "sq": "Albaniera", + "sr": "Serbiera", + "sv-fi": "Suediera (Finlandia)", + "sv": "Suediera", + "sx": "Sutu", + "sz": "Sami (Laponiera)", + "th": "Thailandiera", + "tn": "Tswana", + "tr": "Turkiera", + "ts": "Tsonga", + "uk": "Ukrainera", + "ur": "Urdu", + "ve": "Vendera", + "vi": "Vietnamera", + "xh": "Xhosera", + "zh-cn": "Txinera (PRC)", + "zh-hk": "Txinera (Hong Kong)", + "zh-sg": "Txinera (Singapur)", + "zh-tw": "Txinera (Taiwan)", + "zu": "Zulu", + "a room": "gela bat", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Mezu bat bidali da +%(msisdn)s zenbakira. Sartu hemen mezuko egiaztaketa kodea", + "Accept": "Onartu", + "%(targetName)s accepted an invitation.": "%(targetName)s erabiltzaileak gonbidapena onartu du.", + "Close": "Itxi", + "Create new room": "Sortu gela berria", + "Welcome page": "Ongi etorri orria", + "Continue": "Jarraitu", + "Direct Chat": "Txat zuzena", + "Drop here %(toAction)s": "Jaregin hona %(toAction)s", + "Error": "Errorea", + "Failed to change password. Is your password correct?": "Pasahitza aldatzean huts egin du. Zuzena da pasahitza?", + "Failed to forget room %(errCode)s": "Huts egin du %(errCode)s gela ahaztean", + "Failed to join the room": "Huts egin du gelara elkartzean", + "Favourite": "Gogokoa", + "Mute": "Mututu", + "Notifications": "Jakinarazpenak", + "OK": "Ados", + "Operation failed": "Eragiketak huts egin du", + "Please Register": "Erregistratu", + "Remove": "Kendu", + "Search": "Bilatu", + "Settings": "Ezarpenak", + "unknown error code": "errore kode ezezaguna", + "Monday": "Astelehena", + "Tuesday": "Asteartea", + "Wednesday": "Asteazkena", + "Thursday": "Osteguna", + "Friday": "Ostirala", + "Saturday": "Larunbata", + "Sunday": "Igandea", + "Room directory": "Gelen direktorioa", + "Start chat": "Hasi txata", + "Custom Server Options": "Zerbitzari pertsonalizatuaren aukerak", + "Dismiss": "Baztertu", + "powered by Matrix": "Matrix mamian" +} From 240a3545d0f6aca9f9c882bb28e3f79d1dca5821 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 1 Aug 2017 16:11:16 +0000 Subject: [PATCH 046/164] Translated using Weblate (Basque) Currently translated at 29.2% (268 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 113 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index daca88e67b..e057592e1c 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -155,5 +155,116 @@ "Start chat": "Hasi txata", "Custom Server Options": "Zerbitzari pertsonalizatuaren aukerak", "Dismiss": "Baztertu", - "powered by Matrix": "Matrix mamian" + "powered by Matrix": "Matrix mamian", + "Room": "Gela", + "Historical": "Historiala", + "Save": "Gorde", + "Delete": "Ezabatu", + "Active call": "Dei aktiboa", + "Conference calls are not supported in encrypted rooms": "Konferentzia deiak ez daude onartuta zifratutako geletan", + "or": "edo", + "and": "eta", + "Sign out": "Amaitu saioa", + "Home": "Hasiera", + "Favourites": "Gogokoak", + "People": "Jendea", + "Rooms": "Gelak", + "Invites": "Gonbidapenak", + "Low priority": "Lehentasun baxua", + "No results": "Emaitzarik ez", + "Bug Report": "Arazte txostena", + "Join Room": "Elkartu gelara", + "Register": "Erregistratu", + "Submit": "Bidali", + "Skip": "Saltatu", + "Send Reset Email": "Bidali berrezartzeko e-maila", + "Return to login screen": "Itzuli saio hasierarako pantailara", + "Password": "Pasahitza", + "New password": "Pasahitz berria", + "User name": "Erabiltzaile-izena", + "Email address": "E-mail helbidea", + "Email address (optional)": "E-mail helbidea (aukerazkoa)", + "Confirm your new password": "Berretsi zure pasahitza", + "This Home Server would like to make sure you are not a robot": "Hasiera zerbitzari honek robot bat ez zarela egiaztatu nahi du", + "I have verified my email address": "Nire e-mail helbidea baieztatu dut", + "The email address linked to your account must be entered.": "Zure kontura gehitutako e-mail helbidea sartu behar da.", + "A new password must be entered.": "Pasahitz berri bat sartu behar da.", + "Failed to verify email address: make sure you clicked the link in the email": "Huts egin du e-mail helbidearen egiaztaketak, egin klik e-mailean zetorren estekan", + "Jump to first unread message.": "Jauzi irakurri gabeko lehen mezura.", + "Warning!": "Abisua!", + "Leave room": "Atera gelatik", + "Online": "Konektatuta", + "Offline": "Deskonektatuta", + "Idle": "Inaktibo", + "Ban": "Debekatu", + "Unban": "Debekua kendu", + "Connectivity to the server has been lost.": "Zerbitzariarekin konexioa galdu da.", + "You do not have permission to post to this room": "Ez duzu gela honetan idazteko baimena", + "Logout": "Amaitu saioa", + "Filter room members": "Iragazi gelako kideak", + "Email": "E-mail", + "Add email address": "Gehitu e-mail helbidea", + "Phone": "Telefonoa", + "Add phone number": "Gehitu telefono zenbakia", + "Advanced": "Aurreratua", + "Cryptography": "Kriptografia", + "Devices": "Gailuak", + "Hide read receipts": "Ezkutatu irakurtze-agiria", + "Don't send typing notifications": "Ez bidali idatzi bitarteko jakinarazpenak", + "Always show message timestamps": "Erakutsi beti mezuen denbora-zigilua", + "Disable markdown formatting": "Desgaitu markdown formatua", + "Name": "Izena", + "Device Name": "Gailuaren izena", + "Last seen": "Azkenekoz ikusia", + "Authentication": "Autentifikazioa", + "Password:": "Pasahitza:", + "Interface Language": "Interfazearen hizkuntza", + "Verification Pending": "Egiaztaketa egiteke", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Irakurri zure e-maila eta egin klik dakarren estekan. Behin eginda, egin klik Jarraitu botoian.", + "This email address is already in use": "E-mail helbide hau erabilita dago", + "This phone number is already in use": "Telefono zenbaki hau erabilita dago", + "Topic": "Gaia", + "favourite": "gogokoa", + "none": "bat ere ez", + "Who can read history?": "Nork irakurri dezake historiala?", + "Who can access this room?": "Nor sartu daiteke gelara?", + "Anyone": "Edonor", + "Only people who have been invited": "Gonbidatua izan den jendea besterik ez", + "Anyone who knows the room's link, apart from guests": "Gelaren esteka dakien edonor, bisitariak ezik", + "Anyone who knows the room's link, including guests": "Gelaren esteka dakien edonor, bisitariak barne", + "Banned users": "Debekatutako erabiltzaileak", + "Labs": "Laborategia", + "This room has no local addresses": "Gela honek ez du tokiko helbiderik", + "Invalid alias format": "Ezizenaren formatu baliogabea", + "End-to-end encryption information": "Muturretik muturrerako zifratzearen informazioa", + "Event information": "Gertaeraren informazioa", + "Curve25519 identity key": "Curve25519 identitate gakoa", + "Claimed Ed25519 fingerprint key": "Aldarrikatutako Ed25519 hatz-marka gakoa", + "Algorithm": "Algoritmoa", + "Session ID": "Saioaren IDa", + "Decryption error": "Deszifratze errorea", + "Sender device information": "Igorlearen gailuaren informazioa", + "Device name": "Gailuaren izena", + "Device ID": "Gailuaren IDa", + "Device key": "Gailuaren gakoa", + "Verification": "Egiaztaketa", + "Ed25519 fingerprint": "Ed25519 hatz-marka", + "Export E2E room keys": "Esportatu gelako E2E gakoak", + "Export room keys": "Esportatu gelako gakoak", + "Export": "Esportatu", + "Enter passphrase": "Idatzi pasaesaldia", + "Confirm passphrase": "Berretsi pasaesaldia", + "Import E2E room keys": "Inportatu gelako E2E gakoak", + "Import room keys": "Inportatu gelako gakoak", + "Import": "Inportatu", + "Never send encrypted messages to unverified devices from this device": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gailu honetatik", + "Verified": "Egiaztatuta", + "Blacklisted": "Zerrenda beltzean", + "unknown device": "gailu ezezaguna", + "Unverify": "Kendu egiaztaketa", + "Blacklist": "Sartu zerrenda beltzean", + "Unblacklist": "Atera zerrenda beltzean", + "Verify device": "Egiaztatu gailua", + "I verify that the keys match": "Gakoak bat datozela egiaztatu dut", + "Room contains unknown devices": "Gelan gailu ezezagunak daude" } From bc4d979d1e8000d6af167cd87142ddba90660f25 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 1 Aug 2017 17:29:29 +0100 Subject: [PATCH 047/164] Display warning if widget is mixed content --- src/components/views/elements/AppTile.js | 20 +++++++++++++++++ src/components/views/elements/AppWarning.js | 25 +++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/components/views/elements/AppWarning.js diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 0e2a78e34d..22c1300c64 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -25,6 +25,7 @@ import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; import AppPermission from './AppPermission'; +import AppWarning from './AppWarning'; import MessageSpinner from './MessageSpinner'; import WidgetUtils from '../../../WidgetUtils'; @@ -70,6 +71,17 @@ export default React.createClass({ return scalarUrl && this.props.url.startsWith(scalarUrl); }, + isMixedContent: function() { + const parentContentProtocol = window.location.protocol; + const u = url.parse(this.props.url); + const childContentProtocol = u.protocol; + if (parentContentProtocol === 'https:' && childContentProtocol !== parentContentProtocol) { + console.warn("Refusing to load mixed-content app:", parentContentProtocol, childContentProtocol, window.location, this.props.url); + return true; + } + return false; + }, + componentWillMount: function() { if (!this.isScalarUrl()) { return; @@ -207,6 +219,14 @@ export default React.createClass({ >
); + } else if (this.isMixedContent() == true) { + appTileBody = ( +
+ +
+ ); } else { appTileBody = (
diff --git a/src/components/views/elements/AppWarning.js b/src/components/views/elements/AppWarning.js new file mode 100644 index 0000000000..527ee087d6 --- /dev/null +++ b/src/components/views/elements/AppWarning.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { _t } from '../../../languageHandler'; + +function AppWarning(props) { + return ( +
+
+ {_t('Warning!')}/ +
+
+ {props.errorMsg} +
+
+ ); +} + +AppWarning.propTypes = { + errorMsg: PropTypes.string, +}; +AppWarning.defaultProps = { + errorMsg: _t('Error'), +}; + +export default AppWarning; From f57b0d4cc7521f06b09406aaaadfbb08a8085db7 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 1 Aug 2017 17:43:38 +0100 Subject: [PATCH 048/164] Fix invalid translation --- src/components/views/elements/AppWarning.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/AppWarning.js b/src/components/views/elements/AppWarning.js index 527ee087d6..372535e069 100644 --- a/src/components/views/elements/AppWarning.js +++ b/src/components/views/elements/AppWarning.js @@ -19,7 +19,7 @@ AppWarning.propTypes = { errorMsg: PropTypes.string, }; AppWarning.defaultProps = { - errorMsg: _t('Error'), + errorMsg: 'Error', }; export default AppWarning; From d29610bdd21aef970d62e493fe5e079d2914f2f4 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 1 Aug 2017 17:45:06 +0100 Subject: [PATCH 049/164] Fix boolean comparison. --- src/components/views/elements/AppTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 22c1300c64..1119cf0387 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -219,7 +219,7 @@ export default React.createClass({ >
); - } else if (this.isMixedContent() == true) { + } else if (this.isMixedContent()) { appTileBody = (
Date: Tue, 1 Aug 2017 17:48:02 +0100 Subject: [PATCH 050/164] Fix comparison and handle case where app has permission to load but content is mixed protocol. --- src/components/views/elements/AppTile.js | 38 +++++++++++++----------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 1119cf0387..2aebc217f5 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -209,24 +209,26 @@ export default React.createClass({
); } else if (this.state.hasPermissionToLoad == true) { - appTileBody = ( -
- -
- ); - } else if (this.isMixedContent()) { - appTileBody = ( -
- -
- ); + if (this.isMixedContent()) { + appTileBody = ( +
+ +
+ ); + } else { + appTileBody = ( +
+ +
+ ); + } } else { appTileBody = (
From 2ab6bc84a79135d23006506642dc5f3c8fdfcc93 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 1 Aug 2017 17:49:41 +0100 Subject: [PATCH 051/164] Improve clarity --- src/components/views/elements/AppTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 2aebc217f5..ce64d2ff22 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -75,7 +75,7 @@ export default React.createClass({ const parentContentProtocol = window.location.protocol; const u = url.parse(this.props.url); const childContentProtocol = u.protocol; - if (parentContentProtocol === 'https:' && childContentProtocol !== parentContentProtocol) { + if (parentContentProtocol === 'https:' && childContentProtocol !== 'https:') { console.warn("Refusing to load mixed-content app:", parentContentProtocol, childContentProtocol, window.location, this.props.url); return true; } From 48faf72fdc992d0e39219caf6b96dc1658a52a59 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 1 Aug 2017 21:00:18 +0100 Subject: [PATCH 052/164] Disable eslint rule --- src/components/views/elements/AppWarning.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/AppWarning.js b/src/components/views/elements/AppWarning.js index 372535e069..944f1422e6 100644 --- a/src/components/views/elements/AppWarning.js +++ b/src/components/views/elements/AppWarning.js @@ -1,8 +1,8 @@ -import React from 'react'; +import React from 'react'; // eslint-disable-line no-unused-vars import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; -function AppWarning(props) { +const AppWarning = (props) => { return (
@@ -13,7 +13,7 @@ function AppWarning(props) {
); -} +}; AppWarning.propTypes = { errorMsg: PropTypes.string, From 2c86086444f2b9977198ba20b20e0f2dae403120 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 Aug 2017 10:51:34 +0100 Subject: [PATCH 053/164] Account for `\n` after each block when converting from text offsets to selection state. fixes vector-im/riot-web#4728 --- src/RichText.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index c060565e2f..ff223525d4 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -201,10 +201,8 @@ export function selectionStateToTextOffsets(selectionState: SelectionState, export function textOffsetsToSelectionState({start, end}: SelectionRange, contentBlocks: Array): SelectionState { let selectionState = SelectionState.createEmpty(); - - for (let block of contentBlocks) { - let blockLength = block.getLength(); - + for (const block of contentBlocks) { + const blockLength = block.getLength(); if (start !== -1 && start < blockLength) { selectionState = selectionState.merge({ anchorKey: block.getKey(), @@ -212,9 +210,8 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, }); start = -1; } else { - start -= blockLength; + start -= blockLength + 1; } - if (end !== -1 && end <= blockLength) { selectionState = selectionState.merge({ focusKey: block.getKey(), @@ -222,10 +219,9 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, }); end = -1; } else { - end -= blockLength; + end -= blockLength + 1; } } - return selectionState; } From 1512aff326d41157c8861dd782163fd958569e39 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 Aug 2017 11:06:02 +0100 Subject: [PATCH 054/164] Add comments --- src/RichText.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index ff223525d4..225a1c212a 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -210,7 +210,7 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, }); start = -1; } else { - start -= blockLength + 1; + start -= blockLength + 1; // +1 to account for newline between blocks } if (end !== -1 && end <= blockLength) { selectionState = selectionState.merge({ @@ -219,7 +219,7 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, }); end = -1; } else { - end -= blockLength + 1; + end -= blockLength + 1; // +1 to account for newline between blocks } } return selectionState; From c914f1607beca31a7bd0504c52744388e0904753 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 2 Aug 2017 14:35:14 +0100 Subject: [PATCH 055/164] scalar-develop is a scalar URL --- src/components/views/elements/AppPermission.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/AppPermission.js b/src/components/views/elements/AppPermission.js index dbdf74dbbc..083a7cd9c7 100644 --- a/src/components/views/elements/AppPermission.js +++ b/src/components/views/elements/AppPermission.js @@ -37,6 +37,7 @@ export default class AppPermission extends React.Component { if(wurl && wurl.hostname && ( wurl.hostname === 'scalar.vector.im' || wurl.hostname === 'scalar-staging.riot.im' || + wurl.hostname === 'scalar-develop.riot.im' || wurl.hostname === 'demo.riot.im' || wurl.hostname === 'localhost' )) { From 7599bde1f6a48ab51fad8f7aeead81c7de74c7f0 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 2 Aug 2017 17:05:46 +0100 Subject: [PATCH 056/164] Fix logging line length. --- src/components/views/elements/AppTile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index ce64d2ff22..2fcacaaee2 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -76,7 +76,8 @@ export default React.createClass({ const u = url.parse(this.props.url); const childContentProtocol = u.protocol; if (parentContentProtocol === 'https:' && childContentProtocol !== 'https:') { - console.warn("Refusing to load mixed-content app:", parentContentProtocol, childContentProtocol, window.location, this.props.url); + console.warn("Refusing to load mixed-content app:", + parentContentProtocol, childContentProtocol, window.location, this.props.url); return true; } return false; From da2b3c067b53b7c43a9953f717abd69064568f40 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 3 Aug 2017 06:11:00 +0000 Subject: [PATCH 057/164] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 581 +++++++++++++++++++++++++++++++++- 1 file changed, 571 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index d247a81931..09a3d4f1c0 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -131,7 +131,7 @@ "Device ID": "設備識別碼", "Devices": "設備列表", "Devices will not yet be able to decrypt history from before they joined the room": "新加入聊天室的設備不能解密加入之前的聊天記錄", - "Direct Chat": "私聊", + "Direct Chat": "私人聊天", "Direct chats": "私聊", "Disable inline URL previews by default": "默認禁用自動網址預覽", "Disinvite": "取消邀請", @@ -139,7 +139,7 @@ "Displays action": "顯示操作", "Don't send typing notifications": "不要發送我的打字狀態", "Download %(text)s": "下載 %(text)s", - "Drop here %(toAction)s": "拖拽到這里 %(toAction)s", + "Drop here %(toAction)s": "拖曳到這裡 %(toAction)s", "Ed25519 fingerprint": "Ed25519指紋", "Email": "電子郵箱", "Email address": "電子郵箱地址", @@ -158,7 +158,7 @@ "Existing Call": "現有通話", "Export E2E room keys": "導出聊天室的端到端加密密鑰", "Failed to ban user": "封禁用戶失敗", - "Failed to change password. Is your password correct?": "修改密碼失敗。確認原密碼輸入正確嗎?", + "Failed to change password. Is your password correct?": "變更密碼失敗。您的密碼正確嗎?", "Failed to delete device": "刪除設備失敗", "Failed to forget room %(errCode)s": "無法忘記聊天室 %(errCode)s", "Failed to join room": "無法加入聊天室", @@ -181,7 +181,7 @@ "Failed to upload file": "上傳文件失敗", "Failed to verify email address: make sure you clicked the link in the email": "郵箱驗證失敗: 請確保你已點擊郵件中的鏈接", "Failure to create room": "創建聊天室失敗", - "Favourite": "收藏", + "Favourite": "我的最愛", "favourite": "收藏", "Favourites": "收藏夾", "Fill screen": "全螢幕顯示", @@ -235,7 +235,7 @@ "Rooms": "聊天室", "Scroll to bottom of page": "滾動到頁面底部", "Scroll to unread messages": "滾動到未讀消息", - "Search": "搜索", + "Search": "搜尋", "Search failed": "搜索失敗", "Searches DuckDuckGo for results": "搜索 DuckDuckGo", "Send a message (unencrypted)": "發送消息 (非加密)", @@ -256,7 +256,7 @@ "Session ID": "會話 ID", "%(senderName)s set a profile picture.": "%(senderName)s 設置了頭像。.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s 將暱稱改為了 %(displayName)s。.", - "Settings": "設置", + "Settings": "設定", "Show panel": "顯示側邊欄", "Show timestamps in 12 hour format (e.g. 2:30pm)": "用12小時制顯示時間戳 (如:下午 2:30)", "Signed Out": "已退出登錄", @@ -310,12 +310,12 @@ "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s 移除了聊天室圖像", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s 更改了聊天室 %(roomName)s 圖像", "Cancel": "取消", - "Custom Server Options": "自定伺服器選項", + "Custom Server Options": "自訂伺服器選項", "Dismiss": "無視", "Mute": "靜音", "Notifications": "通知", "Operation failed": "操作失敗", - "powered by Matrix": "由Matrix架設", + "powered by Matrix": "由 Matrix 架設", "Remove": "移除", "unknown error code": "未知的錯誤代碼", "Sunday": "星期日", @@ -325,7 +325,7 @@ "Thursday": "星期四", "Friday": "星期五", "Saturday": "星期六", - "OK": "OK", + "OK": "確定", "Please Register": "請註冊", "Add a topic": "新增標題", "VoIP": "VoIP", @@ -360,5 +360,566 @@ "Disable URL previews by default for participants in this room": "默認情況下,此房間的參與者禁用網址預覽", "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "默認情況下,這個房間的參與者的網址預覽是%(globalDisableUrlPreview)s。", "Removed or unknown message type": "已刪除或未知的信息類型", - "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "您即將被帶到第三方網站,以便您可以驗證您的帳戶以使用%(integrationsUrl)s。你想繼續嗎?" + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "您即將被帶到第三方網站,以便您可以驗證您的帳戶以使用%(integrationsUrl)s。你想繼續嗎?", + "Close": "關閉", + "Create new room": "建立新聊天室", + "Room directory": "聊天室目錄", + "Start chat": "開始聊天", + "Welcome page": "歡迎頁面", + "de-li": "德語(列支敦斯登)", + "et": "愛沙尼亞語", + "eu": "巴斯克語(巴斯克)", + "fa": "波斯語", + "fi": "芬蘭語", + "fo": "法羅語", + "ga": "愛爾蘭語", + "gd": "蓋爾語(蘇格蘭)", + "he": "希伯來語", + "hi": "印地語", + "hr": "克羅埃西亞語", + "hu": "匈牙利語", + "id": "印尼語", + "is": "冰島語", + "it-ch": "義大利語(瑞士)", + "it": "義大利語", + "ja": "日語", + "ji": "意第緒語", + "ko": "韓語", + "lt": "立陶宛語", + "lv": "拉脫維亞語", + "mk": "馬其頓語(前南斯拉夫馬其頓共和國)", + "ms": "馬來西亞語", + "mt": "馬爾他語", + "nl-be": "荷蘭語(比利時)", + "nl": "荷蘭語", + "no": "挪威語", + "pl": "波蘭語", + "pt-br": "巴西葡萄牙語", + "pt": "葡萄牙語", + "rm": "羅曼拉丁語", + "ro-mo": "羅馬尼亞語(摩爾多瓦共和國)", + "ro": "羅馬尼亞語", + "ru-mo": "俄語(摩爾多瓦共和國)", + "ru": "俄語", + "sb": "索布語", + "sk": "斯洛伐克語", + "sl": "斯洛維尼亞語", + "sq": "阿爾巴尼亞語", + "sr": "塞爾維亞語", + "sv-fi": "瑞典語(芬蘭)", + "sv": "瑞典語", + "sx": "蘇圖語", + "sz": "基爾丁-薩米語", + "th": "泰語", + "tn": "札那語", + "tr": "土耳其語", + "ts": "聰加語", + "uk": "烏克蘭語", + "ur": "烏爾都語", + "ve": "文達語", + "vi": "越南語", + "xh": "科薩語", + "a room": "房間", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "文字訊息將會傳送到 +%(msisdn)s。請輸入其中包含的驗證碼", + "Accept": "接受", + "%(targetName)s accepted an invitation.": "%(targetName)s 已接受邀請。", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 已接受 %(displayName)s 的邀請。", + "Active call (%(roomName)s)": "活躍的通話(%(roomName)s)", + "Add": "新增", + "Admin tools": "管理員工具", + "And %(count)s more...": "還有 %(count)s 個...", + "Missing Media Permissions, click here to request.": "遺失媒體權限,點選這裡來要求。", + "No Microphones detected": "未偵測到麥克風", + "No Webcams detected": "未偵測到網路攝影機", + "No media permissions": "沒有媒體權限", + "You may need to manually permit Riot to access your microphone/webcam": "您可能需要手動允許 Riot 存取您的麥克風/網路攝影機", + "Hide removed messages": "隱藏已移除的訊息", + "Alias (optional)": "別名(選擇性)", + "and %(overflowCount)s others...": "和另外 %(overflowCount)s 個...", + "%(names)s and one other are typing": "%(names)s 與另外一個人正在輸入", + "Are you sure you want to leave the room '%(roomName)s'?": "您確定您要想要離開房間 '%(roomName)s' 嗎?", + "Bans user with given id": "禁止有指定 ID 的使用者", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "無法連線到家伺服器 - 請檢查您的連線,確保您的家伺服器的 SSL 憑證可被信任,而瀏覽器擴充套件也沒有阻擋請求。", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s 已經變更他們的名稱,從 %(oldDisplayName)s 到 %(displayName)s。", + "%(senderName)s changed their profile picture.": "%(senderName)s 已經變更了他們的基本資料圖片。", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s 變更了 %(powerLevelDiffText)s 權限等級。", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s 將房間名稱變更為 %(roomName)s。", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s 已經移除了房間名稱。", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s 已經變更主題為「%(topic)s」。", + "Changes to who can read history will only apply to future messages in this room": "變更誰可以讀取歷史紀錄的設定僅套用於此房間未來的訊息", + "Changes your display nickname": "變更您的顯示暱稱", + "changing room on a RoomView is not supported": "不支援在房間檢視時變更房間", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "目前變更密碼將會重設在所有裝置上的端對端加密金鑰,讓加密的聊天歷史無法讀取,除非您先匯出您的房間金鑰,並在稍後重新匯入它們。這會在未來改進。", + "Claimed Ed25519 fingerprint key": "已索取 Ed25519 指紋金鑰", + "Clear Cache and Reload": "清除快取並重新載入", + "Click here to join the discussion!": "點選這裡來加入討論!", + "Click to mute audio": "點選以靜音", + "Click to mute video": "點選以讓視訊靜音", + "click to reveal": "點選以顯示", + "Click to unmute video": "點選以解除視訊靜音", + "Click to unmute audio": "點選以解除靜音", + "Conference call failed.": "會議通話失敗。", + "Conference calling is in development and may not be reliable.": "會議通話尚在開發中,可能不太可靠。", + "Conference calls are not supported in encrypted rooms": "不支援在加密房間的會議通話", + "Conference calls are not supported in this client": "這個客戶端不支援會議通話", + "Could not connect to the integration server": "無法連線到整合的伺服器", + "%(count)s new messages.one": "%(count)s 個訊息", + "%(count)s new messages.other": "%(count)s 個訊息", + "Create a new chat or reuse an existing one": "建立新聊天或重新使用既有的", + "Curve25519 identity key": "Curve25519 辨識金鑰", + "Custom": "自訂", + "Custom level": "自訂等級", + "Decline": "拒絕", + "Deops user with given id": "取消指定 ID 使用者的管理員權限", + "Device already verified!": "裝置已驗證!", + "Device key:": "裝置金鑰:", + "Disable Notifications": "停用通知", + "disabled": "已停用", + "Disable markdown formatting": "停用 markdown 格式化", + "Drop File Here": "在此放置檔案", + "Drop here to tag %(section)s": "在此放置以標記 %(section)s", + "Email address (optional)": "電子郵件地址(選擇性)", + "Enable Notifications": "啟用通知", + "enabled": "已啟用", + "Encrypted by a verified device": "已透過驗證過的裝置加密", + "Encrypted by an unverified device": "已透過未驗證過的裝置加密", + "Encryption is enabled in this room": "此房間的加密已啟用", + "Encryption is not enabled in this room": "此房間未啟用加密", + "Enter passphrase": "輸入通關密語", + "Error: Problem communicating with the given homeserver.": "錯誤:與指定的家伺服器有通訊問題。", + "Export": "匯出", + "Failed to change power level": "變更權限等級失敗", + "Failed to fetch avatar URL": "擷取大頭貼 URL 失敗", + "Failed to register as guest:": "註冊為訪客失敗:", + "Failed to upload profile picture!": "上傳基本資料圖片失敗!", + "Guest access is disabled on this Home Server.": "此家伺服器的訪客存取已停用。", + "Home": "家", + "Import": "匯入", + "Incoming call from %(name)s": "從 %(name)s 而來的來電", + "Incoming video call from %(name)s": "從 %(name)s 而來的視訊來電", + "Incoming voice call from %(name)s": "從 %(name)s 而來的語音來電", + "Incorrect username and/or password.": "不正確的使用者名稱和/或密碼。", + "%(senderName)s invited %(targetName)s.": "%(senderName)s 邀請了 %(targetName)s。", + "Invited": "已邀請", + "Invites": "邀請", + "Invites user with given id to current room": "邀請指定 ID 的使用者到目前的房間", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是地址的有效格式", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是別名的有效格式", + "%(displayName)s is typing": "%(displayName)s 正在輸入", + "Sign in with": "登入使用", + "Join as voice or video.": "加入為語音視訊。", + "joined and left": "加入並離開", + "Joins room with given alias": "以指定的別名加入房間", + "Kick": "踢出", + "Kicks user with given id": "踢出指定 ID 的使用者", + "Labs": "實驗室", + "Last seen": "上次檢視", + "left and rejoined": "離開並重新加入", + "left": "離開", + "Level:": "等級:", + "List this room in %(domain)s's room directory?": "在 %(domain)s 的房間目錄中列出此房間嗎?", + "Local addresses for this room:": "此房間的本機地址:", + "Logged in as:": "登入為:", + "Logout": "登出", + "Low priority": "低優先度", + "%(senderName)s made future room history visible to": "%(senderName)s 讓未來的房間歷史紀錄可見於", + "Manage Integrations": "管裡整合", + "Markdown is disabled": "Markdown 已停用", + "Markdown is enabled": "Markdown 已啟用", + "matrix-react-sdk version:": "matrix-react-sdk 版本:", + "Members only": "僅成員", + "Message not sent due to unknown devices being present": "因為未知的裝置存在而未傳送", + "Missing room_id in request": "在請求中遺失房間 ID", + "Missing user_id in request": "在請求中遺失使用者 ID", + "Mobile phone number": "行動電話號碼", + "Mobile phone number (optional)": "行動電話號碼(選擇性)", + "Moderator": "仲裁者", + "Must be viewing a room": "必須檢視房間", + "my Matrix ID": "我的 Matrix ID", + "Name": "名稱", + "Never send encrypted messages to unverified devices from this device": "從不自此裝置傳送加密的訊息到未驗證的裝置", + "Never send encrypted messages to unverified devices in this room": "從不在此房間傳送加密的訊息到未驗證的裝置", + "Never send encrypted messages to unverified devices in this room from this device": "從不在此房間中從此裝置上傳送未加密的訊息到未驗證的裝置", + "New address (e.g. #foo:%(localDomain)s)": "新地址(例如:#foo:%(localDomain)s)", + "New Composer & Autocomplete": "新 Composer 與自動完成", + "New passwords don't match": "新密碼不相符", + "New passwords must match each other.": "新密碼必須互相符合。", + "none": "無", + "not set": "未設定", + "not specified": "未指定", + "(not supported by this browser)": "(不被此瀏覽器支援)", + "": "<不支援>", + "NOT verified": "未驗證", + "No devices with registered encryption keys": "沒有已註冊的加密金鑰的裝置", + "No display name": "沒有顯示名稱", + "No more results": "沒有更多結果", + "No results": "沒有結果", + "No users have specific privileges in this room": "此房間中沒有使用者有指定的權限", + "olm version:": "olm 版本:", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "這個房間只要啟用加密就不能再關掉了(從現在開始)", + "Once you've followed the link it contains, click below": "一旦您跟著它所包含的連結,點選下方", + "Only people who have been invited": "僅有被邀請的夥伴", + "Otherwise, click here to send a bug report.": "否則,請點選此處來傳送錯誤報告。", + "Password": "密碼", + "Password:": "密碼:", + "Passwords can't be empty": "密碼不能為空", + "People": "夥伴", + "Permissions": "權限", + "Phone": "電話", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s 打了 %(callType)s 通話。", + "demote": "降級", + "Please check your email and click on the link it contains. Once this is done, click continue.": "請檢查您的電子郵件並點選其中包含的連結。只要這個完成了,就點選選繼續。", + "Power level must be positive integer.": "權限等級必需為正整數。", + "Press": "按下", + "Press to start a chat with someone": "按下 以開始與某人聊天", + "Privacy warning": "隱私警告", + "Private Chat": "私密聊天", + "Privileged Users": "特別權限使用者", + "Profile": "基本資料", + "Public Chat": "公開聊天", + "Reason: %(reasonText)s": "理由:%(reasonText)s", + "Revoke Moderator": "撤回仲裁者", + "Refer a friend to Riot:": "推薦 Riot 給朋友:", + "%(targetName)s rejected the invitation.": "%(targetName)s 拒絕了邀請。", + "Reject invitation": "拒絕邀請", + "Rejoin": "重新加入", + "Remote addresses for this room:": "此房間的遠端地址:", + "Remove Contact Information?": "移除聯絡人資訊?", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 移除了他們的顯示名稱 (%(oldDisplayName)s)。", + "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他們的基本資寮圖片。", + "Remove %(threePid)s?": "移除 %(threePid)s?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s 請求了一次 VoIP 會議。", + "Results from DuckDuckGo": "DuckDuckGo 的結果", + "Room contains unknown devices": "包含了未知裝置的房間", + "%(roomName)s does not exist.": "%(roomName)s 不存在。", + "%(roomName)s is not accessible at this time.": "%(roomName)s 此時無法存取。", + "Save": "儲存", + "Searching known users": "搜尋已知的使用者", + "Seen by %(userName)s at %(dateTime)s": "%(userName)s 在 %(dateTime)s 時看過", + "Send anyway": "無論如何都要傳送", + "Set": "設定", + "Show Text Formatting Toolbar": "顯示文字格式化工具列", + "Start authentication": "開始認證", + "tag as %(tagName)s": "標記為 %(tagName)s", + "tag direct chat": "標記直接聊天", + "Tagged as: ": "標記為: ", + "The phone number entered looks invalid": "輸入的電話號碼看起來無效", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "您提供的簽署金鑰與您從 %(userId)s 的裝置 %(deviceId)s 收到的簽署金鑰相符。裝置被標記為已驗證。", + "The remote side failed to pick up": "遠端未能接聽", + "This Home Server does not support login using email address.": "這個家伺服器不支援使用電子郵件地址登入。", + "This invitation was sent to an email address which is not associated with this account:": "這份邀請被傳送給與此帳號無關的電子郵件地址:", + "There was a problem logging in.": "登入時出現問題。", + "This room has no local addresses": "此房間沒有本機地址", + "This room is not recognised.": "此房間不被認可。", + "These are experimental features that may break in unexpected ways": "這些是可能會以非預期的方式故障的實驗性功能", + "The visibility of existing history will be unchanged": "既存歷史紀錄的可見性將不會變更", + "This doesn't appear to be a valid email address": "這似乎不是有效的電子郵件地址", + "This is a preview of this room. Room interactions have been disabled": "這是房間的預覽。房間互動已停用", + "This phone number is already in use": "這個電話號碼已在使用中", + "This room": "此房間", + "This room is not accessible by remote Matrix servers": "此房間無法被遠端的 Matrix 伺服器存取", + "This room's internal ID is": "此房間的內部 ID 為", + "times": "次數", + "To ban users": "要禁止使用者", + "to browse the directory": "要瀏覽目錄", + "To configure the room": "要設定房間", + "to demote": "要降級", + "to favourite": "到喜歡", + "To invite users into the room": "要邀請使用者進入此房間", + "To kick users": "要踢出使用者", + "To link to a room it must have an address.": "要連結到房間,它必須有地址。", + "to make a room or": "要開房間或", + "To remove other users' messages": "要移除其他使用者的訊息", + "To reset your password, enter the email address linked to your account": "要重設您的密碼,輸入連結到您的帳號的電子郵件地址", + "to restore": "要復原", + "To send events of type": "要傳送活動類型", + "To send messages": "要傳送訊息", + "to start a chat with someone": "要開始與某人聊天", + "to tag as %(tagName)s": "要標記為 %(tagName)s", + "to tag direct chat": "要標記直接聊天", + "To use it, just wait for autocomplete results to load and tab through them.": "要使用它,只要等待自動完成的結果載入並在它們上面按 Tab。", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "嘗試載入此房間時間軸的特定時間點,但是問題是您沒有權限檢視相關的訊息。", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "嘗試載入此房間時間軸的特定時間點,但是找不到。", + "Unable to remove contact information": "無法移除聯絡人資訊", + "Unable to restore previous session": "無法復原先前的工作階段", + "Unable to verify email address.": "無法驗證電子郵件。", + "Unban": "解除禁止", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s 解除禁止 %(targetName)s。", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "無法確定此邀請是傳送到與您的帳號相關聯的電子郵件地址。", + "Unable to load device list": "無法載入裝置清單", + "Undecryptable": "無法解密", + "Unencrypted room": "未加密的房間", + "unencrypted": "未加密", + "Unencrypted message": "未加密的訊息", + "unknown caller": "不明來電", + "Unknown command": "未知的命令", + "unknown device": "未知的裝置", + "Unknown room %(roomId)s": "未知的房間 %(roomId)s", + "Unknown (user, device) pair:": "未知的(使用者,裝置)配對:", + "unknown": "未知", + "Unmute": "解除靜音", + "Unnamed Room": "未命名的房間", + "Unrecognised command:": "無法識別的命令:", + "Unrecognised room alias:": "無法室別的房間別名:", + "Unverified": "未驗證", + "Uploading %(filename)s and %(count)s others.zero": "正在上傳 %(filename)s", + "Uploading %(filename)s and %(count)s others.one": "正在上傳 %(filename)s 與另外 %(count)s 個", + "Uploading %(filename)s and %(count)s others.other": "正在上傳 %(filename)s 與另外 %(count)s 個", + "uploaded a file": "已上傳檔案", + "Upload avatar": "上傳大頭貼", + "Upload Failed": "上傳失敗", + "Upload Files": "上傳檔案", + "Upload file": "上傳檔案", + "Upload new:": "上傳新的:", + "Usage": "使用方法", + "Use compact timeline layout": "使用緊湊的時間軸佈局", + "Use with caution": "謹慎使用", + "User ID": "使用者 ID", + "User Interface": "使用者介面", + "%(user)s is a": "%(user)s 是一個", + "User name": "使用者名稱", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s(權限等級 %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "使用者名稱無效:%(errMessage)s", + "Users": "使用者", + "User": "使用者", + "Verification Pending": "擱置的驗證", + "Verification": "驗證", + "verified": "已驗證", + "Verified": "已驗證", + "Verified key": "已驗證的金鑰", + "Video call": "視訊通話", + "Voice call": "語音通話", + "VoIP conference finished.": "VoIP 會議已結束。", + "VoIP conference started.": "VoIP 會議已開始。", + "VoIP is unsupported": "VoIP 不支援", + "(could not connect media)": "(無法連線媒體)", + "(no answer)": "(未回覆)", + "(unknown failure: %(reason)s)": "(未知的錯誤:%(reason)s)", + "(warning: cannot be disabled again!)": "(警告:無法再停用!)", + "Warning!": "警告!", + "WARNING: Device already verified, but keys do NOT MATCH!": "警告:裝置已驗證,但金鑰不符合!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "警告:金鑰驗證失敗!%(userId)s 與裝置 %(deviceId)s 的簽署金鑰是「%(fprint)s」,其並不符合提供的金鑰「%(fingerprint)s」。這可能代表您的通訊已被攔截!", + "Who can access this room?": "誰可以存取此房間?", + "Who can read history?": "誰可以讀取歷史紀錄?", + "Who would you like to add to this room?": "您想要新增誰到此房間?", + "Who would you like to communicate with?": "您想與誰通訊?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s 撤回了 %(targetName)s 的邀請。", + "Would you like to accept or decline this invitation?": "您想要接受拒絕此邀請?", + "You already have existing direct chats with this user:": "您已與此使用者直接聊天:", + "You're not in any rooms yet! Press to make a room or to browse the directory": "您尚未在任何房間!按下 來建立房間或 來瀏覽目錄", + "You do not have permission to post to this room": "您沒有權限在此房間發言", + "You have been banned from %(roomName)s by %(userName)s.": "您已經被 %(userName)s 從 %(roomName)s 禁止。", + "You have been invited to join this room by %(inviterName)s": "您已被 %(inviterName)s 邀請加入此房間", + "You have been kicked from %(roomName)s by %(userName)s.": "您已被 %(userName)s 從 %(roomName)s 踢出。", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "您已在所有裝置上登出,並且不會再收到推送通知。要重新啟用通知,再次於每個裝置上登入", + "You have disabled URL previews by default.": "您已預設停用 URL 預覽。", + "You have enabled URL previews by default.": "您已預設啟用 URL 預覽。", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "您輸入了無效的聯絡人。嘗試使用他們的 Matrix ID 或電子郵件地址。", + "You have no visible notifications": "您沒有可見的通知", + "You may wish to login with a different account, or add this email to this account.": "您可能會想要以不同的帳號登入,或是把這個電子郵件加入到此帳號中。", + "you must be a": "您一定是", + "You must register to use this functionality": "您必須註冊以使用此功能", + "You need to be able to invite users to do that.": "您需要邀請使用者來做這件事。", + "You need to be logged in.": "您需要登入。", + "You need to enter a user name.": "您需要輸入使用者名稱。", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "您的電子郵件地址似乎未在此家伺服器上與 Matrix ID 關聯。", + "Your password has been reset": "您的密碼已重設", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "您的密碼已成功變更。您將不會在其他裝置上收到推送通知,一直到您登入回那些裝置為止", + "You seem to be in a call, are you sure you want to quit?": "您似乎尚在通話中,您確定您想要結束通話嗎?", + "You seem to be uploading files, are you sure you want to quit?": "您似乎正在上傳檔案,您確定您想要結束嗎?", + "You should not yet trust it to secure data": "您不應該相信它來保護資料", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "您將無法復原此變更,因為您正在將其他使用者的權限等級提升到與您相同。", + "Your home server does not support device management.": "您的家伺服器不支援裝置管理。", + "Wed": "週二", + "Thu": "週四", + "Fri": "週五", + "Sat": "週六", + "Jan": "一月", + "Feb": "二月", + "Mar": "三月", + "Apr": "四月", + "May": "五月", + "Jun": "六月", + "Jul": "七月", + "Aug": "八月", + "Sep": "九月", + "Oct": "十月", + "Nov": "十一月", + "Dec": "十二月", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "Set a display name:": "設定顯示名稱:", + "Set a Display Name": "設定顯示名稱", + "Upload an avatar:": "上傳大頭貼:", + "This server does not support authentication with a phone number.": "這個伺服器不支援以電話號碼認證。", + "Missing password.": "密碼遺失。", + "Passwords don't match.": "密碼不符合。", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "密碼太短(最少 %(MIN_PASSWORD_LENGTH)s)。", + "This doesn't look like a valid email address.": "這看起不像是有效的電子郵件地址。", + "This doesn't look like a valid phone number.": "這看起來不像有效的電話號碼。", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "使用者名稱僅能包含字母、數字、點、連字號與底線。", + "An unknown error occurred.": "遇到未知的錯誤。", + "I already have an account": "我已經有帳號了", + "An error occurred: %(error_string)s": "遇到錯誤:%(error_string)s", + "Topic": "主題", + "Make Moderator": "給予仲裁者", + "Make this room private": "讓此房間變為私密", + "Share message history with new users": "與新使用者分享歷史紀錄", + "Encrypt room": "加密房間", + "There are no visible files in this room": "此房間中沒有可見的檔案", + "Room": "房間", + "Connectivity to the server has been lost.": "至伺服器的連線已遺失。", + "Sent messages will be stored until your connection has returned.": "傳送的訊息會在您的連線恢復前先儲存起來。", + "Auto-complete": "自動完成", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "現在重新傳送全部或是取消全部。您也可以單獨選擇訊息來重新傳送或取消。", + "(~%(count)s results).one": "(~%(count)s 結果)", + "(~%(count)s results).other": "(~%(count)s 結果)", + "or": "或", + "Active call": "活躍的通話", + "bold": "粗體", + "italic": "斜體", + "strike": "刪除線", + "underline": "底線", + "code": "程式碼", + "quote": "引言", + "bullet": "子彈", + "numbullet": "numbullet", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s 加入了 %(repeats)s 次", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s 加入了 %(repeats)s 次", + "%(severalUsers)sjoined": "%(severalUsers)s 已加入", + "%(oneUser)sjoined": "%(oneUser)s 已加入", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s 離開了 %(repeats)s 次", + "%(oneUser)sleft %(repeats)s times": "%(oneUser)s 離開了 %(repeats)s 次", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s 加入並離開了 %(repeats)s 次", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s 加入並離開了 %(repeats)s 次", + "%(oneUser)sjoined and left": "%(oneUser)s 加入並離開了", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s 離開並重新加入了 %(repeats)s 次", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s 離開並重新加入了 %(repeats)s 次", + "%(severalUsers)sleft and rejoined": "%(severalUsers)s 離開並重新加入了", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s 拒絕了他們的邀請 %(repeats)s 次", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)s 拒絕了他/她的邀請 %(repeats)s 次", + "%(severalUsers)srejected their invitations": "%(severalUsers)s 拒絕了他們的邀請", + "%(oneUser)srejected their invitation": "%(oneUser)s 拒絕了他/她的邀請", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)s 將他們的邀請撤回 %(repeats)s 次", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s 將他/她的邀請撤回 %(repeats)s 次", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s 將他們的邀請撤回", + "%(oneUser)shad their invitation withdrawn": "%(oneUser)s 將他/她的邀請撤回", + "were invited %(repeats)s times": "被邀請了 %(repeats)s 次", + "was invited %(repeats)s times": "被邀請了 %(repeats)s 次", + "were invited": "被邀請了", + "was invited": "被邀請了", + "were banned %(repeats)s times": "被禁止了 %(repeats)s 次", + "was banned %(repeats)s times": "被禁止了 %(repeats)s 次", + "were banned": "被禁止了", + "was banned": "被禁止了", + "were unbanned %(repeats)s times": "被解禁 %(repeats)s 次", + "was unbanned %(repeats)s times": "被解禁 %(repeats)s 次", + "were unbanned": "被解禁", + "was unbanned": "被解禁", + "were kicked %(repeats)s times": "被踢出 %(repeats)s 次", + "was kicked %(repeats)s times": "被踢出 %(repeats)s 次", + "were kicked": "被踢出", + "was kicked": "被踢出", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)s 變更了他們的名稱 %(repeats)s 次", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)s 變更了他/她的名稱 %(repeats)s 次", + "%(severalUsers)schanged their name": "%(severalUsers)s 變更了他們的名稱", + "%(oneUser)schanged their name": "%(oneUser)s 變更了他/她的名稱", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)s 變更了他們的大頭貼 %(repeats)s 次", + "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)s 變更了他/她的大頭貼 %(repeats)s 次", + "%(severalUsers)schanged their avatar": "%(severalUsers)s 變更了他們的大頭貼", + "%(oneUser)schanged their avatar": "%(oneUser)s 變更了他/她的大頭貼", + "Please select the destination room for this message": "請選取此訊息的目標房間", + "New Password": "新密碼", + "Start automatically after system login": "在系統登入後自動開始", + "Desktop specific": "桌面版特有", + "Analytics": "分析", + "Opt out of analytics": "選擇退出分析", + "Options": "選項", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot 會收集匿名分析以讓我們可以改進此應用程式。", + "Passphrases must match": "通關密語必須符合", + "Passphrase must not be empty": "通關密語不能為空", + "Export room keys": "匯出房間金鑰", + "Confirm passphrase": "確認通關密語", + "Import room keys": "匯入房間金鑰", + "File to import": "要匯入的檔案", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "這個過程讓您可以匯出您在加密的房間裡收到的訊息的金鑰到一個本機檔案。您將可以在未來匯入檔案到其他的 Matrix 客戶端,這樣客戶端就可以解密此訊息。", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "匯出的檔案將會讓任何可以讀取它的人解密任何您可以看到的加密訊息,所以您必須謹慎地保管好它。為了協助您,您應該輸入下面的通關密語,其將會被用於加密匯出的資料。其只能使用相同的密碼來匯入資料。", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "這個過程讓您可以匯入您先前從其他 Matrix 客戶端匯出的加密金鑰。您將可以解密在其他客戶端可以解密的訊息。", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "匯出檔案被通關密語所保護。您應該在這裡輸入通關密語來解密檔案。", + "You must join the room to see its files": "您必須加入房間來檢視它的檔案", + "Reject all %(invitedRooms)s invites": "拒絕所有 %(invitedRooms)s 邀請", + "Start new chat": "開始新聊天", + "Guest users can't invite users. Please register.": "訪客無法邀請使用者。請註冊。", + "Failed to invite": "邀請失敗", + "Failed to invite user": "邀請使用者失敗", + "Failed to invite the following users to the %(roomName)s room:": "邀請下列使用者到 %(roomName)s 房間失敗:", + "Confirm Removal": "確認移除", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "您確定您想要移除(刪除)此活動嗎?注意若您刪除房間名稱或主題變更,還是可以復原變更。", + "Unknown error": "未知的錯誤", + "Incorrect password": "不正確的密碼", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "這將會讓您的帳號永遠無法使用。您將無法重新註冊相同的使用者 ID。", + "This action is irreversible.": "此動作是不可逆的。", + "To continue, please enter your password.": "要繼續,請輸入您的密碼。", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "要驗證此裝置是否可信,請使用其他方式(例如:面對面或是打電話)聯絡它的擁有者並詢問他們在使用者設定中看到此裝置的金鑰是否與下列的金鑰相符:", + "Device name": "裝置名稱", + "Device Name": "裝置名稱", + "Device key": "裝置金鑰", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "若其符合,按下下面的驗證按鈕。若其不符合,那麼就是有其他人試圖攔截此裝置,您應該按下黑名單按鈕。", + "In future this verification process will be more sophisticated.": "在未來,這個過程會更加複雜。", + "Verify device": "驗證裝置", + "I verify that the keys match": "我驗證金鑰相符", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我們在嘗試復原您的前一個工作階段中遇到了錯誤。若您繼續,您將會需要再次登入,而加密的聊天歷史也將會無法讀取。", + "Unable to restore session": "無法復原工作階段", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "若您先前使用過較新版本的 Riot,您的工作階段可能與此版本不相容。關閉此視窗並回到較新的版本。", + "Continue anyway": "無論如何都繼續", + "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "您的顯示名稱是您在房間裡說話是,別人會看到的名字。您想要怎麼做?", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前正把未驗證的裝置列入黑名單;要傳送訊息到這些裝置,您必須先驗證它們。", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "我們建議您對每一個裝置執行驗證過程以確認它們屬於其合法擁有者,但若您想要的話,您也可以重新傳送訊息而不必驗證它們。", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "「%(RoomName)s」包含了您先前沒看過的裝置。", + "Unknown devices": "未知的裝置", + "Unknown Address": "未知的地址", + "Unblacklist": "解除黑名單", + "Blacklist": "黑名單", + "Unverify": "取消驗證", + "Verify...": "驗證...", + "ex. @bob:example.com": "例如:@bob:example.com", + "Add User": "新增使用者", + "This Home Server would like to make sure you are not a robot": "此家伺服器想要確定您不是機器人", + "Sign in with CAS": "使用 CAS 登入", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "您可以使用自訂伺服器選項來指定不同的家伺服器 URL 以登入到其他的 Matrix 伺服器。", + "This allows you to use this app with an existing Matrix account on a different home server.": "這讓您可以利用在不同的家伺服器上既有的 Matrix 帳號使用此應用程式。", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以設定自訂的身份伺服器,但其通常會阻止基於電子郵件的使用者互動。", + "Please check your email to continue registration.": "請檢查您的電子郵件來繼續註冊。", + "Token incorrect": "Token 不正確", + "A text message has been sent to": "文字訊息要被傳送到", + "Please enter the code it contains:": "請輸入其包含的代碼", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "若您不指定電子郵件,您將無法重設您的密碼。您確定嗎?", + "You are registering with %(SelectedTeamName)s": "您正以 %(SelectedTeamName)s 註冊", + "for %(amount)ss": "給 %(amount)s", + "for %(amount)sm": "給 %(amount)sm", + "Updates": "更新", + "Check for update": "檢查更新", + "Start chatting": "開始聊天", + "Start Chatting": "開始聊天", + "Click on the button below to start chatting!": "點選下面的按鈕以開始聊天!", + "Username available": "使用者名稱可用", + "Username not available": "使用者名稱不可用", + "Something went wrong!": "出了點問題!", + "This will be your account name on the homeserver, or you can pick a different server.": "這將是您在家伺服器上的帳號名稱,或是您可以挑選一個不同的伺服器。", + "If you already have a Matrix account you can log in instead.": "若您已經有 Matrix 帳號,您可以登入。", + "Your browser does not support the required cryptography extensions": "您的瀏覽器不支援需要的加密擴充", + "Not a valid Riot keyfile": "不是有效的 Riot 金鑰檔案", + "Authentication check failed: incorrect password?": "認證檢查失敗:不正確的密碼?", + "Disable Peer-to-Peer for 1:1 calls": "在 1:1 通話時停用點對點", + "Do you want to set an email address?": "您想要設定電子郵件地址嗎?", + "This will allow you to reset your password and receive notifications.": "這讓您可以重設您的密碼與接收通知。", + "To return to your account in future you need to set a password": "要在未來回到您的帳號,您需要設定密碼", + "Skip": "略過", + "Start verification": "開始驗證", + "Share without verifying": "不驗證就分享", + "Ignore request": "忽略請求", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "您加入了新裝置 '%(displayName)s',其將會要求加密金鑰。", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "您未驗證的裝置 '%(displayName)s' 正在請求加密金鑰。", + "Encryption key request": "加密金鑰請求" } From 5872f2389fe8a12612b629deb37d8e9654261a41 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Thu, 3 Aug 2017 06:29:49 +0000 Subject: [PATCH 058/164] Translated using Weblate (Basque) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 654 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 651 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index e057592e1c..01a12ac96a 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -107,7 +107,7 @@ "sx": "Sutu", "sz": "Sami (Laponiera)", "th": "Thailandiera", - "tn": "Tswana", + "tn": "Tswanera", "tr": "Turkiera", "ts": "Tsonga", "uk": "Ukrainera", @@ -172,7 +172,7 @@ "Invites": "Gonbidapenak", "Low priority": "Lehentasun baxua", "No results": "Emaitzarik ez", - "Bug Report": "Arazte txostena", + "Bug Report": "Arazte-txostena", "Join Room": "Elkartu gelara", "Register": "Erregistratu", "Submit": "Bidali", @@ -266,5 +266,653 @@ "Unblacklist": "Atera zerrenda beltzean", "Verify device": "Egiaztatu gailua", "I verify that the keys match": "Gakoak bat datozela egiaztatu dut", - "Room contains unknown devices": "Gelan gailu ezezagunak daude" + "Room contains unknown devices": "Gelan gailu ezezagunak daude", + "Someone": "Norbait", + "Start a chat": "Hasi txat bat", + "Start authentication": "Hasi autentifikazioa", + "Start Chat": "Hasi txata", + "Success": "Arrakasta", + "For security, this session has been signed out. Please sign in again.": "Segurtasunagatik saio hau amaitu da. Hasi saioa berriro.", + "Found a bug?": "Akats bat aurkitu duzu?", + "Guests can't use labs features. Please register.": "Bisitariek ezin dituzte laborategiko ezaugarriak erabili. Erregistratu.", + "Guests cannot join this room even if explicitly invited.": "Bisitariak ezin dira gela honetara elkartu ez bazaie zuzenean gonbidatu.", + "Hangup": "Eseki", + "Homeserver is": "Hasiera zerbitzaria:", + "Identity Server is": "Identitate zerbitzaria:", + "Mobile phone number (optional)": "Mugikorraren telefono zenbakia (aukerazkoa)", + "Moderator": "Moderatzailea", + "Must be viewing a room": "Gela bat ikusten egon behar da", + "Account": "Kontua", + "Access Token:": "Sarbide tokena:", + "Active call (%(roomName)s)": "Dei aktiboa (%(roomName)s)", + "Add": "Gehitu", + "Add a topic": "Gehitu gai bat", + "Admin": "Kudeatzailea", + "Admin tools": "Kudeaketa tresnak", + "And %(count)s more...": "Eta %(count)s gehiago...", + "VoIP": "VoIP", + "Missing Media Permissions, click here to request.": "Media baimenak falta dira, egin klik eskatzeko.", + "No Microphones detected": "Ez da mikrofonorik atzeman", + "No Webcams detected": "Ez da kamerarik atzeman", + "No media permissions": "Media baimenik ez", + "You may need to manually permit Riot to access your microphone/webcam": "Agian eskuz baimendu behar duzu Riotek mikrofonoa edo kamera atzitzea", + "Default Device": "Lehenetsitako gailua", + "Microphone": "Mikrofonoa", + "Camera": "Kamera", + "Hide removed messages": "Ezkutatu kendutako mezuak", + "Alias (optional)": "Ezizena (aukerazkoa)", + "all room members": "gelako kide guztiak", + "all room members, from the point they are invited": "gelako kide guztiak, gonbidapena egiten zaienetik", + "all room members, from the point they joined": "gelako kide guztiak, elkartzen direnetik", + "and one other...": "eta beste bat...", + "%(names)s and %(lastPerson)s are typing": "%(names)s eta %(lastPerson)s idazten ari dira", + "%(names)s and one other are typing": "%(names)s eta beste inor idazten ari dira", + "%(names)s and %(count)s others are typing": "%(names)s eta beste %(count)s idazten ari dira", + "An email has been sent to": "E-mail bat bidali da hona:", + "anyone": "edonor", + "An error has occurred.": "Errore bat gertatu da.", + "Are you sure?": "Ziur zaude?", + "Are you sure you want to leave the room '%(roomName)s'?": "Ziur '%(roomName)s' gela utzi nahi duzula?", + "Are you sure you want to reject the invitation?": "Ziur gonbidapena baztertu nahi duzula?", + "Are you sure you want to upload the following files?": "Ziur hurrengo fitxategiak igo nahi dituzula?", + "Attachment": "Eranskina", + "Autoplay GIFs and videos": "Automatikoki erreproduzitu GIFak eta bideoa", + "%(senderName)s banned %(targetName)s.": "%(senderName)s erabiltzaileak %(targetName)s debekatu du.", + "Bans user with given id": "Debekatu ID zehatz bat duen erabiltzailea", + "Call Timeout": "Deiaren denbora-muga", + "Change Password": "Aldatu pasahitza", + "Changes your display nickname": "Zure pantaila izena aldatzen du", + "Clear Cache": "Garbitu cachea", + "Click here to join the discussion!": "Elkartu elkarrizketara!", + "Click here to fix": "Egin klik hemen konpontzeko", + "Click to mute audio": "Egin klik audioa mututzeko", + "Click to mute video": "Egin klik bideoa mututzeko", + "click to reveal": "egin klik erakusteko", + "Click to unmute video": "Egin klik bideoaren audioa gaitzeko", + "Click to unmute audio": "Egin klik audioa gaitzeko", + "Command error": "Aginduaren errorea", + "Commands": "Aginduak", + "Conference call failed.": "Konferentzia deiak huts egin du.", + "Conference calling is in development and may not be reliable.": "Konferentzia deia garapenean dago eta agian ez dabil behar bezala.", + "Confirm password": "Berretsi pasahitza", + "Conference calls are not supported in this client": "Bezero honek ez ditu konferentzia deiak onartzen", + "Could not connect to the integration server": "Ezin izan da integrazio zerbitzarira konektatu", + "%(count)s new messages.one": "mezu berri %(count)s", + "%(count)s new messages.other": "%(count)s mezu berri", + "Create a new chat or reuse an existing one": "Sortu txat berria edo berrerabili aurreko bat", + "Create an account": "Sortu kontua", + "Create Room": "Sortu gela", + "Current password": "Oraingo pasahitza", + "Custom": "Pertsonalizatua", + "Custom level": "Maila pertsonalizatua", + "/ddg is not a command": "/ddg ez da agindu bat", + "Deactivate Account": "Desaktibatu kontua", + "Deactivate my account": "Desaktibatu nire kontua", + "Decline": "Ukatu", + "Decrypt %(text)s": "Deszifratu %(text)s", + "demote": "Jaitsi maila", + "Default": "Lehenetsia", + "Device already verified!": "Gailua egiaztatuta dago!", + "Device ID:": "Gailuaren IDa:", + "device id: ": "gailuaren id-a: ", + "Device key:": "Gailuaren gakoa:", + "Direct chats": "Txat zuzenak", + "Disable Notifications": "Desgaitu jakinarazpenak", + "disabled": "desgaituta", + "Display name": "Pantaila izena", + "Displays action": "Ekintza bistaratzen du", + "Drop File Here": "Jaregin fitxategia hona", + "%(items)s and one other": "%(items)s eta beste bat", + "%(items)s and %(lastItem)s": "%(items)s eta %(lastItem)s", + "and %(overflowCount)s others...": "eta beste %(overflowCount)s...", + "%(senderName)s answered the call.": "%(senderName)s erabiltzaileak deia erantzun du.", + "Can't load user settings": "Ezin izan dira erabiltzailearen ezarpenak kargatu", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s erabiltzaileak gelaren izena kendu du.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s erabiltzaileak gaia aldatu du beste honetara: \"%(topic)s\".", + "Changes to who can read history will only apply to future messages in this room": "Historiala irakurtzeko baimenen aldaketak gela honetara hemendik aurrera heldutako mezuei aplikatuko zaizkie", + "Clear Cache and Reload": "Garbitu cache eta birkargatu", + "Devices will not yet be able to decrypt history from before they joined the room": "Gailuek ezin izango dute taldera elkartu aurretiko historiala deszifratu", + "Disable inline URL previews by default": "Desgaitu URLen aurrebista lehenetsita", + "Disinvite": "Kendu gonbidapena", + "Download %(text)s": "Deskargatu %(text)s", + "Email, name or matrix ID": "E-mail, izena edo Matrix ID-a", + "Emoji": "Emoji", + "Enable encryption": "Gaitu zifratzea", + "Enable Notifications": "Gaitu jakinarazpenak", + "enabled": "gaituta", + "Encrypted by a verified device": "Egiaztatutako gailu batek zifratuta", + "Encrypted by an unverified device": "Egiaztatu gabeko gailu batek zifratuta", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Zifratutako mezuak ez dira ikusgai izango oraindik zifratzea onartzen ez duten bezeroetan", + "Encrypted room": "Zifratutako gela", + "Encryption is enabled in this room": "Zifratzea gaitu da gela honetan", + "Encryption is not enabled in this room": "Ez da zifratzea gaitu gela honetan", + "%(senderName)s ended the call.": "%(senderName)s erabiltzaileak deia amaitu du.", + "End-to-end encryption is in beta and may not be reliable": "Muturretik muturrerako zifratzea beta egoeran dago eta agian ez dabil guztiz ondo", + "Enter Code": "Sartu kodea", + "Error decrypting attachment": "Errorea eranskina deszifratzean", + "Error: Problem communicating with the given homeserver.": "Errorea: Arazoa emandako hasiera zerbitzariarekin komunikatzeko.", + "Existing Call": "Badagoen deia", + "Failed to ban user": "Huts egin du erabiltzailea debekatzean", + "Failed to change power level": "Huts egin du botere maila aldatzean", + "Failed to delete device": "Huts egin du gailua ezabatzean", + "Failed to fetch avatar URL": "Huts egin du abatarraren URLa jasotzean", + "Failed to join room": "Huts egin du gelara elkartzean", + "Failed to kick": "Huts egin du kanporatzean", + "Failed to leave room": "Huts egin du gelatik ateratzean", + "Failed to load timeline position": "Huts egin du denbora-lerroko puntua kargatzean", + "Failed to lookup current room": "Huts egin du uneko gela bilatzean", + "Failed to mute user": "Huts egin du erabiltzailea mututzean", + "Failed to register as guest:": "Huts egin du bisitari gisa erregistratzean:", + "Failed to reject invite": "Huts egin du gonbidapena baztertzean", + "Failed to reject invitation": "Huts egin du gonbidapena baztertzean", + "Failed to save settings": "Huts egin du ezarpenak gordetzean", + "Failed to send email": "Huts egin du e-maila bidaltzean", + "Failed to send request.": "Huts egin du eskaera bidaltzean.", + "Failed to set avatar.": "Huts egin du abatarra ezartzean.", + "Failed to set display name": "Huts egin du pantaila izena ezartzean", + "Failed to set up conference call": "Huts egin du konferentzia deia ezartzean", + "Failed to toggle moderator status": "Huts egin du moderatzaile rola aldatzean", + "Failed to unban": "Huts egin du debekua kentzean", + "Failed to upload file": "Huts egin du fitxategia igotzean", + "Failed to upload profile picture!": "Huts egin du profileko argazkia igotzean!", + "Failure to create room": "Huts egin du gela sortzean", + "Fill screen": "Bete pantaila", + "Forget room": "Ahaztu gela", + "Forgot your password?": "Pasahitza ahaztu duzu?", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s %(fromPowerLevel)s mailatik %(toPowerLevel)s mailara", + "Guest access is disabled on this Home Server.": "Bisitarien sarbidea desgaituta dago hasiera zerbitzari honetan.", + "Guests can't set avatars. Please register.": "Bisitariek ezin dituzte abatarrak ezarri. Erregistratu zaitez.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Bisitariek ezin dituzte gela berriak sortu. Erregistratu gela sortu eta txat bat hasteko.", + "Guest users can't upload files. Please register to upload.": "Bisitariek ezin dituzte fitxategiak igo. Erregistratu igotzeko.", + "Hide Text Formatting Toolbar": "Ezkutatu testu-formatuaren tresna-barra", + "Incoming call from %(name)s": "%(name)s erabiltzailearen deia jasotzen", + "Incoming video call from %(name)s": "%(name)s erabiltzailearen bideo deia jasotzen", + "%(items)s and %(remaining)s others": "%(items)s eta beste %(remaining)s", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s erabiltzaileak %(displayName)s erabiltzailearen gonbidapena onartu du.", + "Bulk Options": "Aukera masiboak", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Ezin da hasiera zerbitzarira konektatu, egiaztatu zure konexioa, ziurtatu zure hasiera zerbitzariaren SSL ziurtagiria fidagarritzat jotzen duela zure gailuak, eta nabigatzailearen pluginen batek ez dituela eskaerak blokeatzen.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Ezin zara hasiera zerbitzarira HTTP bidez konektatu zure nabigatzailearen barran dagoen URLa HTTS bada. Erabili HTTPS edo gaitu script ez seguruak.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s erabiltzaileak bere pantaila izena aldatu du, %(oldDisplayName)s izatetik %(displayName)s izatera.", + "%(senderName)s changed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia aldatu du.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s erabiltzaileak %(powerLevelDiffText)s erabiltzailearen botere maila aldatu du.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s erabiltzaileak gelaren izena aldatu du, orain %(roomName)s da.", + "changing room on a RoomView is not supported": "ez da onartzen gela ikuspegi batean gelaz aldatzea", + "Drop here to tag %(section)s": "Jaregin hona %(section)s atalari etiketa jartzeko", + "Incoming voice call from %(name)s": "%(name)s erabiltzailearen deia jasotzen", + "Incorrect username and/or password.": "Erabiltzaile-izen edo pasahitz okerra.", + "Incorrect verification code": "Egiaztaketa kode okerra", + "Invalid address format": "Helbide formatu baliogabea", + "Invalid Email Address": "E-mail helbide baliogabea", + "Invalid file%(extra)s": "Fitxategi %(extra)s baliogabea", + "%(senderName)s invited %(targetName)s.": "%(senderName)s erabiltzaileak %(targetName)s gonbidatu du.", + "Invite new room members": "Gonbidatu kide berriak gelara", + "Invited": "Gonbidatuta", + "Invites user with given id to current room": "Emandako ID-a duen erabiltzailea gonbidatzen du gelara", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' ez da baliozko formatua helbide batentzat", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' ez da baliozko formatua ezizen batentzat", + "%(displayName)s is typing": "%(displayName)s idazten ari da", + "Sign in with": "Hasi saioa honekin:", + "Join as voice or video.": "Elkartu ahotsa edo bideoa erabiliz.", + "joined and left": "elkartu eta atera da", + "joined": "elkartuta", + "%(targetName)s joined the room.": "%(targetName)s erabiltzailea gelara elkartu da.", + "Joins room with given alias": "Gelara emandako ezizenarekin elkartu da", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s erabiltzaileak %(targetName)s kanporatu du.", + "Kick": "Kanporatu", + "Kicks user with given id": "Kanporatu emandako ID-a duen erabiltzailea", + "left and rejoined": "atera eta berriro elkartu da", + "left": "atera da", + "%(targetName)s left the room.": "%(targetName)s erabiltzailea gelatik atera da.", + "Level:": "Maila:", + "List this room in %(domain)s's room directory?": "Gela hau %(domain)s's domeinuko gelen direktorioan zerrendatu?", + "Local addresses for this room:": "Gela honen tokiko helbideak:", + "Logged in as:": "Saioa hasteko erabiltzailea:", + "Login as guest": "Hasi saioa bisitari gisa", + "%(senderName)s made future room history visible to": "%(senderName)s erabiltzaileak etorkizuneko gelaren historiala ikusgai jarri du hauentzat:", + "Manage Integrations": "Kudeatu interakzioak", + "Markdown is disabled": "Markdown desgaituta dago", + "Markdown is enabled": "Markdown gaituta dago", + "matrix-react-sdk version:": "matrix-react-sdk bertsioa:", + "Members only": "Kideak besterik ez", + "Message not sent due to unknown devices being present": "Ez da mezua bidali gailu ezezagunak daudelako", + "Missing room_id in request": "Gelaren ID-a falta da eskaeran", + "Missing user_id in request": "Erabiltzailearen ID-a falta da eskaeran", + "Mobile phone number": "Mugikorraren telefono zenbakia", + "my Matrix ID": "Nire Matrix ID-a", + "Never send encrypted messages to unverified devices in this room": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan", + "Never send encrypted messages to unverified devices in this room from this device": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan gailu honetatik", + "New address (e.g. #foo:%(localDomain)s)": "Helbide berria (adib. #foo:%(localDomain)s)", + "New Composer & Autocomplete": "Konposatzaile berria eta osatze automatikoa", + "New passwords don't match": "Pasahitz berriak ez datoz bat", + "New passwords must match each other.": "Pasahitz berriak berdinak izan behar dira.", + "not set": "ezarri gabe", + "not specified": "zehaztu gabe", + "(not supported by this browser)": "(nabigatzaile honek ez du euskarririk)", + "": "", + "NOT verified": "EZ egiaztatuta", + "No devices with registered encryption keys": "Erregistratutako zifratze gakoak dituen gailurik ez", + "No display name": "Pantaila izenik ez", + "No more results": "Emaitza gehiagorik ez", + "No users have specific privileges in this room": "Ez dago gela honetan baimen zehatzik duen erabiltzailerik", + "olm version:": "olm bertsioa:", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Behin gela batean zifratzea gaituta ezin da gero desgaitu (oraingoz)", + "Once you've followed the link it contains, click below": "Behin dakarren esteka jarraitu duzula, egin klik azpian", + "Otherwise, click here to send a bug report.": "Bestela, bidali arazte-txosten bat.", + "Server may be unavailable, overloaded, or you hit a bug.": "Agian zerbitzaria ez dago eskuragarri, edo gainezka dago, edo akats bat aurkitu duzu.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen. Etorkizunean hau hobetuko da.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Segurtasunagatik, saioa amaitzeak nabigatzaile honetako muturretik muturrerako zifratze gako guztiak ezabatuko ditu. Zure elkarrizketen historiala deszifratzeko gai izan nahi baduzu etorkizuneko Riot saioetan, esportatu zure gelako gakoen babes-kopia bat.", + "Passwords can't be empty": "Pasahitzak ezin dira hutsik egon", + "Permissions": "Baimenak", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s erabiltzaileak %(callType)s dei bat hasi du.", + "Power level must be positive integer.": "Botere maila osoko zenbaki positibo bat izan behar da.", + "Press": "Sakatu", + "Press to start a chat with someone": "Sakatu norbaitekin txat bat hasteko", + "Privacy warning": "Pribatutasun abisua", + "Private Chat": "Txat pribatua", + "Privileged Users": "Baimenak dituzten erabiltzaileak", + "Profile": "Profila", + "Public Chat": "Txat publikoa", + "Reason": "Arrazoia", + "Reason: %(reasonText)s": "Arrazoia: %(reasonText)s", + "Revoke Moderator": "Kendu moderatzaile baimena", + "Refer a friend to Riot:": "Aipatu Riot lagun bati:", + "rejected": "baztertua", + "%(targetName)s rejected the invitation.": "%(targetName)s erabiltzaileak gonbidapena baztertu du.", + "Reject invitation": "Baztertu gonbidapena", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s erabiltzailek bere gonbidapenak baztertu dituzte %(repeats)s aldiz", + "%(oneUser)srejected their invitation %(repeats)s times": "Erabiltzaile %(oneUser)sek bere gonbidapenak baztertu ditu %(repeats)s aldiz", + "%(severalUsers)srejected their invitations": "%(severalUsers)s erabiltzailek bere gonbidapenak baztertu dituzte", + "%(oneUser)srejected their invitation": "Erabiltzaile %(oneUser)sek bere gonbidapena baztertu du", + "Reject all %(invitedRooms)s invites": "Baztertu %(invitedRooms)s gelarako gonbidapen guztiak", + "Rejoin": "Berriro elkartu", + "Remote addresses for this room:": "Gela honen urruneko helbideak:", + "Remove Contact Information?": "Kendu kontaktuaren informazioa?", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s erabiltzaileak bere pantaila izena kendu du (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia kendu du.", + "Remove %(threePid)s?": "Kendu %(threePid)s?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s erabiltzaileak VoIP konferentzia bat eskatu du.", + "Report it": "Salatu", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Une honetan egiaztatu gabeko gailuak blokeatzen ari zara, gailu hauetara mezuak bidali ahal izateko egiaztatu behar dituzu.", + "restore": "berreskuratu", + "Results from DuckDuckGo": "DuckDuckGo bilatzaileko emaitzak", + "Return to app": "Itzuli aplikaziora", + "Riot does not have permission to send you notifications - please check your browser settings": "Riotek ez du zuri jakinarazpenak bidaltzeko baimenik, egiaztatu nabigatzailearen ezarpenak", + "Riot was not given permission to send notifications - please try again": "Ez zaio jakinarazpenak bidaltzeko baimena eman Rioti, saiatu berriro", + "riot-web version:": "riot-web bertsioa:", + "Room %(roomId)s not visible": "%(roomId)s gela ez dago ikusgai", + "Room Colour": "Gelaren kolorea", + "Room name (optional)": "Gelaren izena (aukerazkoa)", + "%(roomName)s does not exist.": "Ez dago %(roomName)s izeneko gela.", + "%(roomName)s is not accessible at this time.": "%(roomName)s ez dago eskuragarri orain.", + "Scroll to bottom of page": "Korritu orria behera arte", + "Scroll to unread messages": "Korritu irakurri gabeko mezuetara", + "Search failed": "Bilaketak huts egin du", + "Searches DuckDuckGo for results": "DuckDuckGo-n bilatzen ditu emaitzak", + "Searching known users": "Erabiltzaile ezagunen bila", + "Seen by %(userName)s at %(dateTime)s": "%(userName)s erabiltzaileak ikusia %(dateTime)s(e)an", + "Send a message (unencrypted)": "Bidali mezua (zifratu gabea)", + "Send an encrypted message": "Bidali mezu zifratua", + "Send anyway": "Bidali hala ere", + "Send Invites": "Bidali gonbidapenak", + "sent an image": "irudi bat bidali du", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s erabiltzaileak irudi bat bidali du.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s erabiltzaileak gelara elkartzeko gonbidapen bat bidali dio %(targetDisplayName)s erbiltzaileari.", + "sent a video": "bideo bat bidali du", + "Server error": "Zerbitzari-errorea", + "Server may be unavailable or overloaded": "Zerbitzaria eskuraezin edo gainezka egon daiteke", + "Server may be unavailable, overloaded, or search timed out :(": "Zerbitzaria eskuraezin edo gainezka egon daiteke, edo bilaketaren denbora muga gainditu da :(", + "Server may be unavailable, overloaded, or the file too big": "Zerbitzaria eskuraezin edo gainezka egon daiteke edo fitxategia handiegia da", + "Server unavailable, overloaded, or something else went wrong.": "Zerbitzaria eskuraezin edo gainezka egon daiteke edo zerbaitek huts egin du.", + "%(senderName)s set a profile picture.": "%(senderName)s erabiltzaileak profileko argazkia ezarri du.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s erabiltzaileak %(displayName)s ezarri du pantaila izen gisa.", + "Set": "Ezarri", + "Show panel": "Erakutsi panela", + "Show Text Formatting Toolbar": "Erakutsi testu-formatuaren tresna-barra", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Erakutsi denbora-zigiluak 12 ordutako formatuan (adib. 2:30pm)", + "Signed Out": "Saioa amaituta", + "Sign in": "Hasi saioa", + "since the point in time of selecting this option": "aukera hau hautatu denetik", + "since they joined": "elkartu direnetik", + "since they were invited": "gonbidatu zaienetik", + "Some of your messages have not been sent.": "Zure mezu batzuk ez dira bidali.", + "Sorry, this homeserver is using a login which is not recognised ": "Hasiera zerbitzari honek ezagutzen ez den saio bat erabiltzen du ", + "tag as %(tagName)s": "jarri %(tagName)s etiketa", + "tag direct chat": "jarri etiketa txat zuzenari", + "Tagged as: ": "Jarritako etiketa: ", + "The default role for new room members is": "Gelako kide berrien lehenetsitako rola:", + "The main address for this room is": "Gela honen helbide nagusia:", + "The phone number entered looks invalid": "Sartutako telefono zenbakia ez dirudi baliozkoa", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Eman duzun sinadura-gakoa %(userId)s erabiltzailearen %(deviceId)s gailutik jasotako bera da. Gailua egiaztatuta gisa markatu da.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Bisitari batek ezin du ekintza hau burutu. Erregistratu hau egin ahal izateko.", + "This email address was not found": "Ez da e-mail helbide hau aurkitu", + "%(actionVerb)s this person?": "%(actionVerb)s pertsona hau?", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fitxategiak hasiera zerbitzarian igoerei ezarritako tamaina-muga gainditzen du", + "The file '%(fileName)s' failed to upload": "'%(fileName)s' igotzean huts egin du", + "The remote side failed to pick up": "Urruneko aldeak hartzean huts egin du", + "This Home Server does not support login using email address.": "Hasiera zerbitzari honek ez du e-mail helbidearekin saioa hastea onartzen.", + "This invitation was sent to an email address which is not associated with this account:": "Gonbidapen hau kontu honekin lotuta ez dagoen e-mail helbide batera bidali da:", + "There was a problem logging in.": "Arazo bat egon da saioa hastean.", + "This room is not recognised.": "Ez da gela hau ezagutzen.", + "These are experimental features that may break in unexpected ways": "Hauek ezaugarri esperimentalak dira eta agian ez dabiltza behar bezala", + "The visibility of existing history will be unchanged": "Aurreko historialaren ikusgaitasuna ez da aldatuko", + "This doesn't appear to be a valid email address": "Honek ez du baliozko e-mail baten antzik", + "This is a preview of this room. Room interactions have been disabled": "Hau gelaren aurrebista bat da. Gelako elkarrekintzak desgaituta daude", + "This room": "Gela hau", + "This room is not accessible by remote Matrix servers": "Gela hau ez dago eskuragarri urruneko zerbitzarietan", + "This room's internal ID is": "Gela honen barne ID-a:", + "times": "aldi", + "To ban users": "Erabiltzaileak debekatzea", + "to browse the directory": "direktorioa arakatzea", + "To configure the room": "Gela konfiguratzea", + "to demote": "mailaz jaistea", + "to favourite": "gogoko egitea", + "To invite users into the room": "Erabiltzaileak gela honetara gonbidatzea", + "To kick users": "Erabiltzaileak kaleratzea", + "To link to a room it must have an address.": "Gelara estekatzeko honek helbide bat izan behar du.", + "to make a room or": "gela bat egitea edo", + "To remove other users' messages": "Beste erabiltzaileen mezuak kentzea", + "To reset your password, enter the email address linked to your account": "Zure pasahitza berrezartzeko, sartu zure kontuarekin lotutako e-mail helbidea", + "to restore": "berreskuratzea", + "To send events of type": "Mota honetako gertaerak bidaltzea:", + "To send messages": "Mezuak bidaltzea", + "to start a chat with someone": "norbaitekin txat bat hastea", + "to tag as %(tagName)s": "%(tagName)s gisa etiketatzea", + "to tag direct chat": "txat zuzena etiketatzea", + "To use it, just wait for autocomplete results to load and tab through them.": "Erabiltzeko, itxaron osatze automatikoaren emaitzak kargatu arte eta gero tabuladorearekin hautatu.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Gela honen denbora-lerroko puntu zehatz bat kargatzen saiatu zara, baina ez duzu mezu zehatz hori ikusteko baimenik.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Gela honen denbora-lerroko puntu zehatz bat kargatzen saiatu da, baina ezin izan da aurkitu.", + "Turn Markdown off": "Desaktibatu Markdown", + "Turn Markdown on": "Aktibatu Markdown", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s erabiltzaileak muturretik muturrerako (algorithm %(algorithm)s) zifratzea aktibatu du.", + "Unable to add email address": "Ezin izan da e-mail helbidea gehitu", + "Unable to remove contact information": "Ezin izan da kontaktuaren informazioa kendu", + "Unable to restore previous session": "Ezin izan da aurreko saioa berreskuratu", + "Unable to verify email address.": "Ezin izan da e-mail helbidea egiaztatu.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s erabiltzaileak debekua kendu dio %(targetName)s erabiltzaileari.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Ezin izan da ziurtatu gonbidapen hau zure kontuarekin lotutako helbide batera bidali zela.", + "Unable to capture screen": "Ezin izan da pantaila-argazkia atera", + "Unable to enable Notifications": "Ezin izan dira jakinarazpenak gaitu", + "Unable to load device list": "Ezin izan da gailuen zerrenda kargatu", + "Undecryptable": "Deszifraezina", + "Unencrypted room": "Zifratu gabeko gela", + "unencrypted": "zifratu gabe", + "Unencrypted message": "Zifratu gabeko mezua", + "unknown caller": "deitzaile ezezaguna", + "Unknown command": "Agindu ezezaguna", + "Unknown room %(roomId)s": "%(roomId)s gela ezezaguna da", + "Unknown (user, device) pair:": "Erabiltzaile eta gailu bikote ezezaguna:", + "unknown": "ezezaguna", + "Unmute": "Audioa aktibatu", + "Unnamed Room": "Izen gabeko gela", + "Unrecognised command:": "Agindu ezezaguna:", + "Unrecognised room alias:": "Gelaren ezizen ezezaguna:", + "Unverified": "Egiaztatu gabea", + "Uploading %(filename)s and %(count)s others.zero": "%(filename)s igotzen", + "Uploading %(filename)s and %(count)s others.one": "%(filename)s eta beste %(count)s igotzen", + "Uploading %(filename)s and %(count)s others.other": "%(filename)s eta beste %(count)s igotzen", + "uploaded a file": "fitxategi bat igo du", + "Upload avatar": "Igo abatarra", + "Upload Failed": "Igoerak huts egin du", + "Upload Files": "Igo fitxategiak", + "Upload file": "Igo fitxategia", + "Upload new:": "Igo berria:", + "Usage": "Erabilera", + "Use compact timeline layout": "Erabili denbora-lerro diseinu konpaktua", + "Use with caution": "Erabili kontuz", + "User ID": "Erabiltzaile ID-a", + "User Interface": "Erabiltzaile interfazea", + "%(user)s is a": "%(user)s hau da:", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "Erabiltzaile-izen baliogabea: %(errMessage)s", + "Users": "Erabiltzaileak", + "User": "Erabiltzailea", + "verified": "egiaztatuta", + "Verified key": "Egiaztatutako gakoa", + "Video call": "Bideo-deia", + "Voice call": "Ahots-deia", + "VoIP conference finished.": "VoIP konferentzia amaituta.", + "VoIP conference started.": "VoIP konferentzia hasita.", + "VoIP is unsupported": "VoIP ez dago onartuta", + "(could not connect media)": "(ezin izan da media konektatu)", + "(no answer)": "(erantzunik ez)", + "(unknown failure: %(reason)s)": "(hutsegite ezezaguna: %(reason)s)", + "(warning: cannot be disabled again!)": "(abisua: ezin da gero desgaitu!)", + "WARNING: Device already verified, but keys do NOT MATCH!": "ABISUA: Gailua egiaztatuta dago, baina gakoak EZ DATOZ BAT!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ABISUA: GAKOEN EGIAZTAKETAK HUTS EGIN DU! %(userId)s erabiltzailearen %(deviceId)s gailuaren sinadura-gakoa \"%(fprint)s\" da, eta ez dator bat emandako \"%(fingerprint)s\" gakoarekin. Honek inor komunikazioa antzematen ari dela esan nahi lezake!", + "Who would you like to add to this room?": "Nor gehitu nahi duzu gela honetara?", + "Who would you like to communicate with?": "Norekin komunikatu nahi duzu?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s erabiltzaileak atzera bota du %(targetName)s erabiltzailearen gonbidapena.", + "Would you like to accept or decline this invitation?": "Gonbidapen hau onartu ala ukatu nahi duzu?", + "You already have existing direct chats with this user:": "Baduzu jada txat zuzen bat erabiltzaile honekin:", + "You are already in a call.": "Bazaude dei batean.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Ez zaude inolako gelatan oraindik! Sakatu gela bat sortzeko edo direktorioa arakatzeko", + "You are trying to access %(roomName)s.": "%(roomName)s atzitzen saiatzen ari zara.", + "You cannot place a call with yourself.": "Ezin diozu zure buruari deitu.", + "You cannot place VoIP calls in this browser.": "Ezin dituzu VoIP deiak egin nabigatzaile honekin.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s erabiltzaileak %(roomName)s gelan debekatu zaitu.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s erabiltzaileak gela honetara gonbidatu zaitu", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s erabiltzaileak %(roomName)s gelatik kanporatu zaitu.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Saioa amaitu duzu eta ez dituzu jakinarazpenak jasoko. Jakinarazpenak jaso nahi badituzu hasi saioa berriro gailu bakoitzean", + "You have disabled URL previews by default.": "Lehenetsita URLak aurreikustea desgaitu duzu.", + "You have enabled URL previews by default.": "Lehenetsita URLak aurreikustea gaitu duzu.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Kontaktu baliogabea sartu duzu. Saiatu bere Matrix ID-a edo e-mail helbidea erabiltzen.", + "You have no visible notifications": "Ez daukazu jakinarazpen ikusgairik", + "You may wish to login with a different account, or add this email to this account.": "Agian beste kontu batekin hasi nahi duzu saioa, edo e-mail hau kontu honetara gehitu.", + "you must be a": "hau izan behar duzu:", + "You must register to use this functionality": "Funtzionaltasun hau erabiltzeko erregistratu", + "You need to be able to invite users to do that.": "Erabiltzaileak gonbidatzeko baimena behar duzu hori egiteko.", + "You need to be logged in.": "Saioa hasi duzu.", + "You need to enter a user name.": "Erabiltzaile-izen bat sartu behar duzu.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Zure e-mail helbidea ez dago antza hasiera zerbitzari honetako Matrix ID batekin lotuta.", + "Your password has been reset": "Zure pasahitza berrezarri da", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Zure pasahitza ongi aldatu da. Ez dituzu beste gailuetan jakinarazpenak jasoko hauetan saioa berriro hasi arte", + "You seem to be in a call, are you sure you want to quit?": "Badirudi dei batean zaudela, ziur irten nahi duzula?", + "You seem to be uploading files, are you sure you want to quit?": "Badirudi fitxategiak iotzen zaudela, ziur irten nahi duzula?", + "You should not yet trust it to secure data": "Oraindik ez zenuke datuak babesteko erabili behar", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Ezin izango duzu hau atzera bota erabiltzailea zure botere maila berera igotzen ari zarelako.", + "Your home server does not support device management.": "Zure hasiera zerbitzariak ez du onartzen gailuen kudeaketa.", + "Sun": "Ig", + "Mon": "Al", + "Tue": "Ar", + "Wed": "Az", + "Thu": "Og", + "Fri": "Or", + "Sat": "La", + "Jan": "Urt", + "Feb": "Ots", + "Mar": "Mar", + "Apr": "Api", + "May": "Mai", + "Jun": "Eka", + "Jul": "Uzt", + "Aug": "Abu", + "Sep": "Ira", + "Oct": "Urr", + "Nov": "Aza", + "Dec": "Abe", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "Set a display name:": "Ezarri pantaila-izena:", + "Set a Display Name": "Ezarri pantaila-izena", + "Upload an avatar:": "Igo abatarra:", + "This server does not support authentication with a phone number.": "Zerbitzari honek ez du telefono zenbakia erabiliz autentifikatzea onartzen.", + "Missing password.": "Pasahitza falta da.", + "Passwords don't match.": "Pasahitzak ez datoz bat.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Pasahitz laburregia (min %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Honek ez du baliozko e-mail helbide baten antzik.", + "This doesn't look like a valid phone number.": "Honek ez du baliozko telefono zenbaki baten antzik.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Erabiltzaile-izenek letrak, zenbakiak, puntuak, gidoiak eta gidoi baxuak besterik ezin dituzte izan.", + "An unknown error occurred.": "Errore ezezaguna gertatu da.", + "I already have an account": "Badut kontu bat", + "An error occurred: %(error_string)s": "Errore bat gertatu da: %(error_string)s", + "Make Moderator": "Bihurtu moderatzaile", + "Make this room private": "Egin gela hau pribatu", + "Share message history with new users": "Partekatu mezuen historiala erabiltzaile berriekin", + "Encrypt room": "Zifratu gela", + "There are no visible files in this room": "Ez dago fitxategi ikusgairik gela honetan", + "Sent messages will be stored until your connection has returned.": "Bidalitako mezuak zure konexioa berreskuratu arte gordeko dira.", + "Auto-complete": "Osatze automatikoa", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Birbidali guztiak edo baztertu guztiak orain. Mezuak banaka aukeratu ditzakezu ere birbidali ala baztertzeko.", + "(~%(count)s results).one": "(~%(count)s emaitza)", + "(~%(count)s results).other": "(~%(count)s emaitza)", + "bold": "lodia", + "italic": "etzana", + "strike": "marratua", + "underline": "azpimarratua", + "code": "kodea", + "quote": "aipua", + "bullet": "buleta", + "numbullet": "numerazioa", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s erabiltzaile %(repeats)s aldiz elkartu dira", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s erabiltzailea %(repeats)s aldiz elkartu da", + "%(severalUsers)sjoined": "%(severalUsers)s elkartu dira", + "%(oneUser)sjoined": "%(oneUser)s elkartu da", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s erabiltzaile %(repeats)s aldiz atera dira", + "%(oneUser)sleft %(repeats)s times": "Erabiltzaile %(oneUser)s %(repeats)s aldiz atera da", + "%(severalUsers)sleft": "%(severalUsers)s atera dira", + "%(oneUser)sleft": "%(oneUser)s atera da", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s erabiltzaile %(repeats)s aldiz elkartu eta atera dira", + "%(oneUser)sjoined and left %(repeats)s times": "Erabiltzaile %(oneUser)s %(repeats)s aldiz elkartu eta atera da", + "%(severalUsers)sjoined and left": "%(severalUsers)s elkartu eta atera dira", + "%(oneUser)sjoined and left": "%(oneUser)s elkartu eta atera da", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s erabiltzaile %(repeats)s aldiz atera eta berriro elkartu dira", + "%(oneUser)sleft and rejoined %(repeats)s times": "Erabiltzaile %(oneUser)s %(repeats)s aldiz atera eta berriro elkartu da", + "%(severalUsers)sleft and rejoined": "%(severalUsers)s erabiltzaile atera eta berriro elkartu dira", + "%(oneUser)sleft and rejoined": "Erabiltzaile %(oneUser)s atera eta berriro sartu da", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers) erabiltzaileen gonbidapenak %(repeats)s aldiz atzera bota dira", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "Erabiltzaile %(oneUser)sen gonbidapena %(repeats)s aldiz bota da atzera", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s erabiltzaileen gonbidapena atzera bota da", + "%(oneUser)shad their invitation withdrawn": "Erabiltzaile %(oneUser)sen gonbidapena atzera bota da", + "were invited %(repeats)s times": "%(repeats)s aldiz gonbidatu zaie", + "was invited %(repeats)s times": "%(repeats)s aldiz gonbidatu zaio", + "were invited": "gonbidatu zaie", + "was invited": "gonbidatu zaio", + "were banned %(repeats)s times": "%(repeats)s aldiz debekatu zaie", + "was banned %(repeats)s times": "%(repeats)s aldiz debekatu zaio", + "were banned": "debekatu zaie", + "was banned": "debekatu zaio", + "were unbanned %(repeats)s times": "debekua %(repeats)s aldiz kendu zaie", + "was unbanned %(repeats)s times": "debekua %(repeats)s aldiz kendu zaio", + "were unbanned": "debekua kendu zaie", + "was unbanned": "debekua kendu zaio", + "were kicked %(repeats)s times": "%(repeats)s aldiz kaleratu zaie", + "was kicked %(repeats)s times": "%(repeats)s aldiz kaleratu zaio", + "were kicked": "kaleratu zaie", + "was kicked": "kaleratu zaio", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)s erabiltzailek izena %(repeats)s aldiz aldatu dute", + "%(oneUser)schanged their name %(repeats)s times": "Erabiltzaile %(oneUser)sek izena %(repeats)s aldiz aldatu du", + "%(severalUsers)schanged their name": "%(severalUsers)s erabiltzailek izena aldatu dute", + "%(oneUser)schanged their name": "Erabiltzaile %(oneUser)sek izena aldatu du", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)s erabiltzailek abatarra %(repeats)s aldiz aldatu dute", + "%(oneUser)schanged their avatar %(repeats)s times": "Erabiltzaile %(oneUser)sek abatarra %(repeats)s aldiz aldatu du", + "%(severalUsers)schanged their avatar": "%(severalUsers)s erabiltzailek abatarra aldatu dute", + "%(oneUser)schanged their avatar": "Erabiltzaile %(oneUser)sek abatarra aldatu du", + "Please select the destination room for this message": "Hautatu mezu hau bidaltzeko gela", + "New Password": "Pasahitz berria", + "Start automatically after system login": "Hasi automatikoki sisteman saioa hasi eta gero", + "Desktop specific": "Mahaigainean besterik ez", + "Analytics": "Estatistikak", + "Opt out of analytics": "Ez bidali estatistikak", + "Options": "Aukerak", + "Riot collects anonymous analytics to allow us to improve the application.": "Riotek estatistika anonimoak jasotzen ditu aplikazioa hobetzeko.", + "Passphrases must match": "Pasaesaldiak bat etorri behar dira", + "Passphrase must not be empty": "Pasaesaldia ezin da hutsik egon", + "File to import": "Inportatu beharreko fitxategia", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Prozesu honek zifratutako gelatan jaso dituzun mezuentzako gakoak tokiko fitxategi batera esportatzea ahalbidetzen dizu. Fitxategia beste Matrix bezero batean inportatu dezakezu, bezero hori ere mezuak deszifratzeko gai izan dadin.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Esportatutako fitxategiak berau irakurri dezakeen edonori zuk ikusi ditzakezun mezu zifratuak deszifratzea ahalbidetzen dio, beraz kontuz gorde beharko zenuke. Honetarako azpian pasaesaldi bat sartu beharko zenuke, eta hau esportatuko datuak zifratzeko erabiliko da. Datuak inportatzeko pasaesaldi hori beharko da.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Prozesu honek aurretik beste Matrix bezero batetik esportatu dituzun zifratze gakoak inportatzea ahalbidetzen dizu. Gero beste bezeroak deszifratu zitzakeen mezuak deszifratu ahal izango dituzu.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Esportatutako fitxategia pasaesaldi batez babestuko da. Pasaesaldia bertan idatzi behar duzu, fitxategia deszifratzeko.", + "You must join the room to see its files": "Gelara elkartu behar zara bertako fitxategiak ikusteko", + "Start new chat": "Hasi txat berria", + "Guest users can't invite users. Please register.": "Bisitariek ezin dituzte erabiltzaileak gonbidatu, erregistratu zaitez.", + "Failed to invite": "Huts egin du ganbidapenak", + "Failed to invite user": "Huts egin du erabiltzailea gonbidatzean", + "Failed to invite the following users to the %(roomName)s room:": "Huts egin du honako erabiltzaile hauek %(roomName)s gelara gonbidatzean:", + "Confirm Removal": "Berretsi kentzea", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ziur gertaera hau kendu (ezabatu) nahi duzula? Jakin gelaren izenaren edo gaiaren aldaketa ezabatzen baduzu, desegitea dagoela.", + "Unknown error": "Errore ezezaguna", + "Incorrect password": "Pasahitz okerra", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Honek zure kontua behin betiko erabilezin bihurtuko du. Ezin izango duzu ID honekin berriro erregistratu.", + "This action is irreversible.": "Ez dago ekintza hau atzera egiterik.", + "To continue, please enter your password.": "Jarraitzeko sartu zure pasahitza.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Gailu hau fidagarria dela egiaztatzeko, kontaktatu bere jabea beste medio bat erabiliz (adib. aurrez aurre edo telefonoz deituz) eta galdetu beraien erabiltzaile-ezarpenetan bere gailurako ikusten duen gakoa hemen beheko bera den:", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Bat badator sakatu egiaztatu botoia. Bat ez badator, beste inor gailu hau atzematen dago eta zerrenda beltzera gehitu beharko zenuke.", + "In future this verification process will be more sophisticated.": "etorkizunean egiaztaketa metodoa hobetuko da.", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Errore bat gertatu da zure aurreko saioa berreskuratzen saiatzean. Jarraitzen baduzu berriro hasi beharko duzu saioa eta ezin izango duzu irakurri zifratutako historiala.", + "Unable to restore session": "Ezin izan da saioa berreskuratu", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Aurretik Riot bertsio berriago bat erabili baduzu, zure saioa bertsio honekin bateraezina izan daiteke. Itxi leiho hau eta itzuli bertsio berriagora.", + "Continue anyway": "Jarraitu hala ere", + "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Zure pantaila izena geletan hitz egiten duzunean besteek ikusten dutena da. Zein nahi duzu?", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Gailu bakoitzaren egiaztaketa prozesua jarraitzea aholkatzen dizugu, benetako jabeari dagozkiela baieztatzeko, baina mezua egiaztatu gabe birbidali dezakezu ere.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" gelan aurretik ikusi ez dituzun gailuak daude.", + "Unknown devices": "Gailu ezezagunak", + "Unknown Address": "Helbide ezezaguna", + "Verify...": "Egiaztatu...", + "ex. @bob:example.com": "adib. @urko:adibidea.eus", + "Add User": "Gehitu erabiltzailea", + "Sign in with CAS": "Hasi saioa CAS erabiliz", + "This allows you to use this app with an existing Matrix account on a different home server.": "Honek aplikazio hau badagoen Matrix kontu batekin beste hasiera zerbitzari batean erabiltzea ahalbidetzen dizu.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Identitate erabiltzaile pertsonalizatu bat ezarri dezakezu ere, baina honek maiz erabiltzaileekin e-mail helbidea erabiliz elkar aritzea eragozten du maiz.", + "Please check your email to continue registration.": "Egiaztatu zure e-maila erregistroarekin jarraitzeko.", + "Token incorrect": "Token okerra", + "A text message has been sent to": "Testu mezua bidali zaio honi:", + "Please enter the code it contains:": "Sartu dakarren kodea:", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ez baduzu e-mail helbide bat zehazten, ezin izango duzu zure pasahitza berrezarri. Ziur zaude?", + "You are registering with %(SelectedTeamName)s": "%(SelectedTeamName)s erabiliz erregistratzen ari zara", + "Default server": "Lehenetsitako zerbitzaria", + "Custom server": "Zerbitzari pertsonalizatua", + "Home server URL": "Hasiera zerbitzariaren URLa", + "Identity server URL": "Identitate zerbitzariaren URLa", + "What does this mean?": "Zer esan nahi du honek?", + "Error decrypting audio": "Errorea audioa deszifratzean", + "Error decrypting image": "Errorea audioa deszifratzean", + "Image '%(Body)s' cannot be displayed.": "Ezin da '%(Body)s' irudia bistaratu.", + "This image cannot be displayed.": "Irudi hau ezin da bistaratu.", + "Error decrypting video": "Errorea bideoa deszifratzean", + "Add an Integration": "Gehitu integrazioa", + "Removed or unknown message type": "Kenduta edo mezu mota ezezaguna", + "Disable URL previews by default for participants in this room": "Desgaitu URLen aurrebista gela honetako parte-hartzaileentzat", + "Disable URL previews for this room (affects only you)": "Desgaitu URLen aurrebista gela honetan (zuretzat besterik ez)", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URLen aurrebista lehenetsita %(globalDisableUrlPreview)s daude gela honetako parte-hartzaileentzat.", + "URL Previews": "URL-en aurrebistak", + "Enable URL previews for this room (affects only you)": "Gaitu URL-en aurrebistak gela honetan (zuretzat besterik ez)", + "Drop file here to upload": "Jaregin fitxategia hona igotzeko", + " (unsupported)": " (euskarririk gabe)", + "Ongoing conference call%(supportedText)s.": "%(supportedText)s konferentzia deia abian.", + "for %(amount)ss": "%(amount)ss", + "for %(amount)sm": "%(amount)sm", + "for %(amount)sh": "%(amount)sh", + "for %(amount)sd": "%(amount)se", + "Updates": "Eguneraketak", + "Check for update": "Egiaztatu eguneraketa", + "Start chatting": "Hasi txateatzen", + "Start Chatting": "Hasi txateatzen", + "Click on the button below to start chatting!": "Egin klik beheko botoian txateatzen hasteko!", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName erabiltzaileak gelaren abatarra aldatu du beste honetara: ", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s erabiltzaileak gelaren abatarra ezabatu du.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s erabiltzaileak %(roomName)s gelaren abatarra aldatu du", + "Username available": "Erabiltzaile-izena eskuragarri dago", + "Username not available": "Erabiltzaile-izena ez dago eskuragarri", + "Something went wrong!": "Zerk edo zerk huts egin du!", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Zerbitzari pertsonalizatuaren aukerak erabili ditzakezu beste Matrix zerbitzarietan saioa hasteko hasiera zerbitzari desberdin baten URLa zehaztuz.", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Kanpo webgune batetara eramango zaizu zure kontua %(integrationsUrl)s helbidearekin erabiltzeko egiaztatzeko. Jarraitu nahi duzu?", + "This will be your account name on the homeserver, or you can pick a different server.": "Hau izango da zure izena hasiera zerbitzarian, edo hautatu beste zerbitzari bat.", + "If you already have a Matrix account you can log in instead.": "Jada Matrix kontua baduzu saioa hasi dezakezu zuzenean.", + "Your browser does not support the required cryptography extensions": "Zure nabigatzaileak ez ditu onartzen beharrezkoak diren kriptografia gehigarriak", + "Not a valid Riot keyfile": "Ez da baliozko Riot gako-fitxategia", + "Authentication check failed: incorrect password?": "Autentifikazio errorea: pasahitz okerra?", + "Do you want to set an email address?": "E-mail helbidea ezarri nahi duzu?", + "This will allow you to reset your password and receive notifications.": "Honek zure pasahitza berrezarri eta jakinarazpenak jasotzea ahalbidetuko dizu.", + "To return to your account in future you need to set a password": "Etorkizunean kontura itzuli ahal izateko pasahitz bat ezarri behar duzu", + "Start verification": "Hasi egiaztaketa", + "Share without verifying": "Partekatu egiaztatu gabe", + "Ignore request": "Ezikusi eskaera", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "'%(displayName)s' gailua gehitu duzu eta zifratze-gakoak eskatzen ari da.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Zure egiaztatu gabeko '%(displayName)s' gailua zifratze-gakoak eskatzen ari da.", + "Encryption key request": "Zifratze-gakoa eskatuta", + "Deops user with given id": "Emandako ID-a duen erabiltzailea mailaz jaisten du", + "had": "zuen", + "Disable Peer-to-Peer for 1:1 calls": "Desgaitu P2P biren arteko deietan" } From 48351232567fe66917606e9d17a4a9bfc665cf26 Mon Sep 17 00:00:00 2001 From: yuurii Date: Thu, 3 Aug 2017 09:15:56 +0000 Subject: [PATCH 059/164] Added translation using Weblate (Japanese) --- src/i18n/strings/ja.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/ja.json diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/ja.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 4f0cf7d6ecc39799ba8c0f6ea3b1c3bd173c68cb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 11:16:32 +0100 Subject: [PATCH 060/164] Update npm dep of draft-js to 0.11.0-alpha --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a3bab88d45..496d8a7de6 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", - "draft-js": "^0.10.1", + "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.5.0", "draft-js-export-markdown": "^0.2.0", "emojione": "2.2.7", From 124795006ce071e1e3faa6a622c9adfc7ab1f6a2 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 11:18:56 +0100 Subject: [PATCH 061/164] Reflect API change for creating an Entity --- src/RichText.js | 5 ++++- .../views/rooms/MessageComposerInput.js | 15 +++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 225a1c212a..6f7d143e04 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -248,7 +248,10 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor .set('anchorOffset', start) .set('focusOffset', end); const emojiText = plainText.substring(start, end); - const entityKey = Entity.create('emoji', 'IMMUTABLE', { emojiUnicode: emojiText }); + newContentState = newContentState.createEntity( + 'emoji', 'IMMUTABLE', { emojiUnicode: emojiText } + ); + const entityKey = newContentState.getLastCreatedEntityKey(); newContentState = Modifier.replaceText( newContentState, selection, diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 743caf3a76..222a473a23 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -936,32 +936,27 @@ export default class MessageComposerInput extends React.Component { } const {range = null, completion = '', href = null, suffix = ''} = displayedCompletion; + let contentState = activeEditorState.getCurrentContent(); let entityKey; - let mdCompletion; if (href) { - entityKey = Entity.create('LINK', 'IMMUTABLE', { + contentState = contentState.createEntity('LINK', 'IMMUTABLE', { url: href, isCompletion: true, }); + entityKey = contentState.getLastCreatedEntityKey(); } let selection; if (range) { selection = RichText.textOffsetsToSelectionState( - range, activeEditorState.getCurrentContent().getBlocksAsArray(), + range, contentState.getBlocksAsArray(), ); } else { selection = activeEditorState.getSelection(); } - let contentState = Modifier.replaceText( - activeEditorState.getCurrentContent(), - selection, - mdCompletion || completion, - null, - entityKey, - ); + contentState = Modifier.replaceText(contentState, selection, completion, null, entityKey); // Move the selection to the end of the block const afterSelection = contentState.getSelectionAfter(); From fb5dc295aa1dd109c09b119bf2c38ea47e3169d9 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 11:29:26 +0100 Subject: [PATCH 062/164] Reflect API change for getting an Entity --- src/RichText.js | 2 +- .../views/rooms/MessageComposerInput.js | 36 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 6f7d143e04..5f37d89c6f 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -238,7 +238,7 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor const existingEntityKey = block.getEntityAt(start); if (existingEntityKey) { // avoid manipulation in case the emoji already has an entity - const entity = Entity.get(existingEntityKey); + const entity = newContentState.getEntity(existingEntityKey); if (entity && entity.get('type') === 'emoji') { return; } diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 222a473a23..669156ba7a 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -165,17 +165,20 @@ export default class MessageComposerInput extends React.Component { this.client = MatrixClientPeg.get(); } - findLinkEntities(contentBlock, callback) { - contentBlock.findEntityRanges( - (character) => { - const entityKey = character.getEntity(); - return ( - entityKey !== null && - Entity.get(entityKey).getType() === 'LINK' - ); - }, callback, - ); + getLinkFindingStrategy(contentState: ContentState) { + return (contentBlock, callback) => { + contentBlock.findEntityRanges( + (character) => { + const entityKey = character.getEntity(); + return ( + entityKey !== null && + contentState.getEntity(entityKey).getType() === 'LINK' + ); + }, callback, + ); + }; } + /* * "Does the right thing" to create an EditorState, based on: * - whether we've got rich text mode enabled @@ -185,10 +188,10 @@ export default class MessageComposerInput extends React.Component { const decorators = richText ? RichText.getScopedRTDecorators(this.props) : RichText.getScopedMDDecorators(this.props); decorators.push({ - strategy: this.findLinkEntities.bind(this), + strategy: this.getLinkFindingStrategy(contentState), component: (entityProps) => { const Pill = sdk.getComponent('elements.Pill'); - const {url} = Entity.get(entityProps.entityKey).getData(); + const {url} = contentState.getEntity(entityProps.entityKey).getData(); if (Pill.isPillUrl(url)) { return ; } @@ -713,7 +716,7 @@ export default class MessageComposerInput extends React.Component { const hasLink = blocks.some((block) => { return block.getCharacterList().filter((c) => { const entityKey = c.getEntity(); - return entityKey && Entity.get(entityKey).getType() === 'LINK'; + return entityKey && contentState.getEntity(entityKey).getType() === 'LINK'; }).size > 0; }); shouldSendHTML = hasLink; @@ -724,6 +727,7 @@ export default class MessageComposerInput extends React.Component { ); } } else { + const findLinkEntities = this.getLinkFindingStrategy(contentState); // Use the original contentState because `contentText` has had mentions // stripped and these need to end up in contentHTML. @@ -734,8 +738,8 @@ export default class MessageComposerInput extends React.Component { const pt = contentState.getBlocksAsArray().map((block) => { let blockText = block.getText(); let offset = 0; - this.findLinkEntities(block, (start, end) => { - const entity = Entity.get(block.getEntityAt(start)); + findLinkEntities(block, (start, end) => { + const entity = contentState.getEntity(block.getEntityAt(start)); if (entity.getType() !== 'LINK') { return; } @@ -1042,7 +1046,7 @@ export default class MessageComposerInput extends React.Component { offset -= sum; const entityKey = block.getEntityAt(offset); - const entity = entityKey ? Entity.get(entityKey) : null; + const entity = entityKey ? contentState.getEntity(entityKey) : null; if (entity && entity.getData().isCompletion) { // This is a completed mention, so do not insert MD link, just text return text; From 1d1cd5f691f57c388fb2ba2c0c8fc6c317a707e1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 11:36:07 +0100 Subject: [PATCH 063/164] Reflect API change for decorator strategy --- .../views/rooms/MessageComposerInput.js | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 669156ba7a..18b2424106 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -165,18 +165,16 @@ export default class MessageComposerInput extends React.Component { this.client = MatrixClientPeg.get(); } - getLinkFindingStrategy(contentState: ContentState) { - return (contentBlock, callback) => { - contentBlock.findEntityRanges( - (character) => { - const entityKey = character.getEntity(); - return ( - entityKey !== null && - contentState.getEntity(entityKey).getType() === 'LINK' - ); - }, callback, - ); - }; + findLinkEntities(contentBlock: ContentBlock, callback, contentState: ContentState) { + contentBlock.findEntityRanges( + (character) => { + const entityKey = character.getEntity(); + return ( + entityKey !== null && + contentState.getEntity(entityKey).getType() === 'LINK' + ); + }, callback, + ); } /* @@ -188,7 +186,7 @@ export default class MessageComposerInput extends React.Component { const decorators = richText ? RichText.getScopedRTDecorators(this.props) : RichText.getScopedMDDecorators(this.props); decorators.push({ - strategy: this.getLinkFindingStrategy(contentState), + strategy: this.findLinkEntities.bind(this), component: (entityProps) => { const Pill = sdk.getComponent('elements.Pill'); const {url} = contentState.getEntity(entityProps.entityKey).getData(); @@ -727,7 +725,6 @@ export default class MessageComposerInput extends React.Component { ); } } else { - const findLinkEntities = this.getLinkFindingStrategy(contentState); // Use the original contentState because `contentText` has had mentions // stripped and these need to end up in contentHTML. @@ -738,7 +735,7 @@ export default class MessageComposerInput extends React.Component { const pt = contentState.getBlocksAsArray().map((block) => { let blockText = block.getText(); let offset = 0; - findLinkEntities(block, (start, end) => { + this.findLinkEntities(block, (start, end) => { const entity = contentState.getEntity(block.getEntityAt(start)); if (entity.getType() !== 'LINK') { return; From 901cbf495dfce1edeed791edf1606a374e83ee5b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 12:02:29 +0100 Subject: [PATCH 064/164] Update decorator strategy API in accordance with recent changes to 0.11.0 See https://github.com/facebook/draft-js/commit/590cdc6c54b409be750f5ad88206873218c6c289, which is a change to the API not mentioned in the migration to v0.10 notes https://draftjs.org/docs/v0-10-api-migration.html --- src/RichText.js | 6 +++--- src/components/views/rooms/MessageComposerInput.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 5f37d89c6f..6a183b31be 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -90,7 +90,7 @@ function findWithRegex(regex, contentBlock: ContentBlock, callback: (start: numb // Workaround for https://github.com/facebook/draft-js/issues/414 let emojiDecorator = { - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { findWithRegex(EMOJI_REGEX, contentBlock, callback); }, component: (props) => { @@ -119,7 +119,7 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator { export function getScopedMDDecorators(scope: any): CompositeDecorator { let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map( (style) => ({ - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback); }, component: (props) => ( @@ -130,7 +130,7 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator { })); markdownDecorators.push({ - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { return findWithRegex(MARKDOWN_REGEX.LINK, contentBlock, callback); }, component: (props) => ( diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 18b2424106..938caa0969 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -165,7 +165,7 @@ export default class MessageComposerInput extends React.Component { this.client = MatrixClientPeg.get(); } - findLinkEntities(contentBlock: ContentBlock, callback, contentState: ContentState) { + findLinkEntities(contentState: ContentState, contentBlock: ContentBlock, callback) { contentBlock.findEntityRanges( (character) => { const entityKey = character.getEntity(); @@ -189,7 +189,7 @@ export default class MessageComposerInput extends React.Component { strategy: this.findLinkEntities.bind(this), component: (entityProps) => { const Pill = sdk.getComponent('elements.Pill'); - const {url} = contentState.getEntity(entityProps.entityKey).getData(); + const {url} = entityProps.contentState.getEntity(entityProps.entityKey).getData(); if (Pill.isPillUrl(url)) { return ; } From a27eefd89338cf1546f859bdae434afc4052d30e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 15:20:44 +0100 Subject: [PATCH 065/164] Fix a couple of more errors due to API changes --- src/RichText.js | 3 ++- src/components/views/rooms/MessageComposerInput.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 6a183b31be..9876fcc93f 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -51,7 +51,8 @@ export const contentStateToHTML = (contentState: ContentState) => { }; export function htmlToContentState(html: string): ContentState { - return ContentState.createFromBlockArray(convertFromHTML(html)); + const blockArray = convertFromHTML(html).contentBlocks; + return ContentState.createFromBlockArray(blockArray); } function unicodeToEmojiUri(str) { diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 938caa0969..c16348300f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -735,7 +735,7 @@ export default class MessageComposerInput extends React.Component { const pt = contentState.getBlocksAsArray().map((block) => { let blockText = block.getText(); let offset = 0; - this.findLinkEntities(block, (start, end) => { + this.findLinkEntities(contentState, block, (start, end) => { const entity = contentState.getEntity(block.getEntityAt(start)); if (entity.getType() !== 'LINK') { return; From ee18ddb7003e9004ea5ad18759e65a5dfb4db6b6 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 Aug 2017 18:21:08 +0100 Subject: [PATCH 066/164] MD-escape URLs/alises/user IDs prior to parsing markdown So that MD characters in them do not result in formatting being applied. Fixes https://github.com/vector-im/riot-web/issues/3428 Fixes https://github.com/vector-im/riot-web/issues/4674 --- src/Markdown.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Markdown.js b/src/Markdown.js index 5730e42a09..6e735c6f0e 100644 --- a/src/Markdown.js +++ b/src/Markdown.js @@ -55,6 +55,25 @@ function is_multi_line(node) { return par.firstChild != par.lastChild; } +import linkifyMatrix from './linkify-matrix'; +import * as linkify from 'linkifyjs'; +linkifyMatrix(linkify); + +// Thieved from draft-js-export-markdown +function escapeMarkdown(s) { + return s.replace(/[*_`]/g, '\\$&'); +} + +// Replace URLs, room aliases and user IDs with md-escaped URLs +function linkifyMarkdown(s) { + const links = linkify.find(s); + links.forEach((l) => { + // This may replace several instances of `l.value` at once, but that's OK + s = s.replace(l.value, escapeMarkdown(l.value)); + }); + return s; +} + /** * Class that wraps commonmark, adding the ability to see whether * a given message actually uses any markdown syntax or whether @@ -62,7 +81,7 @@ function is_multi_line(node) { */ export default class Markdown { constructor(input) { - this.input = input; + this.input = linkifyMarkdown(input); const parser = new commonmark.Parser(); this.parsed = parser.parse(this.input); From fb8d6c962d5c0a00afad3d3bc1a4a5fed7a35227 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 4 Aug 2017 11:28:42 +0100 Subject: [PATCH 067/164] Use npm 6 --- jenkins.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins.sh b/jenkins.sh index a0e8d2e893..0979edfa13 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -4,7 +4,7 @@ set -e export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" -nvm use 4 +nvm use 6 set -x From 91c96c1c27684200d6ee5ed31fa93ca8039b450e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 4 Aug 2017 15:08:03 +0100 Subject: [PATCH 068/164] Update draft-js-export-* deps to be compatible with draft-js >0.10.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 496d8a7de6..661db4b6bc 100644 --- a/package.json +++ b/package.json @@ -54,8 +54,8 @@ "commonmark": "^0.27.0", "counterpart": "^0.18.0", "draft-js": "^0.11.0-alpha", - "draft-js-export-html": "^0.5.0", - "draft-js-export-markdown": "^0.2.0", + "draft-js-export-html": "^0.6.0", + "draft-js-export-markdown": "^0.3.0", "emojione": "2.2.7", "file-saver": "^1.3.3", "filesize": "3.5.6", From ffdffb643d0a23c2a43e2d2b2e952fcdf7cecd06 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 4 Aug 2017 17:22:01 +0100 Subject: [PATCH 069/164] allow hiding of avatar/display name changes --- src/components/structures/UserSettings.js | 4 ++ src/i18n/strings/en_EN.json | 1 + src/shouldHideEvent.js | 48 +++++++++++------------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 1e0fcff445..483aab7e58 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -85,6 +85,10 @@ const SETTINGS_LABELS = [ id: 'hideJoinLeaves', label: 'Hide join/leave messages (invites/kicks/bans unaffected)', }, + { + id: 'hideAvatarDisplaynameChanges', + label: 'Hide Avatar and Display Name changes', + }, { id: 'useCompactLayout', label: 'Use compact timeline layout', diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0402c242aa..3edebc0284 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -346,6 +346,7 @@ "Hangup": "Hangup", "Hide Apps": "Hide Apps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Hide join/leave messages (invites/kicks/bans unaffected)", + "Hide Avatar and Display Name changes": "Hide Avatar and Display Name changes", "Hide read receipts": "Hide read receipts", "Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar", "Historical": "Historical", diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index afc8fdc596..c7bb547512 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -14,38 +14,36 @@ limitations under the License. */ -function _isLeaveOrJoin(ev) { - const isMemberEvent = ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined; - if (!isMemberEvent) { - return false; // bail early: all the checks below concern member events only - } +function memberEventDiff(ev) { + const diff = { + isMembershipEvent: ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined, + }; - // TODO: These checks are done to make sure we're dealing with membership transitions not avatar changes / dupe joins - // These checks are also being done in TextForEvent and should really reside in the JS SDK as a helper function - const membership = ev.getContent().membership; - const prevMembership = ev.getPrevContent().membership; - if (membership === prevMembership && membership === 'join') { - // join -> join : This happens when display names change / avatars are set / genuine dupe joins with no changes. - // Find out which we're dealing with. - if (ev.getPrevContent().displayname !== ev.getContent().displayname) { - return false; // display name changed - } - if (ev.getPrevContent().avatar_url !== ev.getContent().avatar_url) { - return false; // avatar url changed - } - // dupe join event, fall through to hide rules - } + if (!diff.isMembershipEvent) return diff; + const content = ev.getContent(); + const prevContent = ev.getPrevContent(); - // this only applies to joins/invited joins/leaves not invites/kicks/bans - const isJoin = membership === 'join' && prevMembership !== 'ban'; - const isLeave = membership === 'leave' && ev.getStateKey() === ev.getSender(); - return isJoin || isLeave; + diff.isJoin = content.membership === 'join' && prevContent.membership !== 'ban'; + diff.isPart = content.membership === 'leave' && ev.getStateKey() === ev.getSender(); + + const isJoinToJoin = content.membership === prevContent.membership && content.membership === 'join'; + diff.isDisplaynameChange = isJoinToJoin && content.displayname !== prevContent.displayname; + diff.isAvatarChange = isJoinToJoin && content.avatar_url !== prevContent.avatar_url; + return diff; } export default function(ev, syncedSettings) { // Hide redacted events if (syncedSettings['hideRedactions'] && ev.isRedacted()) return true; - if (syncedSettings['hideJoinLeaves'] && _isLeaveOrJoin(ev)) return true; + + const eventDiff = memberEventDiff(ev); + + if (eventDiff.isMembershipEvent) { + if (syncedSettings['hideJoinLeaves'] && (eventDiff.isJoin || eventDiff.isPart)) return true; + const isMemberAvatarDisplaynameChange = eventDiff.isAvatarChange || eventDiff.isDisplaynameChange; + if (syncedSettings['hideAvatarDisplaynameChanges'] && isMemberAvatarDisplaynameChange) return true; + } + return false; } From d9d8f2055ff34b2c5e2ca7167c9728ecd3e0bb19 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 7 Aug 2017 16:23:37 +0100 Subject: [PATCH 070/164] Allow default for ctrl+shift+b, ctrl+shift+u in RTE fixes vector-im/riot-web#4750 --- src/components/views/rooms/MessageComposerInput.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index c16348300f..68df8fce57 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -104,7 +104,11 @@ export default class MessageComposerInput extends React.Component { } // Allow opening of dev tools. getDefaultKeyBinding would be 'italic' for KEY_I - if (e.keyCode === KeyCode.KEY_I && e.shiftKey && e.ctrlKey) { + // Likewise protect bold and underline (in case some browsers use these as + // shortcuts for things). + if ([KeyCode.KEY_B, KeyCode.KEY_I, KeyCode.KEY_U].includes(e.keyCode) && + e.shiftKey && e.ctrlKey + ) { // When null is returned, draft-js will NOT preventDefault, allowing dev tools // to be toggled when the editor is focussed return null; From 641fda01622754f31a7b49629a617440317c86c1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 7 Aug 2017 16:29:22 +0100 Subject: [PATCH 071/164] Adjust comment --- src/components/views/rooms/MessageComposerInput.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 68df8fce57..f2c6c3a054 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -109,8 +109,7 @@ export default class MessageComposerInput extends React.Component { if ([KeyCode.KEY_B, KeyCode.KEY_I, KeyCode.KEY_U].includes(e.keyCode) && e.shiftKey && e.ctrlKey ) { - // When null is returned, draft-js will NOT preventDefault, allowing dev tools - // to be toggled when the editor is focussed + // When null is returned, draft-js will NOT preventDefault return null; } From 7018deee44da83472be19145cc8f8612ae5d8d32 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 7 Aug 2017 17:16:42 +0100 Subject: [PATCH 072/164] Fix ctrl+a, backspace toggling block format Now it will delete the selected range (and not toggle the block format). Fixes vector-im/riot-web#4753 --- src/components/views/rooms/MessageComposerInput.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index f2c6c3a054..d619de96d3 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -519,7 +519,8 @@ export default class MessageComposerInput extends React.Component { newState = RichUtils.toggleInlineStyle(this.state.editorState, 'STRIKETHROUGH'); } else if (shouldToggleBlockFormat) { const currentStartOffset = this.state.editorState.getSelection().getStartOffset(); - if (currentStartOffset === 0) { + const currentEndOffset = this.state.editorState.getSelection().getEndOffset(); + if (currentStartOffset === 0 && currentEndOffset === 0) { // Toggle current block type (setting it to 'unstyled') newState = RichUtils.toggleBlockType(this.state.editorState, currentBlockType); } From 1743c047bd66366779b80defdb3f2f7534ae7233 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 10:28:11 +0100 Subject: [PATCH 073/164] Use the rawDisplayName for the user provider completion to make sure that the length of text in the decoration (See ) is equal to the length of text in the completion (underlying text range that the Entity covers). --- src/autocomplete/UserProvider.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index 9c93cf537f..499ddb51ce 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -54,7 +54,9 @@ export default class UserProvider extends AutocompleteProvider { completions = this.matcher.match(command[0]).map((user) => { const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done return { - completion: displayName, + // Length of completion should equal length of text in decorator. draft-js + // relies on the length of the entity === length of the text in the decoration. + completion: user.rawDisplayName, suffix: range.start === 0 ? ': ' : ' ', href: 'https://matrix.to/#/' + user.userId, component: ( From b08d32371d07efc572610bdbdc4dabfc6bc5aa6e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 11:13:29 +0100 Subject: [PATCH 074/164] Add optional setting for hiding avatars in s As part of https://github.com/vector-im/riot-web/issues/4640#issuecomment-316659445 --- src/components/structures/UserSettings.js | 4 ++++ src/components/views/elements/Pill.js | 10 ++++++++-- src/components/views/messages/TextualBody.js | 8 +++++++- src/components/views/rooms/MessageComposerInput.js | 8 +++++++- src/i18n/strings/en_EN.json | 3 ++- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 1e0fcff445..72a287d584 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -101,6 +101,10 @@ const SETTINGS_LABELS = [ id: 'MessageComposerInput.autoReplaceEmoji', label: 'Automatically replace plain text Emoji', }, + { + id :'Pill.shouldHidePillAvatar', + label: 'Hide avatars in user and room mentions', + } /* { id: 'useFixedWidthFont', diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index 8d19eb5999..b5fa163608 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -47,6 +47,8 @@ const Pill = React.createClass({ inMessage: PropTypes.bool, // The room in which this pill is being rendered room: PropTypes.instanceOf(Room), + // Whether to include an avatar in the pill + shouldShowPillAvatar: PropTypes.bool, }, getInitialState() { @@ -155,7 +157,9 @@ const Pill = React.createClass({ if (member) { userId = member.userId; linkText = member.rawDisplayName.replace(' (IRC)', ''); // FIXME when groups are done - avatar = ; + if (this.props.shouldShowPillAvatar) { + avatar = ; + } pillClass = 'mx_UserPill'; } } @@ -164,7 +168,9 @@ const Pill = React.createClass({ const room = this.state.room; if (room) { linkText = (room ? getDisplayAliasForRoom(room) : null) || resource; - avatar = ; + if (this.props.shouldShowPillAvatar) { + avatar = ; + } pillClass = 'mx_RoomPill'; } } diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 6d4d01a196..27dba76146 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -170,6 +170,7 @@ module.exports = React.createClass({ }, pillifyLinks: function(nodes) { + const shouldShowPillAvatar = !UserSettingsStore.getSyncedSetting("Pill.shouldHidePillAvatar", false); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (node.tagName === "A" && node.getAttribute("href")) { @@ -181,7 +182,12 @@ module.exports = React.createClass({ const pillContainer = document.createElement('span'); const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); - const pill = ; + const pill = ; ReactDOM.render(pill, pillContainer); node.parentNode.replaceChild(pillContainer, node); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index d619de96d3..81704d5aba 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -188,13 +188,19 @@ export default class MessageComposerInput extends React.Component { createEditorState(richText: boolean, contentState: ?ContentState): EditorState { const decorators = richText ? RichText.getScopedRTDecorators(this.props) : RichText.getScopedMDDecorators(this.props); + const shouldShowPillAvatar = !UserSettingsStore.getSyncedSetting("Pill.shouldHidePillAvatar", false); decorators.push({ strategy: this.findLinkEntities.bind(this), component: (entityProps) => { const Pill = sdk.getComponent('elements.Pill'); const {url} = entityProps.contentState.getEntity(entityProps.entityKey).getData(); if (Pill.isPillUrl(url)) { - return ; + return ; } return ( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0402c242aa..0d5b7d9d96 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -966,5 +966,6 @@ "Edit Group": "Edit Group", "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Failed to upload image": "Failed to upload image", - "Failed to update group": "Failed to update group" + "Failed to update group": "Failed to update group", + "Hide avatars in user and room mentions": "Hide avatars in user and room mentions" } From 91a1cc443142e31fa53c4684e1a38a22e4615609 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 13:36:43 +0100 Subject: [PATCH 075/164] Mandate ctrl/meta ONLY for a subset of key bindings Because by default dratf-js doesn't check that other modifiers are _not_ pressed. --- .../views/rooms/MessageComposerInput.js | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index d619de96d3..1de2214574 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -97,23 +97,39 @@ export default class MessageComposerInput extends React.Component { onInputStateChanged: React.PropTypes.func, }; - static getKeyBinding(e: SyntheticKeyboardEvent): string { - // C-m => Toggles between rich text and markdown modes - if (e.keyCode === KeyCode.KEY_M && KeyBindingUtil.isCtrlKeyCommand(e)) { - return 'toggle-mode'; + static getKeyBinding(ev: SyntheticKeyboardEvent): string { + const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; + let ctrlCmdOnly; + if (isMac) { + ctrlCmdOnly = ev.metaKey && !ev.altKey && !ev.ctrlKey && !ev.shiftKey; + } else { + ctrlCmdOnly = ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey; } - // Allow opening of dev tools. getDefaultKeyBinding would be 'italic' for KEY_I - // Likewise protect bold and underline (in case some browsers use these as - // shortcuts for things). - if ([KeyCode.KEY_B, KeyCode.KEY_I, KeyCode.KEY_U].includes(e.keyCode) && - e.shiftKey && e.ctrlKey - ) { - // When null is returned, draft-js will NOT preventDefault - return null; + // Restrict a subset of key bindings to ONLY having ctrl/meta* pressed and + // importantly NOT having alt, shift, meta/ctrl* pressed. draft-js does not + // handle this in `getDefaultKeyBinding` so we do it ourselves here. + // + // * if macOS, read second option + const ctrlCmdCommand = { + // C-m => Toggles between rich text and markdown modes + [KeyCode.KEY_M]: 'toggle-mode', + [KeyCode.KEY_B]: 'bold', + [KeyCode.KEY_I]: 'italic', + [KeyCode.KEY_U]: 'underline', + [KeyCode.KEY_J]: 'code', + [KeyCode.KEY_O]: 'split-block', + }[ev.keyCode]; + + if (ctrlCmdCommand) { + if (!ctrlCmdOnly) { + return null; + } + return ctrlCmdCommand; } - return getDefaultKeyBinding(e); + // Handle keys such as return, left and right arrows etc. + return getDefaultKeyBinding(ev); } static getBlockStyle(block: ContentBlock): ?string { From bef67262905bee335e90f60627bda0b1ebf9ecf1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 13:42:51 +0100 Subject: [PATCH 076/164] Lint --- src/components/structures/UserSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 72a287d584..916e50d86b 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -102,9 +102,9 @@ const SETTINGS_LABELS = [ label: 'Automatically replace plain text Emoji', }, { - id :'Pill.shouldHidePillAvatar', + id: 'Pill.shouldHidePillAvatar', label: 'Hide avatars in user and room mentions', - } + }, /* { id: 'useFixedWidthFont', From 503fa6a7b3f6c201c805eca3da16f7535364312b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 14:59:56 +0100 Subject: [PATCH 077/164] Always use message `body` when quoting (not formatted_body) This is because draft-js has regressed with a bug that causes some entities to not exist within a given ContentState - see vector-im/riot-web#4756 --- src/components/views/rooms/MessageComposerInput.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 283a0e9330..4e6b57b7f4 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -279,10 +279,13 @@ export default class MessageComposerInput extends React.Component { } break; case 'quote': { - let {body, formatted_body} = payload.event.getContent(); - formatted_body = formatted_body || escape(body); - if (formatted_body) { - let content = RichText.htmlToContentState(`
${formatted_body}
`); + let {body} = payload.event.getContent(); + /// XXX: Not doing rich-text quoting from formatted-body because draft-js + /// has regressed such that when links are quoted, errors are thrown. See + /// https://github.com/vector-im/riot-web/issues/4756. + body = escape(body); + if (body) { + let content = RichText.htmlToContentState(`
${body}
`); if (!this.state.isRichtextEnabled) { content = ContentState.createFromText(RichText.stateToMarkdown(content)); } From a72f38799f82cabe1bc9d0fc1b9d610311490707 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 15:58:15 +0100 Subject: [PATCH 078/164] Disable autocompletions for users and rooms when entering a command This only affects commands that take a room alias or user ID as an argument. (Leaving commands such as `/me` unaffected) --- src/autocomplete/RoomProvider.js | 6 ++++++ src/autocomplete/UserProvider.js | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/autocomplete/RoomProvider.js b/src/autocomplete/RoomProvider.js index 3749e7e693..1770089eb2 100644 --- a/src/autocomplete/RoomProvider.js +++ b/src/autocomplete/RoomProvider.js @@ -49,6 +49,12 @@ export default class RoomProvider extends AutocompleteProvider { async getCompletions(query: string, selection: {start: number, end: number}, force = false) { const RoomAvatar = sdk.getComponent('views.avatars.RoomAvatar'); + // Disable autocompletions when composing commands because of various issues + // (see https://github.com/vector-im/riot-web/issues/4762) + if (/^(\/join|\/leave)/.test(query)) { + return []; + } + const client = MatrixClientPeg.get(); let completions = []; const {command, range} = this.getCurrentCommand(query, selection, force); diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index 499ddb51ce..5db0369150 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -48,6 +48,12 @@ export default class UserProvider extends AutocompleteProvider { async getCompletions(query: string, selection: {start: number, end: number}, force = false) { const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar'); + // Disable autocompletions when composing commands because of various issues + // (see https://github.com/vector-im/riot-web/issues/4762) + if (/^(\/ban|\/unban|\/op|\/deop|\/invite|\/kick|\/verify)/.test(query)) { + return []; + } + let completions = []; let {command, range} = this.getCurrentCommand(query, selection, force); if (command) { From cb8a66b5a119d46e93265b0f73031e10d7559fa0 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 8 Aug 2017 17:25:11 +0100 Subject: [PATCH 079/164] When `hide`ing autocomplete, also remove completion state --- src/components/views/rooms/Autocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index 1ea2eada7c..cdd57801a5 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -172,7 +172,7 @@ export default class Autocomplete extends React.Component { } hide() { - this.setState({hide: true, selectionOffset: 0}); + this.setState({hide: true, selectionOffset: 0, completions: [], completionList: []}); } forceComplete() { From da85cb9f454227d9d165c1e6660463cafaa59457 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Aug 2017 12:34:40 +0100 Subject: [PATCH 080/164] Show unencrypted messages as unencrypted Previously, we were special-casing outgoing messages such that they were shown as encrypted even when encryption had failed for some reason. There's no need for this: outgoing messages have a working isEncrypted() method which we can use to show whether the event has been encrypted yet. Arguably we could do better than an open padlock for events in the 'encrypting' send state, but I'm not really sure what. --- src/components/views/rooms/EventTile.js | 94 +++++++++++++++++++------ 1 file changed, 71 insertions(+), 23 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index b3831a7d0d..815f0a3c6a 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -155,7 +155,9 @@ module.exports = withMatrixClient(React.createClass({ }, componentWillReceiveProps: function(nextProps) { - if (nextProps.mxEvent !== this.props.mxEvent) { + // re-check the sender verification as outgoing events progress through + // the send process. + if (nextProps.eventSendStatus !== this.props.eventSendStatus) { this._verifyEvent(nextProps.mxEvent); } }, @@ -386,6 +388,36 @@ module.exports = withMatrixClient(React.createClass({ }); }, + _renderE2EPadlock: function() { + const ev = this.props.mxEvent; + const props = {onClick: this.onCryptoClicked}; + + + if (ev.getContent().msgtype === 'm.bad.encrypted') { + return ; + } else if (ev.isEncrypted()) { + if (this.state.verified) { + return ; + } else { + return ; + } + } else { + // XXX: if the event is being encrypted (ie eventSendStatus === + // encrypting), it might be nice to show something other than the + // open padlock? + + // if the event is not encrypted, but it's an e2e room, show the + // open padlock + const e2eEnabled = this.props.matrixClient.isRoomEncrypted(ev.getRoomId()); + if (e2eEnabled) { + return ; + } + } + + // no padlock needed + return null; + }, + render: function() { var MessageTimestamp = sdk.getComponent('messages.MessageTimestamp'); var SenderProfile = sdk.getComponent('messages.SenderProfile'); @@ -407,7 +439,6 @@ module.exports = withMatrixClient(React.createClass({ throw new Error("Event type not supported"); } - var e2eEnabled = this.props.matrixClient.isRoomEncrypted(this.props.mxEvent.getRoomId()); var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1); const isRedacted = (eventType === 'm.room.message') && this.props.isRedacted; @@ -485,26 +516,7 @@ module.exports = withMatrixClient(React.createClass({ const editButton = ( ); - let e2e; - // cosmetic padlocks: - if ((e2eEnabled && this.props.eventSendStatus) || this.props.mxEvent.getType() === 'm.room.encryption') { - e2e = {_t("Encrypted; - } - // real padlocks - else if (this.props.mxEvent.isEncrypted() || (e2eEnabled && this.props.eventSendStatus)) { - if (this.props.mxEvent.getContent().msgtype === 'm.bad.encrypted') { - e2e = {_t("Undecryptable")}; - } - else if (this.state.verified == true || (e2eEnabled && this.props.eventSendStatus)) { - e2e = {_t("Encrypted; - } - else { - e2e = {_t("Encrypted; - } - } - else if (e2eEnabled) { - e2e = {_t("Unencrypted; - } + const timestamp = this.props.mxEvent.getTs() ? : null; @@ -572,7 +584,7 @@ module.exports = withMatrixClient(React.createClass({ { timestamp } - { e2e } + { this._renderE2EPadlock() } + ); +} + +function E2ePadlockVerified(props) { + return ( + + ); +} + +function E2ePadlockUnverified(props) { + return ( + + ); +} + +function E2ePadlockUnencrypted(props) { + return ( + + ); +} + +function E2ePadlock(props) { + return ; +} From 38114711fdde1fa5c019c34f3a9c93d3b4e64108 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Aug 2017 22:19:38 +0100 Subject: [PATCH 081/164] Make MatrixChat do fewer render cycles during mount This is mostly with the intent of making the login tests more reliable, but it seems generally worthwhile: * keep screenAfterLogin in the object props rather than `state` so that we can clear it without triggering a rerender * also move our record of the window width to the object props, and call `handleResize` from componentWillMount rather than componentDidMount so that we don't trigger a rerender by updating `state.width` * Remove update of unused `loading` state --- src/components/structures/MatrixChat.js | 48 ++++++++++++------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index b90cb53435..cb6419c9e8 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -131,9 +131,6 @@ module.exports = React.createClass({ // the master view we are showing. view: VIEWS.LOADING, - // a thing to call showScreen with once login completes. - screenAfterLogin: this.props.initialScreenAfterLogin, - // What the LoggedInView would be showing if visible page_type: null, @@ -147,8 +144,6 @@ module.exports = React.createClass({ collapse_lhs: false, collapse_rhs: false, - ready: false, - width: 10000, leftOpacity: 1.0, middleOpacity: 1.0, rightOpacity: 1.0, @@ -274,6 +269,15 @@ module.exports = React.createClass({ register_hs_url: paramHs, }); } + + // a thing to call showScreen with once login completes. this is kept + // outside this.state because updating it should never trigger a + // rerender. + this._screenAfterLogin = this.props.initialScreenAfterLogin; + + this._windowWidth = 10000; + this.handleResize(); + window.addEventListener('resize', this.handleResize); }, componentDidMount: function() { @@ -294,9 +298,6 @@ module.exports = React.createClass({ linkifyMatrix.onGroupClick = this.onGroupClick; } - window.addEventListener('resize', this.handleResize); - this.handleResize(); - const teamServerConfig = this.props.config.teamServerConfig || {}; Lifecycle.initRtsClient(teamServerConfig.teamServerURL); @@ -312,13 +313,12 @@ module.exports = React.createClass({ // if the user has followed a login or register link, don't reanimate // the old creds, but rather go straight to the relevant page - const firstScreen = this.state.screenAfterLogin ? - this.state.screenAfterLogin.screen : null; + const firstScreen = this._screenAfterLogin ? + this._screenAfterLogin.screen : null; if (firstScreen === 'login' || firstScreen === 'register' || firstScreen === 'forgot_password') { - this.setState({loading: false}); this._showScreenAfterLogin(); return; } @@ -367,9 +367,9 @@ module.exports = React.createClass({ } const newState = { viewUserId: null, - }; - Object.assign(newState, state); - this.setState(newState); + }; + Object.assign(newState, state); + this.setState(newState); }, onAction: function(payload) { @@ -992,14 +992,12 @@ module.exports = React.createClass({ _showScreenAfterLogin: function() { // If screenAfterLogin is set, use that, then null it so that a second login will // result in view_home_page, _user_settings or _room_directory - if (this.state.screenAfterLogin && this.state.screenAfterLogin.screen) { + if (this._screenAfterLogin && this._screenAfterLogin.screen) { this.showScreen( - this.state.screenAfterLogin.screen, - this.state.screenAfterLogin.params, + this._screenAfterLogin.screen, + this._screenAfterLogin.params, ); - // XXX: is this necessary? `showScreen` should do it for us. - this.notifyNewScreen(this.state.screenAfterLogin.screen); - this.setState({screenAfterLogin: null}); + this._screenAfterLogin = null; } else if (localStorage && localStorage.getItem('mx_last_room_id')) { // Before defaulting to directory, show the last viewed room dis.dispatch({ @@ -1276,20 +1274,20 @@ module.exports = React.createClass({ const hideRhsThreshold = 820; const showRhsThreshold = 820; - if (this.state.width > hideLhsThreshold && window.innerWidth <= hideLhsThreshold) { + if (this._windowWidth > hideLhsThreshold && window.innerWidth <= hideLhsThreshold) { dis.dispatch({ action: 'hide_left_panel' }); } - if (this.state.width <= showLhsThreshold && window.innerWidth > showLhsThreshold) { + if (this._windowWidth <= showLhsThreshold && window.innerWidth > showLhsThreshold) { dis.dispatch({ action: 'show_left_panel' }); } - if (this.state.width > hideRhsThreshold && window.innerWidth <= hideRhsThreshold) { + if (this._windowWidth > hideRhsThreshold && window.innerWidth <= hideRhsThreshold) { dis.dispatch({ action: 'hide_right_panel' }); } - if (this.state.width <= showRhsThreshold && window.innerWidth > showRhsThreshold) { + if (this._windowWidth <= showRhsThreshold && window.innerWidth > showRhsThreshold) { dis.dispatch({ action: 'show_right_panel' }); } - this.setState({width: window.innerWidth}); + this._windowWidth = window.innerWidth; }, onRoomCreated: function(roomId) { From 610b2a3a428df410d2549508b2a3f883526c4e3b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 Aug 2017 10:40:06 +0100 Subject: [PATCH 082/164] For mentions, always use rawDisplayName and remove (IRC) --- src/autocomplete/UserProvider.js | 2 +- src/components/views/rooms/MessageComposerInput.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index 5db0369150..69b80dade4 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -62,7 +62,7 @@ export default class UserProvider extends AutocompleteProvider { return { // Length of completion should equal length of text in decorator. draft-js // relies on the length of the entity === length of the text in the decoration. - completion: user.rawDisplayName, + completion: user.rawDisplayName.replace(' (IRC)', ''), suffix: range.start === 0 ? ': ' : ' ', href: 'https://matrix.to/#/' + user.userId, component: ( diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 4e6b57b7f4..b2c1436365 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -269,7 +269,8 @@ export default class MessageComposerInput extends React.Component { // paths for inserting a user pill is not fun const selection = this.state.editorState.getSelection(); const member = this.props.room.getMember(payload.user_id); - const completion = member ? member.name.replace(' (IRC)', '') : payload.user_id; + const completion = member ? + member.rawDisplayName.replace(' (IRC)', '') : payload.user_id; this.setDisplayedCompletion({ completion, selection, From 579090a4e307cd38403c7fed163f73b615d34c62 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Wed, 9 Aug 2017 16:37:38 +0100 Subject: [PATCH 083/164] add comment --- src/components/views/dialogs/SetMxIdDialog.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 9fb6b838b2..554a244358 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -108,6 +108,7 @@ export default React.createClass({ _doUsernameCheck: function() { // XXX: SPEC-1 // Check if username is valid + // Naive impl copied from https://github.com/matrix-org/matrix-react-sdk/blob/66c3a6d9ca695780eb6b662e242e88323053ff33/src/components/views/login/RegistrationForm.js#L190 if (encodeURIComponent(this.state.username) !== this.state.username) { this.setState({ usernameError: _t('User names may only contain letters, numbers, dots, hyphens and underscores.'), From 2d47d3d2c371d5d31d1239dc5a98c2a779a07c98 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 Aug 2017 17:36:35 +0100 Subject: [PATCH 084/164] Hide autocomplete when RTE selection state (cursor) changes --- src/components/views/rooms/MessageComposerInput.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index b2c1436365..ab6c20684b 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -457,6 +457,19 @@ export default class MessageComposerInput extends React.Component { state.editorState = RichText.attachImmutableEntitiesToEmoji( state.editorState); + // Hide the autocomplete if the cursor location changes but the plaintext + // content stays the same. We don't hide if the pt has changed because the + // autocomplete will probably have different completions to show. + if ( + !state.editorState.getSelection().equals( + this.state.editorState.getSelection() + ) + && state.editorState.getCurrentContent().getPlainText() === + this.state.editorState.getCurrentContent().getPlainText() + ) { + this.autocomplete.hide(); + } + if (state.editorState.getCurrentContent().hasText()) { this.onTypingActivity(); } else { From e121440d05088ed7267dd40bff5ac6083974e69b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 Aug 2017 18:39:06 +0100 Subject: [PATCH 085/164] Track whether the user has richtext mode enabled --- src/Analytics.js | 6 ++++++ src/components/views/rooms/MessageComposerInput.js | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/Analytics.js b/src/Analytics.js index 92691da1ea..0a31625ebc 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -31,6 +31,7 @@ const customVariables = { 'User Type': 3, 'Chosen Language': 4, 'Instance': 5, + 'RTE: Uses Richtext Mode': 6, }; @@ -145,6 +146,11 @@ class Analytics { if (this.disabled) return; this._setVisitVariable('User Type', guest ? 'Guest' : 'Logged In'); } + + setRichtextMode(state) { + if (this.disabled) return; + this._setVisitVariable('RTE: Uses Richtext Mode', state ? 'on' : 'off'); + } } if (!global.mxAnalytics) { diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index b2c1436365..aa4acd7655 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -31,6 +31,7 @@ import KeyCode from '../../../KeyCode'; import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import Analytics from '../../../Analytics'; import dis from '../../../dispatcher'; import UserSettingsStore from '../../../UserSettingsStore'; @@ -513,6 +514,8 @@ export default class MessageComposerInput extends React.Component { contentState = ContentState.createFromText(markdown); } + Analytics.setRichtextMode(enabled); + this.setState({ editorState: this.createEditorState(enabled, contentState), isRichtextEnabled: enabled, From fc6977e68d5be61a135a47d434cec36f2d61173c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 Aug 2017 19:00:38 +0100 Subject: [PATCH 086/164] Track RT mode once we've retrieved the setting from account data --- src/components/views/rooms/MessageComposerInput.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index aa4acd7655..856c7aaa88 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -161,6 +161,8 @@ export default class MessageComposerInput extends React.Component { const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false); + Analytics.setRichtextMode(isRichtextEnabled); + this.state = { // whether we're in rich text or markdown mode isRichtextEnabled, From 678c472b753940553d68445bd10ded0be27c9295 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 Aug 2017 10:14:14 +0100 Subject: [PATCH 087/164] Quote by taking the innerText of eventTiles because using `body` gives inconsistent results - sometimes it will contain markdown and sometimes not, and this may not correspond with the `formatted_body`. TODO: Do quoting proper - using `in_response_to`. --- src/components/views/messages/TextualBody.js | 15 +++++++++------ .../views/rooms/MessageComposerInput.js | 3 +-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 27dba76146..18265ce559 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -275,18 +275,21 @@ module.exports = React.createClass({ }, getEventTileOps: function() { - var self = this; return { - isWidgetHidden: function() { - return self.state.widgetHidden; + isWidgetHidden: () => { + return this.state.widgetHidden; }, - unhideWidget: function() { - self.setState({ widgetHidden: false }); + unhideWidget: () => { + this.setState({ widgetHidden: false }); if (global.localStorage) { - global.localStorage.removeItem("hide_preview_" + self.props.mxEvent.getId()); + global.localStorage.removeItem("hide_preview_" + this.props.mxEvent.getId()); } }, + + getInnerText: () => { + return this.refs.content.innerText; + } }; }, diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index b2c1436365..950ccfc21f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -280,11 +280,10 @@ export default class MessageComposerInput extends React.Component { } break; case 'quote': { - let {body} = payload.event.getContent(); /// XXX: Not doing rich-text quoting from formatted-body because draft-js /// has regressed such that when links are quoted, errors are thrown. See /// https://github.com/vector-im/riot-web/issues/4756. - body = escape(body); + let body = escape(payload.text); if (body) { let content = RichText.htmlToContentState(`
${body}
`); if (!this.state.isRichtextEnabled) { From 07633fe67f726c84b47fbc41984122f1ffd8ff61 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 Aug 2017 13:12:50 +0100 Subject: [PATCH 088/164] At /user, view member of current room With the fallback of existing behaviour, which is UserView (no middle panel and no avatar, display name). To improve, MemberInfo should probably track the current roomId and userId and then update the view asynchronously by re-fetching the member object when either roomId or userId change. Also, it should be hitting the profile API to get the user's avatar if a room hasn't been specified. --- src/components/structures/LoggedInView.js | 4 +-- src/components/structures/MatrixChat.js | 44 +++++++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 093fae5d7b..0790a5766e 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -301,13 +301,13 @@ export default React.createClass({ case PageTypes.UserView: page_element = null; // deliberately null for now - right_panel = ; + right_panel = ; break; case PageTypes.GroupView: page_element = ; - //right_panel = ; + //right_panel = ; break; } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index cb6419c9e8..784526b09b 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -448,6 +448,7 @@ module.exports = React.createClass({ }); }, 0); } + this.notifyNewScreen('user/' + payload.member.userId); break; case 'view_room': // Takes either a room ID or room alias: if switching to a room the client is already @@ -1203,21 +1204,44 @@ module.exports = React.createClass({ } else if (screen.indexOf('user/') == 0) { const userId = screen.substring(5); - if (params.action === 'chat') { - this._chatCreateOrReuse(userId); - return; - } + // Wait for the first sync so that `getRoom` gives us a room object if it's + // in the sync response + const waitFor = this.firstSyncPromise ? + this.firstSyncPromise.promise : Promise.resolve(); + waitFor.then(() => { + if (params.action === 'chat') { + this._chatCreateOrReuse(userId); + return; + } - this.setState({ viewUserId: userId }); - this._setPage(PageTypes.UserView); - this.notifyNewScreen('user/' + userId); - const member = new Matrix.RoomMember(null, userId); - if (member) { + // Get the member object for the current room, if a current room is set or + // we have a last_room in localStorage. The user might not be a member of + // this room (in which case member will be falsey). + let member; + const roomId = this.state.currentRoomId || localStorage.getItem('mx_last_room_id'); + if (roomId) { + const room = MatrixClientPeg.get().getRoom(roomId); + if (room) { + member = room.getMember(userId); + } + } + + if (member) { + // This user is a member of this room, so view the room + dis.dispatch({ + action: 'view_room', + room_id: roomId, + }); + } else { + // This user is not a member of this room, show the user view + member = new Matrix.RoomMember(roomId, userId); + this._setPage(PageTypes.UserView); + } dis.dispatch({ action: 'view_user', member: member, }); - } + }); } else if (screen.indexOf('group/') == 0) { const groupId = screen.substring(6); From 60c1ba4f4d48c33eaf84a5b6ab66721903db87ea Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 10 Aug 2017 14:29:10 +0200 Subject: [PATCH 089/164] Add LanguageDropdown to LoginPage (#1284) --- src/components/structures/login/Login.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index a081d2a205..a6c0a70c66 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -19,8 +19,11 @@ limitations under the License. import React from 'react'; import { _t, _tJsx } from '../../../languageHandler'; +import * as languageHandler from '../../../languageHandler'; import sdk from '../../../index'; import Login from '../../../Login'; +import UserSettingsStore from '../../../UserSettingsStore'; +import PlatformPeg from '../../../PlatformPeg'; // For validating phone numbers without country codes const PHONE_NUMBER_REGEX = /^[0-9\(\)\-\s]*$/; @@ -306,6 +309,23 @@ module.exports = React.createClass({ } }, + _onLanguageChange: function(newLang) { + if(languageHandler.getCurrentLanguage() !== newLang) { + UserSettingsStore.setLocalSetting('language', newLang); + PlatformPeg.get().reload(); + } + }, + + _renderLanguageSetting: function() { + const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown'); + return
+ +
; + }, + render: function() { const Loader = sdk.getComponent("elements.Spinner"); const LoginHeader = sdk.getComponent("login.LoginHeader"); @@ -354,6 +374,7 @@ module.exports = React.createClass({ { loginAsGuestJsx } { returnToAppJsx } + { this._renderLanguageSetting() }
From 24599ace326fb7f9c1a182757431b45daaa279c5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 13:49:11 +0100 Subject: [PATCH 090/164] don't track error messages Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MatrixChat.js | 4 ++-- src/components/structures/RoomView.js | 2 +- src/components/structures/UserSettings.js | 10 +++++----- src/components/views/dialogs/ChatInviteDialog.js | 6 +++--- src/components/views/dialogs/ErrorDialog.js | 2 +- src/components/views/dialogs/SetEmailDialog.js | 4 ++-- src/components/views/messages/MFileBody.js | 2 +- src/components/views/rooms/MessageComposerInput.js | 2 +- src/components/views/rooms/RoomHeader.js | 2 +- src/components/views/rooms/RoomSettings.js | 4 ++-- src/components/views/settings/AddPhoneNumber.js | 2 +- src/stores/RoomViewStore.js | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f042b41991..be747cc4b0 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -426,7 +426,7 @@ module.exports = React.createClass({ } }, (err) => { modal.close(); - Modal.createTrackedDialog('Failed to reject invitation', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invitation', '', ErrorDialog, { title: _t('Failed to reject invitation'), description: err.toString(), }); @@ -896,7 +896,7 @@ module.exports = React.createClass({ }, (err) => { modal.close(); console.error("Failed to leave room " + roomId + " " + err); - Modal.createTrackedDialog('Failed to leave room', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to leave room', '', ErrorDialog, { title: _t("Failed to leave room"), description: (err && err.message ? err.message : _t("Server may be unavailable, overloaded, or you hit a bug.")), diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 40dbc93071..4aee44d0c2 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1195,7 +1195,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t("unknown error code"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 9a0567ec30..cc385790a8 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -364,7 +364,7 @@ module.exports = React.createClass({ // const errMsg = (typeof err === "string") ? err : (err.error || ""); console.error("Failed to set avatar: " + err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', '', ErrorDialog, { title: _t("Failed to set avatar."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -409,7 +409,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change password: " + errMsg); - Modal.createTrackedDialog('Failed to change password', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to change password', '', ErrorDialog, { title: _t("Error"), description: errMsg, }); @@ -464,7 +464,7 @@ module.exports = React.createClass({ }, (err) => { this.setState({email_add_pending: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', '', ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -489,7 +489,7 @@ module.exports = React.createClass({ }).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to remove contact information: " + err); - Modal.createTrackedDialog('Remove 3pid failed', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Remove 3pid failed', '', ErrorDialog, { title: _t("Unable to remove contact information"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -530,7 +530,7 @@ module.exports = React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', '', ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 156d493fee..728860edec 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -367,7 +367,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -380,7 +380,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite user', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to invite user', '', ErrorDialog, { title: _t("Failed to invite user"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -401,7 +401,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 889549369d..beca107252 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -16,7 +16,7 @@ limitations under the License. /* * Usage: - * Modal.createTrackedDialog('An Identifier', err.toString(), ErrorDialog, { + * Modal.createTrackedDialog('An Identifier', 'some detail', ErrorDialog, { * title: "some text", (default: "Error") * description: "some more text", * button: "Button Text", diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index b5efbab8b7..a16b32d128 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -77,7 +77,7 @@ export default React.createClass({ }, (err) => { this.setState({emailBusy: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', '', ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -115,7 +115,7 @@ export default React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', '', ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index b300e41e50..53c36f234c 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -282,7 +282,7 @@ module.exports = React.createClass({ }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err); - Modal.createTrackedDialog('Error decrypting attachment', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Error decrypting attachment', '', ErrorDialog, { title: _t("Error"), description: _t("Error decrypting attachment"), }); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index c14b9ebf23..c6601f41b1 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -673,7 +673,7 @@ export default class MessageComposerInput extends React.Component { }, function(err) { console.error("Command failure: %s", err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Server error', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Server error', '', ErrorDialog, { title: _t("Server error"), description: ((err && err.message) ? err.message : _t("Server unavailable, overloaded, or something else went wrong.")), }); diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 741d7085e6..edd89e4a35 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -119,7 +119,7 @@ module.exports = React.createClass({ const errMsg = (typeof err === "string") ? err : (err.error || ""); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to set avatar: " + errMsg); - Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to set avatar."), }); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index b59ad1510c..58473f1fb3 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -58,7 +58,7 @@ const BannedUser = React.createClass({ ).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to unban: " + err); - Modal.createTrackedDialog('Failed to unban', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to unban', '', ErrorDialog, { title: _t('Error'), description: _t('Failed to unban'), }); @@ -549,7 +549,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t('unknown error code'); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, { title: _t('Error'), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); diff --git a/src/components/views/settings/AddPhoneNumber.js b/src/components/views/settings/AddPhoneNumber.js index bda488a412..16e768a23f 100644 --- a/src/components/views/settings/AddPhoneNumber.js +++ b/src/components/views/settings/AddPhoneNumber.js @@ -82,7 +82,7 @@ export default withMatrixClient(React.createClass({ }).catch((err) => { console.error("Unable to add phone number: " + err); let msg = err.message; - Modal.createTrackedDialog('Add Phone Number Error', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Add Phone Number Error', '', ErrorDialog, { title: _t("Error"), description: msg, }); diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index e4fe1068b7..bd9d3ea0fa 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -221,7 +221,7 @@ class RoomViewStore extends Store { }); const msg = err.message ? err.message : JSON.stringify(err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to join room', err.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to join room', '', ErrorDialog, { title: _t("Failed to join room"), description: msg, }); From 67f9c3774df15d59eb583e74ff870ee23372e02e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 13:51:47 +0100 Subject: [PATCH 091/164] make string more human-friendly Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/SetEmailDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index a16b32d128..ed5cef2f67 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -106,7 +106,7 @@ export default React.createClass({ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const message = _t("Unable to verify email address.") + " " + _t("Please check your email and click on the link it contains. Once this is done, click continue."); - Modal.createTrackedDialog('Verification Pending', 'M_THREEPID_AUTH_FAILED', QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '3pid Auth Failed', QuestionDialog, { title: _t("Verification Pending"), description: message, button: _t('Continue'), From 1603360c138262a7e20c11b138b0150f328cdaa3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 13:58:19 +0100 Subject: [PATCH 092/164] s/Membership/Member/ Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/shouldHideEvent.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index c7bb547512..8554557b38 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -16,10 +16,10 @@ function memberEventDiff(ev) { const diff = { - isMembershipEvent: ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined, + isMemberEvent: ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined, }; - if (!diff.isMembershipEvent) return diff; + if (!diff.isMemberEvent) return diff; const content = ev.getContent(); const prevContent = ev.getPrevContent(); @@ -39,7 +39,7 @@ export default function(ev, syncedSettings) { const eventDiff = memberEventDiff(ev); - if (eventDiff.isMembershipEvent) { + if (eventDiff.isMemberEvent) { if (syncedSettings['hideJoinLeaves'] && (eventDiff.isJoin || eventDiff.isPart)) return true; const isMemberAvatarDisplaynameChange = eventDiff.isAvatarChange || eventDiff.isDisplaynameChange; if (syncedSettings['hideAvatarDisplaynameChanges'] && isMemberAvatarDisplaynameChange) return true; From ab3abd2f7f5a1b42c2dd5873b8f92e68922b63bd Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 13:59:55 +0100 Subject: [PATCH 093/164] fix string casing Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/UserSettings.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 483aab7e58..3fd4a70c52 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -87,7 +87,7 @@ const SETTINGS_LABELS = [ }, { id: 'hideAvatarDisplaynameChanges', - label: 'Hide Avatar and Display Name changes', + label: 'Hide avatar and display name changes', }, { id: 'useCompactLayout', diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3edebc0284..c5cd6b516d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -346,7 +346,7 @@ "Hangup": "Hangup", "Hide Apps": "Hide Apps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Hide join/leave messages (invites/kicks/bans unaffected)", - "Hide Avatar and Display Name changes": "Hide Avatar and Display Name changes", + "Hide avatar and display name changes": "Hide avatar and display name changes", "Hide read receipts": "Hide read receipts", "Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar", "Historical": "Historical", From a6064c53d3985027f5d8fedad284077889949df3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 14:00:26 +0100 Subject: [PATCH 094/164] export shouldHideEvent fn named Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/shouldHideEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index 8554557b38..36aa2ae17d 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -33,7 +33,7 @@ function memberEventDiff(ev) { return diff; } -export default function(ev, syncedSettings) { +export default function shouldHideEvent(ev, syncedSettings) { // Hide redacted events if (syncedSettings['hideRedactions'] && ev.isRedacted()) return true; From 625ca96d864c1da6e4c054680e65c8f34f8996cc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 14:01:24 +0100 Subject: [PATCH 095/164] add comment about why state key must be not undefined Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/shouldHideEvent.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index 36aa2ae17d..0eec756390 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -16,6 +16,7 @@ function memberEventDiff(ev) { const diff = { + // a Member Event is a State Event and so its State Key must not be undefined. isMemberEvent: ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined, }; From 56ea528f43fc2c7eb9fd530f6c19d55d3fe607ba Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 15:17:52 +0100 Subject: [PATCH 096/164] don't track error messages .2 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 2 +- src/Lifecycle.js | 2 +- src/components/structures/GroupView.js | 4 ++-- src/components/structures/RoomView.js | 6 +++--- src/components/structures/TimelinePanel.js | 2 +- src/components/structures/UserSettings.js | 2 +- src/components/views/rooms/MemberInfo.js | 10 +++++----- src/createRoom.js | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 1bd1332ab3..93057fafed 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -360,7 +360,7 @@ class ContentMessages { desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName}); } var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Upload failed', err.message, ErrorDialog, { + Modal.createTrackedDialog('Upload failed', '', ErrorDialog, { title: _t('Upload Failed'), description: desc, }); diff --git a/src/Lifecycle.js b/src/Lifecycle.js index f4d1eeef08..4d8911f7a6 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -240,7 +240,7 @@ function _handleRestoreFailure(e) { const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - Modal.createTrackedDialog('Session Restore Error', e.message, SessionRestoreErrorDialog, { + Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { error: e.message, onFinished: (success) => { def.resolve(success); diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index fff61b1c24..20fc4841ba 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -266,7 +266,7 @@ export default React.createClass({ this.setState({uploadingAvatar: false}); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload avatar image", e); - Modal.createTrackedDialog('Failed to upload image', e.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to upload image', '', ErrorDialog, { title: _t('Error'), description: _t('Failed to upload image'), }); @@ -288,7 +288,7 @@ export default React.createClass({ }); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to save group profile", e); - Modal.createTrackedDialog('Failed to update group', e.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to update group', '', ErrorDialog, { title: _t('Error'), description: _t('Failed to update group'), }); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 4aee44d0c2..f825d1efbb 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -934,7 +934,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload file " + file + " " + error); - Modal.createTrackedDialog('Failed to upload file', error.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to upload file', '', ErrorDialog, { title: _t('Failed to upload file'), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or the file too big")), }); @@ -1021,7 +1021,7 @@ module.exports = React.createClass({ }, function(error) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Search failed: " + error); - Modal.createTrackedDialog('Search failed', error.toString(), ErrorDialog, { + Modal.createTrackedDialog('Search failed', '', ErrorDialog, { title: _t("Search failed"), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or search timed out :(")), }); @@ -1217,7 +1217,7 @@ module.exports = React.createClass({ var msg = error.message ? error.message : JSON.stringify(error); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to reject invite', error.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, { title: _t("Failed to reject invite"), description: msg, }); diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 7cd67f3da8..6be31361dd 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -923,7 +923,7 @@ var TimelinePanel = React.createClass({ var message = (error.errcode == 'M_FORBIDDEN') ? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.") : _t("Tried to load a specific point in this room's timeline, but was unable to find it."); - Modal.createTrackedDialog('Failed to load timeline position', error.toString(), ErrorDialog, { + Modal.createTrackedDialog('Failed to load timeline position', '', ErrorDialog, { title: _t("Failed to load timeline position"), description: message, onFinished: onFinished, diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 513d754277..e6568f85ec 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -335,7 +335,7 @@ module.exports = React.createClass({ }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to load user settings: " + error); - Modal.createTrackedDialog('Can\'t load user settings', error.toString(), ErrorDialog, { + Modal.createTrackedDialog('Can\'t load user settings', '', ErrorDialog, { title: _t("Can't load user settings"), description: ((error && error.message) ? error.message : _t("Server may be unavailable or overloaded")), }); diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 23c5de2eaa..64eeddb406 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -248,7 +248,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Kick error: " + err); - Modal.createTrackedDialog('Failed to kick', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failed to kick', '', ErrorDialog, { title: _t("Failed to kick"), description: ((err && err.message) ? err.message : "Operation failed"), }); @@ -290,7 +290,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Ban error: " + err); - Modal.createTrackedDialog('Failed to ban user', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failed to ban user', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to ban user"), }); @@ -340,7 +340,7 @@ module.exports = withMatrixClient(React.createClass({ console.log("Mute toggle success"); }, function(err) { console.error("Mute error: " + err); - Modal.createTrackedDialog('Failed to mute user', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failed to mute user', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to mute user"), }); @@ -385,7 +385,7 @@ module.exports = withMatrixClient(React.createClass({ dis.dispatch({action: 'view_set_mxid'}); } else { console.error("Toggle moderator error:" + err); - Modal.createTrackedDialog('Failed to toggle moderator status', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failed to toggle moderator status', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to toggle moderator status"), }); @@ -406,7 +406,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change power level " + err); - Modal.createTrackedDialog('Failed to change power level', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failed to change power level', '', ErrorDialog, { title: _t("Error"), description: _t("Failed to change power level"), }); diff --git a/src/createRoom.js b/src/createRoom.js index 2ba3bd06ef..944c6a70a1 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -115,7 +115,7 @@ function createRoom(opts) { action: 'join_room_error', }); console.error("Failed to create room " + roomId + " " + err); - Modal.createTrackedDialog('Failure to create room', err.message, ErrorDialog, { + Modal.createTrackedDialog('Failure to create room', '', ErrorDialog, { title: _t("Failure to create room"), description: _t("Server may be unavailable, overloaded, or you hit a bug."), }); From 41843f021daae720441a834a05f2861504d7b425 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 15:21:01 +0100 Subject: [PATCH 097/164] don't track two more potential risks Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/login/ForgotPassword.js | 3 +-- src/components/views/rooms/MessageComposerInput.js | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 2a6d5042dd..320d21f5b4 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -150,8 +150,7 @@ module.exports = React.createClass({ showErrorDialog: function(body, title) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - // TODO this will still lead to i18n in Analytics. - Modal.createTrackedDialog('Forgot Password Error', body, ErrorDialog, { + Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, { title: title, description: body, }); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 662d13ecfc..63be026608 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -729,7 +729,8 @@ export default class MessageComposerInput extends React.Component { } else if (cmd.error) { console.error(cmd.error); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Command error', cmd.error, ErrorDialog, { + // TODO possibly track which command they ran (not its Arguments) here + Modal.createTrackedDialog('Command error', '', ErrorDialog, { title: _t("Command error"), description: cmd.error, }); From 5450d6b9cafb2eba2ebb5bdba7e3d03676124a82 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2017 15:22:53 +0100 Subject: [PATCH 098/164] remove redundant check and add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/shouldHideEvent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index 0eec756390..1501e28875 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -16,10 +16,10 @@ function memberEventDiff(ev) { const diff = { - // a Member Event is a State Event and so its State Key must not be undefined. - isMemberEvent: ev.getType() === 'm.room.member' && ev.getStateKey() !== undefined, + isMemberEvent: ev.getType() === 'm.room.member', }; + // If is not a Member Event then the other checks do not apply, so bail early. if (!diff.isMemberEvent) return diff; const content = ev.getContent(); From 89254e77f45998c8b701f19163934cd16ccb534c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 Aug 2017 15:23:14 +0100 Subject: [PATCH 099/164] When no member, use `null` `roomId` --- src/components/structures/MatrixChat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 784526b09b..755109c5de 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1234,7 +1234,7 @@ module.exports = React.createClass({ }); } else { // This user is not a member of this room, show the user view - member = new Matrix.RoomMember(roomId, userId); + member = new Matrix.RoomMember(null, userId); this._setPage(PageTypes.UserView); } dis.dispatch({ From 975aa0f08ae59e6c5cfe9cd4f3c7a59715fb5e6f Mon Sep 17 00:00:00 2001 From: Krombel Date: Thu, 10 Aug 2017 22:24:12 +0000 Subject: [PATCH 100/164] Added translation using Weblate (Indonesian) --- src/i18n/strings/id.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/id.json diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/id.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 8b4e00330a12f189a693db8477c5c74caa80c8ae Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 4 Jul 2017 16:41:49 +0000 Subject: [PATCH 101/164] Translated using Weblate (Hungarian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 7c91079e72..49ddbfe764 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -304,8 +304,8 @@ "Encryption is enabled in this room": "Ebben a szobában a titkosítás be van kapcsolva", "Encryption is not enabled in this room": "Ebben a szobában a titkosítás nincs bekapcsolva", "%(senderName)s ended the call.": "%(senderName)s befejezte a hívást.", - "End-to-end encryption information": "Végponttól végpontig való titkosítási információk", - "End-to-end encryption is in beta and may not be reliable": "Végponttól végpontig tartó titkosítás béta állapotú és lehet, hogy nem megbízható", + "End-to-end encryption information": "Ponttól pontig való titkosítási információk", + "End-to-end encryption is in beta and may not be reliable": "Ponttól pontig tartó titkosítás béta állapotú és lehet, hogy nem megbízható", "Enter Code": "Kód megadása", "Enter passphrase": "Jelmondat megadása", "Error decrypting attachment": "Csatolmány visszafejtése sikertelen", @@ -346,10 +346,10 @@ "Forget room": "Szoba elfelejtése", "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", - "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "A biztonság érdekében a kilépéskor a végponttól végpontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", - "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van az egydi szerveren.", + "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van az Otthoni szerveren.", "Guests can't set avatars. Please register.": "A vendégek nem tudnak avatar képet beállítani. Kérlek regisztrálj.", "Guest users can't create new rooms. Please register to create room and start a chat.": "Vendégek nem készíthetnek szobákat. Kérlek regisztrálj, hogy szobát tudják nyitni és el tudj kezdeni csevegni.", "Guest users can't upload files. Please register to upload.": "Vendégek nem tölthetnek fel fájlokat. A feltöltéshez kérlek regisztrálj.", @@ -549,10 +549,10 @@ "The email address linked to your account must be entered.": "A fiókodhoz kötött e-mail címet add meg.", "Press to start a chat with someone": "Nyomd meg a gombot ha szeretnél csevegni valakivel", "Privacy warning": "Magánéleti figyelmeztetés", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte az egyedi szerverben beállított feltöltési méret határt", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte az Otthoni szerverben beállított feltöltési méret határt", "The file '%(fileName)s' failed to upload": "'%(fileName)s' fájl feltöltése sikertelen", "The remote side failed to pick up": "A hívott fél nem vette fel", - "This Home Server does not support login using email address.": "Az egyedi szerver nem támogatja a belépést e-mail címmel.", + "This Home Server does not support login using email address.": "Az Otthoni szerver nem támogatja a belépést e-mail címmel.", "This invitation was sent to an email address which is not associated with this account:": "A meghívó olyan e-mail címre lett küldve ami nincs összekötve ezzel a fiókkal:", "There was a problem logging in.": "Hiba történt a bejelentkezésnél.", "This room has no local addresses": "Ennek a szobának nincs helyi címe", @@ -587,7 +587,7 @@ "Tried to load a specific point in this room's timeline, but was unable to find it.": "Megpróbáltam betölteni a szoba megadott időpontjának megfelelő adatait, de nem találom.", "Turn Markdown off": "Markdown kikapcsolása", "Turn Markdown on": "Markdown bekapcsolása", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s bekapcsolta a titkosítást végponttól végpontig (algoritmus %(algorithm)s).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s bekapcsolta a titkosítást ponttól pontig (algoritmus %(algorithm)s).", "Unable to add email address": "Az e-mail címet nem sikerült hozzáadni", "Unable to remove contact information": "A névjegy információkat nem sikerült törölni", "Unable to restore previous session": "Az előző kapcsolat visszaállítása sikertelen", @@ -684,7 +684,7 @@ "You seem to be uploading files, are you sure you want to quit?": "Úgy tűnik fájlokat töltesz fel, biztosan kilépsz?", "You should not yet trust it to secure data": "Még ne bízz meg a titkosításban", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Nem leszel képes visszavonni ezt a változtatást mivel a felhasználót ugyanarra a szintre emeled amin te vagy.", - "Your home server does not support device management.": "Az egyedi szervered nem támogatja az eszközök kezelését.", + "Your home server does not support device management.": "Az Otthoni szervered nem támogatja az eszközök kezelését.", "Sun": "Vas", "Mon": "Hé", "Tue": "K", @@ -743,7 +743,7 @@ "quote": "idézet", "bullet": "lista", "numbullet": "számozott lista", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s %(repeats)s alkalommal lépett be", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s %(repeats)s alkalommal léptek be", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s %(repeats)s alkalommal lépett be", "%(severalUsers)sjoined": "%(severalUsers)s csatlakozott", "%(oneUser)sjoined": "%(oneUser)s csatlakozott", @@ -836,7 +836,7 @@ "Verify...": "Ellenőrzés...", "ex. @bob:example.com": "pl.: @bob:example.com", "Add User": "Felhasználó hozzáadás", - "This Home Server would like to make sure you are not a robot": "Az egyedi szerver meg szeretne győződni arról, hogy nem vagy robot", + "This Home Server would like to make sure you are not a robot": "Az Otthoni szerver meg szeretne győződni arról, hogy nem vagy robot", "Sign in with CAS": "Belépés CAS-sal", "Please check your email to continue registration.": "Ellenőrizd az e-mailedet a regisztráció folytatásához.", "Token incorrect": "Helytelen token", @@ -845,7 +845,7 @@ "You are registering with %(SelectedTeamName)s": "%(SelectedTeamName)s névvel regisztrálsz", "Default server": "Alapértelmezett szerver", "Custom server": "Egyedi szerver", - "Home server URL": "Egyedi szerver URL", + "Home server URL": "Otthoni szerver URL", "Identity server URL": "Azonosítási szerver URL", "What does this mean?": "Ez mit jelent?", "Error decrypting audio": "Hiba a hang visszafejtésénél", @@ -885,7 +885,7 @@ "Do you want to set an email address?": "Meg szeretnéd adni az e-mail címet?", "This will allow you to reset your password and receive notifications.": "Ezzel alaphelyzetbe tudod állítani a jelszavad és értesítéseket fogadhatsz.", "Deops user with given id": "A megadott azonosítójú felhasználó lefokozása", - "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "A jelszó lecserélése megújítja a végponttól végpontig való titkosításhoz használt kulcsokat minden eszközön ezzel a titkosított szobák régi üzenetei olvashatatlanok lesznek hacsak nem mented el a kulcsokat és utána visszatöltöd. A jövőben ezen javítunk.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "A jelszó lecserélése megújítja a ponttól pontig való titkosításhoz használt kulcsokat minden eszközön ezzel a titkosított szobák régi üzenetei olvashatatlanok lesznek hacsak nem mented el a kulcsokat és utána visszatöltöd. A jövőben ezen javítunk.", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "FIGYELEM: A KULCS ELLENŐRZÉS SIKERTELEN! A %(userId)s felhasználóhoz és %(deviceId)s eszközhöz tartozó \"%(fprint)s\" ujjlenyomat nem egyezik meg az ismert \"%(fingerprint)s\" ujjlenyomattal. Ez azt jelenti hogy a kapcsolatot lehallgathatják!", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Ezzel a folyamattal kimentheted a titkosított szobák üzeneteihez tartozó kulcsokat egy helyi fájlba. Ez után be tudod tölteni ezt a fájlt egy másik Matrix kliensbe, így az a kliens is vissza tudja fejteni az üzeneteket.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "A kimentett fájlal bárki el tudja olvasni a titkosított üzeneteket amiket te is, ezért tartsd biztonságban. Ehhez segítségül írj be egy jelmondatot amivel a kimentett adatok titkosításra kerülnek. Az adatok betöltése csak a jelmondat megadásával lehetséges később.", @@ -898,8 +898,8 @@ "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "A megjelenítési neved az ahogy a többiek látják amikor a szobában csevegsz. Mit szeretnél mi legyen?", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Jelenleg fekete listára teszel minden ismeretlen eszközt. Ha üzenetet szeretnél küldeni ezekre az eszközökre először ellenőrizned kell őket.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Azt javasoljuk, hogy menj végig ellenőrző folyamaton minden eszköznél, hogy meg megerősítsd minden eszköz a jogos tulajdonosához tartozik, de újraküldheted az üzenetet ellenőrzés nélkül, ha úgy szeretnéd.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Használhatod az egyedi szerver opciót hogy más Matrix szerverre csatlakozz egyedi szerver URL megadásával.", - "This allows you to use this app with an existing Matrix account on a different home server.": "Ezzel használhatod ezt az alkalmazást a meglévő Matrix fiókoddal és másik egyedi szerveren.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Használhatod az Otthoni szerver opciót hogy más Matrix szerverre csatlakozz Otthoni szerver URL megadásával.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Ezzel használhatod ezt az alkalmazást a meglévő Matrix fiókoddal és másik Otthoni szerveren.", "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Beállíthatsz egy egyedi azonosító szervert is de ez tulajdonképpen meggátolja az együttműködést e-mail címmel azonosított felhasználókkal.", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ha nem állítasz be e-mail címet nem fogod tudni a jelszavadat alaphelyzetbe állítani. Biztos vagy benne?", "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Azonosítás céljából egy harmadik félhez leszel irányítva (%(integrationsUrl)s). Folytatod?", From 305adf8b62114a57c31672e77e707ce0e52ed7bb Mon Sep 17 00:00:00 2001 From: ErCiccione Calcifer Date: Wed, 19 Jul 2017 00:02:33 +0000 Subject: [PATCH 102/164] Translated using Weblate (Italian) Currently translated at 19.2% (176 of 915 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 172 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 415761e2fa..835d2b8a0a 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -1,12 +1,178 @@ { - "Failed to forget room %(errCode)s": "Errore nel dimenticare la stanza %(errCode)", + "Failed to forget room %(errCode)s": "Impossibile dimenticare stanza %(errCode)s", "Mute": "Muta", "Notifications": "Notifiche", "Operation failed": "Operazione fallita", "Please Register": "Per favore registrati", - "powered by Matrix": "powered by Matrix", + "powered by Matrix": "offerto da Matrix", "Remove": "Rimuovi", "Search": "Cerca", "Settings": "Impostazioni", - "Start chat": "Avvia una chat" + "Start chat": "Avvia una chat", + "Room directory": "Directory camera", + "unknown error code": "codice errore sconosciuto", + "Cancel": "Annulla", + "Close": "Chiudi", + "Create new room": "Crea una nuova stanza", + "Custom Server Options": "Opzioni Server Personalizzate", + "Direct Chat": "Chat Diretta", + "Dismiss": "Scarta", + "Error": "Errore", + "Failed to join the room": "Impossibile entrare nella stanza", + "Favourite": "Preferito", + "ar-ae": "Arabo (U.A.E.)", + "ar-bh": "Arabo (Bahrain)", + "ar-dz": "Arabo (Algeria)", + "ar-eg": "Arabo (Egitto)", + "Sunday": "Domenica", + "Monday": "Lunedì", + "Tuesday": "Martedì", + "Wednesday": "Mercoledì", + "Thursday": "Giovedì", + "Friday": "Venerdì", + "Saturday": "Sabato", + "OK": "OK", + "Welcome page": "Pagina di benvenuto", + "Drop here %(toAction)s": "Rilascia qui %(toAction)s", + "Failed to change password. Is your password correct?": "Modifica password fallita. La tua password è corretta?", + "Continue": "Continua", + "ar-iq": "Arabo (Iraq)", + "ar-jo": "Arabo (Giordania)", + "ar-kw": "Arabo (Kuwait)", + "ar-lb": "Arabo (Libano)", + "ar-ly": "Arabo (Libia)", + "ar-ma": "Arabo (Marocco)", + "ar-om": "Arabo (Oman)", + "ar-qa": "Arabo (Qatar)", + "ar-sa": "Arabo (Arabia Saudita)", + "ar-sy": "Arabo (Siria)", + "ar-tn": "Arabo (Tunisia)", + "ar-ye": "Arabo (Yemen)", + "be": "Bielorusso", + "bg": "Bulgaro", + "ca": "Catalano", + "da": "Danese", + "de-at": "Tedesco (Austria)", + "de-ch": "Tedesco (Svizzera)", + "de": "Tedesco", + "de-li": "Tedesco (Liechtenstein)", + "de-lu": "Tedesco (Lussemburgo)", + "el": "Greco", + "en-au": "Inglese (Australia)", + "en-bz": "Inglese (Belize)", + "en-ca": "Inglese (Canada)", + "en": "Inglese", + "en-gb": "Inglese (Regno Unito)", + "en-ie": "Inglese (Irlanda)", + "en-jm": "Inglese (Jamaica)", + "en-nz": "Inglese (Nuova Zelanda)", + "en-tt": "Inglese (Trinidad)", + "en-us": "Inglese (Stati Uniti)", + "en-za": "Inglese (Sud Africa)", + "es-ar": "Spagnolo (Argentina)", + "es-bo": "Spagnolo (Bolivia)", + "es-cl": "Spagnolo (Cile)", + "es-co": "Spagnolo (Colombia)", + "es-cr": "Spagnolo (Costa Rica)", + "es-do": "Spagnolo (Repubblica Dominicana)", + "es-ec": "Spagnolo (Ecuador)", + "es-gt": "Spagnolo (Guatemala)", + "es-hn": "Spagnolo (Honduras)", + "es-mx": "Spagnolo (Messico)", + "es-ni": "Spagnolo (Nicaragua)", + "es-pa": "Spagnolo (Panama)", + "es-pe": "Spagnolo (Perù)", + "es-pr": "Spagnolo (Porto Rico)", + "es-py": "Spagnolo (Paraguay)", + "es": "Spagnolo (Spagna)", + "es-sv": "Spagnolo (El Salvador)", + "es-uy": "Spagnolo (Uruguay)", + "es-ve": "Spagnolo (Venezuela)", + "et": "Estone", + "eu": "Basco (Basco)", + "fa": "Farsi", + "fi": "Finlandese", + "fo": "Faeroese", + "fr-be": "Francese (Belgio)", + "fr-ca": "Francese (Canada)", + "fr-ch": "Francese (Svizzera)", + "fr": "Francese", + "fr-lu": "Francese (Lussemburgo)", + "ga": "Irlandese", + "gd": "Gaelico (Scozia)", + "he": "Ebraico", + "hi": "Hindi", + "hr": "Croato", + "hu": "Ungherese", + "id": "Indonesiano", + "is": "Islandese", + "it-ch": "Italiano (Svizzera)", + "it": "Italiano", + "ja": "Giapponese", + "ji": "Yiddish", + "ko": "Coreano", + "lt": "Lituano", + "lv": "Lettone", + "mk": "Macedone (FYROM)", + "ms": "Malese", + "mt": "Maltese", + "nl-be": "Olandese (Belgio)", + "nl": "Olandese", + "no": "Norvegese", + "pl": "Polacco", + "pt-br": "Portoghese Brasiliano", + "pt": "Portoghese", + "rm": "Romancio", + "ro-mo": "Rumeno (Repubblica di Moldavia)", + "ro": "Rumeno", + "ru-mo": "Russo (Repubblica di Moldavia)", + "ru": "Russo", + "sk": "Slovacco", + "sl": "Sloveno", + "sq": "Albanese", + "sr": "Serbo", + "sv-fi": "Svedese (Finlandia)", + "sv": "Svedese", + "sx": "Sutu", + "th": "Tailandese", + "tn": "Tswana", + "tr": "Turco", + "ts": "Tsonga", + "uk": "Ucraino", + "ur": "Urdu", + "vi": "Vietnamese", + "xh": "Xhosa", + "zh-cn": "Cinese (PRC)", + "zh-hk": "Cinese (Honk Kong SAR)", + "zh-sg": "Cinese (Singapore)", + "zh-tw": "Cinese (Taiwan)", + "zu": "Zulu", + "a room": "una stanza", + "%(targetName)s accepted an invitation.": "%(targetName)s ha accettato un invito.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s ha accettato l'invito per %(displayName)s.", + "Account": "Account", + "Access Token:": "Token di Accesso:", + "Add": "Aggiungi", + "Add a topic": "Aggiungi un argomento", + "Add email address": "Aggiungi indirizzo email", + "Add phone number": "Aggiungi numero di telefono", + "Admin": "Amministratore", + "Admin tools": "Strumenti di amministrazione", + "VoIP": "VoIP", + "No Microphones detected": "Nessun Microfono rilevato", + "No Webcams detected": "Nessuna Webcam rilevata", + "You may need to manually permit Riot to access your microphone/webcam": "Potresti dover permettere manualmente a Riot di accedere al tuo microfono/webcam", + "Default Device": "Dispositivo Predefinito", + "Microphone": "Microfono", + "Camera": "Videocamera", + "Advanced": "Avanzate", + "Algorithm": "Algoritmo", + "Hide removed messages": "Nascondi messaggi rimossi", + "Always show message timestamps": "Mostra sempre il timestamps dei messaggi", + "Authentication": "Autenticazione", + "Alias (optional)": "Alias (opzionale)", + "all room members": "Tutti i membri della stanza", + "all room members, from the point they are invited": "Tutti i membri della stanza, dal punto in cui sono stati/e invitati/e", + "all room members, from the point they joined": "tutti i membri della stanza, dal punto in cui si sono uniti", + "and": "e" } From 018c8721f4c011fc1072ca34152d9c162b65abeb Mon Sep 17 00:00:00 2001 From: kaiyou Date: Sun, 23 Jul 2017 08:09:13 +0000 Subject: [PATCH 103/164] Translated using Weblate (French) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 7ea39e40cb..75e44a146c 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -205,7 +205,7 @@ "%(senderName)s banned %(targetName)s.": "%(senderName)s a banni %(targetName)s.", "Ban": "Bannir", "Banned users": "Utilisateurs bannis", - "Bans user with given id": "Utilisateurs bannis avec un identifiant donné", + "Bans user with given id": "Bannit l'utilisateur avec un identifiant donné", "Blacklisted": "Sur liste noire", "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", @@ -541,7 +541,7 @@ "Verification": "Vérification", "verified": "vérifié", "Video call": "Appel vidéo", - "Voice call": "Appel audio", + "Voice call": "Appel vocal", "VoIP conference finished.": "Conférence audio terminée.", "VoIP conference started.": "Conférence audio démarrée.", "VoIP is unsupported": "Appels voix non supportés", @@ -796,7 +796,7 @@ "WARNING: Device already verified, but keys do NOT MATCH!": "ATTENTION : Appareil déjà vérifié mais les clés NE CORRESPONDENT PAS !", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATTENTION : ERREUR DE VÉRIFICATION DES CLÉS ! La clé de signature pour %(userId)s et l'appareil %(deviceId)s est “%(fprint)s” et ne correspond pas à la clé “%(fingerprint)s” qui a été fournie. Cela peut signifier que vos communications sont interceptées !", "VoIP": "Voix sur IP", - "Missing Media Permissions, click here to request.": "Manque de permission pour les médias, cliquer ici pour les demander.", + "Missing Media Permissions, click here to request.": "Manque de permissions pour les médias, cliquer ici pour les demander.", "No Microphones detected": "Aucun micro détecté", "No Webcams detected": "Aucune webcam détectée", "No media permissions": "Pas de permission pour les médias", @@ -867,7 +867,7 @@ "Failed to upload profile picture!": "Échec du téléchargement de la photo de profil !", "Incoming call from %(name)s": "Appel entrant de %(name)s", "Incoming video call from %(name)s": "Appel vidéo entrant de %(name)s", - "Incoming voice call from %(name)s": "Appel audio entrant de %(name)s", + "Incoming voice call from %(name)s": "Appel vocal entrant de %(name)s", "No display name": "Pas de nom d'affichage", "Otherwise, click here to send a bug report.": "Sinon, cliquer ici pour envoyer un rapport d'erreur.", "Private Chat": "Conversation Privée", From 0e2d5a798f485f04fb524b09c19eab29485729e3 Mon Sep 17 00:00:00 2001 From: IMIN <2reeseenmin@gmail.com> Date: Sun, 13 Aug 2017 03:59:17 +0000 Subject: [PATCH 104/164] Translated using Weblate (Korean) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 547fe4e1fb..ff96fed55e 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -560,7 +560,7 @@ "There was a problem logging in.": "로그인하는 데 문제가 있어요.", "This room has no local addresses": "이 방은 로컬 주소가 없어요", "This room is not recognised.": "이 방은 드러나지 않아요.", - "These are experimental features that may break in unexpected ways": "에상치 못한 방법으로 망가질 지도 모르는 실험 기능이에요", + "These are experimental features that may break in unexpected ways": "예상치 못한 방법으로 망가질 지도 모르는 실험 기능이에요", "The visibility of existing history will be unchanged": "기존 기록은 볼 수 있는 대상이 바뀌지 않아요", "This doesn't appear to be a valid email address": "올바르지 않은 이메일 주소로 보여요", "This is a preview of this room. Room interactions have been disabled": "방을 미리보는 거에요. 상호작용은 보이지 않아요", @@ -572,8 +572,8 @@ "To ban users": "사용자를 차단하기", "to browse the directory": "목록에서 찾으려면", "To configure the room": "방을 구성하기", - "to demote": "등급을 낮추려면", - "to favourite": "즐겨찾기하려면", + "to demote": "우선순위 낮추기", + "to favourite": "즐겨찾기", "To invite users into the room": "방으로 사용자를 초대하기", "To kick users": "사용자를 내쫓기", "To link to a room it must have an address.": "방에 연결하려면 주소가 있어야 해요.", @@ -628,7 +628,7 @@ "Upload new:": "새로 올리기:", "Usage": "사용", "Use compact timeline layout": "간단한 타임라인 구성 사용", - "Use with caution": "조심해서 사용", + "Use with caution": "조심해주세요", "User ID": "사용자 ID", "User Interface": "사용자 인터페이스", "%(user)s is a": "%(user)s는", From d4a5bd86e612eb9e5ffc8f1ebde7c10d0e289a3a Mon Sep 17 00:00:00 2001 From: IMIN <2reeseenmin@gmail.com> Date: Sun, 13 Aug 2017 03:59:40 +0000 Subject: [PATCH 105/164] Translated using Weblate (Korean) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index ff96fed55e..a0a1a1e90a 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -711,7 +711,7 @@ "Dec": "12월", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s일 %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s일 %(fullYear)s년 %(time)s", - "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s %(time)s": "%(weekDayName)s, %(time)s", "Set a display name:": "별명 설정:", "Set a Display Name": "별명 설정", "Upload an avatar:": "아바타 올리기:", From ab7aeccd35792929c18feeeb717cbdc800e25684 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 28 Jul 2017 07:47:15 +0000 Subject: [PATCH 106/164] Translated using Weblate (Russian) Currently translated at 100.0% (916 of 916 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 522fa75b90..19451170ee 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -104,8 +104,8 @@ "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "is a": "является", "Sign in with": "Войти с помощью", - "joined and left": "вошёл(ла) и вышел(ла)", - "joined": "вошёл(ла)", + "joined and left": "вошел(ла) и вышел(ла)", + "joined": "вошел(ла)", "joined the room": "joined the room", "Joins room with given alias": "Входит в комнату с заданным псевдонимом", "Kicks user with given id": "Выкидывает пользователя с заданным ID", @@ -251,7 +251,7 @@ "click to reveal": "нажмите для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", "%(displayName)s is typing": "%(displayName)s печатает", - "%(targetName)s joined the room.": "%(targetName)s вошел в комнату.", + "%(targetName)s joined the room.": "%(targetName)s вошел(ла) в комнату.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s выкинул %(targetName)s.", "%(targetName)s left the room.": "%(targetName)s покинул комнату.", "%(senderName)s made future room history visible to": "%(senderName)s сделал будущую историю комнаты видимой", @@ -608,17 +608,17 @@ "bullet": "список", "numbullet": "нумерованный список", "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s вошли %(repeats)s раз", - "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s вошёл(ла) %(repeats)s раз", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)s вошел(ла) %(repeats)s раз", "%(severalUsers)sjoined": "%(severalUsers)s вошли", - "%(oneUser)sjoined": "%(oneUser)s вошёл(ла)", + "%(oneUser)sjoined": "%(oneUser)s вошел(ла)", "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)s покинули %(repeats)s раз", "%(oneUser)sleft %(repeats)s times": "%(oneUser)s покинул %(repeats)s раз", "%(severalUsers)sleft": "%(severalUsers)s покинули", "%(oneUser)sleft": "%(oneUser)s покинул", "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s вошли и вышли %(repeats)s раз", - "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s вошёл(ла) и вышел(ла) %(repeats)s раз", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s вошел(ла) и вышел(ла) %(repeats)s раз", "%(severalUsers)sjoined and left": "%(severalUsers)s вошли и вышли", - "%(oneUser)sjoined and left": "%(oneUser)s вошёл(ла) и вышел(ла)", + "%(oneUser)sjoined and left": "%(oneUser)s вошел(ла) и вышел(ла)", "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s вышли и вернулись %(repeats)s раз", "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s вышел(ла) и вернулся(ась) %(repeats)s раз", "%(severalUsers)sleft and rejoined": "%(severalUsers)s вышли и вернулись", @@ -799,7 +799,7 @@ "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Чтобы удостовериться, что этому устройству можно доверять, пожалуйста, свяжитесь с владельцем другим способом (например, лично или по телефону) и спросите его, совпадает ли ключ, указанный у него в настройках для этого устройства, с ключом ниже:", "Device name": "Имя устройства", "Device key": "Ключ устройства", - "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, нажмите кнопку подтверждения ниже. Если нет — значит, кто-то перехватил это устройство, и вы, скорее всего, захотите внести его в чёрный список.", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Если совпадают, нажмите кнопку подтверждения ниже. Если нет — значит, кто-то перехватил это устройство, и вы, скорее всего, захотите внести его в черный список.", "In future this verification process will be more sophisticated.": "В будущем процесс проверки будет усовершенствован.", "Verify device": "Проверить устройство", "I verify that the keys match": "Я подтверждаю, что ключи совпадают", @@ -808,7 +808,7 @@ "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию Riot, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.", "Continue anyway": "Все равно продолжить", "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Отображаемое имя - это то, как вы отображаетесь в чате. Какое имя вы хотите?", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "У вас включено занесение непроверенных устройств в чёрный список. Для отправки сообщений на эти устройства вам необходимо их проверить.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "У вас включено занесение непроверенных устройств в черный список. Для отправки сообщений на эти устройства вам необходимо их проверить.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Мы рекомендуем вам выполнить процедуру проверки каждого устройства, чтобы удостовериться, что они принадлежат их законному владельцу, но вы можете переотправить сообщение без проверки, если хотите.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неподтвержденные устройства.", "Unknown Address": "Неизвестный адрес", From cbd8018ac83863b28a83701c0f0c742b6bc9399f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 12:26:31 +0100 Subject: [PATCH 107/164] Support semi-perma-disabling of lab features Adding `override: true` will remove the feature from the labs section, and force Riot to always use the default value (i.e. ignoring localStorage). This is useful removing features entirely when they might be deliberately not working but we still want to do a release. --- src/UserSettingsStore.js | 36 ++++++++++++++++------- src/components/structures/UserSettings.js | 16 ++++++++-- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index 4c66c90598..bf6d7e93cf 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -171,22 +171,36 @@ export default { localStorage.setItem('mx_local_settings', JSON.stringify(settings)); }, - isFeatureEnabled: function(feature: string): boolean { + getFeatureById(feature: string) { + for (let i = 0; i < this.LABS_FEATURES.length; i++) { + const f = this.LABS_FEATURES[i]; + if (f.id === feature) { + return f; + } + } + return null; + }, + + isFeatureEnabled: function(featureId: string): boolean { // Disable labs for guests. if (MatrixClientPeg.get().isGuest()) return false; - if (localStorage.getItem(`mx_labs_feature_${feature}`) === null) { - for (let i = 0; i < this.LABS_FEATURES.length; i++) { - const f = this.LABS_FEATURES[i]; - if (f.id === feature) { - return f.default; - } - } + const feature = this.getFeatureById(featureId); + if (!feature) { + console.warn('Unknown feature'); + return false; } - return localStorage.getItem(`mx_labs_feature_${feature}`) === 'true'; + // Return the default if this feature has an override to be the default value or + // if the feature has never been toggled and is therefore not in localStorage + if (Object.keys(feature).includes('override') || + localStorage.getItem(`mx_labs_feature_${featureId}`) === null + ) { + return feature.default; + } + return localStorage.getItem(`mx_labs_feature_${featureId}`) === 'true'; }, - setFeatureEnabled: function(feature: string, enabled: boolean) { - localStorage.setItem(`mx_labs_feature_${feature}`, enabled); + setFeatureEnabled: function(featureId: string, enabled: boolean) { + localStorage.setItem(`mx_labs_feature_${featureId}`, enabled); }, }; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index e2463a3ac7..c33410e857 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -859,7 +859,13 @@ module.exports = React.createClass({ if (this.props.enableLabs === false) return null; UserSettingsStore.doTranslations(); - const features = UserSettingsStore.LABS_FEATURES.map((feature) => { + const features = []; + UserSettingsStore.LABS_FEATURES.forEach((feature) => { + // This feature has an override and will be set to the default, so do not + // show it here. + if (feature.override) { + return; + } // TODO: this ought to be a separate component so that we don't need // to rebind the onChange each time we render const onChange = (e) => { @@ -867,7 +873,7 @@ module.exports = React.createClass({ this.forceUpdate(); }; - return ( + features.push(
); }); + + // No labs section when there are no features in labs + if (features.length === 0) { + return null; + } + return (

{ _t("Labs") }

From c97ae5c2e15581ae98f102ecc3e4863684e413b5 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 12:29:42 +0100 Subject: [PATCH 108/164] Override matrix-apps to be disabled - ignores localStorage setting - hides feature from labs section in user settings --- src/UserSettingsStore.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index bf6d7e93cf..ea060ff8d6 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -29,6 +29,9 @@ export default { name: "-", id: 'matrix_apps', default: false, + + // XXX: Always use default, ignore localStorage and remove from labs + override: true, }, ], From 3d5d7fa9c8cd4bb62fe8fcd14b7fb2afa51deccd Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 13:59:12 +0100 Subject: [PATCH 109/164] Lint --- src/components/structures/UserSettings.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index c33410e857..3c139f77a6 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -883,8 +883,7 @@ module.exports = React.createClass({ onChange={ onChange } /> -
- ); +
); }); // No labs section when there are no features in labs From d9e8292a5e1fe8805e3e07718fef957588902ebd Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 14:06:54 +0100 Subject: [PATCH 110/164] Revert "At /user, view member of current room" --- src/components/structures/LoggedInView.js | 4 +-- src/components/structures/MatrixChat.js | 44 ++++++----------------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 0790a5766e..093fae5d7b 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -301,13 +301,13 @@ export default React.createClass({ case PageTypes.UserView: page_element = null; // deliberately null for now - right_panel = ; + right_panel = ; break; case PageTypes.GroupView: page_element = ; - //right_panel = ; + //right_panel = ; break; } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 930c618f7a..6fdec80f38 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -448,7 +448,6 @@ module.exports = React.createClass({ }); }, 0); } - this.notifyNewScreen('user/' + payload.member.userId); break; case 'view_room': // Takes either a room ID or room alias: if switching to a room the client is already @@ -1204,44 +1203,21 @@ module.exports = React.createClass({ } else if (screen.indexOf('user/') == 0) { const userId = screen.substring(5); - // Wait for the first sync so that `getRoom` gives us a room object if it's - // in the sync response - const waitFor = this.firstSyncPromise ? - this.firstSyncPromise.promise : Promise.resolve(); - waitFor.then(() => { - if (params.action === 'chat') { - this._chatCreateOrReuse(userId); - return; - } + if (params.action === 'chat') { + this._chatCreateOrReuse(userId); + return; + } - // Get the member object for the current room, if a current room is set or - // we have a last_room in localStorage. The user might not be a member of - // this room (in which case member will be falsey). - let member; - const roomId = this.state.currentRoomId || localStorage.getItem('mx_last_room_id'); - if (roomId) { - const room = MatrixClientPeg.get().getRoom(roomId); - if (room) { - member = room.getMember(userId); - } - } - - if (member) { - // This user is a member of this room, so view the room - dis.dispatch({ - action: 'view_room', - room_id: roomId, - }); - } else { - // This user is not a member of this room, show the user view - member = new Matrix.RoomMember(null, userId); - this._setPage(PageTypes.UserView); - } + this.setState({ viewUserId: userId }); + this._setPage(PageTypes.UserView); + this.notifyNewScreen('user/' + userId); + const member = new Matrix.RoomMember(null, userId); + if (member) { dis.dispatch({ action: 'view_user', member: member, }); - }); + } } else if (screen.indexOf('group/') == 0) { const groupId = screen.substring(6); From b59de7964cd06f8b846e1b50f6f41384f319494b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 14:37:49 +0100 Subject: [PATCH 111/164] Wait for first sync before dispatching view_user on /user the RightPanel will be mounted once we're done doing the first sync, so wait until then and then dispatch a view_user. This is not very nice but it's what we do for view_room. --- src/components/structures/LoggedInView.js | 4 ++-- src/components/structures/MatrixChat.js | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 093fae5d7b..0790a5766e 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -301,13 +301,13 @@ export default React.createClass({ case PageTypes.UserView: page_element = null; // deliberately null for now - right_panel = ; + right_panel = ; break; case PageTypes.GroupView: page_element = ; - //right_panel = ; + //right_panel = ; break; } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 6fdec80f38..a512d60509 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1203,21 +1203,22 @@ module.exports = React.createClass({ } else if (screen.indexOf('user/') == 0) { const userId = screen.substring(5); - if (params.action === 'chat') { - this._chatCreateOrReuse(userId); - return; - } + const waitFor = this.firstSyncPromise ? + this.firstSyncPromise.promise : Promise.resolve(); + waitFor.then(() => { + if (params.action === 'chat') { + this._chatCreateOrReuse(userId); + return; + } - this.setState({ viewUserId: userId }); - this._setPage(PageTypes.UserView); - this.notifyNewScreen('user/' + userId); - const member = new Matrix.RoomMember(null, userId); - if (member) { + this._setPage(PageTypes.UserView); + this.notifyNewScreen('user/' + userId); + const member = new Matrix.RoomMember(null, userId); dis.dispatch({ action: 'view_user', member: member, }); - } + }); } else if (screen.indexOf('group/') == 0) { const groupId = screen.substring(6); From 2844b574d59124d3957d20da75a08024ef5d2dbd Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 14:41:03 +0100 Subject: [PATCH 112/164] Re-add useful comment --- src/components/structures/MatrixChat.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index a512d60509..8cb111bf82 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1203,6 +1203,8 @@ module.exports = React.createClass({ } else if (screen.indexOf('user/') == 0) { const userId = screen.substring(5); + // Wait for the first sync so that `getRoom` gives us a room object if it's + // in the sync response const waitFor = this.firstSyncPromise ? this.firstSyncPromise.promise : Promise.resolve(); waitFor.then(() => { From bb229d33a4f4bdd9db99ef13904a2fc95bfeb84f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 14:44:08 +0100 Subject: [PATCH 113/164] Add onClick to user pills instead of using the converted matrix.to href. This is undesirable and a better solution would be to fix routing in Riot in general and then change user pills to do something like `/room/../member/@userId`. --- src/components/views/elements/Pill.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index b5fa163608..7dee5f6a40 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; import sdk from '../../../index'; +import dis from '../../../dispatcher'; import classNames from 'classnames'; import { Room, RoomMember } from 'matrix-js-sdk'; import PropTypes from 'prop-types'; @@ -140,6 +141,12 @@ const Pill = React.createClass({ }); }, + onUserPillClicked: function() { + dis.dispatch({ + action: 'view_user', + member: this.state.member, + }); + }, render: function() { const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const RoomAvatar = sdk.getComponent('avatars.RoomAvatar'); @@ -150,6 +157,8 @@ const Pill = React.createClass({ let linkText = resource; let pillClass; let userId; + let href = this.props.url; + let onClick; switch (this.state.pillType) { case Pill.TYPE_USER_MENTION: { // If this user is not a member of this room, default to the empty member @@ -161,6 +170,8 @@ const Pill = React.createClass({ avatar = ; } pillClass = 'mx_UserPill'; + href = null; + onClick = this.onUserPillClicked.bind(this); } } break; @@ -183,7 +194,7 @@ const Pill = React.createClass({ if (this.state.pillType) { return this.props.inMessage ? - + {avatar} {linkText} : From 867e83edffd3b04f606085bd8e775f5dddde5eb1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 14:47:05 +0100 Subject: [PATCH 114/164] Fix log to include some useful info --- src/UserSettingsStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index ea060ff8d6..796dab4d60 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -190,7 +190,7 @@ export default { const feature = this.getFeatureById(featureId); if (!feature) { - console.warn('Unknown feature'); + console.warn(`Unknown feature "${featureId}"`); return false; } // Return the default if this feature has an override to be the default value or From 9742962d6136e30775887ab96d45a17990a56be3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 15:16:13 +0100 Subject: [PATCH 115/164] preventDefault when moving autocomplete selection with vertical arrow Otherwise the composer selection updates, in turn hiding the autocomplete box - fixes vector-im/riot-web#4790 --- src/components/views/rooms/MessageComposerInput.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 63be026608..636addb79c 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -890,6 +890,7 @@ export default class MessageComposerInput extends React.Component { } } else { this.moveAutocompleteSelection(up); + e.preventDefault(); } }; From 0079e70006dd0f72238c3b664155f0b11f8cdbd1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 15:40:49 +0100 Subject: [PATCH 116/164] Display RM when it = a standalone member event Standalone = not next to any member events in the timeline. fixes vector-im/riot-web#4694 --- src/components/structures/MessagePanel.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 6f4a5460f6..02f224e942 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -307,13 +307,13 @@ module.exports = React.createClass({ for (i = 0; i < this.props.events.length; i++) { let mxEv = this.props.events[i]; let eventId = mxEv.getId(); - let readMarkerInMels = false; let last = (mxEv === lastShownEvent); const wantTile = this._shouldShowEvent(mxEv); // Wrap consecutive member events in a ListSummary, ignore if redacted if (isMembershipChange(mxEv) && wantTile) { + let readMarkerInMels = false; let ts1 = mxEv.getTs(); // Ensure that the key of the MemberEventListSummary does not change with new // member events. This will prevent it from being re-created unnecessarily, and @@ -330,6 +330,11 @@ module.exports = React.createClass({ ret.push(dateSeparator); } + // If RM event is the first in the MELS, append the RM after MELS + if (mxEv.getId() === this.props.readMarkerEventId) { + readMarkerInMels = true; + } + let summarisedEvents = [mxEv]; for (;i + 1 < this.props.events.length; i++) { const collapsedMxEv = this.props.events[i + 1]; From ecef9cf22f229be7209335640e395cea467abbae Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 16:48:29 +0100 Subject: [PATCH 117/164] Use plaintext when loading a markdown history item into RT mode --- src/ComposerHistoryManager.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ComposerHistoryManager.js b/src/ComposerHistoryManager.js index ee2c748dc6..2fff3882b4 100644 --- a/src/ComposerHistoryManager.js +++ b/src/ComposerHistoryManager.js @@ -38,13 +38,11 @@ class HistoryItem { const contentState = convertFromRaw(this.rawContentState); if (outputFormat === 'markdown') { if (this.format === 'html') { - console.info(outputFormat, 'to other format'); return ContentState.createFromText(RichText.stateToMarkdown(contentState)); } } else { if (this.format === 'markdown') { - console.info(outputFormat, 'to other format'); - return RichText.htmlToContentState(new Markdown(contentState).toHTML()); + return RichText.htmlToContentState(new Markdown(contentState.getPlainText()).toHTML()); } } // history item has format === outputFormat From 844ca249d0276691436e0b8d8fc2388756b386db Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 Aug 2017 17:31:16 +0100 Subject: [PATCH 118/164] Fix bugs in textOffsetsToSelectionState This just had some thinkos in it. Namely the conditionals were slightly wrong and this lead to negative offset selection state being returned, causing vector-im/riot-web#4792 fixes vector-im/riot-web#4792 --- src/RichText.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 9876fcc93f..8d1177cdd2 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -204,23 +204,27 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, let selectionState = SelectionState.createEmpty(); for (const block of contentBlocks) { const blockLength = block.getLength(); - if (start !== -1 && start < blockLength) { - selectionState = selectionState.merge({ - anchorKey: block.getKey(), - anchorOffset: start, - }); - start = -1; - } else { - start -= blockLength + 1; // +1 to account for newline between blocks + if (start !== -1) { + if (start < blockLength + 1) { + selectionState = selectionState.merge({ + anchorKey: block.getKey(), + anchorOffset: start, + }); + start = -1; + } else { + start -= blockLength + 1; // +1 to account for newline between blocks + } } - if (end !== -1 && end <= blockLength) { - selectionState = selectionState.merge({ - focusKey: block.getKey(), - focusOffset: end, - }); - end = -1; - } else { - end -= blockLength + 1; // +1 to account for newline between blocks + if (end !== -1) { + if (end < blockLength + 1) { + selectionState = selectionState.merge({ + focusKey: block.getKey(), + focusOffset: end, + }); + end = -1; + } else { + end -= blockLength + 1; // +1 to account for newline between blocks + } } } return selectionState; From 447aa1e5a0fd9e3e4862ff25354f1a83728b63df Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 14 Aug 2017 17:38:59 +0100 Subject: [PATCH 119/164] Refactor ChatInviteDialog to be UserPickerDialog Now it's just a means of choosing users and all the actual inviting functionality is moved out to Invite.js. This will allow us to reuse it for inviting to groups. Adds the ability to restrict what types of addresses may be chosen, although this isn;t used yet, it will be necessary for groups because groups don't support 3pid invites. --- .../views/dialogs/{ChatInviteDialog.js => UserPickerDialog.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/views/dialogs/{ChatInviteDialog.js => UserPickerDialog.js} (100%) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/UserPickerDialog.js similarity index 100% rename from src/components/views/dialogs/ChatInviteDialog.js rename to src/components/views/dialogs/UserPickerDialog.js From 1b66e88b6ef1affbeaf5c32d347b64be1dd08be7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 14 Aug 2017 17:43:00 +0100 Subject: [PATCH 120/164] ChatInviteDialog -> UserPickerDialog pt 2 The other changes I forgot to add --- src/Invite.js | 129 ++++++++++ src/components/structures/MatrixChat.js | 23 +- .../views/dialogs/UserPickerDialog.js | 221 +++--------------- .../views/elements/AddressSelector.js | 2 +- src/components/views/elements/AddressTile.js | 22 +- 5 files changed, 164 insertions(+), 233 deletions(-) diff --git a/src/Invite.js b/src/Invite.js index 0e8aca2cb5..d825dac6f5 100644 --- a/src/Invite.js +++ b/src/Invite.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,11 +17,35 @@ limitations under the License. import MatrixClientPeg from './MatrixClientPeg'; import MultiInviter from './utils/MultiInviter'; +import Modal from "./Modal"; +import createRoom from './createRoom'; +import sdk from "./"; +import { _t } from './languageHandler'; const emailRegex = /^\S+@\S+\.\S+$/; const mxidRegex = /^@\S+:\S+$/ +export const addressTypes = [ + 'mx', 'email', +]; + +// React PropType definition for an object describing +// an address that can be invited to a room (which +// could be a third party identifier or a matrix ID) +// along with some additional information about the +// address / target. +export const InviteAddressType = React.PropTypes.shape({ + addressType: React.PropTypes.oneOf(addressTypes).isRequired, + address: React.PropTypes.string.isRequired, + displayName: React.PropTypes.string, + avatarMxc: React.PropTypes.string, + // true if the address is known to be a valid address (eg. is a real + // user we've seen) or false otherwise (eg. is just an address the + // user has entered) + isKnown: React.PropTypes.bool, +}); + export function getAddressType(inputText) { const isEmailAddress = emailRegex.test(inputText); const isMatrixId = mxidRegex.test(inputText); @@ -61,3 +86,107 @@ export function inviteMultipleToRoom(roomId, addrs) { return inviter.invite(addrs); } +export function showStartChatInviteDialog() { + const UserPickerDialog = sdk.getComponent("dialogs.UserPickerDialog"); + Modal.createTrackedDialog('Start a chat', '', UserPickerDialog, { + title: _t('Start a chat'), + description: _t("Who would you like to communicate with?"), + placeholder: _t("Email, name or matrix ID"), + button: _t("Start Chat"), + onFinished: _onStartChatFinished, + }); +} + +export function showRoomInviteDialog(roomId) { + const UserPickerDialog = sdk.getComponent("dialogs.UserPickerDialog"); + Modal.createTrackedDialog('Chat Invite', '', UserPickerDialog, { + title: _t('Invite new room members'), + description: _t('Who would you like to add to this room?'), + button: _t('Send Invites'), + placeholder: _t("Email, name or matrix ID"), + onFinished: (shouldInvite, addrs) => { + _onRoomInviteFinished(roomId, shouldInvite, addrs); + }, + }); +} + +function _onStartChatFinished(shouldInvite, addrs) { + if (!shouldInvite) return; + + const addrTexts = addrs.map(addr => addr.address); + + if (_isDmChat(addrTexts)) { + // Start a new DM chat + createRoom({dmUserId: addrTexts[0]}).catch((err) => { + console.error(err.stack); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite user', '', ErrorDialog, { + title: _t("Failed to invite user"), + description: ((err && err.message) ? err.message : _t("Operation failed")), + }); + }); + } else { + // Start multi user chat + let room; + createRoom().then((roomId) => { + room = MatrixClientPeg.get().getRoom(roomId); + return inviteMultipleToRoom(roomId, addrTexts); + }).then((addrs) => { + return _showAnyInviteErrors(addrs, room); + }).catch((err) => { + console.error(err.stack); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { + title: _t("Failed to invite"), + description: ((err && err.message) ? err.message : _t("Operation failed")), + }); + }); + } +} + +function _onRoomInviteFinished(roomId, shouldInvite, addrs) { + if (!shouldInvite) return; + + const addrTexts = addrs.map(addr => addr.address); + + // Invite new users to a room + inviteMultipleToRoom(roomId, addrTexts).then((addrs) => { + const room = MatrixClientPeg.get().getRoom(roomId); + return _showAnyInviteErrors(addrs, room); + }).catch((err) => { + console.error(err.stack); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { + title: _t("Failed to invite"), + description: ((err && err.message) ? err.message : _t("Operation failed")), + }); + }); +} + +function _isDmChat(addrTexts) { + if (addrTexts.length === 1 && getAddressType(addrTexts[0])) { + return true; + } else { + return false; + } +} + +function _showAnyInviteErrors(addrs, room) { + // Show user any errors + let errorList = []; + for (let addr of Object.keys(addrs)) { + if (addrs[addr] === "error") { + errorList.push(addr); + } + } + + if (errorList.length > 0) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { + title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), + description: errorList.join(", "), + }); + } + return addrs; +} + diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 6fdec80f38..fcd5ac2bd0 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -31,6 +32,7 @@ import dis from "../../dispatcher"; import Modal from "../../Modal"; import Tinter from "../../Tinter"; import sdk from '../../index'; +import { showStartChatInviteDialog, showRoomInviteDialog } from '../../Invite'; import * as Rooms from '../../Rooms'; import linkifyMatrix from "../../linkify-matrix"; import * as Lifecycle from '../../Lifecycle'; @@ -512,7 +514,7 @@ module.exports = React.createClass({ this._createChat(); break; case 'view_invite': - this._invite(payload.roomId); + showRoomInviteDialog(payload.roomId); break; case 'notifier_enabled': this.forceUpdate(); @@ -766,13 +768,7 @@ module.exports = React.createClass({ dis.dispatch({action: 'view_set_mxid'}); return; } - const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createTrackedDialog('Start a chat', '', ChatInviteDialog, { - title: _t('Start a chat'), - description: _t("Who would you like to communicate with?"), - placeholder: _t("Email, name or matrix ID"), - button: _t("Start Chat"), - }); + showStartChatInviteDialog(); }, _createRoom: function() { @@ -857,17 +853,6 @@ module.exports = React.createClass({ }).close; }, - _invite: function(roomId) { - const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createTrackedDialog('Chat Invite', '', ChatInviteDialog, { - title: _t('Invite new room members'), - description: _t('Who would you like to add to this room?'), - button: _t('Send Invites'), - placeholder: _t("Email, name or matrix ID"), - roomId: roomId, - }); - }, - _leaveRoom: function(roomId) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/components/views/dialogs/UserPickerDialog.js b/src/components/views/dialogs/UserPickerDialog.js index 728860edec..5627a814c0 100644 --- a/src/components/views/dialogs/UserPickerDialog.js +++ b/src/components/views/dialogs/UserPickerDialog.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,9 +16,10 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import { getAddressType, inviteMultipleToRoom } from '../../../Invite'; +import { getAddressType } from '../../../Invite'; import createRoom from '../../../createRoom'; import MatrixClientPeg from '../../../MatrixClientPeg'; import DMRoomMap from '../../../utils/DMRoomMap'; @@ -25,30 +27,34 @@ import Modal from '../../../Modal'; import AccessibleButton from '../elements/AccessibleButton'; import Promise from 'bluebird'; import dis from '../../../dispatcher'; +import { addressTypes, InviteAddressType } from '../../../Invite.js'; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; module.exports = React.createClass({ - displayName: "ChatInviteDialog", + displayName: "UserPickerDialog", + propTypes: { - title: React.PropTypes.string.isRequired, - description: React.PropTypes.oneOfType([ - React.PropTypes.element, - React.PropTypes.string, + title: PropTypes.string.isRequired, + description: PropTypes.oneOfType([ + PropTypes.element, + PropTypes.string, ]), - value: React.PropTypes.string, - placeholder: React.PropTypes.string, - roomId: React.PropTypes.string, - button: React.PropTypes.string, - focus: React.PropTypes.bool, - onFinished: React.PropTypes.func.isRequired, + value: PropTypes.string, + placeholder: PropTypes.string, + roomId: PropTypes.string, + button: PropTypes.string, + focus: PropTypes.bool, + validAddressTypes: PropTypes.arrayOf(PropTypes.oneOfType(addressTypes)), + onFinished: PropTypes.func.isRequired, }, getDefaultProps: function() { return { value: "", focus: true, + validAddressTypes: addressTypes, }; }, @@ -56,7 +62,7 @@ module.exports = React.createClass({ return { error: false, - // List of AddressTile.InviteAddressType objects representing + // List of InviteAddressType objects representing // the list of addresses we're going to invite inviteList: [], @@ -90,50 +96,7 @@ module.exports = React.createClass({ inviteList = this._addInputToList(); if (inviteList === null) return; } - - const addrTexts = inviteList.map(addr => addr.address); - if (inviteList.length > 0) { - if (this._isDmChat(addrTexts)) { - const userId = inviteList[0].address; - // Direct Message chat - const rooms = this._getDirectMessageRooms(userId); - if (rooms.length > 0) { - // A Direct Message room already exists for this user, so select a - // room from a list that is similar to the one in MemberInfo panel - const ChatCreateOrReuseDialog = sdk.getComponent( - "views.dialogs.ChatCreateOrReuseDialog", - ); - const close = Modal.createTrackedDialog('Create or Reuse', '', ChatCreateOrReuseDialog, { - userId: userId, - onFinished: (success) => { - this.props.onFinished(success); - }, - onNewDMClick: () => { - dis.dispatch({ - action: 'start_chat', - user_id: userId, - }); - close(true); - }, - onExistingRoomSelected: (roomId) => { - dis.dispatch({ - action: 'view_room', - room_id: roomId, - }); - close(true); - }, - }).close; - } else { - this._startChat(inviteList); - } - } else { - // Multi invite chat - this._startChat(inviteList); - } - } else { - // No addresses supplied - this.setState({ error: true }); - } + this.props.onFinished(true, inviteList); }, onCancel: function() { @@ -201,11 +164,10 @@ module.exports = React.createClass({ }, onDismissed: function(index) { - var self = this; return () => { - var inviteList = self.state.inviteList.slice(); + const inviteList = this.state.inviteList.slice(); inviteList.splice(index, 1); - self.setState({ + this.setState({ inviteList: inviteList, queryList: [], query: "", @@ -215,14 +177,13 @@ module.exports = React.createClass({ }, onClick: function(index) { - var self = this; - return function() { - self.onSelected(index); + return () => { + this.onSelected(index); }; }, onSelected: function(index) { - var inviteList = this.state.inviteList.slice(); + const inviteList = this.state.inviteList.slice(); inviteList.push(this.state.queryList[index]); this.setState({ inviteList: inviteList, @@ -311,7 +272,7 @@ module.exports = React.createClass({ // This is important, otherwise there's no way to invite // a perfectly valid address if there are close matches. const addrType = getAddressType(query); - if (addrType !== null) { + if (this.props.validAddressTypes.indexOf(addrType) !== -1) { queryList.unshift({ addressType: addrType, address: query, @@ -330,132 +291,6 @@ module.exports = React.createClass({ }); }, - _getDirectMessageRooms: function(addr) { - const dmRoomMap = new DMRoomMap(MatrixClientPeg.get()); - const dmRooms = dmRoomMap.getDMRoomsForUserId(addr); - const rooms = []; - dmRooms.forEach(dmRoom => { - let room = MatrixClientPeg.get().getRoom(dmRoom); - if (room) { - const me = room.getMember(MatrixClientPeg.get().credentials.userId); - if (me.membership == 'join') { - rooms.push(room); - } - } - }); - return rooms; - }, - - _startChat: function(addrs) { - if (MatrixClientPeg.get().isGuest()) { - dis.dispatch({action: 'view_set_mxid'}); - return; - } - - const addrTexts = addrs.map((addr) => { - return addr.address; - }); - - if (this.props.roomId) { - // Invite new user to a room - var self = this; - inviteMultipleToRoom(this.props.roomId, addrTexts) - .then(function(addrs) { - var room = MatrixClientPeg.get().getRoom(self.props.roomId); - return self._showAnyInviteErrors(addrs, room); - }) - .catch(function(err) { - console.error(err.stack); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { - title: _t("Failed to invite"), - description: ((err && err.message) ? err.message : _t("Operation failed")), - }); - return null; - }) - .done(); - } else if (this._isDmChat(addrTexts)) { - // Start the DM chat - createRoom({dmUserId: addrTexts[0]}) - .catch(function(err) { - console.error(err.stack); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite user', '', ErrorDialog, { - title: _t("Failed to invite user"), - description: ((err && err.message) ? err.message : _t("Operation failed")), - }); - return null; - }) - .done(); - } else { - // Start multi user chat - var self = this; - var room; - createRoom().then(function(roomId) { - room = MatrixClientPeg.get().getRoom(roomId); - return inviteMultipleToRoom(roomId, addrTexts); - }) - .then(function(addrs) { - return self._showAnyInviteErrors(addrs, room); - }) - .catch(function(err) { - console.error(err.stack); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { - title: _t("Failed to invite"), - description: ((err && err.message) ? err.message : _t("Operation failed")), - }); - return null; - }) - .done(); - } - - // Close - this will happen before the above, as that is async - this.props.onFinished(true, addrTexts); - }, - - _isOnInviteList: function(uid) { - for (let i = 0; i < this.state.inviteList.length; i++) { - if ( - this.state.inviteList[i].addressType == 'mx' && - this.state.inviteList[i].address.toLowerCase() === uid - ) { - return true; - } - } - return false; - }, - - _isDmChat: function(addrTexts) { - if (addrTexts.length === 1 && - getAddressType(addrTexts[0]) === "mx" && - !this.props.roomId - ) { - return true; - } else { - return false; - } - }, - - _showAnyInviteErrors: function(addrs, room) { - // Show user any errors - var errorList = []; - for (var addr in addrs) { - if (addrs.hasOwnProperty(addr) && addrs[addr] === "error") { - errorList.push(addr); - } - } - - if (errorList.length > 0) { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { - title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), - description: errorList.join(", "), - }); - } - return addrs; - }, - _addInputToList: function() { const addressText = this.refs.textinput.value.trim(); const addrType = getAddressType(addressText); @@ -527,10 +362,10 @@ module.exports = React.createClass({ const AddressSelector = sdk.getComponent("elements.AddressSelector"); this.scrollElement = null; - var query = []; + let query = []; // create the invite list if (this.state.inviteList.length > 0) { - var AddressTile = sdk.getComponent("elements.AddressTile"); + const AddressTile = sdk.getComponent("elements.AddressTile"); for (let i = 0; i < this.state.inviteList.length; i++) { query.push( diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js index 5329994037..003fd534bb 100644 --- a/src/components/views/elements/AddressSelector.js +++ b/src/components/views/elements/AddressSelector.js @@ -20,7 +20,7 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; import classNames from 'classnames'; -import { InviteAddressType } from './AddressTile'; +import { InviteAddressType } from '../../../Invite'; export default React.createClass({ displayName: 'AddressSelector', diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index 78fd942a46..fb35dafa5c 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,31 +15,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; import classNames from 'classnames'; import sdk from "../../../index"; import MatrixClientPeg from "../../../MatrixClientPeg"; import { _t } from '../../../languageHandler'; - -// React PropType definition for an object describing -// an address that can be invited to a room (which -// could be a third party identifier or a matrix ID) -// along with some additional information about the -// address / target. -export const InviteAddressType = React.PropTypes.shape({ - addressType: React.PropTypes.oneOf([ - 'mx', 'email' - ]).isRequired, - address: React.PropTypes.string.isRequired, - displayName: React.PropTypes.string, - avatarMxc: React.PropTypes.string, - // true if the address is known to be a valid address (eg. is a real - // user we've seen) or false otherwise (eg. is just an address the - // user has entered) - isKnown: React.PropTypes.bool, -}); +import { InviteAddressType } from '../../../Invite.js'; export default React.createClass({ From 00d69aa938bd7e0fcd8fc8d861cf7af2a119753b Mon Sep 17 00:00:00 2001 From: krombel Date: Tue, 15 Aug 2017 00:32:38 +0200 Subject: [PATCH 121/164] Update Link to Translation status The translation is now done at translate.riot.im but the link was not updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f5ef73365..144e89c938 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ are currently filed against vector-im/riot-web rather than this project). Translation Status ================== -[![translationsstatus](https://translate.nordgedanken.de/widgets/riot-web/-/multi-auto.svg)](https://translate.nordgedanken.de/engage/riot-web/?utm_source=widget) +[![Translation status](https://translate.riot.im/widgets/riot-web/-/multi-auto.svg)](https://translate.riot.im/engage/riot-web/?utm_source=widget) Developer Guide =============== From d1c54e1224d2c8c46e91fe480527046cac26164d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Aug 2017 08:58:08 +0100 Subject: [PATCH 122/164] Switch to prop-types --- src/Invite.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Invite.js b/src/Invite.js index d825dac6f5..e7e7264d11 100644 --- a/src/Invite.js +++ b/src/Invite.js @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import PropTypes from 'prop-types'; import MatrixClientPeg from './MatrixClientPeg'; import MultiInviter from './utils/MultiInviter'; import Modal from "./Modal"; @@ -30,20 +31,20 @@ export const addressTypes = [ 'mx', 'email', ]; -// React PropType definition for an object describing +// PropType definition for an object describing // an address that can be invited to a room (which // could be a third party identifier or a matrix ID) // along with some additional information about the // address / target. -export const InviteAddressType = React.PropTypes.shape({ - addressType: React.PropTypes.oneOf(addressTypes).isRequired, - address: React.PropTypes.string.isRequired, - displayName: React.PropTypes.string, - avatarMxc: React.PropTypes.string, +export const InviteAddressType = PropTypes.shape({ + addressType: PropTypes.oneOf(addressTypes).isRequired, + address: PropTypes.string.isRequired, + displayName: PropTypes.string, + avatarMxc: PropTypes.string, // true if the address is known to be a valid address (eg. is a real // user we've seen) or false otherwise (eg. is just an address the // user has entered) - isKnown: React.PropTypes.bool, + isKnown: PropTypes.bool, }); export function getAddressType(inputText) { From b7b449434dd5859ac8a66a240683766101044ab6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Aug 2017 09:10:13 +0100 Subject: [PATCH 123/164] Lint --- .eslintignore.errorfiles | 1 - .../views/dialogs/UserPickerDialog.js | 18 ++++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.eslintignore.errorfiles b/.eslintignore.errorfiles index 55eaf75e4b..2018961854 100644 --- a/.eslintignore.errorfiles +++ b/.eslintignore.errorfiles @@ -33,7 +33,6 @@ src/components/views/create_room/CreateRoomButton.js src/components/views/create_room/Presets.js src/components/views/create_room/RoomAlias.js src/components/views/dialogs/ChatCreateOrReuseDialog.js -src/components/views/dialogs/ChatInviteDialog.js src/components/views/dialogs/DeactivateAccountDialog.js src/components/views/dialogs/InteractiveAuthDialog.js src/components/views/dialogs/SetMxIdDialog.js diff --git a/src/components/views/dialogs/UserPickerDialog.js b/src/components/views/dialogs/UserPickerDialog.js index 5627a814c0..7dc1be7d25 100644 --- a/src/components/views/dialogs/UserPickerDialog.js +++ b/src/components/views/dialogs/UserPickerDialog.js @@ -20,14 +20,10 @@ import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; import { getAddressType } from '../../../Invite'; -import createRoom from '../../../createRoom'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import DMRoomMap from '../../../utils/DMRoomMap'; -import Modal from '../../../Modal'; import AccessibleButton from '../elements/AccessibleButton'; import Promise from 'bluebird'; -import dis from '../../../dispatcher'; -import { addressTypes, InviteAddressType } from '../../../Invite.js'; +import { addressTypes } from '../../../Invite.js'; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -330,7 +326,7 @@ module.exports = React.createClass({ // not like they leak. this._cancelThreepidLookup = function() { cancelled = true; - } + }; // wait a bit to let the user finish typing return Promise.delay(500).then(() => { @@ -362,13 +358,13 @@ module.exports = React.createClass({ const AddressSelector = sdk.getComponent("elements.AddressSelector"); this.scrollElement = null; - let query = []; + const query = []; // create the invite list if (this.state.inviteList.length > 0) { const AddressTile = sdk.getComponent("elements.AddressTile"); for (let i = 0; i < this.state.inviteList.length; i++) { query.push( - + , ); } } @@ -390,7 +386,9 @@ module.exports = React.createClass({ let error; let addressSelector; if (this.state.error) { - error =
{_t("You have entered an invalid contact. Try using their Matrix ID or email address.")}
; + error =
+ {_t("You have entered an invalid contact. Try using their Matrix ID or email address.")} +
; } else if (this.state.searchError) { error =
{this.state.searchError}
; } else if ( @@ -433,5 +431,5 @@ module.exports = React.createClass({
); - } + }, }); From 5f00bbbff6e87968eac0d22e12e45f58b17a7632 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 Aug 2017 09:22:50 +0100 Subject: [PATCH 124/164] Add comments --- src/RichText.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index 8d1177cdd2..a34f8b6b30 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -204,24 +204,26 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, let selectionState = SelectionState.createEmpty(); for (const block of contentBlocks) { const blockLength = block.getLength(); + // -1 indicating that the position start position has been found if (start !== -1) { if (start < blockLength + 1) { selectionState = selectionState.merge({ anchorKey: block.getKey(), anchorOffset: start, }); - start = -1; + start = -1; // selection state for the start calculated } else { start -= blockLength + 1; // +1 to account for newline between blocks } } + // -1 indicating that the position end position has been found if (end !== -1) { if (end < blockLength + 1) { selectionState = selectionState.merge({ focusKey: block.getKey(), focusOffset: end, }); - end = -1; + end = -1; // selection state for the start calculated } else { end -= blockLength + 1; // +1 to account for newline between blocks } From 65dc9fda6e774584db572eefca5b0ed9e566a52f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 Aug 2017 09:25:23 +0100 Subject: [PATCH 125/164] Alter comments --- src/RichText.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RichText.js b/src/RichText.js index a34f8b6b30..cbd3b9ae18 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -202,6 +202,9 @@ export function selectionStateToTextOffsets(selectionState: SelectionState, export function textOffsetsToSelectionState({start, end}: SelectionRange, contentBlocks: Array): SelectionState { let selectionState = SelectionState.createEmpty(); + // Subtract block lengths from `start` and `end` until they are less than the current + // block length (accounting for the NL at the end of each block). Set them to -1 to + // indicate that the corresponding selection state has been determined. for (const block of contentBlocks) { const blockLength = block.getLength(); // -1 indicating that the position start position has been found @@ -223,7 +226,7 @@ export function textOffsetsToSelectionState({start, end}: SelectionRange, focusKey: block.getKey(), focusOffset: end, }); - end = -1; // selection state for the start calculated + end = -1; // selection state for the end calculated } else { end -= blockLength + 1; // +1 to account for newline between blocks } From fa660c8211bf834781af5872bae59d2b3387f99d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Aug 2017 10:57:24 +0100 Subject: [PATCH 126/164] PR feedback --- src/Invite.js | 6 +++--- src/components/views/dialogs/UserPickerDialog.js | 15 ++++++--------- src/components/views/elements/AddressSelector.js | 4 ++-- src/components/views/elements/AddressTile.js | 4 ++-- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/Invite.js b/src/Invite.js index e7e7264d11..b79a245549 100644 --- a/src/Invite.js +++ b/src/Invite.js @@ -18,9 +18,9 @@ limitations under the License. import PropTypes from 'prop-types'; import MatrixClientPeg from './MatrixClientPeg'; import MultiInviter from './utils/MultiInviter'; -import Modal from "./Modal"; +import Modal from './Modal'; import createRoom from './createRoom'; -import sdk from "./"; +import sdk from './'; import { _t } from './languageHandler'; const emailRegex = /^\S+@\S+\.\S+$/; @@ -36,7 +36,7 @@ export const addressTypes = [ // could be a third party identifier or a matrix ID) // along with some additional information about the // address / target. -export const InviteAddressType = PropTypes.shape({ +export const UserAddressType = PropTypes.shape({ addressType: PropTypes.oneOf(addressTypes).isRequired, address: PropTypes.string.isRequired, displayName: PropTypes.string, diff --git a/src/components/views/dialogs/UserPickerDialog.js b/src/components/views/dialogs/UserPickerDialog.js index 7dc1be7d25..1405bc754b 100644 --- a/src/components/views/dialogs/UserPickerDialog.js +++ b/src/components/views/dialogs/UserPickerDialog.js @@ -33,10 +33,7 @@ module.exports = React.createClass({ propTypes: { title: PropTypes.string.isRequired, - description: PropTypes.oneOfType([ - PropTypes.element, - PropTypes.string, - ]), + description: PropTypes.node, value: PropTypes.string, placeholder: PropTypes.string, roomId: PropTypes.string, @@ -58,7 +55,7 @@ module.exports = React.createClass({ return { error: false, - // List of InviteAddressType objects representing + // List of UserAddressType objects representing // the list of addresses we're going to invite inviteList: [], @@ -70,7 +67,7 @@ module.exports = React.createClass({ serverSupportsUserDirectory: true, // The query being searched for query: "", - // List of AddressTile.InviteAddressType objects representing + // List of UserAddressType objects representing // the set of auto-completion results for the current search // query. queryList: [], @@ -254,7 +251,7 @@ module.exports = React.createClass({ return; } // Return objects, structure of which is defined - // by InviteAddressType + // by UserAddressType queryList.push({ addressType: 'mx', address: user.user_id, @@ -268,7 +265,7 @@ module.exports = React.createClass({ // This is important, otherwise there's no way to invite // a perfectly valid address if there are close matches. const addrType = getAddressType(query); - if (this.props.validAddressTypes.indexOf(addrType) !== -1) { + if (this.props.validAddressTypes.includes(addrType)) { queryList.unshift({ addressType: addrType, address: query, @@ -342,7 +339,7 @@ module.exports = React.createClass({ if (cancelled) return null; this.setState({ queryList: [{ - // an InviteAddressType + // a UserAddressType addressType: medium, address: address, displayName: res.displayname, diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js index 003fd534bb..1aae10737e 100644 --- a/src/components/views/elements/AddressSelector.js +++ b/src/components/views/elements/AddressSelector.js @@ -20,7 +20,7 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; import classNames from 'classnames'; -import { InviteAddressType } from '../../../Invite'; +import { UserAddressType } from '../../../Invite'; export default React.createClass({ displayName: 'AddressSelector', @@ -29,7 +29,7 @@ export default React.createClass({ onSelected: React.PropTypes.func.isRequired, // List of the addresses to display - addressList: React.PropTypes.arrayOf(InviteAddressType).isRequired, + addressList: React.PropTypes.arrayOf(UserAddressType).isRequired, truncateAt: React.PropTypes.number.isRequired, selected: React.PropTypes.number, diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index fb35dafa5c..ba7d79d987 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -20,14 +20,14 @@ import classNames from 'classnames'; import sdk from "../../../index"; import MatrixClientPeg from "../../../MatrixClientPeg"; import { _t } from '../../../languageHandler'; -import { InviteAddressType } from '../../../Invite.js'; +import { UserAddressType } from '../../../Invite.js'; export default React.createClass({ displayName: 'AddressTile', propTypes: { - address: InviteAddressType.isRequired, + address: UserAddressType.isRequired, canDismiss: React.PropTypes.bool, onDismissed: React.PropTypes.func, justified: React.PropTypes.bool, From bbcf7e1d9bd6f0de315f4c251510b2de95bb4cbe Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Aug 2017 13:30:13 +0100 Subject: [PATCH 127/164] s/inviteList/userList/ --- .../views/dialogs/UserPickerDialog.js | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/components/views/dialogs/UserPickerDialog.js b/src/components/views/dialogs/UserPickerDialog.js index 1405bc754b..f4ea0c6a24 100644 --- a/src/components/views/dialogs/UserPickerDialog.js +++ b/src/components/views/dialogs/UserPickerDialog.js @@ -57,7 +57,7 @@ module.exports = React.createClass({ // List of UserAddressType objects representing // the list of addresses we're going to invite - inviteList: [], + userList: [], // Whether a search is ongoing busy: false, @@ -82,14 +82,14 @@ module.exports = React.createClass({ }, onButtonClick: function() { - let inviteList = this.state.inviteList.slice(); + let userList = this.state.userList.slice(); // Check the text input field to see if user has an unconverted address - // If there is and it's valid add it to the local inviteList + // If there is and it's valid add it to the local userList if (this.refs.textinput.value !== '') { - inviteList = this._addInputToList(); - if (inviteList === null) return; + userList = this._addInputToList(); + if (userList === null) return; } - this.props.onFinished(true, inviteList); + this.props.onFinished(true, userList); }, onCancel: function() { @@ -113,10 +113,10 @@ module.exports = React.createClass({ e.stopPropagation(); e.preventDefault(); if (this.addressSelector) this.addressSelector.chooseSelection(); - } else if (this.refs.textinput.value.length === 0 && this.state.inviteList.length && e.keyCode === 8) { // backspace + } else if (this.refs.textinput.value.length === 0 && this.state.userList.length && e.keyCode === 8) { // backspace e.stopPropagation(); e.preventDefault(); - this.onDismissed(this.state.inviteList.length - 1)(); + this.onDismissed(this.state.userList.length - 1)(); } else if (e.keyCode === 13) { // enter e.stopPropagation(); e.preventDefault(); @@ -158,10 +158,10 @@ module.exports = React.createClass({ onDismissed: function(index) { return () => { - const inviteList = this.state.inviteList.slice(); - inviteList.splice(index, 1); + const userList = this.state.userList.slice(); + userList.splice(index, 1); this.setState({ - inviteList: inviteList, + userList: userList, queryList: [], query: "", }); @@ -176,10 +176,10 @@ module.exports = React.createClass({ }, onSelected: function(index) { - const inviteList = this.state.inviteList.slice(); - inviteList.push(this.state.queryList[index]); + const userList = this.state.userList.slice(); + userList.push(this.state.queryList[index]); this.setState({ - inviteList: inviteList, + userList: userList, queryList: [], query: "", }); @@ -304,15 +304,15 @@ module.exports = React.createClass({ } } - const inviteList = this.state.inviteList.slice(); - inviteList.push(addrObj); + const userList = this.state.userList.slice(); + userList.push(addrObj); this.setState({ - inviteList: inviteList, + userList: userList, queryList: [], query: "", }); if (this._cancelThreepidLookup) this._cancelThreepidLookup(); - return inviteList; + return userList; }, _lookupThreepid: function(medium, address) { @@ -357,18 +357,18 @@ module.exports = React.createClass({ const query = []; // create the invite list - if (this.state.inviteList.length > 0) { + if (this.state.userList.length > 0) { const AddressTile = sdk.getComponent("elements.AddressTile"); - for (let i = 0; i < this.state.inviteList.length; i++) { + for (let i = 0; i < this.state.userList.length; i++) { query.push( - , + , ); } } // Add the query at the end query.push( -