diff --git a/CHANGES.md b/CHANGES.md index f3e7f3890..b2b3f97d8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,67 @@ +## Changes in 1.8.12 (2022-04-06) + +🐛 Bugfixes + +- RecentsViewController: Room context preview dismissed unexpectedly ([#5992](https://github.com/vector-im/element-ios/issues/5992)) +- Notifications: Strings now fall back to English if they're missing for the current language. ([#5996](https://github.com/vector-im/element-ios/issues/5996)) + + +## Changes in 1.8.11 (2022-04-05) + +✨ Features + +- RoomViewController: Display threads notice if not displayed before. ([#5770](https://github.com/vector-im/element-ios/issues/5770)) +- Addded support for Apple context menus in matrix items list screens ([#5953](https://github.com/vector-im/element-ios/issues/5953)) + +🙌 Improvements + +- Upgrade MatrixSDK version ([v0.23.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.23.2)). +- Threads: Strip `ìn reply to` from thread summaries and latest messages. ([#5488](https://github.com/vector-im/element-ios/issues/5488)) +- Room: New loading indicators when joining room ([#5604](https://github.com/vector-im/element-ios/issues/5604)) +- Room: New loading indicators when creating a room ([#5606](https://github.com/vector-im/element-ios/issues/5606)) +- Location Sharing: Update UI on location sharing view ([#5720](https://github.com/vector-im/element-ios/issues/5720)) +- Update suggested room preview to behave the same way in all cases ([#5771](https://github.com/vector-im/element-ios/issues/5771)) +- RoomViewController: Enable thread menu option and display opt-in screen if threads disabled. ([#5772](https://github.com/vector-im/element-ios/issues/5772)) +- Add "Invite people" to the space menu in the left panel and update menu order ([#5810](https://github.com/vector-im/element-ios/issues/5810)) +- Allow empty Jitsi default URL in BuildSettings ([#5837](https://github.com/vector-im/element-ios/issues/5837)) +- Location sharing: Add the ability for the user to share static location of a pin anywhere on the map ([#5858](https://github.com/vector-im/element-ios/issues/5858)) +- Restrict UI components on authentication screen to readable width ([#5898](https://github.com/vector-im/element-ios/issues/5898)) + +🐛 Bugfixes + +- Fixed the regular expression used for link detection in attributed strings. ([#5926](https://github.com/vector-im/element-ios/pull/5926)) +- Jitsi: fix app not leaving call when widget is removed ([#1575](https://github.com/vector-im/element-ios/issues/1575)) +- Space preview shows wrong number of members ([#4842](https://github.com/vector-im/element-ios/issues/4842)) +- Room: Enable joining a room via identifier from another home server ([#4858](https://github.com/vector-im/element-ios/issues/4858)) +- MXKRoomDataSource: Fix retain cycle ([#5058](https://github.com/vector-im/element-ios/issues/5058)) +- Sync Spaces order with web ([#5134](https://github.com/vector-im/element-ios/issues/5134)) +- Fix “It is not possible to join an empty room” on some suggested rooms. ([#5170](https://github.com/vector-im/element-ios/issues/5170)) +- Fixed "Add Space" error message ([#5797](https://github.com/vector-im/element-ios/issues/5797)) +- RoomDataSource: Reload thread data source without notifying the screen for the first reply. ([#5838](https://github.com/vector-im/element-ios/issues/5838)) +- VoiceMessagePlainCell: Fix cell height by adding missing thread summary displayable conformance. ([#5870](https://github.com/vector-im/element-ios/issues/5870)) +- Authentication: Ensure the login button is always visible ([#5875](https://github.com/vector-im/element-ios/issues/5875)) +- Threads: Tweaks for design review. ([#5878](https://github.com/vector-im/element-ios/issues/5878)) +- Search: prevent crash when searching for rooms ([#5883](https://github.com/vector-im/element-ios/issues/5883)) +- Room: Fix typing performance by avoiding expensive UI operations ([#5906](https://github.com/vector-im/element-ios/issues/5906)) +- The "Swipe to see all rooms" hint is sometimes presented at the wrong time ([#5911](https://github.com/vector-im/element-ios/issues/5911)) +- Push notifications: show space preview if user taps invite notification ([#5915](https://github.com/vector-im/element-ios/issues/5915)) +- Fix session handling of the call presenter. ([#5938](https://github.com/vector-im/element-ios/issues/5938)) +- m.room.join_rules not properly set for private access ([#5943](https://github.com/vector-im/element-ios/issues/5943)) +- Fix for app occasionally getting stuck during launch after Login/Register. ([#5948](https://github.com/vector-im/element-ios/issues/5948)) + +⚠️ API Changes + +- Remove unused Bindings in RoundedBorderTextField/Editor ([#5910](https://github.com/vector-im/element-ios/pull/5910)) + +🗣 Translations + +- Translations: Enable all languages rather than waiting for an 80% translation. RTL languages are still disabled due to layout and formatting bugs. ([#5935](https://github.com/vector-im/element-ios/issues/5935)) + +🚧 In development 🚧 + +- Onboarding: Add celebration screen after display name and avatar screens. ([#5651](https://github.com/vector-im/element-ios/issues/5651)) + + ## Changes in 1.8.10 (2022-03-31) 🐛 Bugfixes diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index a9ed9e328..b5cb77e7c 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.8.11 -CURRENT_PROJECT_VERSION = 1.8.11 +MARKETING_VERSION = 1.8.13 +CURRENT_PROJECT_VERSION = 1.8.13 diff --git a/Podfile b/Podfile index ec5c0420d..ec921a026 100644 --- a/Podfile +++ b/Podfile @@ -13,7 +13,7 @@ use_frameworks! # - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI # # Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixSDKVersion = '= 0.23.1' +$matrixSDKVersion = '= 0.23.2' # $matrixSDKVersion = :local # $matrixSDKVersion = { :branch => 'develop'} # $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } } diff --git a/Podfile.lock b/Podfile.lock index 761bfd2ad..1c2108fe2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -56,16 +56,16 @@ PODS: - LoggerAPI (1.9.200): - Logging (~> 1.1) - Logging (1.4.0) - - MatrixSDK (0.23.1): - - MatrixSDK/Core (= 0.23.1) - - MatrixSDK/Core (0.23.1): + - MatrixSDK (0.23.2): + - MatrixSDK/Core (= 0.23.2) + - MatrixSDK/Core (0.23.2): - AFNetworking (~> 4.0.0) - GZIP (~> 1.3.0) - libbase58 (~> 0.1.4) - OLMKit (~> 3.2.5) - Realm (= 10.16.0) - SwiftyBeaver (= 1.9.5) - - MatrixSDK/JingleCallStack (0.23.1): + - MatrixSDK/JingleCallStack (0.23.2): - JitsiMeetSDK (= 3.10.2) - MatrixSDK/Core - OLMKit (3.2.5): @@ -115,8 +115,8 @@ DEPENDENCIES: - KeychainAccess (~> 4.2.2) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.23.1) - - MatrixSDK/JingleCallStack (= 0.23.1) + - MatrixSDK (= 0.23.2) + - MatrixSDK/JingleCallStack (= 0.23.2) - OLMKit - PostHog (~> 1.4.4) - ReadMoreTextView (~> 3.0.1) @@ -208,7 +208,7 @@ SPEC CHECKSUMS: libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d Logging: beeb016c9c80cf77042d62e83495816847ef108b - MatrixSDK: 54d16aa08f3043fb1bcf639ef1ac5c589100f39f + MatrixSDK: ab6cbb1e8c437eac4f999be516b5e76c2bca9f6a OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5 PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d @@ -225,6 +225,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: 820f04e07aa252459ecfa88d04da729daca4fcbb +PODFILE CHECKSUM: 677ee0df159e298fde825885ea85e4ebfa8e32fd COCOAPODS: 1.11.2 diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1.imageset/OnboardingSplashScreenPage1.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1.imageset/OnboardingSplashScreenPage1.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1.imageset/OnboardingSplashScreenPage1.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1.imageset/OnboardingSplashScreenPage1.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1Dark.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1_dark.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1Dark.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1_dark.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1Dark.imageset/OnboardingSplashScreenPage1-Dark.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1_dark.imageset/OnboardingSplashScreenPage1-Dark.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1Dark.imageset/OnboardingSplashScreenPage1-Dark.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_1_dark.imageset/OnboardingSplashScreenPage1-Dark.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2.imageset/OnboardingSplashScreenPage2.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2.imageset/OnboardingSplashScreenPage2.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2.imageset/OnboardingSplashScreenPage2.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2.imageset/OnboardingSplashScreenPage2.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2Dark.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2_dark.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2Dark.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2_dark.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2Dark.imageset/OnboardingSplashScreenPage2-Dark.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2_dark.imageset/OnboardingSplashScreenPage2-Dark.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2Dark.imageset/OnboardingSplashScreenPage2-Dark.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_2_dark.imageset/OnboardingSplashScreenPage2-Dark.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3.imageset/OnboardingSplashScreenPage3.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3.imageset/OnboardingSplashScreenPage3.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3.imageset/OnboardingSplashScreenPage3.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3.imageset/OnboardingSplashScreenPage3.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3Dark.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3_dark.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3Dark.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3_dark.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3Dark.imageset/OnboardingSplashScreenPage3-Dark.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3_dark.imageset/OnboardingSplashScreenPage3-Dark.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3Dark.imageset/OnboardingSplashScreenPage3-Dark.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_3_dark.imageset/OnboardingSplashScreenPage3-Dark.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4.imageset/OnboardingSplashScreenPage4.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4.imageset/OnboardingSplashScreenPage4.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4.imageset/OnboardingSplashScreenPage4.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4.imageset/OnboardingSplashScreenPage4.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4Dark.imageset/Contents.json b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4_dark.imageset/Contents.json similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4Dark.imageset/Contents.json rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4_dark.imageset/Contents.json diff --git a/Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4Dark.imageset/OnboardingSplashScreenPage4-Dark.pdf b/Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4_dark.imageset/OnboardingSplashScreenPage4-Dark.pdf similarity index 100% rename from Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4Dark.imageset/OnboardingSplashScreenPage4-Dark.pdf rename to Riot/Assets/Images.xcassets/Onboarding/onboarding_splash_screen_page_4_dark.imageset/OnboardingSplashScreenPage4-Dark.pdf diff --git a/Riot/Assets/Images.xcassets/Onboarding/onboarding_use_case_icon.imageset/onboarding_use_case_icon.svg b/Riot/Assets/Images.xcassets/Onboarding/onboarding_use_case_icon.imageset/onboarding_use_case_icon.svg index 2366becdb..9a85dbb0a 100644 --- a/Riot/Assets/Images.xcassets/Onboarding/onboarding_use_case_icon.imageset/onboarding_use_case_icon.svg +++ b/Riot/Assets/Images.xcassets/Onboarding/onboarding_use_case_icon.imageset/onboarding_use_case_icon.svg @@ -1,4 +1,5 @@ - - - + + + + diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/Contents.json new file mode 100644 index 000000000..7934b19cd --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "location_center_map_icon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "location_center_map_icon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "location_center_map_icon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon.png b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon.png new file mode 100644 index 000000000..6b73b4557 Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon.png differ diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@2x.png new file mode 100644 index 000000000..d9f6f7297 Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@2x.png differ diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@3x.png new file mode 100644 index 000000000..f68f36c74 Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_center_map_icon.imageset/location_center_map_icon@3x.png differ diff --git a/Riot/Assets/cs.lproj/InfoPlist.strings b/Riot/Assets/cs.lproj/InfoPlist.strings index 88c506408..444e8dc28 100644 --- a/Riot/Assets/cs.lproj/InfoPlist.strings +++ b/Riot/Assets/cs.lproj/InfoPlist.strings @@ -5,3 +5,5 @@ "NSPhotoLibraryUsageDescription" = "Galerie se používá k posílání obrázků a videí."; "NSCalendarsUsageDescription" = "Zobrazuje události v aplikaci."; "NSFaceIDUsageDescription" = "Face ID se používá k přístupu do aplikace."; +"NSLocationWhenInUseUsageDescription" = "Když sdílíte svou polohu s lidmi, Element potřebuje přístup, aby jim mohl zobrazit mapu."; +"NSMicrophoneUsageDescription" = "Element vyžaduje přístup k mikrofonu vašeho zařízení pro zahajování a přijímání hovorů, pořizování videa a nahrávání hlasových zpráv."; diff --git a/Riot/Assets/cs.lproj/Vector.strings b/Riot/Assets/cs.lproj/Vector.strings index 23f79ca59..ddb31ffaa 100644 --- a/Riot/Assets/cs.lproj/Vector.strings +++ b/Riot/Assets/cs.lproj/Vector.strings @@ -50,7 +50,7 @@ "auth_optional_phone_placeholder" = "Číslo mobilního telefonu (nepovinné)"; "auth_phone_placeholder" = "Telefonní číslo"; "auth_repeat_password_placeholder" = "Zopakovat heslo"; -"auth_repeat_new_password_placeholder" = "Potvrďte své nové heslo"; +"auth_repeat_new_password_placeholder" = "Potvrďte své nové heslo k účtu Matrix"; "auth_home_server_placeholder" = "URL (např. https://matrix.org)"; "auth_identity_server_placeholder" = "URL (např. https://vector.im)"; "auth_invalid_login_param" = "Nesprávné uživatelské jméno nebo heslo"; @@ -69,13 +69,13 @@ "auth_untrusted_id_server" = "Server identit není důvěryhodný"; "auth_password_dont_match" = "Hesla se neshodují"; "auth_username_in_use" = "Uživatelské jméno je použito"; -"auth_forgot_password" = "Zapomenuté heslo?"; +"auth_forgot_password" = "Zapomenuté heslo k účtu Matrix?"; "auth_email_not_found" = "Chyba odeslání emailu: Tato emailová adresa nebyla nalezena"; "auth_use_server_options" = "Použít vlastní možnosti serveru (pokročilé)"; "auth_email_validation_message" = "Prosím zkontrolujte své emaily, abyste mohli pokračovat v registraci"; "auth_msisdn_validation_title" = "Čeká na ověření"; "auth_recaptcha_message" = "Tento domovský server by se rád přesvědčil, že nejste robot"; -"auth_reset_password_message" = "K resetování hesla vložte e-mailovou adresu spojenou s vaším účtem:"; +"auth_reset_password_message" = "K resetování hesla Matrix účtu vložte e-mailovou adresu spojenou s vaším účtem:"; "auth_reset_password_missing_email" = "Musíte zadat emailovou adresu spojenou s vaším účtem."; "auth_reset_password_missing_password" = "Musíte zadat nové heslo."; "auth_reset_password_email_validation_message" = "Na adresu %@ byla odeslána zpráva. Potom, co přejdete na odkaz z této zprávy, klikněte níže."; @@ -95,7 +95,7 @@ "room_creation_keep_private" = "Zachovat jako soukromí"; "room_creation_make_private" = "Nastavit jako soukromé"; "room_creation_wait_for_creation" = "Místnost byla již vytvořena. Prosím vyčkejte."; -"room_creation_invite_another_user" = "Hledat / Pozvat podle uživatelského ID, jména nebo emailu"; +"room_creation_invite_another_user" = "Uživatelské ID, jméno, nebo email"; // Room recents "room_recents_directory_section" = "ADRESÁŘ MÍSTNOSTÍ"; "room_recents_directory_section_network" = "Síť"; @@ -236,7 +236,7 @@ "settings_config_user_id" = "Přihlášen/a jako %@"; "auth_msisdn_validation_message" = "Odeslali jsme vám SMS aktivační kod. Prosím, zadejte jej níže."; "auth_msisdn_validation_error" = "Nelze ověřit telefonní číslo."; -"auth_reset_password_success_message" = "Vaše heslo bylo úspěšně resetováno.\n\nByl jste právě odhlášen na všech vašich relací a nebudete vánm nadále zasíláno oznámení. Pro znovu povolení zasílání oznámení, přihlašte se znovu na každém zařízení."; +"auth_reset_password_success_message" = "Vaše heslo Matrix účtu bylo úspěšně resetováno.\n\nByl jste právě odhlášen na všech vašich relací a nebudou vám nadále zasílána oznámení. Pro opětovné zasílání oznámení se znovu přihlaste na každém zařízení."; "store_full_description" = "Element je novým typem komunikátoru a propojovací aplikace která:\n\n1. Dává vám kontrolu nad vaším soukromím\n2. Vás nechá komunikovat s kýmkoli v Matrix síti a dokonce mimo ni, díky integrace s aplikacemi jako je například Slack\n3. Vás chrání před reklamou, těžbou Vašich dat, nechráněnými přístupy nebo nezdokumentovanými fukncemi\n4. Zabezpečuje Vaši komunikaci pomocí koncového šifrování s distribuovaným ověřením ostatních\n\nElement se liší od ostatních komunikačních řešeních především tím, že je decentralizovaný a open-source\n\nElement vám umožňuje provozovat vlastní server anebo si vybrat nějakyý z veřejných, takže máte controlu nad vašimi konverzacemi a soukromím. Dává vám přístup do otevřené sítě, takže nejste odkázání jen ke komunikaci s ostatními uživateli Elementu. A je vysoce bezpečný.\n\nElement je toho všeho schopen díky svému operačnímu protokolu - Matrix, otevřeného standartu pro decentralizovanou komunikaci.\n\nElement vás nechává vybrat, kdo bude hostovat vaše konverzace. Přímo z aplikace si můžete vybrat několik rozdílných řešení:\n\n1. Účet zdarma na veřejném serveru matrix.org\n2. Vlastní hosting serveru na vlastním hardwaru\n3. Účet na přizpůsobeném serveru jednodýúchým přihlášením na hosting Element Matrix Services\n\nProč Element?\n\nVLASTNĚTE SVÁ DATA: Vy rozhodujete kde jsou vaše data a zprávy uchovávány. Svá data vlastníte a spravujete Vy, ne nějaká obří korporace, která o vás sbírá osobní data nebo poskytuje přístup dalším stranám.\n\nOTEVŘENÁ KOMUNIKACE A SPOLUPRÁCE: Máte možnost spojit se s kýmkoli v síti Matrix bez ohledu na jeho softwarové řešení, a dokonce se můžete připojit i na jiné komunikační protokoly, jako je Slack, IRC nebo XMPP (Jabber). Komunita podporuje i komunikátory jako Whatsapp, Telegram nebo iMessage.\n\nNEPROLOMITELNÉ ŠIFROVÁNÍ: Skutečné koncové šifrování (pouze přímí účastníci konverzace mají možnost rozšifrovat jejich zprávy) a pokročilé ověřování kontaktů.\n\nVŠESTRANNÉ KOMUNIKAČNÍ MOŽNOSTI: Textové zprávy, hlasové nebo videohovory, přenos souborů, sdílení obrazovky a mnoho dalších funkcí a možností pro implementaci. Vytvářejte místnosti a komunity a zůstaňte v kontaktu.\n\nKDEKOLI SE NACHÁZÍTE: Přístup k plně synchronizované historii konverzací máte kdekoli se nacházíte, ať už z aplikace anebo webového rozhraní na https://element.io/app."; "user_verification_sessions_list_session_untrusted" = "Nedůvěryhodná"; "user_verification_sessions_list_session_trusted" = "Důvěryhodná"; @@ -274,8 +274,8 @@ "auth_autodiscover_invalid_response" = "Neplatná odpověď na objevení domovského serveru"; "auth_accept_policies" = "Přečtěte si a přijměte zásady tohoto domovského serveru:"; "auth_add_email_and_phone_warning" = "Registrace pomocí e-mailu a telefonního čísla najednou ještě není podporována, dokud neexistuje rozhraní API. Zohledněno bude pouze telefonní číslo. Svůj e-mail můžete přidat do svého profilu v nastavení."; -"auth_reset_password_error_is_required" = "Není nakonfigurován žádný server identity: pro obnovení hesla přidejte jeden server z možností ."; -"auth_forgot_password_error_no_configured_identity_server" = "Není nakonfigurován žádný server identity: pro obnovení hesla jeden přidejte ."; +"auth_reset_password_error_is_required" = "Není nakonfigurován žádný server identity: pro obnovení hesla Matrix účtu přidejte jeden server z možností."; +"auth_forgot_password_error_no_configured_identity_server" = "Není nakonfigurován žádný server identity: pro obnovení hesla k Matrix účtu jeden přidejte."; "settings_key_backup_button_delete" = "Smazat zálohu"; "settings_key_backup_button_restore" = "Obnovit ze zálohy"; "auth_login_single_sign_on" = "Přihlásit se"; @@ -345,3 +345,36 @@ "network_offline_prompt" = "Zdá se, že připojení k internetu je offline."; "yesterday" = "Včera"; "today" = "Dnes"; +"people_empty_view_title" = "Lidé"; +"room_recents_unknown_room_error_message" = "Nelze najít místnost. Zkontrolujte, jestli existuje"; +"room_recents_join_room_prompt" = "Napište ID nebo alias místnosti"; +"room_recents_suggested_rooms_section" = "DOPORUČENÉ MÍSTNOSTI"; +"auth_phone_is_required" = "Nelze přidat telefonní číslo pro obnovení hesla k vašemu Matrix účtu, protože není nastaven žádný server identity."; +"auth_email_is_required" = "Nelze přidat emailovou adresu pro obnovení hesla k vašemu Matrix účtu, protože není nastaven žádný server identity."; +"onboarding_use_case_existing_server_button" = "Připojit k serveru"; +"onboarding_use_case_existing_server_message" = "Chcete se připojit k již existujícímu serveru?"; +"onboarding_use_case_skip_button" = "přeskočit tuto otázku"; +/* The placeholder string contains onboarding_use_case_skip_button as a tappable action */ +"onboarding_use_case_not_sure_yet" = "Ještě si nejste jistí? Můžete %@"; +"onboarding_use_case_community_messaging" = "Komunity"; +"onboarding_use_case_work_messaging" = "Týmy"; +"onboarding_use_case_personal_messaging" = "Přátelé a rodina"; +"onboarding_use_case_message" = "Pomůžeme vám navázat kontakty."; +"onboarding_use_case_title" = "S kým si budete nejvíce psát?"; +"onboarding_splash_page_4_message" = "Element je také skvělý na pracovišti. Důvěřují mu nejbezpečnější světové organizace."; +"onboarding_splash_page_4_title_no_pun" = "Zasílání zpráv pro váš tým."; +"onboarding_splash_page_3_message" = "End-to-end šifrování a bez potřeby telefonního čísla. Žádné reklamy nebo zneužívání údajů."; +"onboarding_splash_page_2_message" = "Volba, kde jsou vaše konverzace uloženy, vám dává kontrolu a nezávislost. Spojeno pomocí Matrix."; +"onboarding_splash_page_1_message" = "Bezpečná a nezávislá komunikace, která vám zajistí stejnou úroveň soukromý, jako konverzace z očí do očí ve vašem vlastním domě."; +"onboarding_splash_page_3_title" = "Zabezpečené zasílání zpráv."; +"onboarding_splash_page_2_title" = "Vy máte kontrolu."; +"onboarding_splash_page_1_title" = "Vlastněte své konverzace."; +"onboarding_splash_login_button_title" = "Již mám účet"; + +// Onboarding +"onboarding_splash_register_button_title" = "Vytvořit účet"; +"accessibility_button_label" = "tlačítko"; +"ok" = "OK"; +"done" = "Hotovo"; +"open" = "Otevřít"; +"enable" = "Povolit"; diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index 4ddccf894..4fedaa943 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -56,7 +56,7 @@ "auth_missing_email_or_phone" = "Fehlende E-Mail-Adresse oder Telefon-Nummer"; "auth_password_dont_match" = "Passwörter stimmen nicht überein"; "auth_username_in_use" = "Benutzername bereits verwendet"; -"auth_forgot_password" = "Passwort des Matrix-Kontos vergessen?"; +"auth_forgot_password" = "Passwort deines Matrix-Kontos vergessen?"; "auth_msisdn_validation_title" = "Verifizierung ausstehend"; "auth_msisdn_validation_message" = "Bitte gib unten den Aktivierungs-Code ein, den wir per SMS verschickt haben."; "auth_msisdn_validation_error" = "Telefonnummer kann nicht verifiziert werden."; @@ -2138,3 +2138,8 @@ "attachment_unsupported_preview_title" = "Vorschau kann nicht angezeigt werden"; "message_reply_to_sender_sent_their_location" = "hat den eigenen Standort geteilt."; "room_displayname_all_other_members_left" = "%@ (Verlassen)"; +"notice_error_unformattable_event" = "** Nachricht kann nicht dargestellt werden. Bitte erstelle einen Bug-Report"; +"home_syncing" = "Synchronisiere"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Immer aktuelle Profilbilder und Nicknamen anzeigen"; +"room_participants_leave_success" = "Raum verlassen"; +"room_participants_leave_processing" = "Verlassen"; diff --git a/Riot/Assets/en.lproj/Untranslated.strings b/Riot/Assets/en.lproj/Untranslated.strings index 4e116c5be..d1710dc24 100644 --- a/Riot/Assets/en.lproj/Untranslated.strings +++ b/Riot/Assets/en.lproj/Untranslated.strings @@ -17,27 +17,6 @@ /** These strings will be ignored by Weblate. Useful for WIP **/ // MARK: Onboarding Personalization WIP -"onboarding_congratulations_title" = "Congratulations!"; -"onboarding_congratulations_message" = "Your account %@ has been created."; -"onboarding_congratulations_personalize_button" = "Personalise profile"; -"onboarding_congratulations_home_button" = "Take me home"; - -"onboarding_personalization_save" = "Save and continue"; -"onboarding_personalization_skip" = "Skip this step"; - -"onboarding_display_name_title" = "Choose a display name"; -"onboarding_display_name_message" = "This will be shown when you send messages."; -"onboarding_display_name_placeholder" = "Display Name"; -"onboarding_display_name_hint" = "You can change this later"; -"onboarding_display_name_max_length" = "Your display name must be less than 256 characters"; - -"onboarding_avatar_title" = "Add a profile picture"; -"onboarding_avatar_message" = "You can change this anytime."; -"onboarding_avatar_accessibility_label" = "Profile picture"; - -"onboarding_celebration_title" = "You’re all set!"; -"onboarding_celebration_message" = "Your preferences have been saved."; -"onboarding_celebration_button" = "Let's go"; "image_picker_action_files" = "Choose from files"; diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index ab8dfe66c..8f6405336 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -118,6 +118,29 @@ "onboarding_use_case_existing_server_message" = "Looking to join an existing server?"; "onboarding_use_case_existing_server_button" = "Connect to server"; +"onboarding_congratulations_title" = "Congratulations!"; +/* The placeholder string contains the user's matrix ID */ +"onboarding_congratulations_message" = "Your account %@ has been created."; +"onboarding_congratulations_personalize_button" = "Personalise profile"; +"onboarding_congratulations_home_button" = "Take me home"; + +"onboarding_personalization_save" = "Save and continue"; +"onboarding_personalization_skip" = "Skip this step"; + +"onboarding_display_name_title" = "Choose a display name"; +"onboarding_display_name_message" = "This will be shown when you send messages."; +"onboarding_display_name_placeholder" = "Display Name"; +"onboarding_display_name_hint" = "You can change this later"; +"onboarding_display_name_max_length" = "Your display name must be less than 256 characters"; + +"onboarding_avatar_title" = "Add a profile picture"; +"onboarding_avatar_message" = "You can change this anytime."; +"onboarding_avatar_accessibility_label" = "Profile picture"; + +"onboarding_celebration_title" = "You’re all set!"; +"onboarding_celebration_message" = "Your preferences have been saved."; +"onboarding_celebration_button" = "Let's go"; + // Authentication "auth_login" = "Log in"; "auth_register" = "Register"; @@ -479,6 +502,11 @@ Tap the + to start adding people."; "threads_notice_title" = "Threads no longer experimental 🎉"; "threads_notice_information" = "All threads created during the experimental period will now be rendered as regular replies.

This will be a one-off transition, as threads are now part of the Matrix specification."; "threads_notice_done" = "Got it"; +"threads_beta_title" = "Threads"; +"threads_beta_information" = "Keep discussions organised with threads.\n\nThreads help keep your conversations on-topic and easy to track. "; +"threads_beta_information_link" = "Learn more"; +"threads_beta_enable" = "Try it out"; +"threads_beta_cancel" = "Not now"; "media_type_accessibility_image" = "Image"; "media_type_accessibility_audio" = "Audio"; diff --git a/Riot/Assets/es.lproj/InfoPlist.strings b/Riot/Assets/es.lproj/InfoPlist.strings index db8c99db1..1f83ea895 100644 --- a/Riot/Assets/es.lproj/InfoPlist.strings +++ b/Riot/Assets/es.lproj/InfoPlist.strings @@ -1,7 +1,8 @@ // Permissions usage explanations "NSCameraUsageDescription" = "La cámara se usa para sacar fotos, vídeos y hacer videollamadas."; "NSPhotoLibraryUsageDescription" = "La biblioteca de fotos se usa para enviar fotos y vídeos."; -"NSMicrophoneUsageDescription" = "El micrófono se usa para grabar vídeos y realizar llamadas."; -"NSContactsUsageDescription" = "Para mostrarte cuáles de tus contactos ya utilizan Matrix, Element puede enviar las direcciones de correo electrónico y números telefónicos de tu agenda de contactos a tu Servidor de Identidad de Matrix. En los casos que se puede, tu información personal se cifra antes de ser enviada - por favor consulta la política de privacidad de tu Servidor de Identidad."; +"NSMicrophoneUsageDescription" = "Element necesita usar tu micrófono para hacer y recibir llamadas y grabar vídeos y mensajes de voz."; +"NSContactsUsageDescription" = "Element te mostrará tus contactos para que les puedas invitar a una conversación."; "NSFaceIDUsageDescription" = "Face ID se usa para acceder a tu aplicación."; "NSCalendarsUsageDescription" = "Mostrar tus reuniones en la aplicación."; +"NSLocationWhenInUseUsageDescription" = "Cuando compartes tu ubicación con otras personas, Element necesita acceso para que puedan verla en el mapa."; diff --git a/Riot/Assets/es.lproj/Localizable.strings b/Riot/Assets/es.lproj/Localizable.strings index dbac976df..6bd52f85a 100644 --- a/Riot/Assets/es.lproj/Localizable.strings +++ b/Riot/Assets/es.lproj/Localizable.strings @@ -70,3 +70,60 @@ /* New message indicator on a room */ "MESSAGE_IN_X" = "Mensaje en %@"; "MESSAGE_PROTECTED" = "Nuevo mensaje"; + +/* Group call from user, CallKit caller name */ +"GROUP_CALL_FROM_USER" = "%@ (llamada en grupo)"; + +/* A user added a Jitsi call to a room */ +"GROUP_CALL_STARTED" = "Llamada en grupo empezada"; + +/* A user's membership has updated in an unknown way */ +"USER_MEMBERSHIP_UPDATED" = "%@ ha actualizado su perfil"; + +/* A user has change their avatar */ +"USER_UPDATED_AVATAR" = "%@ ha cambiado su foto de perfil"; + +/* A user has change their name to a new name which we don't know */ +"GENERIC_USER_UPDATED_DISPLAYNAME" = "%@ ha cambiado su nombre"; + +/** Membership Updates **/ + +/* A user has change their name to a new name */ +"USER_UPDATED_DISPLAYNAME" = "%@ ha cambiado su nombre a %@"; + +/* A user has reacted to a message, but the reaction content is unknown */ +"GENERIC_REACTION_FROM_USER" = "%@ ha enviado una reacción"; + +/** Reactions **/ + +/* A user has reacted to a message, including the reaction e.g. "Alice reacted 👍". */ +"REACTION_FROM_USER" = "%@ ha reaccionado %@"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ ha compartido su ubicación"; + +/* New file message from a specific person, not referencing a room. */ +"FILE_FROM_USER" = "%@ ha enviado un archivo %@"; + +/* New voice message from a specific person, not referencing a room. */ +"VOICE_MESSAGE_FROM_USER" = "%@ ha enviado un mensaje de voz"; + +/* New audio message from a specific person, not referencing a room. */ +"AUDIO_FROM_USER" = "%@ ha enviado un audio %@"; + +/* New video message from a specific person, not referencing a room. */ +"VIDEO_FROM_USER" = "%@ ha enviado un vídeo"; + +/** Media Messages **/ + +/* New image message from a specific person, not referencing a room. */ +"PICTURE_FROM_USER" = "%@ ha enviado una imagen"; + +/* New message reply from a specific person in a named room. */ +"REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ ha respondido en %@"; + +/* New message reply from a specific person, not referencing a room. */ +"REPLY_FROM_USER_TITLE" = "%@ ha respondido"; +/** General **/ + +"NOTIFICATION" = "Notificación"; diff --git a/Riot/Assets/es.lproj/Vector.strings b/Riot/Assets/es.lproj/Vector.strings index 39c7fd78c..269c6bce9 100644 --- a/Riot/Assets/es.lproj/Vector.strings +++ b/Riot/Assets/es.lproj/Vector.strings @@ -36,7 +36,7 @@ "auth_register" = "Registrar"; "auth_submit" = "Enviar"; "auth_skip" = "Omitir"; -"auth_send_reset_email" = "Enviar Correo Electrónico de Restauración"; +"auth_send_reset_email" = "Enviar correo electrónico de restauración"; "auth_return_to_login" = "Regresar a la pantalla de inicio de sesión"; "auth_user_id_placeholder" = "Correo electrónico o nombre de usuario"; "auth_password_placeholder" = "Contraseña"; @@ -46,35 +46,35 @@ "auth_email_placeholder" = "Dirección de correo electrónico"; "send_to" = "Enviar a %@"; "sending" = "Enviando"; -"auth_optional_phone_placeholder" = "Número telefónico (opcional)"; -"auth_phone_placeholder" = "Número telefónico"; +"auth_optional_phone_placeholder" = "Número de teléfono (opcional)"; +"auth_phone_placeholder" = "Número de teléfono"; "auth_repeat_password_placeholder" = "Repite la contraseña"; -"auth_repeat_new_password_placeholder" = "Confirma tu contraseña nueva"; -"auth_home_server_placeholder" = "URL (ej. https://matrix.org)"; +"auth_repeat_new_password_placeholder" = "Confirma la nueva contraseña de tu cuenta de Matrix"; +"auth_home_server_placeholder" = "URL (ej.: https://matrix.org)"; "auth_identity_server_placeholder" = "URL (ej.: https://matrix.org)"; "auth_invalid_login_param" = "Nombre de usuario y/o contraseña incorrectos"; "auth_invalid_user_name" = "Los nombres de usuario solo pueden contener letras, números, puntos, guiones y guiones bajos"; "auth_invalid_password" = "Contraseña demasiado corta (mínimo 6)"; "auth_invalid_email" = "Esto no parece ser una dirección de correo electrónico válida"; -"auth_invalid_phone" = "Esto no parece ser un número telefónico válido"; +"auth_invalid_phone" = "Esto no parece ser un número de teléfono válido"; "auth_missing_password" = "Falta la contraseña"; "auth_add_email_message" = "Añade una dirección de correo electrónico a tu cuenta para poder ser descubierto por otros usuarios, y ser capaz de restablecer tu contraseña."; "auth_add_phone_message" = "Añade un número telefónico a tu cuenta para poder ser descubierto por otros usuarios."; "title_groups" = "Comunidades"; "deactivate_account_password_alert_title" = "Desactivar Cuenta"; "deactivate_account_validate_action" = "Desactivar cuenta"; -"deactivate_account_password_alert_message" = "Para continuar, ingresa tu contraseña por favor"; +"deactivate_account_password_alert_message" = "Para continuar, introduce la contraseña de tu cuenta de Matrix"; "deactivate_account_forget_messages_information_part2_emphasize" = "Advertencia"; "deactivate_account_informations_part2_emphasize" = "Esta acción es irreversible."; -"rerequest_keys_alert_message" = "Por favor, inicia Element en otro dispositivo que pueda descifrar el mensaje para que pueda enviar las claves a este dispositivo."; +"rerequest_keys_alert_message" = "Por favor, abre Element en otro dispositivo que pueda descifrar el mensaje para que envíe las claves a esta sesión."; // Re-request confirmation dialog "rerequest_keys_alert_title" = "Solicitud Enviada"; "auth_password_dont_match" = "Las contraseñas no coinciden"; "auth_username_in_use" = "Nombre de usuario en uso"; "auth_email_in_use" = "Esta dirección de correo electrónico ya está en uso"; -"auth_phone_in_use" = "Este número telefónico ya está en uso"; +"auth_phone_in_use" = "Este número de teléfono ya está en uso"; "auth_use_server_options" = "Utilizar opciones personalizadas del servidor (avanzado)"; -"auth_reset_password_missing_password" = "Debes ingresar una contraseña nueva."; +"auth_reset_password_missing_password" = "Debes escribir una contraseña nueva."; "auth_reset_password_next_step_button" = "He verificado mi dirección de correo electrónico"; "room_creation_appearance" = "Apariencia"; "room_creation_appearance_name" = "Nombre"; @@ -112,23 +112,23 @@ "auth_add_email_phone_message" = "Añade una dirección de correo electrónico y/o un número telefónico a tu cuenta para poder ser descubierto por otros usuarios. Además, la dirección de correo electrónico te permitirá restablecer tu contraseña."; "auth_add_email_and_phone_message" = "Añade una dirección de correo electrónico y un número telefónico a tu cuenta para poder ser descubierto por otros usuarios. Además, la dirección de correo electrónico te permitirá restablecer tu contraseña."; "auth_missing_email" = "Falta la dirección de correo electrónico"; -"auth_missing_phone" = "Falta el número telefónico"; -"auth_missing_email_or_phone" = "Falta la dirección de correo electrónico o el número telefónico"; +"auth_missing_phone" = "Falta el número de teléfono"; +"auth_missing_email_or_phone" = "Falta la dirección de correo electrónico o el número de teléfono"; "auth_untrusted_id_server" = "El servidor de identidad no es de confianza"; -"auth_forgot_password" = "¿Olvidaste tu contraseña?"; +"auth_forgot_password" = "¿Has olvidado la contraseña de tu cuenta de Matrix?"; "auth_email_not_found" = "No se pudo enviar el correo electrónico: No se encontró esta dirección de correo electrónico"; "auth_email_validation_message" = "Por favor consulta tu correo electrónico para continuar con el registro"; "auth_msisdn_validation_title" = "Verificación Pendiente"; -"auth_msisdn_validation_message" = "Hemos enviado un SMS con un código de activación. Por favor, ingresa este código a continuación."; -"auth_msisdn_validation_error" = "No se pudo verificar el número telefónico."; +"auth_msisdn_validation_message" = "Hemos enviado un SMS con un código de activación. Por favor, escribe este código a continuación."; +"auth_msisdn_validation_error" = "No ha podido verificar el número de teléfono."; "auth_recaptcha_message" = "Este servidor base quiere asegurarse de que no eres un robot"; -"auth_reset_password_message" = "Para restablecer tu contraseña, ingresa la dirección de correo electrónico vinculada a tu cuenta:"; -"auth_reset_password_missing_email" = "Debes ingresar la dirección de correo electrónico vinculada a tu cuenta."; +"auth_reset_password_message" = "Para restablecer la contraseña de tu cuenta de Matrix, escribe la dirección de correo electrónico vinculada a tu cuenta:"; +"auth_reset_password_missing_email" = "Debes escribir la dirección de correo electrónico vinculada a tu cuenta."; "auth_reset_password_email_validation_message" = "Se envió un correo electrónico a %@. Una vez que hayas seguido el enlace que contiene, haz clic a continuación."; "auth_reset_password_error_unauthorized" = "No se pudo verificar la dirección de correo electrónico: asegúrate de hacer clic en el enlace del correo electrónico"; "auth_reset_password_error_not_found" = "Tu dirección de correo electrónico no parece estar asociada a una ID de Matrix en este servidor base."; -"auth_reset_password_success_message" = "Has restablecido tu contraseña.\n\nHemos cerrado sesión en todos tus dispositivos, y ya no recibirás notificaciones. Para volver a activar las notificaciones, vuelve a iniciar sesión en cada dispositivo."; -"auth_add_email_and_phone_warning" = "Todavía no es posible registrarse con correo electrónico y número telefónico a la vez, hasta que exista la API. Solo se tendrá en cuenta el número telefónico. Puedes añadir tu correo electrónico a tu perfil en ajustes."; +"auth_reset_password_success_message" = "Has cambiado la contraseña de tu cuenta de Matrix.\n\nHemos cerrado todas tus sesiones, por lo que dejarás de recibir notificaciones push. Para volver a activar las notificaciones, vuelve a iniciar sesión en cada dispositivo."; +"auth_add_email_and_phone_warning" = "Todavía no es posible registrarse con correo electrónico y número de teléfono a la vez, hasta que exista la API. Solo se tendrá en cuenta el número telefónico. Puedes añadir tu correo electrónico a tu perfil en ajustes."; // Chat creation "room_creation_title" = "Nueva Conversación"; "room_creation_account" = "Cuenta"; @@ -141,7 +141,7 @@ "room_creation_keep_private" = "Mantener privada"; "room_creation_make_private" = "Hacer privada"; "room_creation_wait_for_creation" = "Ya se está creando una sala. Espera por favor."; -"room_creation_invite_another_user" = "Buscar / invitar por ID de Usuario, Nombre o correo electrónico"; +"room_creation_invite_another_user" = "ID de usuario, nombre o correo electrónico"; // Room recents "room_recents_directory_section" = "DIRECTORIO DE SALAS"; "room_recents_favourites_section" = "FAVORITOS"; @@ -165,7 +165,7 @@ "directory_search_fail" = "Error al buscar datos"; "contacts_address_book_no_contact" = "No hay contactos locales"; "contacts_address_book_permission_required" = "Se requiere permiso para acceder a tus contactos locales"; -"contacts_address_book_permission_denied" = "No permitiste que Element acceda a tus contactos locales"; +"contacts_address_book_permission_denied" = "No has permitido que %@ acceda a tus contactos locales"; "contacts_user_directory_section" = "DIRECTORIO DE USUARIOS"; "contacts_user_directory_offline_section" = "DIRECTORIO DE USUARIOS (desconectados)"; "room_participants_leave_prompt_title" = "Salir de la sala"; @@ -216,7 +216,7 @@ "room_message_reply_to_short_placeholder" = "Enviar una respuesta…"; "room_offline_notification" = "Se perdió la conexión con el servidor."; "room_unsent_messages_notification" = "Los mensajes no se enviaron."; -"room_unsent_messages_unknown_devices_notification" = "No se envió el mensaje debido a dispositivos desconocidos presentes."; +"room_unsent_messages_unknown_devices_notification" = "No se ha enviado el mensaje porque hay sesiones desconocidas presentes."; "room_recents_server_notice_section" = "ALERTAS DE SISTEMA"; "room_ongoing_conference_call" = "Llamada de conferencia en curso. Unirse con %@ o %@."; "room_ongoing_conference_call_with_close" = "Llamada de conferencia en curso. Unirse con %@ o %@. %@ la."; @@ -231,12 +231,12 @@ "room_event_action_redact" = "Eliminar"; "room_event_action_more" = "Más"; "room_event_action_share" = "Compartir"; -"room_event_action_permalink" = "Enlace Permanente"; +"room_event_action_permalink" = "Copiar enlace al mensaje"; "room_event_action_view_source" = "Ver Fuente"; "room_event_action_view_decrypted_source" = "Ver Fuente Descifrada"; "room_event_action_report" = "Reportar contenido"; "room_event_action_report_prompt_reason" = "Motivo para reportar este contenido"; -"room_event_action_kick_prompt_reason" = "Motivo para expulsar a este usuario"; +"room_event_action_kick_prompt_reason" = "Motivo para sacar a este usuario"; "room_event_action_ban_prompt_reason" = "Motivo para vetar a este usuario"; "room_event_action_report_prompt_ignore_user" = "¿Quieres ocultar todos los mensajes de este usuario?"; "room_event_action_save" = "Guardar"; @@ -257,13 +257,13 @@ "room_resource_limit_exceeded_message_contact_2_link" = "contacta al administrador de tu servicio"; "room_resource_limit_exceeded_message_contact_3" = " para continuar utilizando este servicio."; // Unknown devices -"unknown_devices_alert_title" = "La sala contiene dispositivos desconocidos"; -"unknown_devices_alert" = "Esta sala contiene dispositivos desconocidos que no han sido verificados.\nEsto significa que no hay garantía de que los dispositivos pertenezcan a los usuarios a los que dicen pertenecer.\nRecomendamos que pases por el proceso de verificación para cada dispositivo antes de continuar, pero puedes reenviar el mensaje sin verificarlos si prefieres."; +"unknown_devices_alert_title" = "La sala contiene sesiones desconocidas"; +"unknown_devices_alert" = "Esta sala contiene sesiones desconocidas que no han sido verificadas.\nEsto significa que no hay garantía de que las sesiones pertenezcan a los usuarios a los que dicen pertenecer.\nRecomendamos que pases por el proceso de verificación para cada dispositivo antes de continuar, pero puedes reenviar el mensaje sin verificarlas si prefieres."; "unknown_devices_send_anyway" = "Enviar de Todos Modos"; "unknown_devices_call_anyway" = "Llamar de todos modos"; "unknown_devices_answer_anyway" = "Contestar de Todos Modos"; "unknown_devices_verify" = "Verificar…"; -"unknown_devices_title" = "Dispositivos desconocidos"; +"unknown_devices_title" = "Sesiones desconocidas"; // Room Title "room_title_new_room" = "Sala nueva"; "room_title_multiple_active_members" = "%@/%@ miembros activos"; @@ -283,7 +283,7 @@ "settings_config_no_build_info" = "No hay información de compilación"; "settings_mark_all_as_read" = "Marcar todos los mensajes como leídos"; "settings_report_bug" = "Reportar error"; -"settings_config_home_server" = "Servidor doméstico es %@"; +"settings_config_home_server" = "El servidor base es %@"; "settings_config_identity_server" = "Servidor de identidad es %@"; "settings_config_user_id" = "Sesión iniciada como %@"; "settings_user_settings" = "AJUSTES DE USUARIO"; @@ -291,29 +291,29 @@ "settings_calls_settings" = "LLAMADAS"; "settings_user_interface" = "INTERFAZ DE USUARIO"; "settings_ignored_users" = "USUARIOS IGNORADOS"; -"settings_contacts" = "CONTACTOS LOCALES"; +"settings_contacts" = "CONTACTOS DEL DISPOSITIVO"; "settings_advanced" = "AVANZADO"; -"settings_other" = "OTRO"; +"settings_other" = "OTROS"; "settings_labs" = "LABORATORIOS"; "settings_flair" = "Mostrar insignia donde esté permitido"; -"settings_devices" = "DISPOSITIVOS"; +"settings_devices" = "SESIONES"; "settings_cryptography" = "CRIPTOGRAFÍA"; "settings_deactivate_account" = "DESACTIVAR CUENTA"; "settings_sign_out" = "Cerrar Sesión"; "settings_sign_out_confirmation" = "¿Estás seguro?"; -"settings_sign_out_e2e_warn" = "Perderás tus claves de cifrado de extremo a extremo. Esto significa que no podrás leer mensajes antiguos en salas cifradas desde este dispositivo."; -"settings_profile_picture" = "Imagen de Perfil"; -"settings_display_name" = "Nombre Público"; +"settings_sign_out_e2e_warn" = "Perderás tus claves de cifrado de extremo a extremo. Esto significa que, desde este dispositivo, no podrás leer mensajes los antiguos en salas cifradas."; +"settings_profile_picture" = "Imagen de perfil"; +"settings_display_name" = "Nombre público"; "settings_first_name" = "Nombre de Pila"; "settings_surname" = "Apellido"; "settings_remove_prompt_title" = "Confirmación"; "settings_remove_email_prompt_msg" = "¿Seguro que quieres eliminar la dirección de correo electrónico %@?"; -"settings_remove_phone_prompt_msg" = "¿Seguro que quieres eliminar el número telefónico %@?"; -"settings_email_address" = "Correo Electrónico"; -"settings_email_address_placeholder" = "Ingresa tu dirección de correo electrónico"; +"settings_remove_phone_prompt_msg" = "¿Seguro que quieres eliminar el número de teléfono %@?"; +"settings_email_address" = "Correo electrónico"; +"settings_email_address_placeholder" = "Escribe tu dirección de correo electrónico"; "settings_add_email_address" = "Añadir dirección de correo electrónico"; "settings_phone_number" = "Teléfono"; -"settings_add_phone_number" = "Añadir número telefónico"; +"settings_add_phone_number" = "Añadir número de teléfono"; "settings_night_mode" = "Modo Nocturno"; "settings_fail_to_update_profile" = "Error al actualizar el perfil"; "settings_enable_push_notif" = "Notificaciones en este dispositivo"; @@ -322,7 +322,7 @@ "settings_pin_rooms_with_missed_notif" = "Fijar salas con notificaciones pendientes"; "settings_pin_rooms_with_unread" = "Fijar salas con mensajes no leídos"; "settings_enable_callkit" = "Integración de llamadas"; -"settings_callkit_info" = "Recibe llamadas entrantes en tu pantalla de bloqueo. Ve tus llamadas de Element en el historial de llamadas del sistema. Si iCloud está habilitado, este historial de llamadas se compartirá con Apple."; +"settings_callkit_info" = "Recibe llamadas entrantes en tu pantalla de bloqueo. Ve tus llamadas de %@ en el historial de llamadas del sistema. Si has activado iCloud, este historial de llamadas se compartirá con Apple."; "settings_ui_language" = "Idioma"; "settings_ui_theme" = "Tema"; "settings_ui_theme_auto" = "Automático"; @@ -348,17 +348,17 @@ "settings_send_crash_report" = "Enviar datos de uso e informes de fallas anónimos"; "settings_enable_rageshake" = "Agitar con rabia para reportar un error"; "settings_clear_cache" = "Borrar caché"; -"settings_change_password" = "Cambiar contraseña"; +"settings_change_password" = "Cambiar contraseña en la cuenta de Matrix"; "settings_old_password" = "contraseña anterior"; "settings_new_password" = "contraseña nueva"; "settings_confirm_password" = "confirmar contraseña"; -"settings_fail_to_update_password" = "No se pudo actualizar la contraseña"; -"settings_password_updated" = "Tu contraseña ha sido actualizada"; -"settings_crypto_device_name" = "Nombre de dispositivo: "; -"settings_crypto_device_id" = "\nID de Dispositivo: "; -"settings_crypto_device_key" = "\nClave de dispositivo: "; +"settings_fail_to_update_password" = "No se ha podido cambiar la contraseña de Matrix"; +"settings_password_updated" = "La contraseña de tu cuenta de Matrix ha sido cambiada"; +"settings_crypto_device_name" = "Nombre de la sesión: "; +"settings_crypto_device_id" = "\nID de la sesión: "; +"settings_crypto_device_key" = "\nClave de la sesión:\n"; "settings_crypto_export" = "Exportar claves"; -"settings_crypto_blacklist_unverified_devices" = "Cifrar solo a dispositivos verificados"; +"settings_crypto_blacklist_unverified_devices" = "Cifrar solo a sesiones verificadas"; "settings_deactivate_my_account" = "Desactivar mi cuenta"; // Room Details "room_details_title" = "Detalles de Sala"; @@ -368,7 +368,7 @@ "room_details_photo" = "Imagen de Sala"; "room_details_room_name" = "Nombre de Sala"; "room_details_topic" = "Tema"; -"room_details_favourite_tag" = "Agregar a Favoritos"; +"room_details_favourite_tag" = "Añadir a favoritos"; "room_details_low_priority_tag" = "Prioridad baja"; "room_details_mute_notifs" = "Silenciar notificaciones"; "room_details_direct_chat" = "Conversación Directa"; @@ -405,7 +405,7 @@ "room_details_advanced_enable_e2e_encryption" = "Habilitar cifrado (advertencia: ¡no se puede volver a deshabilitar!)"; "room_details_advanced_e2e_encryption_enabled" = "El cifrado está habilitado en esta sala"; "room_details_advanced_e2e_encryption_disabled" = "El cifrado no está habilitado en esta sala."; -"room_details_advanced_e2e_encryption_blacklist_unverified_devices" = "Cifrar solo a dispositivos verificados"; +"room_details_advanced_e2e_encryption_blacklist_unverified_devices" = "Cifrar solo a sesiones verificadas"; "room_details_advanced_e2e_encryption_prompt_message" = "El cifrado de extremo a extremo es experimental y puede no ser confiable.\n\nAún no deberías confiar en él para proteger tus datos.\n\nLos dispositivos todavía no podrán descifrar el historial desde antes de unirse a la sala.\n\nUna vez que se habilita el cifrado en una sala no se puede volver a desactivar (por ahora).\n\nLos mensajes cifrados no serán visibles en clientes que aún no implementen el cifrado."; "room_details_fail_to_update_avatar" = "No se pudo actualizar la imagen de la sala"; "room_details_fail_to_update_room_name" = "No se pudo actualizar el nombre de la sala"; @@ -470,7 +470,7 @@ "event_formatter_jitsi_widget_added" = "conferencia vozIP añadida por %@"; "event_formatter_jitsi_widget_removed" = "conferencia vozIP eliminada por %@"; "event_formatter_rerequest_keys_part1_link" = "Volver a solicitar las claves de cifrado"; -"event_formatter_rerequest_keys_part2" = " de tus otros dispositivos."; +"event_formatter_rerequest_keys_part2" = " de tus otras sesiones."; // Others "or" = "o"; "you" = "Tú"; @@ -487,8 +487,8 @@ // Call "call_incoming_voice_prompt" = "Llamada de voz entrante de %@"; "call_incoming_video_prompt" = "Llamada de vídeo entrante de %@"; -"call_incoming_voice" = "Llamada entrante..."; -"call_incoming_video" = "Llamada de vídeo entrante..."; +"call_incoming_voice" = "Llamada entrante…"; +"call_incoming_video" = "Llamada de vídeo entrante…"; "call_already_displayed" = "Ya hay una llamada en curso."; "call_jitsi_error" = "No se ha podido unir a la llamada de conferencia."; // No VoIP support @@ -497,8 +497,8 @@ // Crash report "google_analytics_use_prompt" = "¿Te gustaría ayudar a mejorar %@ enviando automáticamente informes de fallas y datos de uso anónimos?"; // Crypto -"e2e_enabling_on_app_update" = "Element ahora admite cifrado de extremo a extremo pero debes volver a iniciar sesión para habilitarlo.\n\nPuedes hacerlo ahora o más tarde desde los ajustes de la aplicación."; -"e2e_need_log_in_again" = "Tienes que volver a iniciar sesión para generar claves de cifrado de extremo a extremo para este dispositivo y enviar la clave pública a tu servidor doméstico.\nEsto es por única vez; disculpas por la molestia."; +"e2e_enabling_on_app_update" = "Element ahora admite cifrado de extremo a extremo, pero debes volver a iniciar sesión para activarlo.\n\nPuedes hacerlo ahora o más tarde desde los ajustes de la aplicación."; +"e2e_need_log_in_again" = "Tienes que volver a iniciar sesión para generar claves de cifrado de extremo a extremo para este dispositivo y enviar la clave pública a tu servidor base.\nSolo hay que hacer esto una vez, disculpa las molestias."; // Bug report "bug_report_title" = "Informe de Error"; "bug_report_description" = "Por favor describe el error. ¿Qué hiciste? ¿Qué esperabas que sucediera? ¿Qué sucedió realmente?"; @@ -532,9 +532,9 @@ "widget_integration_missing_user_id" = "Falta el user_id en la solicitud."; "widget_integration_room_not_visible" = "La sala %@ no está visible."; "share_extension_failed_to_encrypt" = "Falló el envío. Comprueba los ajustes de cifrado para esta sala en la aplicación principal"; -"e2e_room_key_request_message_new_device" = "Añadiste un nuevo dispositivo '%@', que está solicitando claves de cifrado."; -"e2e_room_key_request_message" = "Tu dispositivo sin verificar '%@' está solicitando claves de cifrado."; -"e2e_room_key_request_start_verification" = "Iniciar verificación..."; +"e2e_room_key_request_message_new_device" = "Has añadido una nueva sesión «%@», que está pidiendo claves de cifrado."; +"e2e_room_key_request_message" = "Tu sesión sin verificar «%@» está pidiendo claves de cifrado."; +"e2e_room_key_request_start_verification" = "Empezar la verificación…"; "e2e_room_key_request_share_without_verifying" = "Compartir sin verificar"; "e2e_room_key_request_ignore_request" = "Ignorar solicitud"; // GDPR @@ -634,8 +634,8 @@ "room_recents_unknown_room_error_message" = "No encuentro la sala. Asegúrate de que existe de verdad"; "auth_softlogout_clear_data_sign_out_msg" = "¿Quieres borrar todos los datos que hemos almacenado en el dispositivo? Vuelve a iniciar sesión para acceder de nuevo a tu cuenta y mensajes."; "auth_autodiscover_invalid_response" = "La respuesta de descubrimiento del servidor base no es válida"; -"auth_forgot_password_error_no_configured_identity_server" = "No hay ningún servidor de identidad configurado: añade uno para poder recuperar tu contraseña en el futuro."; -"auth_email_is_required" = "No hay ningún servidor de identidad configurado, por lo que no puedes añadir una dirección de correo para recuperar tu contraseña en el futuro."; +"auth_forgot_password_error_no_configured_identity_server" = "No hay ningún servidor de identidad configurado: añade uno para poder recuperar la contraseña de tu cuenta de Matrix en el futuro."; +"auth_email_is_required" = "No hay ningún servidor de identidad configurado, por lo que no puedes añadir una dirección de correo para recuperar la contraseña de tu cuenta de Matrix en el futuro."; "auth_add_email_phone_message_2" = "Dinos tu correo para recuperar tu cuenta en un futuro. Además, también puedes activar que la gente te encuentre al buscar tu correo o número de teléfono."; "callbar_only_single_active_group" = "Toca para unirte a la llamada en grupo (%@)"; "room_accessibility_integrations" = "Integraciones"; @@ -668,7 +668,7 @@ "user_id_placeholder" = "ej: @juan:servidordomestico"; "login_email_info" = "Especificar una dirección de correo electrónico permite que otros usuarios te encuentren en Matrix más fácilmente, y te dará una manera de restablecer tu contraseña en el futuro."; "login_email_placeholder" = "Dirección de correo electrónico"; -"login_prompt_email_token" = "Por favor ingresa tu código de validación de correo electrónico:"; +"login_prompt_email_token" = "Escribe tu código de validación de correo electrónico:"; "login_error_title" = "No se pudo iniciar sesión"; "login_error_no_login_flow" = "No pudimos recuperar la información de autenticación de este Servidor Local"; "login_error_do_not_support_login_flows" = "Actualmente no admitimos cualquiera o todos los flujos de inicio de sesión definidos por este Servidor Local"; @@ -779,7 +779,7 @@ "device_details_last_seen_format" = "%@ @ %@\n"; "device_details_rename_prompt_message" = "Un nombre público de una sesión es invisible para personas con que Ud. se comunica"; "device_details_delete_prompt_title" = "Autenticación"; -"device_details_delete_prompt_message" = "Esta operación requiere autenticación adicional.\nPara continuar, ingresa tu contraseña por favor."; +"device_details_delete_prompt_message" = "Esta operación requiere autenticación adicional.\nPara continuar, escribe tu contraseña."; // Encryption information "room_event_encryption_info_title" = "Información de cifrado de extremo a extremo\n\n"; "room_event_encryption_info_event" = "Información de evento\n"; @@ -816,14 +816,14 @@ "account_email_validation_error" = "No es posible verificar la dirección de correo electrónico. Por favor, consulta tu correo electrónico y haz clic en el enlace que contiene. Una vez hecho esto, haz clic en continuar"; "account_msisdn_validation_title" = "Verificación Pendiente"; "account_msisdn_validation_message" = "Hemos enviado un SMS con un código de activación. Por favor, ingresa este código a continuación."; -"account_msisdn_validation_error" = "No es posible verificar el número telefónico."; +"account_msisdn_validation_error" = "No es posible verificar el número de teléfono."; "account_error_display_name_change_failed" = "El cambio de nombre público falló"; "account_error_picture_change_failed" = "El cambio de imagen falló"; "account_error_matrix_session_is_not_opened" = "La sesión de Matrix no está abierta"; "account_error_email_wrong_title" = "Dirección de Correo Electrónico Inválida"; "account_error_email_wrong_description" = "Esto no parece ser una dirección de correo electrónico válida"; -"account_error_msisdn_wrong_title" = "Número Telefónico Inválido"; -"account_error_msisdn_wrong_description" = "Esto no parece ser un número telefónico válido"; +"account_error_msisdn_wrong_title" = "Número de teléfono inválido"; +"account_error_msisdn_wrong_description" = "Esto no parece ser un número de teléfono válido"; // Room creation "room_creation_name_title" = "Nombre de sala:"; "room_creation_name_placeholder" = "(ej. grupoDeAlmuerzo)"; @@ -906,7 +906,7 @@ "microphone_access_not_granted_for_call" = "Las llamadas requieren acceso al Micrófono pero %@ no tiene permiso para utilizarlo"; "local_contacts_access_not_granted" = "El descubrimiento de usuarios desde los contactos locales requiere acceso a tus contactos pero %@ no tiene permiso para utilizarlo"; "local_contacts_access_discovery_warning_title" = "Descubrimiento de usuarios"; -"local_contacts_access_discovery_warning" = "Para descubrir contactos que ya usan Matrix, %@ puede enviar correos electrónicos y números telefónicos desde tus Contactos hacia el Servidor de Identidades de Matrix. Cuando es posible, los datos personales se procesan antes de enviarlos. Por favor, compruebe la política de privacidad de su servidor de identidad para más detalles."; +"local_contacts_access_discovery_warning" = "Para descubrir contactos que ya usan Matrix, %@ puede enviar correos electrónicos y números de teléfono desde tus Contactos hacia el Servidor de Identidades de Matrix. Cuando es posible, los datos personales se procesan antes de enviarlos. Por favor, compruebe la política de privacidad de su servidor de identidad para más detalles."; // Country picker "country_picker_title" = "Elige un país"; // Language picker @@ -927,8 +927,8 @@ "notice_display_name_set" = "%@ estableció %@ como su nombre público"; "notice_display_name_changed_from" = "%@ cambió su nombre público de %@ a %@"; "notice_display_name_removed" = "%@ eliminó su nombre público"; -"notice_topic_changed" = "%@ cambió el tema a: %@"; -"notice_room_name_changed" = "%@ cambió el nombre de la sala a: %@"; +"notice_topic_changed" = "%@ cambió el asunto a: %@."; +"notice_room_name_changed" = "%@ cambió el nombre de la sala a: %@."; "notice_placed_voice_call" = "%@ realizó una llamada de voz"; "notice_answered_video_call" = "%@ contestó la llamada"; "notice_ended_video_call" = "%@ finalizó la llamada"; @@ -996,7 +996,7 @@ // gcm section // call string "call_waiting" = "Esperando..."; -"call_connecting" = "Conectando llamada..."; +"call_connecting" = "Conectando…"; "call_ended" = "Llamada finalizada"; "call_ring" = "Llamando..."; "incoming_video_call" = "Llamada de Vídeo Entrante"; @@ -1015,7 +1015,7 @@ "ssl_only_accept" = "SOLO acepta el certificado si el administrador del servidor ha publicado una huella digital que coincide con la indicada arriba."; "notice_placed_video_call" = "%@ realizó una llamada de vídeo"; "e2e_passphrase_create" = "Crear contraseña"; -"notice_encryption_enabled_ok" = "%@ activó encriptación de extremo a extremo"; +"notice_encryption_enabled_ok" = "%@ activó el cifrado de extremo a extremo."; "notice_encryption_enabled_unknown_algorithm" = "%1$@ activó encriptación de extremo a extremo (algoritmo %2$@ desconocido)."; "device_details_rename_prompt_title" = "Nombre de Sesión"; "account_error_push_not_allowed" = "No se permite notificaciones"; @@ -1036,3 +1036,1194 @@ // New "notice_room_join_rule_invite" = "%@ ha hecho que la sala solo sea accesible por invitación."; "resume_call" = "Volver a la llamada"; +"settings_key_backup_info_checking" = "Comprobando…"; +"settings_messages_containing_display_name" = "Mi nombre"; +"settings_three_pids_management_information_part2" = "Descubrir"; +"threads_empty_tip" = "Consejo: toca un mensaje y dale a «Hilo» para empezar uno nuevo."; +"threads_empty_info_my" = "Responde en un hilo que ya exista o toca un mensaje y dale a «Hilo» para empezar uno nuevo."; +"threads_empty_info_all" = "Los hilos ayudan a que las conversaciones no se desvíen y sean fáciles de seguir."; +"threads_empty_title" = "Mantén las conversaciones organizadas usando los hilos"; +"thread_copy_link_to_thread" = "Copiar enlace al hilo"; +"room_event_copy_link_info" = "Enlace copiado al portapapeles."; +"room_event_action_delete_confirmation_message" = "¿Seguro que quieres borrar este no enviado?"; +"room_participants_security_information_room_not_encrypted_for_dm" = "Estos mensajes no están cifrados de extremo a extremo."; +"store_promotional_text" = "Aplicación para chatear y colaborar que respeta tu privacidad y funciona con una red abierta. Descentralizada, para que puedas mantener el control. Sin minería de datos, puertas traseras ni acceso de terceros."; +"settings_call_invitations" = "Llamadas"; +"settings_room_invitations" = "Invitaciones a salas"; +"settings_messages_containing_keywords" = "Palabras clave"; +"settings_messages_containing_user_name" = "Tu nombre de usuario"; +"settings_messages_containing_at_room" = "@room"; +"settings_security" = "SEGURIDAD"; +"settings_three_pids_management_information_part3" = "."; +"settings_about" = "ACERCA DE"; +"settings_notifications" = "NOTIFICACIONES"; +"settings_links" = "ENLACES"; +"settings_sending_media" = "ENVÍA IMÁGENES Y VÍDEOS"; +"threads_empty_show_all_threads" = "Ver todos los hilos"; +"message_from_a_thread" = "Desde un hilo"; +"threads_action_my_threads" = "Mis hilos"; +"threads_action_all_threads" = "Todos los hilos"; +"threads_title" = "Hilos"; + +// MARK: Threads +"room_thread_title" = "Hilo"; +"room_no_privileges_to_create_group_call" = "Tienes que ser un administrador o moderador para empezar una llamada."; +"room_accessibility_thread_more" = "Más"; +"room_accessibility_threads" = "Hilos"; +"room_message_edits_history_title" = "Ediciones de mensajes"; +"room_event_action_reaction_history" = "Historial de reacciones"; +"room_event_action_reply_in_thread" = "Hilo"; +"room_event_action_view_in_room" = "Ver en la sala"; +"room_event_action_forward" = "Reenviar"; +"room_event_action_end_poll" = "Terminar encuesta"; +"room_event_action_remove_poll" = "Quitar encuesta"; +"room_participants_action_security_status_complete_security" = "Completar la seguridad"; +"room_participants_leave_success" = "Salió de la sala"; +"find_your_contacts_footer" = "Puedes desactivar esto cuando quieres desde ajustes."; +"find_your_contacts_button_title" = "Encuentra tus contactos"; +"find_your_contacts_message" = "Deja que %@ te muestre tus contactos, para que puedas empezar a hablar rápidamente con quienes más te relacionas."; +"contacts_address_book_permission_denied_alert_message" = "Para activar los contactos, ve a los ajustes de tu dispositivo."; +"contacts_address_book_permission_denied_alert_title" = "Contactos desactivados"; +"search_filter_placeholder" = "Filtrar"; +"room_recents_suggested_rooms_section" = "SALAS SUGERIDAS"; +"onboarding_use_case_existing_server_button" = "Conectar a un servidor"; +"onboarding_use_case_existing_server_message" = "¿Te quieres unir a un servidor que ya existe?"; +"onboarding_use_case_skip_button" = "saltar esta pregunta"; +/* The placeholder string contains onboarding_use_case_skip_button as a tappable action */ +"onboarding_use_case_not_sure_yet" = "¿Todavía no lo sabes? Puedes %@"; +"onboarding_use_case_community_messaging" = "Comunidades"; +"onboarding_use_case_work_messaging" = "Equipos"; +"onboarding_use_case_personal_messaging" = "Familia y amigos"; +"onboarding_use_case_message" = "Te vamos a ayudar a conectarte."; +"onboarding_use_case_title" = "¿Con quién vas a hablar más?"; +"onboarding_splash_page_4_message" = "Element también funciona genial en el trabajo. Usado por algunas de las organizaciones más seguras."; +"onboarding_splash_page_4_title_no_pun" = "Mensajería para tu equipo."; +"onboarding_splash_page_3_message" = "Cifrado de extremo a extremo, y no hace falta que nos des tu número de móvil. Sin anuncios ni minería de datos."; +"onboarding_splash_page_3_title" = "Mensajería segura."; +"onboarding_splash_page_2_message" = "Decide cómo quieres guardar tus conversaciones, te damos el control y la independencia. Gracias a Matrix."; +"onboarding_splash_page_2_title" = "Tú mandas."; +"onboarding_splash_page_1_message" = "Comunicación segura e independiente que te ofrece el mismo nivel de privacidad que las conversaciones en persona dentro de tu casa."; +"onboarding_splash_page_1_title" = "Toma el control de tus conversaciones."; +"onboarding_splash_login_button_title" = "Ya tengo cuenta"; + +// Onboarding +"onboarding_splash_register_button_title" = "Crear una cuenta"; +"accessibility_button_label" = "botón"; +"done" = "Terminado"; +"open" = "Abrir"; +"joined" = "Se unió"; +"enable" = "Activar"; +"space_home_show_all_rooms" = "Mostrar todas las salas"; +"store_full_description" = "Element es un nuevo tipo de aplicación de mensajería y colaboración que:\n\n1. Te pone al mando, para que puedas proteger tu privacidad\n2. Te permite comunicarte con cualquiera en la red Matrix, y hasta fuera de ella, integrándose con aplicaciones como Slack\n3. Te protege delos anuncios, minería de datos, puertas traseras y «jardines vallados»\n4. Protege tus mensajes gracias al cifrado de extremo a extremo, con firma cruzada para verificar a otras personas\n\nElement es una aplicación de mensajería y colaboración completamente distinta al resto, porque es descentralizada y de código abierto.\n\nCon Element, puedes usar tu propio servidor (o elegir un alojamiento), de manera que disfrutes de privacidad, los datos y conservaciones sean realmente tu propiedad y bajo tu control. Te da acceso a una red abierta, para que puedas hablar incluso con gente que no use Element. Y es muy seguro.\n\nElement puede hacer todo esto porque por debajo funciona gracias a Matrix: el estándar para comunicaciones abiertas y descentralizadas.\n\nElement te pone al mando, permitiéndote elegir quién aloja tus conversaciones. Desde la aplicación de Element puedes elegir entre varias opciones dónde alojar:\n\n1. Registra una cuenta gratis en el servidor público matrix.org\n2. Usa tu propio servidor para registrar tu cuenta\n3. Simplemente suscríbete a la plataforma de Element Matrix Services para crear una cuenta en un servidor personalizado\n\n¿Por qué elegir Element?\n\nTUS DATOS, TU PROPIEDAD: Decide dónde guardar tus datos y mensajes. Son tuyos, y tú los controlas, en lugar de que una MEGAEMPRESA que los exprime o da acceso a terceros.\n\nMENSAJERÍA Y COLABORACIÓN ABIERTAS: Puedes hablar con el resto de personas en la red Matrix, usen Element o cualquier otra aplicación de Matrix. Incluso si usan otro sistema de mensajería como Slack, IRC o XMPP.\n\nSUPERSEGURO: Cifrado de extremo a extremo real (solo quienes participen en la conversación pueden descifrar los mensajes), y firma cruzada para verificar los dispositivos de los participantes en la conversación.\n\nCOMUNICACIÓN COMPLETA: Texto, llamadas de voz y vídeo, comparte archivos, comparte tu pantalla y un montón de integraciones, bots y accesorios. Crea salas, comunidades, mantén el contacto y lleva las cosas a cabo. \n\nESTÉS DONDE ESTÉS: Mantén el contacto estés dond estés gracias a que los mensajes y el historial se sincroniza entre todos tus dispositivos y hasta la web https://element.io/app."; +"secrets_setup_recovery_passphrase_additional_information" = "No uses la contraseña de tu cuenta de Matrix."; + +// Success from passphrase +"key_backup_setup_success_from_passphrase_info" = "Se está creando una copia de seguridad de tus claves.\n\nTus claves de seguridad son como tu red de protección: las puedes usar para recuperar el acceso a tus mensajes cifrados si te olvidas de la frase secreta.\n\nMantén tu clave de seguridad en un lugar seguro, como un gestor de contraseñas (o una caja fuerte)."; +"security_settings_crosssigning_info_ok" = "La firma cruzada está lista para ser usada."; +"notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "Has hecho los mensajes futuros visibles a todos los miembros, desde el momento en el que se unieron."; +"notice_room_history_visible_to_members_from_joined_point_by_you" = "Has hecho el futuro historial de la sala visible a todos los miembros, desde el momento en el que se unieron."; +"notice_room_history_visible_to_members_from_invited_point_by_you_for_dm" = "Has hecho los mensajes futuros visibles para todos, desde que fueron invitados."; +"notice_room_history_visible_to_members_from_invited_point_by_you" = "Has hecho el historial futuro de la sala visible para todos los miembros, desde el momento en el que fueron invitados."; +"call_ringing" = "Llamando…"; +"call_holded" = "Has puesto en espera la llamada"; +"call_remote_holded" = "%@ te ha puesto en espera"; +"call_video_with_user" = "Llamada de vídeo con %@"; +"call_voice_with_user" = "Llamada de voz con %@"; +"call_more_actions_dialpad" = "Teclado numérico"; +"call_more_actions_transfer" = "Transferir"; +"call_more_actions_audio_use_device" = "Altavoz del dispositivo"; +"call_more_actions_change_audio_device" = "Cambiar dispositivo de audio"; +"call_more_actions_unhold" = "Volver a la llamada"; +"call_more_actions_hold" = "Poner en espera"; +"call_consulting_with_user" = "Consultando con %@"; +"call_transfer_to_user" = "Transferir a %@"; +"notice_room_history_visible_to_members_by_you_for_dm" = "Has hecho que los mensajes a partir de ahora sean visibles por todos los miembros."; +"notice_room_history_visible_to_members_by_you" = "Has hecho el historial de la sala visible a partir de ahora."; +"notice_room_history_visible_to_anyone_by_you" = "Has hecho el historial de la sala visible para todo el mundo."; +"notice_redaction_by_you" = "Has borrado un evento (id: %@)"; +"notice_encryption_enabled_unknown_algorithm_by_you" = "Has activado el cifrado (algoritmo no reconocido %@)."; +"notice_encryption_enabled_ok_by_you" = "Has activado el cifrado de extremo a extremo."; +"notice_room_created_by_you_for_dm" = "Te has unido."; +"notice_room_created_by_you" = "Has creado y configurado la sala."; +"notice_profile_change_redacted_by_you" = "Has actualizado tu perfil %@"; +"notice_event_redacted_by_you" = " por ti"; +"notice_room_topic_removed_by_you" = "Has quitado el asunto"; +"notice_room_name_removed_by_you_for_dm" = "Has quitado el nombre"; +"notice_room_name_removed_by_you" = "Has quitado el nombre de la sala"; +"notice_conference_call_request_by_you" = "Has solicitado una conferencia VoIP"; +"notice_declined_video_call_by_you" = "Has rechazado la llamada"; +"notice_ended_video_call_by_you" = "Has terminado la llamada"; +"notice_answered_video_call_by_you" = "Has respondido a la llamada"; +"notice_placed_video_call_by_you" = "Has iniciado una videollamada"; +"notice_placed_voice_call_by_you" = "Has iniciado una llamada de voz"; +"notice_room_name_changed_by_you_for_dm" = "Has cambiado el nombre a %@."; +"notice_room_name_changed_by_you" = "Has cambiado el nombre de la sala a %@."; +"notice_topic_changed_by_you" = "Has cambiado el asunto a «%@»."; +"notice_display_name_removed_by_you" = "Has quitado tu nombre público"; +"notice_display_name_changed_from_by_you" = "Has cambiado tu nombre público de %@ a %@"; +"notice_display_name_set_by_you" = "Has cambiado tu nombre público a %@"; +"notice_avatar_url_changed_by_you" = "Has cambiado tu avatar"; +"notice_room_withdraw_by_you" = "Has anulado la invitación de %@"; +"notice_room_ban_by_you" = "Has vetado a %@"; +"notice_room_unban_by_you" = "Has quitado el veto a %@"; +"notice_room_kick_by_you" = "Has sacado a %@"; +"notice_room_reject_by_you" = "Has rechazado la invitación"; +"notice_room_leave_by_you" = "Te has salido"; +"notice_room_join_by_you" = "Te has unido"; +"notice_room_third_party_revoked_invite_by_you_for_dm" = "Has borrado la invitación de %@"; +"notice_room_third_party_revoked_invite_by_you" = "Has borrado la invitación a la sala de %@"; +"notice_room_third_party_registered_invite_by_you" = "Has aceptado la invitación de %@"; +"notice_room_third_party_invite_by_you_for_dm" = "Has invitado a %@"; +"notice_room_third_party_invite_by_you" = "Has enviado una invitación a la sala a %@"; +"notice_room_invite_you" = "%@ te invitó"; + +// Notice Events with "You" +"notice_room_invite_by_you" = "Has invitado a %@"; +"notice_declined_video_call" = "%@ rechazó la llamada"; +"notice_room_name_changed_for_dm" = "%@ cambió su nombre a %@."; +"notice_room_third_party_revoked_invite_for_dm" = "%@ borró la invitación de %@"; +"notice_room_third_party_invite_for_dm" = "%@ invitó a %@"; +"microphone_access_not_granted_for_voice_message" = "Para los mensajes de voz, hace falta acceso al micrófono. Sin embargo, %@ no tiene permisos para acceder"; +"e2e_passphrase_too_short" = "Frase secreta demasiado corta (debe ser de al menos %d caracteres)"; +"attachment_unsupported_preview_message" = "Este tipo de archivo no es compatible."; +"attachment_unsupported_preview_title" = "No se ha podido generar una vista previa"; +"attachment_large_with_resolution" = "Grande %@ (~%@)"; +"attachment_medium_with_resolution" = "Mediano %@ (~%@)"; +"attachment_small_with_resolution" = "Pequeño %@ (~%@)"; +"message_reply_to_sender_sent_their_location" = "compartió su ubicación."; +"notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ hizo los mensajes enviados en el futuro visibles a todo el mundo, pero solo desde que se unieron a la sala."; +"notice_room_history_visible_to_members_from_invited_point_for_dm" = "%@ hizo los mensajes enviados en el futuro visibles a todo el mundo, pero solo desde el momento en el que fueron invitados."; +"notice_room_history_visible_to_members_for_dm" = "%@ hizo que los mensajes desde este momento sean visibles para todos los miembros."; +"notice_error_unformattable_event" = "** No se ha podido mostrar el mensaje. Por favor, avísanos del fallo"; +"notice_room_aliases_for_dm" = "Los sinónimos son: %@"; +"notice_room_power_level_intro_for_dm" = "El nivel de poder del os miembros es:"; +"notice_room_join_rule_invite_by_you_for_dm" = "Has hecho que haga falta invitación para unirse a la sala."; +"location_sharing_settings_toggle_title" = "Activar compartir ubicación"; +"location_sharing_settings_header" = "Compartir ubicación"; +"location_sharing_open_open_street_maps" = "Abrir en OpenStreetMap"; +"location_sharing_open_google_maps" = "Abrir en Google Maps"; +"location_sharing_open_apple_maps" = "Abrir en Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Ajustes"; +"location_sharing_invalid_authorization_not_now" = "Ahora no"; +"location_sharing_invalid_authorization_error_title" = "%@ no tiene permiso para acceder a tu ubicación. Puedes activarlo en Ajustes > Ubicación"; +"location_sharing_locating_user_error_title" = "%@ no ha podido acceder tu ubicación. Inténtalo de nuevo más tarde."; +"location_sharing_loading_map_error_title" = "%@ no ha podido cargar el mapa. Inténtalo de nuevo más tarde."; +"location_sharing_post_failure_subtitle" = "%@ no ha podido enviar tu ubicación. Inténtalo de nuevo más tarde."; +"location_sharing_post_failure_title" = "No hemos podido enviar tu ubicación"; +"biometrics_cant_unlocked_alert_message_login" = "Volver a iniciar sesión"; +"biometrics_cant_unlocked_alert_message_x" = "Para desbloquear, usa %@ o vuelve a iniciar sesión y vuelve a activar %@"; +"biometrics_cant_unlocked_alert_title" = "No se ha podido desbloquear la aplicación"; +"biometrics_usage_reason" = "Identifícate para acceder a la aplicación"; +"biometrics_desetup_disable_button_title_x" = "Desactivar %@"; +"biometrics_desetup_title_x" = "Desactivar %@"; +"biometrics_setup_subtitle" = "Ahorra tiempo"; +"biometrics_setup_enable_button_title_x" = "Activar %@"; +"biometrics_setup_title_x" = "Activar %@"; +"biometrics_settings_enable_x" = "Activar %@"; +"biometrics_mode_face_id" = "Face ID"; + +// MARK: - Biometrics Protection + +"biometrics_mode_touch_id" = "Touch ID"; +"pin_protection_kick_user_alert_message" = "Demasiados errores, hemos cerrado tu sesión"; +"pin_protection_explanatory" = "Tener un código PIN te permite proteger datos como tus mensajes y contactos, para que solo tú puedas acceder a ellos. Te pediremos el código PIN cuando abras la aplicación."; +"pin_protection_not_allowed_pin" = "Por motivos de seguridad, no puedes usar este código PIN. Intenta con otro código"; +"pin_protection_settings_change_pin" = "Cambiar código PIN"; +"pin_protection_settings_enable_pin" = "Activar código PIN"; +"pin_protection_settings_enabled_forced" = "Código PIN activado"; +"pin_protection_settings_section_footer" = "Para restablecer tu código PIN, tienes que volver a iniciar sesión y crear uno nuevo."; +"pin_protection_settings_section_header_with_biometrics" = "PIN y %@"; +"pin_protection_settings_section_header" = "PIN"; +"pin_protection_mismatch_too_many_times_error_message" = "Si no te acuerdas de tu PIN, dale a «He olvidado mi PIN»."; +"pin_protection_mismatch_error_message" = "Inténtalo de nuevo"; +"pin_protection_mismatch_error_title" = "Los códigos PIN no coinciden"; +"pin_protection_reset_alert_action_reset" = "Restablecer"; +"pin_protection_reset_alert_message" = "Para restablecer tu PIN, tienes que cerrar sesión y volver a abrirla, y entonces podrás crear uno nuevo"; +"pin_protection_reset_alert_title" = "Restablecer PIN"; +"pin_protection_forgot_pin" = "He olvidado mi PIN"; +"pin_protection_enter_pin" = "Escribe tu PIN"; +"pin_protection_confirm_pin_to_change" = "Confirma el PIN para cambiarlo"; +"pin_protection_confirm_pin_to_disable" = "Confirma el PIN para desactivarlo"; +"pin_protection_confirm_pin" = "Confirma tu PIN"; +"pin_protection_choose_pin" = "Crea un PIN para mayor seguridad"; + +// MARK: - PIN Protection + +"pin_protection_choose_pin_welcome_after_login" = "Hola de nuevo."; +"pin_protection_choose_pin_welcome_after_register" = "Te damos la bienvenida."; +"major_update_done_action" = "Vale"; +"major_update_learn_more_action" = "Más información"; +"major_update_information" = "¡Nos alegra anunciar que hemos cambiado nuestro nombre! Tu aplicación está actualizada, y sigues con la sesión iniciada en tu cuenta."; + +// MARK: - Major update + +"major_update_title" = "Riot ahora es %@"; +"cross_signing_setup_banner_subtitle" = "Verifica tus otros dispositivos de forma más fácil"; + +// MARK: - Cross-signing + +// Banner + +"cross_signing_setup_banner_title" = "Configurar cifrado"; +"secrets_reset_authentication_message" = "Escribe la contraseña de tu cuenta de Matrix para confirmar"; +"secrets_reset_reset_action" = "Restablecer"; +"secrets_reset_warning_message" = "Volverás a empezar sin historial, sin mensajes y sin dispositivos ni usuarios marcados como de confianza."; +"secrets_reset_warning_title" = "Si restableces todo"; +"secrets_reset_information" = "Haz esto solo si no te queda ningún otro dispositivo con el que puedas verificar este."; + +// MARK: - Secrets reset + +"secrets_reset_title" = "Restablecer todo"; +"secrets_setup_recovery_passphrase_summary_information" = "Memoriza tu frase de seguridad. Puede ser usada para desbloquear tus mensajes y datos cifrados."; + + +"secrets_setup_recovery_passphrase_summary_title" = "Guarda tu frase de seguridad"; +"secrets_setup_recovery_passphrase_confirm_passphrase_placeholder" = "Confirma la frase"; +"secrets_setup_recovery_passphrase_confirm_information" = "Vuelve a escribir tu frase de seguridad una vez más para confirmarla."; +"secrets_setup_recovery_passphrase_confirm_passphrase_title" = "Confirmar"; +"secrets_setup_recovery_key_done_action" = "Terminar"; +"secrets_setup_recovery_passphrase_validate_action" = "Terminar"; +"secrets_setup_recovery_passphrase_information" = "Escribe una frase segura que solo tú conozcas, servirá para guardar datos secretos en tu servidor."; + +// Recovery passphrase + +"secrets_setup_recovery_passphrase_title" = "Configura una frase de seguridad"; +"secrets_setup_recovery_key_storage_alert_message" = "✓ Imprímela y ponla en un lugar seguro\n✓ Guárdala en un USB o en un disco de copias de seguridad\n✓ Cópiala a tu almacenamiento privado en la nube"; +"secrets_setup_recovery_key_storage_alert_title" = "Guárdala bien"; +"secrets_setup_recovery_key_export_action" = "Guardar"; +"secrets_setup_recovery_key_loading" = "Cargando…"; +"secrets_setup_recovery_key_information" = "Almacena tu clave de seguridad en un sitio seguro. Puede ser usada para desbloquear tus mensajes y datos cifrados."; + +// MARK: - Secrets set up + +// Recovery Key + +"secrets_setup_recovery_key_title" = "Guarda tu clave de seguridad"; +"secrets_recovery_with_key_invalid_recovery_key_message" = "Por favor, comprueba que hayas puesto la clave de seguridad correcta."; +"secrets_recovery_with_key_invalid_recovery_key_title" = "No ha sido posible acceder al almacenamiento seguro"; +"secrets_recovery_with_key_recover_action" = "Usar clave"; +"secrets_recovery_with_key_recovery_key_placeholder" = "Escribe tu clave de seguridad"; +"secrets_recovery_with_key_recovery_key_title" = "Introducir"; +"secrets_recovery_with_key_information_unlock_secure_backup_with_key" = "Escribe tu clave de seguridad para continuar."; +"secrets_recovery_with_key_information_unlock_secure_backup_with_phrase" = "Escribe tu frase de seguridad para continuar."; +"secrets_recovery_with_key_information_verify_device" = "Usa tu clave de seguridad para verificar este dispositivo."; +"secrets_recovery_with_key_information_default" = "Escribe tu clave de seguridad para acceder a tu historial de mensajes seguros y a tu identidad de firma cruzada para verificar otras sesiones."; +"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "usar tu clave de seguridad"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "¿No te acuerdas de tu frase de seguridad? Puedes "; +"secrets_recovery_with_passphrase_passphrase_placeholder" = "Escribe tu frase de seguridad"; +"secrets_recovery_with_passphrase_information_verify_device" = "Usa tu frase de seguridad para verificar este dispositivo."; +"secrets_recovery_with_passphrase_information_default" = "Escribe tu frase de seguridad para acceder a tu historial de mensajes seguros y a tu identidad de firma cruzada para verificar otras sesiones."; + +// Recover with key + +"secrets_recovery_with_key_title" = "Clave de seguridad"; +"secrets_recovery_with_passphrase_invalid_passphrase_message" = "Por favor, asegúrate de que has puesto la frase de seguridad correcta."; +"secrets_recovery_with_passphrase_invalid_passphrase_title" = "No ha sido posible acceder al almacenamiento seguro"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part3" = "."; +"secrets_recovery_with_passphrase_recover_action" = "Usar frase"; +"secrets_recovery_with_passphrase_passphrase_title" = "Introducir"; + +// Recover with passphrase + +"secrets_recovery_with_passphrase_title" = "Frase de seguridad"; + +// MARK: - Secrets recovery + +"secrets_recovery_reset_action_part_1" = "¿No tienes acceso a ningún método de recuperación? "; +"secrets_recovery_reset_action_part_2" = "Restablecer todo"; +"user_verification_session_details_verify_action_other_user" = "Verificar manualmente"; +"user_verification_session_details_verify_action_current_user_manually" = "Verificar manualmente con un texto"; +"user_verification_session_details_verify_action_current_user" = "Verificar de forma interactiva"; +"user_verification_session_details_additional_information_untrusted_current_user" = "Si no has iniciado esta sesión, puede que alguien más tenga acceso a tu cuenta."; +"user_verification_session_details_additional_information_untrusted_other_user" = "Hasta que este usuario confíe en esta sesión, los mensajes que le envíes y recibas de él irán acompañados de un aviso. También puedes verificarla manualmente."; +"user_verification_session_details_information_untrusted_other_user" = " inició una nueva sesión:"; +"user_verification_session_details_information_untrusted_current_user" = "Verifica esta sesión para marcarla como «de confianza» y darle acceso a tus mensajes cifrados:"; +"user_verification_session_details_information_trusted_other_user_part2" = " la ha verificado:"; +"user_verification_session_details_information_trusted_other_user_part1" = "Confías en esta sesión para mensajería segura porque "; +"user_verification_session_details_information_trusted_current_user" = "Confías en esta sesión para mensajería segura porque la has verificado:"; +"user_verification_session_details_untrusted_title" = "No es de confianza"; + +// Session details + +"user_verification_session_details_trusted_title" = "De confianza"; +"user_verification_sessions_list_session_untrusted" = "No es de confianza"; +"user_verification_sessions_list_session_trusted" = "De confianza"; +"user_verification_sessions_list_table_title" = "Sesiones"; +"user_verification_sessions_list_information" = "Los mensajes con este usuario en esta sala están cifrados de extremo a extremo, y no pueden ser leídos por terceros."; +"user_verification_sessions_list_user_trust_level_unknown_title" = "Desconocido"; +"user_verification_sessions_list_user_trust_level_warning_title" = "Advertencia"; + +// Sessions list + +"user_verification_sessions_list_user_trust_level_trusted_title" = "De confianza"; +"user_verification_start_additional_information" = "Para mayor seguridad, haz esto en persona o usa otra forma para comunicarte mientras lo haces."; +"user_verification_start_waiting_partner" = "Esperando a %@…"; +"user_verification_start_information_part2" = " comprobando el código único en los dos dispositivos."; +"user_verification_start_information_part1" = "Para más seguridad, verifica "; + +// MARK: - User verification + +// Start + +"user_verification_start_verify_action" = "Empezar verificación"; +"key_verification_scan_confirmation_scanned_device_information" = "¿Le aparece al otro dispositivo el mismo icono de escudo?"; +"key_verification_scan_confirmation_scanned_user_information" = "¿Le aparece el mismo icono de escudo a %@?"; + +// Scanned +"key_verification_scan_confirmation_scanned_title" = "¡Ya casi está!"; +"key_verification_scan_confirmation_scanning_device_waiting_other" = "Esperando al otro dispositivo…"; +"key_verification_scan_confirmation_scanning_user_waiting_other" = "Esperando a %@…"; + +// MARK: Scan confirmation + +// Scanning +"key_verification_scan_confirmation_scanning_title" = "¡Ya casi está! Esperando confirmación…"; +"key_verification_verify_qr_code_scan_other_code_success_message" = "El código QR ha sido validado."; +"key_verification_verify_qr_code_scan_other_code_success_title" = "¡Código validado!"; +"key_verification_verify_qr_code_other_scan_my_code_title" = "¿Ha podido la otra persona escanear el código QR?"; +"key_verification_verify_qr_code_start_emoji_action" = "Verificar con emojis"; +"key_verification_verify_qr_code_cannot_scan_action" = "¿No puedes escanear?"; +"key_verification_verify_qr_code_scan_code_other_device_action" = "Escanea con este dispositivo"; +"key_verification_verify_qr_code_scan_code_action" = "Escanea el otro código"; +"key_verification_verify_qr_code_emoji_information" = "Verificar comparando emojis."; +"key_verification_verify_qr_code_information_other_device" = "Escanea el siguiente código para verificar:"; +"key_verification_verify_qr_code_information" = "Escanea el código para verificar de forma segura."; + +// MARK: QR code + +"key_verification_verify_qr_code_title" = "Verificar con la cámara"; + +// Incoming key verification request + +"key_verification_incoming_request_incoming_alert_message" = "%@ quiere verificar"; +"key_verification_tile_conclusion_warning_title" = "Inicio de sesión sin verificar"; +"key_verification_tile_conclusion_done_title" = "Verificada"; +"key_verification_tile_request_incoming_approval_decline" = "Rechazar"; +"key_verification_tile_request_incoming_approval_accept" = "Aceptar"; +"key_verification_tile_request_status_accepted" = "Has aceptado"; +"key_verification_tile_request_status_cancelled" = "%@ ha cancelado"; +"key_verification_tile_request_status_cancelled_by_me" = "Has cancelado"; +"key_verification_tile_request_status_expired" = "Caducada"; +"key_verification_tile_request_status_waiting" = "Esperando…"; +"key_verification_tile_request_status_data_loading" = "Cargando datos…"; +"key_verification_tile_request_outgoing_title" = "Verificación enviada"; + +// Tiles + +"key_verification_tile_request_incoming_title" = "Solicitud de verificación"; +"key_verification_bootstrap_not_setup_message" = "Debes terminar la configuración iniciar de la firma cruzada."; + +// MARK: - Key Verification + +"key_verification_bootstrap_not_setup_title" = "Error"; +"error_not_supported_on_mobile" = "No puedes hacer esto desde la versión móvil de %@."; + + +// Generic errors +"error_invite_3pid_with_no_identity_server" = "Añade un servidor de identidad en ajustes para invitar por correo."; + +// MARK: Reaction history +"reaction_history_title" = "Reacciones"; +"emoji_picker_flags_category" = "Banderas"; +"emoji_picker_symbols_category" = "Símbolos"; +"emoji_picker_objects_category" = "Objetos"; +"emoji_picker_places_category" = "Viajes y lugares"; +"emoji_picker_activity_category" = "Actividades"; +"emoji_picker_foods_category" = "Comida y bebida"; +"emoji_picker_nature_category" = "Animales y naturaleza"; +"emoji_picker_people_category" = "Caras y personas"; + +// MARK: Emoji picker +"emoji_picker_title" = "Reacciones"; +"file_upload_error_unsupported_file_type_message" = "Tipo de archivo no compatible."; + +// MARK: File upload +"file_upload_error_title" = "Enviar archivo"; +"device_verification_emoji_pin" = "Chincheta"; +"device_verification_emoji_folder" = "Carpeta"; +"device_verification_emoji_headphones" = "Cascos"; +"device_verification_emoji_anchor" = "Ancla"; +"device_verification_emoji_bell" = "Campana"; +"device_verification_emoji_trumpet" = "Trompeta"; +"device_verification_emoji_guitar" = "Guitarra"; +"device_verification_emoji_ball" = "Bola"; +"device_verification_emoji_trophy" = "Trofeo"; +"device_verification_emoji_rocket" = "Cohete"; +"device_verification_emoji_aeroplane" = "Avión"; +"device_verification_emoji_bicycle" = "Bicicleta"; +"device_verification_emoji_train" = "Tren"; +"device_verification_emoji_flag" = "Bandera"; +"device_verification_emoji_telephone" = "Teléfono"; +"device_verification_emoji_hammer" = "Martillo"; +"device_verification_emoji_key" = "Llave"; +"device_verification_emoji_lock" = "Candado"; +"device_verification_emoji_scissors" = "Tijeras"; +"device_verification_emoji_paperclip" = "Clip"; +"device_verification_emoji_pencil" = "Pintura"; +"device_verification_emoji_book" = "Libro"; +"device_verification_emoji_light bulb" = "Bombilla"; +"device_verification_emoji_gift" = "Regalo"; +"device_verification_emoji_clock" = "Reloj"; +"device_verification_emoji_hourglass" = "Reloj de arena"; +"device_verification_emoji_umbrella" = "Paraguas"; +"device_verification_emoji_thumbs up" = "Pulgar arriba"; +"device_verification_emoji_santa" = "Papá Noel"; +"device_verification_emoji_spanner" = "Llave inglesa"; +"device_verification_emoji_glasses" = "Gafas"; +"device_verification_emoji_hat" = "Sombrero"; +"device_verification_emoji_robot" = "Robot"; +"device_verification_emoji_smiley" = "Sonrisa"; +"device_verification_emoji_heart" = "Corazón"; +"device_verification_emoji_cake" = "Tarta"; +"device_verification_emoji_pizza" = "Pizza"; +"device_verification_emoji_corn" = "Maíz"; +"device_verification_emoji_strawberry" = "Fresa"; +"device_verification_emoji_apple" = "Manzana"; +"device_verification_emoji_banana" = "Plátano"; +"device_verification_emoji_fire" = "Fuego"; +"device_verification_emoji_cloud" = "Nube"; +"device_verification_emoji_moon" = "Luna"; +"device_verification_emoji_globe" = "La Tierra"; +"device_verification_emoji_mushroom" = "Champiñón"; +"device_verification_emoji_cactus" = "Cactus"; +"device_verification_emoji_tree" = "Árbol"; +"device_verification_emoji_flower" = "Flor"; +"device_verification_emoji_butterfly" = "Mariposa"; +"device_verification_emoji_octopus" = "Pulpo"; +"device_verification_emoji_fish" = "Pez"; +"device_verification_emoji_turtle" = "Tortuga"; +"device_verification_emoji_penguin" = "Pingüino"; +"device_verification_emoji_rooster" = "Gallo"; +"device_verification_emoji_panda" = "Oso panda"; +"device_verification_emoji_rabbit" = "Conejo"; +"device_verification_emoji_elephant" = "Elefante"; +"device_verification_emoji_pig" = "Cerdo"; +"device_verification_emoji_unicorn" = "Unicorno"; +"device_verification_emoji_horse" = "Caballo"; +"device_verification_emoji_lion" = "León"; +"device_verification_emoji_cat" = "Gato"; + +// MARK: Emoji +"device_verification_emoji_dog" = "Perro"; + +// User + +"key_verification_verified_user_information" = "Los mensajes que mandes y recibas de este usuario están cifrados de extremo a extremo, por lo que nadie más podrá leerlos."; +"key_verification_verified_this_session_information" = "Ahora puedes leer los mensajes seguros en este dispositivo, y otros usuarios sabrán que es de confianza."; +"key_verification_verified_new_session_information" = "Ahora puedes leer los mensajes seguros en tu nuevo dispositivo, y otros usuarios sabrán que es de confianza."; +"key_verification_verified_other_session_information" = "Ya puedes leer los mensajes cifrados en la otra sesión, y otros usuarios sabrán que es de confianza."; +"key_verification_verified_new_session_title" = "¡Nueva sesión verificada!"; +"device_verification_verified_got_it_button" = "Vale"; + +// MARK: Verified + +// Device + +"device_verification_verified_title" = "¡Verificada!"; + +// Device + +"device_verification_verify_wait_partner" = "Esperando a que la otra parte confirme…"; +"key_verification_manually_verify_device_validate_action" = "Verificar"; +"key_verification_manually_verify_device_additional_information" = "Si no coinciden, la seguridad de la comunicación podría estar comprometida."; +"key_verification_manually_verify_device_key_title" = "Clave de la sesión"; +"key_verification_manually_verify_device_id_title" = "ID de la sesión"; +"key_verification_manually_verify_device_name_title" = "Nombre de la sesión"; +"key_verification_manually_verify_device_instruction" = "Confirma comparando el siguiente texto con el que verás en los ajustes en tu otra sesión:"; + +// MARK: Manually Verify Device + +"key_verification_manually_verify_device_title" = "Verificar manualmente con un texto"; +"key_verification_verify_sas_additional_information" = "Para más seguridad todavía, usa otro método de comunicación de confianza o verifícalo en persona."; +"key_verification_verify_sas_validate_action" = "Coinciden"; +"key_verification_verify_sas_cancel_action" = "No coinciden"; +"key_verification_verify_sas_title_number" = "Comparar números"; + +// MARK: Verify + +"key_verification_verify_sas_title_emoji" = "Comparar emojis"; +"device_verification_self_verify_wait_recover_secrets_checking_availability" = "Comprobando otros métodos de verificación…"; +"device_verification_self_verify_wait_recover_secrets_additional_information" = "So no tienes acceso a ninguna otra sesión"; +"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Usar clave o frase de seguridad"; +"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Usar clave de seguridad"; +"device_verification_self_verify_wait_additional_information" = "Esto funciona en %@ y otras aplicaciones de Matrix que hagan firma cruzada."; +"device_verification_self_verify_wait_information" = "Verifica esta sesión desde otro sitio donde hayas iniciado sesión antes para recibir acceso a tus mensajes cifrados.\n\nUsa la última versión de %@ en tu otros dispositivos:"; +"device_verification_self_verify_wait_new_sign_in_title" = "Verifica este inicio de sesión"; + +// MARK: Self verification wait + +"device_verification_self_verify_wait_title" = "Completar proceso de seguridad"; +"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Revisar"; +"key_verification_self_verify_unverified_sessions_alert_message" = "Verifica todas tus sesiones para asegurarte de que tu cuenta y tus mensajes están a salvo."; + +// Unverified sessions + +"key_verification_self_verify_unverified_sessions_alert_title" = "Revisa dónde has iniciado sesión"; +"key_verification_self_verify_current_session_alert_validate_action" = "Verificar"; +"key_verification_self_verify_current_session_alert_message" = "Puede que otras personas no confíen en la sesión."; + +// Current session + +"key_verification_self_verify_current_session_alert_title" = "Verifica esta sesión"; +"device_verification_self_verify_start_waiting" = "Esperando…"; +"device_verification_self_verify_start_information" = "Usa esta sesión para verificar la nueva, dándole acceso a tus mensajes cifrados."; +"device_verification_self_verify_start_verify_action" = "Empezar la verificación"; +"device_verification_self_verify_alert_validate_action" = "Verificar"; +"device_verification_self_verify_alert_message" = "Verifica el nuevo inicio de sesión de tu cuenta: %@"; + +// MARK: Self verification start + +// New login +"device_verification_self_verify_alert_title" = "Nuevo inicio de sesión. ¿Has sido tú?"; +"device_verification_start_use_legacy_action" = "Usar verificación antigua"; +"device_verification_start_verify_button" = "Empezar la verificación"; +"device_verification_start_use_legacy" = "¿No ocurre nada? Todavía hay aplicaciones que no son compatibles con la verificación interactiva. Usa la autenticación antigua."; +"device_verification_start_wait_partner" = "Esperando a que la otra parte acepte…"; + +// MARK: Start +"device_verification_start_title" = "Verifica comparando unos pocos caracteres"; +"device_verification_incoming_description_2" = "Si verificas esta sesión, la marcarás como «de confianza». También, otras personas que ya confíen en ti la marcarán como «de confianza»."; +"device_verification_incoming_description_1" = "Verifica esta sesión para marcarla como «de confianza». Confiar en las sesiones de tus conocidos permitirá hablar tranquilamente cuando uses el cifrado de extremo a extremo."; + +// Mark: Incoming +"device_verification_incoming_title" = "Nueva solicitud de verificación"; +"device_verification_error_cannot_load_device" = "No se ha podido cargar la información de la sesión."; +"device_verification_cancelled_by_me" = "La verificación ha sido cancelada. Motivo: %@"; +"device_verification_cancelled" = "La otra parte ha cancelado la verificación."; +"device_verification_security_advice_emoji" = "Compara los siguientes emojis. Asegúrate de que están en el mismo orden."; +"device_verification_security_advice_number" = "Compara los números. Asegúrate de que están en el mismo orden."; +"key_verification_user_title" = "Verificar usuario"; +"key_verification_this_session_title" = "Verifica esta sesión"; +"key_verification_new_session_title" = "Verifica tu nueva sesión"; + +// MARK: - Device Verification +"key_verification_other_session_title" = "Verificar sesión"; +"sign_out_key_backup_in_progress_alert_cancel_action" = "Esperar"; +"sign_out_key_backup_in_progress_alert_discard_key_backup_action" = "Ya no quiero mis mensajes cifrados"; +"sign_out_key_backup_in_progress_alert_title" = "Copia de seguridad de las claves en curso. Si cierras sesión ahora, perderás acceso a tus mensajes cifrados."; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_backup_action" = "Copia de seguridad"; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_sign_out_action" = "Cerrar sesión"; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_message" = "Perderás acceso a tus mensajes cifrados a menos que configures las copias de seguridad antes de cerrar sesión."; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_title" = "Perderás acceso a tus mensajes cifrados"; +"sign_out_non_existing_key_backup_alert_discard_key_backup_action" = "Ya no quiero mis mensajes cifrados"; +"sign_out_non_existing_key_backup_alert_setup_secure_backup_action" = "Configurar copia de seguridad"; +"sign_out_non_existing_key_backup_alert_title" = "Perderás acceso a tus mensajes cifrados si cierras sesión ahora"; +"sign_out_existing_key_backup_alert_sign_out_action" = "Cerrar sesión"; + +// MARK: Sign out warning + +"sign_out_existing_key_backup_alert_title" = "¿Seguro que quieres cerrar sesión?"; +"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "¿Has perdido tu clave de seguridad? Puedes configurar una nueva en ajustes."; +"key_backup_recover_done_action" = "Vale"; + +// Success + +"key_backup_recover_success_info" = "¡Copia de seguridad restaurada!"; +"key_backup_recover_from_recovery_key_recover_action" = "Desbloquear historial"; +"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "Introduce la clave de seguridad"; +"key_backup_recover_from_recovery_key_recovery_key_title" = "Introducir"; + +// Recover from recovery key + +"key_backup_recover_from_recovery_key_info" = "Usa tu clave de seguridad para desbloquear tu historial de mensajes seguros"; +"key_backup_recover_from_passphrase_lost_passphrase_action_part3" = "."; +"key_backup_recover_from_passphrase_lost_passphrase_action_part2" = "usar tu clave de seguridad"; +"key_backup_recover_from_passphrase_lost_passphrase_action_part1" = "¿No sabes tu frase de seguridad? Puedes "; +"key_backup_recover_from_passphrase_recover_action" = "Desbloquear historial"; +"key_backup_recover_from_passphrase_passphrase_placeholder" = "Introduce la frase"; + +// Recover from passphrase + +"key_backup_recover_from_passphrase_info" = "Usa tu frase de seguridad para desbloquear el historial de mensajes seguros"; +"key_backup_recover_from_passphrase_passphrase_title" = "Introducir"; + +// Recover from private key +"key_backup_recover_from_private_key_info" = "Restaurando copia de seguridad…"; +"key_backup_recover_invalid_recovery_key" = "No ha sido posible descifrar la copia de seguridad con esta clave. Asegúrate de que la que has introducido es correcta."; +"key_backup_recover_invalid_recovery_key_title" = "La clave de seguridad no coincide"; +"key_backup_recover_invalid_passphrase" = "No ha sido posible descifrar la copia de seguridad con esta frase. Asegúrate de que la que has introducido es correcta."; +"key_backup_recover_invalid_passphrase_title" = "Frase de seguridad incorrecta"; + +// MARK: Key backup recover + +"key_backup_recover_title" = "Mensajes seguros"; + +// Success from secure backup +"key_backup_setup_success_from_secure_backup_info" = "Se están creando copias de seguridad de tus claves."; +"key_backup_setup_success_from_recovery_key_made_copy_action" = "Ya la he copiado"; +"key_backup_setup_success_from_recovery_key_make_copy_action" = "Copiar"; +"key_backup_setup_success_from_recovery_key_recovery_key_title" = "Clave de seguridad"; + +// Success from recovery key +"key_backup_setup_success_from_recovery_key_info" = "Se está creando una copia de seguridad de tus claves.\n\nHaz una copia de esta clave de seguridad, y guárdala en un sitio seguro."; +"key_backup_setup_success_from_passphrase_done_action" = "Vale"; +"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "Guardar clave de seguridad"; + +// Success + +"key_backup_setup_success_title" = "¡Has terminado!"; +"key_backup_setup_passphrase_setup_recovery_key_action" = "(Avanzado) Configurar con clave de seguridad"; +"key_backup_setup_passphrase_setup_recovery_key_info" = "O protege tu copia de seguridad con una clave de seguridad, guardándola en un lugar seguro."; +"key_backup_setup_passphrase_set_passphrase_action" = "Elegir frase"; +"key_backup_setup_passphrase_confirm_passphrase_invalid" = "las frases no coinciden"; +"key_backup_setup_passphrase_confirm_passphrase_valid" = "¡Genial!"; +"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "Confirma la frase"; +"key_backup_setup_passphrase_confirm_passphrase_title" = "Confirmar"; +"key_backup_setup_passphrase_passphrase_invalid" = "Prueba a añadir una palabra"; +"key_backup_setup_passphrase_passphrase_valid" = "¡Muy bien!"; +"key_backup_setup_passphrase_passphrase_placeholder" = "Escribir frase"; +"key_backup_setup_passphrase_passphrase_title" = "Escribir"; +"key_backup_setup_passphrase_info" = "Guardaremos una copia cifrada de tus claves en nuestro servidor. Protege la copia de seguridad con una frase para mantenerla a salvo.\n\nPara mayor seguridad, debería ser distinta a la contraseña de tu cuenta de Matrix."; + +// Passphrase + +"key_backup_setup_passphrase_title" = "Protege tu copia de seguridad con una frase de seguridad"; +"key_backup_setup_intro_manual_export_action" = "Exportar claves manualmente"; +"key_backup_setup_intro_manual_export_info" = "(Avanzado)"; +"key_backup_setup_intro_setup_connect_action_with_existing_backup" = "Conecta este dispositivo a las copias de seguridad de claves"; +"key_backup_setup_intro_setup_action_without_existing_backup" = "Empezar a hacer copias de seguridad de las claves"; +"key_backup_setup_intro_info" = "Los mensajes en salas cifradas están protegidos con cifrado de extremo a extremo. Solo tú y los destinatarios tendréis las claves para leer estos mensajes.\n\nHaz una copia de seguridad de tus claves para evitar perderlas."; + +// Intro + +"key_backup_setup_intro_title" = "No pierdas nunca tus mensajes cifradoa"; +"key_backup_setup_skip_alert_skip_action" = "Saltar"; +"key_backup_setup_skip_alert_message" = "Podrías perder acceso a mensajes cifrados si cierras sesión o pierdes tu dispositivo."; +"key_backup_setup_skip_alert_title" = "¿Seguro?"; + + +// MARK: Key backup setup + +"key_backup_setup_title" = "Copia de seguridad de claves"; +"secure_backup_setup_banner_subtitle" = "Protégete frente a pérdidas de acceso a mensajes y datos cifrados"; + +// Banner + +"secure_backup_setup_banner_title" = "Copia de seguridad"; +"secure_key_backup_setup_cancel_alert_message" = "Si cancelas ahora, podrías perder mensajes y datos cifrados si dejas de tener acceso a tus otros inicios de sesión.\n\nTambién puedes configurar una copia de seguridad y gestionar tus claves en ajustes."; +"secure_key_backup_setup_existing_backup_error_info" = "Desbloquéala para volverla a usar en la copia de seguridad, o elimínala para crear una nueva copia de seguridad dentro."; + + +// Cancel + +"secure_key_backup_setup_cancel_alert_title" = "¿Seguro?"; +"secure_key_backup_setup_existing_backup_error_delete_it" = "Eliminar"; +"secure_key_backup_setup_existing_backup_error_unlock_it" = "Desbloquear"; +"secure_key_backup_setup_existing_backup_error_title" = "Ya existe una copia de seguridad de los mensajes"; +"secure_key_backup_setup_intro_use_security_passphrase_info" = "Escribe una frase secreta que solo tú conozcas, y generar una clave para la copia de seguridad."; +"secure_key_backup_setup_intro_use_security_passphrase_title" = "Usar una frase de seguridad"; +"secure_key_backup_setup_intro_use_security_key_info" = "Genera una clave de seguridad, que habitualmente se guarda en un lugar seguro como un gestor de contraseñas o una caja fuerte."; +"secure_key_backup_setup_intro_use_security_key_title" = "Usar una clave de seguridad"; +"secure_key_backup_setup_intro_info" = "Evita perder acceso a tus mensajes y datos cifrados creando una copia de seguridad de las claves de cifrado en tu servidor."; + +// MARK: Secure backup setup + +// Intro + +"secure_key_backup_setup_intro_title" = "Copia de seguridad"; +"service_terms_modal_information_description_integration_manager" = "Los gestores de integración te permiten añadir funcionalidades de terceros."; +"service_terms_modal_policy_checkbox_accessibility_hint" = "Marca para aceptar %@"; +"service_terms_modal_information_description_identity_server" = "Los servidores de identidad te ayudan a encontrar tus contactos buscando su número de teléfono o dirección de correo, para ver si tienen una cuenta."; +"service_terms_modal_information_title_integration_manager" = "Gestor de integraciones"; + +// Alert explaining what an identity server / integration manager is. +"service_terms_modal_information_title_identity_server" = "Servidor de identidad"; +"service_terms_modal_description_integration_manager" = "Esto te permitirá usar bots, puentes, accesorios y paquetes de pegatinas."; +"service_terms_modal_description_identity_server" = "Esto permitirá que la gente te encuentre a partir del número de teléfono o correo electrónico que tengan guardado en sus contactos."; +"service_terms_modal_table_header_integration_manager" = "TÉRMINOS DEL GESTOR DE INTEGRACIONES"; +"service_terms_modal_table_header_identity_server" = "TÉRMINOS DEL SERVIDOR DE IDENTIDAD"; +"service_terms_modal_footer" = "Puedes desactivarlo en cualquier momento desde ajustes."; +"service_terms_modal_decline_button" = "Rechazar"; +"service_terms_modal_accept_button" = "Aceptar"; + +// Service terms +"service_terms_modal_title_message" = "Para continuar, acepta los siguientes términos y condiciones"; +"location_sharing_share_action" = "Compartir"; +"location_sharing_close_action" = "Cerrar"; + +// MARK: - Location sharing + +"location_sharing_title" = "Ubicación"; +"poll_timeline_not_closed_subtitle" = "Inténtalo de nuevo"; +"poll_timeline_not_closed_title" = "Fallo al cerrar la encuesta"; +"poll_timeline_vote_not_registered_subtitle" = "Lo siento, tu voto no ha sido registrado. Inténtalo de nuevo"; +"poll_timeline_vote_not_registered_title" = "Voto no registrado"; +"poll_timeline_total_final_results" = "Resultados finales, basados en %lu votos"; +"poll_timeline_total_final_results_one_vote" = "Resultados finales, basados en 1 voto"; +"poll_timeline_total_votes_not_voted" = "%lu votos emitidos. Vota para ver los resultados"; +"poll_timeline_total_one_vote_not_voted" = "1 voto emitido. Vota para ver los resultados"; +"poll_timeline_total_votes" = "%lu votos emitidos"; +"poll_timeline_total_one_vote" = "1 voto emitido"; +"poll_timeline_total_no_votes" = "Todavía no ha votado nadie"; +"poll_timeline_votes_count" = "%lu votos"; +"poll_timeline_one_vote" = "1 voto"; +"poll_edit_form_poll_type_closed_description" = "Los resultados solo se conocerán cuando cierres la encuesta"; +"poll_edit_form_poll_type_closed" = "Encuesta cerrada"; +"poll_edit_form_poll_type_open_description" = "Los votantes podrán ver los resultados una vez seleccionen una opción"; +"poll_edit_form_poll_type_open" = "Encuesta abierta"; +"poll_edit_form_update_failure_subtitle" = "Inténtalo de nuevo"; +"poll_edit_form_update_failure_title" = "No se ha podido actualizar la encuesta"; +"poll_edit_form_post_failure_subtitle" = "Inténtalo de nuevo"; +"poll_edit_form_post_failure_title" = "No se ha podido enviar la encuesta"; +"poll_edit_form_add_option" = "Añadir otra opción"; +"poll_edit_form_option_number" = "Opción %lu"; +"poll_edit_form_create_options" = "Crear opciones"; +"poll_edit_form_input_placeholder" = "Escribe algo"; +"poll_edit_form_question_or_topic" = "Pregunta o asunto"; +"poll_edit_form_poll_question_or_topic" = "Pregunta o asunto de la encuesta"; +"poll_edit_form_poll_type" = "Tipo de encuesta"; + +// Mark: - Polls + +"poll_edit_form_create_poll" = "Crear encuesta"; +"version_check_modal_action_title_deprecated" = "Descubre cómo"; +"version_check_modal_title_deprecated" = "iOS %@ ya no es compatible"; +"version_check_modal_subtitle_deprecated" = "Hemos estado trabajando para mejorar %@, aumentando la velocidad y puliendo la experiencia. Por desgracia, tu versión actual de iOS no es compatible con algunos de estos arreglos, por lo que no funcionará bien.\nTe recomendamos que actualices tu sistema operativo para usar todas las funcionalidades de %@."; +"version_check_modal_action_title_supported" = "Vale"; +"version_check_modal_subtitle_supported" = "Hemos estado trabajando para mejorar %@, aumentando la velocidad y puliendo la experiencia. Por desgracia, tu versión actual de iOS no es compatible con algunos de estos arreglos, por lo que podría no funcionar bien.\nTe recomendamos que actualices tu sistema operativo para usar todas las funcionalidades de %@."; +"version_check_modal_title_supported" = "Vamos a dejar de funcionar en iOS %@"; +"version_check_banner_subtitle_deprecated" = "%@ ya no funciona en %@. Para seguir usando %@, te recomendamos que actualices tu versión de iOS."; +"version_check_banner_title_deprecated" = "iOS %@ ya no es compatible"; +"version_check_banner_subtitle_supported" = "Dentro de poco, %@ no funcionará en iOS %@. Para seguir usando %@ con todas las funcionalidades, te recomendamos que actualices tu versión de iOS."; + +// Mark: - Version check + +"version_check_banner_title_supported" = "Vamos a dejar de funcionar en iOS %@"; +"voice_message_lock_screen_placeholder" = "Mensaje de voz"; +"voice_message_stop_locked_mode_recording" = "Toca en tu grabación para escuchar y parar"; +"voice_message_remaining_recording_time" = "%@ salió"; + +// Mark: - Voice Messages + +"voice_message_release_to_send" = "Mantén para grabar, suelta para enviar"; +"side_menu_app_version" = "Versión %@"; +"side_menu_action_feedback" = "Danos tu opinión"; +"side_menu_action_help" = "Ayuda"; +"side_menu_action_settings" = "Ajustes"; +"side_menu_action_invite_friends" = "Invitar amigos"; + +// Mark: - Side menu + +"side_menu_reveal_action_accessibility_label" = "Panel izquierdo"; +"user_avatar_view_accessibility_hint" = "Cambiar avatar del usuario"; + +// Mark: - User avatar view + +"user_avatar_view_accessibility_label" = "avatar"; +"space_avatar_view_accessibility_hint" = "Cambiar avatar del espacio"; + +// Mark: Avatar + +"space_avatar_view_accessibility_label" = "Avatar"; +"space_public_join_rule" = "Espacio público"; +"space_private_join_rule" = "Espacio privado"; +"space_participants_action_ban" = "Vetar de este espacio"; +"space_participants_action_remove" = "Quitar de este espacio"; +"spaces_coming_soon_detail" = "Esta funcionalidad todavía no funciona aquí, pero llegará pronto. Por ahora, puedes hacer eso con %@ desde tu ordenador."; +"spaces_invites_coming_soon_title" = "Pronto podrás invitar"; +"spaces_add_rooms_coming_soon_title" = "Pronto podrás añadir salas"; +"spaces_coming_soon_title" = "Próximamente"; +"spaces_no_member_found_detail" = "¿Buscas a alguien que no esté en %@? Por ahora, puedes invitarles desde la web o aplicaciones de escritorios."; +"spaces_no_room_found_detail" = "Puede que no veas algunos resultados porque sean salas privadas y no te hayan invitado a ellas."; +"spaces_no_result_found_title" = "Ningún resultado"; +"spaces_empty_space_detail" = "Puede que no veas algunas salas porque sean privadas y no te hayan invitado a ellas."; +"spaces_empty_space_title" = "Este espacio no tiene salas (todavía)"; +"space_tag" = "espacio"; +"spaces_suggested_room" = "Sugerencia"; +"spaces_explore_rooms" = "Explorar salas"; +"leave_space_and_all_rooms_action" = "Salir de todas las salas y espacios"; +"leave_space_only_action" = "No salir de ninguna sala"; +"leave_space_message_admin_warning" = "Eres administrador en este espacio, asegúrate de darle permisos de administrador a otro miembro antes de salirte."; +"leave_space_message" = "¿Seguro que quieres salir de %@? ¿Quieres también salir de todas las salas y espacios dentro del espacio?"; +"leave_space_title" = "Salir de %@"; +"spaces_left_panel_title" = "Espacios"; +"spaces_home_space_title" = "Inicio"; +"space_beta_announce_information" = "Los espacios son una nueva manera de agrupar salas y personas. Todavía no funcionan en iOS, pero puedes usarlos ya en la web y desde aplicaciones para escritorio."; +"space_feature_unavailable_information" = "Los espacios son una nueva manera de agrupar salas y personas.\n\nPodrás usarlos dentro de poco. Por ahora, si te unes a uno en otra plataforma, podrás acceder las salas a las que te hayas unido desde aquí."; +"space_beta_announce_subtitle" = "La nueva versión de las comunidades"; +"space_beta_announce_title" = "Los espacios estarán disponibles dentro de poco"; +"space_beta_announce_badge" = "BETA"; +"space_feature_unavailable_subtitle" = "Los espacios aún no han llegado a iOS, pero puedes usarlos en la web y en las aplicaciones de escritorio"; + +// Mark: - Spaces + +"space_feature_unavailable_title" = "Los espacios todavía no funcionan"; +"room_intro_cell_information_multiple_dm_sentence2" = "Solo vosotros estáis en esta conversación, salvo que invitéis a alguien más."; +"room_intro_cell_information_dm_sentence2" = "Solo vosotros estáis en esta conversación, no puede entrar nadie más."; +"room_intro_cell_information_dm_sentence1_part3" = ". "; +"room_intro_cell_information_dm_sentence1_part1" = "Aquí empieza tu conversación privada con "; +"room_intro_cell_information_room_without_topic_sentence2_part2" = " para que se sepa de qué va esta sala."; +"room_intro_cell_information_room_without_topic_sentence2_part1" = "Añade un asunto"; +"room_intro_cell_information_room_with_topic_sentence2" = "Asunto: %@"; +"room_intro_cell_information_room_sentence1_part3" = ". "; +"room_intro_cell_information_room_sentence1_part1" = "Aquí empieza "; + +// Mark: - Room creation introduction cell + +"room_intro_cell_add_participants_action" = "Añadir gente"; +"room_avatar_view_accessibility_hint" = "Cambiar avatar de la sala"; + +// Mark: - Room avatar view + +"room_avatar_view_accessibility_label" = "avatar"; +"invite_friends_share_text" = "Hola, puedes hablar conmigo en %@: %@"; + +// MARK: - Invite friends + +"invite_friends_action" = "Invitar amigos a %@"; +"favourites_empty_view_information" = "Puedes añadir a favoritos de varias formas, pero la más rápida es tocar y mantener. Toca la estrella y aparecerán aquí, para que les tengas a un toque."; + +// MARK: - Favourites + +"favourites_empty_view_title" = "Salas y personas favoritas"; +"home_syncing" = "Sincronización"; +"home_context_menu_leave" = "Salir"; +"home_context_menu_normal_priority" = "Prioridad normal"; +"home_context_menu_low_priority" = "Prioridad baja"; +"home_context_menu_unfavourite" = "Quitar de favoritos"; +"home_context_menu_favourite" = "Añadir a favoritos"; +"home_context_menu_unmute" = "Dejar de silenciar"; +"home_context_menu_mute" = "Silenciar"; +"home_context_menu_notifications" = "Notificaciones"; +"home_context_menu_make_room" = "Mover a salas"; +"home_context_menu_make_dm" = "Mover a gente"; +"home_empty_view_information" = "Una completa aplicación segura de mensajería para equipos, amigos y organizaciones. Toca el botón + abajo para añadir gente y salas."; + +// MARK: - Home + +"home_empty_view_title" = "Te damos la bienvenida a %@,\n%@"; +"call_transfer_error_message" = "Error al transferir la llamada"; +"call_transfer_error_title" = "Error"; +"call_transfer_contacts_all" = "Todos"; +"call_transfer_contacts_recent" = "Recientes"; +"call_transfer_dialpad" = "Teclado numérico"; +"call_transfer_users" = "Usuarios"; + +// MARK: - Call Transfer +"call_transfer_title" = "Transferir"; + +// MARK: - Dial Pad +"dialpad_title" = "Teclado numérico"; +"room_info_list_section_other" = "Otros"; +"room_info_list_several_members" = "%@ miembros"; + +// MARK: - Room Info + +"room_info_list_one_member" = "1 miembro"; +"create_room_placeholder_address" = "#saladepruebas:matrix.org"; +"create_room_section_header_address" = "Dirección de la sala"; +"create_room_show_in_directory" = "Incluir en la lista pública de salas"; +"create_room_section_footer_type" = "La gente solo puede unirse a una sala privada si les invitas."; +"create_room_type_public" = "Sala pública"; +"create_room_type_private" = "Sala privada"; +"create_room_section_header_type" = "Tipo de sala"; +"create_room_section_footer_encryption" = "Una vez la actives, no podrás desactivarla."; +"create_room_enable_encryption" = "Activar cifrado"; +"create_room_section_header_encryption" = "Cifrado de la sala"; +"create_room_placeholder_topic" = "Asunto"; +"create_room_section_header_topic" = "Asunto de la sala (opcional)"; +"create_room_placeholder_name" = "Nombre"; +"create_room_section_header_name" = "Nombre de la sala"; + +// MARK: - Create Room + +"create_room_title" = "Nueva sala"; +"searchable_directory_search_placeholder" = "Nombre o ID"; +"searchable_directory_x_network" = "Red %@"; + +// MARK: - Searchable Directory View Controller + +"searchable_directory_create_new_room" = "Crear una sala nueva"; +"biometrics_cant_unlocked_alert_message_retry" = "Volver a intentar"; +"share_extension_send_now" = "Enviar"; +"share_extension_low_quality_video_message" = "Envíalo en %@ para una mejor calidad, o en una calidad menor abajo."; +"share_extension_low_quality_video_title" = "El vídeo se enviará en baja calidad"; +"room_widget_permission_room_id_permission" = "La ID de la sala"; +"room_widget_permission_widget_id_permission" = "La ID del accesorio"; +"room_widget_permission_theme_permission" = "Tu tema"; +"room_widget_permission_user_id_permission" = "Tu ID de usuario"; +"room_widget_permission_avatar_url_permission" = "Dirección URL de tu avatar"; +"room_widget_permission_display_name_permission" = "Tu nombre público"; +"room_widget_permission_information_title" = "Si lo usas, puede que comparta datos con %@:\n"; +"room_widget_permission_webview_information_title" = "Si lo usas, puede que guarde cookies y comparta datos con %@:\n"; +"room_widget_permission_creator_info_title" = "Este accesorio fue añadido por:"; + +// Room widget permissions +"room_widget_permission_title" = "Cargar accesorio"; +"widget_picker_manage_integrations" = "Gestionar integraciones…"; + +// Widget Picker +"widget_picker_title" = "Integraciones"; +"widget_integration_manager_disabled" = "Debes activar un gestor de integraciones en ajustes"; +"widget_menu_remove" = "Quitar para todos"; +"widget_menu_revoke_permission" = "Revocar mi acceso"; +"widget_menu_open_outside" = "Abrir en el navegador"; +"widget_menu_refresh" = "Recargar"; +"widget_integrations_server_failed_to_connect" = "No se ha podido conectar con el servidor de integraciones"; + +// Widget +"widget_no_integrations_server_configured" = "No hay un servidor de integraciones configurado"; +"bug_report_background_mode" = "Seguir en segundo plano"; +"e2e_key_backup_wrong_version_button_wasme" = "He sido yo"; +"e2e_key_backup_wrong_version_button_settings" = "Ajustes"; +"e2e_key_backup_wrong_version" = "Hemos detectado una copia de seguridad de claves.\n\nSi no la has creado tú, cambia tu frase de seguridad en ajustes."; + +// Key backup wrong version +"e2e_key_backup_wrong_version_title" = "Nueva copia de seguridad de claves"; +"analytics_prompt_stop" = "Dejar de compartir"; +"analytics_prompt_yes" = "Vale, de acuerdo"; +"analytics_prompt_not_now" = "Ahora no"; +"analytics_prompt_point_3" = "Puedes desactivar esto cuando quieras desde ajustes"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_2" = "No compartimos información con terceros"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_1" = "No guardamos ni analizamos ningún dato sobre tu cuenta"; +"analytics_prompt_terms_link_upgrade" = "aquí"; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_upgrade */ +"analytics_prompt_terms_upgrade" = "Lee todos los términos %@. ¿Aceptas?"; +"analytics_prompt_terms_link_new_user" = "aquí"; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ +"analytics_prompt_terms_new_user" = "Puedes leer todos los términos %@."; +"settings_discovery_three_pid_details_information_phone_number" = "Gestiona las preferencias de este número de teléfono, ¿qué otros usuarios pueden usarlo para encontrarte o invitarte a salas? Añade o quita números de teléfonos en Cuentas."; +"settings_three_pids_management_information_part1" = "Gestiona qué direcciones de correo o números de teléfono puedes usar para iniciar sesión o recuperar tu cuenta. Elige quién puede encontrarte en "; +"auth_reset_password_error_is_required" = "No has configurado un servidor de identidad. Añade uno en ajustes para poder recuperar la contraseña de tu cuenta de Matrix."; +"room_participants_security_information_room_encrypted_for_dm" = "Estos mensajes están cifrados de extremo a extremo.\n\nTus mensajes están protegidos, y solo tú y el destinatario tenéis las claves únicas para desbloquearlos."; +"room_participants_security_information_room_encrypted" = "Los mensajes en esta sala están cifrados de extremo a extremo.\n\nTus mensajes están protegidos, y solo tú y el destinatario tenéis las claves únicas para desbloquearlos."; +"room_participants_start_new_chat_error_using_user_email_without_identity_server" = "No has configurado un servidor de identidad, por lo que no puedes empezar una conversación usando un correo electrónico."; +"room_participants_leave_processing" = "Saliendo"; +"find_your_contacts_title" = "Empieza por listar tus contactos"; +"room_creation_error_invite_user_by_email_without_identity_server" = "No has configurado un servidor de identidad, por lo que no puedes añadir un participante usando su correo."; +"auth_softlogout_recover_encryption_keys" = "Inicia sesión para recuperar las claves de cifrado almacenadas solo en este dispositivo. Las necesitas para leer todos tus mensajes seguros en cualquier dispositivo."; +"auth_phone_is_required" = "No has configurado un servidor de identidad, por lo que no puedes añadir un número de teléfono para recuperar la contraseña de tu cuenta de Matrix en el futuro."; +"external_link_confirmation_message" = "El enlace %@ te está llevando a otro sitio: %@\n\n¿Seguro que quieres continuar?"; +"room_resource_usage_limit_reached_message_contact_3" = " para aumentar este límite."; +"room_resource_usage_limit_reached_message_2" = "algunos usuarios no podrán iniciar sesión."; +"room_resource_usage_limit_reached_message_1_monthly_active_user" = "Este servidor base ha llegado a su límite de usuarios activos al mes, por lo que "; +"room_resource_usage_limit_reached_message_1_default" = "Este servidor base ha sobrepasado uno de sus límites de recursos, por lo que "; +"room_unsent_messages_cancel_message" = "¿Seguro que quieres borrar todos los mensajes sin enviar en esta sala?"; +"analytics_prompt_message_new_user" = "Ayúdanos a identificar problemas y a mejorar %@ compartiendo datos anónimos de uso. Para entender mejor cómo la gente usa varios dispositivos, generaremos un identificador aleatorio que compartirán tus dispositivos."; +"analytics_prompt_message_upgrade" = "Anteriormente aceptaste compartir con nosotros datos anónimos de uso. Ahora, para entender cómo usa la gente varios dispositivos, generaremos un identificador aleatorio que compartirán tus dispositivos."; + +// Analytics +"analytics_prompt_title" = "Ayuda a mejorar %@"; +"call_actions_unhold" = "Volver a la llamada"; +"call_no_stun_server_error_message_2" = "También puedes intentar usar el servidor público %@, pero esto será tan estable, y compartirá tu dirección IP con ese servidor. También puedes cambiarlo en ajustes"; +"call_no_stun_server_error_use_fallback_button" = "Probar usando %@"; +"call_no_stun_server_error_message_1" = "Por favor, pídele al administrador de tu servidor base %@ que configure un «servidor TURN» para que las llamadas funcionen de forma consistente."; +"call_no_stun_server_error_title" = "La llamada ha fallado porque el servidor está mal configurado"; +"photo_library_access_not_granted" = "%@ no tiene permiso para acceder a tu galería de fotos. Por favor, cambia los ajustes de privacidad"; +"room_does_not_exist" = "%@ no existe"; +"camera_unavailable" = "La cámara de tu dispositivo no está disponible"; +"event_formatter_jitsi_widget_removed_by_you" = "Has quitado una conferencia VoIP"; +"event_formatter_jitsi_widget_added_by_you" = "Has añadido una conferencia VoIP"; +"event_formatter_widget_removed_by_you" = "Has quitado el accesorio: %@"; + +// Events formatter with you +"event_formatter_widget_added_by_you" = "Has añadido el accesorio: %@"; +"event_formatter_message_deleted" = "Mensaje borrado"; +"event_formatter_group_call_incoming" = "%@ en %@"; +"event_formatter_group_call_leave" = "Salir"; +"event_formatter_group_call_join" = "Unirme"; +"event_formatter_group_call" = "Llamada en grupo"; +"event_formatter_call_end_call" = "Colgar"; +"event_formatter_call_retry" = "Reintentar"; +"event_formatter_call_answer" = "Aceptar"; +"event_formatter_call_decline" = "Rechazar"; +"event_formatter_call_back" = "Devolver llamada"; +"event_formatter_call_connection_failed" = "Error de conexión"; +"event_formatter_call_missed_video" = "Videollamada perdida"; +"event_formatter_call_missed_voice" = "Llamada perdida"; +"event_formatter_call_you_declined" = "Llamada rechazada"; +"event_formatter_call_active_video" = "Videollamada en curso"; +"event_formatter_call_active_voice" = "Llamada en curso"; +"event_formatter_call_incoming_video" = "Videollamada entrante"; +"event_formatter_call_incoming_voice" = "Llamada entrante"; +"event_formatter_call_has_ended" = "Llamada terminada"; +"event_formatter_call_has_ended_with_time" = "Llamada terminada • %@"; +"event_formatter_call_ringing" = "Llamando…"; +"event_formatter_call_connecting" = "Conectando…"; +"event_formatter_message_edited_mention" = "(editado)"; +"image_picker_action_library" = "Elegir de la galería"; + +// Image picker +"image_picker_action_camera" = "Sacar una foto"; + +// Media picker +"media_picker_title" = "Galería"; +"room_notifs_settings_encrypted_room_notice" = "Ten en cuenta que, en dispositivos móviles, las notificaciones sobre menciones y palabras claves no están disponibles."; +"room_notifs_settings_account_settings" = "Ajustes de la cuenta"; +"room_notifs_settings_manage_notifications" = "Puedes gestionar las notificaciones en %@"; +"room_notifs_settings_cancel_action" = "Cancelar"; +"room_notifs_settings_done_action" = "Aceptar"; +"room_notifs_settings_none" = "Nada"; +"room_notifs_settings_mentions_and_keywords" = "Menciones y palabras clave"; +"room_notifs_settings_all_messages" = "Todos los mensajes"; + +// Room Notification Settings +"room_notifs_settings_notify_me_for" = "Notificarme sobre"; +"room_details_advanced_e2e_encryption_disabled_for_dm" = "El cifrado no está activado aquí."; +"room_details_advanced_e2e_encryption_enabled_for_dm" = "El cifrado está activado aquí"; +"room_details_advanced_room_id_for_dm" = "ID:"; +"room_details_no_local_addresses_for_dm" = "No tiene una dirección local"; +"room_details_access_section_directory_toggle_for_dm" = "Incluir la sala en la lista de salas"; +"room_details_access_section_anyone_for_dm" = "Cualquiera que tenga el enlace, incluso si no tiene cuenta"; +"room_details_access_section_anyone_apart_from_guest_for_dm" = "Cualquiera que tenga el enlace, si tiene una cuenta"; +"room_details_access_section_for_dm" = "¿Quién puede acceder?"; +"room_details_notifs" = "Notificaciones"; +"room_details_room_name_for_dm" = "Nombre"; +"room_details_photo_for_dm" = "Foto"; +"room_details_integrations" = "Integraciones"; +"room_details_search" = "Buscar en la sala"; +"room_details_title_for_dm" = "Detalles"; +"identity_server_settings_alert_error_invalid_identity_server" = "%@ no es un servidor de identidad válido."; +"identity_server_settings_alert_error_terms_not_accepted" = "Debes aceptar los términos de %@ para usarlo como servidor de identidad."; +"identity_server_settings_alert_disconnect_still_sharing_3pid_button" = "Desconectar de todos modos"; +"identity_server_settings_alert_disconnect_still_sharing_3pid" = "Todavía estás compartiendo tus datos personales con el servidor de identidad %@.\n\nAntes de desconectarte, te recomendamos que primero quites tus direcciones de correo electrónico y números de teléfono."; +"identity_server_settings_alert_disconnect_button" = "Desconectar"; +"identity_server_settings_alert_disconnect" = "¿Desconectarte del servidor de identidad %@?"; +"identity_server_settings_alert_disconnect_title" = "Desconectar servidor de identidad"; +"identity_server_settings_alert_change" = "¿Te quieres desconectar del servidor de identidad %1$@ y conectarte a %2$@ en su lugar?"; +"identity_server_settings_alert_change_title" = "Cambiar servidor de identidad"; +"identity_server_settings_alert_no_terms_title" = "El servidor de identidad no tiene términos del servicio"; +"identity_server_settings_alert_no_terms" = "El servidor de identidad que has elegido no tiene términos del servicio. Continúa solo si confías en el dueño del servidor."; +"identity_server_settings_disconnect" = "Desconectar"; +"identity_server_settings_disconnect_info" = "Si te desconectas del servidor de identidad, otras personas no podrán encontrarte ni invitarte por tu correo o número de teléfono."; +"identity_server_settings_change" = "Cambiar"; +"identity_server_settings_add" = "Añadir"; +"identity_server_settings_place_holder" = "Escribe un servidor de identidad"; +"identity_server_settings_no_is_description" = "No estás usando un servidor de identidad. Añade uno arriba para encontrar y ser encontrado por contactos existentes."; +"identity_server_settings_description" = "Usas %@ para encontrar y ser encontrado por contactos que conozcas."; + +// Identity server settings +"identity_server_settings_title" = "Servidor de identidad"; + +// AuthenticatedSessionViewControllerFactory +"authenticated_session_flow_not_supported" = "Esta aplicación no es compatible con el mecanismo de inicio de sesión de tu servidor base."; +"manage_session_sign_out" = "Cerrar esta sesión"; +"manage_session_not_trusted" = "No es de confianza"; +"manage_session_trusted" = "Es de confianza"; +"manage_session_name" = "Nombre de la sesión"; +"manage_session_info" = "INFORMACIÓN DE LA SESIÓN"; + +// Manage session +"manage_session_title" = "Gestionar sesión"; +"security_settings_user_password_description" = "Escribe la contraseña de tu cuenta de Matrix para confirmar tu identidad"; +"security_settings_coming_soon" = "Lo siento, pero esta acción todavía no está disponible en %@ iOS. Por favor, usa otra aplicación de Matrix para configurarlo. %@ iOS lo usará."; +"security_settings_complete_security_alert_message" = "Primero debes completar el proceso de seguridad en esta sesión."; +"security_settings_complete_security_alert_title" = "Completar proceso de seguridad"; +"security_settings_blacklist_unverified_devices_description" = "Verifica todas las sesiones de un usuario para marcarles como «de confianza» y poder enviarles mensajes."; +"security_settings_blacklist_unverified_devices" = "No enviar nunca mensajes a sesiones que no sean de confianza"; +"security_settings_advanced" = "AVANZADO"; +"security_settings_export_keys_manually" = "Exportar claves manualmente"; +"security_settings_cryptography" = "CRIPTOGRAFÍA"; +"security_settings_crosssigning_complete_security" = "Completar proceso de seguridad"; +"security_settings_crosssigning_reset" = "Restablecer"; +"security_settings_crosssigning_bootstrap" = "Configurar"; +"security_settings_crosssigning_info_exists" = "Tu cuenta usa la firma cruzada para la identidad, pero todavía no confías en ella desde esta sesión. Completa el proceso de seguridad de esta sesión."; +"security_settings_crosssigning_info_trusted" = "Has activado la firma cruzada. Puedes marcar a otras personas y tus otras sesiones como «de confianza» basándote en la firma cruzada. Sin embargo, no puedes realizar la firma cruzada desde esta sesión porque no ha recibido las claves privadas para ello. Completa el proceso de seguridad de esta sesión."; +"security_settings_crosssigning_info_not_bootstrapped" = "Todavía no has configurado la firma cruzada."; +"security_settings_crosssigning" = "FIRMA CRUZADA"; +"security_settings_backup" = "COPIA DE SEGURIDAD DE MENSAJES"; +"security_settings_secure_backup_delete" = "Eliminar copia de seguridad"; +"security_settings_secure_backup_restore" = "Restaurar desde una copia de seguridad"; +"security_settings_secure_backup_reset" = "Restablecer"; +"security_settings_secure_backup_setup" = "Configurar"; +"security_settings_secure_backup_info_valid" = "Esta sesión está haciendo copias de seguridad de tus claves."; +"security_settings_secure_backup_info_checking" = "Comprobando…"; +"security_settings_secure_backup_description" = "Haz copias de seguridad de las claves con los datos de tu cuenta, por si pierdes acceso a tus sesiones. Tus claves de seguridad se protegerán con una clave de seguridad única."; +"security_settings_secure_backup" = "COPIAS DE SEGURIDAD"; +"security_settings_crypto_sessions_description_2" = "Si no reconoces un inicio se sesión, cambia la contraseña de tu cuenta de Matrix y restablece las copias de seguridad."; +"security_settings_crypto_sessions_loading" = "Cargando sesiones…"; +"security_settings_crypto_sessions" = "MIS SESIONES"; + +// Security settings +"security_settings_title" = "Seguridad"; +"settings_enable_room_message_bubbles" = "Burbujas de mensajes"; +"settings_show_NSFW_public_rooms" = "Mostrar salas públicas con contenido para mayores de edad"; +"settings_identity_server_no_is_description" = "No estás usando un servidor de identidad. Para encontrar y que te encuentren contactos que conozcas, añade uno arriba."; +"settings_identity_server_no_is" = "No has configurado un servidor de identidad"; +"settings_identity_server_description" = "Al usar el servidor de identidad de arriba, puedes encontrar y ser encontrado por contactos que conozcas."; +"settings_discovery_three_pid_details_enter_sms_code_action" = "Introduce el código de activación del SMS"; +"settings_discovery_three_pid_details_cancel_email_validation_action" = "Cancelar validación del correo"; +"settings_discovery_three_pid_details_revoke_action" = "Revocar"; +"settings_discovery_three_pid_details_share_action" = "Compartir"; +"settings_discovery_three_pid_details_information_email" = "Gestiona los ajustes de esta dirección de correo, que otros usuarios pueden usar para encontrarte e invitarte a salas. Añade o quita direcciones de correo en Cuentas."; +"settings_discovery_three_pids_management_information_part1" = "Gestiona las direcciones de correo y números de teléfono que otros usuarios pueden usar para encontrarte e invitarte a salas. Añade o quita direcciones de correo o números de teléfono en "; +"settings_integrations_allow_description" = "Usar un gestor de integraciones (%@) para bots, puentes, accesorios y paquetes de etiquetas.\n\nLos gestores de integraciones reciben datos sobre la configuración, y pueden modificar accesorios, invitar a salas y cambiar los niveles de permisos en tu nombre."; +"settings_confirm_media_size_description" = "Si lo activas, te preguntaremos que confirmes el tamaño con el que enviar imágenes y vídeos."; +"settings_discovery_three_pid_details_title_phone_number" = "Gestionar número de teléfono"; +"settings_discovery_three_pid_details_title_email" = "Gestionar correo electrónico"; +"settings_discovery_error_message" = "Ha ocurrido un error. Por favor, inténtalo de nuevo."; +"settings_discovery_three_pids_management_information_part3" = "."; +"settings_discovery_three_pids_management_information_part2" = "Ajustes de usuario"; +"settings_discovery_accept_terms" = "Aceptar los términos del servidor de identidad"; +"settings_discovery_terms_not_signed" = "Aceptar los términos del servicio del servidor de identidad (%@) para que te puedan encontrar por tu dirección de correo o número de teléfono."; +"settings_discovery_no_identity_server" = "No estás usando un servidor de identidad. Añade uno para que los contactos que te conozcan puedan encontrarte."; +"settings_devices_description" = "La gente con la que te comuniques podrá ver el nombre público de las sesiones"; +"settings_key_backup_delete_confirmation_prompt_msg" = "¿Seguro? Perderás tus mensajes cifrados si no hay copias de seguridad válidas de las claves."; +"settings_key_backup_delete_confirmation_prompt_title" = "Eliminar copia de seguridad"; +"settings_key_backup_button_connect" = "Conectar esta sesión a las copias de seguridad de las claves"; +"settings_key_backup_button_delete" = "Eliminar copia de seguridad"; +"settings_key_backup_button_restore" = "Restaurar desde una copia de seguridad"; +"settings_key_backup_button_create" = "Empezar a hacer copias de seguridad de las claves"; +"settings_key_backup_info_trust_signature_invalid_device_verified" = "La copia de seguridad tiene una firma inválida de %@"; +"settings_key_backup_info_trust_signature_invalid_device_unverified" = "La copia de seguridad tiene una firma inválida de %@"; +"settings_key_backup_info_trust_signature_valid_device_unverified" = "La copia de seguridad tiene una firma de %@"; +"settings_key_backup_info_trust_signature_valid_device_verified" = "La copia de seguridad tiene una firma válida de %@"; +"settings_key_backup_info_trust_signature_valid" = "La copia de seguridad tiene una firma válida de esta sesión"; +"settings_key_backup_info_trust_signature_unknown" = "La copia de seguridad está firmada por la sesión con ID: %@"; +"settings_key_backup_info_progress_done" = "Hay copias de seguridad de todas las claves"; +"settings_key_backup_info_progress" = "Haciendo una copia de seguridad de %@ claves…"; +"settings_key_backup_info_not_valid" = "Esta sesión no guarda una copia de seguridad de tus claves, aunque tienes una copia de seguridad desde la que restaurar y añadir en el futuro."; +"settings_key_backup_info_valid" = "Esta sesión guarda una copia de seguridad de tus claves."; +"settings_key_backup_info_algorithm" = "Algoritmo: %@"; +"settings_key_backup_info_version" = "Versión de la copia de seguridad de las claves: %@"; +"settings_key_backup_info_signout_warning" = "Para evitar perderlas, haz una copia de seguridad antes de cerrar sesión."; +"settings_key_backup_info_none" = "No hay copia de seguridad de tus claves para esta sesión."; +"settings_key_backup_info" = "Los mensajes cifrados están protegidos por el cifrado de extremo a extremo. Solo tú y los destinatarios tendrán las claves para leer estos mensajes."; +"settings_add_3pid_invalid_password_message" = "Datos de la cuenta incorrectos"; +"settings_add_3pid_password_message" = "Para continuar, escribe la contraseña de tu cuenta de Matrix"; +"settings_add_3pid_password_title_msidsn" = "Añadir número de teléfono"; +"settings_add_3pid_password_title_email" = "Añadir dirección de correo electrónico"; +"settings_analytics_and_crash_data" = "Enviar informes y datos sobre cierres inesperados"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Mostrar el último avatar y nombre de usuarios en el historial de mensajes"; +"settings_labs_enable_threads" = "Hilos de mensajes"; +"settings_labs_enabled_polls" = "Encuestas"; +"settings_labs_enable_ringing_for_group_calls" = "Hacer que las llamadas grupales suenen"; +"settings_labs_message_reaction" = "Reaccionar a mensajes con emojis"; +"settings_contacts_enable_sync_description" = "Esto usará tu servidor de identidad para conectarte con tus contactos, así como para ayudarles a que te encuentren."; +"settings_contacts_enable_sync" = "Encuentra a tus contactos"; +"settings_show_url_previews_description" = "Las vistas previas solo aparecerán en salas sin cifrar."; +"settings_show_url_previews" = "Mostrar vistas previas de páginas web"; +"settings_ui_theme_picker_message_match_system_theme" = "«Auto» usará el tema actual de tu dispositivo"; +"settings_ui_theme_picker_message_invert_colours" = "«Auto» usa los ajustes sobre colores invertidos de tu dispositivo"; +"settings_calls_stun_server_fallback_description" = "Conectar con el servidor de respaldo «%@» cuando tu servidor base no ofrezca uno (tu dirección IP se compartiría con él durante las llamadas)."; +"settings_integrations_allow_button" = "Gestionar integraciones"; +"settings_calls_stun_server_fallback_button" = "Conectar con un servidor de respaldo para las llamadas si fuera necesario"; +"settings_mentions_and_keywords_encryption_notice" = "En dispositivos móviles, no recibirás notificaciones de menciones y palabras claves dentro de salas cifradas."; +"settings_new_keyword" = "Añadir nueva palabra clave"; +"settings_your_keywords" = "Palabras clave"; +"settings_room_upgrades" = "Actualizaciones de salas"; +"settings_messages_by_a_bot" = "Mensajes de bots"; +"settings_encrypted_group_messages" = "Mensajes cifrados de grupos"; +"settings_group_messages" = "Mensajes en grupo"; +"settings_encrypted_direct_messages" = "Mensajes directos cifrados"; +"settings_direct_messages" = "Mensajes directos"; +"settings_notify_me_for" = "Notificarme sobre"; +"settings_mentions_and_keywords" = "Menciones y palabras clave"; +"settings_default" = "Notificaciones por defecto"; +"settings_notifications_disabled_alert_message" = "Para activar las notificaciones, ve a los ajustes del dispositivo."; +"settings_notifications_disabled_alert_title" = "Notificaciones desactivadas"; +"settings_device_notifications" = "Notificaciones en el dispositivo"; +"settings_confirm_media_size" = "Confirmar el tamaño al enviar"; +"settings_key_backup" = "COPIA DE SEGURIDAD DE CLAVES"; +"settings_phone_contacts" = "CONTACTOS DEL DISPOSITIVO"; +"settings_identity_server_settings" = "SERVIDOR DE IDENTIDAD"; +"settings_discovery_settings" = "DESCUBRIR"; + +// Errors +"error_user_already_logged_in" = "Parece que te estás intentando conectar a otro servidor base. ¿Quieres cerrar sesión?"; +"room_creation_dm_error" = "No hemos podido crear el mensaje directo. Por favor, comprueba los usuarios a los que quieres invitar e inténtalo de nuevo."; +"rooms_empty_view_information" = "Las salas son buena opción para grupos públicos o privados. Toca el + para encontrar salas existentes o crear nuevas."; +"contacts_address_book_no_identity_server" = "No hay un servidor de identidad configurado"; +"find_your_contacts_identity_service_error" = "No se ha podido conectar con el servidor de identidad."; diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings index 0923de120..ff6b4bcaa 100644 --- a/Riot/Assets/et.lproj/Vector.strings +++ b/Riot/Assets/et.lproj/Vector.strings @@ -2075,3 +2075,5 @@ "home_syncing" = "Sünkroniseerimine"; "room_participants_leave_success" = "Sa oled jututoast lahkunud"; "room_participants_leave_processing" = "Lahkumine"; +"notice_error_unformattable_event" = "** Sõnumi töötlemine ei õnnestu. Palun anna meile sellest veast teada"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Sõnumite ajaloos leiduvate kasutajate puhul näita viimati kasutatud tunnuspilti ning nime"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index cb13dec6c..27540c367 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -2149,3 +2149,8 @@ "attachment_unsupported_preview_title" = "Prévisualisation impossible"; "room_displayname_all_other_members_left" = "%@ (Quitté)"; "message_reply_to_sender_sent_their_location" = "a partagé sa localisation."; +"settings_labs_use_only_latest_user_avatar_and_name" = "Afficher le dernier avatar et nom des utilisateurs dans l’historique de messages"; +"room_participants_leave_success" = "Parti du salon"; +"room_participants_leave_processing" = "Départ"; +"notice_error_unformattable_event" = "** Impossible d’afficher le message. Merci de signaler une erreur"; +"home_syncing" = "Synchronisation"; diff --git a/Riot/Assets/he.lproj/Vector.strings b/Riot/Assets/he.lproj/Vector.strings index f13b3b81c..9295a642c 100644 --- a/Riot/Assets/he.lproj/Vector.strings +++ b/Riot/Assets/he.lproj/Vector.strings @@ -121,7 +121,7 @@ "ssl_trust" = "בטוח"; "ssl_unexpected_existing_expl" = "התעודה שונתה מזו שאומתה ע\"י הטלפון שלך. זה חריג לחלוטין. מומלץ לך לא לקבל את התעודה החדשה הזו."; "start_chat" = "התחל צ'אט"; -"store_full_description" = "Element היא סוג חדש של אפליקציית הודעות ושיתוף :\n\n1. מאפשרת לך לשלוט ולשמור על פרטיותך.\n2. מאפשרת לך לתקשר עם כל אחד ברשת, ואפילו מעבר לכך ע\"י שילוב אפליקציות כמו Slack\n3. מגנה עליך מפני פרסומות, כריית מידע ופרצות אחוריות.\n4. מגנה עליך ע\"י הצפנה מקצה לקצה, תוך התחברות מוצלבת לווידוא אחרים.\n\nElement היא אפליקצית הודעות ושיתוף השונה לחלוטין מאפליקציות אחרות מכיון שהיא מבוזרת ועובדת בקוד פתוח.\n\nElement מאפשרת לך לעבוד כמשתמש עצמי או לבחור לעבוד כמשתמש אורח, כך שתהיה לך פרטיות, בעלות וניהול של המידע שלך. היא מאפשרת לך גישה פתוחה לרשת כך שאתה לא מדבר רק עם משתמשים אחרים במערכת ה Element. ובנוסף המערכת מאוד מאובטחת.\n\nElement מסוגלת לבצע כל זאת מכיון שהיא עובדת במטריצה - הסטנדרט עבור תקשורת פתוחה ומבוזרת.\n\nElement נותנת לך בקרה ע\"י כך שהיא מאפשרת לך לבחור מי יהיו המשתמשים בחדרי השיחה. מאפליקציית Element אתה יכול לבחור את צורת ההתחברות בשלוש דרכים שונות:\n\n1. קבלת חשבון חינמי בשרת ציבורי matrix.org\n2. הקמת חשבון משתמש עצמי על שרת אישי שלך.\n3. רישום והקמת חשבון על שרת אירוח של מערכת Element\n\nמדוע לבחור ב Element ?\n\nשלוט במידע שלך : אתה מחליט היכן לשמור את המידע שלך וההודעות שלך. אתה הבעלים והמנהל של המידע, ולא איזה ארגון ענק שכורה את המידע ומאפשר גישה לצד שלישי.\n\nפתיחת הודעות וחדרים: אתה יכול לדבר בחדרי הצ'אט עם כל אחד אחר ברשת, בין אם הם משתמשים ב Element או בכל אפליקציית מטריקס, ואפילו אם הם משתמשים במערכת הודעות שונה כגון Slack, IRC או XMPP.\n\nאבטחה מקסימלית: הצפנה קצה לקצה אמתית (רק אלו שנמצאים בשיחה יכולים לפענח את ההודעות), וחתימה מוצלבת ע\"מ לאשר את מכשירי המשתתפים בשיחות.\n\nתקשורת מלאה: הודעות, שיחות קול ווידאו, שיתוף קבצים, שיתוף מסכים, ומבחר של התקנות, בוטים ויישומים. בניית חדרים, קהילות, \"שמירה על קשר\" ומעקב ביצוע משימות.\n\nהיכן שאתה נמצא: הישאר בקשר היכן שאתה נמצא עם סנכרון מלא להודעות היסטוריות בכל המכשירים ובאתר בכתובת : https://element.io/app"; +"store_full_description" = "Element היא סוג חדש של אפליקציית הודעות ושיתוף :\n\n1. מאפשרת לך לשלוט ולשמור על פרטיותך\n2. מאפשרת לך לתקשר עם כל אחד ברשת, ואפילו מעבר לכך ע\"י שילוב אפליקציות כמו Slack\n3. מגנה עליך מפני פרסומות, כריית מידע ופרצות אחוריות\n4. מגנה עליך ע\"י הצפנה מקצה לקצה, תוך התחברות מוצלבת לווידוא אחרים\n\nElement היא אפליקצית הודעות ושיתוף השונה לחלוטין מאפליקציות אחרות מכיון שהיא מבוזרת ועובדת בקוד פתוח.\n\nElement מאפשרת לך לעבוד כמשתמש עצמי או לבחור לעבוד כמשתמש אורח כך שתהיה לך פרטיות, בעלות וניהול של המידע שלך. היא מאפשרת לך גישה פתוחה לרשת; כך שאתה לא מדבר רק עם משתמשים אחרים במערכת ה Element. ובנוסף המערכת מאוד מאובטחת.\n\nElement מסוגלת לבצע כל זאת מכיון שהיא עובדת במטריצה - הסטנדרט עבור תקשורת פתוחה ומבוזרת.\n\nElement נותנת לך בקרה ע\"י כך שהיא מאפשרת לך לבחור מי יהיו המשתמשים בחדרי השיחה. מאפליקציית Element אתה יכול לבחור את צורת ההתחברות בשלוש דרכים שונות:\n\n1. קבלת חשבון חינמי בשרת ציבורי matrix.org\n2. הקמת חשבון משתמש עצמי על שרת אישי שלך\n3. רישום והקמת חשבון על שרת אירוח של מערכת Element\n\nמדוע לבחור ב Element?\n\nשלוט במידע שלך: אתה מחליט היכן לשמור את המידע שלך וההודעות שלך. אתה הבעלים והמנהל של המידע, ולא איזה ארגון ענק שכורה את המידע ומאפשר גישה לצד שלישי.\n\nפתיחת הודעות וחדרים: אתה יכול לדבר בחדרי הצ'אט עם כל אחד אחר ברשת, בין אם הם משתמשים ב Element או בכל אפליקציית מטריקס, ואפילו אם הם משתמשים במערכת הודעות שונה כגון Slack, IRC או XMPP.\n\nאבטחה מקסימלית: הצפנה קצה לקצה אמתית (רק אלו שנמצאים בשיחה יכולים לפענח את ההודעות), וחתימה מוצלבת ע\"מ לאשר את מכשירי המשתתפים בשיחות.\n\nתקשורת מלאה: הודעות, שיחות קול ווידאו, שיתוף קבצים, שיתוף מסכים, ומבחר של התקנות, בוטים ויישומים. בניית חדרים, קהילות, \"שמירה על קשר\" ומעקב ביצוע משימות.\n\nהיכן שאתה נמצא: הישאר בקשר היכן שאתה נמצא עם סנכרון מלא להודעות היסטוריות בכל המכשירים שלך ובאתר בכתובת : https://element.io/app."; "onboarding_splash_login_button_title" = "קיים ברשותי חשבון"; "accessibility_button_label" = "כפתור"; "callbar_only_single_active_group" = "החלק להשתתפות בשיחת הועידה (%@)"; @@ -490,3 +490,616 @@ "spaces_empty_space_title" = "למרחב הזה אין עדיין חדרים"; "space_beta_announce_title" = "בקרוב - מרחבים"; "space_feature_unavailable_subtitle" = "מרחבים עדיין לא קיימים עבור iOS, אפשר להשתמש בהם בממשק ה WEB והמחשב"; + +// Recover with key + +"secrets_recovery_with_key_title" = "מפתח אבטחה"; +"secrets_recovery_with_passphrase_invalid_passphrase_message" = "אנא וודא שהכנסת ביטוי אבטחה נכון."; +"secrets_recovery_with_passphrase_invalid_passphrase_title" = "לא יכול לגשת לאחסון סודי"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part3" = "."; +"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "השתמש במפתח האבטחה שלך"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "לא יודע את ביטוי האבטחה שלך? אתה יכול "; +"secrets_recovery_with_passphrase_recover_action" = "השתמש בביטוי"; +"secrets_recovery_with_passphrase_passphrase_placeholder" = "הכנס ביטוי אבטחה"; +"secrets_recovery_with_passphrase_passphrase_title" = "הכנס"; +"secrets_recovery_with_passphrase_information_verify_device" = "השתמש בביטוי האבטחה שלך על מנת לאמת התקן זה."; +"secrets_recovery_with_passphrase_information_default" = "הכנס את הודעת האבטחה הישנה שלך ואת זיהוי החתימה שלך על מנת לאמת ממשקים אחרים ע\"י הכנסת ביטוי האבטחה שלך."; + +// Recover with passphrase + +"secrets_recovery_with_passphrase_title" = "ביטוי אבטחה"; +"secrets_recovery_reset_action_part_2" = "אתחל הכל"; + +// MARK: - Secrets recovery + +"secrets_recovery_reset_action_part_1" = "אפשרויות שחזור נשכחו או הלכו לאיבוד? "; +"user_verification_session_details_verify_action_other_user" = "מאומת ידנית"; +"user_verification_session_details_verify_action_current_user_manually" = "אימות טקסט ידני"; +"user_verification_session_details_verify_action_current_user" = "אימות אינטראקטיבי"; +"user_verification_session_details_additional_information_untrusted_current_user" = "אם לא התחברת לממשק זה, חשבונך עלול להיחסם."; +"user_verification_session_details_additional_information_untrusted_other_user" = "עד לאישור הממשק ע\"י היוזר, הודעות שנשלחות אליו וממנו יסומנו עם הודעת אזהרה. לחילופין, אתה יכול לאמת אותו ידנית."; +"user_verification_session_details_information_untrusted_other_user" = " התחבר ע\"י שימוש בממשק חדש:"; +"user_verification_session_details_information_untrusted_current_user" = "אמת ממשק זה ע\"מ לסמן אותו כבטוח ואפשר לו גישה להודעות מוצפנות:"; +"user_verification_session_details_information_trusted_other_user_part2" = " אמת זאת:"; +"user_verification_session_details_information_trusted_other_user_part1" = "ממשק זה מהימן עבור הודעות מוצפנות מכיון "; +"user_verification_session_details_information_trusted_current_user" = "ממשק זה מהימן עבור הודעות מוצפנות מכיון שכבר אימתת אותו:"; +"user_verification_session_details_untrusted_title" = "לא מהימן"; + +// Session details + +"user_verification_session_details_trusted_title" = "מהימן"; +"user_verification_sessions_list_session_untrusted" = "לא מהימן"; +"user_verification_sessions_list_session_trusted" = "מהימן"; +"user_verification_sessions_list_table_title" = "ממשק"; +"user_verification_sessions_list_information" = "הודעות עם משתמש זה בחדר זה מוצפנות מקצה לקצה ואינן ניתנות לקריאה ע\"י צד שלישי."; +"user_verification_sessions_list_user_trust_level_unknown_title" = "לא ידוע"; +"user_verification_sessions_list_user_trust_level_warning_title" = "זהירות"; + +// Sessions list + +"user_verification_sessions_list_user_trust_level_trusted_title" = "מהימן"; +"user_verification_start_additional_information" = "ע\"מ לשמור על אבטחה, בצע פעולה זו לבד או מצא דרך חלופית ליצור קשר."; +"user_verification_start_waiting_partner" = "ממתין ל %@…"; +"user_verification_start_information_part2" = " ע\"י בדיקה באמצעות קוד חד פעמי בשני ההתקנים שלך."; +"user_verification_start_information_part1" = "לטובת אבטחה מקסימלית, אנא אשר. "; + +// MARK: - User verification + +// Start + +"user_verification_start_verify_action" = "התחל אימות"; +"key_verification_scan_confirmation_scanned_device_information" = "האם התקן אחר מראה גם את אותה הגנה?"; +"key_verification_scan_confirmation_scanned_user_information" = "האם %@ מציג את אותה הגנה?"; + +// Scanned +"key_verification_scan_confirmation_scanned_title" = "כמעט סיימנו!"; +"key_verification_scan_confirmation_scanning_device_waiting_other" = "ממתין להתקן אחר…"; +"key_verification_scan_confirmation_scanning_user_waiting_other" = "ממתין ל%@…"; + +// MARK: Scan confirmation + +// Scanning +"key_verification_scan_confirmation_scanning_title" = "כמעט סיימנו! ממתין לאישור…"; +"key_verification_verify_qr_code_scan_other_code_success_message" = "קוד QR אומת בהצלחה."; +"auth_add_phone_message_2" = "הגדר מספר טלפון, בהמשך יהווה אפשרות לזיהויך על ידי משתמשים שמכירים אותך."; +"auth_add_email_message_2" = "הגדר דוא\"ל לטובת שחזור החשבון, בהמשך יהווה אפשרות לזיהויך על ידי משתמשים שמכירים אותך."; +"auth_invalid_user_name" = "שמות משתמשים יכולים להכיל רק אותיות, מספרים, נקודות, מקפים וקווים תחתונים"; +"auth_home_server_placeholder" = "כתובת אתר (לדוגמה https://matrix.org)"; +"auth_user_id_placeholder" = "דואר אלקטרוני או שם משתמש"; +"auth_login_single_sign_on" = "התחבר"; +"onboarding_use_case_existing_server_button" = "התחבר לשרת"; +"onboarding_use_case_existing_server_message" = "מחפשים להצטרף לשרת קיים ?"; +"onboarding_use_case_skip_button" = "דלג על השאלה"; +/* The placeholder string contains onboarding_use_case_skip_button as a tappable action */ +"onboarding_use_case_not_sure_yet" = "מתלבט ? אתה מסוגל %@"; +"onboarding_use_case_community_messaging" = "קהילות"; +"onboarding_use_case_personal_messaging" = "חברים ומשפחה"; +"discard" = "לבטל"; +"abort" = "בטל"; +"yes" = "כן"; + +// Action +"no" = "לא"; +"login_error_resource_limit_exceeded_contact_button" = "צור קשר עם מנהל המערכת"; +"login_error_resource_limit_exceeded_message_contact" = "\n\nאנא צור קשר מנהל השירות שלך על מנת להמשיך להשתמש בשירות זה."; +"login_error_resource_limit_exceeded_message_monthly_active_user" = "שרת זה הגיע למגבלת המשתמשים הפעילים בו."; +"login_error_resource_limit_exceeded_message_default" = "שרת בית זה הגיע לסף של אחד המשאבים שלו."; +"login_error_resource_limit_exceeded_title" = "הגעה לסף משאבים"; +"login_desktop_device" = "שולחן עבודה"; +"login_tablet_device" = "טאבלט"; +"login_mobile_device" = "נייד"; +"login_error_forgot_password_is_not_supported" = "שכחתי סיסמה לא נתמך כרגע"; +"register_error_title" = "רישום נכשל"; +"room_accessibility_upload" = "העלאה"; +"room_accessibility_integrations" = "התקנות"; +"room_accessibility_search" = "חפש"; +"room_message_edits_history_title" = "עריכות הודעה"; +"room_resource_usage_limit_reached_message_contact_3" = " על מנת להגיע לעלית סף זה."; +"room_resource_usage_limit_reached_message_2" = "חלק מהמשתמשים לא יוכלו להתחבר."; +"room_resource_usage_limit_reached_message_1_monthly_active_user" = "שרת הבית הזה הגיע לסף החודשי של משתמשים פעילים בו אז "; +"room_resource_usage_limit_reached_message_1_default" = "שרת הבית הזה הגיע לסף של אחד המשאבים שלו אז "; +"room_resource_limit_exceeded_message_contact_3" = " על מנת להמשיך לעשות שימוש בשירות זה."; +"room_resource_limit_exceeded_message_contact_2_link" = "צור קשר עם מנהל השירות שלך"; +"room_resource_limit_exceeded_message_contact_1" = " בבקשה "; +"room_predecessor_link" = "לחץ כאן כדי לראות הודעות ישנות."; +"room_predecessor_information" = "חדר זה הוא המשך של שיחה אחרת."; +"room_replacement_link" = "השיחה ממשיכה כאן."; +"room_replacement_information" = "חדר זה הוחלף והוא אינו פעיל יותר."; +"room_action_reply" = "תשובה"; +"room_action_send_file" = "שלח קובץ"; +"room_action_send_sticker" = "שלח תוית"; +"room_action_send_photo_or_video" = "שלח תמונה אם סרטון וידאו"; +"room_action_camera" = "צלם תמונה או וידאו"; +"room_creation_error_invite_user_by_email_without_identity_server" = "לא הוגדר אף שרת זיהוי לכן אתה לא יכול להוסיף משתתף עם אימייל."; +"room_creation_invite_another_user" = "מספר משתמש, שם או אימייל"; +"room_creation_wait_for_creation" = "החדר כבר הוגדר. אנא המתן."; +"room_creation_make_private" = "הפוך לפרטי"; +"room_creation_keep_private" = "שמור על פרטיות"; +"room_creation_make_public_prompt_msg" = "האם אתה בטוח שברצונך ליצור צ'אט זה ציבורי? כל אחד יוכל לקרא את ההודעות שלך ולהצטרף לצ'אט."; +"room_creation_make_public_prompt_title" = "הגדר צ'אט זה ציבורי?"; +"room_creation_make_public" = "הפוך לציבורי"; +"room_creation_public_room" = "צ'אט זה הוא ציבורי"; +"room_creation_private_room" = "צ'אט זה הוא פרטי"; +"room_creation_privacy" = "פרטי"; +"room_creation_appearance_picture" = "תמונת צ'אט(אופציונלי)"; +"room_creation_appearance_name" = "שם"; +"room_creation_appearance" = "קיים"; +"room_creation_account" = "חשבון"; + +// Chat creation +"room_creation_title" = "צ'אט חדש"; + +// Errors +"error_user_already_logged_in" = "נראה שאתה מנסה להתחבר לשרת בית אחר. האם אתה מעוניין להתנתק?"; +"social_login_button_title_sign_up" = "הירשם באמצעות %@"; +"social_login_button_title_sign_in" = "התחבר באמצעות %@"; +"social_login_button_title_continue" = "המשך עם %@"; +"space_feature_unavailable_information" = "מרחבים הם דרך חדשה לקבץ חדרים ואנשים.\n\nהם יהיו כאן בקרוב. בינתיים, אם תצטרף לאחד בפלטפורמה אחרת, תוכל לגשת לכל חדר אליו אתה מצטרף כאן."; +"leave_space_and_all_rooms_action" = "עזוב את כל החדרים והמרחבים"; +"leave_space_only_action" = "אל תעזוב אף אחד מהחדרים"; +"leave_space_message_admin_warning" = "אתה עם הרשאות admin במרחב זה, וודא שהעברת הרשאות admin לחבר אחר לפני שאתה עוזב."; +"leave_space_message" = "האתם אתה בטוח שברצונך לעזוב את %@? האם אתה מעוניין לעזוב גם את כל החדרים והמרחבים של מרחב זה?"; +"leave_space_title" = "עזוב את %@"; +"spaces_home_space_title" = "בית"; +"space_beta_announce_information" = "מרחבים הם דרך לקבץ חדרים ואנשים. הם לא ב IOS לבינתיים, אבל אתה יכול להשתמש בהם כעת ב WEB או בשולחן העבודה."; +"space_beta_announce_subtitle" = "הגרסה החדשה של קהילות"; +"space_beta_announce_badge" = "בטה"; +"spaces_explore_rooms" = "חשוף חדרים"; +"ssl_fingerprint_hash" = "טביעת אצבע (%@):"; +"call_transfer_to_user" = "העבר ל %@"; +"call_consulting_with_user" = "התייעצות עם %@"; +"call_video_with_user" = "שיחת וידאו באמצעות %@"; +"call_voice_with_user" = "חיוג קולי באמצעות %@"; +"call_more_actions_dialpad" = "מסך חיוג"; +"call_more_actions_transfer" = "העבר"; +"call_more_actions_audio_use_device" = "מכשיר רמקול"; +"call_more_actions_change_audio_device" = "החלף התקן שמע"; +"call_more_actions_unhold" = "התחל שוב"; +"call_more_actions_hold" = "החזק"; +"call_holded" = "אתה מחזיק את השיחה"; +"call_remote_holded" = "%@ מחזיק את השיחה"; +"call_invite_expired" = "פג תוקף הזמנת שיחה"; +"incoming_voice_call" = "שיחת קול נכנסת"; +"incoming_video_call" = "שיחת וידאו נכנסת"; +"call_ended" = "שיחה הסתיימה"; +"call_ringing" = "מצלצל…"; + +// Settings keys + +// call string +"call_connecting" = "מתחבר…"; + +// gcm section +"settings_config_identity_server" = "זהות שרת:%@"; +"notification_settings_notify_all_other" = "עדכן עבור כל ההודעות/החדרים האחרים"; +"notification_settings_by_default" = "בברירת מחדל..."; +"notification_settings_suppress_from_bots" = "השתק התראות מבוטים"; +"notification_settings_receive_a_call" = "עדכן אותי כאשר אני מקבל שיחה"; +"notification_settings_people_join_leave_rooms" = "עדכן אותי כאשר אנשים מצטרפים או עוזבים חדרים"; +"notification_settings_invite_to_a_new_room" = "עדכן אותי כאשר אני מוזמן לחדר חדש"; +"notification_settings_just_sent_to_me" = "עדכן אותי עם צליל עבור הודעות שנשלחות רק אליי"; +"notification_settings_contain_my_display_name" = "עדכן אותי עם צליל לגבי הודעות הכוללות תצוגת שמי"; +"notification_settings_contain_my_user_name" = "עדכן אותי עם צליל לגבי הודעות הכוללות את שם המשתמש שלי"; +"notification_settings_other_alerts" = "התראות אחרות"; +"notification_settings_highlight" = "דבר חשוב"; +"notification_settings_global_info" = "התראת הגדרות עבור החשבון שלך נשמרה ותשותף עם כל ההתקנים שתומכים בה(כולל התראות מסך).\n\nחוקים יושמו; החוק הראשון שיותאם יגדיר את התוצאה שתישלח כהודעה.\nאז:התראות עבור מלה חשובות יותר מהתראות עבור חדר שחשובות יותר מהתראות שולח.\nעבור מספר חוקים מאותו סוג, הראשון ברשימה שיימצא מתאים יקבל את העדיפות."; +"notification_settings_per_word_notifications" = "התראות מלה"; +"notification_settings_enable_notifications_warning" = "ההתראות עבור כל ההתקנים נחסמו כעת."; +"notification_settings_enable_notifications" = "אפשר התראות"; + +// Notification settings screen +"notification_settings_disable_all" = "בטל את כל ההתראות"; +"settings_title_notifications" = "התראות"; + +// Settings screen +"settings_title_config" = "תצורה"; +"settings_integrations" = "התקנה"; +"settings_identity_server_settings" = "שרת הזדהות"; +"settings_discovery_settings" = "גלוי"; +"settings_calls_settings" = "שיחות"; +"account_logout_all" = "צא מכל החשבונות"; + +// Settings +"settings_title" = "הגדרות"; +"settings_ui_theme_picker_title" = "בחר נושא"; +"settings_ui_theme_black" = "שחור"; +"settings_ui_theme_dark" = "חשוך"; +"share_extension_low_quality_video_message" = "שלח ב%@ עבור איכות משופרת, או שלח באיכות נמוכה מזו."; +"share_extension_low_quality_video_title" = "וידאו יישלח באיכות נמוכה"; +"share_extension_failed_to_encrypt" = "שליחה נכשלה. בדוק באפליקציה הראשית את הגדרות ההצפנה עבור חדר זה"; + +// Share extension +"share_extension_auth_prompt" = "התחבר אל האפליקציה הראשית על מנת לחלוק תוכן"; +"room_widget_permission_room_id_permission" = "מספר חדר"; +"room_widget_permission_widget_id_permission" = "מספר יישומון"; +"room_widget_permission_theme_permission" = "שם הנושא"; +"room_widget_permission_user_id_permission" = "מספר המשתמש שלך"; +"room_widget_permission_avatar_url_permission" = "דמות ה URL שלך"; +"room_widget_permission_display_name_permission" = "שם התצוגה שלך"; +"search_no_result" = "אין תוצאות"; +"search_people_placeholder" = "חיפוש באמצעות מספר משתמש, שם או אימייל"; +"search_filter_placeholder" = "סינון"; +"search_default_placeholder" = "חפש"; +"secrets_recovery_with_key_information_verify_device" = "השתמש במפתח האבטחה שלך ע\"מ לאשר התקן זה."; +"secrets_recovery_with_key_information_default" = "היכנס אל ההודעות המאובטחות הישנות שלך ואל זיהוי החתימה שלך ע\"מ לאשר קישורים אחרים ע\"י הכנסת מפתח האבטחה שלך."; +"room_event_action_reaction_history" = "תגובה ישנה"; +"room_event_action_reaction_show_less" = "הראה פחות"; +"room_event_action_reaction_show_all" = "הראה הכל"; +"room_event_action_edit" = "ערוך"; +"room_event_action_reply" = "תגובה"; +"room_event_action_view_encryption" = "מידע מוצפן"; +"room_event_action_cancel_download" = "בטל הורדה"; +"room_event_action_cancel_send" = "בטל שליחה"; +"room_event_action_delete_confirmation_message" = "האם אתה בטוח שברצונך למחוק הודעה זו שלא נשלחה?"; +"room_event_action_delete_confirmation_title" = "מחק הודעה שלא נשלחה"; +"room_event_action_delete" = "מחק"; +"room_event_action_resend" = "שלח שוב"; +"room_event_action_save" = "שמור"; +"room_event_action_report_prompt_ignore_user" = "האם אתה רוצה להסתיר את כל ההודעות ממשתמש זה?"; +"room_event_action_ban_prompt_reason" = "סיבה לחסימת משתמש זה"; +"room_event_action_kick_prompt_reason" = "סיבה להסרת משתמש זה"; +"room_event_action_report_prompt_reason" = "סיבה לדיווח על תוכן זה"; +"room_event_action_report" = "דווח תוכן"; +"room_event_action_view_decrypted_source" = "צפה במקור מפוענח"; +"room_event_action_view_source" = "צפה במקור"; +"room_event_action_permalink" = "העתק קישור להודעה"; +"room_event_action_view_in_room" = "צפה בתוך החדר"; +"room_event_action_forward" = "העבר"; +"room_event_action_share" = "שתף"; +"room_event_action_more" = "עוד"; +"room_event_action_redact" = "הסר"; +"room_event_action_end_poll" = "סוף הצבעה"; +"room_event_action_remove_poll" = "הסר הצבעה"; +"room_event_action_quote" = "ציטוט"; +"room_event_action_copy" = "העתק"; +"room_delete_unsent_messages" = "מחק הודעות שלא נשלחו"; +"room_resend_unsent_messages" = "שלח שוב הודעות שלא נשלחו"; +"room_prompt_cancel" = "בטל הכל"; +"room_prompt_resend" = "שלח שוב הכל"; +"room_conference_call_no_power" = "אתה צריך הרשאה על מנת לנהל שיחת ועידה בחדר זה"; +"room_ongoing_conference_call_close" = "סגור"; +"room_ongoing_conference_call_with_close" = "שיחת ועידה מתמשכת. הצטרף לזה כ%@ או %@. %@."; +"room_ongoing_conference_call" = "שיחת ועידה מתמשכת. הצטרף כ%@ או %@."; +"room_unsent_messages_cancel_message" = "אתה בטוח שברצונך למחוק את כל ההודעות שלא נשלחו בחדר זה?"; +"room_unsent_messages_cancel_title" = "מחק הודעות שלא נשלחו"; +"room_unsent_messages_unknown_devices_notification" = "הודעה נכשלה להישלח בשל קישור לא ידוע שהוצג."; +"room_unsent_messages_notification" = "הודעות נכשלו להישלח."; +"room_offline_notification" = "החיבור לשרת אבד."; +"room_message_reply_to_short_placeholder" = "שלח תגובה…"; +"room_message_short_placeholder" = "שלח הודעה…"; +"encrypted_room_message_reply_to_placeholder" = "שלח תגובה מוצפנת…"; +"encrypted_room_message_placeholder" = "שלח הודעה מוצפנת…"; +"room_do_not_have_permission_to_post" = "אין לך הרשאות לשלוח לחדר זה"; +"room_message_replying_to" = "עונה ל%@"; +"room_message_editing" = "עורך"; +"room_message_unable_open_link_error_message" = "לא יכול לפתוח את הקישור."; +"room_message_reply_to_placeholder" = "שלח תגובה (לא מוצפנת)…"; +"room_message_placeholder" = "שלח הודעה (לא מוצפנת)…"; +"room_many_users_are_typing" = "%@, %@ וגם אחרים מקלידים…"; +"room_two_users_are_typing" = "%@ & %@ מקלידים…"; +"room_one_user_is_typing" = "%@ מקליד…"; +"room_new_messages_notification" = "%@ הודעות חדשות"; +"room_new_message_notification" = "%@ הודעה חדשה"; +"room_accessiblity_scroll_to_bottom" = "גלול לתחתית"; +"room_jump_to_first_unread" = "עבור ללא נקרא"; + +// MARK: - Chat + +"room_slide_to_end_group_call" = "החלק על מנת לסיים את השיחה לכולם"; +"room_member_power_level_short_custom" = "מותאם אישית"; +"room_member_power_level_short_moderator" = "מצב"; +"room_member_power_level_short_admin" = "מנהל מערכת"; +"room_member_power_level_custom_in" = "%@ מותאם אישית ב%@"; +"room_member_power_level_moderator_in" = "מנחה ב %@"; +"room_member_power_level_admin_in" = "מנהל ב%@"; +"room_participants_security_information_room_encrypted_for_dm" = "ההודעות כאן מוצפנות קצה לקצה.\n\nההודעות שלך מאובטחות עם מנעולים ורק לך ולמקבל ההודעות יש מפתחות ייחודיים לפתוח אותם."; +"room_participants_security_information_room_encrypted" = "ההודעות בחדר זה מוצפנות קצה לקצה.\n\nההודעות שלך מאובטחות עם מנעולים ורק לך ולמקבל ההודעות יש מפתח ייחודי לפתוח אותן."; +"room_participants_security_information_room_not_encrypted_for_dm" = "ההודעות כאן אינן מוצפנות קצה לקצה."; +"room_participants_security_information_room_not_encrypted" = "הודעות בחדר זה אינן מוצפנות קצה לקצה."; +"room_participants_security_loading" = "טוען…"; +"room_participants_action_security_status_loading" = "טוען…"; +"room_participants_action_security_status_warning" = "אזהרה"; +"room_participants_action_security_status_complete_security" = "אבטחה מלאה"; +"room_participants_action_security_status_verify" = "תאשר"; +"room_participants_action_security_status_verified" = "מאומת"; +"room_participants_action_mention" = "תזכורת"; +"room_participants_action_start_video_call" = "התחל שיחת וידאו"; +"room_participants_action_start_voice_call" = "התחל שיחת קול"; +"room_participants_action_start_new_chat" = "התחל צ'אט חדש"; +"room_participants_action_set_admin" = "הפוך למנהל"; +"room_participants_action_set_moderator" = "הפוך למנחה"; +"room_participants_action_set_default_power_level" = "אפס הגדרות משתמש לברירת מחדל"; +"room_participants_action_unignore" = "הצג כל ההודעות ממשתמש זה"; +"room_participants_action_ignore" = "הסתר כל ההודעות ממשתמש זה"; +"room_participants_action_unban" = "בטל חסימה"; +"room_participants_action_ban" = "אסור מחדר זה"; +"room_participants_action_remove" = "הוצא מחדר זה"; +"room_participants_action_leave" = "עזוב חדר זה"; +"room_participants_action_invite" = "הזמן"; +"room_participants_action_section_security" = "אבטחה"; +"room_participants_action_section_other" = "אפשרויות"; +"room_participants_action_section_devices" = "ממשקים"; +"room_participants_action_section_direct_chats" = "צ'אטים ישירים"; +"room_participants_action_section_admin_tools" = "כלי מערכת"; +"room_participants_ago" = "לפני"; +"room_participants_now" = "כעת"; +"room_participants_idle" = "פנוי"; +"room_participants_unknown" = "לא ידוע"; +"room_participants_offline" = "לא זמין"; +"room_participants_online" = "זמין"; +"room_participants_start_new_chat_error_using_user_email_without_identity_server" = "לא הוגדר שרת זיהוי לכן אתה לא יכול להתחיל צ'אט עם איש קשר באמצעות אימייל."; +"room_participants_invited_section" = "מוזמן"; +"room_participants_invite_malformed_id" = "מספר מזהה לא תקין. צריך להיות כתובת אימייל או מזהה מערכת כמו 'localpart:domain@'"; +"room_participants_invite_malformed_id_title" = "שגיאת הזמנה"; +"room_participants_invite_another_user" = "חפש/הזמן באמצעות מספר מזהה, שם או כתובת מייל"; +"room_participants_filter_room_members_for_dm" = "סינון חברים"; +"room_participants_filter_room_members" = "סינון חברים בחדר"; +"room_participants_invite_prompt_msg" = "האם אתה בטוח שברצונך להזמין את %@ לצ'אט זה?"; +"room_participants_invite_prompt_title" = "אישור"; +"room_participants_remove_third_party_invite_prompt_msg" = "האם אתה בטוח שברצונך לבטל הזמנה זו?"; +"room_participants_remove_prompt_msg" = "האם אתה בטוח שברצונך להסיר את %@ מצ'אט זה?"; +"room_participants_remove_prompt_title" = "אישור"; +"room_participants_leave_success" = "עזב את החדר"; +"room_participants_leave_processing" = "עוזב"; +"room_participants_leave_prompt_msg_for_dm" = "האם אתה בטוח שברצונך לעזוב?"; +"room_participants_leave_prompt_msg" = "האם אתה בטוח שברצונך לעזוב את החדר?"; +"room_participants_leave_prompt_title_for_dm" = "עזוב"; +"room_participants_leave_prompt_title" = "עזוב חדר"; +"room_participants_multi_participants" = "%@ משתתפים"; +"room_participants_one_participant" = "משתתף 1"; +"room_participants_add_participant" = "הוסף משתתף"; + +// Chat participants +"room_participants_title" = "משתתפים"; +"find_your_contacts_identity_service_error" = "לא ניתן להתחבר לשרת הזיהוי."; +"find_your_contacts_footer" = "ניתן לחסום זאת בכל זמן דרך תפריט הגדרות."; +"find_your_contacts_button_title" = "חפש את אנשי הקשר שלך"; +"find_your_contacts_message" = "אפשר ל%@ להציג את רשימת אנשי הקשר שלך על מנת שתוכל לפתוח צ'אט במהירות עם אלה שאתה מכיר הכי טוב."; +"find_your_contacts_title" = "התחל ע\"י הצגת רשימת אנשי הקשר שלך"; +"contacts_user_directory_offline_section" = "ספריית משתמש (במצב לא מקוון)"; +"contacts_user_directory_section" = "ספריית משתמש"; +"contacts_address_book_permission_denied_alert_message" = "על מנת לאפשר גישה לרשימת אנשי קשר, עבור להגדרות המכשיר שלך."; +"contacts_address_book_permission_denied_alert_title" = "גישה לרשימת אנשי קשר נחסמה"; +"contacts_address_book_permission_denied" = "לא אישרת ל %@ גישה לרשימת אנשי הקשר שלך"; +"contacts_address_book_permission_required" = "נדרשת הרשאה עבור גישה לרשימת אנשי הקשר"; +"contacts_address_book_no_contact" = "אין אנשי קשר לוקליים"; +"contacts_address_book_no_identity_server" = "לא הוגדר שרת זיהוי"; +"contacts_address_book_matrix_users_toggle" = "משתמשי מטריצה בלבד"; + +// Contacts +"contacts_address_book_section" = "אנשי קשר מקומיים"; +"directory_searching_title" = "מחפש ספריות…"; +"directory_search_results_more_than" = ">% תוצאות נמצאו עבור %@"; +"directory_search_results" = "% תוצאות נמצאו עבור %@"; +"directory_search_results_title" = "דפדף תוצאות ספרייה"; +"directory_cell_description" = "% חדרים"; + +// Directory +"directory_cell_title" = "דפדף תיקייה"; +"search_in_progress" = "מחפש…"; +"search_files" = "קבצים"; +"search_people" = "אנשים"; +"search_messages" = "הודעות"; + +// Search +"search_rooms" = "חדרים"; +"group_section" = "קהילות"; + +// Groups tab +"group_invite_section" = "הזמנות"; +"rooms_empty_view_information" = "חדרים הם דבר נפלא עבור כל קבוצת צ'אט , פרטית או ציבורית. הקש + על מנת לחפש חדרים קיימים, או צור חדשים."; +"rooms_empty_view_title" = "חדרים"; + +// Rooms tab +"room_directory_no_public_room" = "אין חדרים ציבוריים זמינים"; +"people_empty_view_information" = "השתמש בצ'אט בצורה בטוחה עם כל אחד. הקש + על מנת להוסיף אנשים."; +"people_empty_view_title" = "אנשים"; +"people_no_conversation" = "אין שיחות"; +"people_conversation_section" = "שיחות"; + +// People tab +"people_invites_section" = "הזמנות"; +"room_recents_unknown_room_error_message" = "חדר זה לא נמצא.וודא האם הוא קיים"; +"room_recents_join_room_prompt" = "הכנס מספר או כינוי חדר"; +"room_recents_join_room_title" = "הצטרף לחדר"; +"room_recents_join_room" = "הצטרף לחדר"; +"room_recents_create_empty_room" = "צור חדר"; +"room_recents_start_chat_with" = "התחל צ'אט"; +"room_recents_suggested_rooms_section" = "חדרים מומלצים"; +"room_recents_invites_section" = "הזמנות"; +"room_recents_server_notice_section" = "התראות מערכת"; +"room_recents_low_priority_section" = "הרשאה נמוכה"; +"room_recents_no_conversation" = "אין חדרים"; +"room_recents_conversations_section" = "חדרים"; +"room_recents_people_section" = "אנשים"; +"room_recents_favourites_section" = "מועדפים"; + +// Room recents +"room_recents_directory_section" = "ספריית חדר"; +"room_creation_dm_error" = "לא הצלחנו ליצור את מנהל ההתקן. אנא בדוק את המשתמשים אותם אתה מעוניין להזמין ונסה שוב."; +"social_login_list_title_sign_up" = "או"; +"social_login_list_title_sign_in" = "או"; + +// Social login + +"social_login_list_title_continue" = "המשך עם"; +"auth_softlogout_clear_data_sign_out_msg" = "האם אתה בטוח שברצונך למחוק את כל המידע השמור כרגע במכשיר זה? התחבר שוב על מנת לגשת לחשבון המידע וההודעות שלך."; +"auth_softlogout_clear_data_message_2" = "מחק אותו שם סיימת להשתמש במכשיר זה, או אם אתה מעוניין להתחבר לחשבון אחר."; +"auth_softlogout_clear_data_message_1" = "זהירות:המידע האישי שלך (כולל מפתחות הצפנה) עדיין שמור במכשיר זה."; +"auth_softlogout_recover_encryption_keys" = "התחבר על מנת לשחזר את מפתחות ההצפנה השמור בצורה בלעדית במכשיר זה. תצטרך אותם על מנת לקרא את כל ההודעות המאובטחות שלך בכל מכשיר."; +"auth_softlogout_reason" = "מנהל שרת הבית שלך (% 1 $@) הוציא אותך החוצה מהחשבון שלך % 2 $@ (% 3 $@)."; +"auth_autodiscover_invalid_response" = "תגובת חשיפה לא חוקית של שרת הבית"; +"auth_accept_policies" = "אנא עבור ואשר את המדיניות בשרת הבית הזה:"; +"auth_add_email_and_phone_warning" = "רישום באמצעות מייל ומספר טלפון יחד לא נתמך עדיין עד שה API קיים. רק מספר הטלפון יילקח בחשבון. תוכל להוסיף את כתובת המייל שלך בהגדרות הפרופיל שלך."; +"auth_reset_password_error_is_required" = "לא הוגדר שרת זיהוי: הוסף אחד באפשרויות שרת על מנת לאפס את סיסמת חשבון המטריצה שלך."; +"auth_reset_password_error_not_found" = "כתובת המייל שלך לא מופיעה כמשוייכת למספר המטריצה בשרת הבית הזה."; +"auth_reset_password_email_validation_message" = "אי מייל נשלח אל %@. ברגע שתעקוב הלינק המצורף, הקלק עליו."; +"auth_reset_password_missing_email" = "חובה להכניס את כתובת המייל המשוייכת לחשבון שלך."; +"auth_reset_password_message" = "על מנת לאפס את סיסמת החשבון שלך, הכנס את כתובת המייל המשוייכת לחשבון שלך:"; +"auth_msisdn_validation_title" = "ממתין לאימות"; +"auth_email_validation_message" = "אנא בדוק את כתובת המייל ע\"מ להמשיך ברישום"; +"auth_use_server_options" = "השתמש באפשרות שרת מותאמות אישית (מתקדמת)"; +"auth_email_not_found" = "שליחת הודעה נכשלה:כתובת מייל זו לא נמצאה"; +"auth_forgot_password_error_no_configured_identity_server" = "לא הוגדר שרת זיהוי:הוסף אחד על מנת לאפס את סיסמת החשבון שלך."; +"auth_forgot_password" = "שכחת את סיסמת החשבון?"; +"auth_untrusted_id_server" = "שרת הזיהוי אינו מהימן"; +"auth_phone_is_required" = "לא הוגדר שרת זיהוי לכן אתה לא יכול להוסיף מספר טלפון על מנת לאפס את סיסמת החשבון שלך בעתיד."; +"auth_email_is_required" = "לא הוגדר שרת זיהוי לכן אתה לא יכול להוסיף כתובת מייל על מנת לאפס את סיסמת החשבון שלך בעתיד."; +"auth_add_email_phone_message_2" = "הגדר כתובת מייל עבור שחזור חשבון. השתמש במייל עדכני או טלפון על מנת להיות מזוהה ע\"י אנשים שמכירים אותך."; +"auth_identity_server_placeholder" = "דף (https://vector.im לדוגמא)"; +"auth_repeat_new_password_placeholder" = "אשר את סיסמת החשבון החדשה שלך"; +"onboarding_use_case_message" = "אנחנו נעזור לך להתחבר."; +"onboarding_use_case_title" = "עם מי תהיה לרוב בצ'אט?"; + +// Accessibility +"accessibility_checkbox_label" = "תיבת סימון"; +"store_promotional_text" = "צ'אט הגנה על פרטיות ואפליקציית שיתוף, ברשת פתוחה. מבוזרים על מנת לשמור אותך בבקרה. ללא כריית מידע, דלתות אחוריות או גישה של צד שלישי."; +"sign_up" = "הירשם"; +"dismiss" = "לדחות"; + +// Banner + +"secure_backup_setup_banner_title" = "גיבוי מאובטח"; +"secure_key_backup_setup_cancel_alert_message" = "אם תבטל כעת, אתה עלול לאבד הודעות מוצפנות ומידע אם תאבד את הגישה שלך.\n\nאתה יכול להגדיר גם גיבוי מאובטח ולנהל את המפתחות שלך בהגדרות."; + + +// Cancel + +"secure_key_backup_setup_cancel_alert_title" = "האם אתה בטוח?"; +"secure_key_backup_setup_existing_backup_error_delete_it" = "מחק זאת"; +"secure_key_backup_setup_existing_backup_error_unlock_it" = "פתח נעילה זו"; +"secure_key_backup_setup_existing_backup_error_info" = "בטל נעילה זו על מנת להשתמש בזה בגיבוי מאובטח או מחק זאת על מנת ליצור גיבוי הודעות חדש בגיבוי המאובטח."; +"secure_key_backup_setup_existing_backup_error_title" = "גיבוי להודעות כבר קיים"; +"secure_key_backup_setup_intro_use_security_passphrase_info" = "השתמש בביטוי סודי שרק אתה יודע, וחולל מפתח לגיבוי."; +"secure_key_backup_setup_intro_use_security_passphrase_title" = "השתמש בביטוי מאובטח"; +"secure_key_backup_setup_intro_use_security_key_info" = "חולל מפתח הצפנה כדי לשמור במקום בטוח כגון מנהל הצפנה או כספת."; +"secure_key_backup_setup_intro_use_security_key_title" = "השתמש במפתח אבטחה"; +"secure_key_backup_setup_intro_info" = "אמצעי אבטחה למניעת איבוד גישה של הודעות מוצפנות ומידע באמצעות גיבוי מפתחות הצפנה בשרת שלך."; + +// MARK: Secure backup setup + +// Intro + +"secure_key_backup_setup_intro_title" = "גיבוי מאובטח"; +"rerequest_keys_alert_message" = "שלח בבקשה את %@ בהתקן אחר שיכול לפענח את ההודעה כך שניתן יהיה לשלוח את המפתח בממשק זה."; + +// Re-request confirmation dialog +"rerequest_keys_alert_title" = "בקשה נשלחה"; +"room_event_failed_to_send" = "שליחה נכשלה"; +"room_warning_about_encryption" = "הצפנה קצה לקצה בפיתוח ולא ניתן לסמוך על כך.\n\nאתה עדיין לא יכול לסמוך על זה בשמירה על מידע.\n\nהתקנים עדיין לא יוכלו לפענח היסטוריה מלפני השלב בו הצטרפו לחדר.\n\nהודעות מוצפנות לא יוכלו להיות נצפות ע\"י משתמשים שטרם התקינו הצפנה."; +"room_event_copy_link_info" = "לינק הועתק ללוח הכתיבה."; +"settings_integrations_allow_button" = "נהל שילובים"; +"settings_calls_stun_server_fallback_description" = "אפשר שרת סיוע לשיחות חלופיות %@ כאשר שרת הבית שלך לא מציע כזו (כתובת ה IP שלך תשותף במהלך השיחה)."; +"settings_calls_stun_server_fallback_button" = "אפשר שרת סיוע לשיחות חלופיות"; +"settings_callkit_info" = "קבל שיחות נכנסות במסך הנעילה שלך. ראה את %@ השיחות שלך בהיסטורית השיחות של המערכת. אם iCloud מאופשר, היסטורית שיחות אלה תשותף עם Apple."; +"settings_enable_callkit" = "שיחות משולבות"; +"settings_mentions_and_keywords_encryption_notice" = "לא תקבל הודעות עבור תזכורות ומפתחות מלים בחדרים מוצפנים בסלולרי."; +"settings_new_keyword" = "הוסף מלת מפתח חדשה"; +"settings_your_keywords" = "מפתח המלים שלך"; +"key_backup_recover_done_action" = "בוצע"; + +// Success + +"key_backup_recover_success_info" = "גיבוי שוחזר!"; +"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "אבדת את מפתח האבטחה שלך אתה יכול להגדיר חדש בתפריט הגדרות."; +"key_backup_recover_from_recovery_key_recover_action" = "פתח הסטוריה מנעילה"; +"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "הכנס מפתח אבטחה"; +"key_backup_recover_from_recovery_key_recovery_key_title" = "הכנס"; + +// Recover from recovery key + +"key_backup_recover_from_recovery_key_info" = "השתמש במפתח האבטחה שלך על מנת לפתוח את הסטורית ההודעות שלך"; +"key_backup_recover_from_passphrase_lost_passphrase_action_part3" = "."; +"key_backup_recover_from_passphrase_lost_passphrase_action_part2" = "השתמש במפתח האבטחה שלך"; +"key_backup_recover_from_passphrase_lost_passphrase_action_part1" = "לא יודע את את ביטוי האבטחה שלך? אתה יכול "; +"key_backup_recover_from_passphrase_recover_action" = "בטל נעילת היסטוריה"; +"key_backup_recover_from_passphrase_passphrase_placeholder" = "הכנס ביטוי"; +"key_backup_recover_from_passphrase_passphrase_title" = "הכנס"; + +// Recover from passphrase + +"key_backup_recover_from_passphrase_info" = "השתמש בביטוי האבטחה שלך על מנת לפתוח הסטורית הודעות מאובטחת"; + +// Recover from private key +"key_backup_recover_from_private_key_info" = "משחזר גיבוי…"; +"key_backup_recover_invalid_recovery_key" = "הגיבוי לא יכול להיות מפוענח באמצעות מפתח זה: אנא וודא שהכנסת את מפתח האבטחה הנכון."; +"key_backup_recover_invalid_recovery_key_title" = "מפתח אבטחה לא תואם"; +"key_backup_recover_invalid_passphrase" = "הגיבוי לא יכול להיות מפוענח עם ביטוי זה: אנא וודא שהכנסת את ביטוי האבטחה הנכון."; +"key_backup_recover_invalid_passphrase_title" = "ביטוי אבטחה לא תקין"; + +// MARK: Key backup recover + +"key_backup_recover_title" = "הודעות מאובטחות"; + +// Success from secure backup +"key_backup_setup_success_from_secure_backup_info" = "המפתחות שלך מגובים."; +"key_backup_setup_success_from_recovery_key_made_copy_action" = "ביצעתי עותק"; +"key_backup_setup_success_from_recovery_key_make_copy_action" = "בצע עותק"; +"key_backup_setup_success_from_recovery_key_recovery_key_title" = "מפתח אבטחה"; + +// Success from recovery key +"key_backup_setup_success_from_recovery_key_info" = "המפתחות שלך גובו.\n\nהעתק את מפתח ההצפנה ושמור אותו בטוח."; +"key_backup_setup_success_from_passphrase_done_action" = "בוצע"; +"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "שמור מפתח אבטחה"; + +// Success from passphrase +"key_backup_setup_success_from_passphrase_info" = "המפתחות שלך גובו.\n\nמפתח האבטחה שלך הוא רשת ביטחון - אתה יכול לעשות בו שימוש לשחזור הגישה להודעות המוצפנות שלך אם שכחת את ביטוי הסיסמה שלך.\n\nשמור את מפתח האבטחה שלך במקום מאובטח ביותר, כגון מנהל סיסמאות (או כספת)."; + +// Success + +"key_backup_setup_success_title" = "הצלחה!"; +"key_backup_setup_passphrase_setup_recovery_key_action" = "(מתקדם) הגדרה עם מפתח אבטחה"; +"key_backup_setup_passphrase_setup_recovery_key_info" = "או, אבטח את הגיבוי שלך עם מפתח אבטחה, שמור אותו במקום בטוח."; +"key_backup_setup_passphrase_set_passphrase_action" = "בחר ביטוי"; +"key_backup_setup_passphrase_confirm_passphrase_invalid" = "ביטוי לא תואם"; +"key_backup_setup_passphrase_confirm_passphrase_valid" = "מעולה!"; +"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "אשר ביטוי"; +"key_backup_setup_passphrase_confirm_passphrase_title" = "אשר"; +"key_backup_setup_passphrase_passphrase_invalid" = "נסה להוסיף מלה"; +"key_backup_setup_passphrase_passphrase_valid" = "מעולה!"; +"key_backup_setup_passphrase_passphrase_placeholder" = "הכנס ביטוי"; +"key_backup_setup_passphrase_passphrase_title" = "הכנס"; +"key_backup_setup_passphrase_info" = "אנחנו נשמור גיבוי מוצפן של המפתחות שלך בשרת שלנו. הגן על הגיבוי שלך באמצעות ביטוי על מנת להשאיר אותו בטוח.\n\nלאבטחה מקסימלית, זה אמור להיות שונה מסיסמת החשבון שלך."; + +// Passphrase + +"key_backup_setup_passphrase_title" = "אבטח את הגיבוי שלך באמצעות ביטוי מאובטח"; +"key_backup_setup_intro_manual_export_action" = "הוצא מפתחות בצורה ידנית"; +"key_backup_setup_intro_manual_export_info" = "(מתקדם)"; +"key_backup_setup_intro_setup_connect_action_with_existing_backup" = "חבר התקן זה לגיבוי מפתח"; +"key_backup_setup_intro_setup_action_without_existing_backup" = "התחל להשתמש בגיבוי מפתח"; +"key_backup_setup_intro_info" = "הודעות בחדרים מוצפנים הן מאובטחות קצה לקצה. רק לך ולמקבל(ים) יש את המפתחות לקרוא הודעות אלה.\n\nגבה בצורה מאובטחת את המפתחות שלך על מנת להימנע מלאבד אותם."; + +// Intro + +"key_backup_setup_intro_title" = "אף פעם אל תאבד הודעות מוצפנות"; +"key_backup_setup_skip_alert_skip_action" = "דלג"; +"key_backup_setup_skip_alert_message" = "אתה עלול לאבד הודעות מאובטחות אם תתנתק או תאבד את המכשיר שלך."; +"key_backup_setup_skip_alert_title" = "האם אתה בטוח?"; + + +// MARK: Key backup setup + +"key_backup_setup_title" = "גיבוי מפתח"; +"secure_backup_setup_banner_subtitle" = "אמצעי אבטחה למניעת איבוד גישה להודעות מוצפנות ומידע"; +"settings_confirm_media_size" = "אשר גודל בזמן שליחה"; +"settings_three_pids_management_information_part3" = "."; +"settings_three_pids_management_information_part2" = "גלוי"; +"settings_three_pids_management_information_part1" = "קבע איזה כתובות אימייל או מספרי טלפון אתה יכול לעשות בהם שימוש להתחברות או לשחזור החשבון שלך כאן. החלט מי יכול למצא אותך ב "; +"settings_fail_to_update_profile" = "כשלון בעדכון הפרופיל"; +"settings_night_mode" = "מצב לילה"; +"settings_change_password" = "שנה סיסמת חשבון מטריקס"; +"settings_add_phone_number" = "הוסף מספר טלפון"; +"settings_phone_number" = "טלפון"; +"settings_add_email_address" = "הוסף כתובת אימייל"; +"settings_email_address_placeholder" = "הכנס את כתובת האימייל שלך"; +"settings_email_address" = "אימייל"; +"settings_display_name" = "הצג שם"; +"settings_profile_picture" = "תמונת פרופיל"; +"settings_sign_out_e2e_warn" = "אתה תאבד את מפתחות ההצפנה קצה לקצה. המשמעות היא שלא תוכל יותר לקרא הודעות ישנות בחדרים מוצפנים בהתקן זה."; +"settings_sign_out_confirmation" = "האם אתה בטוח?"; +"settings_ui_theme_light" = "אור"; +"settings_ui_theme_auto" = "אוטומטי"; +"settings_ui_theme" = "נושא"; +"settings_ui_language" = "שפה"; +"settings_integrations_allow_description" = "השתמש במנהל שילובים (%@) לניהול בוטים, גשרי ועידה, וו'ידגטים ומדבקות.\n\nמנהלי שילובים מקבלים נתוני תצורה, ויכולים להגדיר וו'ידגטים, לשלוח הזמנות חדרים ורמות הספק בשמך."; diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings index cca7148ed..757189a94 100644 --- a/Riot/Assets/hu.lproj/Vector.strings +++ b/Riot/Assets/hu.lproj/Vector.strings @@ -2136,3 +2136,5 @@ "home_syncing" = "Szinkronizálás"; "room_participants_leave_success" = "Szobából kilépve"; "room_participants_leave_processing" = "Távozás"; +"notice_error_unformattable_event" = "** Az üzenetet nem lehet megjeleníteni. Kérlek jelezd ezt a hibát"; +"settings_labs_use_only_latest_user_avatar_and_name" = "A felhasználó jelenlegi profilképének és nevének megjelenítése a régi üzeneteknél is"; diff --git a/Riot/Assets/id.lproj/Vector.strings b/Riot/Assets/id.lproj/Vector.strings index 7940ead90..50b6eba23 100644 --- a/Riot/Assets/id.lproj/Vector.strings +++ b/Riot/Assets/id.lproj/Vector.strings @@ -298,7 +298,7 @@ "emoji_picker_flags_category" = "Bendera"; "emoji_picker_symbols_category" = "Simbol"; "emoji_picker_objects_category" = "Benda"; -"emoji_picker_activity_category" = "Aktifitas"; +"emoji_picker_activity_category" = "Aktivitas"; // MARK: Emoji picker "emoji_picker_title" = "Reaksi"; @@ -1859,7 +1859,7 @@ "login_error_resource_limit_exceeded_title" = "Melebihi Batas Sumber"; "login_desktop_device" = "Desktop"; "login_tablet_device" = "Tablet"; -"login_mobile_device" = "Mobile"; +"login_mobile_device" = "Ponsel"; "login_error_forgot_password_is_not_supported" = "Lupa kata sandi saat ini belum didukung"; "register_error_title" = "Pendaftaran Gagal"; "login_invalid_param" = "Parameter tidak valid"; @@ -1947,7 +1947,7 @@ "notification_settings_per_sender_notifications" = "Notifikasi per pengirim"; "notification_settings_per_room_notifications" = "Notifikasi per ruangan"; "notification_settings_custom_sound" = "Suara kustom"; -"notification_settings_highlight" = "Highlight"; +"notification_settings_highlight" = "Sorotan"; "notification_settings_word_to_match" = "kata untuk dicocokkan"; "notification_settings_never_notify" = "Jangan diberitahu"; "notification_settings_always_notify" = "Selalu diberitahu"; @@ -2333,3 +2333,5 @@ "home_syncing" = "Menyinkronkan"; "room_participants_leave_success" = "Telah keluar dari ruangan"; "room_participants_leave_processing" = "Meninggalkan"; +"notice_error_unformattable_event" = "** Tidak dapat memuat pesan. Mohon laporkan sebuah kutu"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Tampilkan avatar dan nama terkini untuk pengguna di riwayat pesan"; diff --git a/Riot/Assets/is.lproj/InfoPlist.strings b/Riot/Assets/is.lproj/InfoPlist.strings index 8b1378917..ea0b89629 100644 --- a/Riot/Assets/is.lproj/InfoPlist.strings +++ b/Riot/Assets/is.lproj/InfoPlist.strings @@ -1 +1,10 @@ + +"NSLocationWhenInUseUsageDescription" = "Þegar þú deilir staðsetningunni þinni með öðru fólki, þarf Element aðgang að henni til að geta birt hana á landakorti."; +"NSFaceIDUsageDescription" = "Face ID er notað til að fá aðgang að forritinu þínu."; +"NSCalendarsUsageDescription" = "Skoðaðu áætlaða fundi þína í forritinu."; +"NSContactsUsageDescription" = "Element mun birta tengiliðina þína svo þú getir boðið þeim að spjalla."; +"NSMicrophoneUsageDescription" = "Element þarf að fá aðgang að hljóðnemanum þínum fyrir símtöl, upptöku á myndskeiðum og upptöku talskilaboða."; +"NSPhotoLibraryUsageDescription" = "Myndasafnið er notað til að senda myndir og myndskeið."; +// Permissions usage explanations +"NSCameraUsageDescription" = "Myndavélin er notuð til að taka myndir og myndskeið og fyrir myndsímtöl."; diff --git a/Riot/Assets/is.lproj/Localizable.strings b/Riot/Assets/is.lproj/Localizable.strings index 8b1378917..562f6da4b 100644 --- a/Riot/Assets/is.lproj/Localizable.strings +++ b/Riot/Assets/is.lproj/Localizable.strings @@ -1 +1,170 @@ + + +/** Media Messages **/ + +/* New image message from a specific person, not referencing a room. */ +"PICTURE_FROM_USER" = "%@ sendi mynd"; + +/** Key verification **/ + +"KEY_VERIFICATION_REQUEST_FROM_USER" = "%@ vill sannreyna"; + +/* Group call from user, CallKit caller name */ +"GROUP_CALL_FROM_USER" = "%@ (hópsímtal)"; + +/* A user added a Jitsi call to a room */ +"GROUP_CALL_STARTED" = "Hópsímtal er byrjað"; + +/* Incoming named video conference invite from a specific person */ +"VIDEO_CONF_NAMED_FROM_USER" = "Myndsamtal í hópi frá %@: '%@'"; + +/* Incoming named voice conference invite from a specific person */ +"VOICE_CONF_NAMED_FROM_USER" = "Hópsímtal frá %@: '%@'"; + +/* Incoming unnamed video conference invite from a specific person */ +"VIDEO_CONF_FROM_USER" = "Myndsamtal í hópi frá %@"; + +/* Incoming unnamed voice conference invite from a specific person */ +"VOICE_CONF_FROM_USER" = "Hópsímtal frá %@"; + +/* Incoming one-to-one video call */ +"VIDEO_CALL_FROM_USER" = "Myndsamtal frá %@"; + +/** Calls **/ + +/* Incoming one-to-one voice call */ +"VOICE_CALL_FROM_USER" = "Símtal frá %@"; + +/* A user's membership has updated in an unknown way */ +"USER_MEMBERSHIP_UPDATED" = "%@ uppfærði notandasniðið sitt"; + +/* A user has change their avatar */ +"USER_UPDATED_AVATAR" = "%@ breytti auðkennismynd sinni"; + +/* A user has change their name to a new name which we don't know */ +"GENERIC_USER_UPDATED_DISPLAYNAME" = "%@ breytti nafni sínu"; + +/** Membership Updates **/ + +/* A user has change their name to a new name */ +"USER_UPDATED_DISPLAYNAME" = "%@ breyttu nafni sínu í %@"; + +/* A user has invited you to a named room */ +"USER_INVITE_TO_NAMED_ROOM" = "%@ bauð þér í %@"; + +/* A user has invited you to an (unamed) group chat */ +"USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ bauð þér að taka þátt í hópspjalli"; + +/** Invites **/ + +/* A user has invited you to a chat */ +"USER_INVITE_TO_CHAT" = "%@ hefur boðið þér að spjalla"; + +/* A user has reacted to a message, but the reaction content is unknown */ +"GENERIC_REACTION_FROM_USER" = "%@ sendi viðbrögð"; + +/** Reactions **/ + +/* A user has reacted to a message, including the reaction e.g. "Alice reacted 👍". */ +"REACTION_FROM_USER" = "%@ brást við með %@"; + +/* Look, stuff's happened, alright? Just open the app. */ +"MSGS_IN_TWO_PLUS_ROOMS" = "@ ný skilaboð í %@, %@ og víðar"; + +/* Multiple messages in two rooms */ +"MSGS_IN_TWO_ROOMS" = "%@ ný skilaboð í %@ og %@"; + +/* Multiple unread messages from two plus people (ie. for 4+ people: 'others' replaces the third person) */ +"MSGS_FROM_TWO_PLUS_USERS" = "%@ ný skilaboð frá %@, %@ og fleirum"; + +/* Multiple unread messages from three people */ +"MSGS_FROM_THREE_USERS" = "%@ ný skilaboð frá %@, %@ og %@"; + +/* Multiple unread messages from two people */ +"MSGS_FROM_TWO_USERS" = "%@ ný skilaboð frá %@ og %@"; + +/* Multiple unread messages from a specific person, not referencing a room */ +"MSGS_FROM_USER" = "%@ ný skilaboð í %@"; + +/** Coalesced messages **/ + +/* Multiple unread messages in a room */ +"UNREAD_IN_ROOM" = "%@ ný skilaboð í %@"; + +/* New message with hidden content due to PIN enabled */ +"MESSAGE_PROTECTED" = "Ný skilaboð"; + +/* New message indicator on a room */ +"MESSAGE_IN_X" = "Skilaboð í %@"; + +/* New message indicator from a DM */ +"MESSAGE_FROM_X" = "Skilaboð frá %@"; + +/** Notification messages **/ + +/* New message indicator on unknown room */ +"MESSAGE" = "Skilaboð"; + +/* Sticker from a specific person, not referencing a room. */ +"STICKER_FROM_USER" = "%@ sendi límmerki"; + +/* A single unread message */ +"SINGLE_UNREAD" = "Þú hefur fengið skilaboð"; + +/* A single unread message in a room */ +"SINGLE_UNREAD_IN_ROOM" = "Þú hefur fengið skilaboð í %@"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ hefur deilt staðsetningu sinni"; + +/* New file message from a specific person, not referencing a room. */ +"FILE_FROM_USER" = "%@ sendi skrá %@"; + +/* New voice message from a specific person, not referencing a room. */ +"VOICE_MESSAGE_FROM_USER" = "%@ sendi talskilaboð"; + +/* New audio message from a specific person, not referencing a room. */ +"AUDIO_FROM_USER" = "%@ sendi hljóðskrá %@"; + +/* New video message from a specific person, not referencing a room. */ +"VIDEO_FROM_USER" = "%@ sendi myndskeið"; + +/* New image message from a specific person in a named room. */ +"IMAGE_FROM_USER_IN_ROOM" = "%@ birti mynd %@ í %@"; + +/* New action message from a specific person in a named room. */ +"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@"; + +/* New action message from a specific person, not referencing a room. */ +"ACTION_FROM_USER" = "* %@ %@"; + +/* New message from a specific person in a named room. Content included. */ +"MSG_FROM_USER_IN_ROOM_WITH_CONTENT" = "%@ í %@: %@"; + +/** Single, unencrypted messages (where we can include the content */ + +/* New message from a specific person, not referencing a room. Content included. */ +"MSG_FROM_USER_WITH_CONTENT" = "%@: %@"; + +/* New message from a specific person in a named room */ +"MSG_FROM_USER_IN_ROOM" = "%@ birti í %@"; + +/** Single, end-to-end encrypted messages (ie. we don't know what they say) */ + +/* New message from a specific person, not referencing a room */ +"MSG_FROM_USER" = "%@ sendi skilboð"; + +/* New message reply from a specific person in a named room. */ +"REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ svaraði í %@"; + +/* New message reply from a specific person, not referencing a room. */ +"REPLY_FROM_USER_TITLE" = "%@ svaraði"; + +/** Titles **/ + +/* Message title for a specific person in a named room */ +"MSG_FROM_USER_IN_ROOM_TITLE" = "%@ í %@"; +/** General **/ + +"NOTIFICATION" = "Tilkynning"; diff --git a/Riot/Assets/is.lproj/Vector.strings b/Riot/Assets/is.lproj/Vector.strings index 2c53b14b6..069a72d7e 100644 --- a/Riot/Assets/is.lproj/Vector.strings +++ b/Riot/Assets/is.lproj/Vector.strings @@ -1,5 +1,5 @@ // Titles -"title_home" = "Heim"; +"title_home" = "Forsíða"; "title_favourites" = "Eftirlæti"; "title_people" = "Fólk"; "title_rooms" = "Spjallrásir"; @@ -46,7 +46,7 @@ "auth_optional_phone_placeholder" = "Símanúmer (valfrjálst)"; "auth_phone_placeholder" = "Símanúmer"; "auth_repeat_password_placeholder" = "Endurtaka lykilorð"; -"auth_repeat_new_password_placeholder" = "Staðfestu nýtt lykilorð"; +"auth_repeat_new_password_placeholder" = "Staðfestu nýtt lykilorð á Matrix-aðganginn þinn"; "auth_invalid_login_param" = "Rangt notandanafn og/eða lykilorð"; "auth_invalid_user_name" = "Notandanöfn mega einungis innihalda bókstafi, tölustafi, punkta, bandstrik eða undirstrik"; "auth_invalid_password" = "Lykilorð er of stutt (lágmark 6 stafir)"; @@ -56,12 +56,12 @@ "auth_missing_email_or_phone" = "Vantar tölvupóstfang eða símanúmer"; "auth_password_dont_match" = "Lykilorðin stemma ekki"; "auth_username_in_use" = "Notandanafn er í notkun"; -"auth_forgot_password" = "Gleymt lykilorð?"; +"auth_forgot_password" = "Gleymt lykilorð á Matrix-notandaaðgangi?"; "auth_msisdn_validation_title" = "Sannvottun í bið"; "room_creation_account" = "Notandaaðgangur"; "room_creation_appearance" = "Útlit"; "room_creation_appearance_name" = "Heiti"; -"room_creation_privacy" = "Meðferð persónuupplýsinga"; +"room_creation_privacy" = "Friðhelgi"; "room_creation_make_private" = "Gera einka"; "room_recents_favourites_section" = "Eftirlæti"; "room_recents_people_section" = "FÓLK"; @@ -95,7 +95,7 @@ "contacts_address_book_section" = "TENGILIÐIR Á TÆKI"; "contacts_address_book_matrix_users_toggle" = "Einungis notendur Matrix"; "room_participants_leave_prompt_title" = "Fara af spjallrás"; -"room_participants_leave_prompt_msg" = "Ertu viss um að þú viljir fara út spjallrásinni?"; +"room_participants_leave_prompt_msg" = "Ertu viss um að þú viljir fara út úr spjallrásinni?"; "room_participants_remove_prompt_title" = "Staðfesting"; "room_participants_invite_prompt_title" = "Staðfesting"; "room_participants_filter_room_members" = "Sía meðlimi spjallrásar"; @@ -107,8 +107,8 @@ "room_participants_ago" = "síðan"; "room_participants_action_section_admin_tools" = "Kerfisstjóratól"; "room_participants_action_section_direct_chats" = "Beint spjall"; -"room_participants_action_section_devices" = "Tæki"; -"room_participants_action_section_other" = "Annað"; +"room_participants_action_section_devices" = "Setur"; +"room_participants_action_section_other" = "Valkostir"; "room_participants_action_invite" = "Bjóða"; "room_participants_action_leave" = "Fara af spjallrás"; "room_participants_action_remove" = "Fjarlægja úr þessari spjallrás"; @@ -116,8 +116,8 @@ "room_participants_action_unban" = "Afbanna"; "room_participants_action_set_admin" = "Gera að stjórnanda"; "room_participants_action_start_new_chat" = "Hefja nýtt spjall"; -"room_participants_action_start_voice_call" = "Hefja raddsamtal"; -"room_participants_action_start_video_call" = "Hefja myndsamtal"; +"room_participants_action_start_voice_call" = "Hefja raddsímtal"; +"room_participants_action_start_video_call" = "Hefja myndsímtal"; "room_new_message_notification" = "%d ný skilaboð"; "room_new_messages_notification" = "%d ný skilaboð"; "room_one_user_is_typing" = "%@ er að skrifa…"; @@ -129,10 +129,10 @@ "room_prompt_cancel" = "hætta við allt"; "room_event_action_copy" = "Afrita"; "room_event_action_quote" = "Tilvitnun"; -"room_event_action_redact" = "Ritstýra"; +"room_event_action_redact" = "Fjarlægja"; "room_event_action_more" = "Meira"; "room_event_action_share" = "Deila"; -"room_event_action_permalink" = "Varanlegur tengill"; +"room_event_action_permalink" = "Afrita tengil á skilaboð"; "room_event_action_view_source" = "Skoða frumkóða"; "room_event_action_save" = "Vista"; "room_event_action_resend" = "Endursenda"; @@ -157,10 +157,10 @@ "settings_calls_settings" = "SAMTÖL"; "settings_user_interface" = "NOTANDAVIÐMÓT"; "settings_ignored_users" = "HUNSAÐIR NOTENDUR"; -"settings_contacts" = "TENGILIÐIR Á TÆKI"; +"settings_contacts" = "TENGILIÐIR TÆKIS"; "settings_advanced" = "ÍTARLEGT"; -"settings_other" = "ANNAÐ"; -"settings_devices" = "TÆKI"; +"settings_other" = "Annað"; +"settings_devices" = "SETUR"; "settings_cryptography" = "DULRITUN"; "settings_sign_out" = "Skrá út"; "settings_sign_out_confirmation" = "Ertu viss?"; @@ -186,27 +186,27 @@ "settings_olm_version" = "Útgáfa olm %@"; "settings_copyright" = "Höfundarréttur"; "settings_term_conditions" = "Skilmálar og kvaðir"; -"settings_privacy_policy" = "Stefna vegna meðferðar persónuupplýsinga"; +"settings_privacy_policy" = "Persónuverndarstefna"; "settings_third_party_notices" = "Athugasemdir frá þriðja aðila"; "settings_send_crash_report" = "Senda nafnlausar hrunskýrslur og upplýsingar um notkun"; "settings_clear_cache" = "Hreinsa skyndiminni"; -"settings_change_password" = "Breyta lykilorði"; +"settings_change_password" = "Breyta Matrix-lykilorði"; "settings_old_password" = "eldra lykilorð"; "settings_new_password" = "nýtt lykilorð"; "settings_confirm_password" = "staðfestu lykilorð"; -"settings_fail_to_update_password" = "Mistókst að uppfæra lykilorð"; -"settings_password_updated" = "Lykilorðið þitt hefur verið uppfært"; -"settings_crypto_device_name" = "Heiti tækis: "; -"settings_crypto_device_id" = "\nAuðkenni tækis: "; -"settings_crypto_device_key" = "\nDulritunarlykill tækis: "; +"settings_fail_to_update_password" = "Mistókst að uppfæra Matrix-lykilorð"; +"settings_password_updated" = "Matrix-lykilorðið þitt hefur verið uppfært"; +"settings_crypto_device_name" = "Nafn á setu: "; +"settings_crypto_device_id" = "\nAuðkenni setu: "; +"settings_crypto_device_key" = "\nDulritunarlykill setu:\n"; "settings_crypto_export" = "Flytja út dulritunarlykla"; // Room Details "room_details_title" = "Nánar um spjallrás"; "room_details_people" = "Meðlimir"; -"room_details_files" = "Skrár"; +"room_details_files" = "Innsendingar"; "room_details_settings" = "Stillingar"; "room_details_photo" = "Mynd spjallrásar"; -"room_details_room_name" = "Nafn spjallrásar"; +"room_details_room_name" = "Heiti spjallrásar"; "room_details_topic" = "Umfjöllunarefni"; "room_details_favourite_tag" = "Eftirlæti"; "room_details_low_priority_tag" = "Lítill forgangur"; @@ -221,7 +221,7 @@ "room_details_advanced_section" = "Ítarlegt"; // Group Details "group_details_title" = "Nánar um samfélag"; -"group_details_home" = "Heim"; +"group_details_home" = "Forsíða"; "group_details_people" = "Fólk"; "group_details_rooms" = "Spjallrásir"; // Group Home @@ -256,10 +256,10 @@ "do_not_ask_again" = "Ekki spyrja aftur"; "large_badge_value_k_format" = "%.1fK"; // Call -"call_incoming_voice_prompt" = "Innhringing raddsamtals frá %@"; -"call_incoming_video_prompt" = "Innhringing myndsamtals frá %@"; -"call_incoming_voice" = "Innhringing..."; -"call_incoming_video" = "Innhringing myndsamtals..."; +"call_incoming_voice_prompt" = "Innhringing raddsímtals frá %@"; +"call_incoming_video_prompt" = "Innhringing myndsímtals frá %@"; +"call_incoming_voice" = "Innhringing…"; +"call_incoming_video" = "Innhringing myndsímtals…"; // No VoIP support "no_voip_title" = "Innhringing"; // Bug report @@ -273,14 +273,14 @@ "widget_integration_must_be_in_room" = "Þú ert ekki á þessari spjallrás."; "widget_integration_no_permission_in_room" = "Þú hefur ekki réttindi til þess að gera þetta á þessari spjallrás."; "e2e_room_key_request_ignore_request" = "Hunsa beiðni"; -"active_call" = "Virkt samtal"; +"active_call" = "Virkt símtal"; "unknown_devices_call_anyway" = "hringja samt"; -"call_already_displayed" = "Þegar er samtal í gangi."; -"active_call_details" = "Virkt samtal (%@)"; +"call_already_displayed" = "Þegar er símtal í gangi."; +"active_call_details" = "Virkt símtal (%@)"; "auth_send_reset_email" = "Senda endurstillingarpóst"; "auth_return_to_login" = "Fara aftur í innskráningargluggann"; "auth_home_server_placeholder" = "URL-slóð (t.d. https://matrix.org)"; -"auth_identity_server_placeholder" = "URL-slóð (t.d. https://matrix.org)"; +"auth_identity_server_placeholder" = "URL-slóð (t.d. https://vector.im)"; "auth_invalid_email" = "Þetta lítur ekki út eins og gilt tölvupóstfang"; "auth_invalid_phone" = "Þetta lítur ekki út eins og gilt símanúmer"; "auth_email_in_use" = "Þetta tölvupóstfang er nú þegar í notkun"; @@ -313,7 +313,7 @@ "room_participants_action_set_moderator" = "Gera að umsjónarmanni"; "room_participants_action_mention" = "Minnst á"; // Chat -"room_jump_to_first_unread" = "Fara í fyrstu ólesin skilaboð"; +"room_jump_to_first_unread" = "Fara í ólesið"; "room_message_placeholder" = "Senda skilaboð (ódulrituð)…"; "room_do_not_have_permission_to_post" = "Þú hefur ekki heimild til að senda skilaboð á þessa spjallrás"; "room_message_short_placeholder" = "Senda skilaboð…"; @@ -321,15 +321,15 @@ "room_resend_unsent_messages" = "Senda aftur ósend skilaboð"; "room_delete_unsent_messages" = "Eyða ósendum skilaboðum"; "room_event_action_report" = "Klaga efni"; -"room_event_action_report_prompt_reason" = "Ástæður fyrir tilkynningu um vankanta á þessu efni"; +"room_event_action_report_prompt_reason" = "Ástæður fyrir kæru á þessu efni"; "room_event_action_report_prompt_ignore_user" = "Viltu fela öll skilaboð frá þessum notanda?"; "room_event_action_cancel_send" = "Hætta við sendingu"; "room_event_action_view_encryption" = "Dulritunarupplýsingar"; "room_event_failed_to_send" = "Mistókst að senda"; // Unknown devices -"unknown_devices_alert_title" = "Spjallrás inniheldur óþekkt tæki"; +"unknown_devices_alert_title" = "Spjallrás inniheldur óþekktar setur"; "unknown_devices_answer_anyway" = "Svara samt"; -"unknown_devices_title" = "Óþekkt tæki"; +"unknown_devices_title" = "Óþekktar setur"; // Room Preview "room_preview_invitation_format" = "Þér hefur verið boðið af %@ að taka þátt í þessari spjallrás"; "account_logout_all" = "Skrá út af öllum notandaaðgöngum"; @@ -349,10 +349,10 @@ "room_participants_invited_section" = "BOÐIÐ"; "room_details_access_section" = "Hver hefur aðgang að þessari spjallrás?"; "room_details_advanced_e2e_encryption_enabled" = "Dulritun er virk í þessari spjallrás"; -"e2e_room_key_request_start_verification" = "Hefja sannvottun..."; +"e2e_room_key_request_start_verification" = "Hefja sannvottun…"; "e2e_room_key_request_share_without_verifying" = "Deila án sannvottunar"; "room_creation_appearance_picture" = "Mynd spjalls (valfrjálst)"; -"room_creation_invite_another_user" = "Leita/Bjóða eftir notandaauðkenni, nafni eða tölvupóstfangi"; +"room_creation_invite_another_user" = "Notandaauðkenni, nafn eða tölvupóstfang"; // Room recents "room_recents_directory_section" = "SKRÁ YFIR SPJALLRÁSIR"; "directory_searching_title" = "Leita í yfirlitsskrá.…"; @@ -370,14 +370,14 @@ "room_creation_wait_for_creation" = "Verið er að útbúa spjallrás. Bíddu aðeins."; "room_recents_join_room_prompt" = "Settu inn auðkenni eða samheiti spjallrásar"; "room_participants_invite_another_user" = "Leita/Bjóða eftir notandauðkenni, nafni eða tölvupóstfangi"; -"room_event_action_kick_prompt_reason" = "Ástæða fyrir að sparka þessum notanda"; +"room_event_action_kick_prompt_reason" = "Ástæða fyrir að fjarlægja þennan notanda"; "room_event_action_ban_prompt_reason" = "Ástæða fyrir að banna þennan notanda"; "settings_unignore_user" = "Sýna öll skilaboð frá %@?"; "settings_labs_create_conference_with_jitsi" = "Búa til símafundi með Jitsi"; "room_details_history_section_members_only" = "Einungis meðlimir (síðan þessi kostur var valinn)"; "room_details_history_section_members_only_since_invited" = "Einungis meðlimir (síðan þeim var boðið)"; "room_details_history_section_members_only_since_joined" = "Einungis meðlimir (síðan þeir skráðu sig)"; -"room_details_new_flair_placeholder" = "Bæta við nýjui samfélag (t.d. +foo%@)"; +"room_details_new_flair_placeholder" = "Bæta við nýju samfélag (t.d. +foo%@)"; "room_details_flair_invalid_id_prompt_msg" = "%@ er ekki gilt auðkenni samfélags"; "room_details_advanced_e2e_encryption_disabled" = "Dulritun er ekki virk í þessari spjallrás."; "room_details_save_changes_prompt" = "Viltu vista breytingarnar?"; @@ -388,20 +388,20 @@ "auth_add_phone_message" = "Bættu símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig."; "auth_add_email_phone_message" = "Bættu tölvupóstfangi og/eða símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig. Tölvupóstfang nýtist einnig til að endurstilla lykilorðið þitt."; "auth_add_email_and_phone_message" = "Bættu tölvupóstfangi og símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig. Tölvupóstfang nýtist einnig til að endurstilla lykilorðið þitt."; -"auth_recaptcha_message" = "Þessi heimavefþjónn vill ganga úr skugga um að þú sért ekki vélmenni"; -"auth_reset_password_message" = "Til að endursetja lykilorðið þitt, settu þá inn tölvupóstfangið sem tengt er notandaaðgangnum þínum:"; +"auth_recaptcha_message" = "Þessi heimaþjónn vill ganga úr skugga um að þú sért ekki vélmenni"; +"auth_reset_password_message" = "Til að endursetja Matrix-lykilorðið þitt, settu þá inn tölvupóstfangið sem tengt er notandaaðgangnum þínum:"; "auth_reset_password_missing_email" = "Það þarf að setja inn tölvupóstfangið sem tengt er notandaaðgangnum þínum."; "auth_reset_password_email_validation_message" = "Tölvupóstur hefur verið sendur á %@ Þegar þú ert búin/n að fylgja tenglinum sem sá póstur inniheldur, smelltu þá hér fyrir neðan."; "auth_reset_password_error_unauthorized" = "Gat ekki sannprófað tölvupóstfang: gakktu úr skugga um að þú hafir smellt á tengilinn í tölvupóstinum"; -"auth_reset_password_success_message" = "Lykilorðið þitt hefur verið endurstillt.\n\nÞú hefur verið skráður út af öllum tækjum og munt ekki lengur fá ýti-tilkynningar. Til að endurvirkja tilkynningar, þarf að skrá sig aftur inn á hverju tæki fyrir sig."; +"auth_reset_password_success_message" = "Matrix-ykilorðið þitt hefur verið endurstillt.\n\nÞú hefur verið skráður út af öllum tækjum og munt ekki lengur fá ýti-tilkynningar. Til að endurvirkja tilkynningar, þarf að skrá sig aftur inn á hverju tæki fyrir sig."; "directory_search_results" = "%tu niðurstöður fundust fyrir %@"; "directory_search_results_more_than" = ">%tu niðurstöður fundust fyrir %@"; -"contacts_address_book_permission_denied" = "Þú heimilaðir Element ekki aðgang að tengiliðum á tækinu"; +"contacts_address_book_permission_denied" = "Þú heimilaðir %@ ekki aðgang að tengiliðum á tækinu"; "room_participants_remove_prompt_msg" = "Ertu viss um að þú viljir fjarlægja %@ úr þessu spjalli?"; "room_participants_invite_prompt_msg" = "Ertu viss um að þú viljir bjóða %@ á þetta spjall?"; "room_participants_invite_malformed_id" = "Rangt formað auðkenni. Ætti að vera tölvupóstfang eða Matrix-auðkenni á borð við'@sérheiti:lén'"; "room_unsent_messages_notification" = "Skilaboð ekki send."; -"room_unsent_messages_unknown_devices_notification" = "Skilaboð ekki send vegna þess að vart var við óþekkt tæki."; +"room_unsent_messages_unknown_devices_notification" = "Skilaboð ekki send vegna þess að vart var við óþekkta setu."; "room_ongoing_conference_call" = "Símafundur í gangi. Taka þátt með %@ eða %@."; "room_ongoing_conference_call_with_close" = "Símafundur í gangi. Taka þátt með %@ eða %@. %@ því."; "room_conference_call_no_power" = "Þú þarft aðgangsheimildir til að sýsla með símafundi á þessari spjallrás"; @@ -476,11 +476,1496 @@ "widget_integration_room_not_recognised" = "Spjallrás er ekki þekkt."; // Share extension "share_extension_auth_prompt" = "Skráðu inn í aðalforrit til að deila efni"; -"e2e_room_key_request_message_new_device" = "Þú bættir við nýju tæki '%@', sem er að krefjast dulritunarlykla."; -"e2e_room_key_request_message" = "Ósannvottaða tækið þitt '%@' er að krefjast dulritunarlykla."; +"e2e_room_key_request_message_new_device" = "Þú bættir við nýrri setu '%@', sem er að krefjast dulritunarlykla."; +"e2e_room_key_request_message" = "Ósannvottaða setan þín '%@' er að krefjast dulritunarlykla."; // MARK: - MatrixKit + +"select_account" = "Veldu notandaaðgang"; +"login_error_resource_limit_exceeded_contact_button" = "Hafðu samband við kerfisstjóra"; +"register_error_title" = "Nýskráning mistókst"; +"poll_timeline_vote_not_registered_title" = "Atkvæði ekki skráð"; +"poll_timeline_total_final_results" = "Lokaniðurstöður byggðar á %lu atkvæðum"; +"poll_timeline_total_final_results_one_vote" = "Lokaniðurstöður byggðar á 1 atkvæði"; +"poll_timeline_total_votes_not_voted" = "%lu atkvæði greidd. Greiddu atkvæði til að sjá útkomuna"; +"poll_timeline_total_one_vote_not_voted" = "1 atkvæði greitt. Greiddu atkvæði til að sjá útkomuna"; +"poll_timeline_total_votes" = "%lu atkvæði greidd"; +"poll_timeline_votes_count" = "%lu atkvæði"; +"poll_edit_form_update_failure_title" = "Mistókst að uppfæra könnun"; +"poll_edit_form_option_number" = "Valkostur %lu"; +"user_avatar_view_accessibility_hint" = "Skipta um auðkennismynd notanda"; +"leave_space_and_all_rooms_action" = "Yfirgefa allar spjallrásir og svæði"; +"room_intro_cell_information_room_sentence1_part3" = ". "; + +// MARK: - Favourites + +"favourites_empty_view_title" = "Eftirlætisspjallrásir og fólk"; +"home_context_menu_normal_priority" = "Venjulegur forgangur"; +"home_context_menu_make_room" = "Færa í Spjallrásir"; +"home_context_menu_make_dm" = "Færa í Fólk"; + +// MARK: - Home + +"home_empty_view_title" = "Velkomin í %@,\n%@"; +"create_room_type_private" = "Einkaspjallrás"; +"create_room_section_header_type" = "Tegund spjallrásar"; +"create_room_section_header_encryption" = "Dulritun spjallrásar"; +"searchable_directory_search_placeholder" = "Nafn eða auðkenni"; +"biometrics_cant_unlocked_alert_message_login" = "Skráðu þig aftur inn"; +"biometrics_mode_face_id" = "Face ID"; + +// MARK: - Biometrics Protection + +"biometrics_mode_touch_id" = "Touch ID"; +"pin_protection_settings_section_header_with_biometrics" = "PIN & %@"; +"pin_protection_settings_section_header" = "PIN-númer"; +"secrets_setup_recovery_key_storage_alert_title" = "Haltu þessu öruggu"; +"secrets_recovery_with_key_recover_action" = "Nota lykil"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part3" = "."; + +// Session details + +"user_verification_session_details_trusted_title" = "Treyst"; +"user_verification_start_waiting_partner" = "Bíð eftir %@…"; +"room_multiple_typing_notification" = "%@ auk annarra"; +"room_resource_usage_limit_reached_message_contact_3" = " til að fá þessi takmörk hækkuð."; +"room_resource_usage_limit_reached_message_2" = "að sumir notendur munu ekki geta skráð sig inn."; +"room_resource_usage_limit_reached_message_1_monthly_active_user" = "Þessi heimaþjónn er kominn fram yfir takmörk á mánaðarlega virkum notendum þannig "; +"room_resource_usage_limit_reached_message_1_default" = "Þessi heimaþjónn er kominn fram yfir takmörk á tilföngum sínum þannig "; +"room_resource_limit_exceeded_message_contact_3" = " til að halda áfram að nota þessa þjónustu."; +"room_resource_limit_exceeded_message_contact_1" = " Endilega "; +"room_predecessor_link" = "Ýttu hér til að sjá eldri skilaboð."; +"room_action_send_file" = "Senda skrá"; +"room_action_send_photo_or_video" = "Senda ljósmynd eða myndskeið"; +"room_event_action_delete_confirmation_message" = "Ertu viss um að þú viljir eyða þessum ósendu skilaboðum?"; +"room_event_action_delete_confirmation_title" = "Eyða ósendum skilaboðum"; +"room_message_reply_to_short_placeholder" = "Senda svar…"; +"room_message_replying_to" = "Svara %@"; +"room_message_unable_open_link_error_message" = "Gat ekki opnað tengilinn."; +"room_message_reply_to_placeholder" = "Senda svar (án dulritunar)…"; +"room_accessiblity_scroll_to_bottom" = "Skruna neðst"; + +// MARK: - Chat + +"room_slide_to_end_group_call" = "Renna til að ljúka símtalinu hjá öllum"; +"room_member_power_level_custom_in" = "Sérsniðið (%@) í %@"; +"room_member_power_level_moderator_in" = "Umsjónarmaður í %@"; +"room_member_power_level_admin_in" = "Stjórnandi í %@"; +"room_participants_security_information_room_not_encrypted_for_dm" = "Skilaboð hér eru ekki enda-í-enda dulrituð."; +"room_participants_filter_room_members_for_dm" = "Sía meðlimi"; +"room_participants_remove_third_party_invite_prompt_msg" = "Ertu viss um að þú viljir afturkalla þetta boð?"; +"room_participants_leave_success" = "Fór af spjallrásinni"; +"room_participants_leave_processing" = "Fer út"; +"room_participants_leave_prompt_msg_for_dm" = "Ertu viss um að þú viljir fara?"; +"ssl_could_not_verify" = "Gat ekki sannreynt auðkenni fjartengds þjóns."; +"ssl_fingerprint_hash" = "Fingrafar (%@):"; +"ssl_remain_offline" = "Hunsa"; +"ssl_logout_account" = "Útskráning"; + +// unrecognized SSL certificate +"ssl_trust" = "Treysta"; +"call_transfer_to_user" = "Færa á %@"; +"call_video_with_user" = "Myndsímtal við %s@"; +"call_voice_with_user" = "Raddsímtal við %@"; +"call_more_actions_dialpad" = "Talnaborð"; +"call_more_actions_transfer" = "Flutningur"; +"call_more_actions_audio_use_device" = "Hátalari tækis"; +"call_more_actions_change_audio_device" = "Skipta um hljóðtæki"; +"call_more_actions_unhold" = "Halda áfram"; +"call_more_actions_hold" = "Bíða"; +"call_holded" = "Þú settir símtalið í bið"; +"call_remote_holded" = "%@ setti símtalið í bið"; +"incoming_voice_call" = "Innhringing raddsímtals"; +"incoming_video_call" = "Innhringing myndsímtals"; +"call_ended" = "Símtali lokið"; +"call_ringing" = "Hringing…"; + +// Settings keys + +// call string +"call_connecting" = "Tengist…"; +"notification_settings_notify_all_other" = "Senda tilkynningar fyrir öll önnur skilaboð/spjallrásir"; +"notification_settings_by_default" = "Sjálfgefið..."; +"notification_settings_other_alerts" = "Aðrar aðvaranir"; +"notification_settings_select_room" = "Veldu spjallrás"; +"notification_settings_custom_sound" = "Sérsniðið hljóð"; +"notification_settings_highlight" = "Áherslulita"; +"notification_settings_never_notify" = "Aldrei láta vita"; +"notification_settings_always_notify" = "Alltaf láta vita"; +"notification_settings_enable_notifications" = "Virkja tilkynningar"; +"settings_title_notifications" = "Tilkynningar"; + +// Settings screen +"settings_title_config" = "Uppsetning"; +"login_error_must_start_http" = "Slóð verður að byrja á http[s]://"; + +// Login Screen +"login_error_already_logged_in" = "Nú þegar innskráð(ur)"; +"ban" = "Banna"; + +/* -*- + Automatic localization for en + + The following key/value pairs were extracted from the android i18n file: + /matrix-sdk/src/main/res/values/strings.xml. +*/ + +"notice_room_invite" = "%@ bauð %@"; +"language_picker_default_language" = "Sjálfgefið (%@)"; + +// Language picker +"language_picker_title" = "Veldu tungumál"; + +// Country picker +"country_picker_title" = "Veldu land"; +"ssl_homeserver_url" = "URL-slóð heimaþjóns: %@"; +"power_level" = "Valdastig"; +"public" = "Opinbert"; +"private" = "Einka"; +"default" = "sjálfgefið"; +"not_supported_yet" = "Ekki stutt ennþá"; +"error" = "Villa"; +"offline" = "ónettengdur"; + +// Others +"user_id_title" = "Notandaauðkenni:"; +"e2e_passphrase_create" = "Búa til lykilsetningu"; +"e2e_passphrase_not_match" = "Lykilsetningar verða að stemma"; +"e2e_passphrase_empty" = "Lykilsetning má ekki vera auð"; +"e2e_passphrase_confirm" = "Staðfestu lykilsetningu"; +"e2e_export" = "Flytja út"; + +// E2E export +"e2e_export_room_keys" = "Flytja út dulritunarlykla spjallrásar"; +"e2e_passphrase_enter" = "Settu inn lykilsetningu"; +"e2e_import" = "Flytja inn"; + +// E2E import +"e2e_import_room_keys" = "Flytja inn dulritunarlykla spjallrásar"; +"format_time_d" = "d"; +"format_time_h" = "klst"; +"format_time_m" = "mín"; + +// Time +"format_time_s" = "sek"; + +// Groups + +// Search +"search_no_results" = "Engar niðurstöður"; +"contact_local_contacts" = "Tengiliðir á tæki"; +"attachment_unsupported_preview_message" = "Þessi skráategund er ekki studd."; +"attachment_e2e_keys_import" = "Flytja inn..."; +"attachment_multiselection_original" = "Raunstærð"; +"attachment_cancel_upload" = "Hætta við innsendinguna?"; +"attachment_cancel_download" = "Hætta við niðurhalið?"; +"attachment_large_with_resolution" = "Stórt %@ (~%@)"; +"attachment_medium_with_resolution" = "Miðlungs %@ (~%@)"; +"attachment_small_with_resolution" = "Lítið %@ (~%@)"; +"attachment_large" = "Stórt (~%@)"; +"attachment_medium" = "Miðlungs (~%@)"; +"attachment_small" = "Lítið (~%@)"; +"attachment_original" = "Raunstærð (%@)"; +"room_member_power_level_prompt" = "Þú getur ekki afturkallað þessa aðgerð, þar sem þú ert að gefa notandanum jafn mikil völd og þú hefur sjálf/ur.\nErtu alveg viss?"; +"message_reply_to_message_to_reply_to_prefix" = "Sem svar til"; +"message_reply_to_sender_sent_their_location" = "hefur deilt staðsetningu sinni."; +"message_reply_to_sender_sent_a_file" = "sendi skrá."; +"message_reply_to_sender_sent_a_voice_message" = "sendi talskilaboð."; +"message_reply_to_sender_sent_an_audio_file" = "sendi hljóðskrá."; +"message_reply_to_sender_sent_a_video" = "sendi myndskeið."; + +// Reply to message +"message_reply_to_sender_sent_an_image" = "sendi mynd."; +"room_no_conference_call_in_encrypted_rooms" = "Símafundir eru ekki studdir í dulrituðum spjallrásum"; +"room_no_power_to_create_conference_call" = "Þú þarft aðgangsheimildir til að bjóða til símafundar á þessari spjallrás"; +"room_left" = "Þú hættir í spjallrásinni"; +"room_error_timeline_event_not_found_title" = "Mistókst að hlaða inn staðsetningu á tímalínu"; +"room_error_join_failed_title" = "Mistókst að taka þátt í spjallrás"; +"room_creation_participants_title" = "Þátttakendur:"; +"room_creation_alias_title" = "Samnefni spjallrásar:"; + +// Room creation +"room_creation_name_title" = "Heiti spjallrásar:"; +"account_error_msisdn_wrong_title" = "Ógilt símanúmer"; +"account_error_email_wrong_description" = "Þetta lítur ekki út eins og gilt tölvupóstfang"; +"account_error_email_wrong_title" = "Ógilt tölvupóstfang"; +"account_msisdn_validation_error" = "Ekki var hægt að sannreyna símanúmer."; +"account_msisdn_validation_message" = "Við höfum sent SMS-skilaboð með virkjunarkóða. Settu þennan kóða inn hér fyrir neðan."; +"account_msisdn_validation_title" = "Sannvottun í bið"; +"account_email_validation_error" = "Tókst ekki að sannreyna tölvupóstfang. Skoðaðu tölvupóstinn þinn og smelltu á tengilinn sem hann inniheldur. Þegar því er lokið skaltu smella á að halda áfram"; +"account_email_validation_message" = "Skoðaðu tölvupóstinn þinn og smelltu á tengilinn sem hann inniheldur. Þegar því er lokið skaltu smella á að halda áfram."; +"account_email_validation_title" = "Sannvottun í bið"; + +// Account +"account_save_changes" = "Vista breytingar"; +"room_event_encryption_verify_ok" = "Sannreyna"; +"room_event_encryption_info_unblock" = "Taka af bannlista"; +"room_event_encryption_info_block" = "Bannlisti"; +"room_event_encryption_info_unverify" = "Afturkalla sannvottun"; +"room_event_encryption_info_verify" = "Sannreyna..."; +"room_event_encryption_info_device_blocked" = "Á bannlista"; +"room_event_encryption_info_device_not_verified" = "EKKI sannreynt"; +"room_event_encryption_info_device_verified" = "Sannreynt"; +"room_event_encryption_info_event_none" = "ekkert"; +"room_event_encryption_info_event_unencrypted" = "ódulritað"; +"device_details_delete_prompt_message" = "Þessi aðgerð krefst viðbótar-auðkenningar.\nTil að halda áfram skaltu setja inn lykilorðið þitt."; +"device_details_delete_prompt_title" = "Auðkenning"; +"device_details_rename_prompt_title" = "Nafn á setu"; +"device_details_last_seen_format" = "%@ @ %@\n"; +"notification_settings_room_rule_title" = "Spjallrás: '%@'"; + +// Settings +"settings" = "Stillingar"; +"room_displayname_all_other_members_left" = "%@ (fór)"; +"room_displayname_two_members" = "%@ og %@"; + +// room display name +"room_displayname_empty_room" = "Tóm spjallrás"; +"notice_in_reply_to" = "Sem svar til"; +"notice_sticker" = "límmerki"; +"notice_encrypted_message" = "Dulrituð skilaboð"; +"notice_room_created_for_dm" = "%@ gekk í hópinn."; +"notice_event_redacted_reason" = " [ástæða: %@]"; +"notice_event_redacted_by" = " eftir %@"; + +// Events formatter +"notice_avatar_changed_too" = "(einnig var skipt um auðkennismynd)"; +"unignore" = "Hætta að hunsa"; +"ignore" = "Hunsa"; +"resume_call" = "Halda áfram"; +"end_call" = "Ljúka símtali"; +"answer_call" = "Svara símtali"; +"show_details" = "Sýna ítarlegri upplýsingar"; +"cancel_download" = "Hætta við niðurhal"; +"cancel_upload" = "Hætta við innsendingu"; +"select_all" = "Velja allt"; +"reset_to_default" = "Frumstilla á sjálfgefið"; +"mention" = "Minnst á"; +"start_video_call" = "Hefja myndsímtal"; +"start_voice_call" = "Hefja raddsímtal"; +"start_chat" = "Hefja spjall"; +"submit" = "Senda inn"; +"sign_up" = "Nýskrá"; +"dismiss" = "Hunsa"; +"discard" = "Henda"; +"abort" = "Hætta"; +"yes" = "Já"; + +// Action +"no" = "Nei"; +"login_error_resource_limit_exceeded_message_monthly_active_user" = "Þessi heimaþjónn er kominn fram yfir takmörk á mánaðarlega virkum notendum."; +"login_error_resource_limit_exceeded_message_default" = "Þessi heimaþjónn er kominn fram yfir takmörk á tilföngum sínum."; +"login_desktop_device" = "Einkatölva"; +"login_tablet_device" = "Spjaldtölva"; +"login_mobile_device" = "Farsími"; +"login_invalid_param" = "Ógild færibreyta"; +"login_leave_fallback" = "Hætta við"; +"login_error_login_email_not_yet" = "Tölvupósttengill sem ekki er enn búið að smella á"; +"login_error_user_in_use" = "Þetta notandanafn er þegar í notkun"; +"login_error_limit_exceeded" = "Of margar beiðnir hafa verið sendar"; +"login_error_not_json" = "Inniheldur ekki gilt JSON"; +"login_error_bad_json" = "Gallað JSON"; +"login_error_unknown_token" = "Tiltekið aðgangsteikn þekktist ekki"; +"login_error_forbidden" = "Ótækt notandanafn/lykilorð"; +"login_error_title" = "Innskráning mistókst"; +"login_email_placeholder" = "Tölvupóstfang"; +"login_optional_field" = "valkvætt"; +"login_password_placeholder" = "Lykilorð"; +"login_identity_server_title" = "Slóð á auðkennisþjón:"; +"login_home_server_title" = "Slóð á heimaþjón:"; +"login_server_url_placeholder" = "URL-slóð (t.d. https://matrix.org)"; + +// Login Screen +"login_create_account" = "Búa til notandaaðgang:"; + + +// MARK: - MatrixKit + + +/* *********************** */ +/* iOS specific */ +/* *********************** */ + +"matrix" = "Matrix"; +"location_sharing_settings_toggle_title" = "Virkja deilingu staðsetninga"; +"location_sharing_settings_header" = "Deiling staðsetninga"; +"location_sharing_open_open_street_maps" = "Opna í OpenStreetMap"; +"location_sharing_open_google_maps" = "Opna í Google Maps"; +"location_sharing_open_apple_maps" = "Opna í Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Stillingar"; +"location_sharing_invalid_authorization_not_now" = "Ekki núna"; +"location_sharing_share_action" = "Deila"; +"location_sharing_close_action" = "Loka"; + +// MARK: - Location sharing + +"location_sharing_title" = "Staðsetning"; +"poll_timeline_not_closed_subtitle" = "Endilega reyndu aftur"; +"poll_timeline_not_closed_title" = "Mistókst að ljúka könnun"; +"poll_timeline_total_one_vote" = "1 atkvæði greitt"; +"poll_timeline_total_no_votes" = "Engin atkvæði greidd"; +"poll_timeline_one_vote" = "1 atkvæði"; +"poll_edit_form_poll_type_closed_description" = "Niðurstöður birtast einungis eftir að þú hefur lokað könnuninni"; +"poll_edit_form_poll_type_closed" = "Lokuð könnun"; +"poll_edit_form_poll_type_open_description" = "Kjósendur sjá niðurstöðurnar þegar þeir hafa kosið"; +"poll_edit_form_poll_type_open" = "Opna könnun"; +"poll_edit_form_update_failure_subtitle" = "Endilega reyndu aftur"; +"poll_edit_form_post_failure_subtitle" = "Endilega reyndu aftur"; +"poll_edit_form_post_failure_title" = "Mistókst að birta könnun"; +"poll_edit_form_add_option" = "Bæta við valkosti"; +"poll_edit_form_create_options" = "Búa til valkosti"; +"poll_edit_form_input_placeholder" = "Skrifaðu eitthvað"; +"poll_edit_form_question_or_topic" = "Spurning eða viðfangsefni"; +"poll_edit_form_poll_question_or_topic" = "Spurning eða viðfangsefni könnunar"; +"poll_edit_form_poll_type" = "Tegund könnunar"; + +// Mark: - Polls + +"poll_edit_form_create_poll" = "Búa til könnun"; +"version_check_modal_action_title_supported" = "Náði því"; +"voice_message_lock_screen_placeholder" = "Talskilaboð"; +"voice_message_remaining_recording_time" = "%@s fór út"; +"side_menu_app_version" = "Útgáfa %@"; +"side_menu_action_feedback" = "Umsagnir"; +"side_menu_action_help" = "Hjálp"; +"side_menu_action_settings" = "Stillingar"; +"side_menu_action_invite_friends" = "Bjóða vinum"; + +// Mark: - Side menu + +"side_menu_reveal_action_accessibility_label" = "Vinstra spjald"; + +// Mark: - User avatar view + +"user_avatar_view_accessibility_label" = "auðkennismynd"; +"space_avatar_view_accessibility_hint" = "Skipta um táknmynd svæðis"; + +// Mark: Avatar + +"space_avatar_view_accessibility_label" = "auðkennismynd"; +"space_public_join_rule" = "Opinbert svæði"; +"space_private_join_rule" = "Einkasvæði"; +"space_home_show_all_rooms" = "Sýna allar spjallrásir"; +"spaces_coming_soon_title" = "Kemur bráðum"; +"spaces_no_result_found_title" = "Engar niðurstöður fundust"; +"space_tag" = "bil"; +"spaces_suggested_room" = "Tillögur"; +"spaces_explore_rooms" = "Kanna spjallrásir"; +"leave_space_only_action" = "Ekki yfirgefa neinar spjallrásir"; +"leave_space_title" = "Fara út úr %@"; +"spaces_left_panel_title" = "Svæði"; +"spaces_home_space_title" = "Forsíða"; +"space_beta_announce_badge" = "BETA-prófunarútgáfa"; +"room_intro_cell_information_room_with_topic_sentence2" = "Umfjöllunarefni: %@"; + +// Mark: - Room creation introduction cell + +"room_intro_cell_add_participants_action" = "Bæta við fólki"; +"room_avatar_view_accessibility_hint" = "Skipta um auðkennismynd spjallrásar"; + +// Mark: - Room avatar view + +"room_avatar_view_accessibility_label" = "auðkennismynd"; +"home_syncing" = "Samstilli"; +"home_context_menu_leave" = "Fara út"; +"home_context_menu_low_priority" = "Lítill forgangur"; +"home_context_menu_unfavourite" = "Fjarlægja úr eftirlætum"; +"home_context_menu_favourite" = "Eftirlæti"; +"home_context_menu_unmute" = "Kveikja á hljóði"; +"home_context_menu_mute" = "Þagga niður"; +"home_context_menu_notifications" = "Tilkynningar"; +"call_transfer_error_title" = "Villa"; +"call_transfer_contacts_all" = "Allt"; +"call_transfer_contacts_recent" = "Nýlegt"; +"call_transfer_dialpad" = "Talnaborð"; +"call_transfer_users" = "Notendur"; + +// MARK: - Call Transfer +"call_transfer_title" = "Flutningur"; + +// MARK: - Dial Pad +"dialpad_title" = "Talnaborð"; +"room_info_list_section_other" = "Annað"; +"room_info_list_several_members" = "%@ meðlimir"; + +// MARK: - Room Info + +"room_info_list_one_member" = "1 meðlimur"; +"create_room_section_header_address" = "Vistfang spjallrásar"; +"create_room_type_public" = "Almenningsspjallrás"; +"create_room_enable_encryption" = "Þvinga dulritun"; +"create_room_placeholder_topic" = "Umfjöllunarefni"; +"key_verification_tile_request_incoming_approval_decline" = "Hafna"; +"key_verification_tile_request_incoming_approval_accept" = "Samþykkja"; +"key_verification_tile_request_status_cancelled" = "Hætt við %@"; +"key_verification_tile_request_status_expired" = "Útrunnið"; +"key_verification_tile_request_status_waiting" = "Bíð…"; + +// MARK: - Key Verification + +"key_verification_bootstrap_not_setup_title" = "Villa"; + +// MARK: Reaction history +"reaction_history_title" = "Viðbrögð"; +"emoji_picker_flags_category" = "Fánar"; +"emoji_picker_symbols_category" = "Tákn"; +"emoji_picker_objects_category" = "Hlutir"; +"emoji_picker_places_category" = "Ferðalög og staðir"; +"emoji_picker_activity_category" = "Starfsemi"; +"emoji_picker_foods_category" = "Mat og drykkur"; +"emoji_picker_nature_category" = "Dýr og náttúra"; +"emoji_picker_people_category" = "Broskarlar og fólk"; + +// MARK: Emoji picker +"emoji_picker_title" = "Viðbrögð"; +"file_upload_error_unsupported_file_type_message" = "Skráartegundin er ekki studd."; + +// MARK: File upload +"file_upload_error_title" = "Hlaða upp skrá"; +"device_verification_emoji_pin" = "Pinni"; +"device_verification_emoji_folder" = "Mappa"; +"device_verification_emoji_headphones" = "Heyrnartól"; +"device_verification_emoji_anchor" = "Akkeri"; +"device_verification_emoji_bell" = "Bjalla"; +"device_verification_emoji_trumpet" = "Trompet"; +"device_verification_emoji_guitar" = "Gítar"; +"device_verification_emoji_ball" = "Bolti"; +"device_verification_emoji_trophy" = "Verðlaun"; +"device_verification_emoji_rocket" = "Eldflaug"; +"device_verification_emoji_aeroplane" = "Flugvél"; +"device_verification_emoji_bicycle" = "Reiðhjól"; +"device_verification_emoji_train" = "Lest"; +"device_verification_emoji_flag" = "Flagg"; +"device_verification_emoji_telephone" = "Sími"; +"device_verification_emoji_hammer" = "Hamar"; +"device_verification_emoji_key" = "Lykill"; +"device_verification_emoji_lock" = "Lás"; +"device_verification_emoji_scissors" = "Skæri"; +"device_verification_emoji_paperclip" = "Bréfaklemma"; +"device_verification_emoji_pencil" = "Blýantur"; +"device_verification_emoji_book" = "Bók"; +"device_verification_emoji_light bulb" = "Ljósapera"; +"device_verification_emoji_gift" = "Gjöf"; +"device_verification_emoji_clock" = "Klukka"; +"device_verification_emoji_hourglass" = "Stundaglas"; +"device_verification_emoji_umbrella" = "Regnhlíf"; +"device_verification_emoji_thumbs up" = "Þumlar upp"; +"device_verification_emoji_santa" = "Jólasveinn"; +"device_verification_emoji_spanner" = "Skrúflykill"; +"device_verification_emoji_glasses" = "Gleraugu"; +"device_verification_emoji_hat" = "Hattur"; +"device_verification_emoji_robot" = "Vélmenni"; +"device_verification_emoji_smiley" = "Broskall"; +"device_verification_emoji_heart" = "Hjarta"; +"device_verification_emoji_cake" = "Kökur"; +"device_verification_emoji_pizza" = "Flatbökur"; +"device_verification_emoji_corn" = "Maís"; +"device_verification_emoji_strawberry" = "Jarðarber"; +"device_verification_emoji_apple" = "Epli"; +"device_verification_emoji_banana" = "Banani"; +"device_verification_emoji_fire" = "Eldur"; +"device_verification_emoji_cloud" = "Ský"; +"device_verification_emoji_moon" = "Tungl"; +"device_verification_emoji_globe" = "Hnöttur"; +"device_verification_emoji_mushroom" = "Sveppur"; +"device_verification_emoji_cactus" = "Kaktus"; +"device_verification_emoji_tree" = "Tré"; +"device_verification_emoji_flower" = "Blóm"; +"device_verification_emoji_butterfly" = "Fiðrildi"; +"device_verification_emoji_octopus" = "Kolkrabbi"; +"device_verification_emoji_fish" = "Fiskur"; +"device_verification_emoji_turtle" = "Skjaldbaka"; +"device_verification_emoji_penguin" = "Mörgæs"; +"device_verification_emoji_rooster" = "Hani"; +"device_verification_emoji_panda" = "Pandabjörn"; +"device_verification_emoji_rabbit" = "Kanína"; +"device_verification_emoji_elephant" = "Fíll"; +"device_verification_emoji_pig" = "Svín"; +"device_verification_emoji_unicorn" = "Einhyrningur"; +"device_verification_emoji_horse" = "Hestur"; +"device_verification_emoji_lion" = "Ljón"; +"device_verification_emoji_cat" = "Köttur"; + +// MARK: Emoji +"device_verification_emoji_dog" = "Hundur"; +"device_verification_verified_got_it_button" = "Náði því"; + +// MARK: Verified + +// Device + +"device_verification_verified_title" = "Sannreynt!"; +"key_verification_manually_verify_device_validate_action" = "Sannreyna"; +"key_verification_manually_verify_device_additional_information" = "Ef þetta samsvarar ekki, getur verið að samskiptin þín séu berskjölduð."; +"key_verification_manually_verify_device_key_title" = "Dulritunarlykill setu"; +"key_verification_manually_verify_device_id_title" = "Auðkenni setu"; +"key_verification_manually_verify_device_name_title" = "Nafn á setu"; +"key_verification_manually_verify_device_instruction" = "Staðfestu með því að bera eftirfarandi saman við 'Stillingar notanda' í hinni setunni þinni:"; + +// MARK: Manually Verify Device + +"key_verification_manually_verify_device_title" = "Sannreyna handvirkt með textaskilaboðum"; +"key_verification_verify_sas_validate_action" = "Þau samsvara"; +"key_verification_verify_sas_cancel_action" = "Þau samsvara ekki"; +"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Nota öryggislykil"; +"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Yfirfara"; +"key_verification_self_verify_current_session_alert_validate_action" = "Sannreyna"; +"key_verification_self_verify_current_session_alert_message" = "Aðrir notendur gætu ekki treyst því."; + +// Current session + +"key_verification_self_verify_current_session_alert_title" = "Sannprófa þessa setu"; +"device_verification_self_verify_start_waiting" = "Bíð…"; +"device_verification_self_verify_start_verify_action" = "Hefja sannvottun"; +"device_verification_self_verify_alert_validate_action" = "Sannreyna"; + +// MARK: Self verification start + +// New login +"device_verification_self_verify_alert_title" = "Ný innskráning. Varst þetta þú?"; +"device_verification_cancelled" = "Hinn aðilinn hætti við sannvottunina."; +"key_verification_this_session_title" = "Sannprófa þessa setu"; + +// MARK: - Device Verification +"key_verification_other_session_title" = "Sannprófa setu"; +"sign_out_key_backup_in_progress_alert_discard_key_backup_action" = "Ég vil ekki dulrituðu skilaboðin mín"; +"sign_out_key_backup_in_progress_alert_title" = "Öryggisafritun dulritunarlykla í gangi. Þú munt tapa dulrituðu skilaboðunum þínum ef þú skráir þig út núna."; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_backup_action" = "Öryggisafrit"; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_sign_out_action" = "Skrá út"; +"sign_out_non_existing_key_backup_sign_out_confirmation_alert_message" = "Þú munt missa aðgang að dulrituðu skilaboðunum þínum nema þú takir öryggisafrit af dulritunarlyklum áður en þú skráir þig út."; +"sign_out_non_existing_key_backup_alert_discard_key_backup_action" = "Ég vil ekki dulrituðu skilaboðin mín"; +"sign_out_existing_key_backup_alert_sign_out_action" = "Skrá út"; + +// MARK: Sign out warning + +"sign_out_existing_key_backup_alert_title" = "Ertu viss um að þú viljir skrá þig út?"; +"key_backup_recover_done_action" = "Lokið"; + +// Success + +"key_backup_recover_success_info" = "Öryggisafrit var endurheimt!"; +"key_backup_recover_from_recovery_key_recover_action" = "Aflæsi ferli"; +"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "Settu inn öryggislykil"; +"key_backup_recover_from_passphrase_recover_action" = "Aflæsi ferli"; + +// Recover from private key +"key_backup_recover_from_private_key_info" = "Endurheimti úr öryggisafriti…"; +"key_backup_recover_invalid_recovery_key_title" = "Misræmi í öryggislyklum"; +"key_backup_setup_success_from_recovery_key_made_copy_action" = "Ég hef gert afrit"; +"key_backup_setup_success_from_recovery_key_recovery_key_title" = "Öryggislykill"; +"key_backup_setup_success_from_passphrase_done_action" = "Lokið"; + +// Success + +"key_backup_setup_success_title" = "Tókst!"; +"key_backup_setup_passphrase_confirm_passphrase_valid" = "Frábært!"; +"key_backup_setup_passphrase_confirm_passphrase_title" = "Staðfesta"; +"key_backup_setup_passphrase_passphrase_valid" = "Frábært!"; +"key_backup_setup_intro_manual_export_info" = "(Ítarlegt)"; +"key_backup_setup_intro_setup_action_without_existing_backup" = "Byrja að nota öryggisafrit dulritunarlykla"; + +// Intro + +"key_backup_setup_intro_title" = "Tapaðu aldrei dulrituðum skilaboðum"; +"key_backup_setup_skip_alert_skip_action" = "Sleppa"; +"key_backup_setup_skip_alert_title" = "Ertu viss?"; + + +// MARK: Key backup setup + +"key_backup_setup_title" = "Öryggisafrit af lykli"; + +// Banner + +"secure_backup_setup_banner_title" = "Varið öryggisafrit"; +"secure_key_backup_setup_existing_backup_error_delete_it" = "Eyða því"; + +// MARK: Secure backup setup + +// Intro + +"secure_key_backup_setup_intro_title" = "Varið öryggisafrit"; + +// Re-request confirmation dialog +"rerequest_keys_alert_title" = "Beiðni send"; +"deactivate_account_password_alert_title" = "Gera notandaaðgang óvirkann"; +"deactivate_account_validate_action" = "Gera notandaaðgang óvirkann"; +"deactivate_account_forget_messages_information_part2_emphasize" = "Aðvörun"; +"deactivate_account_informations_part2_emphasize" = "Þessa aðgerð er ekki hægt að afturkalla."; + +// Deactivate account + +"deactivate_account_title" = "Gera notandaaðgang óvirkann"; +"service_terms_modal_information_title_integration_manager" = "Samþættingarstýring"; + +// Alert explaining what an identity server / integration manager is. +"service_terms_modal_information_title_identity_server" = "Auðkennisþjónn"; +"service_terms_modal_decline_button" = "Hafna"; +"service_terms_modal_accept_button" = "Samþykkja"; +"room_widget_permission_room_id_permission" = "Auðkenni spjallrásar"; +"room_widget_permission_widget_id_permission" = "Auðkenni viðmótshluta"; +"room_widget_permission_theme_permission" = "Þemað þitt"; +"room_widget_permission_user_id_permission" = "Notandaauðkennið þitt"; +"room_widget_permission_avatar_url_permission" = "Vefslóð á auðkennismyndina þína"; +"room_widget_permission_display_name_permission" = "Birtingarnafnið þitt"; +"room_widget_permission_creator_info_title" = "Þessum viðmótshluta var bætt við af:"; + +// Room widget permissions +"room_widget_permission_title" = "Hlaða inn viðmótshluta"; +"kick" = "Fjarlægja úr spjalli"; +"num_members_other" = "%@ notendur"; +"num_members_one" = "%@ notandi"; +"membership_ban" = "Bannað/ur"; +"membership_leave" = "Fór út"; +"membership_invite" = "Boðið"; +"create_account" = "Búa til notandaaðgang"; +"login" = "Innskráning"; +"create_room" = "Búa til spjallrás"; + +// actions +"action_logout" = "Útskráning"; +"delete" = "Eyða"; +"share" = "Deila"; +"redact" = "Fjarlægja"; +"resend" = "Endursenda"; +"copy_button_name" = "Afrita"; + +// Room Screen + +// general errors + +// Home Screen + +// Last seen time + +// call events + +/* -*- + Automatic localization for en + + The following key/value pairs were extracted from the android i18n file: + /console/src/main/res/values/strings.xml. +*/ + + +// titles + +// button names +"send" = "Senda"; +"notice_encryption_enabled_ok_by_you" = "Þú kveiktir á enda-í-enda dulritun."; +"notice_room_created_by_you_for_dm" = "Þú gekkst í hópinn."; +"notice_event_redacted_by_you" = " af þér"; +"notice_room_name_removed_by_you" = "Þú fjarlægðir heiti spjallrásar"; +"notice_ended_video_call_by_you" = "Þú laukst símtalinu"; +"notice_answered_video_call_by_you" = "Þú svaraðir símtalinu"; +"notice_placed_video_call_by_you" = "Þú hringdir myndsímtal"; +"notice_placed_voice_call_by_you" = "Þú hringdir raddsímtal"; +"notice_avatar_url_changed_by_you" = "Þú breyttir auðkennismyndinni þinni"; +"notice_room_reject_by_you" = "Þú hafnaðir boðinu"; +"notice_room_join_by_you" = "Þú gekkst í hópinn"; +"notice_room_invite_you" = "%@ bauð þér"; +"notice_conference_call_finished" = "VoIP-símafundi lokið"; +"notice_conference_call_started" = "VoIP-símafundur hafinn"; +"notice_room_reason" = ". Ástæða: %@"; +"notice_room_kick" = "%@ fjarlægði %@"; +"notice_room_leave" = "%@ fór út"; +"notice_room_join" = "%@ gekk í hópinn"; +"notice_room_third_party_invite_for_dm" = "%@ bauð %@"; +"widget_picker_manage_integrations" = "Sýsla með samþættingar…"; + +// Widget Picker +"widget_picker_title" = "Samþættingar"; + +// Widget Integration Manager +"widget_integration_need_to_be_able_to_invite" = "Þú þarft að hafa heimild til að bjóða notendum til að gera þetta."; +"widget_menu_revoke_permission" = "Afturkalla aðgang fyrir mig"; +"widget_menu_open_outside" = "Opna í vafra"; +"widget_menu_refresh" = "Endurlesa"; +"e2e_key_backup_wrong_version_button_settings" = "Stillingar"; +"analytics_prompt_stop" = "Hætta deilingu"; +"analytics_prompt_not_now" = "Ekki núna"; +"analytics_prompt_point_3" = "Þú getur slökkt á þessu hvenær sem er í stillingunum"; +"analytics_prompt_terms_link_upgrade" = "hér"; +"analytics_prompt_terms_link_new_user" = "hér"; +"call_actions_unhold" = "Halda áfram"; +"call_no_stun_server_error_title" = "Símtal mistókst vegna vanstillingar netþjóns"; +"room_does_not_exist" = "%@ er ekki til"; +"event_formatter_message_deleted" = "Skilaboðum eytt"; +"event_formatter_group_call_incoming" = "%@ í %@"; +"event_formatter_group_call_leave" = "Fara út"; +"event_formatter_group_call_join" = "Taka þátt"; +"event_formatter_call_end_call" = "Ljúka símtali"; +"event_formatter_call_retry" = "Reyna aftur"; +"event_formatter_call_answer" = "Svara"; +"event_formatter_call_decline" = "Hafna"; +"event_formatter_call_back" = "Hringja til baka"; +"event_formatter_call_connection_failed" = "Tenging mistókst"; +"event_formatter_call_missed_video" = "Ósvarað myndsímtal"; +"event_formatter_call_you_declined" = "Símtali hafnað"; +"event_formatter_call_incoming_video" = "Innhringing myndsímtals"; +"event_formatter_call_incoming_voice" = "Innhringing raddsímtals"; +"event_formatter_call_has_ended_with_time" = "Símtali lokið • %@"; +"event_formatter_call_has_ended" = "Símtali lokið"; +"event_formatter_call_ringing" = "Hringing…"; +"event_formatter_call_connecting" = "Tengist…"; +"event_formatter_message_edited_mention" = "(breytt)"; + +// Image picker +"image_picker_action_camera" = "Taka ljósmynd"; + +// Media picker +"media_picker_title" = "Margmiðlunarsafn"; +"room_notifs_settings_account_settings" = "Stillingar notandaaðgangs"; +"room_notifs_settings_cancel_action" = "Hætta við"; +"room_notifs_settings_done_action" = "Lokið"; +"room_notifs_settings_none" = "Ekkert"; +"room_notifs_settings_all_messages" = "Öll skilaboð"; + +// Room Notification Settings +"room_notifs_settings_notify_me_for" = "Láta mig vita fyrir"; +"room_details_advanced_room_id_for_dm" = "Auðkenni (ID):"; +"room_details_no_local_addresses" = "Þessi spjallrás er ekki með nein staðvær vistföng"; +"room_details_notifs" = "Tilkynningar"; +"room_details_room_name_for_dm" = "Heiti"; +"room_details_photo_for_dm" = "Ljósmynd"; +"room_details_integrations" = "Samþættingar"; +"room_details_title_for_dm" = "Nánar"; +"identity_server_settings_alert_disconnect_still_sharing_3pid_button" = "Aftengja samt"; +"identity_server_settings_alert_disconnect_button" = "Aftengjast"; +"identity_server_settings_alert_disconnect" = "Aftengjast frá auðkennisþjóninum %@?"; +"identity_server_settings_alert_disconnect_title" = "Aftengja auðkennisþjón"; +"identity_server_settings_disconnect" = "Aftengjast"; +"identity_server_settings_change" = "Breyta"; +"identity_server_settings_add" = "Bæta við"; + +// Identity server settings +"identity_server_settings_title" = "Auðkennisþjónn"; +"manage_session_not_trusted" = "Ekki treyst"; +"manage_session_name" = "Nafn á setu"; +"security_settings_advanced" = "ÍTARLEGT"; +"security_settings_cryptography" = "DULRITUN"; +"security_settings_crosssigning_reset" = "Endurstilla"; +"security_settings_crosssigning_bootstrap" = "Setja upp"; +"security_settings_crosssigning_info_ok" = "Kross-undirritun er tilbúin til notkunar."; +"security_settings_crosssigning" = "KROSS-UNDIRRITUN"; +"security_settings_secure_backup_delete" = "Eyða öryggisafriti"; +"security_settings_secure_backup_restore" = "Endurheimta úr öryggisafriti"; +"security_settings_secure_backup_reset" = "Endurstilla"; +"security_settings_secure_backup_setup" = "Setja upp"; +"security_settings_secure_backup_info_valid" = "Þessi seta öryggisafritar dulritunarlyklana þína."; +"security_settings_secure_backup_info_checking" = "Athuga…"; +"security_settings_secure_backup_description" = "Taktu öryggisafrit af dulritunarlyklunum þínum ásamt gögnum notandaaðgangsins fari svo að þú missir aðgang að setunum þínum. Dulritunarlyklarnir verða varðir með einstökum öryggislykli."; +"security_settings_secure_backup" = "VARIÐ ÖRYGGISAFRIT"; + +// Security settings +"security_settings_title" = "Öryggi"; +"settings_enable_room_message_bubbles" = "Skilaboðablöðrur"; +"settings_discovery_three_pid_details_revoke_action" = "Afturkalla"; +"settings_discovery_three_pid_details_share_action" = "Deila"; +"settings_discovery_three_pids_management_information_part2" = "Notandastillingar"; +"settings_key_backup_delete_confirmation_prompt_msg" = "Ertu viss? Þú munt tapa dulrituðu skilaboðunum þínum ef dulritunarlyklarnir þínir eru ekki rétt öryggisafritaðir."; +"settings_key_backup_delete_confirmation_prompt_title" = "Eyða öryggisafriti"; +"settings_key_backup_button_delete" = "Eyða öryggisafriti"; +"settings_key_backup_button_restore" = "Endurheimta úr öryggisafriti"; +"settings_key_backup_button_create" = "Byrja að nota öryggisafrit dulritunarlykla"; +"settings_key_backup_info_progress_done" = "Allir lyklar öryggisafritaðir"; +"settings_key_backup_info_progress" = "Öryggisafrita %@ lykla…"; +"settings_key_backup_info_not_valid" = "Þessi seta er ekki að öryggisafrita dulritunarlyklana þína, en þú ert með fyrirliggjandi öryggisafrit sem þú getur endurheimt úr og notað til að halda áfram."; +"settings_key_backup_info_valid" = "Þessi seta öryggisafritar dulritunarlyklana þína."; +"settings_key_backup_info_algorithm" = "Reiknirit: %@"; +"settings_key_backup_info_signout_warning" = "Taktu öryggisafrit af dulritunarlyklunum áður en þú skráir þig út svo þeir tapist ekki."; +"settings_key_backup_info_none" = "Dulritunarlyklarnir þínir eru ekki öryggisafritaðir úr þessari setu."; +"settings_key_backup_info_checking" = "Athuga…"; +"settings_deactivate_my_account" = "Gera notandaaðganginn minn óvirkann"; +"settings_add_3pid_invalid_password_message" = "Ógild auðkenni"; +"settings_add_3pid_password_title_msidsn" = "Bæta við símanúmeri"; +"settings_add_3pid_password_title_email" = "Bæta við tölvupóstfangi"; +"settings_labs_enable_threads" = "Skilaboð í spjallþráðum"; +"settings_labs_enabled_polls" = "Kannanir"; +"settings_integrations_allow_button" = "Sýsla með samþættingar"; +"settings_new_keyword" = "Bæta við nýju stikkorði"; +"settings_your_keywords" = "Stikkorðin þín"; +"settings_room_upgrades" = "Uppfærslur spjallrásar"; +"settings_call_invitations" = "Boð um símtöl"; +"settings_room_invitations" = "Boð á spjallrás"; +"settings_messages_containing_keywords" = "Stikkorð"; +"settings_messages_containing_at_room" = "@spjallrás"; +"settings_messages_containing_user_name" = "Notandanafnið mitt"; +"settings_messages_containing_display_name" = "Birtingarnafn mitt"; +"settings_encrypted_group_messages" = "Dulrituð hópskilaboð"; +"settings_group_messages" = "Hópskilaboð"; +"settings_encrypted_direct_messages" = "Dulrituð bein skilaboð"; +"settings_direct_messages" = "Bein skilaboð"; +"settings_notify_me_for" = "Láta mig vita fyrir"; +"settings_mentions_and_keywords" = "Minnst á og stikkorð"; +"settings_default" = "Sjálfgefnar tilkynningar"; +"settings_security" = "ÖRYGGI"; +"settings_three_pids_management_information_part2" = "Uppgötvun"; +"settings_deactivate_account" = "GERA AÐGANG ÓVIRKANN"; +"settings_key_backup" = "ÖRYGGISAFRIT AF LYKLI"; +"settings_about" = "UM HUGBÚNAÐINN"; +"settings_integrations" = "SAMÞÆTTINGAR"; +"settings_identity_server_settings" = "AUÐKENNISÞJÓNN"; +"settings_discovery_settings" = "UPPGÖTVUN"; +"settings_notifications" = "TILKYNNINGAR"; +"settings_links" = "TENGLAR"; +"media_type_accessibility_sticker" = "Límmerki"; +"media_type_accessibility_file" = "Skrá"; +"media_type_accessibility_location" = "Staðsetning"; +"media_type_accessibility_video" = "Myndskeið"; +"media_type_accessibility_audio" = "Hljóð"; +"media_type_accessibility_image" = "Mynd"; +"message_from_a_thread" = "Úr spjallþræði"; +"threads_empty_show_all_threads" = "Birta alla spjallþræði"; +"threads_empty_info_all" = "Spjallþræðir hjálpa til við að halda samræðum við efnið og gerir auðveldara að rekja þær."; +"threads_empty_title" = "Haltu umræðum skipulögðum með spjallþráðum"; +"threads_action_my_threads" = "Spjallþræðirnir mínir"; +"threads_action_all_threads" = "Allir spjallþræðir"; +"threads_title" = "Spjallþræðir"; +"thread_copy_link_to_thread" = "Afrita tengil á spjallþráð"; + +// MARK: Threads +"room_thread_title" = "Spjallþráður"; +"room_join_group_call" = "Taka þátt"; +"room_open_dialpad" = "Talnaborð"; +"room_place_voice_call" = "Raddsímtal"; +"room_accessibility_thread_more" = "Meira"; +"room_accessibility_hangup" = "Hang up"; +"room_accessibility_threads" = "Spjallþræðir"; +"room_accessibility_video_call" = "Myndsímtal"; +"room_accessibility_call" = "Símtal"; +"room_accessibility_upload" = "Senda inn"; +"room_accessibility_integrations" = "Samþættingar"; +"room_accessibility_search" = "Leita"; +"room_message_edits_history_title" = "Breytingar á skilaboðum"; +"room_resource_limit_exceeded_message_contact_2_link" = "hafðu samband við kerfisstjóra þjónustunnar þinnar"; +"room_predecessor_information" = "Þessi spjallrás er framhald af öðru samtali."; +"room_replacement_link" = "Samtalið heldur áfram hér."; +"room_replacement_information" = "Þessari spjallrás hefur verið skipt út og er hún ekki lengur virk."; +"room_action_reply" = "Svara"; +"room_action_send_sticker" = "Senda límmerki"; +"room_action_camera" = "Taka ljósmynd eða myndskeið"; +"room_event_copy_link_info" = "Tengill afritaður á klippispjald."; +"room_event_action_reaction_show_less" = "Sýna minna"; +"room_event_action_reaction_show_all" = "Sýna allt"; +"room_event_action_edit" = "Breyta"; +"room_event_action_reply_in_thread" = "Spjallþráður"; +"room_event_action_reply" = "Svara"; +"room_event_action_view_decrypted_source" = "Skoða afkóðaða upprunaskrá"; +"room_event_action_view_in_room" = "Skoða á spjallrás"; +"room_event_action_forward" = "Áfram"; +"room_event_action_end_poll" = "Ljúka könnun"; +"room_event_action_remove_poll" = "Fjarlægja könnun"; +"room_unsent_messages_cancel_title" = "Eyða ósendum skilaboðum"; +"encrypted_room_message_reply_to_placeholder" = "Senda dulritað svar…"; +"room_message_editing" = "Breytingar"; +"room_member_power_level_short_custom" = "Sérsniðið"; +"room_member_power_level_short_moderator" = "Umsjón"; +"room_member_power_level_short_admin" = "Stjórnandi"; +"room_participants_security_information_room_not_encrypted" = "Skilaboð í þessari spjallrás eru ekki enda-í-enda dulrituð."; +"room_participants_security_loading" = "Hleð inn…"; +"room_participants_action_security_status_loading" = "Hleð inn…"; +"room_participants_action_security_status_warning" = "Aðvörun"; +"room_participants_action_security_status_verify" = "Sannreyna"; +"room_participants_action_security_status_verified" = "Sannreynt"; +"room_participants_action_section_security" = "Öryggi"; +"room_participants_leave_prompt_title_for_dm" = "Fara út"; +"find_your_contacts_button_title" = "Finndu tengiliðina þína"; +"search_filter_placeholder" = "Sía"; +"rooms_empty_view_title" = "Spjallrásir"; +"people_empty_view_title" = "Fólk"; +"room_recents_suggested_rooms_section" = "TILLÖGUR AÐ SPJALLRÁSUM"; +"room_recents_server_notice_section" = "AÐVARANIR KERFIS"; +"social_login_button_title_sign_up" = "Skrá inn með %@"; +"create_room_section_header_topic" = "Umfjöllunarefni spjallrásar (valkvætt)"; +"create_room_placeholder_name" = "Heiti"; +"create_room_section_header_name" = "Heiti spjallrásar"; + +// MARK: - Create Room + +"create_room_title" = "Ný spjallrás"; +"searchable_directory_x_network" = "%@ netkerfi"; + +// MARK: - Searchable Directory View Controller + +"searchable_directory_create_new_room" = "Búa til nýja spjallrás"; +"biometrics_cant_unlocked_alert_message_retry" = "Reyna aftur"; +"biometrics_desetup_disable_button_title_x" = "Gera %@ óvirkt"; +"biometrics_desetup_title_x" = "Gera %@ óvirkt"; +"biometrics_setup_enable_button_title_x" = "Virkja %@"; +"biometrics_setup_title_x" = "Virkja %@"; +"biometrics_settings_enable_x" = "Virkja %@"; +"pin_protection_settings_change_pin" = "Breyta PIN-númeri"; +"pin_protection_settings_enable_pin" = "Virkja PIN-númer"; +"pin_protection_mismatch_error_message" = "Endilega reyndu aftur"; +"pin_protection_reset_alert_action_reset" = "Endurstilla"; +"pin_protection_forgot_pin" = "Gleymt PIN-númer"; +"pin_protection_enter_pin" = "Settu inn PIN-númerið þitt"; +"pin_protection_choose_pin_welcome_after_register" = "Velkomin."; + +// MARK: - PIN Protection + +"pin_protection_choose_pin_welcome_after_login" = "Velkomin(n) aftur."; +"major_update_done_action" = "Náði því"; +"major_update_learn_more_action" = "Kanna nánar"; +"secrets_reset_reset_action" = "Endurstilla"; + +// MARK: - Secrets reset + +"secrets_reset_title" = "Frumstilla allt"; +"secrets_setup_recovery_passphrase_confirm_passphrase_title" = "Staðfesta"; +"secrets_setup_recovery_passphrase_validate_action" = "Lokið"; +"secrets_setup_recovery_key_done_action" = "Lokið"; +"secrets_setup_recovery_key_export_action" = "Vista"; +"secrets_setup_recovery_key_loading" = "Hleð inn…"; +"secrets_recovery_with_key_recovery_key_placeholder" = "Settu inn öryggislykil"; +"secrets_recovery_with_key_recovery_key_title" = "Setja inn"; + +// Recover with key + +"secrets_recovery_with_key_title" = "Öryggislykill"; +"secrets_recovery_with_passphrase_passphrase_title" = "Setja inn"; +"secrets_recovery_reset_action_part_2" = "Frumstilla allt"; +"user_verification_session_details_verify_action_current_user_manually" = "Sannreyna handvirkt með textaskilaboðum"; +"user_verification_session_details_untrusted_title" = "Ekki treyst"; +"user_verification_sessions_list_session_untrusted" = "Ekki treyst"; +"user_verification_sessions_list_session_trusted" = "Treyst"; +"user_verification_sessions_list_table_title" = "Setur"; +"user_verification_sessions_list_user_trust_level_unknown_title" = "Óþekkt"; +"user_verification_sessions_list_user_trust_level_warning_title" = "Aðvörun"; + +// Sessions list + +"user_verification_sessions_list_user_trust_level_trusted_title" = "Treyst"; + +// MARK: - User verification + +// Start + +"user_verification_start_verify_action" = "Hefja sannvottun"; +"key_verification_tile_conclusion_done_title" = "Sannreynt"; +"social_login_button_title_sign_in" = "Skrá inn með %@"; +"social_login_button_title_continue" = "Halda áfram með %@"; +"social_login_list_title_sign_up" = "Eða"; +"social_login_list_title_sign_in" = "Eða"; + +// Social login + +"social_login_list_title_continue" = "Halda áfram með"; +"auth_softlogout_clear_data_sign_out" = "Skrá út"; +"auth_softlogout_clear_data_sign_out_title" = "Ertu viss?"; +"auth_softlogout_clear_data_button" = "Hreinsa öll gögn"; +"auth_softlogout_sign_in" = "Skrá inn"; +"auth_reset_password_error_not_found" = "Tölvupóstfangið þitt lítur ekki út fyrir að vera tengt við Matrix-auðkenni á þessum heimaþjóni."; +"auth_login_single_sign_on" = "Skrá inn"; +"onboarding_use_case_existing_server_button" = "Tengjast þjóni"; +"onboarding_use_case_skip_button" = "sleppt þessari spurningu"; +"onboarding_use_case_community_messaging" = "Samfélög"; +"onboarding_use_case_work_messaging" = "Teymi"; +"onboarding_use_case_personal_messaging" = "Vinir og fjölskylda"; +"onboarding_splash_page_1_title" = "Eigðu samtölin þín."; +"onboarding_splash_login_button_title" = "Ég er nú þegar með notandaaðgang"; + +// Onboarding +"onboarding_splash_register_button_title" = "Stofna notandaaðgang"; +"accessibility_button_label" = "hnappur"; + +// Accessibility +"accessibility_checkbox_label" = "hakreitur"; +"callbar_return" = "Til baka"; +"callbar_only_single_paused" = "Símtal í bið"; +"ok" = "Í lagi"; +"done" = "Lokið"; +"open" = "Opna"; +"less" = "Minna"; +"more" = "Meira"; +"switch" = "Skipta um"; +"joined" = "Gekk í hópinn"; +"skip" = "Sleppa"; +"close" = "Loka"; +"enable" = "Virkja"; +"notice_encryption_enabled_unknown_algorithm_by_you" = "Þú kveiktir á enda-í-enda dulritun (óþekkt algrími %@)."; +"notice_room_name_changed_by_you" = "Þú breyttir heiti spjallrásarinnar í %@."; +"notification_settings_receive_a_call" = "Láta mig vita þegar ég fæ símtal"; +"notification_settings_people_join_leave_rooms" = "Láta mig vita þegar fólk tekur þátt eða yfirgefur spjallrásir"; +"notification_settings_invite_to_a_new_room" = "Láta mig vita þegar mér er boðið á nýja spjallrás"; +"account_error_matrix_session_is_not_opened" = "Matrix-seta er ekki opnuð"; +"notice_error_unformattable_event" = "** Gat ekki myndgert skilaboð. Endilega tilkynntu villu"; +"notice_error_unknown_event_type" = "Óþekkt tegund atburðar"; +"notice_error_unexpected_event" = "Óvænt atvik"; +"notice_error_unsupported_event" = "Óstuddur atburður"; +"notice_unsupported_attachment" = "Óstutt viðhengi: %@"; +"notice_event_redacted" = ""; +"reject_call" = "Hafna símtali"; +"resend_message" = "Endursenda skilaboðin"; +"invite_user" = "Bjóða Matrix-notanda"; +"capture_media" = "Taka ljósmynd/myndskeið"; +"set_admin" = "Setja stjórnanda"; +"set_moderator" = "Setja umsjónarmann"; +"set_default_power_level" = "Frumstilla valdastig"; +"set_power_level" = "Setja valdastig"; +"submit_code" = "Senda inn kóða"; +"login_use_fallback" = "Nota varasíðu"; +"login_display_name_placeholder" = "Birtingarnafn (t.d. Jón Sigurðsson)"; +"login_user_id_placeholder" = "Matrix-auðkenni (t.d. @jon:matrix.org eða jon)"; +"poll_timeline_vote_not_registered_subtitle" = "Því miður, atkvæðið þitt var ekki skráð Prófaðu aftur"; +"version_check_modal_action_title_deprecated" = "Sjáðu hvernig"; +"space_participants_action_ban" = "Banna á þessu svæði"; +"space_participants_action_remove" = "Fjarlægja úr þessu svæði"; +"space_beta_announce_information" = "Svæði eru ný leið til að hópa fólk og spjallrásir. Svæði eru ekki ennþá tiltæk á iOS, en þú getur notað þau í vef- og vinnutölvuútgáfunum."; +"space_beta_announce_title" = "Svæði er eiginleiki sem kemur bráðum"; +"space_feature_unavailable_subtitle" = "Svæði eru ekki ennþá tiltæk á iOS, en þú getur notað þau í vef- og vinnutölvuútgáfunum"; + +// Mark: - Spaces + +"space_feature_unavailable_title" = "Svæði (Spaces) eru ekki ennþá komin hingað"; +"room_intro_cell_information_multiple_dm_sentence2" = "Aðeins þið eruð í þessu samtali, nema einhver bjóði einhverjum öðrum að taka þátt."; +"room_intro_cell_information_dm_sentence2" = "Aðeins þið tveir/tvö eruð í þessu samtali, enginn annar getur tekið þátt."; +"room_intro_cell_information_dm_sentence1_part3" = ". "; +"room_intro_cell_information_dm_sentence1_part1" = "Þetta er upphaf beinna skilaboða með "; +"room_intro_cell_information_room_without_topic_sentence2_part1" = "Bæta við umræðuefni"; +"room_intro_cell_information_room_sentence1_part1" = "Þetta er upphafið á "; +"invite_friends_share_text" = "Halló, talaðu við mig á %@: %@"; + +// MARK: - Invite friends + +"invite_friends_action" = "Bjóða vinum á %@"; +"call_transfer_error_message" = "Flutningur símtals mistókst"; +"create_room_show_in_directory" = "Birta spjallrás í spjallrásalistanum"; +"create_room_section_footer_encryption" = "Ekki er hægt að gera dulritun óvirka eftirá."; +"biometrics_cant_unlocked_alert_title" = "Get ekki aflæst forriti"; +"biometrics_usage_reason" = "Þú þarft að auðkenna þig til að fá aðgang að forritinu þínu"; +"pin_protection_confirm_pin" = "Staðfestu PIN-númerið þitt"; +"pin_protection_choose_pin" = "Útbúðu PIN-númer í öryggisskyni"; +"secrets_reset_warning_title" = "Ef þú frumstillir allt"; + + +"secrets_setup_recovery_passphrase_summary_title" = "Vista öryggisfrasann þinn"; +"secrets_setup_recovery_passphrase_confirm_information" = "Settu aftur inn öryggisfrasann þinn til að staðfesta hann."; +"secrets_setup_recovery_passphrase_additional_information" = "Ekki nota Matrix-lykilorðið þitt."; + +// Recovery passphrase + +"secrets_setup_recovery_passphrase_title" = "Setja öryggisfrasa"; + +// MARK: - Secrets set up + +// Recovery Key + +"secrets_setup_recovery_key_title" = "Vista öryggislykilinn þinn"; +"secrets_recovery_with_key_invalid_recovery_key_message" = "Gakktu úr skugga um að þú hafðir sett inn réttan öryggislykil."; +"secrets_recovery_with_key_information_unlock_secure_backup_with_key" = "Settu inn öryggislykilinn þinn til að halda áfram."; +"secrets_recovery_with_key_information_unlock_secure_backup_with_phrase" = "Settu inn öryggisfrasann þinn til að halda áfram."; +"secrets_recovery_with_passphrase_invalid_passphrase_message" = "Gakktu úr skugga um að þú hafðir sett inn réttan öryggisfrasa."; +"secrets_recovery_with_passphrase_recover_action" = "Nota frasa"; + +// Recover with passphrase + +"secrets_recovery_with_passphrase_title" = "Öryggisfrasi"; +"user_verification_session_details_verify_action_other_user" = "Sannreyna handvirkt"; +"user_verification_session_details_verify_action_current_user" = "Sannprófa gagnvirkt"; +"user_verification_sessions_list_information" = "Skilaboð við þennan notanda í þessari spjallrás eru enda-í-enda dulrituð þannig að enginn annar getur lesið þau."; + +// Scanned +"key_verification_scan_confirmation_scanned_title" = "Næstum því búið!"; +"key_verification_scan_confirmation_scanning_device_waiting_other" = "Bíð eftir hinu tækinu…"; +"key_verification_scan_confirmation_scanning_user_waiting_other" = "Bíð eftir %@…"; + +// MARK: Scan confirmation + +// Scanning +"key_verification_scan_confirmation_scanning_title" = "Næstum því búið! Bíð eftir staðfestingu…"; +"key_verification_verify_qr_code_scan_other_code_success_title" = "Kóði sannvottaður!"; +"key_verification_verify_qr_code_other_scan_my_code_title" = "Tókst hinum notandanum að skanna QR-kóðann?"; +"key_verification_verify_qr_code_cannot_scan_action" = "Geturðu ekki skannað?"; +"key_verification_verify_qr_code_scan_code_other_device_action" = "Skanna með þessu tæki"; +"key_verification_verify_qr_code_scan_code_action" = "Skannaðu kóðann hinna"; +"key_verification_verify_qr_code_information_other_device" = "Skannaðu kóðann hér fyrir neðan til að staðfesta:"; +"key_verification_tile_request_outgoing_title" = "Sannvottun send"; + +// Tiles + +"key_verification_tile_request_incoming_title" = "Beiðni um sannvottun"; + + +// Generic errors +"error_invite_3pid_with_no_identity_server" = "Bættu við auðkennisþjóni í stillingunum til að geta boðið með tölvupósti."; + +// User + +"key_verification_verified_user_information" = "Skilaboð við þennan notanda eru enda-í-enda dulrituð þannig að enginn annar getur lesið þau."; +"key_verification_verified_new_session_title" = "Ný seta er sannreynd!"; +"key_verification_verify_sas_title_number" = "Bera saman númer"; + +// MARK: Verify + +"key_verification_verify_sas_title_emoji" = "Bera saman táknmyndir"; +"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Nota öryggisfrasa eða öryggislykil"; +"device_verification_self_verify_wait_new_sign_in_title" = "Sannprófa þessa innskráningu"; + +// Unverified sessions + +"key_verification_self_verify_unverified_sessions_alert_title" = "Yfirfarðu hvar þú sért skráð/ur inn"; +"device_verification_start_verify_button" = "Byrja sannprófun"; + +// Mark: Incoming +"device_verification_incoming_title" = "Innkomin beiðni um sannvottun"; +"device_verification_error_cannot_load_device" = "Gat ekki hlaðið inn upplýsingum um setu."; +"key_verification_new_session_title" = "Sannprófaðu nýju setuna þína"; +"sign_out_key_backup_in_progress_alert_cancel_action" = "Ég mun bíða"; +"sign_out_non_existing_key_backup_alert_setup_secure_backup_action" = "Byrja að nota varin öryggisafrit"; +"key_backup_recover_from_recovery_key_recovery_key_title" = "Setja inn"; +"key_backup_recover_from_passphrase_lost_passphrase_action_part3" = "."; +"key_backup_recover_from_passphrase_passphrase_placeholder" = "Settu inn frasa"; +"key_backup_recover_from_passphrase_passphrase_title" = "Setja inn"; + +// MARK: Key backup recover + +"key_backup_recover_title" = "Örugg skilaboð"; +"key_backup_setup_success_from_recovery_key_make_copy_action" = "Gera afrit"; +"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "Vista öryggislykil"; +"key_backup_setup_passphrase_set_passphrase_action" = "Setja frasa"; +"key_backup_setup_passphrase_passphrase_invalid" = "Prófaðu að bæta við orði"; +"key_backup_setup_passphrase_passphrase_placeholder" = "Settu inn frasa"; +"key_backup_setup_passphrase_passphrase_title" = "Setja inn"; + +// Passphrase + +"key_backup_setup_passphrase_title" = "Verðu öryggisafritið þitt með öryggisfrasa"; +"key_backup_setup_intro_manual_export_action" = "Flytja út dulritunarlykla handvirkt"; + + +// Cancel + +"secure_key_backup_setup_cancel_alert_title" = "Ertu viss?"; +"secure_key_backup_setup_existing_backup_error_unlock_it" = "Aflæsa því"; +"secure_key_backup_setup_existing_backup_error_title" = "Öryggisafrit skilaboða er þegar til"; +"secure_key_backup_setup_intro_use_security_passphrase_title" = "Nota öryggisfrasa"; +"secure_key_backup_setup_intro_use_security_key_title" = "Nota öryggislykil"; +"deactivate_account_password_alert_message" = "Til að halda áfram, settu inn Matrix-lykilorðið þitt"; +"service_terms_modal_description_integration_manager" = "Þetta gerir þér kleift að nota vélmenni, viðmótshluta og límmerkjapakka."; +"service_terms_modal_table_header_integration_manager" = "SKILMÁLAR SAMÞÆTTINGARSTÝRINGAR"; +"service_terms_modal_table_header_identity_server" = "SKILMÁLAR AUÐKENNISÞJÓNS"; +"service_terms_modal_footer" = "Þetta má gera óvirkt hvenær sem er í stillingunum."; +"share_extension_send_now" = "Senda núna"; +"room_widget_permission_information_title" = "Að nota það gæti deilt gögnum með %@:\n"; +"room_widget_permission_webview_information_title" = "Að nota það gæti stillt vefkökur og deilt gögnum með %@:\n"; +"widget_menu_remove" = "Fjarlægja fyrir alla"; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "Bæta við núna?"; +"bug_report_background_mode" = "Halda áfram í bakgrunni"; + +// Key backup wrong version +"e2e_key_backup_wrong_version_title" = "Nýtt öryggisafrit af lykli"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_2" = "Við deilum ekki upplýsingum með utanaðkomandi aðilum"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_1" = "Við skráum ekki eða búum til snið með gögnum notendaaðganga"; + +// Analytics +"analytics_prompt_title" = "Hjálpaðu okkur að bæta %@"; +"call_no_stun_server_error_use_fallback_button" = "Reyndu að nota %@"; +"call_no_stun_server_error_message_2" = "Annars geturðu reynt að nota almenningsþjóninn á %@, en það er oft ekki eins áreiðanlegt, auk þess að þá er IP-vistfanginu þínu deilt með þeim þjóni. Þú getur líka föndrað við þetta í stillingunum"; +"call_no_stun_server_error_message_1" = "Spurðu kerfisstjóra %@ heimaþjónsins þíns um að setja upp TURN-þjón til að tryggja að símtöl virki eðlilega."; +"camera_unavailable" = "Myndavélin er ekki aðgengileg á tækinu þínu"; +"homeserver_connection_lost" = "Gat ekki tengst við heimaþjóninn."; +"event_formatter_rerequest_keys_part1_link" = "Biðja aftur um dulritunarlykla"; +"image_picker_action_library" = "Velja úr safni"; +"room_notifs_settings_mentions_and_keywords" = "Einungis þar sem er minnst á og stikkorð"; +"room_details_advanced_e2e_encryption_disabled_for_dm" = "Dulritun er ekki virkjuð hér."; +"room_details_advanced_e2e_encryption_enabled_for_dm" = "Dulritun er ekki virk hér"; +"identity_server_settings_alert_change" = "Aftengjast frá auðkennisþjóninum %1$@ og tengjast í staðinn við %2$@?"; +"identity_server_settings_alert_change_title" = "Skipta um auðkennisþjón"; +"identity_server_settings_alert_no_terms" = "Auðkennisþjónninn sem þú valdir er ekki með neina þjónustuskilmála. Ekki halda áfram nema þú treystir eiganda netþjónsins."; +"identity_server_settings_alert_no_terms_title" = "Auðkennisþjónninn er ekki með neina þjónustuskilmála"; +"identity_server_settings_disconnect_info" = "Ef þú aftengist frá auðkennisþjóninum þínum, munu aðrir notendur ekki geta fundið þig og þú munt ekki geta boðið öðrum með símanúmeri eða tölvupósti."; +"manage_session_sign_out" = "Skrá út úr þessari setu"; +"manage_session_info" = "UPPLÝSINGAR UM SETU"; + +// Manage session +"manage_session_title" = "Sýsla með setu"; +"security_settings_user_password_description" = "Staðfestu auðkennin þín með því að setja inn lykilorðið á Matrix-aðganginn þinn"; +"security_settings_blacklist_unverified_devices" = "Aldrei senda skilaboð til ósannvottaðra tækja"; +"security_settings_export_keys_manually" = "Flytja handvirkt út dulritunarlykla"; +"security_settings_crosssigning_info_not_bootstrapped" = "Kross-undirritun er ekki ennþá uppsett."; +"security_settings_backup" = "ÖRYGGISAFRIT SKILABOÐA"; +"security_settings_crypto_sessions_loading" = "Hleð inn setum…"; +"settings_identity_server_no_is" = "Enginn auðkennisþjónn stilltur"; +"settings_identity_server_description" = "Með auðkennisþjóninum hér fyrir ofan, geturðu uppgötvað og verið finnanleg/ur fyrir þá tengiliði sem þú þekkir."; +"settings_discovery_three_pid_details_enter_sms_code_action" = "Settu inn SMS-virkjunarkóða"; +"settings_discovery_three_pid_details_cancel_email_validation_action" = "Hætta við að sannvotta tölvupóstfang"; +"settings_discovery_three_pid_details_title_phone_number" = "Sýsla með símanúmer"; +"settings_discovery_three_pid_details_title_email" = "Sýsla með tölvupóst"; +"settings_discovery_error_message" = "Villa kom upp. Endilega reyndu aftur."; +"settings_discovery_accept_terms" = "Samþykktu skilmála auðkennisþjónsins"; +"settings_discovery_terms_not_signed" = "Samþykktu þjónustuskilmála auðkennisþjónsins (%@) svo hægt sé að finna þig með tölvupóstfangi eða símanúmeri."; +"settings_devices_description" = "Opinbert heiti setu er sýnilegt þeim sem þú átt samskipti við"; +"settings_key_backup_info_version" = "Útgáfa öryggisafrits af lykli: %@"; +"settings_add_3pid_password_message" = "Til að halda áfram, settu inn Matrix-lykilorðið þitt"; +"settings_analytics_and_crash_data" = "Senda hrun- og greiningargögn"; +"settings_show_url_previews_description" = "Forskoðanir verða eingöngu sýndar í ódulrituðum spjallrásum."; +"settings_show_url_previews" = "Birta forskoðun vefsvæða"; +"settings_integrations_allow_description" = "Notaðu samþættingarstýringu (%@ til að stýra vélmennum, viðmótshlutum og límmerkjapökkum.\n\nSamþættingarstýringar taka við stillingagögnum og geta breytt viðmótshlutum, sent boð í spjallrásir, auk þess að geta úthlutað völdum fyrir þína hönd."; +"settings_calls_stun_server_fallback_description" = "Leyfa %@ sem varaleið fyrir símtalaþjónustu þegar heimaþjónninn þinn býður ekki upp á slíkt (IP-vistfanginu þínu yrði deilt á meðan símtali stendur)."; +"external_link_confirmation_title" = "Yfirfarðu þennan tengil"; +"find_your_contacts_footer" = "Þetta má gera óvirkt hvenær sem er í stillingunum."; +"contacts_address_book_permission_denied_alert_title" = "Tengiliðir óvirkir"; +"directory_search_results_title" = "Vafra í niðurstöðum möppu"; +/* The placeholder string contains onboarding_use_case_skip_button as a tappable action */ +"onboarding_use_case_not_sure_yet" = "Ekki ennþá viss? Þú getur %@"; +"call_invite_expired" = "Boð í símtal er útrunnið"; +"notification_settings_suppress_from_bots" = "Útiloka tilkynningar frá vélmennum"; +"notification_settings_sender_hint" = "@notandi:lén.is"; + +// Notification settings screen +"notification_settings_disable_all" = "Gera allar tilkynningar óvirkar"; +"message_unsaved_changes" = "Það eru óvistaðar breytingar. Ef þú ferð verður þeim hent."; +"unban" = "Taka úr banni"; +"notice_room_created_by_you" = "Þú bjóst til og stilltir spjallrásina."; +"notice_profile_change_redacted_by_you" = "Þú uppfærðir notandasniðið þitt %@"; +"notice_room_topic_removed_by_you" = "Þú fjarlægðir umfjöllunarefnið"; +"notice_room_name_removed_by_you_for_dm" = "Þú fjarlægðir heitið"; +"notice_conference_call_request_by_you" = "Þú baðst um VoIP-símafund"; +"notice_declined_video_call_by_you" = "Þú hafnaðir símtalinu"; +"notice_room_name_changed_by_you_for_dm" = "Þú breyttir heitinu í %@."; +"notice_topic_changed_by_you" = "Þú breyttir umræðuefninu í \"%@\"."; +"notice_display_name_removed_by_you" = "Þú fjarlægðir birtingarnafn þitt"; +"notice_display_name_changed_from_by_you" = "Þú breytti birtingarnafni þínu úr %@ í %@"; +"notice_display_name_set_by_you" = "Þú settir birtingarnafn þitt sem %@"; +"notice_room_withdraw_by_you" = "Þú tókst til baka boð til %@"; +"notice_room_ban_by_you" = "Þú bannaðir %@"; +"notice_room_unban_by_you" = "Þú tókst %@ úr banni"; +"notice_room_kick_by_you" = "Þú fjarlægðir %@"; +"notice_room_leave_by_you" = "Þú fórst út"; +"notice_room_third_party_revoked_invite_by_you_for_dm" = "Þú afturkallaðir boð til %@"; +"notice_room_third_party_revoked_invite_by_you" = "Þú afturkallaðir boð til %@ um þátttöku í spjallrásinni"; +"notice_room_third_party_registered_invite_by_you" = "Þú samþykktir boð um að taka þátt í %@"; +"notice_room_third_party_invite_by_you_for_dm" = "Þú bauðst %@"; +"notice_room_third_party_invite_by_you" = "Þú sendir boð til %@ um þátttöku í spjallrásinni"; + +// Notice Events with "You" +"notice_room_invite_by_you" = "Þú bauðst %@"; +"notice_conference_call_request" = "%@ bað um VoIP-símafund"; +"notice_declined_video_call" = "%@ hafnaði símtalinu"; +"notice_ended_video_call" = "%@ lauk símtalinu"; +"notice_answered_video_call" = "%@ svaraði símtalinu"; +"notice_placed_video_call" = "%@ hringdi myndsímtal"; +"notice_placed_voice_call" = "%@ hringdi raddsímtal"; +"notice_room_name_changed_for_dm" = "%@ breytti heitinu í %@."; +"notice_room_name_changed" = "%@ breytti heiti spjallrásarinnar í %@."; +"notice_topic_changed" = "%@ breytti umræðuefninu í \"%@\"."; +"notice_display_name_removed" = "%@ fjarlægði birtingarnafn sitt"; +"notice_display_name_changed_from" = "%@ breytti birtingarnafni sínu úr %@ í %@"; +"notice_display_name_set" = "%@ setti birtingarnafn sitt sem %@"; +"notice_avatar_url_changed" = "%@ breytti auðkennismynd sinni"; +"notice_room_withdraw" = "%@ tók til baka boð til %@"; +"notice_room_ban" = "%@ bannaði %@"; +"notice_room_unban" = "%@ tók %@ úr banni"; +"notice_room_reject" = "%@ hafnaði boðinu"; +"notice_room_third_party_revoked_invite_for_dm" = "%@ afturkallaði boð til %@"; +"notice_room_third_party_revoked_invite" = "%@ afturkallaði boð til %@ um þátttöku í spjallrásinni"; +"notice_room_third_party_registered_invite" = "%@ samþykkti boð um að taka þátt í %@"; +"notice_room_third_party_invite" = "%@ sendi boð til %@ um þátttöku í spjallrásinni"; +"local_contacts_access_discovery_warning_title" = "Uppgötvun notenda"; +"user_id_placeholder" = "t.d.: @jon:heimaþjónn"; +"network_error_not_reachable" = "Athugaðu nettenginguna þína"; +"error_common_message" = "Villa kom upp. Endilega reyndu aftur síðar."; +"unsent" = "Ósent"; +"search_searching" = "Leit í gangi..."; + +// Contacts +"contact_mx_users" = "Matrix-notendur"; +"attachment_unsupported_preview_title" = "Ekki tókst að forskoða"; +"attachment_multiselection_size_prompt" = "Viltu senda myndir sem:"; +"attachment_size_prompt_message" = "Þú getur slökkt á þessu í stillingunum."; +"attachment_size_prompt_title" = "Staðfestu stærð til að senda"; + +// Attachment +"attachment_size_prompt" = "Viltu senda sem:"; + +// Room members +"room_member_ignore_prompt" = "Ertu viss um að þú viljir fela öll skilaboð frá þessum notanda?"; +"room_left_for_dm" = "Þú fórst út"; +"room_error_timeline_event_not_found" = "Forritið reyndi að hlaða inn tilteknum punkti úr tímalínu þessarar spjallrásar, en tókst ekki að finna þetta"; +"room_error_cannot_load_timeline" = "Mistókst að hlaða inn tímalínu"; +"room_error_topic_edition_not_authorized" = "Þú hefur ekki heimild til að breyta umfjöllunarefni þessarar spjallrásar"; +"room_error_name_edition_not_authorized" = "Þú hefur ekki heimild til að breyta heiti þessarar spjallrásar"; +"room_error_join_failed_empty_room" = "Ekki er í augnablikinu hægt að taka þátt í spjallrás sem er tóm."; + +// Room +"room_please_select" = "Veldu einhverja spjallrás"; +"room_creation_participants_placeholder" = "(t.d.: @jon:heimaþjónn1; @sigga:heimaþjónn2...)"; +"room_creation_alias_placeholder_with_homeserver" = "(t.d. #eitthvað%@)"; +"room_creation_alias_placeholder" = "(t.d. #eitthvað:vefur.is)"; +"room_creation_name_placeholder" = "(t.d. kaffiHópur)"; +"account_error_push_not_allowed" = "Tilkynningar ekki leyfðar"; +"account_error_msisdn_wrong_description" = "Þetta lítur ekki út eins og gilt símanúmer"; +"account_error_picture_change_failed" = "Breyting á mynd mistókst"; +"account_error_display_name_change_failed" = "Breyting birtingarnafns mistókst"; +"account_linked_emails" = "Tengd tölvupóstföng"; +"account_link_email" = "Tengja tölvupóstfang"; +"room_event_encryption_verify_title" = "Sannprófa setu\n\n"; +"room_event_encryption_info_device_fingerprint" = "Ed25519 fingrafar\n"; +"room_event_encryption_info_device_verification" = "Sannvottun\n"; +"room_event_encryption_info_device_id" = "Auðkenni\n"; +"room_event_encryption_info_device_name" = "Opinbert nafn\n"; +"room_event_encryption_info_device_unknown" = "óþekkt seta\n"; +"room_event_encryption_info_device" = "\nUpplýsingar um setu sendanda\n"; +"room_event_encryption_info_event_decryption_error" = "Afkóðunarvilla\n"; +"room_event_encryption_info_event_session_id" = "Auðkenni setu\n"; +"room_event_encryption_info_event_algorithm" = "Reiknirit\n"; +"room_event_encryption_info_event_fingerprint_key" = "Tilkynnti Ed25519 fingrafarslykil\n"; +"room_event_encryption_info_event_identity_key" = "Curve25519 auðkennislykill\n"; +"room_event_encryption_info_event_user_id" = "Notandaauðkenni\n"; +"room_event_encryption_info_event" = "Upplýsingar um atburð\n"; + +// Encryption information +"room_event_encryption_info_title" = "Enda-í-enda dulritunarupplýsingar\n\n"; +"device_details_rename_prompt_message" = "Opinbert heiti setu er sýnilegt þeim sem þú átt samskipti við"; +"device_details_last_seen" = "Sást síðast\n"; +"device_details_identifier" = "Auðkenni\n"; +"device_details_name" = "Opinbert nafn\n"; + +// Devices +"device_details_title" = "Upplýsingar um setu\n"; +"settings_enable_push_notifications" = "Virkja ýtitilkynningar"; +"settings_enable_inapp_notifications" = "Virkja tilkynningar innan forrits"; +"room_displayname_more_than_two_members" = "%@ og %@ til viðbótar"; +"notice_crypto_error_unknown_inbound_session_id" = "Seta sendandans hefur ekki sent okkur dulritunarlyklana fyrir þessi skilaboð."; +"notice_crypto_unable_to_decrypt" = "** Mistókst að afkóða: %@ **"; +"biometrics_setup_subtitle" = "Sparaðu þér tíma"; +"pin_protection_settings_enabled_forced" = "PIN-númer virkt"; +"pin_protection_mismatch_error_title" = "PIN-númer samsvara ekki"; +"pin_protection_reset_alert_title" = "Endursetja PIN-númer"; + +// MARK: - Major update + +"major_update_title" = "Riot er núna %@"; + +// MARK: - Cross-signing + +// Banner + +"cross_signing_setup_banner_title" = "Setja upp dulritun"; + +// Incoming key verification request + +"key_verification_incoming_request_incoming_alert_message" = "%@ vill sannreyna"; +"key_verification_tile_conclusion_warning_title" = "Ótreyst innskráning"; +"key_verification_tile_request_status_accepted" = "Þú samþykktir"; +"key_verification_tile_request_status_cancelled_by_me" = "Þú hættir við"; +"key_verification_tile_request_status_data_loading" = "Hleð gögnum…"; +"e2e_key_backup_wrong_version_button_wasme" = "Það var ég"; +"analytics_prompt_yes" = "Já, það er í góðu lagi"; +"event_formatter_group_call" = "Hópsímtal"; +"event_formatter_call_missed_voice" = "Ósvarað símtal"; +"event_formatter_call_active_video" = "Virkt myndsímtal"; +"event_formatter_call_active_voice" = "Virkt raddsímtal"; +"room_details_no_local_addresses_for_dm" = "Þessi spjallrás er ekki með nein staðvær vistföng"; +"room_details_access_section_directory_toggle_for_dm" = "Setja á skrá yfir spjallrásir"; +"room_details_access_section_anyone_for_dm" = "Hver sá sem þekkir slóðina á spjallrásina, að gestum meðtöldum"; +"room_details_access_section_anyone_apart_from_guest_for_dm" = "Hver sá sem þekkir slóðina á spjallrásina, fyrir utan gesti"; +"room_details_access_section_for_dm" = "Hver hefur aðgang að þessu?"; +"room_details_search" = "Leita í spjallrás"; +"manage_session_trusted" = "Treyst af þér"; +"security_settings_crypto_sessions" = "SETURNAR MÍNAR"; +"settings_discovery_three_pids_management_information_part3" = "."; +"settings_contacts_enable_sync" = "Finndu tengiliðina þína"; +"settings_messages_by_a_bot" = "Skilaboð frá vélmenni"; +"settings_notifications_disabled_alert_title" = "Tilkynningar óvirkar"; +"settings_device_notifications" = "Tilkynningar tækis"; +"settings_confirm_media_size" = "Staðfesta stærð við sendingu"; +"settings_three_pids_management_information_part3" = "."; +"settings_phone_contacts" = "TENGILIÐIR SÍMANS"; +"settings_sending_media" = "SENDING MYNDA OG MYNDSKEIÐA"; +"room_event_action_reaction_history" = "Ferill viðbragða"; +"contacts_address_book_no_identity_server" = "Enginn auðkennisþjónn stilltur"; +"auth_softlogout_clear_data" = "Hreinsa persónuleg gögn"; +"onboarding_splash_page_3_title" = "Örugg skilaboð."; +"onboarding_splash_page_2_title" = "Þú ert við stjórnvölinn."; +"callbar_only_multiple_paused" = "%@ símtöl í bið"; +"callbar_active_and_multiple_paused" = "1 virkt símtal (%@) · %@ símtöl í bið"; +"callbar_active_and_single_paused" = "1 virkt símtal (%@) · 1 símtal í bið"; + +// Call Bar +"callbar_only_single_active" = "Ýttu til að fara til baka í símtalið (%@)"; +"notice_feedback" = "Umsögn um atburð (id: %@): %@"; +"notice_invalid_attachment" = "ógilt viðhengi"; +"notice_file_attachment" = "skráarviðhengi"; +"notice_location_attachment" = "staðsetningarviðhengi"; +"notice_video_attachment" = "myndskeiðsviðhengi"; +"notice_audio_attachment" = "hljóðskrárviðhengi"; +"notice_image_attachment" = "myndskrárviðhengi"; +"notice_room_join_rule_invite_by_you_for_dm" = "Þú gerðir þetta einungis aðgengilegt gegn boði."; +"notice_room_join_rule_invite_by_you" = "Þú gerðir spjallrás einungis aðgengilega gegn boði."; +"notice_room_created" = "%@ bjó til og stillti spjallrásina."; +"notice_profile_change_redacted" = "%@ uppfærði notandasniðið sitt %@"; +"notice_room_topic_removed" = "%@ fjarlægði umfjöllunarefnið"; +"notice_room_name_removed_for_dm" = "%@ fjarlægði heitið"; +"notice_room_name_removed" = "%@ fjarlægði heiti spjallrásar"; +"voice_message_stop_locked_mode_recording" = "Ýttu á upptökuna þína til að stöðva eða hlusta"; + +// Mark: - Voice Messages + +"voice_message_release_to_send" = "Haltu niðri til að taka upp, slepptu til að senda"; +"pin_protection_kick_user_alert_message" = "Of margar villur, þú hefur verið skráð/ur út"; +"pin_protection_settings_section_footer" = "Til að endurstilla PIN-númerið, þarftu að skrá þig inn aftur og útbúa nýtt."; +"secrets_setup_recovery_passphrase_confirm_passphrase_placeholder" = "Staðfestu frasa"; +"key_verification_verify_qr_code_start_emoji_action" = "Sannprófa með táknmyndum"; +"key_verification_verify_qr_code_emoji_information" = "Sannprófaðu með því að bera saman einstakar táknmyndir."; + +// MARK: Self verification wait + +"device_verification_self_verify_wait_title" = "Algjört öryggi"; +"key_verification_user_title" = "Sannreyndu þau"; + +// Success from secure backup +"key_backup_setup_success_from_secure_backup_info" = "Verið er að öryggisafrita dulritunarlyklana þína."; +"secure_key_backup_setup_intro_use_security_passphrase_info" = "Settu inn leynilegan frasa eða setningu sem aðeins þú þekkir, og útbúðu lykil fyrir öryggisafrit."; +"secure_key_backup_setup_intro_use_security_key_info" = "Útbúðu öryggislykil til að geyma á öruggum stað, eins og í lykilorðastýringu eða jafnvel í peningaskáp."; +"event_formatter_jitsi_widget_removed_by_you" = "Þú fjarlægðir VoIP-símafund"; +"event_formatter_jitsi_widget_added_by_you" = "Þú bættir við VoIP-símafundi"; +"event_formatter_widget_removed_by_you" = "Þú fjarlægðir viðmótshluta: %@"; + +// Events formatter with you +"event_formatter_widget_added_by_you" = "Þú bættir inn viðmótshluta: %@"; +"external_link_confirmation_message" = "Tengillinn %@ fer með þig yfir á annað vefsvæði: %@\n\nErtu viss um að þú viljir halda áfram?"; +"room_unsent_messages_cancel_message" = "Ertu viss um að þú viljir eyða öllum ósendum skilaboðum úr þessari spjallrás?"; +"room_participants_action_security_status_complete_security" = "Algjört öryggi"; +"find_your_contacts_identity_service_error" = "Tókst ekki að tengjast auðkennisþjóninum."; +"find_your_contacts_message" = "Leyfðu %@ að birta tengiliðina þína svo þú getir strax farið að spjalla við þá sem þú þekkir best."; +"room_recents_unknown_room_error_message" = "Finn ekki þessa spjallrás. Gakktu úr skugga um að hún sé til"; +"auth_softlogout_signed_out" = "Þú ert skráð/ur út"; +"auth_accept_policies" = "Yfirfarðu og samþykktu reglur þessa heimaþjóns:"; +"secrets_recovery_with_key_invalid_recovery_key_title" = "Tókst ekki að tengjast leynigeymslu"; +"secrets_recovery_with_passphrase_invalid_passphrase_title" = "Tókst ekki að tengjast leynigeymslu"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "notað öryggislykilinn þinn"; +"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "Ertu ekki með öryggisfrasann þinn? Þú getur "; +"secrets_recovery_with_passphrase_passphrase_placeholder" = "Settu inn öryggisfrasa"; +"key_verification_scan_confirmation_scanned_user_information" = "Sýnir %@ sama skjöldinn?"; + +// MARK: QR code + +"key_verification_verify_qr_code_title" = "Sannprófa með skönnun"; + +// MARK: Start +"device_verification_start_title" = "Sannprófaðu með því að bera saman stuttan textastreng"; +"key_backup_recover_invalid_passphrase_title" = "Rangur öryggisfrasi"; +"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "Staðfestu frasa"; +"secure_backup_setup_banner_subtitle" = "Tryggðu þig gegn því að missa aðgang að dulrituðum skilaboðum og gögnum"; +"secure_key_backup_setup_intro_info" = "Tryggðu þig gegn því að missa aðgang að dulrituðum skilaboðum og gögnum með því að taka öryggisafrit af dulritunarlyklunum á netþjóninum þinum."; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_upgrade */ +"analytics_prompt_terms_upgrade" = "Lestu alla skilmálana okkar %@. Er það í lagi?"; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ +"analytics_prompt_terms_new_user" = "Þú getur lesið skilmálana okkar %@."; +"identity_server_settings_alert_error_invalid_identity_server" = "%@ er ekki gildur auðkennisþjónn."; +"identity_server_settings_place_holder" = "Settu inn slóð á auðkennisþjón"; +"security_settings_complete_security_alert_title" = "Algjört öryggi"; +"security_settings_crosssigning_complete_security" = "Algjört öryggi"; +"settings_key_backup_info" = "Öryggi dulritaðra skilaboða er tryggt með enda-í-enda dulritun. Einungis þú og viðtakendurnir hafa dulritunarlyklana til að lesa slík skilaboð."; +"settings_labs_enable_ringing_for_group_calls" = "Hringing fyrir hópsímtöl"; +"onboarding_use_case_message" = "Við munum hjálpa þér að tengjast."; +"callbar_only_single_active_group" = "Ýttu til að taka þátt í hópsímtalinu (%@)"; diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings index e9b963254..83bf336fc 100644 --- a/Riot/Assets/it.lproj/Vector.strings +++ b/Riot/Assets/it.lproj/Vector.strings @@ -2109,3 +2109,5 @@ "home_syncing" = "Sincronizzazione"; "room_participants_leave_success" = "Stanza abbandonata"; "room_participants_leave_processing" = "Uscita in corso"; +"notice_error_unformattable_event" = "** Impossibile visualizzare il messaggio. Si prega di segnalare l'errore"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Mostra avatar e nome più recenti per gli utenti nella cronologia dei messaggi"; diff --git a/Riot/Assets/ja.lproj/Vector.strings b/Riot/Assets/ja.lproj/Vector.strings index 9a3211902..10c27e967 100644 --- a/Riot/Assets/ja.lproj/Vector.strings +++ b/Riot/Assets/ja.lproj/Vector.strings @@ -1477,7 +1477,7 @@ "notification_settings_always_notify" = "常に通知"; "notification_settings_never_notify" = "決して通知しない"; "notification_settings_word_to_match" = "一致する単語"; -"notification_settings_highlight" = "Highlight"; +"notification_settings_highlight" = "ハイライト"; "notification_settings_custom_sound" = "カスタムサウンド"; "notification_settings_per_room_notifications" = "1ルームあたりの通知"; "notification_settings_per_sender_notifications" = "送信者ごとの通知"; @@ -1600,3 +1600,17 @@ "settings_sending_media" = "画像と動画の送信"; "invite_friends_share_text" = "%@ での連絡先: %@"; "side_menu_action_invite_friends" = "招待する"; +"call_more_actions_change_audio_device" = "オーディオデバイスを変更"; +"call_more_actions_dialpad" = "ダイヤルパッド"; +"onboarding_splash_login_button_title" = "既にアカウントを持っています"; + +// Onboarding +"onboarding_splash_register_button_title" = "アカウントを作成"; +"notice_room_created_by_you_for_dm" = "参加しました"; +"notice_room_created_for_dm" = "%@が参加しました"; +"onboarding_use_case_existing_server_button" = "サーバーに接続"; +"callbar_only_single_active_group" = "タップしてグループ通話に参加 (%@)"; +"settings_confirm_media_size" = "送信時のサイズ確認"; +"settings_confirm_media_size_description" = "この機能をオンにすると、画像や動画をどのサイズで送信するか確認する画面が表示されます。"; +"settings_contacts_enable_sync_description" = "IDサーバーを使用して連絡先を探すと同時に、連絡先があなたを探せるようにします。"; +"home_syncing" = "同期中"; diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index 92f52bca6..7ca1ea2d9 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -2107,3 +2107,5 @@ "home_syncing" = "Sincando"; "room_participants_leave_success" = "Saiu de sala"; "room_participants_leave_processing" = "Saindo"; +"notice_error_unformattable_event" = "** Incapaz de render mensagem. Por favor reporte um bug"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Mostrar avatar e nomes mais recentes para usuárias(os) em histórico de mensagem"; diff --git a/Riot/Assets/sk.lproj/Vector.strings b/Riot/Assets/sk.lproj/Vector.strings index 0d9b39df7..1c27c3981 100644 --- a/Riot/Assets/sk.lproj/Vector.strings +++ b/Riot/Assets/sk.lproj/Vector.strings @@ -490,7 +490,7 @@ "unknown_devices_verify" = "Overiť…"; "media_type_accessibility_sticker" = "Nálepka"; "media_type_accessibility_file" = "Súbor"; -"media_type_accessibility_location" = "Miesto"; +"media_type_accessibility_location" = "Poloha"; "media_type_accessibility_video" = "Video"; "media_type_accessibility_audio" = "Audio"; "media_type_accessibility_image" = "Obrázok"; @@ -644,7 +644,7 @@ "room_details_low_priority_tag" = "Nízka priorita"; "room_details_room_name" = "Názov miestnosti"; "room_details_photo" = "Obrázok miestnosti"; -"room_details_search" = "Hľadať miestnosť"; +"room_details_search" = "Prehľadať miestnosť"; "identity_server_settings_alert_disconnect_still_sharing_3pid_button" = "Napriek tomu sa odpojiť"; // Identity server settings @@ -1680,7 +1680,7 @@ "poll_edit_form_poll_type" = "Typ ankety"; "poll_edit_form_update_failure_title" = "Nepodarilo sa aktualizovať anketu"; "poll_edit_form_update_failure_subtitle" = "Prosím, skúste to znova"; -"poll_edit_form_poll_type_open" = "Otvoriť anketu"; +"poll_edit_form_poll_type_open" = "Otvorená anketa"; "poll_edit_form_poll_type_open_description" = "Hlasujúci uvidia výsledky hneď po hlasovaní"; "poll_edit_form_poll_type_closed_description" = "Výsledky sa zobrazia až po ukončení ankety"; "poll_timeline_total_votes_not_voted" = "%lu odovzdaných hlasov. Hlasujte a pozrite si výsledky"; @@ -2320,3 +2320,13 @@ "notice_event_redacted_by_you" = " vami"; "home_syncing" = "Synchronizácia"; "room_participants_leave_success" = "Opustil miestnosť"; +"notice_error_unformattable_event" = "** Správa sa nedá zobraziť. Prosím, nahláste chybu"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Zobraziť posledný obrázok a meno používateľov v histórii správ"; +"room_participants_ago" = "pred"; +"notice_location_attachment" = "umiestnenie prílohy"; +"room_details_fail_to_update_room_direct" = "Nepodarilo sa aktualizovať priamy príznak tejto miestnosti"; +"room_details_flair_section" = "Zobraziť štýl pre komunity"; +"settings_flair" = "Zobraziť štýl, kde je to povolené"; +"room_participants_leave_processing" = "Opustenie"; +"joined" = "Sa pripojil/a"; +"callbar_return" = "Späť"; diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings index 9c2024b3d..509287f56 100644 --- a/Riot/Assets/sq.lproj/Vector.strings +++ b/Riot/Assets/sq.lproj/Vector.strings @@ -2124,3 +2124,7 @@ "attachment_unsupported_preview_title" = "S’arrihet të bëhet paraparje"; "room_displayname_all_other_members_left" = "%@ (Iku)"; "message_reply_to_sender_sent_their_location" = "ka dhënë vendndodhjen e vet."; +"room_participants_leave_processing" = "Dalje"; +"notice_error_unformattable_event" = "** S’arrihet të riprodhohet mesazhi. Ju lutemi, njoftoni një të metë"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Shfaq në historik mesazhesh avatarin dhe emrin më të ri të përdoruesve"; +"room_participants_leave_success" = "Doli nga dhoma"; diff --git a/Riot/Assets/sv.lproj/Vector.strings b/Riot/Assets/sv.lproj/Vector.strings index 0875e55cd..bfb2bf910 100644 --- a/Riot/Assets/sv.lproj/Vector.strings +++ b/Riot/Assets/sv.lproj/Vector.strings @@ -2068,3 +2068,8 @@ "attachment_unsupported_preview_title" = "Kunde inte förhandsgranska"; "room_displayname_all_other_members_left" = "%@ (Kvar)"; "message_reply_to_sender_sent_their_location" = "har delat sin plats."; +"notice_error_unformattable_event" = "** Kunde inte rendera meddelande. Vänligen rapportera en bugg"; +"home_syncing" = "Synkar"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Visa senaste avatar och namn för användare i meddelandehistoriken"; +"room_participants_leave_success" = "Lämnade rummet"; +"room_participants_leave_processing" = "Lämnar"; diff --git a/Riot/Assets/uk.lproj/Vector.strings b/Riot/Assets/uk.lproj/Vector.strings index dc6711737..c3b7f33a4 100644 --- a/Riot/Assets/uk.lproj/Vector.strings +++ b/Riot/Assets/uk.lproj/Vector.strings @@ -2330,3 +2330,5 @@ "home_syncing" = "Синхронізація"; "room_participants_leave_success" = "Вихід успішний"; "room_participants_leave_processing" = "Вихід триває"; +"notice_error_unformattable_event" = "** Неможливо показати повідомлення. Надішліть звіт про помилку"; +"settings_labs_use_only_latest_user_avatar_and_name" = "Показувати останній аватар та ім'я для користувачів у історії повідомлень"; diff --git a/Riot/Categories/Bundle.swift b/Riot/Categories/Bundle.swift index 5b3430154..458469742 100644 --- a/Riot/Categories/Bundle.swift +++ b/Riot/Categories/Bundle.swift @@ -19,7 +19,7 @@ import Foundation public extension Bundle { /// Returns the real app bundle. /// Can also be used in app extensions. - static var app: Bundle { + @objc static var app: Bundle { let bundle = main if bundle.bundleURL.pathExtension == "appex" { // Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex @@ -31,6 +31,14 @@ public extension Bundle { return bundle } + /// Get an lproj language bundle from the main app bundle. + /// - Parameter language: The language to try to load. + /// - Returns: The lproj bundle if found otherwise `nil`. + @objc static func lprojBundle(for language: String) -> Bundle? { + guard let lprojURL = Bundle.app.url(forResource: language, withExtension: "lproj") else { return nil } + return Bundle(url: lprojURL) + } + /// Whether or not the bundle is the RiotShareExtension. var isShareExtension: Bool { bundleURL.lastPathComponent.contains("RiotShareExtension.appex") diff --git a/Riot/Categories/NSAttributedString.swift b/Riot/Categories/NSAttributedString.swift new file mode 100644 index 000000000..65c2db8a7 --- /dev/null +++ b/Riot/Categories/NSAttributedString.swift @@ -0,0 +1,27 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +public extension NSAttributedString { + + /// Returns a new attributed string by removing all links from the receiver. + @objc var vc_byRemovingLinks: NSAttributedString { + let result = NSMutableAttributedString(attributedString: self) + result.removeAttribute(.link, range: NSRange(location: 0, length: length)) + return result + } +} diff --git a/Riot/Generated/Images.swift b/Riot/Generated/Images.swift index 0863cd042..d9c9dadb8 100644 --- a/Riot/Generated/Images.swift +++ b/Riot/Generated/Images.swift @@ -116,18 +116,18 @@ internal class Asset: NSObject { internal static let cameraStop = ImageAsset(name: "camera_stop") internal static let cameraVideoCapture = ImageAsset(name: "camera_video_capture") internal static let videoIcon = ImageAsset(name: "video_icon") - internal static let onboardingSplashScreenPage1 = ImageAsset(name: "OnboardingSplashScreenPage1") - internal static let onboardingSplashScreenPage1Dark = ImageAsset(name: "OnboardingSplashScreenPage1Dark") - internal static let onboardingSplashScreenPage2 = ImageAsset(name: "OnboardingSplashScreenPage2") - internal static let onboardingSplashScreenPage2Dark = ImageAsset(name: "OnboardingSplashScreenPage2Dark") - internal static let onboardingSplashScreenPage3 = ImageAsset(name: "OnboardingSplashScreenPage3") - internal static let onboardingSplashScreenPage3Dark = ImageAsset(name: "OnboardingSplashScreenPage3Dark") - internal static let onboardingSplashScreenPage4 = ImageAsset(name: "OnboardingSplashScreenPage4") - internal static let onboardingSplashScreenPage4Dark = ImageAsset(name: "OnboardingSplashScreenPage4Dark") internal static let onboardingAvatarCamera = ImageAsset(name: "onboarding_avatar_camera") internal static let onboardingAvatarEdit = ImageAsset(name: "onboarding_avatar_edit") internal static let onboardingCelebrationIcon = ImageAsset(name: "onboarding_celebration_icon") internal static let onboardingCongratulationsIcon = ImageAsset(name: "onboarding_congratulations_icon") + internal static let onboardingSplashScreenPage1 = ImageAsset(name: "onboarding_splash_screen_page_1") + internal static let onboardingSplashScreenPage1Dark = ImageAsset(name: "onboarding_splash_screen_page_1_dark") + internal static let onboardingSplashScreenPage2 = ImageAsset(name: "onboarding_splash_screen_page_2") + internal static let onboardingSplashScreenPage2Dark = ImageAsset(name: "onboarding_splash_screen_page_2_dark") + internal static let onboardingSplashScreenPage3 = ImageAsset(name: "onboarding_splash_screen_page_3") + internal static let onboardingSplashScreenPage3Dark = ImageAsset(name: "onboarding_splash_screen_page_3_dark") + internal static let onboardingSplashScreenPage4 = ImageAsset(name: "onboarding_splash_screen_page_4") + internal static let onboardingSplashScreenPage4Dark = ImageAsset(name: "onboarding_splash_screen_page_4_dark") internal static let onboardingUseCaseCommunity = ImageAsset(name: "onboarding_use_case_community") internal static let onboardingUseCaseCommunityDark = ImageAsset(name: "onboarding_use_case_community_dark") internal static let onboardingUseCaseIcon = ImageAsset(name: "onboarding_use_case_icon") @@ -173,6 +173,7 @@ internal class Asset: NSObject { internal static let voiceCallHangonIcon = ImageAsset(name: "voice_call_hangon_icon") internal static let voiceCallHangupIcon = ImageAsset(name: "voice_call_hangup_icon") internal static let liveLocationIcon = ImageAsset(name: "live_location_icon") + internal static let locationCenterMapIcon = ImageAsset(name: "location_center_map_icon") internal static let locationLiveIcon = ImageAsset(name: "location_live_icon") internal static let locationMarkerIcon = ImageAsset(name: "location_marker_icon") internal static let locationPinIcon = ImageAsset(name: "location_pin_icon") diff --git a/Riot/Generated/Storyboards.swift b/Riot/Generated/Storyboards.swift index ac4781afb..84fa5c1d6 100644 --- a/Riot/Generated/Storyboards.swift +++ b/Riot/Generated/Storyboards.swift @@ -162,6 +162,11 @@ internal enum StoryboardScene { internal static let initialScene = InitialSceneType(storyboard: ReactionHistoryViewController.self) } + internal enum RoomContextPreviewViewController: StoryboardType { + internal static let storyboardName = "RoomContextPreviewViewController" + + internal static let initialScene = InitialSceneType(storyboard: RoomContextPreviewViewController.self) + } internal enum RoomContextualMenuViewController: StoryboardType { internal static let storyboardName = "RoomContextualMenuViewController" @@ -279,11 +284,6 @@ internal enum StoryboardScene { internal static let initialScene = InitialSceneType(storyboard: SpaceMenuViewController.self) } - internal enum SpaceRoomPreviewViewController: StoryboardType { - internal static let storyboardName = "SpaceRoomPreviewViewController" - - internal static let initialScene = InitialSceneType(storyboard: SpaceRoomPreviewViewController.self) - } internal enum TemplateScreenViewController: StoryboardType { internal static let storyboardName = "TemplateScreenViewController" @@ -294,6 +294,11 @@ internal enum StoryboardScene { internal static let initialScene = InitialSceneType(storyboard: ThreadListViewController.self) } + internal enum ThreadsBetaViewController: StoryboardType { + internal static let storyboardName = "ThreadsBetaViewController" + + internal static let initialScene = InitialSceneType(storyboard: ThreadsBetaViewController.self) + } internal enum ThreadsNoticeViewController: StoryboardType { internal static let storyboardName = "ThreadsNoticeViewController" diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index d599c8296..34b6299d6 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -3775,6 +3775,74 @@ public class VectorL10n: NSObject { public static var on: String { return VectorL10n.tr("Vector", "on") } + /// Profile picture + public static var onboardingAvatarAccessibilityLabel: String { + return VectorL10n.tr("Vector", "onboarding_avatar_accessibility_label") + } + /// You can change this anytime. + public static var onboardingAvatarMessage: String { + return VectorL10n.tr("Vector", "onboarding_avatar_message") + } + /// Add a profile picture + public static var onboardingAvatarTitle: String { + return VectorL10n.tr("Vector", "onboarding_avatar_title") + } + /// Let's go + public static var onboardingCelebrationButton: String { + return VectorL10n.tr("Vector", "onboarding_celebration_button") + } + /// Your preferences have been saved. + public static var onboardingCelebrationMessage: String { + return VectorL10n.tr("Vector", "onboarding_celebration_message") + } + /// You’re all set! + public static var onboardingCelebrationTitle: String { + return VectorL10n.tr("Vector", "onboarding_celebration_title") + } + /// Take me home + public static var onboardingCongratulationsHomeButton: String { + return VectorL10n.tr("Vector", "onboarding_congratulations_home_button") + } + /// Your account %@ has been created. + public static func onboardingCongratulationsMessage(_ p1: String) -> String { + return VectorL10n.tr("Vector", "onboarding_congratulations_message", p1) + } + /// Personalise profile + public static var onboardingCongratulationsPersonalizeButton: String { + return VectorL10n.tr("Vector", "onboarding_congratulations_personalize_button") + } + /// Congratulations! + public static var onboardingCongratulationsTitle: String { + return VectorL10n.tr("Vector", "onboarding_congratulations_title") + } + /// You can change this later + public static var onboardingDisplayNameHint: String { + return VectorL10n.tr("Vector", "onboarding_display_name_hint") + } + /// Your display name must be less than 256 characters + public static var onboardingDisplayNameMaxLength: String { + return VectorL10n.tr("Vector", "onboarding_display_name_max_length") + } + /// This will be shown when you send messages. + public static var onboardingDisplayNameMessage: String { + return VectorL10n.tr("Vector", "onboarding_display_name_message") + } + /// Display Name + public static var onboardingDisplayNamePlaceholder: String { + return VectorL10n.tr("Vector", "onboarding_display_name_placeholder") + } + /// Choose a display name + public static var onboardingDisplayNameTitle: String { + return VectorL10n.tr("Vector", "onboarding_display_name_title") + } + /// Save and continue + public static var onboardingPersonalizationSave: String { + return VectorL10n.tr("Vector", "onboarding_personalization_save") + } + /// Skip this step + public static var onboardingPersonalizationSkip: String { + return VectorL10n.tr("Vector", "onboarding_personalization_skip") + } /// I already have an account public static var onboardingSplashLoginButtonTitle: String { return VectorL10n.tr("Vector", "onboarding_splash_login_button_title") @@ -7591,6 +7659,26 @@ public class VectorL10n: NSObject { public static var threadsActionMyThreads: String { return VectorL10n.tr("Vector", "threads_action_my_threads") } + /// Not now + public static var threadsBetaCancel: String { + return VectorL10n.tr("Vector", "threads_beta_cancel") + } + /// Try it out + public static var threadsBetaEnable: String { + return VectorL10n.tr("Vector", "threads_beta_enable") + } + /// Keep discussions organised with threads.\n\nThreads help keep your conversations on-topic and easy to track. + public static var threadsBetaInformation: String { + return VectorL10n.tr("Vector", "threads_beta_information") + } + /// Learn more + public static var threadsBetaInformationLink: String { + return VectorL10n.tr("Vector", "threads_beta_information_link") + } + /// Threads + public static var threadsBetaTitle: String { + return VectorL10n.tr("Vector", "threads_beta_title") + } /// Threads help keep your conversations on-topic and easy to track. public static var threadsEmptyInfoAll: String { return VectorL10n.tr("Vector", "threads_empty_info_all") @@ -7986,7 +8074,7 @@ public class VectorL10n: NSObject { extension VectorL10n { static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "") + let format = NSLocalizedString(key, tableName: table, bundle: Bundle.app, comment: "") let locale: Locale if let providedLocale = LocaleProvider.locale { locale = providedLocale @@ -7998,4 +8086,3 @@ extension VectorL10n { } } -private final class BundleToken {} diff --git a/Riot/Generated/UntranslatedStrings.swift b/Riot/Generated/UntranslatedStrings.swift index bd89722e0..b44654fd3 100644 --- a/Riot/Generated/UntranslatedStrings.swift +++ b/Riot/Generated/UntranslatedStrings.swift @@ -14,74 +14,6 @@ public extension VectorL10n { static var imagePickerActionFiles: String { return VectorL10n.tr("Untranslated", "image_picker_action_files") } - /// Profile picture - static var onboardingAvatarAccessibilityLabel: String { - return VectorL10n.tr("Untranslated", "onboarding_avatar_accessibility_label") - } - /// You can change this anytime. - static var onboardingAvatarMessage: String { - return VectorL10n.tr("Untranslated", "onboarding_avatar_message") - } - /// Add a profile picture - static var onboardingAvatarTitle: String { - return VectorL10n.tr("Untranslated", "onboarding_avatar_title") - } - /// Let's go - static var onboardingCelebrationButton: String { - return VectorL10n.tr("Untranslated", "onboarding_celebration_button") - } - /// Your preferences have been saved. - static var onboardingCelebrationMessage: String { - return VectorL10n.tr("Untranslated", "onboarding_celebration_message") - } - /// You’re all set! - static var onboardingCelebrationTitle: String { - return VectorL10n.tr("Untranslated", "onboarding_celebration_title") - } - /// Take me home - static var onboardingCongratulationsHomeButton: String { - return VectorL10n.tr("Untranslated", "onboarding_congratulations_home_button") - } - /// Your account %@ has been created. - static func onboardingCongratulationsMessage(_ p1: String) -> String { - return VectorL10n.tr("Untranslated", "onboarding_congratulations_message", p1) - } - /// Personalise profile - static var onboardingCongratulationsPersonalizeButton: String { - return VectorL10n.tr("Untranslated", "onboarding_congratulations_personalize_button") - } - /// Congratulations! - static var onboardingCongratulationsTitle: String { - return VectorL10n.tr("Untranslated", "onboarding_congratulations_title") - } - /// You can change this later - static var onboardingDisplayNameHint: String { - return VectorL10n.tr("Untranslated", "onboarding_display_name_hint") - } - /// Your display name must be less than 256 characters - static var onboardingDisplayNameMaxLength: String { - return VectorL10n.tr("Untranslated", "onboarding_display_name_max_length") - } - /// This will be shown when you send messages. - static var onboardingDisplayNameMessage: String { - return VectorL10n.tr("Untranslated", "onboarding_display_name_message") - } - /// Display Name - static var onboardingDisplayNamePlaceholder: String { - return VectorL10n.tr("Untranslated", "onboarding_display_name_placeholder") - } - /// Choose a display name - static var onboardingDisplayNameTitle: String { - return VectorL10n.tr("Untranslated", "onboarding_display_name_title") - } - /// Save and continue - static var onboardingPersonalizationSave: String { - return VectorL10n.tr("Untranslated", "onboarding_personalization_save") - } - /// Skip this step - static var onboardingPersonalizationSkip: String { - return VectorL10n.tr("Untranslated", "onboarding_personalization_skip") - } /// This feature isn't available here. For now, you can do this with %@ on your computer. static func spacesFeatureNotAvailable(_ p1: String) -> String { return VectorL10n.tr("Untranslated", "spaces_feature_not_available", p1) diff --git a/Riot/Modules/Authentication/AuthenticationViewController.m b/Riot/Modules/Authentication/AuthenticationViewController.m index c8c95e2dd..ff5c06ca8 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/AuthenticationViewController.m @@ -1214,25 +1214,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0; [self.identityServerTextField resignFirstResponder]; // Report server url typed by the user as custom url. - NSString *homeServerURL = self.homeServerTextField.text; - if (homeServerURL.length && ![homeServerURL isEqualToString:self.defaultHomeServerUrl]) - { - [[NSUserDefaults standardUserDefaults] setObject:homeServerURL forKey:@"customHomeServerURL"]; - } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"customHomeServerURL"]; - } - - NSString *identityServerURL = self.identityServerTextField.text; - if (identityServerURL.length && ![identityServerURL isEqualToString:self.defaultIdentityServerUrl]) - { - [[NSUserDefaults standardUserDefaults] setObject:identityServerURL forKey:@"customIdentityServerURL"]; - } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"customIdentityServerURL"]; - } + [self saveCustomServerInputs]; // Restore default configuration [self setHomeServerTextFieldText:self.defaultHomeServerUrl]; @@ -1275,6 +1257,29 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0; } } +- (void)saveCustomServerInputs +{ + NSString *homeServerURL = self.homeServerTextField.text; + if (homeServerURL.length && ![homeServerURL isEqualToString:self.defaultHomeServerUrl]) + { + [[NSUserDefaults standardUserDefaults] setObject:homeServerURL forKey:@"customHomeServerURL"]; + } + else + { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"customHomeServerURL"]; + } + + NSString *identityServerURL = self.identityServerTextField.text; + if (identityServerURL.length && ![identityServerURL isEqualToString:self.defaultIdentityServerUrl]) + { + [[NSUserDefaults standardUserDefaults] setObject:identityServerURL forKey:@"customIdentityServerURL"]; + } + else + { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"customIdentityServerURL"]; + } +} + - (void)showResourceLimitExceededError:(NSDictionary *)errorDict { MXLogDebug(@"[AuthenticationVC] showResourceLimitExceededError"); @@ -1325,8 +1330,11 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0; self.userInteractionEnabled = NO; [self.authenticationActivityIndicator startAnimating]; - // Hide the custom server details in order to save customized inputs - [self setCustomServerFieldsVisible:NO]; + // Save customized server inputs if used + if (!self.customServersContainer.isHidden) + { + [self saveCustomServerInputs]; + } MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:userId]; MXSession *session = account.mxSession; diff --git a/Riot/Modules/Common/PresenceIndicator/PresenceIndicatorView.swift b/Riot/Modules/Common/PresenceIndicator/PresenceIndicatorView.swift new file mode 100644 index 000000000..2380368eb --- /dev/null +++ b/Riot/Modules/Common/PresenceIndicator/PresenceIndicatorView.swift @@ -0,0 +1,98 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +/// `PresenceIndicatorView` is used to display a presence indicator over an avatar. +@objcMembers +@IBDesignable +final class PresenceIndicatorView: UIView { + // MARK: - Internal Properties + @IBInspectable var borderWidth: CGFloat = 0.0 + var borderColor: UIColor = ThemeService.shared().theme.backgroundColor + + // MARK: - Private Properties + private let borderLayer = CALayer() + + // MARK: - Private Constants + private enum Constants { + static let borderLayerOffset: CGFloat = 1.0 + } + + // MARK: - Init + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setup() + } + + // MARK: - Override + override func layoutSubviews() { + super.layoutSubviews() + + // This sets up a slightly larger border layer to avoid common iOS + // issue of having a very thin but noticeable additional border of + // backgroundColor when using corner radius + borderWidth. + self.layer.cornerRadius = self.frame.width / 2.0 + self.borderLayer.borderWidth = self.borderWidth + Constants.borderLayerOffset + self.borderLayer.cornerRadius = self.layer.cornerRadius + Constants.borderLayerOffset + self.borderLayer.frame = self.frame.withOffset(Constants.borderLayerOffset) + } + + // MARK: - Internal Methods + /// Updates presence indicator with given `MXPresence`. + /// + /// - Parameters: + /// - presence: `MXPresence` to display + func setPresence(_ presence: MXPresence) { + switch presence { + case MXPresenceOnline: + self.backgroundColor = ThemeService.shared().theme.tintColor + self.borderLayer.borderColor = self.borderColor.cgColor + case MXPresenceOffline, MXPresenceUnavailable: + self.backgroundColor = ThemeService.shared().theme.tabBarUnselectedItemTintColor + self.borderLayer.borderColor = self.borderColor.cgColor + default: + self.backgroundColor = UIColor.clear + self.borderLayer.borderColor = UIColor.clear.cgColor + } + } +} + +// MARK: - Private Methods +private extension PresenceIndicatorView { + func setup() { + self.layer.addSublayer(borderLayer) + } +} + +// MARK: - CGRect Helper +private extension CGRect { + /// Returns a `CGRect` with given offset on each side. + /// + /// - Parameters: + /// - offset: offset to apply + /// - Returns: `CGRect` with given offset + func withOffset(_ offset: CGFloat) -> CGRect { + return CGRect(x: -offset, y: -offset, + width: self.width + 2.0 * offset, + height: self.height + 2.0 * offset) + } +} diff --git a/Riot/Modules/Common/Recents/RecentsViewController.h b/Riot/Modules/Common/Recents/RecentsViewController.h index a2fefb47d..09a9ee572 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.h +++ b/Riot/Modules/Common/Recents/RecentsViewController.h @@ -20,6 +20,7 @@ @class RootTabEmptyView; @class AnalyticsScreenTracker; @class UserIndicatorStore; +@class RecentCellContextMenuProvider; /** Notification to be posted when recents data is ready. Notification object will be the RecentsViewController instance. @@ -103,6 +104,8 @@ FOUNDATION_EXPORT NSString *const RecentsViewControllerDataReadyNotification; */ @property (nonatomic, strong) UserIndicatorStore *userIndicatorStore; +@property (nonatomic, readonly) RecentCellContextMenuProvider *contextMenuProvider; + /** Return the sticky header for the specified section of the table view @@ -198,6 +201,11 @@ Enable/disable the notifications for the selected room. */ - (void)openPublicRoom:(MXPublicRoom *)publicRoom; +/** + Show a room using its roomID + */ +- (void)showRoomWithRoomId:(NSString*)roomId inMatrixSession:(MXSession*)matrixSession; + #pragma mark - Scrolling /** diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index ea12f0516..59a7c6084 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -36,7 +36,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewControllerDataReadyNotification"; -@interface RecentsViewController () +@interface RecentsViewController () { // Tell whether a recents refresh is pending (suspended during editing mode). BOOL isRefreshPending; @@ -138,6 +138,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro displayedSectionHeaders = [NSMutableArray array]; + _contextMenuProvider = [RecentCellContextMenuProvider new]; + self.contextMenuProvider.serviceDelegate = self; + // Set itself as delegate by default. self.delegate = self; } @@ -363,6 +366,14 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro - (void)refreshRecentsTable { + if (!self.recentsUpdateEnabled) + { + isRefreshNeeded = NO; + return; + } + + isRefreshNeeded = NO; + // Refresh the tabBar icon badges [[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges]; @@ -1031,6 +1042,12 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro - (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes { + if (!self.recentsUpdateEnabled) + { + [super dataSource:dataSource didCellChange:changes]; + return; + } + BOOL cellReloaded = NO; if ([changes isKindOfClass:RecentsSectionUpdate.class]) { @@ -2487,4 +2504,78 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro } } +#pragma mark - Context Menu + +- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) +{ + id cellData = [self.dataSource cellDataAtIndexPath:indexPath]; + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + + if (!cellData || !cell) + { + return nil; + } + + self.recentsUpdateEnabled = NO; + return [self.contextMenuProvider contextMenuConfigurationWith:cellData from:cell session:self.dataSource.mxSession]; +} + +- (void)tableView:(UITableView *)tableView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)) +{ + NSString *roomId = [self.contextMenuProvider roomIdFrom:configuration.identifier]; + + if (!roomId) + { + self.recentsUpdateEnabled = YES; + return; + } + + [animator addCompletion:^{ + self.recentsUpdateEnabled = YES; + [self showRoomWithRoomId:roomId inMatrixSession:self.mainSession]; + }]; +} + +- (UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) +{ + self.recentsUpdateEnabled = YES; + return nil; +} + +#pragma mark - RoomContextActionServiceDelegate + +- (void)roomContextActionServiceDidJoinRoom:(id)service +{ + [self showRoomWithRoomId:service.roomId inMatrixSession:service.session]; +} + +- (void)roomContextActionServiceDidLeaveRoom:(id)service +{ + [self.userIndicatorStore presentSuccessWithLabel:VectorL10n.roomParticipantsLeaveSuccess]; +} + +- (void)roomContextActionService:(id)service presentAlert:(UIAlertController *)alertController +{ + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)roomContextActionService:(id)service updateActivityIndicator:(BOOL)isActive +{ + if (isActive) + { + [self startActivityIndicator]; + } + else if ([self canStopActivityIndicator]) + { + [self stopActivityIndicator]; + } +} + +- (void)roomContextActionService:(id)service showRoomNotificationSettingsForRoomWithId:(NSString *)roomId +{ + editedRoomId = roomId; + [self changeEditedRoomNotificationSettings]; + editedRoomId = nil; +} + @end diff --git a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.h b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.h index 347a92f76..ee4489402 100644 --- a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.h +++ b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.h @@ -16,6 +16,8 @@ #import "MatrixKit.h" +@class PresenceIndicatorView; + /** `RecentTableViewCell` instances display a room in the context of the recents list. */ @@ -24,6 +26,7 @@ @property (weak, nonatomic) IBOutlet UIView *missedNotifAndUnreadIndicator; @property (weak, nonatomic) IBOutlet MXKImageView *roomAvatar; @property (weak, nonatomic) IBOutlet UIImageView *encryptedRoomIcon; +@property (weak, nonatomic) IBOutlet PresenceIndicatorView *presenceIndicatorView; @property (weak, nonatomic) IBOutlet UILabel *missedNotifAndUnreadBadgeLabel; @property (weak, nonatomic) IBOutlet UIView *missedNotifAndUnreadBadgeBgView; diff --git a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m index 6b2df4055..4ab4b68bc 100644 --- a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m +++ b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m @@ -128,6 +128,11 @@ roomId:roomCellData.roomIdentifier displayName:roomCellData.roomDisplayname mediaManager:roomCellData.mxSession.mediaManager]; + + // Presence indicator + self.presenceIndicatorView.borderColor = ThemeService.shared.theme.backgroundColor; + self.presenceIndicatorView.presence = roomCellData.presence; + self.presenceIndicatorView.hidden = roomCellData.presence == MXPresenceUnknown; } else { diff --git a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.xib b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.xib index dec130d7d..f0718884a 100644 --- a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.xib +++ b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.xib @@ -1,9 +1,9 @@ - + - + @@ -98,9 +98,24 @@ + + + @@ -120,7 +135,7 @@ - + @@ -131,6 +146,7 @@ + diff --git a/Riot/Modules/Common/SwiftUI/VectorHostingController.swift b/Riot/Modules/Common/SwiftUI/VectorHostingController.swift index c79762b89..97e5ca5d3 100644 --- a/Riot/Modules/Common/SwiftUI/VectorHostingController.swift +++ b/Riot/Modules/Common/SwiftUI/VectorHostingController.swift @@ -32,7 +32,14 @@ class VectorHostingController: UIHostingController { // MARK: Public + /// Whether or not to use the iOS 15 style scroll edge appearance when the controller has a navigation bar. var enableNavigationBarScrollEdgeAppearance = false + /// When non-nil, the style will be applied to the status bar. + var statusBarStyle: UIStatusBarStyle? + + override var preferredStatusBarStyle: UIStatusBarStyle { + statusBarStyle ?? super.preferredStatusBarStyle + } init(rootView: Content) where Content: View { self.theme = ThemeService.shared().theme diff --git a/Riot/Modules/Contacts/Views/ContactTableViewCell.m b/Riot/Modules/Contacts/Views/ContactTableViewCell.m index a1c3b12a2..423445cb9 100644 --- a/Riot/Modules/Contacts/Views/ContactTableViewCell.m +++ b/Riot/Modules/Contacts/Views/ContactTableViewCell.m @@ -150,7 +150,9 @@ if (contact.isMatrixContact) { // Observe contact presence change + MXWeakify(self); mxPresenceObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKContactManagerMatrixUserPresenceChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); NSString* matrixId = self.firstMatrixId; diff --git a/Riot/Modules/ContextMenu/ActionProviders/PublicRoomActionProvider.swift b/Riot/Modules/ContextMenu/ActionProviders/PublicRoomActionProvider.swift new file mode 100644 index 000000000..c2d340797 --- /dev/null +++ b/Riot/Modules/ContextMenu/ActionProviders/PublicRoomActionProvider.swift @@ -0,0 +1,51 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `PublicRoomActionProvider` provides the menu for `MXPUblicRoom` instances +@available(iOS 13.0, *) +class PublicRoomActionProvider: RoomActionProviderProtocol { + + // MARK: - Properties + + private let publicRoom: MXPublicRoom + private let service: UnownedRoomContextActionService + + // MARK: - Setup + + init(publicRoom: MXPublicRoom, service: UnownedRoomContextActionService) { + self.publicRoom = publicRoom + self.service = service + } + + // MARK: - RoomActionProviderProtocol + + var menu: UIMenu { + return UIMenu(children: [ + self.joinAction + ]) + } + + // MARK: - Private + + private var joinAction: UIAction { + return UIAction( + title: VectorL10n.join) { [weak self] action in + self?.service.joinRoom() + } + } +} diff --git a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift new file mode 100644 index 000000000..12346a193 --- /dev/null +++ b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift @@ -0,0 +1,147 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +/// `RoomActionProvider` provides the menu for `MXRoom` instances +@available(iOS 13.0, *) +class RoomActionProvider: RoomActionProviderProtocol { + + // MARK: - Properties + + private let service: RoomContextActionService + + // MARK: - Setup + + init(service: RoomContextActionService) { + self.service = service + } + + // MARK: - RoomActionProviderProtocol + + var menu: UIMenu { + if service.isRoomJoined { + return UIMenu(children: [ + self.directChatAction, + self.notificationsAction, + self.favouriteAction, + self.lowPriorityAction, + self.leaveAction + ]) + } else { + if service.roomMembership == .invite { + return UIMenu(children: [ + self.acceptInviteAction, + self.declineInviteAction + ]) + } else { + return UIMenu(children: [ + self.joinAction + ]) + } + } + } + + // MARK: - Private + + private var directChatAction: UIAction { + return UIAction( + title: service.isRoomDirect ? VectorL10n.homeContextMenuMakeRoom : VectorL10n.homeContextMenuMakeDm, + image: UIImage(systemName: service.isRoomDirect ? "person.crop.circle.badge.xmark" : "person.circle")) { [weak self] action in + guard let self = self else { return } + self.service.isRoomDirect = !self.service.isRoomDirect + } + } + + private var notificationsAction: UIAction { + let notificationsImage: UIImage? + let notificationsTitle: String + if BuildSettings.showNotificationsV2 { + notificationsTitle = VectorL10n.homeContextMenuNotifications + notificationsImage = UIImage(systemName: "bell") + } else { + notificationsTitle = service.isRoomMuted ? VectorL10n.homeContextMenuUnmute : VectorL10n.homeContextMenuMute + notificationsImage = UIImage(systemName: service.isRoomMuted ? "bell.slash": "bell") + } + + return UIAction( + title: notificationsTitle, + image: notificationsImage) { [weak self] action in + guard let self = self else { return } + self.service.isRoomMuted = !self.service.isRoomMuted + } + } + + private var favouriteAction: UIAction { + return UIAction( + title: self.service.isRoomFavourite ? VectorL10n.homeContextMenuUnfavourite : VectorL10n.homeContextMenuFavourite, + image: UIImage(systemName: self.service.isRoomFavourite ? "star.slash" : "star")) { [weak self] action in + guard let self = self else { return } + self.service.isRoomFavourite = !self.service.isRoomFavourite + } + } + + private var lowPriorityAction: UIAction { + return UIAction( + title: self.service.isRoomLowPriority ? VectorL10n.homeContextMenuNormalPriority : VectorL10n.homeContextMenuLowPriority, + image: UIImage(systemName: self.service.isRoomLowPriority ? "arrow.up" : "arrow.down")) { [weak self] action in + guard let self = self else { return } + self.service.isRoomLowPriority = !self.service.isRoomLowPriority + } + } + + private var leaveAction: UIAction { + let image: UIImage? + if #available(iOS 14.0, *) { + image = UIImage(systemName: "rectangle.righthalf.inset.fill.arrow.right") + } else { + image = UIImage(systemName: "rectangle.xmark") + } + + let action = UIAction(title: VectorL10n.homeContextMenuLeave, image: image) { [weak self] action in + guard let self = self else { return } + self.service.leaveRoom(promptUser: true) + } + action.attributes = .destructive + return action + } + + private var acceptInviteAction: UIAction { + return UIAction( + title: VectorL10n.accept) { [weak self] action in + guard let self = self else { return } + self.service.joinRoom() + } + } + + private var declineInviteAction: UIAction { + let action = UIAction( + title: VectorL10n.decline) { [weak self] action in + guard let self = self else { return } + self.service.leaveRoom(promptUser: false) + } + action.attributes = .destructive + return action + } + + private var joinAction: UIAction { + return UIAction( + title: VectorL10n.join) { [weak self] action in + guard let self = self else { return } + self.service.joinRoom() + } + } +} diff --git a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProviderProtocol.swift b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProviderProtocol.swift new file mode 100644 index 000000000..21d5f6ef3 --- /dev/null +++ b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProviderProtocol.swift @@ -0,0 +1,24 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Classes compliant with the protocol `RoomActionProviderProtocol` are meant to provide the menu within `UIContextMenuActionProvider` +@available(iOS 13.0, *) +protocol RoomActionProviderProtocol { + /// menu instance returned within the `UIContextMenuActionProvider` block + var menu: UIMenu { get } +} diff --git a/Riot/Modules/ContextMenu/ActionProviders/SpaceChildActionProvider.swift b/Riot/Modules/ContextMenu/ActionProviders/SpaceChildActionProvider.swift new file mode 100644 index 000000000..97fd5efb4 --- /dev/null +++ b/Riot/Modules/ContextMenu/ActionProviders/SpaceChildActionProvider.swift @@ -0,0 +1,51 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `SpaceChildActionProvider` provides the menu for `MXSpaceChildInfo` instances +@available(iOS 13.0, *) +class SpaceChildActionProvider: RoomActionProviderProtocol { + + // MARK: - Properties + + private let spaceChildInfo: MXSpaceChildInfo + private let service: UnownedRoomContextActionService + + // MARK: - Setup + + init(spaceChildInfo: MXSpaceChildInfo, service: UnownedRoomContextActionService) { + self.spaceChildInfo = spaceChildInfo + self.service = service + } + + // MARK: - RoomActionProviderProtocol + + var menu: UIMenu { + return UIMenu(children: [ + self.joinAction + ]) + } + + // MARK: - Private + + private var joinAction: UIAction { + return UIAction( + title: VectorL10n.join) { [weak self] action in + self?.service.joinRoom() + } + } +} diff --git a/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift b/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift new file mode 100644 index 000000000..a9a800517 --- /dev/null +++ b/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift @@ -0,0 +1,83 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Helper class `PublicRoomContextMenuProvider` that provides an instace of `UIContextMenuConfiguration` from an instance of `MXPublicRoom` +@objcMembers +class PublicRoomContextMenuProvider: NSObject { + + weak var serviceDelegate: RoomContextActionServiceDelegate? + private var currentService: RoomContextActionServiceProtocol? + + @available(iOS 13.0, *) + func contextMenuConfiguration(with publicRoom: MXPublicRoom, from cell: UIView, session: MXSession) -> UIContextMenuConfiguration? { + if let room = session.room(withRoomId: publicRoom.roomId) { + let service = RoomContextActionService(room: room, delegate: serviceDelegate) + self.currentService = service + let actionProvider = RoomActionProvider(service: service) + return UIContextMenuConfiguration(identifier: publicRoom.jsonString() as? NSString) { + if room.summary?.isJoined == true { + let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) + guard let roomViewController = storyboard.instantiateViewController(withIdentifier: "RoomViewControllerStoryboardId") as? RoomViewController else { + return nil + } + roomViewController.isContextPreview = true + + let roomDataSourceManager = MXKRoomDataSourceManager.sharedManager(forMatrixSession: session) + roomDataSourceManager?.roomDataSource(forRoom: room.roomId, create: true, onComplete: { roomDataSource in + roomViewController.displayRoom(roomDataSource) + }) + + return roomViewController + } else { + let viewModel = RoomContextPreviewViewModel(room: room) + return RoomContextPreviewViewController.instantiate(with: viewModel, mediaManager: session.mediaManager) + } + } actionProvider: { suggestedActions in + return actionProvider.menu + } + } else { + let service = UnownedRoomContextActionService(roomId: publicRoom.roomId, canonicalAlias: publicRoom.canonicalAlias, session: session, delegate: serviceDelegate) + self.currentService = service + let actionProvider = PublicRoomActionProvider(publicRoom: publicRoom, service: service) + return UIContextMenuConfiguration(identifier: publicRoom.jsonString() as? NSString) { + let viewModel = PublicRoomContextPreviewViewModel(publicRoom: publicRoom) + return RoomContextPreviewViewController.instantiate(with: viewModel, mediaManager: session.mediaManager) + } actionProvider: { suggestedActions in + return actionProvider.menu + } + } + } + + func publicRoom(from identifier: NSCopying) -> MXPublicRoom? { + guard let jsonString = identifier as? String, let data = jsonString.data(using: .utf8) else { + return nil + } + + do { + let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + + guard let publicRoom = MXPublicRoom(fromJSON: json) else { + return nil + } + + return publicRoom + } catch { + return nil + } + } +} diff --git a/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift b/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift new file mode 100644 index 000000000..066499ff3 --- /dev/null +++ b/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift @@ -0,0 +1,72 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Helper class `RecentCellContextMenuProvider` that provides an instace of `UIContextMenuConfiguration` from an instance of `MXKRecentCellDataStoring` +@objcMembers +class RecentCellContextMenuProvider: NSObject { + + weak var serviceDelegate: RoomContextActionServiceDelegate? + private var currentService: RoomContextActionServiceProtocol? + + @available(iOS 13.0, *) + func contextMenuConfiguration(with cellData: MXKRecentCellDataStoring, from cell: UIView, session: MXSession) -> UIContextMenuConfiguration? { + if cellData.isSuggestedRoom, let childInfo = cellData.roomSummary.spaceChildInfo { + let service = UnownedRoomContextActionService(roomId: childInfo.childRoomId, canonicalAlias: childInfo.canonicalAlias, session: session, delegate: serviceDelegate) + self.currentService = service + let actionProvider = SpaceChildActionProvider(spaceChildInfo: childInfo, service: service) + return UIContextMenuConfiguration(identifier: "" as NSString) { + let viewModel = SpaceChildContextPreviewViewModel(childInfo: childInfo) + return RoomContextPreviewViewController.instantiate(with: viewModel, mediaManager: session.mediaManager) + } actionProvider: { suggestedActions in + return actionProvider.menu + } + } else if let room = session.room(withRoomId: cellData.roomIdentifier) { + let service = RoomContextActionService(room: room, delegate: serviceDelegate) + self.currentService = service + let actionProvider = RoomActionProvider(service: service) + return UIContextMenuConfiguration(identifier: cellData.roomIdentifier as NSString) { + if room.summary?.isJoined == true { + let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) + guard let roomViewController = storyboard.instantiateViewController(withIdentifier: "RoomViewControllerStoryboardId") as? RoomViewController else { + return nil + } + roomViewController.isContextPreview = true + + let roomDataSourceManager = MXKRoomDataSourceManager.sharedManager(forMatrixSession: session) + roomDataSourceManager?.roomDataSource(forRoom: room.roomId, create: true, onComplete: { roomDataSource in + roomViewController.displayRoom(roomDataSource) + }) + + return roomViewController + } else { + let viewModel = RoomContextPreviewViewModel(room: room) + return RoomContextPreviewViewController.instantiate(with: viewModel, mediaManager: session.mediaManager) + } + } actionProvider: { suggestedActions in + return actionProvider.menu + } + } + + return nil + } + + func roomId(from identifier: NSCopying) -> String? { + let roomId = identifier as? String + return roomId?.isEmpty == true ? nil : roomId + } +} diff --git a/Riot/Modules/ContextMenu/RoomContextPreviewViewController.storyboard b/Riot/Modules/ContextMenu/RoomContextPreviewViewController.storyboard new file mode 100644 index 000000000..d9c7dc7df --- /dev/null +++ b/Riot/Modules/ContextMenu/RoomContextPreviewViewController.storyboard @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoom/SpaceRoomPreviewViewController.swift b/Riot/Modules/ContextMenu/RoomContextPreviewViewController.swift similarity index 51% rename from Riot/Modules/Spaces/SpaceRoomList/ExploreRoom/SpaceRoomPreviewViewController.swift rename to Riot/Modules/ContextMenu/RoomContextPreviewViewController.swift index 57b7af624..7a9f49b57 100644 --- a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoom/SpaceRoomPreviewViewController.swift +++ b/Riot/Modules/ContextMenu/RoomContextPreviewViewController.swift @@ -17,8 +17,10 @@ */ import UIKit +import MatrixSDK -final class SpaceRoomPreviewViewController: UIViewController { +/// `RoomContextPreviewViewController` is used to dsplay room preview data within a `UIContextMenuContentPreviewProvider` +final class RoomContextPreviewViewController: UIViewController { // MARK: - Constants @@ -39,19 +41,25 @@ final class SpaceRoomPreviewViewController: UIViewController { @IBOutlet private weak var topicLabelBottomMargin: NSLayoutConstraint! @IBOutlet private weak var spaceTagView: UIView! @IBOutlet private weak var spaceTagLabel: UILabel! + @IBOutlet private weak var stackView: UIStackView! + @IBOutlet private weak var inviteHeaderView: UIView! + @IBOutlet private weak var inviterAvatarView: UserAvatarView! + @IBOutlet private weak var inviteTitleLabel: UILabel! + @IBOutlet private weak var inviteDetailLabel: UILabel! + @IBOutlet private weak var inviteSeparatorView: UIView! // MARK: Private private var theme: Theme! - private var roomInfo: MXSpaceChildInfo! - private var avatarViewData: AvatarViewDataProtocol! + private var viewModel: RoomContextPreviewViewModelProtocol! + private var mediaManager: MXMediaManager? // MARK: - Setup - class func instantiate(with roomInfo: MXSpaceChildInfo, avatarViewData: AvatarViewDataProtocol!) -> SpaceRoomPreviewViewController { - let viewController = StoryboardScene.SpaceRoomPreviewViewController.initialScene.instantiate() - viewController.roomInfo = roomInfo - viewController.avatarViewData = avatarViewData + class func instantiate(with viewModel: RoomContextPreviewViewModelProtocol, mediaManager: MXMediaManager?) -> RoomContextPreviewViewController { + let viewController = StoryboardScene.RoomContextPreviewViewController.initialScene.instantiate() + viewController.viewModel = viewModel + viewController.mediaManager = mediaManager viewController.theme = ThemeService.shared().theme return viewController } @@ -60,11 +68,14 @@ final class SpaceRoomPreviewViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - + // Do any additional setup after loading the view. + viewModel.viewDelegate = self + setupView() self.registerThemeServiceDidChangeThemeNotification() self.update(theme: self.theme) + self.viewModel.process(viewAction: .loadData) } override var preferredContentSize: CGSize { @@ -105,6 +116,15 @@ final class SpaceRoomPreviewViewController: UIViewController { self.spaceTagView.backgroundColor = theme.colors.quinaryContent self.spaceTagLabel.font = theme.fonts.caption1 self.spaceTagLabel.textColor = theme.colors.tertiaryContent + + self.inviteTitleLabel.textColor = theme.colors.tertiaryContent + self.inviteTitleLabel.font = theme.fonts.calloutSB + + self.inviteDetailLabel.textColor = theme.colors.tertiaryContent + self.inviteDetailLabel.font = theme.fonts.caption1 + + self.inviteSeparatorView.backgroundColor = theme.colors.quinaryContent + self.inviterAvatarView.alpha = 0.7 } private func registerThemeServiceDidChangeThemeNotification() { @@ -115,42 +135,85 @@ final class SpaceRoomPreviewViewController: UIViewController { self.update(theme: ThemeService.shared().theme) } - private func setupView() { - self.titleLabel.text = roomInfo.displayName - - self.spaceTagView.layer.masksToBounds = true - self.spaceTagView.layer.cornerRadius = 2 - self.spaceTagView.isHidden = roomInfo.roomType != .space - self.spaceTagLabel.text = VectorL10n.spaceTag + private func renderLoaded(with parameters: RoomContextPreviewLoadedParameters) { + self.titleLabel.text = parameters.displayName - self.avatarView.isHidden = roomInfo.roomType == .space - self.spaceAvatarView.isHidden = roomInfo.roomType != .space + self.spaceTagView.isHidden = parameters.roomType != .space + self.avatarView.isHidden = parameters.roomType == .space + self.spaceAvatarView.isHidden = parameters.roomType != .space + + let avatarViewData = AvatarViewData(matrixItemId: parameters.roomId, + displayName: parameters.displayName, + avatarUrl: parameters.avatarUrl, + mediaManager: mediaManager, + fallbackImage: .matrixItem(parameters.roomId, parameters.displayName)) + if !self.avatarView.isHidden { self.avatarView.fill(with: avatarViewData) } if !self.spaceAvatarView.isHidden { self.spaceAvatarView.fill(with: avatarViewData) } - self.membersLabel.text = roomInfo.activeMemberCount == 1 ? VectorL10n.roomTitleOneMember : VectorL10n.roomTitleMembers("\(roomInfo.activeMemberCount)") - if roomInfo.childrenIds.count == 1 { - self.roomsLabel.text = VectorL10n.spacesExploreRoomsOneRoom - } else { - self.roomsLabel.text = VectorL10n.spacesExploreRoomsRoomNumber("\(roomInfo.childrenIds.count)") + + if parameters.membership != .invite { + self.stackView.removeArrangedSubview(self.inviteHeaderView) + self.inviteHeaderView.isHidden = true } - self.topicLabel.text = roomInfo.topic + + self.membersLabel.text = parameters.membersCount == 1 ? VectorL10n.roomTitleOneMember : VectorL10n.roomTitleMembers("\(parameters.membersCount)") + + if let inviterId = parameters.inviterId { + if let inviter = parameters.inviter { + let avatarData = AvatarViewData(matrixItemId: inviterId, + displayName: inviter.displayname, + avatarUrl: inviter.avatarUrl, + mediaManager: mediaManager, + fallbackImage: .matrixItem(inviterId, inviter.displayname)) + self.inviterAvatarView.fill(with: avatarData) + if let inviterName = inviter.displayname { + self.inviteTitleLabel.text = VectorL10n.noticeRoomInviteYou(inviterName) + self.inviteDetailLabel.text = inviterId + } else { + self.inviteTitleLabel.text = VectorL10n.noticeRoomInviteYou(inviterId) + } + } else { + self.inviteTitleLabel.text = VectorL10n.noticeRoomInviteYou(inviterId) + } + } + + self.topicLabel.text = parameters.topic topicLabelBottomMargin.constant = self.topicLabel.text.isEmptyOrNil ? 0 : 16 - self.roomsIconView.isHidden = roomInfo.roomType != .space - self.roomsLabel.isHidden = roomInfo.roomType != .space + self.roomsIconView.isHidden = parameters.roomType != .space + self.roomsLabel.isHidden = parameters.roomType != .space + + self.view.layoutIfNeeded() + } + + private func setupView() { + self.spaceTagView.layer.masksToBounds = true + self.spaceTagView.layer.cornerRadius = 2 + self.spaceTagLabel.text = VectorL10n.spaceTag } private func intrisicHeight(with width: CGFloat) -> CGFloat { if self.topicLabel.text.isEmptyOrNil { return self.topicLabel.frame.minY } - + let topicHeight = self.topicLabel.sizeThatFits(CGSize(width: width - self.topicLabel.frame.minX * 2, height: 0)).height return self.topicLabel.frame.minY + topicHeight + 16 } } + +// MARK: - RoomContextPreviewViewModelViewDelegate + +extension RoomContextPreviewViewController: RoomContextPreviewViewModelViewDelegate { + func roomContextPreviewViewModel(_ viewModel: RoomContextPreviewViewModelProtocol, didUpdateViewState viewSate: RoomContextPreviewViewState) { + switch viewSate { + case .loaded(let parameters): + self.renderLoaded(with: parameters) + } + } +} diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift new file mode 100644 index 000000000..add4db41e --- /dev/null +++ b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift @@ -0,0 +1,178 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `RoomContextActionService` implements all the possible actions for an instance of `MXRoom` +class RoomContextActionService: NSObject, RoomContextActionServiceProtocol { + + // MARK: - RoomContextActionServiceProtocol + + private(set) var session: MXSession + var roomId: String { + return room.roomId + } + internal weak var delegate: RoomContextActionServiceDelegate? + + // MARK: - Properties + + private let room: MXRoom + private let unownedRoomService: UnownedRoomContextActionService + + // MARK: - Setup + + init(room: MXRoom, delegate: RoomContextActionServiceDelegate?) { + self.room = room + self.delegate = delegate + self.isRoomJoined = room.summary?.isJoined ?? false + self.roomMembership = room.summary?.membership ?? .unknown + self.session = room.mxSession + self.unownedRoomService = UnownedRoomContextActionService(roomId: room.roomId, canonicalAlias: room.summary?.aliases?.first, session: self.session, delegate: delegate) + } + + // MARK: - Public + + let isRoomJoined: Bool + let roomMembership: MXMembership + + var isRoomDirect: Bool { + get { + return room.isDirect + } + set { + delegate?.roomContextActionService(self, updateActivityIndicator: true) + room.setIsDirect(newValue, withUserId: nil) { [weak self] in + guard let self = self else { return } + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + } failure: { [weak self] error in + guard let self = self else { return } + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + + // Notify the end user + if let userId = self.session.myUserId { + NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error, userInfo: [kMXKErrorUserIdKey: userId]) + } else { + NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error) + } + } + } + } + + var isRoomMuted: Bool { + get { + return room.isMuted || room.isMentionsOnly + } + set { + if BuildSettings.showNotificationsV2 { + self.delegate?.roomContextActionService(self, showRoomNotificationSettingsForRoomWithId: room.roomId) + } else { + self.muteRoomNotifications(newValue) + } + } + } + + var isRoomFavourite: Bool { + get { + let currentTag = room.accountData.tags?.values.first + return currentTag?.name == kMXRoomTagFavourite + } + set { + self.updateRoom(tag: newValue ? kMXRoomTagFavourite : nil) + } + } + + var isRoomLowPriority: Bool { + get { + let currentTag = room.accountData.tags?.values.first + return currentTag?.name == kMXRoomTagLowPriority + } + set { + self.updateRoom(tag: newValue ? kMXRoomTagLowPriority : nil) + } + } + + private func muteRoomNotifications(_ isMuted: Bool) { + self.delegate?.roomContextActionService(self, updateActivityIndicator: true) + if isMuted { + room.mentionsOnly { [weak self] in + guard let self = self else { return } + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + } + } else { + room.allMessages { [weak self] in + guard let self = self else { return } + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + } + } + } + + private func updateRoom(tag: String?) { + self.delegate?.roomContextActionService(self, updateActivityIndicator: true) + room.setRoomTag(tag) { + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + } + } + + func leaveRoom(promptUser: Bool) { + guard promptUser else { + self.leaveRoom() + return + } + + let title = room.isDirect ? VectorL10n.roomParticipantsLeavePromptTitleForDm : VectorL10n.roomParticipantsLeavePromptTitle + let message = room.isDirect ? VectorL10n.roomParticipantsLeavePromptMsgForDm : VectorL10n.roomParticipantsLeavePromptMsg + + let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)) + alertController.addAction(UIAlertAction(title: VectorL10n.leave, style: .default, handler: { action in + self.leaveRoom() + })) + self.delegate?.roomContextActionService(self, presentAlert: alertController) + } + + func joinRoom() { + unownedRoomService.joinRoom() + } + + private func leaveRoom() { + self.delegate?.roomContextActionService(self, updateActivityIndicator: true) + // cancel pending uploads/downloads + // they are useless by now + MXMediaManager.cancelDownloads(inCacheFolder: self.room.roomId) + + // TODO: GFO cancel pending uploads related to this room + + MXLog.debug("[RoomContextActionService] leaving room \(self.room.roomId ?? "nil")") + + self.room.leave { [weak self] response in + guard let self = self else { return } + + switch response { + case .success: + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + self.delegate?.roomContextActionServiceDidLeaveRoom(self) + case .failure(let error): + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + // Notify the end user + if let userId = self.session.myUserId { + NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error, userInfo: [kMXKErrorUserIdKey: userId]) + } else { + NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error) + } + } + } + } +} diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift new file mode 100644 index 000000000..d44213bd4 --- /dev/null +++ b/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift @@ -0,0 +1,32 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +@objc protocol RoomContextActionServiceDelegate { + func roomContextActionService(_ service: RoomContextActionServiceProtocol, updateActivityIndicator isActive: Bool) + func roomContextActionService(_ service: RoomContextActionServiceProtocol, presentAlert alertController: UIAlertController) + func roomContextActionService(_ service: RoomContextActionServiceProtocol, showRoomNotificationSettingsForRoomWithId roomId: String) + func roomContextActionServiceDidJoinRoom(_ service: RoomContextActionServiceProtocol) + func roomContextActionServiceDidLeaveRoom(_ service: RoomContextActionServiceProtocol) +} + +/// `RoomContextActionServiceProtocol` classes are meant to be called by a `RoomActionProviderProtocol` instance so it provides the implementation of the menu actions. +@objc protocol RoomContextActionServiceProtocol { + var delegate: RoomContextActionServiceDelegate? { get set } + var roomId: String { get } + var session: MXSession { get } +} diff --git a/Riot/Modules/ContextMenu/Services/UnownedRoomContextActionService.swift b/Riot/Modules/ContextMenu/Services/UnownedRoomContextActionService.swift new file mode 100644 index 000000000..a23cc706c --- /dev/null +++ b/Riot/Modules/ContextMenu/Services/UnownedRoomContextActionService.swift @@ -0,0 +1,90 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `RoomContextActionService` implements all the possible actions for a room not owned by the user (e.g. `MXPublicRoom`, `MXSpaceChildInfo`) +class UnownedRoomContextActionService: NSObject, RoomContextActionServiceProtocol { + + // MARK: - RoomContextActionServiceProtocol + + internal let roomId: String + internal let session: MXSession + internal weak var delegate: RoomContextActionServiceDelegate? + + // MARK: - Properties + + private let canonicalAlias: String? + + // MARK: - Setup + + init(roomId: String, canonicalAlias: String?, session: MXSession, delegate: RoomContextActionServiceDelegate?) { + self.roomId = roomId + self.canonicalAlias = canonicalAlias + self.session = session + self.delegate = delegate + } + + // MARK: - Public + + func joinRoom() { + self.delegate?.roomContextActionService(self, updateActivityIndicator: true) + if let canonicalAlias = canonicalAlias { + self.session.matrixRestClient.resolveRoomAlias(canonicalAlias) { [weak self] (response) in + guard let self = self else { return } + switch response { + case .success(let resolution): + self.joinRoom(withId: resolution.roomId, via: resolution.servers) + case .failure(let error): + MXLog.warning("[UnownedRoomContextActionService] joinRoom: failed to resolve room alias due to error \(error).") + self.joinRoom(withId: self.roomId, via: nil) + } + } + } else { + MXLog.warning("[UnownedRoomContextActionService] joinRoom: no canonical alias provided.") + joinRoom(withId: self.roomId, via: nil) + } + } + + // MARK: - Private + + private func joinRoom(withId roomId: String, via viaServers: [String]?) { + self.session.joinRoom(roomId, viaServers: viaServers, withSignUrl: nil) { [weak self] response in + guard let self = self else { return } + switch response { + case .success: + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + self.delegate?.roomContextActionServiceDidJoinRoom(self) + case .failure(let error): + self.delegate?.roomContextActionService(self, updateActivityIndicator: false) + self.delegate?.roomContextActionService(self, presentAlert: self.roomJoinFailedAlert(with: error)) + } + } + } + + private func roomJoinFailedAlert(with error: Error) -> UIAlertController { + var message = (error as NSError).userInfo[NSLocalizedDescriptionKey] as? String + if message == "No known servers" { + // minging kludge until https://matrix.org/jira/browse/SYN-678 is fixed + // 'Error when trying to join an empty room should be more explicit' + message = VectorL10n.roomErrorJoinFailedEmptyRoom + } + + let alertController = UIAlertController(title: VectorL10n.roomErrorJoinFailedTitle, message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: VectorL10n.ok, style: .default, handler: nil)) + return alertController + } +} diff --git a/Riot/Modules/ContextMenu/ViewModels/PublicRoomContextPreviewViewModel.swift b/Riot/Modules/ContextMenu/ViewModels/PublicRoomContextPreviewViewModel.swift new file mode 100644 index 000000000..72c0f2ba8 --- /dev/null +++ b/Riot/Modules/ContextMenu/ViewModels/PublicRoomContextPreviewViewModel.swift @@ -0,0 +1,59 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `PublicRoomContextPreviewViewModel` provides the data to the `RoomContextPreviewViewController` from an instance of `MXPublicRoom` +class PublicRoomContextPreviewViewModel: RoomContextPreviewViewModelProtocol { + + // MARK: - Properties + + private let publicRoom: MXPublicRoom + weak var viewDelegate: RoomContextPreviewViewModelViewDelegate? + + // MARK: - Setup + + init(publicRoom: MXPublicRoom) { + self.publicRoom = publicRoom + } + + // MARK: - RoomContextPreviewViewModelProtocol + + func process(viewAction: RoomContextPreviewViewAction) { + switch viewAction { + case .loadData: + self.loadData() + } + } + + // MARK: - Private + + private func loadData() { + let mapper = MXRoomTypeMapper(defaultRoomType: .room) + let parameters = RoomContextPreviewLoadedParameters( + roomId: publicRoom.roomId, + roomType: mapper.roomType(from: publicRoom.roomTypeString), + displayName: publicRoom.name, + topic: publicRoom.topic, + avatarUrl: publicRoom.avatarUrl, + joinRule: .none, + membership: .unknown, + inviterId: nil, + inviter: nil, + membersCount: publicRoom.numJoinedMembers) + self.viewDelegate?.roomContextPreviewViewModel(self, didUpdateViewState: .loaded(parameters)) + } +} diff --git a/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModel.swift b/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModel.swift new file mode 100644 index 000000000..8227fb33d --- /dev/null +++ b/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModel.swift @@ -0,0 +1,91 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `RoomContextPreviewViewModel` provides the data to the `RoomContextPreviewViewController` from an instance of `MXRoom` +class RoomContextPreviewViewModel: RoomContextPreviewViewModelProtocol { + + // MARK: - Properties + + private let room: MXRoom + weak var viewDelegate: RoomContextPreviewViewModelViewDelegate? + + // MARK: - Setup + + init(room: MXRoom) { + self.room = room + } + + // MARK: - RoomContextPreviewViewModelProtocol + + func process(viewAction: RoomContextPreviewViewAction) { + switch viewAction { + case .loadData: + self.loadData() + } + } + + // MARK: - Private + + private func loadData() { + let parameters = RoomContextPreviewLoadedParameters( + roomId: self.room.roomId, + roomType: self.room.summary?.roomType ?? .none, + displayName: self.room.displayName, + topic: self.room.summary?.topic, + avatarUrl: self.room.summary?.avatar, + joinRule: .public, + membership: self.room.summary?.membership ?? .unknown, + inviterId: nil, + inviter: nil, + membersCount: 0) + self.viewDelegate?.roomContextPreviewViewModel(self, didUpdateViewState: .loaded(parameters)) + + room.state { roomState in + let membersCount = roomState?.members.joinedMembers.count ?? 0 + + var inviteEvent: MXEvent? + roomState?.stateEvents.forEach({ event in + guard let membership = event.wireContent["membership"] as? String, membership == "invite", event.stateKey == self.room.mxSession.myUserId else { + return + } + + inviteEvent = event + }) + + let inviter: MXUser? + if let inviterId = inviteEvent?.sender { + inviter = self.room.mxSession.user(withUserId: inviterId) + } else { + inviter = nil + } + + let parameters = RoomContextPreviewLoadedParameters( + roomId: self.room.roomId, + roomType: self.room.summary?.roomType ?? .none, + displayName: self.room.displayName, + topic: roomState?.topic, + avatarUrl: roomState?.avatar, + joinRule: roomState?.joinRule, + membership: self.room.summary?.membership ?? .unknown, + inviterId: inviteEvent?.sender, + inviter: inviter, + membersCount: membersCount) + self.viewDelegate?.roomContextPreviewViewModel(self, didUpdateViewState: .loaded(parameters)) + } + } +} diff --git a/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModels.swift b/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModels.swift new file mode 100644 index 000000000..16867bd40 --- /dev/null +++ b/Riot/Modules/ContextMenu/ViewModels/RoomContextPreviewViewModels.swift @@ -0,0 +1,52 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// All the data potentially loaded by the `RoomContextPreviewViewModelProtocol` to the `RoomContextPreviewViewController` +struct RoomContextPreviewLoadedParameters { + let roomId: String + let roomType: MXRoomType + let displayName: String? + let topic: String? + let avatarUrl: String? + let joinRule: MXRoomJoinRule? + let membership: MXMembership + let inviterId: String? + let inviter: MXUser? + let membersCount: Int +} + +/// `RoomContextPreviewViewController` view state +enum RoomContextPreviewViewState { + case loaded(_ paremeters: RoomContextPreviewLoadedParameters) +} + +/// `RoomContextPreviewViewController` view action +enum RoomContextPreviewViewAction { + case loadData +} + +/// View delegate for `RoomContextPreviewViewModelProtocol` +protocol RoomContextPreviewViewModelViewDelegate: AnyObject { + func roomContextPreviewViewModel(_ viewModel: RoomContextPreviewViewModelProtocol, didUpdateViewState viewSate: RoomContextPreviewViewState) +} + +/// Classes compliant with `RoomContextPreviewViewModelProtocol` are meant to provide the data to the `RoomContextPreviewViewController` +protocol RoomContextPreviewViewModelProtocol { + var viewDelegate: RoomContextPreviewViewModelViewDelegate? { get set } + func process(viewAction: RoomContextPreviewViewAction) +} diff --git a/Riot/Modules/ContextMenu/ViewModels/SpaceChildContextPreviewViewModel.swift b/Riot/Modules/ContextMenu/ViewModels/SpaceChildContextPreviewViewModel.swift new file mode 100644 index 000000000..aaee23760 --- /dev/null +++ b/Riot/Modules/ContextMenu/ViewModels/SpaceChildContextPreviewViewModel.swift @@ -0,0 +1,58 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// `SpaceChildContextPreviewViewModel` provides the data to the `RoomContextPreviewViewController` from an instance of `MXSpaceChildInfo` +class SpaceChildContextPreviewViewModel: RoomContextPreviewViewModelProtocol { + + // MARK: - Properties + + private let childInfo: MXSpaceChildInfo + weak var viewDelegate: RoomContextPreviewViewModelViewDelegate? + + // MARK: - Setup + + init(childInfo: MXSpaceChildInfo) { + self.childInfo = childInfo + } + + // MARK: - RoomContextPreviewViewModelProtocol + + func process(viewAction: RoomContextPreviewViewAction) { + switch viewAction { + case .loadData: + self.loadData() + } + } + + // MARK: - Private + + private func loadData() { + let parameters = RoomContextPreviewLoadedParameters( + roomId: childInfo.childRoomId, + roomType: childInfo.roomType, + displayName: childInfo.displayName, + topic: childInfo.topic, + avatarUrl: childInfo.avatarUrl, + joinRule: .none, + membership: .unknown, + inviterId: nil, + inviter: nil, + membersCount: childInfo.activeMemberCount) + self.viewDelegate?.roomContextPreviewViewModel(self, didUpdateViewState: .loaded(parameters)) + } +} diff --git a/Riot/Modules/GlobalSearch/Files/HomeFilesSearchViewController.m b/Riot/Modules/GlobalSearch/Files/HomeFilesSearchViewController.m index 04297d759..151f9733d 100644 --- a/Riot/Modules/GlobalSearch/Files/HomeFilesSearchViewController.m +++ b/Riot/Modules/GlobalSearch/Files/HomeFilesSearchViewController.m @@ -150,11 +150,6 @@ threadParameters = [[ThreadParameters alloc] initWithThreadId:event.threadId stackRoomScreen:NO]; } - else if (event.unsignedData.relations.thread || [self.mainSession.threadingService isEventThreadRoot:event]) - { - threadParameters = [[ThreadParameters alloc] initWithThreadId:event.eventId - stackRoomScreen:NO]; - } } ScreenPresentationParameters *presentationParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:NO stackAboveVisibleViews:NO]; diff --git a/Riot/Modules/GlobalSearch/Messages/HomeMessagesSearchViewController.m b/Riot/Modules/GlobalSearch/Messages/HomeMessagesSearchViewController.m index ea0c6a2f3..6be8de0e8 100644 --- a/Riot/Modules/GlobalSearch/Messages/HomeMessagesSearchViewController.m +++ b/Riot/Modules/GlobalSearch/Messages/HomeMessagesSearchViewController.m @@ -157,11 +157,6 @@ threadParameters = [[ThreadParameters alloc] initWithThreadId:event.threadId stackRoomScreen:NO]; } - else if (event.unsignedData.relations.thread || [self.mainSession.threadingService isEventThreadRoot:event]) - { - threadParameters = [[ThreadParameters alloc] initWithThreadId:event.eventId - stackRoomScreen:NO]; - } } ScreenPresentationParameters *screenParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:NO stackAboveVisibleViews:NO]; diff --git a/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m b/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m index 876d80cab..020dc624f 100644 --- a/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m +++ b/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m @@ -21,7 +21,7 @@ #import "GeneratedInterface-Swift.h" -@interface DirectoryViewController () +@interface DirectoryViewController () { PublicRoomsDirectoryDataSource *dataSource; @@ -37,6 +37,10 @@ @property (nonatomic) AnalyticsScreenTracker *screenTracker; +@property (nonatomic, strong) RoomNotificationSettingsCoordinatorBridgePresenter *roomNotificationSettingsCoordinatorBridgePresenter; + +@property (nonatomic, strong) PublicRoomContextMenuProvider *contextMenuProvider; + @end @implementation DirectoryViewController @@ -45,6 +49,9 @@ { [super finalizeInit]; + self.contextMenuProvider = [PublicRoomContextMenuProvider new]; + self.contextMenuProvider.serviceDelegate = self; + // Setup `MXKViewControllerHandling` properties self.enableBarTintColorStatusChange = NO; self.rageShakeManager = [RageShakeManager sharedManager]; @@ -191,36 +198,7 @@ { MXPublicRoom *publicRoom = [dataSource roomAtIndexPath:indexPath]; - // Check whether the user has already joined the selected public room - if ([dataSource.mxSession isJoinedOnRoom:publicRoom.roomId]) - { - // Open the public room. - [self showRoomWithId:publicRoom.roomId inMatrixSession:dataSource.mxSession]; - } - else - { - // Preview the public room - if (publicRoom.worldReadable) - { - RoomPreviewData *roomPreviewData = [[RoomPreviewData alloc] initWithPublicRoom:publicRoom andSession:dataSource.mxSession]; - - [self startActivityIndicator]; - - // Try to get more information about the room before opening its preview - [roomPreviewData peekInRoom:^(BOOL succeeded) { - - [self stopActivityIndicator]; - - [self showRoomPreviewWithData:roomPreviewData]; - }]; - } - else - { - RoomPreviewData *roomPreviewData = [[RoomPreviewData alloc] initWithPublicRoom:publicRoom andSession:dataSource.mxSession]; - [self showRoomPreviewWithData:roomPreviewData]; - } - - } + [self showRoomWithPublicRoom:publicRoom]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView @@ -360,4 +338,120 @@ } } +- (void)showRoomWithPublicRoom:(MXPublicRoom*)publicRoom +{ + // Check whether the user has already joined the selected public room + if ([dataSource.mxSession isJoinedOnRoom:publicRoom.roomId]) + { + // Open the public room. + [self showRoomWithId:publicRoom.roomId inMatrixSession:dataSource.mxSession]; + } + else + { + // Preview the public room + if (publicRoom.worldReadable) + { + RoomPreviewData *roomPreviewData = [[RoomPreviewData alloc] initWithPublicRoom:publicRoom andSession:dataSource.mxSession]; + + [self startActivityIndicator]; + + // Try to get more information about the room before opening its preview + [roomPreviewData peekInRoom:^(BOOL succeeded) { + + [self stopActivityIndicator]; + + [self showRoomPreviewWithData:roomPreviewData]; + }]; + } + else + { + RoomPreviewData *roomPreviewData = [[RoomPreviewData alloc] initWithPublicRoom:publicRoom andSession:dataSource.mxSession]; + [self showRoomPreviewWithData:roomPreviewData]; + } + + } +} + +- (void)changeRoomNotificationSettingsForRoomWithId:(NSString*)roomId +{ + MXRoom *room = [dataSource.mxSession roomWithRoomId:roomId]; + if (room) + { + // navigate + self.roomNotificationSettingsCoordinatorBridgePresenter = [[RoomNotificationSettingsCoordinatorBridgePresenter alloc] initWithRoom:room]; + self.roomNotificationSettingsCoordinatorBridgePresenter.delegate = self; + [self.roomNotificationSettingsCoordinatorBridgePresenter presentFrom:self animated:YES]; + } +} + +#pragma mark - Context Menu + +- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) +{ + MXPublicRoom *publicRoom = [dataSource roomAtIndexPath:indexPath]; + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + + if (!publicRoom || !cell) + { + return nil; + } + + return [self.contextMenuProvider contextMenuConfigurationWith:publicRoom from:cell session:dataSource.mxSession]; +} + +- (void)tableView:(UITableView *)tableView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)) +{ + MXPublicRoom *publicRoom = [self.contextMenuProvider publicRoomFrom:configuration.identifier]; + if (!publicRoom) + { + return; + } + + [animator addCompletion:^{ + [self showRoomWithPublicRoom:publicRoom]; + }]; +} + +#pragma mark - RoomContextActionServiceDelegate + +- (void)roomContextActionServiceDidJoinRoom:(id)service +{ + // Nothing to do here +} + +- (void)roomContextActionServiceDidLeaveRoom:(id)service +{ + // Nothing to do here +} + +- (void)roomContextActionService:(id)service presentAlert:(UIAlertController *)alertController +{ + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)roomContextActionService:(id)service updateActivityIndicator:(BOOL)isActive +{ + if (isActive) + { + [self startActivityIndicator]; + } + else + { + [self stopActivityIndicator]; + } +} + +- (void)roomContextActionService:(id)service showRoomNotificationSettingsForRoomWithId:(NSString *)roomId +{ + [self changeRoomNotificationSettingsForRoomWithId:roomId]; +} + +#pragma mark - RoomNotificationSettingsCoordinatorBridgePresenterDelegate + +-(void)roomNotificationSettingsCoordinatorBridgePresenterDelegateDidComplete:(RoomNotificationSettingsCoordinatorBridgePresenter *)coordinatorBridgePresenter +{ + [coordinatorBridgePresenter dismissWithAnimated:YES completion:nil]; + self.roomNotificationSettingsCoordinatorBridgePresenter = nil; +} + @end diff --git a/Riot/Modules/Home/HomeViewController.m b/Riot/Modules/Home/HomeViewController.m index a850c2271..fbc87e04a 100644 --- a/Riot/Modules/Home/HomeViewController.m +++ b/Riot/Modules/Home/HomeViewController.m @@ -675,111 +675,6 @@ [self.recentsSearchBar resignFirstResponder]; } -- (UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) -{ - UIView *cell = [collectionView cellForItemAtIndexPath:indexPath]; - MXRoom *room = [self.dataSource getRoomAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:collectionView.tag]]; - NSString *roomId = room.roomId; - - MXWeakify(self); - MXWeakify(room); - - return [UIContextMenuConfiguration configurationWithIdentifier:roomId previewProvider:^UIViewController * _Nullable { - // Add a preview using the cell's data to prevent the avatar and displayname from changing with a room list update. - return [[ContextMenuSnapshotPreviewViewController alloc] initWithView:cell]; - - } actionProvider:^UIMenu * _Nullable(NSArray * _Nonnull suggestedActions) { - MXStrongifyAndReturnValueIfNil(room, nil); - - BOOL isDirect = room.isDirect; - UIAction *directChatAction = [UIAction actionWithTitle:isDirect ? VectorL10n.homeContextMenuMakeRoom : VectorL10n.homeContextMenuMakeDm - image:[UIImage systemImageNamed:isDirect ? @"person.crop.circle.badge.xmark" : @"person.circle"] - identifier:nil - handler:^(__kindof UIAction * _Nonnull action) { - MXStrongifyAndReturnIfNil(self); - [self updateRoomWithId:roomId asDirect:!isDirect]; - }]; - - BOOL isMuted = room.isMute || room.isMentionsOnly; - UIImage *notificationsImage; - NSString *notificationsTitle; - if ([BuildSettings showNotificationsV2]) - { - notificationsTitle = VectorL10n.homeContextMenuNotifications; - notificationsImage = [UIImage systemImageNamed:@"bell"]; - } - else - { - notificationsTitle = isMuted ? VectorL10n.homeContextMenuUnmute : VectorL10n.homeContextMenuMute; - notificationsImage = [UIImage systemImageNamed:isMuted ? @"bell.slash": @"bell"]; - } - - UIAction *notificationsAction = [UIAction actionWithTitle:notificationsTitle - image:notificationsImage - identifier:nil - handler:^(__kindof UIAction * _Nonnull action) { - MXStrongifyAndReturnIfNil(self); - [self updateRoomWithId:roomId asMuted:!isMuted]; - }]; - - - // Get the room tag (use only the first one). - MXRoomTag* currentTag = nil; - if (room.accountData.tags) - { - NSArray* tags = room.accountData.tags.allValues; - if (tags.count) - { - currentTag = tags[0]; - } - } - - BOOL isFavourite = (currentTag && [kMXRoomTagFavourite isEqualToString:currentTag.name]); - UIAction *favouriteAction = [UIAction actionWithTitle:isFavourite ? VectorL10n.homeContextMenuUnfavourite : VectorL10n.homeContextMenuFavourite - image:[UIImage systemImageNamed:isFavourite ? @"star.slash" : @"star"] - identifier:nil - handler:^(__kindof UIAction * _Nonnull action) { - MXStrongifyAndReturnIfNil(self); - [self updateRoomWithId:roomId asFavourite:!isFavourite]; - }]; - - BOOL isLowPriority = (currentTag && [kMXRoomTagLowPriority isEqualToString:currentTag.name]); - UIAction *lowPriorityAction = [UIAction actionWithTitle:isLowPriority ? VectorL10n.homeContextMenuNormalPriority : VectorL10n.homeContextMenuLowPriority - image:[UIImage systemImageNamed:isLowPriority ? @"arrow.up" : @"arrow.down"] - identifier:nil - handler:^(__kindof UIAction * _Nonnull action) { - MXStrongifyAndReturnIfNil(self); - [self updateRoomWithId:roomId asLowPriority:!isLowPriority]; - }]; - - UIImage *leaveImage; - if (@available(iOS 14.0, *)) - { - leaveImage = [UIImage systemImageNamed:@"rectangle.righthalf.inset.fill.arrow.right"]; - } - else - { - leaveImage = [UIImage systemImageNamed:@"rectangle.xmark"]; - } - UIAction *leaveAction = [UIAction actionWithTitle:VectorL10n.homeContextMenuLeave - image:leaveImage - identifier:nil - handler:^(__kindof UIAction * _Nonnull action) { - MXStrongifyAndReturnIfNil(self); - [self leaveRoomWithId:roomId]; - }]; - leaveAction.attributes = UIMenuElementAttributesDestructive; - - return [UIMenu menuWithTitle:@"" children:@[ - directChatAction, - notificationsAction, - favouriteAction, - lowPriorityAction, - leaveAction - ]]; - }]; -} - #pragma mark - UICollectionViewDelegateFlowLayout - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath @@ -916,50 +811,6 @@ [self leaveEditedRoom]; } -// MARK: - Context Menu Actions - -- (void)updateRoomWithId:(NSString *)roomId asDirect:(BOOL)direct -{ - editedRoomId = roomId; - [self makeDirectEditedRoom:direct]; - editedRoomId = nil; -} - -- (void)updateRoomWithId:(NSString *)roomId asMuted:(BOOL)muted -{ - editedRoomId = roomId; - if ([BuildSettings showNotificationsV2]) - { - [self changeEditedRoomNotificationSettings]; - } - else - { - [self muteEditedRoomNotifications:muted]; - } - editedRoomId = nil; -} - -- (void)updateRoomWithId:(NSString *)roomId asFavourite:(BOOL)favourite -{ - editedRoomId = roomId; - [self updateEditedRoomTag:favourite ? kMXRoomTagFavourite : nil]; - editedRoomId = nil; -} - -- (void)updateRoomWithId:(NSString *)roomId asLowPriority:(BOOL)lowPriority -{ - editedRoomId = roomId; - [self updateEditedRoomTag:lowPriority ? kMXRoomTagLowPriority : nil]; - editedRoomId = nil; -} - -- (void)leaveRoomWithId:(NSString *)roomId -{ - editedRoomId = roomId; - [self leaveEditedRoom]; - editedRoomId = nil; -} - #pragma mark - SecureBackupSetupCoordinatorBridgePresenterDelegate - (void)secureBackupSetupCoordinatorBridgePresenterDelegateDidComplete:(SecureBackupSetupCoordinatorBridgePresenter *)coordinatorBridgePresenter @@ -1087,4 +938,47 @@ }]; } +#pragma mark - Context Menu + +- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) +{ + return nil; +} + +- (UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) +{ + id cellData = [recentsDataSource cellDataAtIndexPath:[NSIndexPath indexPathForRow:indexPath.item inSection:collectionView.tag]]; + UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; + + if (!cellData || !cell) + { + return nil; + } + + self.recentsUpdateEnabled = NO; + return [self.contextMenuProvider contextMenuConfigurationWith:cellData from:cell session:self.dataSource.mxSession]; +} + +- (void)collectionView:(UICollectionView *)collectionView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)) +{ + NSString *roomId = [self.contextMenuProvider roomIdFrom:configuration.identifier]; + + if (!roomId) + { + self.recentsUpdateEnabled = YES; + return; + } + + [animator addCompletion:^{ + self.recentsUpdateEnabled = YES; + [self showRoomWithRoomId:roomId inMatrixSession:self.mainSession]; + }]; +} + +- (UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) +{ + self.recentsUpdateEnabled = YES; + return nil; +} + @end diff --git a/Riot/Modules/Home/Views/RoomCollectionViewCell.h b/Riot/Modules/Home/Views/RoomCollectionViewCell.h index f08116c11..614524187 100644 --- a/Riot/Modules/Home/Views/RoomCollectionViewCell.h +++ b/Riot/Modules/Home/Views/RoomCollectionViewCell.h @@ -17,6 +17,7 @@ #import "MatrixKit.h" @class BadgeLabel; +@class PresenceIndicatorView; /** 'RoomCollectionViewCell' class is used to display a room in a collection view. @@ -38,6 +39,7 @@ @property (weak, nonatomic) IBOutlet MXKImageView *roomAvatar; @property (weak, nonatomic) IBOutlet UIImageView *encryptedRoomIcon; +@property (weak, nonatomic) IBOutlet PresenceIndicatorView *presenceIndicatorView; @property (weak, nonatomic) IBOutlet BadgeLabel *badgeLabel; diff --git a/Riot/Modules/Home/Views/RoomCollectionViewCell.m b/Riot/Modules/Home/Views/RoomCollectionViewCell.m index a6e115192..550aa8ce1 100644 --- a/Riot/Modules/Home/Views/RoomCollectionViewCell.m +++ b/Riot/Modules/Home/Views/RoomCollectionViewCell.m @@ -63,6 +63,7 @@ self.roomTitle.textColor = ThemeService.shared.theme.textPrimaryColor; self.roomTitle1.textColor = ThemeService.shared.theme.textPrimaryColor; self.roomTitle2.textColor = ThemeService.shared.theme.textPrimaryColor; + self.presenceIndicatorView.borderColor = ThemeService.shared.theme.backgroundColor; self.editionArrowView.backgroundColor = ThemeService.shared.theme.headerBackgroundColor; @@ -145,6 +146,10 @@ roomId:roomCellData.roomIdentifier displayName:roomCellData.roomDisplayname mediaManager:roomCellData.mxSession.mediaManager]; + + // Presence indicator + self.presenceIndicatorView.presence = roomCellData.presence; + self.presenceIndicatorView.hidden = roomCellData.presence == MXPresenceUnknown; } } diff --git a/Riot/Modules/Home/Views/RoomCollectionViewCell.xib b/Riot/Modules/Home/Views/RoomCollectionViewCell.xib index 83b28104b..6852f6ac9 100644 --- a/Riot/Modules/Home/Views/RoomCollectionViewCell.xib +++ b/Riot/Modules/Home/Views/RoomCollectionViewCell.xib @@ -1,9 +1,9 @@ - + - + @@ -37,6 +37,19 @@ + diff --git a/Riot/Modules/Threads/ThreadList/Views/Empty/ThreadListEmptyView.xib b/Riot/Modules/Threads/ThreadList/Views/Empty/ThreadListEmptyView.xib index d4b40f6f5..bfef99ff8 100644 --- a/Riot/Modules/Threads/ThreadList/Views/Empty/ThreadListEmptyView.xib +++ b/Riot/Modules/Threads/ThreadList/Views/Empty/ThreadListEmptyView.xib @@ -1,9 +1,9 @@ - + - + @@ -63,13 +63,13 @@ - - + diff --git a/Riot/SupportingFiles/Riot-Bridging-Header.h b/Riot/SupportingFiles/Riot-Bridging-Header.h index e629216ae..1de9b0dc7 100644 --- a/Riot/SupportingFiles/Riot-Bridging-Header.h +++ b/Riot/SupportingFiles/Riot-Bridging-Header.h @@ -51,6 +51,7 @@ #import "PlainRoomTimelineCellProvider.h" #import "BubbleRoomTimelineCellProvider.h" #import "RoomSelectedStickerBubbleCell.h" +#import "MXRoom+Riot.h" // MatrixKit common imports, shared with all targets #import "MatrixKit-Bridging-Header.h" diff --git a/Riot/target.yml b/Riot/target.yml index 76014eb44..d0239e9ae 100644 --- a/Riot/target.yml +++ b/Riot/target.yml @@ -67,6 +67,8 @@ targets: - path: . excludes: - "Modules/Room/EmojiPicker/Data/EmojiMart/EmojiJSONStore.swift" + - "Assets/ar.lproj/**" # RTL is broken so languages are disabled for now + - "Assets/he.lproj/**" - path: ../RiotShareExtension/Shared - path: Modules/MatrixKit excludes: diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index e72804449..5e141c574 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -74,6 +74,17 @@ class NotificationService: UNNotificationServiceExtension { private static let backgroundServiceInitQueue = DispatchQueue(label: "io.element.NotificationService.backgroundServiceInitQueue") // MARK: - Method Overrides + override init() { + super.init() + + // Set up runtime language and fallback by considering the userDefaults object shared within the application group. + let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults + if let language = sharedUserDefaults?.string(forKey: "appLanguage") { + Bundle.mxk_setLanguage(language) + } + Bundle.mxk_setFallbackLanguage("en") + } + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { let userInfo = request.content.userInfo @@ -341,9 +352,9 @@ class NotificationService: UNNotificationServiceExtension { let isVideoCall = sdp?.contains("m=video") ?? false if isVideoCall { - notificationBody = NSString.localizedUserNotificationString(forKey: "VIDEO_CALL_FROM_USER", arguments: [eventSenderName as Any]) + notificationBody = NotificationService.localizedString(forKey: "VIDEO_CALL_FROM_USER", eventSenderName) } else { - notificationBody = NSString.localizedUserNotificationString(forKey: "VOICE_CALL_FROM_USER", arguments: [eventSenderName as Any]) + notificationBody = NotificationService.localizedString(forKey: "VOICE_CALL_FROM_USER", eventSenderName) } // call notifications should stand out from normal messages, so we don't stack them @@ -405,7 +416,7 @@ class NotificationService: UNNotificationServiceExtension { } let msgType = event.content[kMXMessageTypeKey] as? String - let messageContent = event.content[kMXMessageBodyKey] as? String + let messageContent = event.content[kMXMessageBodyKey] as? String ?? "" let isReply = event.isReply() if isReply { @@ -416,30 +427,30 @@ class NotificationService: UNNotificationServiceExtension { if event.isEncrypted && !self.showDecryptedContentInNotifications { // Hide the content - notificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE", arguments: []) + notificationBody = NotificationService.localizedString(forKey: "MESSAGE") break } if event.location != nil { - notificationBody = NSString.localizedUserNotificationString(forKey: "LOCATION_FROM_USER", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "LOCATION_FROM_USER", eventSenderName) break } switch msgType { case kMXMessageTypeEmote: - notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments: [eventSenderName, messageContent as Any]) + notificationBody = NotificationService.localizedString(forKey: "ACTION_FROM_USER", eventSenderName, messageContent) case kMXMessageTypeImage: - notificationBody = NSString.localizedUserNotificationString(forKey: "PICTURE_FROM_USER", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "PICTURE_FROM_USER", eventSenderName) case kMXMessageTypeVideo: - notificationBody = NSString.localizedUserNotificationString(forKey: "VIDEO_FROM_USER", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "VIDEO_FROM_USER", eventSenderName) case kMXMessageTypeAudio: if event.isVoiceMessage() { - notificationBody = NSString.localizedUserNotificationString(forKey: "VOICE_MESSAGE_FROM_USER", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "VOICE_MESSAGE_FROM_USER", eventSenderName) } else { - notificationBody = NSString.localizedUserNotificationString(forKey: "AUDIO_FROM_USER", arguments: [eventSenderName, messageContent as Any]) + notificationBody = NotificationService.localizedString(forKey: "AUDIO_FROM_USER", eventSenderName, messageContent) } case kMXMessageTypeFile: - notificationBody = NSString.localizedUserNotificationString(forKey: "FILE_FROM_USER", arguments: [eventSenderName, messageContent as Any]) + notificationBody = NotificationService.localizedString(forKey: "FILE_FROM_USER", eventSenderName, messageContent) // All other message types such as text, notice, server notice etc default: @@ -469,50 +480,50 @@ class NotificationService: UNNotificationServiceExtension { // If there was a change, use the sender's userID if one was blank and show the change. if let oldDisplayname = oldContent.displayname ?? event.sender, let displayname = newContent.displayname ?? event.sender { - notificationBody = NSString.localizedUserNotificationString(forKey: "USER_UPDATED_DISPLAYNAME", arguments: [oldDisplayname, displayname]) + notificationBody = NotificationService.localizedString(forKey: "USER_UPDATED_DISPLAYNAME", oldDisplayname, displayname) } else { // Should never be reached as the event should always have a sender. - notificationBody = NSString.localizedUserNotificationString(forKey: "GENERIC_USER_UPDATED_DISPLAYNAME", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "GENERIC_USER_UPDATED_DISPLAYNAME", eventSenderName) } } else { // If the display name hasn't changed, handle as an avatar change. - notificationBody = NSString.localizedUserNotificationString(forKey: "USER_UPDATED_AVATAR", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "USER_UPDATED_AVATAR", eventSenderName) } } else { // No known reports of having reached this situation for a membership notification // So use a generic membership updated fallback. - notificationBody = NSString.localizedUserNotificationString(forKey: "USER_MEMBERSHIP_UPDATED", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "USER_MEMBERSHIP_UPDATED", eventSenderName) } // Otherwise treat the notification as an invite. // This is the expected notification content for a membership event. } else { - if roomDisplayName != nil && roomDisplayName != eventSenderName { - notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_NAMED_ROOM", arguments: [eventSenderName, roomDisplayName as Any]) + if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName { + notificationBody = NotificationService.localizedString(forKey: "USER_INVITE_TO_NAMED_ROOM", eventSenderName, roomDisplayName) } else { - notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_CHAT", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "USER_INVITE_TO_CHAT", eventSenderName) } } case .sticker: notificationTitle = self.messageTitle(for: eventSenderName, in: roomDisplayName) - notificationBody = NSString.localizedUserNotificationString(forKey: "STICKER_FROM_USER", arguments: [eventSenderName as Any]) + notificationBody = NotificationService.localizedString(forKey: "STICKER_FROM_USER", eventSenderName) // Reactions are unexpected notification types, but have been seen in some circumstances. case .reaction: notificationTitle = self.messageTitle(for: eventSenderName, in: roomDisplayName) if let reactionKey = event.relatesTo?.key { // Try to show the reaction key in the notification. - notificationBody = NSString.localizedUserNotificationString(forKey: "REACTION_FROM_USER", arguments: [eventSenderName, reactionKey]) + notificationBody = NotificationService.localizedString(forKey: "REACTION_FROM_USER", eventSenderName, reactionKey) } else { // Otherwise show a generic reaction. - notificationBody = NSString.localizedUserNotificationString(forKey: "GENERIC_REACTION_FROM_USER", arguments: [eventSenderName]) + notificationBody = NotificationService.localizedString(forKey: "GENERIC_REACTION_FROM_USER", eventSenderName) } case .custom: if (event.type == kWidgetMatrixEventTypeString || event.type == kWidgetModularEventTypeString), let type = event.content?["type"] as? String, (type == kWidgetTypeJitsiV1 || type == kWidgetTypeJitsiV2) { - notificationBody = NSString.localizedUserNotificationString(forKey: "GROUP_CALL_STARTED", arguments: nil) + notificationBody = NotificationService.localizedString(forKey: "GROUP_CALL_STARTED") notificationTitle = roomDisplayName // call notifications should stand out from normal messages, so we don't stack them @@ -566,7 +577,7 @@ class NotificationService: UNNotificationServiceExtension { var validatedNotificationTitle: String? = notificationTitle if self.localAuthenticationService.isProtectionSet { MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Resetting title and body because app protection is set") - validatedNotificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) + validatedNotificationBody = NotificationService.localizedString(forKey: "MESSAGE_PROTECTED") validatedNotificationTitle = nil } @@ -596,7 +607,7 @@ class NotificationService: UNNotificationServiceExtension { private func messageTitle(for eventSenderName: String, in roomDisplayName: String?) -> String { // Display the room name only if it is different than the sender name if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName { - return NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName, roomDisplayName]) + return NotificationService.localizedString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", eventSenderName, roomDisplayName) } else { return eventSenderName } @@ -605,9 +616,9 @@ class NotificationService: UNNotificationServiceExtension { private func replyTitle(for eventSenderName: String, in roomDisplayName: String?) -> String { // Display the room name only if it is different than the sender name if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName { - return NSString.localizedUserNotificationString(forKey: "REPLY_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName, roomDisplayName]) + return NotificationService.localizedString(forKey: "REPLY_FROM_USER_IN_ROOM_TITLE", eventSenderName, roomDisplayName) } else { - return NSString.localizedUserNotificationString(forKey: "REPLY_FROM_USER_TITLE", arguments: [eventSenderName]) + return NotificationService.localizedString(forKey: "REPLY_FROM_USER_TITLE", eventSenderName) } } @@ -816,4 +827,13 @@ class NotificationService: UNNotificationServiceExtension { } } } + + private static func localizedString(forKey key: String, _ args: CVarArg...) -> String { + // The bundle needs to be an MXKLanguageBundle and contain the lproj files. + // MatrixKit now sets the app bundle as the MXKLanguageBundle + let format = NSLocalizedString(key, bundle: Bundle.app, comment: "") + let locale = LocaleProvider.locale ?? Locale.current + + return String(format: format, locale: locale, arguments: args) + } } diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift index 637e1689f..1d6ff6893 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift @@ -114,17 +114,24 @@ struct AnalyticsPrompt: View { GeometryReader { geometry in VStack { ScrollView(showsIndicators: false) { + Spacer() + .frame(height: OnboardingMetrics.spacerHeight(in: geometry)) + mainContent - .padding(.top, 50) + .frame(maxWidth: OnboardingMetrics.maxContentWidth) .padding(.horizontal, horizontalPadding) + .padding(.top, OnboardingMetrics.breakerScreenTopPadding) } - .frame(maxWidth: OnboardingMetrics.maxContentWidth) .frame(maxWidth: .infinity) buttons .frame(maxWidth: OnboardingMetrics.maxContentWidth) .padding(.horizontal, horizontalPadding) + .padding(.bottom, OnboardingMetrics.actionButtonBottomPadding) .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 0 : 16) + + Spacer() + .frame(height: OnboardingMetrics.spacerHeight(in: geometry)) } .background(theme.colors.background.ignoresSafeArea()) .accentColor(theme.colors.accent) @@ -136,10 +143,13 @@ struct AnalyticsPrompt: View { // MARK: - Previews -@available(iOS 14.0, *) +@available(iOS 15.0, *) struct AnalyticsPrompt_Previews: PreviewProvider { static let stateRenderer = MockAnalyticsPromptScreenState.stateRenderer static var previews: some View { stateRenderer.screenGroup() + .theme(.light).preferredColorScheme(.light) + stateRenderer.screenGroup() + .theme(.dark).preferredColorScheme(.dark) } } diff --git a/RiotSwiftUI/Modules/Common/EffectsScene/EffectsView.swift b/RiotSwiftUI/Modules/Common/EffectsScene/EffectsView.swift index aa868f90c..a3ca268f1 100644 --- a/RiotSwiftUI/Modules/Common/EffectsScene/EffectsView.swift +++ b/RiotSwiftUI/Modules/Common/EffectsScene/EffectsView.swift @@ -28,7 +28,7 @@ struct EffectsView: UIViewRepresentable { // MARK: - Public - enum EffectsType { + enum Effect { /// A confetti drop effect from the top centre of the screen. case confetti /// No effect will be shown. @@ -36,7 +36,7 @@ struct EffectsView: UIViewRepresentable { } /// The type of effects to be shown in the view. - var effectsType: EffectsType = .none + var effect: Effect // MARK: - Lifecycle @@ -52,7 +52,7 @@ struct EffectsView: UIViewRepresentable { // MARK: - Private private func makeScene() -> EffectsScene? { - switch effectsType { + switch effect { case .confetti: return EffectsScene.confetti(with: theme) case .none: diff --git a/RiotSwiftUI/Modules/Common/Extensions/CLLocationCoordinate2D.swift b/RiotSwiftUI/Modules/Common/Extensions/CLLocationCoordinate2D.swift new file mode 100644 index 000000000..cdc21e100 --- /dev/null +++ b/RiotSwiftUI/Modules/Common/Extensions/CLLocationCoordinate2D.swift @@ -0,0 +1,33 @@ +// +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import CoreLocation + +extension CLLocationCoordinate2D { + + /// Compare two coordinates + /// - parameter coordinate: another coordinate to compare + /// - parameter precision:it represente how close you want the two coordinates + /// - return: bool value + func isEqual(to coordinate: CLLocationCoordinate2D, precision: Double) -> Bool { + + if fabs(self.latitude - coordinate.latitude) <= precision && fabs(self.longitude - coordinate.longitude) <= precision { + return true + } + return false + } +} diff --git a/RiotSwiftUI/Modules/Onboarding/Avatar/Coordinator/OnboardingAvatarCoordinator.swift b/RiotSwiftUI/Modules/Onboarding/Avatar/Coordinator/OnboardingAvatarCoordinator.swift index 70a9651d2..f66847a9c 100644 --- a/RiotSwiftUI/Modules/Onboarding/Avatar/Coordinator/OnboardingAvatarCoordinator.swift +++ b/RiotSwiftUI/Modules/Onboarding/Avatar/Coordinator/OnboardingAvatarCoordinator.swift @@ -19,6 +19,15 @@ import CommonKit struct OnboardingAvatarCoordinatorParameters { let userSession: UserSession + /// An optional image that can be set to pre-fill the avatar. + let avatar: UIImage? +} + +enum OnboardingAvatarCoordinatorResult { + /// The user has chosen an image (but hasn't yet saved it). + case selectedAvatar(UIImage?) + /// The screen is finished and the next one can be shown. + case complete(UserSession) } @available(iOS 14.0, *) @@ -55,7 +64,7 @@ final class OnboardingAvatarCoordinator: Coordinator, Presentable { // Must be used only internally var childCoordinators: [Coordinator] = [] - var completion: ((UserSession) -> Void)? + var completion: ((OnboardingAvatarCoordinatorResult) -> Void)? // MARK: - Setup @@ -64,6 +73,8 @@ final class OnboardingAvatarCoordinator: Coordinator, Presentable { let viewModel = OnboardingAvatarViewModel(userId: parameters.userSession.userId, displayName: parameters.userSession.account.userDisplayName, avatarColorCount: DefaultThemeSwiftUI().colors.namesAndAvatars.count) + viewModel.updateAvatarImage(with: parameters.avatar) + let view = OnboardingAvatarScreen(viewModel: viewModel.context) onboardingAvatarViewModel = viewModel onboardingAvatarHostingController = VectorHostingController(rootView: view) @@ -89,7 +100,7 @@ final class OnboardingAvatarCoordinator: Coordinator, Presentable { case .save(let avatar): self.setAvatar(avatar) case .skip: - self.completion?(self.parameters.userSession) + self.completion?(.complete(self.parameters.userSession)) } } } @@ -151,7 +162,7 @@ final class OnboardingAvatarCoordinator: Coordinator, Presentable { self.parameters.userSession.account.setUserAvatarUrl(urlString) { [weak self] in guard let self = self else { return } self.stopWaiting() - self.completion?(self.parameters.userSession) + self.completion?(.complete(self.parameters.userSession)) } failure: { [weak self] error in guard let self = self else { return } self.stopWaiting() @@ -169,8 +180,11 @@ final class OnboardingAvatarCoordinator: Coordinator, Presentable { @available(iOS 14.0, *) extension OnboardingAvatarCoordinator: MediaPickerPresenterDelegate { + /// **Note:** MediaPickerPresenter fails to load images on the simulator as of Xcode 13.3 (at least on an M1 Mac), + /// so whilst this method may not appear to be called, everything works fine when run on a device. func mediaPickerPresenter(_ presenter: MediaPickerPresenter, didPickImage image: UIImage) { onboardingAvatarViewModel.updateAvatarImage(with: image) + completion?(.selectedAvatar(image)) presenter.dismiss(animated: true, completion: nil) } @@ -185,6 +199,7 @@ extension OnboardingAvatarCoordinator: MediaPickerPresenterDelegate { extension OnboardingAvatarCoordinator: CameraPresenterDelegate { func cameraPresenter(_ presenter: CameraPresenter, didSelectImage image: UIImage) { onboardingAvatarViewModel.updateAvatarImage(with: image) + completion?(.selectedAvatar(image)) presenter.dismiss(animated: true, completion: nil) } diff --git a/RiotSwiftUI/Modules/Onboarding/Avatar/View/OnboardingAvatarScreen.swift b/RiotSwiftUI/Modules/Onboarding/Avatar/View/OnboardingAvatarScreen.swift index 498510671..6474afabd 100644 --- a/RiotSwiftUI/Modules/Onboarding/Avatar/View/OnboardingAvatarScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/Avatar/View/OnboardingAvatarScreen.swift @@ -44,9 +44,9 @@ struct OnboardingAvatarScreen: View { buttons } - .padding(.horizontal) - .padding(.top, 8) .frame(maxWidth: OnboardingMetrics.maxContentWidth) + .padding(.horizontal) + .padding(.top, OnboardingMetrics.topPaddingToNavigationBar) } .frame(maxWidth: .infinity, maxHeight: .infinity) .accentColor(theme.colors.accent) @@ -116,7 +116,7 @@ struct OnboardingAvatarScreen: View { .foregroundColor(theme.colors.primaryContent) Text(VectorL10n.onboardingAvatarMessage) - .font(theme.fonts.subheadline) + .font(theme.fonts.body) .multilineTextAlignment(.center) .foregroundColor(theme.colors.secondaryContent) } diff --git a/RiotSwiftUI/Modules/Onboarding/Celebration/View/OnboardingCelebrationScreen.swift b/RiotSwiftUI/Modules/Onboarding/Celebration/View/OnboardingCelebrationScreen.swift index 9039f1025..1a1ac57f3 100644 --- a/RiotSwiftUI/Modules/Onboarding/Celebration/View/OnboardingCelebrationScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/Celebration/View/OnboardingCelebrationScreen.swift @@ -45,16 +45,16 @@ struct OnboardingCelebrationScreen: View { .frame(height: OnboardingMetrics.spacerHeight(in: geometry)) mainContent - .padding(.top, 106) - .padding(.horizontal, horizontalPadding) .frame(maxWidth: OnboardingMetrics.maxContentWidth) + .padding(.top, OnboardingMetrics.breakerScreenTopPadding) + .padding(.horizontal, horizontalPadding) } .frame(maxWidth: .infinity) buttons .frame(maxWidth: OnboardingMetrics.maxContentWidth) .padding(.horizontal, horizontalPadding) - .padding(.bottom, 24) + .padding(.bottom, OnboardingMetrics.actionButtonBottomPadding) .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 0 : 16) Spacer() @@ -74,7 +74,7 @@ struct OnboardingCelebrationScreen: View { Image(Asset.Images.onboardingCelebrationIcon.name) .resizable() .scaledToFit() - .frame(width: 90) + .frame(width: OnboardingMetrics.iconSize, height: OnboardingMetrics.iconSize) .foregroundColor(theme.colors.accent) .background(Circle().foregroundColor(.white).padding(2)) .padding(.bottom, 42) @@ -86,7 +86,7 @@ struct OnboardingCelebrationScreen: View { .foregroundColor(theme.colors.primaryContent) Text(VectorL10n.onboardingCelebrationMessage) - .font(theme.fonts.subheadline) + .font(theme.fonts.body) .multilineTextAlignment(.center) .foregroundColor(theme.colors.secondaryContent) } @@ -104,7 +104,7 @@ struct OnboardingCelebrationScreen: View { } var effects: some View { - EffectsView(effectsType: .confetti) + EffectsView(effect: .confetti) .allowsHitTesting(false) } } diff --git a/RiotSwiftUI/Modules/Onboarding/Common/OnboardingMetrics.swift b/RiotSwiftUI/Modules/Onboarding/Common/OnboardingMetrics.swift index a4102a5f0..5a337efec 100644 --- a/RiotSwiftUI/Modules/Onboarding/Common/OnboardingMetrics.swift +++ b/RiotSwiftUI/Modules/Onboarding/Common/OnboardingMetrics.swift @@ -22,6 +22,16 @@ struct OnboardingMetrics { static let maxContentWidth: CGFloat = 600 static let maxContentHeight: CGFloat = 750 + /// The padding used to the top of the view for breaker screens that don't have a navigation bar. + static let breakerScreenTopPadding: CGFloat = 80 + /// The padding used between the top of the main content and the navigation bar. + static let topPaddingToNavigationBar: CGFloat = 16 + /// The padding used between the footer and the bottom of the view. + static let actionButtonBottomPadding: CGFloat = 24 + /// The width/height used for the main icon shown in most of the screens. + static let iconSize: CGFloat = 90 + + /// The height to use for top/bottom spacers to pad the views to fit the `maxContentHeight`. static func spacerHeight(in geometry: GeometryProxy) -> CGFloat { max(0, (geometry.size.height - maxContentHeight) / 2) } diff --git a/RiotSwiftUI/Modules/Onboarding/Congratulations/Coordinator/OnboardingCongratulationsCoordinator.swift b/RiotSwiftUI/Modules/Onboarding/Congratulations/Coordinator/OnboardingCongratulationsCoordinator.swift index 47f6ee54b..97d218ea1 100644 --- a/RiotSwiftUI/Modules/Onboarding/Congratulations/Coordinator/OnboardingCongratulationsCoordinator.swift +++ b/RiotSwiftUI/Modules/Onboarding/Congratulations/Coordinator/OnboardingCongratulationsCoordinator.swift @@ -31,6 +31,7 @@ enum OnboardingCongratulationsCoordinatorResult { case takeMeHome(UserSession) } +@available(iOS 14.0, *) final class OnboardingCongratulationsCoordinator: Coordinator, Presentable { // MARK: - Properties @@ -38,7 +39,7 @@ final class OnboardingCongratulationsCoordinator: Coordinator, Presentable { // MARK: Private private let parameters: OnboardingCongratulationsCoordinatorParameters - private let onboardingCongratulationsHostingController: UIViewController + private let onboardingCongratulationsHostingController: VectorHostingController private var onboardingCongratulationsViewModel: OnboardingCongratulationsViewModelProtocol // MARK: Public @@ -49,7 +50,6 @@ final class OnboardingCongratulationsCoordinator: Coordinator, Presentable { // MARK: - Setup - @available(iOS 14.0, *) init(parameters: OnboardingCongratulationsCoordinatorParameters) { self.parameters = parameters @@ -59,6 +59,7 @@ final class OnboardingCongratulationsCoordinator: Coordinator, Presentable { let view = OnboardingCongratulationsScreen(viewModel: viewModel.context) onboardingCongratulationsViewModel = viewModel onboardingCongratulationsHostingController = VectorHostingController(rootView: view) + onboardingCongratulationsHostingController.statusBarStyle = .lightContent } // MARK: - Public diff --git a/RiotSwiftUI/Modules/Onboarding/Congratulations/View/OnboardingCongratulationsScreen.swift b/RiotSwiftUI/Modules/Onboarding/Congratulations/View/OnboardingCongratulationsScreen.swift index eacdd0eb2..2c6e877d0 100644 --- a/RiotSwiftUI/Modules/Onboarding/Congratulations/View/OnboardingCongratulationsScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/Congratulations/View/OnboardingCongratulationsScreen.swift @@ -45,7 +45,7 @@ struct OnboardingCongratulationsScreen: View { mainContent .frame(maxWidth: OnboardingMetrics.maxContentWidth) - .padding(.top, 60) + .padding(.top, OnboardingMetrics.breakerScreenTopPadding) .padding(.horizontal, horizontalPadding) } .frame(maxWidth: .infinity) @@ -53,7 +53,7 @@ struct OnboardingCongratulationsScreen: View { footer .frame(maxWidth: OnboardingMetrics.maxContentWidth) .padding(.horizontal, horizontalPadding) - .padding(.bottom, 24) + .padding(.bottom, OnboardingMetrics.actionButtonBottomPadding) .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 0 : 16) Spacer() @@ -73,7 +73,7 @@ struct OnboardingCongratulationsScreen: View { VStack(spacing: 42) { Image(Asset.Images.onboardingCongratulationsIcon.name) .resizable() - .frame(width: 90, height: 90) + .frame(width: OnboardingMetrics.iconSize, height: OnboardingMetrics.iconSize) .accessibilityHidden(true) VStack(spacing: 8) { @@ -132,7 +132,7 @@ struct OnboardingCongratulationsScreen: View { @ViewBuilder var effects: some View { if viewModel.viewState.personalizationDisabled { - EffectsView(effectsType: .confetti) + EffectsView(effect: .confetti) .allowsHitTesting(false) .accessibilityIdentifier("confetti") } diff --git a/RiotSwiftUI/Modules/Onboarding/DisplayName/View/OnboardingDisplayNameScreen.swift b/RiotSwiftUI/Modules/Onboarding/DisplayName/View/OnboardingDisplayNameScreen.swift index a9cceb4e4..e5e149b73 100644 --- a/RiotSwiftUI/Modules/Onboarding/DisplayName/View/OnboardingDisplayNameScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/DisplayName/View/OnboardingDisplayNameScreen.swift @@ -49,9 +49,9 @@ struct OnboardingDisplayNameScreen: View { buttons } - .padding(.horizontal) - .padding(.top, 8) .frame(maxWidth: OnboardingMetrics.maxContentWidth) + .padding(.horizontal) + .padding(.top, OnboardingMetrics.topPaddingToNavigationBar) } .frame(maxWidth: .infinity, maxHeight: .infinity) .accentColor(theme.colors.accent) @@ -69,7 +69,7 @@ struct OnboardingDisplayNameScreen: View { .resizable() .renderingMode(.template) .foregroundColor(theme.colors.accent) - .frame(width: 90, height: 90) + .frame(width: OnboardingMetrics.iconSize, height: OnboardingMetrics.iconSize) .background(Circle().foregroundColor(.white).padding(2)) .padding(.bottom, 8) .accessibilityHidden(true) @@ -80,7 +80,7 @@ struct OnboardingDisplayNameScreen: View { .foregroundColor(theme.colors.primaryContent) Text(VectorL10n.onboardingDisplayNameMessage) - .font(theme.fonts.subheadline) + .font(theme.fonts.body) .multilineTextAlignment(.center) .foregroundColor(theme.colors.secondaryContent) } @@ -92,6 +92,7 @@ struct OnboardingDisplayNameScreen: View { TextField(VectorL10n.onboardingDisplayNamePlaceholder, text: $viewModel.displayName) { isEditingTextField = $0 } + .autocapitalization(.words) .textFieldStyle(BorderedInputFieldStyle(theme: _theme, isEditing: isEditingTextField, isError: viewModel.viewState.validationErrorMessage != nil)) diff --git a/RiotSwiftUI/Modules/Onboarding/UseCase/View/OnboardingUseCaseSelectionScreen.swift b/RiotSwiftUI/Modules/Onboarding/UseCase/View/OnboardingUseCaseSelectionScreen.swift index 13d748fb0..1d96f4b42 100644 --- a/RiotSwiftUI/Modules/Onboarding/UseCase/View/OnboardingUseCaseSelectionScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/UseCase/View/OnboardingUseCaseSelectionScreen.swift @@ -34,6 +34,11 @@ struct OnboardingUseCaseSelectionScreen: View { var titleContent: some View { VStack(spacing: 8) { Image(Asset.Images.onboardingUseCaseIcon.name) + .resizable() + .renderingMode(.template) + .foregroundColor(theme.colors.accent) + .frame(width: OnboardingMetrics.iconSize, height: OnboardingMetrics.iconSize) + .background(Circle().foregroundColor(.white).padding(2)) .padding(.bottom, 8) .accessibilityHidden(true) @@ -99,9 +104,9 @@ struct OnboardingUseCaseSelectionScreen: View { useCaseButtons } - .frame(maxWidth: OnboardingMetrics.maxContentWidth, - maxHeight: OnboardingMetrics.maxContentHeight) - .padding(16) + .frame(maxWidth: OnboardingMetrics.maxContentWidth) + .padding(.top, OnboardingMetrics.topPaddingToNavigationBar) + .padding(.horizontal, 16) } .frame(maxWidth: .infinity) @@ -120,11 +125,11 @@ struct OnboardingUseCaseSelectionScreen: View { @available(iOS 14.0, *) struct OnboardingUseCase_Previews: PreviewProvider { static let stateRenderer = MockOnboardingUseCaseSelectionScreenState.stateRenderer + static var previews: some View { - NavigationView { - stateRenderer.screenGroup() - .navigationBarTitleDisplayMode(.inline) - } - .navigationViewStyle(StackNavigationViewStyle()) + stateRenderer.screenGroup(addNavigation: true) + .theme(.light).preferredColorScheme(.light) + stateRenderer.screenGroup(addNavigation: true) + .theme(.dark).preferredColorScheme(.dark) } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift index 85adbc669..aa2512fa4 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift @@ -17,12 +17,44 @@ import Foundation import UIKit import SwiftUI +import MatrixSDK struct LocationSharingCoordinatorParameters { let roomDataSource: MXKRoomDataSource let mediaManager: MXMediaManager let avatarData: AvatarInputProtocol let location: CLLocationCoordinate2D? + let coordinateType: MXEventAssetType +} + +// Map between type from MatrixSDK and type from SwiftUI target, as we don't want +// to add the SDK as a dependency to it. We need to translate from one to the other on this level. +extension MXEventAssetType { + func locationSharingCoordinateType() -> LocationSharingCoordinateType { + let coordinateType: LocationSharingCoordinateType + switch self { + case .user, .generic: + coordinateType = .user + case .pin: + coordinateType = .pin + @unknown default: + coordinateType = .user + } + return coordinateType + } +} + +extension LocationSharingCoordinateType { + func eventAssetType() -> MXEventAssetType { + let eventAssetType: MXEventAssetType + switch self { + case .user: + eventAssetType = .user + case .pin: + eventAssetType = .pin + } + return eventAssetType + } } final class LocationSharingCoordinator: Coordinator, Presentable { @@ -50,6 +82,7 @@ final class LocationSharingCoordinator: Coordinator, Presentable { let viewModel = LocationSharingViewModel(mapStyleURL: BuildSettings.tileServerMapStyleURL, avatarData: parameters.avatarData, location: parameters.location, + coordinateType: parameters.coordinateType.locationSharingCoordinateType(), isLiveLocationSharingEnabled: BuildSettings.liveLocationSharingEnabled) let view = LocationSharingView(context: viewModel.context) .addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager)) @@ -71,7 +104,7 @@ final class LocationSharingCoordinator: Coordinator, Presentable { switch result { case .cancel: self.completion?() - case .share(let latitude, let longitude): + case .share(let latitude, let longitude, let coordinateType): // Show share sheet on existing location display if let location = self.parameters.location { @@ -81,7 +114,7 @@ final class LocationSharingCoordinator: Coordinator, Presentable { self.locationSharingViewModel.startLoading() - self.parameters.roomDataSource.sendLocation(withLatitude: latitude, longitude: longitude, description: nil) { [weak self] _ in + self.parameters.roomDataSource.sendLocation(withLatitude: latitude, longitude: longitude, description: nil, coordinateType: coordinateType.eventAssetType()) { [weak self] _ in guard let self = self else { return } self.locationSharingViewModel.stopLoading() diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/UserLocationAnnotation.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationAnnotation.swift similarity index 75% rename from RiotSwiftUI/Modules/Room/LocationSharing/UserLocationAnnotation.swift rename to RiotSwiftUI/Modules/Room/LocationSharing/LocationAnnotation.swift index f4e2453df..545348f0e 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/UserLocationAnnotation.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationAnnotation.swift @@ -17,22 +17,35 @@ import Foundation import Mapbox -class UserLocationAnnotation: NSObject, MGLAnnotation { +class LocationAnnotation: NSObject, MGLAnnotation { // MARK: - Properties - let avatarData: AvatarInputProtocol - let coordinate: CLLocationCoordinate2D // MARK: - Setup - init(avatarData: AvatarInputProtocol, - coordinate: CLLocationCoordinate2D) { + init(coordinate: CLLocationCoordinate2D) { self.coordinate = coordinate - self.avatarData = avatarData - - super.init() + } +} + +class PinLocationAnnotation: LocationAnnotation {} + +class UserLocationAnnotation: LocationAnnotation { + + // MARK: - Properties + + let avatarData: AvatarInputProtocol + + // MARK: - Setup + + init(avatarData: AvatarInputProtocol, + coordinate: CLLocationCoordinate2D) { + + self.avatarData = avatarData + + super.init(coordinate: coordinate) } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift index f06d80562..346b458a1 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift @@ -19,14 +19,22 @@ import SwiftUI import Combine import CoreLocation +// This is the equivalent of MXEventAssetType in the MatrixSDK +enum LocationSharingCoordinateType { + case user + case pin +} + enum LocationSharingViewAction { case cancel case share + case sharePinLocation + case goToUserLocation } enum LocationSharingViewModelResult { case cancel - case share(latitude: Double, longitude: Double) + case share(latitude: Double, longitude: Double, coordinateType: LocationSharingCoordinateType) } enum LocationSharingViewError { @@ -45,17 +53,19 @@ struct LocationSharingViewState: BindableState { /// Current user avatarData let userAvatarData: AvatarInputProtocol - /// User map annotation to display existing location - let userAnnotation: UserLocationAnnotation? + /// Shared annotation to display existing location + let sharedAnnotation: LocationAnnotation? /// Map annotations to display on map - var annotations: [UserLocationAnnotation] + var annotations: [LocationAnnotation] /// Map annotation to focus on - var highlightedAnnotation: UserLocationAnnotation? + var highlightedAnnotation: LocationAnnotation? /// Indicates whether the user has moved around the map to drop a pin somewhere other than their current location - var isPinDropSharing: Bool = false + var isPinDropSharing: Bool { + return bindings.pinLocation != nil + } var showLoadingIndicator: Bool = false @@ -70,7 +80,7 @@ struct LocationSharingViewState: BindableState { } var displayExistingLocation: Bool { - return userAnnotation != nil + return sharedAnnotation != nil } var shareButtonEnabled: Bool { @@ -85,6 +95,7 @@ struct LocationSharingViewState: BindableState { struct LocationSharingViewStateBindings { var alertInfo: AlertInfo? var userLocation: CLLocationCoordinate2D? + var pinLocation: CLLocationCoordinate2D? } enum LocationSharingAlertType { diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift index 0c9b21853..ff439069d 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift @@ -38,6 +38,7 @@ enum MockLocationSharingScreenState: MockScreenState, CaseIterable { let viewModel = LocationSharingViewModel(mapStyleURL: mapStyleURL, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "alice:matrix.org", displayName: "Alice"), location: location, + coordinateType: .user, isLiveLocationSharingEnabled: true) return ([viewModel], AnyView(LocationSharingView(context: viewModel.context) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift index bccd95391..6295aab9c 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift @@ -35,21 +35,27 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie // MARK: - Setup - init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil, isLiveLocationSharingEnabled: Bool = false) { + init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil, coordinateType: LocationSharingCoordinateType, isLiveLocationSharingEnabled: Bool = false) { - var userAnnotation: UserLocationAnnotation? - var annotations: [UserLocationAnnotation] = [] - var highlightedAnnotation: UserLocationAnnotation? + var sharedAnnotation: LocationAnnotation? + var annotations: [LocationAnnotation] = [] + var highlightedAnnotation: LocationAnnotation? var showsUserLocation: Bool = false // Displaying an existing location - if let userCoordinate = location { - let userLocationAnnotation = UserLocationAnnotation(avatarData: avatarData, coordinate: userCoordinate) + if let sharedCoordinate = location { + let sharedLocationAnnotation: LocationAnnotation + switch coordinateType { + case .user: + sharedLocationAnnotation = UserLocationAnnotation(avatarData: avatarData, coordinate: sharedCoordinate) + case .pin: + sharedLocationAnnotation = PinLocationAnnotation(coordinate: sharedCoordinate) + } - annotations.append(userLocationAnnotation) - highlightedAnnotation = userLocationAnnotation + annotations.append(sharedLocationAnnotation) + highlightedAnnotation = sharedLocationAnnotation - userAnnotation = userLocationAnnotation + sharedAnnotation = sharedLocationAnnotation } else { // Share current location showsUserLocation = true @@ -57,7 +63,7 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie let viewState = LocationSharingViewState(mapStyleURL: mapStyleURL, userAvatarData: avatarData, - userAnnotation: userAnnotation, + sharedAnnotation: sharedAnnotation, annotations: annotations, highlightedAnnotation: highlightedAnnotation, showsUserLocation: showsUserLocation, @@ -79,8 +85,8 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie completion?(.cancel) case .share: // Share existing location - if let location = state.userAnnotation?.coordinate { - completion?(.share(latitude: location.latitude, longitude: location.longitude)) + if let location = state.sharedAnnotation?.coordinate { + completion?(.share(latitude: location.latitude, longitude: location.longitude, coordinateType: .user)) return } @@ -90,7 +96,16 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie return } - completion?(.share(latitude: location.latitude, longitude: location.longitude)) + completion?(.share(latitude: location.latitude, longitude: location.longitude, coordinateType: .user)) + case .sharePinLocation: + guard let pinLocation = state.bindings.pinLocation else { + processError(.failedLocatingUser) + return + } + + completion?(.share(latitude: pinLocation.latitude, longitude: pinLocation.longitude, coordinateType: .pin)) + case .goToUserLocation: + state.bindings.pinLocation = nil } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/Test/Unit/LocationSharingViewModelTests.swift b/RiotSwiftUI/Modules/Room/LocationSharing/Test/Unit/LocationSharingViewModelTests.swift index 299740112..2ba7899ec 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/Test/Unit/LocationSharingViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/Test/Unit/LocationSharingViewModelTests.swift @@ -35,7 +35,7 @@ class LocationSharingViewModelTests: XCTestCase { XCTAssertNotNil(viewModel.context.viewState.mapStyleURL) XCTAssertNotNil(viewModel.context.viewState.userAvatarData) - XCTAssertNil(viewModel.context.viewState.userAnnotation) + XCTAssertNil(viewModel.context.viewState.sharedAnnotation) XCTAssertNil(viewModel.context.viewState.bindings.userLocation) XCTAssertNil(viewModel.context.viewState.bindings.alertInfo) } @@ -63,7 +63,7 @@ class LocationSharingViewModelTests: XCTestCase { let viewModel = buildViewModel(withLocation: false) XCTAssertNil(viewModel.context.viewState.bindings.userLocation) - XCTAssertNil(viewModel.context.viewState.userAnnotation) + XCTAssertNil(viewModel.context.viewState.sharedAnnotation) viewModel.context.send(viewAction: .share) @@ -78,9 +78,9 @@ class LocationSharingViewModelTests: XCTestCase { viewModel.completion = { result in switch result { - case .share(let latitude, let longitude): - XCTAssertEqual(latitude, viewModel.context.viewState.userAnnotation?.coordinate.latitude) - XCTAssertEqual(longitude, viewModel.context.viewState.userAnnotation?.coordinate.longitude) + case .share(let latitude, let longitude, _): + XCTAssertEqual(latitude, viewModel.context.viewState.sharedAnnotation?.coordinate.latitude) + XCTAssertEqual(longitude, viewModel.context.viewState.sharedAnnotation?.coordinate.longitude) expectation.fulfill() case .cancel: XCTFail() @@ -88,7 +88,7 @@ class LocationSharingViewModelTests: XCTestCase { } XCTAssertNil(viewModel.context.viewState.bindings.userLocation) - XCTAssertNotNil(viewModel.context.viewState.userAnnotation) + XCTAssertNotNil(viewModel.context.viewState.sharedAnnotation) viewModel.context.send(viewAction: .share) @@ -123,6 +123,6 @@ class LocationSharingViewModelTests: XCTestCase { private func buildViewModel(withLocation: Bool) -> LocationSharingViewModel { LocationSharingViewModel(mapStyleURL: URL(string: "http://empty.com")!, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: ""), - location: (withLocation ? CLLocationCoordinate2D(latitude: 51.4932641, longitude: -0.257096) : nil)) + location: (withLocation ? CLLocationCoordinate2D(latitude: 51.4932641, longitude: -0.257096) : nil), coordinateType: .user) } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMapView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMapView.swift index 0ca25dc6b..5828e5d0c 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMapView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMapView.swift @@ -33,10 +33,10 @@ struct LocationSharingMapView: UIViewRepresentable { let tileServerMapURL: URL /// Map annotations - let annotations: [UserLocationAnnotation] + let annotations: [LocationAnnotation] /// Map annotation to focus on - let highlightedAnnotation: UserLocationAnnotation? + let highlightedAnnotation: LocationAnnotation? /// Current user avatar data, used to replace current location annotation view with the user avatar let userAvatarData: AvatarInputProtocol? @@ -47,6 +47,9 @@ struct LocationSharingMapView: UIViewRepresentable { /// Last user location if `showsUserLocation` has been enabled @Binding var userLocation: CLLocationCoordinate2D? + /// Coordinate of the center of the map + @Binding var mapCenterCoordinate: CLLocationCoordinate2D? + /// Publish view errors if any let errorSubject: PassthroughSubject @@ -68,7 +71,7 @@ struct LocationSharingMapView: UIViewRepresentable { mapView.setCenter(highlightedAnnotation.coordinate, zoomLevel: Constants.mapZoomLevel, animated: false) } - if self.showsUserLocation { + if self.showsUserLocation && mapCenterCoordinate == nil { mapView.showsUserLocation = true mapView.userTrackingMode = .follow } else { @@ -114,10 +117,12 @@ extension LocationSharingMapView { func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? { if let userLocationAnnotation = annotation as? UserLocationAnnotation { - return UserLocationAnnotatonView(userLocationAnnotation: userLocationAnnotation) - } else if annotation is MGLUserLocation, let currentUserAvatarData = locationSharingMapView.userAvatarData { - // Replace default current location annotation view with a UserLocationAnnotatonView - return UserLocationAnnotatonView(avatarData: currentUserAvatarData) + return LocationAnnotatonView(userLocationAnnotation: userLocationAnnotation) + } else if let pinLocationAnnotation = annotation as? PinLocationAnnotation { + return LocationAnnotatonView(pinLocationAnnotation: pinLocationAnnotation) + } else if annotation is MGLUserLocation && locationSharingMapView.mapCenterCoordinate == nil, let currentUserAvatarData = locationSharingMapView.userAvatarData { + // Replace default current location annotation view with a UserLocationAnnotatonView when the map is center on user location + return LocationAnnotatonView(avatarData: currentUserAvatarData) } return nil @@ -145,6 +150,16 @@ extension LocationSharingMapView { break } } + + func mapView(_ mapView: MGLMapView, regionDidChangeAnimated animated: Bool) { + let mapCenterCoordinate = mapView.centerCoordinate + // Prevent this function to set pinLocation when the map is openning + guard let userLocation = locationSharingMapView.userLocation, + !userLocation.isEqual(to: mapCenterCoordinate, precision: 0.0000000001) else { + return + } + locationSharingMapView.mapCenterCoordinate = mapCenterCoordinate + } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift index 3c36e7d50..3910b053f 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift @@ -40,6 +40,7 @@ struct LocationSharingMarkerView: View { markerImage .frame(width: 40, height: 40) } + .offset(x: 0, y: -23) } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift index ce3ae579c..430ffdfe5 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift @@ -33,13 +33,7 @@ struct LocationSharingView: View { var body: some View { NavigationView { ZStack(alignment: .bottom) { - LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, - annotations: context.viewState.annotations, - highlightedAnnotation: context.viewState.highlightedAnnotation, - userAvatarData: context.viewState.userAvatarData, - showsUserLocation: context.viewState.showsUserLocation, - userLocation: $context.userLocation, - errorSubject: context.viewState.errorSubject) + mapView VStack(spacing: 0) { MapCreditsView() if context.viewState.shareButtonVisible { @@ -85,6 +79,39 @@ struct LocationSharingView: View { .navigationViewStyle(StackNavigationViewStyle()) } + var mapView: some View { + ZStack(alignment: .topTrailing) { + ZStack(alignment: .center) { + LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, + annotations: context.viewState.annotations, + highlightedAnnotation: context.viewState.highlightedAnnotation, + userAvatarData: context.viewState.userAvatarData, + showsUserLocation: context.viewState.showsUserLocation, + userLocation: $context.userLocation, + mapCenterCoordinate: $context.pinLocation, + errorSubject: context.viewState.errorSubject) + if context.viewState.isPinDropSharing { + LocationSharingMarkerView(backgroundColor: theme.colors.accent) { + Image(uiImage: Asset.Images.locationPinIcon.image) + .resizable() + .shapedBorder(color: theme.colors.accent, borderWidth: 3, shape: Circle()) + } + } + } + Button { + context.send(viewAction: .goToUserLocation) + } label: { + Image(uiImage: Asset.Images.locationCenterMapIcon.image) + .foregroundColor(theme.colors.accent) + } + .padding(6.0) + .background(theme.colors.background) + .clipShape(RoundedCornerShape(radius: 4, corners: [.allCorners])) + .shadow(radius: 2.0) + .offset(x: -11.0, y: 52) + } + } + var buttonsView: some View { VStack(alignment: .leading, spacing: 15) { if !context.viewState.isPinDropSharing { @@ -107,7 +134,7 @@ struct LocationSharingView: View { } } else { LocationSharingOptionButton(text: VectorL10n.locationSharingPinDropShareTitle) { - // TODO: - Pin drop sharing action + context.send(viewAction: .sharePinLocation) } buttonIcon: { Image(uiImage: Asset.Images.locationPinIcon.image) .resizable() diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift index 15c8e0593..92395b483 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift @@ -19,7 +19,7 @@ import SwiftUI import Mapbox @available(iOS 14, *) -class UserLocationAnnotatonView: MGLUserLocationAnnotationView { +class LocationAnnotatonView: MGLUserLocationAnnotationView { // MARK: Private @@ -39,6 +39,14 @@ class UserLocationAnnotatonView: MGLUserLocationAnnotationView { super.init(annotation: userLocationAnnotation, reuseIdentifier: nil) self.addUserMarkerView(with: userLocationAnnotation.avatarData) + + } + + init(pinLocationAnnotation: PinLocationAnnotation) { + // TODO: Use a reuseIdentifier + super.init(annotation: pinLocationAnnotation, reuseIdentifier: nil) + + self.addPinMarkerView() } required init?(coder: NSCoder) { @@ -55,12 +63,26 @@ class UserLocationAnnotatonView: MGLUserLocationAnnotationView { }).view else { return } + addMarkerView(with: avatarImageView) + } + + private func addPinMarkerView() { + guard let pinImageView = UIHostingController(rootView: LocationSharingMarkerView(backgroundColor: theme.colors.accent) { + Image(uiImage: Asset.Images.locationPinIcon.image) + .resizable() + .shapedBorder(color: theme.colors.accent, borderWidth: 3, shape: Circle()) + }).view else { + return + } + addMarkerView(with: pinImageView) + } + + private func addMarkerView(with imageView: UIView) { + addSubview(imageView) - addSubview(avatarImageView) - - addConstraints([topAnchor.constraint(equalTo: avatarImageView.topAnchor), - leadingAnchor.constraint(equalTo: avatarImageView.leadingAnchor), - bottomAnchor.constraint(equalTo: avatarImageView.bottomAnchor), - trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor)]) + addConstraints([topAnchor.constraint(equalTo: imageView.topAnchor), + leadingAnchor.constraint(equalTo: imageView.leadingAnchor), + bottomAnchor.constraint(equalTo: imageView.bottomAnchor), + trailingAnchor.constraint(equalTo: imageView.trailingAnchor)]) } } diff --git a/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift b/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift index 8e9687c6a..03b868a83 100644 --- a/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift +++ b/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift @@ -251,6 +251,25 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy } } +extension MXRoom { + public var isMuted: Bool { + // Check whether an override rule has been defined with the roomm id as rule id. + // This kind of rule is created to mute the room + guard let rule = self.overridePushRule, + rule.actionsContains(actionType: MXPushRuleActionTypeDontNotify), + rule.conditionIsEnabled(kind: .eventMatch, for: roomId) else { + return false + } + return rule.enabled + } + + public var isMentionsOnly: Bool { + // Check push rules at room level + guard let rule = roomPushRule else { return false } + return rule.enabled && rule.actionsContains(actionType: MXPushRuleActionTypeDontNotify) + } +} + // We could move these to their own file and make available in global namespace or move to sdk but they are only used here at the moment fileprivate extension MXRoom { @@ -288,23 +307,6 @@ fileprivate extension MXRoom { return .all } - var isMuted: Bool { - // Check whether an override rule has been defined with the roomm id as rule id. - // This kind of rule is created to mute the room - guard let rule = self.overridePushRule, - rule.actionsContains(actionType: MXPushRuleActionTypeDontNotify), - rule.conditionIsEnabled(kind: .eventMatch, for: roomId) else { - return false - } - return rule.enabled - } - - var isMentionsOnly: Bool { - // Check push rules at room level - guard let rule = roomPushRule else { return false } - return rule.enabled && rule.actionsContains(actionType: MXPushRuleActionTypeDontNotify) - } - } fileprivate extension MXPushRule { diff --git a/Tools/SwiftGen/Templates/Strings/flat-swift4-vector.stencil b/Tools/SwiftGen/Templates/Strings/flat-swift4-vector.stencil index f76780d24..3e3e6f594 100644 --- a/Tools/SwiftGen/Templates/Strings/flat-swift4-vector.stencil +++ b/Tools/SwiftGen/Templates/Strings/flat-swift4-vector.stencil @@ -64,7 +64,7 @@ import Foundation extension {{className}} { static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "") + let format = NSLocalizedString(key, tableName: table, bundle: Bundle.app, comment: "") let locale: Locale if let providedLocale = LocaleProvider.locale { @@ -77,7 +77,6 @@ extension {{className}} { } } -private final class BundleToken {} {% else %} // No string found {% endif %} diff --git a/changelog.d/1575.bugfix b/changelog.d/1575.bugfix deleted file mode 100644 index 609b0150d..000000000 --- a/changelog.d/1575.bugfix +++ /dev/null @@ -1 +0,0 @@ -Jitsi: fix app not leaving call when widget is removed diff --git a/changelog.d/4842.bugfix b/changelog.d/4842.bugfix deleted file mode 100644 index 4e7ef2c03..000000000 --- a/changelog.d/4842.bugfix +++ /dev/null @@ -1 +0,0 @@ -Space preview shows wrong number of members diff --git a/changelog.d/4858.bugfix b/changelog.d/4858.bugfix deleted file mode 100644 index 2a7d342e8..000000000 --- a/changelog.d/4858.bugfix +++ /dev/null @@ -1 +0,0 @@ -Room: Enable joining a room via identifier from another home server diff --git a/changelog.d/5058.bugfix b/changelog.d/5058.bugfix deleted file mode 100644 index 8254bddd2..000000000 --- a/changelog.d/5058.bugfix +++ /dev/null @@ -1 +0,0 @@ -MXKRoomDataSource: Fix retain cycle diff --git a/changelog.d/5134.bugfix b/changelog.d/5134.bugfix deleted file mode 100644 index 74df83c35..000000000 --- a/changelog.d/5134.bugfix +++ /dev/null @@ -1 +0,0 @@ -Sync Spaces order with web \ No newline at end of file diff --git a/changelog.d/5170.bugfix b/changelog.d/5170.bugfix deleted file mode 100644 index 1ef0fceb3..000000000 --- a/changelog.d/5170.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix “It is not possible to join an empty room” on some suggested rooms. diff --git a/changelog.d/5488.change b/changelog.d/5488.change deleted file mode 100644 index e1b4dc675..000000000 --- a/changelog.d/5488.change +++ /dev/null @@ -1 +0,0 @@ -Threads: Strip `ìn reply to` from thread summaries and latest messages. diff --git a/changelog.d/5604.change b/changelog.d/5604.change deleted file mode 100644 index 23bb078ab..000000000 --- a/changelog.d/5604.change +++ /dev/null @@ -1 +0,0 @@ -Room: New loading indicators when joining room diff --git a/changelog.d/5606.change b/changelog.d/5606.change deleted file mode 100644 index 15c4fcd84..000000000 --- a/changelog.d/5606.change +++ /dev/null @@ -1 +0,0 @@ -Room: New loading indicators when creating a room diff --git a/changelog.d/5651.wip b/changelog.d/5651.wip deleted file mode 100644 index d5f2f46bb..000000000 --- a/changelog.d/5651.wip +++ /dev/null @@ -1 +0,0 @@ -Onboarding: Add celebration screen after display name and avatar screens. \ No newline at end of file diff --git a/changelog.d/5652.feature b/changelog.d/5652.feature new file mode 100644 index 000000000..c0b93a678 --- /dev/null +++ b/changelog.d/5652.feature @@ -0,0 +1 @@ +Onboarding: Enable profile personalisation screens after registration. diff --git a/changelog.d/5720.change b/changelog.d/5720.change deleted file mode 100644 index 0b0eeee50..000000000 --- a/changelog.d/5720.change +++ /dev/null @@ -1 +0,0 @@ -Location Sharing: Update UI on location sharing view diff --git a/changelog.d/5770.feature b/changelog.d/5770.feature deleted file mode 100644 index c46dd12ea..000000000 --- a/changelog.d/5770.feature +++ /dev/null @@ -1 +0,0 @@ -RoomViewController: Display threads notice if not displayed before. diff --git a/changelog.d/5771.change b/changelog.d/5771.change deleted file mode 100644 index cef75bd46..000000000 --- a/changelog.d/5771.change +++ /dev/null @@ -1,2 +0,0 @@ -Update suggested room preview to behave the same way in all cases - diff --git a/changelog.d/5797.bugfix b/changelog.d/5797.bugfix deleted file mode 100644 index df2986a5d..000000000 --- a/changelog.d/5797.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed "Add Space" error message diff --git a/changelog.d/5810.change b/changelog.d/5810.change deleted file mode 100644 index 63585a270..000000000 --- a/changelog.d/5810.change +++ /dev/null @@ -1 +0,0 @@ -Add "Invite people" to the space menu in the left panel and update menu order \ No newline at end of file diff --git a/changelog.d/5837.change b/changelog.d/5837.change deleted file mode 100644 index 59904919e..000000000 --- a/changelog.d/5837.change +++ /dev/null @@ -1 +0,0 @@ -Allow empty Jitsi default URL in BuildSettings diff --git a/changelog.d/5870.bugfix b/changelog.d/5870.bugfix deleted file mode 100644 index 7708f0b2d..000000000 --- a/changelog.d/5870.bugfix +++ /dev/null @@ -1 +0,0 @@ -VoiceMessagePlainCell: Fix cell height by adding missing thread summary displayable conformance. diff --git a/changelog.d/5875.bugfix b/changelog.d/5875.bugfix deleted file mode 100644 index cbd4c0699..000000000 --- a/changelog.d/5875.bugfix +++ /dev/null @@ -1 +0,0 @@ -Authentication: Ensure the login button is always visible diff --git a/changelog.d/5883.bugfix b/changelog.d/5883.bugfix deleted file mode 100644 index 27400193c..000000000 --- a/changelog.d/5883.bugfix +++ /dev/null @@ -1,2 +0,0 @@ -Search: prevent crash when searching for rooms - diff --git a/changelog.d/5898.change b/changelog.d/5898.change deleted file mode 100644 index 9d83c6009..000000000 --- a/changelog.d/5898.change +++ /dev/null @@ -1 +0,0 @@ -Restrict UI components on authentication screen to readable width diff --git a/changelog.d/5906.bugfix b/changelog.d/5906.bugfix deleted file mode 100644 index 6015bc061..000000000 --- a/changelog.d/5906.bugfix +++ /dev/null @@ -1 +0,0 @@ -Room: Fix typing performance by avoiding expensive UI operations diff --git a/changelog.d/5911.bugfix b/changelog.d/5911.bugfix deleted file mode 100644 index edbb6c62b..000000000 --- a/changelog.d/5911.bugfix +++ /dev/null @@ -1 +0,0 @@ -The "Swipe to see all rooms" hint is sometimes presented at the wrong time diff --git a/changelog.d/5915.bugfix b/changelog.d/5915.bugfix deleted file mode 100644 index 88733d6ff..000000000 --- a/changelog.d/5915.bugfix +++ /dev/null @@ -1 +0,0 @@ -Push notifications: show space preview if user taps invite notification diff --git a/changelog.d/5933.change b/changelog.d/5933.change new file mode 100644 index 000000000..87e48b73c --- /dev/null +++ b/changelog.d/5933.change @@ -0,0 +1 @@ +Display presence indicator on home, DM list & details diff --git a/changelog.d/5935.i18n b/changelog.d/5935.i18n deleted file mode 100644 index 1d306244d..000000000 --- a/changelog.d/5935.i18n +++ /dev/null @@ -1 +0,0 @@ -Translations: Enable all languages rather than waiting for an 80% translation. diff --git a/changelog.d/5938.bugfix b/changelog.d/5938.bugfix deleted file mode 100644 index 929aff34c..000000000 --- a/changelog.d/5938.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix session handling of the call presenter. diff --git a/changelog.d/5943.bugfix b/changelog.d/5943.bugfix deleted file mode 100644 index ceae52674..000000000 --- a/changelog.d/5943.bugfix +++ /dev/null @@ -1 +0,0 @@ -m.room.join_rules not properly set for private access \ No newline at end of file diff --git a/changelog.d/5948.bugfix b/changelog.d/5948.bugfix deleted file mode 100644 index 09e891482..000000000 --- a/changelog.d/5948.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix for app occasionally getting stuck during launch after Login/Register. diff --git a/changelog.d/pr-5910.api b/changelog.d/pr-5910.api deleted file mode 100644 index ff9523166..000000000 --- a/changelog.d/pr-5910.api +++ /dev/null @@ -1 +0,0 @@ -Remove unused Bindings in RoundedBorderTextField/Editor \ No newline at end of file diff --git a/changelog.d/pr-5926.bugfix b/changelog.d/pr-5926.bugfix deleted file mode 100644 index f80a17cc2..000000000 --- a/changelog.d/pr-5926.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed the regular expression used for link detection in attributed strings. \ No newline at end of file