diff --git a/CHANGES.md b/CHANGES.md index 4a47e03b7..47fafd5a4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,26 @@ +## Changes in 0.16.8 (2021-10-20) + +✨ Features + +- M10.4.1 Home space data filtering ([#4570](https://github.com/vector-im/element-ios/issues/4570)) + +🙌 Improvements + +- Upgrade MatrixSDK version ([v0.20.8](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.20.8)). +- MXKRecentCellDataStoring: New initializer & `roomIdentifier` and `avatarUrl` properties. ([#4384](https://github.com/vector-im/element-ios/issues/4384)) +- MXKContactManager: The contacts manager will no longer present a prompt for contacts access for you. This should be done elsewhere. ([#4484](https://github.com/vector-im/element-ios/issues/4484)) + +🐛 Bugfixes + +- MXKRoomInputToolbarView: Fix crash when pasting images backed by NSData (such as WebP from Safari). ([#2076](https://github.com/vector-im/element-ios/issues/2076)) +- MXKContactManager: Add an MXSession parameter to validateSyncLocalContactsState and call from MXKAccount. ([#4989](https://github.com/vector-im/element-ios/issues/4989)) + +⚠️ API Changes + +- MXKRecentsDataSource & MXKSessionRecentsDataSource: Remove `markAllAsRead` methods. ([#4384](https://github.com/vector-im/element-ios/issues/4384)) +- MXKAccount: Remove unused showDecryptedContentInNotifications property. ([#4519](https://github.com/vector-im/element-ios/issues/4519)) + + ## Changes in 0.16.7 (2021-10-13) 🙌 Improvements diff --git a/MatrixKit.podspec b/MatrixKit.podspec index 39b76ac77..81dbaa557 100644 --- a/MatrixKit.podspec +++ b/MatrixKit.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixKit" - s.version = "0.16.7" + s.version = "0.16.8" s.summary = "The Matrix reusable UI library for iOS based on MatrixSDK." s.description = <<-DESC @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.swift_version = '5.0' - s.dependency 'MatrixSDK', "= 0.20.7" + s.dependency 'MatrixSDK', "= 0.20.8" s.dependency 'HPGrowingTextView', '~> 1.1' s.dependency 'libPhoneNumber-iOS', '~> 0.9.13' s.dependency 'DTCoreText', '~> 1.6.25' diff --git a/MatrixKit.xcodeproj/project.pbxproj b/MatrixKit.xcodeproj/project.pbxproj index 4a563a6ea..c9ad84cb4 100644 --- a/MatrixKit.xcodeproj/project.pbxproj +++ b/MatrixKit.xcodeproj/project.pbxproj @@ -373,6 +373,7 @@ 8878281C260C85BB00429B35 /* MXKEventFormatter+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MXKEventFormatter+Tests.h"; sourceTree = ""; }; 8C751E43C4D87B309065E3C8 /* Pods-MatrixKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MatrixKitTests/Pods-MatrixKitTests.release.xcconfig"; sourceTree = ""; }; 9135FFD826DE8EFD000E6D84 /* NSString+MatrixKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+MatrixKit.swift"; sourceTree = ""; }; + 915B171C27105C5700225111 /* MXKAnalyticsConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXKAnalyticsConstants.h; sourceTree = ""; }; 918DAB9E26E622BF00CE20A9 /* NSAttributedString+MatrixKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+MatrixKit.swift"; sourceTree = ""; }; 91FE762A27047EB700E035D9 /* MXKURLPreviewDataProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXKURLPreviewDataProtocol.h; sourceTree = ""; }; 92663A6A1EF6E5B3005FB712 /* MXKSoundPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXKSoundPlayer.h; sourceTree = ""; }; @@ -1060,6 +1061,7 @@ 32BA86B421538B35008F277E /* EventFormatter */, F02D21471B7109950002DE01 /* MXKConstants.h */, F02D21481B7109950002DE01 /* MXKConstants.m */, + 915B171C27105C5700225111 /* MXKAnalyticsConstants.h */, F0F148C41AB31240005F5D4A /* MXKTools.h */, F0F148C51AB31240005F5D4A /* MXKTools.m */, F0F535BC1ACD748E00B603F8 /* MXKResponderRageShaking.h */, diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/es.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/es.lproj/MatrixKit.strings index 5e9e413fc..b8d1695da 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/es.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/es.lproj/MatrixKit.strings @@ -4,7 +4,7 @@ "login_server_url_placeholder" = "URL (p.ej. https://matrix.org)"; "login_home_server_title" = "Servidor Local:"; "login_home_server_info" = "Tu servidor local almacena todas tus conversaciones y los datos de tu cuenta"; -"login_identity_server_title" = "URL de Servidor de Identidades:"; +"login_identity_server_title" = "URL de servidor de identidad:"; "login_identity_server_info" = "Matrix proporciona servidores de identidades para rastrear qué correos electrónicos, etc. pertenecen a qué IDs de Matrix. Actualmente solo existe https://matrix.org."; "login_user_id_placeholder" = "ID de Matrix (p.ej. @juan:matrix.org o juan)"; "login_password_placeholder" = "Contraseña"; @@ -82,7 +82,7 @@ "notice_event_redacted_by" = " por %@"; "notice_event_redacted_reason" = " [motivo: %@]"; "notice_profile_change_redacted" = "%@ actualizó su perfil %@"; -"notice_room_created" = "%@ creó la sala"; +"notice_room_created" = "%@ ha creado y configurado la sala."; "notice_room_join_rule" = "La regla para unirse es: %@"; "notice_room_power_level_intro" = "El nivel de permisos de los miembros de la sala es:"; "notice_room_power_level_acting_requirement" = "Los niveles de permisos mínimos que un usuario debe tener antes de actuar son:"; @@ -184,7 +184,7 @@ // Room "room_please_select" = "Por favor selecciona una sala"; "room_error_join_failed_title" = "No se pudo unir a la sala"; -"room_error_join_failed_empty_room" = "Actualmente no es posible volver a unirse a una sala vacía."; +"room_error_join_failed_empty_room" = "Ahora mismo no es posible volver a unirse a una sala vacía."; "room_error_name_edition_not_authorized" = "No estás autorizado a editar el nombre de esta sala"; "room_error_topic_edition_not_authorized" = "No estás autorizado a editar el tema de esta sala"; "room_error_cannot_load_timeline" = "No se pudo cargar la línea de tiempo"; @@ -204,10 +204,10 @@ "room_member_power_level_prompt" = "No podrás deshacer este cambio porque estás promoviendo al usuario para tener el mismo nivel de autoridad que tú.\n¿Estás seguro?"; // Attachment "attachment_size_prompt" = "Quieres enviar como:"; -"attachment_original" = "Tamaño Real: %@"; -"attachment_small" = "Pequeño: %@"; -"attachment_medium" = "Mediano: %@"; -"attachment_large" = "Grande: %@"; +"attachment_original" = "Tamaño real: %@"; +"attachment_small" = "Pequeño (~%@)"; +"attachment_medium" = "Mediano (~%@)"; +"attachment_large" = "Grande (~%@)"; "attachment_cancel_download" = "¿Cancelar la descarga?"; "attachment_cancel_upload" = "¿Cancelar la subida?"; "attachment_multiselection_size_prompt" = "Quieres enviar imágenes como:"; @@ -381,3 +381,19 @@ "device_details_rename_prompt_title" = "Nombre de Sesión"; "account_error_push_not_allowed" = "No se permite notificaciones"; "notice_room_third_party_revoked_invite" = "%@ revocó la invitación para %@ de unirse a la sala"; +"attachment_size_prompt_message" = "Puedes desactivar esto en ajustes."; +"attachment_size_prompt_title" = "Confirma el tamaño para enviar"; +"message_reply_to_sender_sent_a_voice_message" = "ha enviado un mensaje de voz."; +"room_left_for_dm" = "Te has salido"; +"room_displayname_all_other_members_left" = "%@ (ha salido)"; +"notice_room_join_rule_public_by_you_for_dm" = "Has hecho esta conversación pública."; +"notice_room_join_rule_public_by_you" = "Has hecho la sala pública."; +"notice_room_join_rule_public_for_dm" = "%@ ha hecho esta conversación pública."; +"notice_room_join_rule_public" = "%@ ha hecho pública la sala."; +"notice_room_join_rule_invite_by_you" = "Has hecho que solo se pueda unir a la sala por invitación."; +"notice_room_name_removed_for_dm" = "%@ ha quitado el nombre"; +"notice_room_created_for_dm" = "%@ se ha unido."; +"notice_room_join_rule_invite_for_dm" = "%@ ha hecho que solo sea posible unirse por invitación."; +// New +"notice_room_join_rule_invite" = "%@ ha hecho que la sala solo sea accesible por invitación."; +"resume_call" = "Volver a la llamada"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings index 764771f03..017cbbe88 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings @@ -470,3 +470,9 @@ "attachment_size_prompt_message" = "Seadistustest saad määrata, et see funktsionaalsus pole kasutusel."; "attachment_size_prompt_title" = "Saatmiseks kinnita meedia suurus"; "room_displayname_all_other_participants_left" = "%@ (lahkus(id))"; +"auth_reset_password_error_not_found" = "Pole leitav"; +"auth_reset_password_error_unauthorized" = "Tegevus pole lubatud"; +"auth_username_in_use" = "Selline kasutajanimi on juba olemas"; +"auth_invalid_user_name" = "Vigane kasutajanimi"; +"rename" = "Muuda nime"; +"room_displayname_all_other_members_left" = "%@ (lahkus(id))"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings index 6857bdde1..758c3a3cb 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings @@ -470,3 +470,6 @@ "attachment_small_with_resolution" = "Petit %@ (~%@)"; "attachment_size_prompt_message" = "Vous pouvez désactiver ceci dans les paramètres."; "attachment_size_prompt_title" = "Préciser la taille pour l’envoi"; +"auth_username_in_use" = ""; +"auth_invalid_user_name" = "Nom d’utilisateur invalide"; +"rename" = "Renommer"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings index 2eb16bd4a..1bf93bad0 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings @@ -19,8 +19,8 @@ "login_email_placeholder" = "E-mail cím"; "login_prompt_email_token" = "Kérlek add meg az e-mail érvényesítő kódot:"; "login_error_title" = "A bejelentkezés sikertelen"; -"login_error_no_login_flow" = "Nem sikerült letölteni az azonosítási információkat erről a Saját szerverről"; -"login_error_do_not_support_login_flows" = "Jelenleg nem támogatunk egyetlen bejelentkezési sémát sem azok közül amit a Saját szerver ismer"; +"login_error_no_login_flow" = "Nem sikerült letölteni az azonosítási információkat erről a saját szerverről"; +"login_error_do_not_support_login_flows" = "Jelenleg nem támogatunk egyetlen bejelentkezési sémát sem azok közül amit a saját szerver ismer"; "login_error_registration_is_not_supported" = "A regisztráció jelenleg nem támogatott"; "login_error_forbidden" = "Érvénytelen felhasználói név/jelszó"; "login_error_unknown_token" = "A megadott hozzáférési kód nem ismert"; @@ -471,3 +471,9 @@ "attachment_size_prompt_message" = "Ezt a beállításokban kikapcsolhatod."; "attachment_size_prompt_title" = "Méret megerősítése küldéshez"; "room_displayname_all_other_participants_left" = "%@ (Bal)"; +"auth_reset_password_error_not_found" = "Nem található"; +"auth_reset_password_error_unauthorized" = "Nem engedélyezett"; +"auth_username_in_use" = "A felhasználónév foglalt"; +"auth_invalid_user_name" = "Érvénytelen felhasználónév"; +"rename" = "Átnevez"; +"room_displayname_all_other_members_left" = "%@ (Bal)"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings new file mode 100644 index 000000000..3bee04d44 --- /dev/null +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings @@ -0,0 +1,557 @@ + + +"auth_username_in_use" = "Nama pengguna telah dipakai"; +"invite" = "Undang"; +"rename" = "Ubah Nama"; +"view" = "Tampilkan"; +"cancel" = "Batalkan"; +"leave" = "Tinggalkan"; +"save" = "Simpan"; +"notice_room_power_level_intro_for_dm" = "Level kekuatan anggota pesan langsung adalah:"; +"notice_room_power_level_intro" = "Level kekuatan anggota ruangan adalah:"; +"notice_room_join_rule_public_by_you_for_dm" = "Anda membuat pesan langsung ini publik."; +"notice_room_join_rule_public_by_you" = "Anda membuat ruangan ini publik."; +"notice_room_join_rule_public_for_dm" = "%@ membuat pesan langsung ini publik."; +"notice_room_join_rule_public" = "%@ membuat ruangan ini publik."; +"notice_room_join_rule_invite_by_you_for_dm" = "Anda membuat pesan langsung ini undangan saja."; +"notice_room_join_rule_invite_by_you" = "Anda membuat ruangan ini undangan saja."; +"notice_room_join_rule_invite_for_dm" = "%@ membuat pesan langsung ini undangan saja."; +// New +"notice_room_join_rule_invite" = "%@ membuat ruangan ini undangan saja."; +// Old +"notice_room_join_rule" = "Peraturan bergabung adalah: %@"; +"notice_room_created_for_dm" = "%@ bergabung."; +"notice_room_created" = "%@ membuat dan mengatur ruangan ini."; +"notice_profile_change_redacted" = "%@ memperbarui profilnya %@"; +"notice_event_redacted_reason" = " [alasan: %@]"; +"notice_event_redacted_by" = " dari %@"; +"notice_event_redacted" = ""; +"notice_room_topic_removed" = "%@ menghapus topik ruangan"; +"notice_room_name_removed_for_dm" = "%@ menghapus nama pesan langsung"; +"notice_room_name_removed" = "%@ menghapus nama ruangan"; + +// Events formatter +"notice_avatar_changed_too" = "(avatar juga diganti)"; +"unignore" = "Hapus Pengabaian"; +"ignore" = "Abaikan"; +"resume_call" = "Lanjutkan"; +"end_call" = "Akhiri Panggilan"; +"reject_call" = "Tolak Panggilan"; +"answer_call" = "Jawab Panggilan"; +"show_details" = "Tampilkan Detail"; +"cancel_upload" = "Batal Mengunggah"; +"cancel_download" = "Batal Mengunduh"; +"select_all" = "Pilih Semua"; +"resend_message" = "Kirim ulang pesan"; +"reset_to_default" = "Atur ulang ke bawaan"; +"invite_user" = "Undang pengguna Matrix"; +"capture_media" = "Ambil Foto/Video"; +"attach_media" = "Lampirkan Media dari Library"; +"select_account" = "Pilih sebuah akun"; +"mention" = "Sebutan"; +"start_video_call" = "Mulai Panggilan Video"; +"start_voice_call" = "Mulai Panggilan Suara"; +"start_chat" = "Mulai Mengobrol"; +"set_moderator" = "Tetapkan Moderator"; +"set_admin" = "Tetapkan Admin"; +"set_power_level" = "Atur Level Kekuatan"; +"set_default_power_level" = "Atur Ulang Level Kekuatan"; +"submit_code" = "Kirim kode"; +"submit" = "Kirim"; +"sign_up" = "Daftar"; +"retry" = "Coba Lagi"; +"dismiss" = "Lupakan"; +"discard" = "Buang"; +"continue" = "Lanjutkan"; +"close" = "Tutup"; +"back" = "Kembali"; +"abort" = "Batalkan"; +"yes" = "Ya"; + +// Action +"no" = "Tidak"; +"login_error_resource_limit_exceeded_contact_button" = "Hubungi Administrator"; +"login_error_resource_limit_exceeded_message_contact" = "\n\nSilakan hubungi service homeserver Anda untuk melanjutkan menggunakan perangkat ini."; +"login_error_resource_limit_exceeded_message_monthly_active_user" = "Homeserver ini telah mencapai batas Pengguna Aktif Bulanan."; +"login_error_resource_limit_exceeded_message_default" = "Homeserver ini telah melebihi batas sumbernya."; +"login_error_resource_limit_exceeded_title" = "Melebihi Batas Sumber"; +"login_desktop_device" = "Desktop"; +"login_tablet_device" = "Tablet"; +"login_mobile_device" = "Mobile"; +"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"; +"login_leave_fallback" = "Batalkan"; +"login_use_fallback" = "Gunakan halaman fallback"; +"login_error_login_email_not_yet" = "Tautan email yang belum diklik"; +"login_error_user_in_use" = "Nama pengguna ini sudah dipakai"; +"login_error_limit_exceeded" = "Terlalu banyak permintaan yang dikirim"; +"login_error_not_json" = "Tidak mengandung JSON yang valid"; +"login_error_unknown_token" = "Token akses yang ditentukan tidak diketahui"; +"login_error_bad_json" = "JSON cacat"; +"login_error_forbidden" = "Nama pengguna/kata sandi tidak valid"; +"login_error_registration_is_not_supported" = "Pendaftaran saat ini tidak didukung"; +"login_error_do_not_support_login_flows" = "Saat ini kami tidak mendukung salah satu atau semua alur masuk yang ditentukan oleh homeserver ini"; +"login_error_no_login_flow" = "Kami gagal untuk menerima informasi otentikasi dari homeserver ini"; +"login_error_title" = "Login Gagal"; +"login_prompt_email_token" = "Harap masukkan token validasi email Anda:"; +"login_email_placeholder" = "Alamat email"; +"login_email_info" = "Menentukan alamat email memungkinkan pengguna lain untuk menemukan Anda di Matrix dengan lebih mudah, dan akan memberi Anda cara untuk menyetel ulang sandi di masa mendatang."; +"login_display_name_placeholder" = "Nama tampilan (mis. Bob Obson)"; +"login_optional_field" = "opsional"; +"login_password_placeholder" = "Kata sandi"; +"login_user_id_placeholder" = "ID Matrix (mis. @bob:matrix.org atau bob)"; +"login_identity_server_info" = "Matrix menyediakan server identitas untuk melacak email mana, dll., milik ID Matrix mana. Hanya https://matrix.org yang saat ini ada."; +"login_identity_server_title" = "URL server identitas:"; +"login_home_server_info" = "Homeserver Anda menyimpan semua pesan Anda dan data akun"; +"login_home_server_title" = "URL Homeserver:"; +"login_server_url_placeholder" = "URL (mis. https://matrix.org)"; + +// Login Screen +"login_create_account" = "Buat akun:"; +/* *********************** */ +/* iOS specific */ +/* *********************** */ + +"matrix" = "Matrix"; +"auth_reset_password_error_not_found" = "Tidak ditemukan"; +"auth_reset_password_error_unauthorized" = "Tidak diotorisasi"; +"auth_invalid_user_name" = "Nama pengguna tidak valid"; +"ssl_only_accept" = "HANYA terima sertifikat jika administrator server telah mempublikasikan sidik jari yang cocok dengan sidik jari di atas."; +"ssl_expected_existing_expl" = "Sertifikat ini telah berubah dari yang sebelumnya tepercaya menjadi yang tidak tepercaya. Servernya mungkin telah memperbarui sertifikatnya. Hubungi administrator server untuk sidik jari yang diharapkan."; +"ssl_unexpected_existing_expl" = "Sertifikat ini telah berubah dari yang dipercaya oleh ponsel Anda. Ini SANGAT TIDAK BIASA. Anda disarankan untuk TIDAK MENERIMA sertifikat baru ini."; +"ssl_cert_new_account_expl" = "Jika administrator server mengatakan bahwa ini diharapkan, pastikan bahwa sidik jari di bawah ini cocok dengan sidik jari yang disediakannya."; +"ssl_cert_not_trust" = "Ini bisa berarti bahwa seseorang mencegat lalu lintas Anda, atau bahwa ponsel Anda tidak mempercayai sertifikat yang disediakan oleh server jarak jauh."; +"ssl_could_not_verify" = "Tidak dapat memverifikasi identitas server jarak jauh."; +"ssl_fingerprint_hash" = "Sidik Jari (%@):"; +"ssl_remain_offline" = "Abaikan"; +"ssl_logout_account" = "Keluar"; + +// unrecognized SSL certificate +"ssl_trust" = "Percayai"; +"call_transfer_to_user" = "Pindahkan ke %@"; +"call_consulting_with_user" = "Mengkonsultasi dengan %@"; +"call_video_with_user" = "Panggilan video dengan %@"; +"call_voice_with_user" = "Panggilan suara dengan %@"; +"call_more_actions_dialpad" = "Tombol penyetel"; +"call_more_actions_transfer" = "Pindahkan"; +"call_more_actions_audio_use_device" = "Speaker Perangkat"; +"call_more_actions_change_audio_device" = "Ubah Perangkat Audio"; +"call_more_actions_unhold" = "Lanjutkan"; +"call_more_actions_hold" = "Jeda"; +"call_holded" = "Anda menjeda panggilan ini"; +"call_remote_holded" = "%@ menjeda panggilan ini"; +"call_invite_expired" = "Undangan Panggilan Kedaluwarsa"; +"incoming_voice_call" = "Masuk Panggilan Suara"; +"incoming_video_call" = "Masuk Panggilan Video"; +"call_ended" = "Panggilan diakhiri"; +"call_ringing" = "Berdering…"; + +// Settings keys + +// call string +"call_connecting" = "Menghubungkan…"; +"settings_config_user_id" = "ID Pengguna: %@"; +"settings_config_identity_server" = "Server identitas: %@"; + +// gcm section +"settings_config_home_server" = "Homeserver: %@"; +"notification_settings_notify_all_other" = "Beritahu untuk semua pesan/ruangan lainnya"; +"notification_settings_by_default" = "Secara default..."; +"notification_settings_suppress_from_bots" = "Jangan beritahu saya tentang notifikasi dari bot"; +"notification_settings_receive_a_call" = "Beritahu saya ketika saya menerima panggilan"; +"notification_settings_people_join_leave_rooms" = "Beritahu saya ketika ada orang bergabung atau meninggalkan ruangan"; +"notification_settings_invite_to_a_new_room" = "Beritahu saya ketika saya diundang ke ruangan baru"; +"notification_settings_just_sent_to_me" = "Beritahu saya dengan suara tentang pesan yang baru saja dikirim ke saya"; +"notification_settings_contain_my_display_name" = "Beritahu saya dengan suara tentang pesan yang berisi nama tampilan saya"; +"notification_settings_contain_my_user_name" = "Beritahu saya dengan suara tentang pesan yang berisi nama pengguna saya"; +"notification_settings_other_alerts" = "Pemberitahuan Lainnya"; +"notification_settings_select_room" = "Pilih sebuah ruangan"; +"notification_settings_sender_hint" = "@pengguna:domain.com"; +"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_word_to_match" = "kata untuk dicocokkan"; +"notification_settings_never_notify" = "Jangan diberitahu"; +"notification_settings_always_notify" = "Selalu diberitahu"; +"notification_settings_per_word_info" = "Kata-kata tidak cocok dengan huruf besar-kecil, dan mungkin menyertakan karakter pengganti *. Jadi:\nfoo cocok dengan string foo yang dikelilingi oleh pembatas kata (misalnya tanda baca dan spasi atau awal/akhir baris).\nfoo* cocok dengan kata apa pun yang dimulai foo.\n*foo* cocok dengan kata apa pun yang menyertakan 3 huruf foo."; +"notification_settings_per_word_notifications" = "Notifikasi per kata"; +"notification_settings_global_info" = "Pengaturan notifikasi disimpan ke akun pengguna Anda dan dibagikan di antara semua client yang mendukungnya (termasuk pemberitahuan desktop).\n\nAturan diterapkan secara berurutan; aturan pertama yang cocok menentukan hasil untuk pesan.\nJadi: Notifikasi per kata lebih penting daripada notifikasi per ruangan yang lebih penting daripada notifikasi per pengirim.\nUntuk beberapa aturan dengan jenis yang sama, yang pertama dalam daftar yang cocok akan diprioritaskan."; +"notification_settings_enable_notifications_warning" = "Semua notifikasi saat ini dinonaktifkan untuk semua perangkat."; +"notification_settings_enable_notifications" = "Aktifkan notifikasi"; + +// Notification settings screen +"notification_settings_disable_all" = "Nonaktifkan semua notifikasi"; +"settings_title_notifications" = "Notifikasi"; + +// Settings screen +"settings_title_config" = "Konfigurasi"; + +// members list Screen + +// accounts list Screen + +// image size selection + +// invitation members list Screen + +// room creation dialog Screen + +// room info dialog Screen + +// room details dialog screen +"room_details_title" = "Detail Ruangan"; +"login_error_must_start_http" = "URL harus dimulai dengan http[s]://"; + +// Login Screen +"login_error_already_logged_in" = "Sudah masuk"; +"message_unsaved_changes" = "Ada perubahan yang belum disimpan. Meninggalkannya akan membuang mereka."; +"unban" = "Hilangkan Cekalan"; +"ban" = "Cekal"; +"kick" = "Keluarkan"; +"num_members_other" = "%@ pengguna"; +"num_members_one" = "%@ pengguna"; +"membership_ban" = "Dicekal"; +"membership_leave" = "Keluar"; +"membership_invite" = "Diundang"; +"create_account" = "Buat Akun"; +"create_room" = "Buat Ruangan"; +"login" = "Masuk"; + +// actions +"action_logout" = "Keluar"; +"delete" = "Hapus"; +"share" = "Bagikan"; +"redact" = "Hapus"; +"resend" = "Kirim Ulang"; +"copy_button_name" = "Salin"; +"send" = "Kirim"; + +// 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 +"ok" = "OK"; +"notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "Anda membuat sejarah pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka bergabung."; +"notice_room_history_visible_to_members_from_joined_point_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruang, sejak mereka bergabung."; +"notice_encryption_enabled_unknown_algorithm_by_you" = "Anda mengaktifkan enkripsi ujung-ke-ujung (algoritma %@ tidak dikenal)."; +"notice_room_third_party_revoked_invite" = "%@ menghilangkan undangannya %@ untuk bergabung ke ruangan ini"; +"notice_room_third_party_revoked_invite_by_you" = "Anda menghilangkan undangannya %@ untuk bergabung ke ruangan ini"; +"account_email_validation_error" = "Tidak dapat memverifikasi alamat email. Silakan cek email Anda dan tekan tautannya yang ada. Setelah selesai, tekan lanjut"; + +// contacts list screen +"invitation_message" = "Saya ingin berkomunikasi dengan Anda dengan Matrix. Silakan kunjungi ke websitenya di https://matrix.org untuk informasi selanjutnya."; +"notice_room_history_visible_to_members_from_invited_point_by_you_for_dm" = "Anda membuat sejarah pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka diundang."; +"notice_room_history_visible_to_members_from_invited_point_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruangan, sejak mereka diundang."; +"notice_room_history_visible_to_members_by_you_for_dm" = "Anda membuat pesan di masa depan dapat dilihat oleh semua anggota ruangan."; +"notice_room_history_visible_to_members_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruangan."; +"notice_room_history_visible_to_anyone_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh siapa saja."; +"notice_redaction_by_you" = "Anda menghapus sebuah peristiwa (id: %@)"; +"notice_encryption_enabled_ok_by_you" = "Anda mengaktifkan enkripsi ujung-ke-ujung."; +"notice_room_created_by_you_for_dm" = "Anda bergabung."; +"notice_room_created_by_you" = "Anda membuat dan mengatur ruangan ini."; +"notice_profile_change_redacted_by_you" = "Anda memperbarui profil Anda %@"; +"notice_event_redacted_by_you" = " oleh Anda"; +"notice_room_topic_removed_by_you" = "Anda menghilangkan topik ruangan ini"; +"notice_room_name_removed_by_you_for_dm" = "Anda menghilangkan nama ruangan ini"; +"notice_room_name_removed_by_you" = "Anda menghilangkan nama ruangan ini"; +"notice_conference_call_request_by_you" = "Anda telah meminta konferensi VoIP"; +"notice_declined_video_call_by_you" = "Anda menolak anggilannya"; +"notice_ended_video_call_by_you" = "Anda mengakhiri pangilannya"; +"notice_answered_video_call_by_you" = "Anda menjawab panggilannya"; +"notice_placed_video_call_by_you" = "Anda melakukan panggilan video"; +"notice_placed_voice_call_by_you" = "Anda melakukan panggilan suara"; +"notice_room_name_changed_by_you_for_dm" = "Anda mengubah nama ruangan ini ke%@."; +"notice_room_name_changed_by_you" = "Anda mengubah nama ruangan ini ke %@."; +"notice_topic_changed_by_you" = "Anda mengubah topik ruangan nini ke \"%@\"."; +"notice_display_name_removed_by_you" = "Anda menghilangkan nama tampilan Anda"; +"notice_display_name_changed_from_by_you" = "Anda mengubah nama tampilan Anda dari %@ ke %@"; +"notice_display_name_set_by_you" = "Anda mengubah nama tampilan Anda ke %@"; +"notice_avatar_url_changed_by_you" = "Anda mengubah avatar Anda"; +"notice_room_withdraw_by_you" = "Anda menghilangkan undangannya %@"; +"notice_room_ban_by_you" = "Anda mencekal %@"; +"notice_room_unban_by_you" = "Anda menghilangkan cekalan %@"; +"notice_room_kick_by_you" = "Anda mengeluarkan %@"; +"notice_room_reject_by_you" = "Anda menolak undangannya"; +"notice_room_leave_by_you" = "Anda keluar"; +"notice_room_join_by_you" = "Anda bergabung"; +"notice_room_third_party_revoked_invite_by_you_for_dm" = "Anda menghilangkan undangannya %@"; +"notice_room_third_party_registered_invite_by_you" = "Anda menerima undangan untuk %@"; +"notice_room_third_party_invite_by_you_for_dm" = "Anda mengundang %@"; +"notice_room_third_party_invite_by_you" = "Anda mengirim sebuah undangan ke @% untuk bergabung ke ruangan ini"; +"notice_room_invite_you" = "%@ mengundang Anda"; + +// Notice Events with "You" +"notice_room_invite_by_you" = "Anda mengundang %@"; +"notice_conference_call_finished" = "Konferensi VoIP diakhiri"; +"notice_conference_call_started" = "Konferensi VoIP dimulai"; +"notice_conference_call_request" = "%@ telah meminta konferensi VoIP"; +"notice_declined_video_call" = "%@ menolak panggilannya"; +"notice_ended_video_call" = "%@ mengakhiri panggilannya"; +"notice_answered_video_call" = "%@ menjawab panggilannya"; +"notice_placed_video_call" = "%@ melakukan panggilan video"; +"notice_placed_voice_call" = "%@ melakukan panggilan suara"; +"notice_room_name_changed_for_dm" = "%@ mengubah nama ruangan ini ke %@."; +"notice_room_name_changed" = "%@ mengubah nama ruangan ini ke %@."; +"notice_topic_changed" = "%@ mengubah topik ruangan ini ke \"%@\"."; +"notice_display_name_removed" = "%@ menghilangkan nama tampilannya"; +"notice_display_name_changed_from" = "%@ mengubah nama tampilannya dari %@ ke %@"; +"notice_display_name_set" = "%@ mengubah nama tampilannya ke %@"; +"notice_avatar_url_changed" = "%@ mengubah avatarnya"; +"notice_room_reason" = ". Alasan: %@"; +"notice_room_withdraw" = "%@ menghilangkan undangannya %@"; +"notice_room_ban" = "%@ mencekal %@"; +"notice_room_unban" = "%@ menghilangkan cekalan %@"; +"notice_room_kick" = "%@ mengeluarkan %@"; +"notice_room_reject" = "%@ menolak undangannya"; +"notice_room_leave" = "%@ keluar"; +"notice_room_join" = "%@ bergabung"; +"notice_room_third_party_revoked_invite_for_dm" = "%@ menghilangkan undangannya %@"; +"notice_room_third_party_registered_invite" = "%@ menerima undangan untuk %@"; +"notice_room_third_party_invite_for_dm" = "%@ mengundang %@"; +"notice_room_third_party_invite" = "%@ mengirim sebuah undangan ke %@ untuk bergabung ke ruangan ini"; + +/* -*- + 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" = "%@ mengundang %@"; +"language_picker_default_language" = "Bawaan (%@)"; + +// Language picker +"language_picker_title" = "Pilih sebuah bahasa"; + +// Country picker +"country_picker_title" = "Pilih sebuah negara"; +"microphone_access_not_granted_for_voice_message" = "Pesan suara membutuhkan akses ke Mikrofon tetapi %@ tidak memiliki izin untuk menggunakannya"; +"local_contacts_access_discovery_warning" = "Untuk menemukan kontak Anda yang sudah menggunakan Matrix, %@ dapat mengirim alamat email dan nomor telepon di kontak Anda ke server identitas Matrix yang Anda pilih. Di mana saja yang didukung, data personal akan di-hash sebelum dikirim - mohon cek kebijakan privasi identitas server Anda untuk detail lainnya."; +"local_contacts_access_discovery_warning_title" = "Penemuan pengguna"; +"local_contacts_access_not_granted" = "Penemuan pengguna dari kontak lokal membutuhkan akses ke kontak Anda tetapi %@ tidak memiliki izin untuk menggunakannya"; +"microphone_access_not_granted_for_call" = "Panggilan membutuhkan akses ke Mikrofon tetapi %@ tidak memiliki izin untuk menggunakannya"; + +// Permissions +"camera_access_not_granted_for_call" = "Panggilan video membutuhkan akses ke Kamera tetapi %@ tidak memiliki izin untuk menggunakannya"; +"ssl_homeserver_url" = "URL Homeserver: %@"; +"user_id_placeholder" = "misal: @bob:homeserver"; +"network_error_not_reachable" = "Mohon cek koneksi jaringan Anda"; +"power_level" = "Level Kekuatan"; +"public" = "Publik"; +"private" = "Privat"; +"default" = "bawaan"; +"not_supported_yet" = "Belum didukung"; +"error_common_message" = "Sebuah kesalahan terjadi. Coba lagi nanti."; +"error" = "Gagal"; +"unsent" = "Belum Terkirim"; +"offline" = "offline"; + +// Others +"user_id_title" = "ID Pangguna:"; +"e2e_passphrase_create" = "Buat frasa sandi"; +"e2e_passphrase_not_match" = "Frasa sandi harus cocok"; +"e2e_passphrase_too_short" = "Frasa sandi terlalu pendek (Harus minimal %d karakter panjangnya)"; +"e2e_passphrase_empty" = "Frasa sandi tidak boleh kosong"; +"e2e_passphrase_confirm" = "Konfirmasi frasa sandi"; +"e2e_export" = "Ekspor"; +"e2e_export_prompt" = "Proses ini memungkinkan Anda untuk mengekspor kunci untuk pesan yang Anda telah terima di ruangan terenkripsi ke file lokal. Anda nanti akan dapat mengimpor filenya ke client Matrix lainnya di masa mendatang, supaya client itu juga bisa mendekripsi pesan yang terenkripsi.\nFile yang diekspor akan memungkinan siapa saja yang dapat membaca untuk mendekripsikan pesan terenkripsi apa saja yang Anda bisa lihat, jadi Anda harus berhati-hati untuk menyimpannya secara aman."; + +// E2E export +"e2e_export_room_keys" = "Ekspor kunci ruangan"; +"e2e_passphrase_enter" = "Masukkan frasa sandi"; +"e2e_import" = "Impor"; +"e2e_import_prompt" = "Proses ini memungkinkan Anda untuk mengimpor kunci enkripsi yang Anda punya sebelumnya yang diekspor dari client Matrix lain. Anda nanti akan dapat mendekripsi pesan apa saja yang client lain dapat mendekripsinya.\nFile yang diekspor dilindungi dengan frasa sandi. Anda seharusnya masukkan frasa sandinya di sini, untuk mendekripsi filenya."; + +// E2E import +"e2e_import_room_keys" = "Impor kunci ruangan"; +"format_time_d" = "h"; +"format_time_h" = "j"; +"format_time_m" = "m"; + +// Time +"format_time_s" = "d"; +"search_searching" = "Pencarian sedang dilakukan..."; + +// Search +"search_no_results" = "Tidak Ada Hasil"; +"group_section" = "Grup"; + +// Groups +"group_invite_section" = "Undangan"; +"contact_local_contacts" = "Kontak Local"; + +// Contacts +"contact_mx_users" = "Pengguna Matrix"; +"attachment_e2e_keys_import" = "Impor..."; +"attachment_e2e_keys_file_prompt" = "File ini berisi kunci enkripsi yang diimpor dari client Matrix lain.\nApakah Anda ingin menampilkan konten file atau impor kunci yang berisi?"; +"attachment_multiselection_original" = "Ukuran Sebenarnya"; +"attachment_multiselection_size_prompt" = "Apakah Anda ingin mengirim gambarnya sebagai:"; +"attachment_cancel_upload" = "Batalkan unggahannya?"; +"attachment_cancel_download" = "Batalkan unduhannya?"; +"attachment_large_with_resolution" = "Besar %@ (~%@)"; +"attachment_medium_with_resolution" = "Sedang %@ (~%@)"; +"attachment_small_with_resolution" = "Kecil %@ (~%@)"; +"attachment_large" = "Besar (~%@)"; +"attachment_medium" = "Sedang (~%@)"; +"attachment_small" = "Kecil (~%@)"; +"attachment_original" = "Ukuran Sebenarnya (%@)"; +"attachment_size_prompt_message" = "Anda dapat menonaktifkannya di pengaturan."; +"attachment_size_prompt_title" = "Konfirmasi ukuran untuk dikirim"; + +// Attachment +"attachment_size_prompt" = "Apakah Anda ingin mengirimnya sebagai:"; +"room_member_power_level_prompt" = "Anda tidak akan lagi membatalkan perubahan ini ketika Anda mempromosikan penggunanya untuk memiliki level kekuatan yang sama dengan Anda sendiri.\nApakah Anda yakin?"; + +// Room members +"room_member_ignore_prompt" = "Apakah Anda yakin untuk menyembunyikan semua pesan dari pengguna ini?"; +"message_reply_to_message_to_reply_to_prefix" = "Membalas ke"; +"message_reply_to_sender_sent_a_file" = "mengirim sebuah file."; +"message_reply_to_sender_sent_a_voice_message" = "mengirim sebuah pesan suara."; +"message_reply_to_sender_sent_an_audio_file" = "mengirim sebuah file audio."; +"message_reply_to_sender_sent_a_video" = "mengirim sebuah video."; + +// Reply to message +"message_reply_to_sender_sent_an_image" = "mengirim sebuah gambar."; +"room_no_conference_call_in_encrypted_rooms" = "Panggilan konferensi tidak didukung di ruangan terenkripsi"; +"room_no_power_to_create_conference_call" = "Anda membutuhkan izin untuk mengundang untuk memulai konferensi di ruangan ini"; +"room_left_for_dm" = "Anda keluar"; +"room_left" = "Anda meninggalkan ruangan ini"; +"room_error_timeline_event_not_found" = "Aplikasi ini sedang mencoba untuk memuat titik tertenu di linimasa ruangan ini tetapi tidak dapat menemukannya"; +"room_error_timeline_event_not_found_title" = "Gagal untuk memuat posisi linimasa"; +"room_error_cannot_load_timeline" = "Gagal untuk memuat linimasa"; +"room_error_topic_edition_not_authorized" = "Anda tidak diizinkan untuk mengubah topik ruangan ini"; +"room_error_name_edition_not_authorized" = "Anda tidak diizinkan untuk mengubah nama ruangan ini"; +"room_error_join_failed_empty_room" = "Saat ini tidak mungkin untuk bergabung ke ruangan yang kosong."; +"room_error_join_failed_title" = "Gagal untuk bergabung ke ruangan"; + +// Room +"room_please_select" = "Silakan pilih sebuah ruangan"; +"room_creation_participants_placeholder" = "(mis. @bob:homeserver1; @john:homeserver2...)"; +"room_creation_participants_title" = "Anggota:"; +"room_creation_alias_placeholder_with_homeserver" = "(mis. #foo%@)"; +"room_creation_alias_placeholder" = "(mis. #foo:example.org)"; +"room_creation_alias_title" = "Alias ruangan:"; +"room_creation_name_placeholder" = "(mis. grupMakanSiang)"; + +// Room creation +"room_creation_name_title" = "Nama ruangan:"; +"account_error_push_not_allowed" = "Notifikasi tidak diizinkan"; +"account_error_msisdn_wrong_description" = "Ini sepertinya bukan nomor telepon yang valid"; +"account_error_msisdn_wrong_title" = "Nomor Telepon Tidak Valid"; +"account_error_email_wrong_description" = "Ini sepertinya bukan alamat email yang valid"; +"account_error_email_wrong_title" = "Alamat Email Tidak Valid"; +"account_error_matrix_session_is_not_opened" = "Sesi Matrix tidak dibuka"; +"account_error_picture_change_failed" = "Penggantian gambar gagal"; +"account_error_display_name_change_failed" = "Penggantian nama tampilan gagal"; +"account_msisdn_validation_error" = "Tidak dapat memverifikasi nomor telepon."; +"account_msisdn_validation_message" = "Kami telah mengirim sebuah SMS dengan kode aktivasi. Silakan masukkan kodenya di bawah."; +"account_msisdn_validation_title" = "Menunggu Verifikasi"; +"account_email_validation_message" = "Silakan cek email Anda dan tekan tautannya yang ada. Setelah selesai, tekan lanjut."; +"account_email_validation_title" = "Menunggu Verifikasi"; +"account_linked_emails" = "Email yang tertaut"; +"account_link_email" = "Tautkan Email"; + +// Account +"account_save_changes" = "Simpan perubahan"; +"room_event_encryption_verify_ok" = "Verifikasi"; +"room_event_encryption_verify_message" = "Untuk memverifikasi bahwa sesi ini dapat dipercaya, harap hubungi pemiliknya menggunakan cara lain (misalnya secara langsung atau melalui panggilan telepon) dan tanyakan apakah kunci yang mereka lihat di Pengaturan Pengguna untuk sesi ini cocok dengan kunci di bawah ini:\n\n\tNama sesi: %@\n\tID sesi: %@\n\tKunci sesi: %@\n\nJika cocok, tekan tombol verifikasi di bawah. Jika tidak, maka orang lain mencegat sesi ini dan Anda mungkin ingin menekan tombol daftar hitam sebagai gantinya.\n\nDi masa yang mendatang proses verifikasi ini akan semakin canggih."; +"room_event_encryption_verify_title" = "Verifikasi sesi\n\n"; +"room_event_encryption_info_unblock" = "Hilangkan dari daftar hitam"; +"room_event_encryption_info_block" = "Tambahkan ke daftar hitam"; +"room_event_encryption_info_unverify" = "Hilangkan verifikasi"; +"room_event_encryption_info_verify" = "Verifikasi..."; +"room_event_encryption_info_device_blocked" = "Di dalam daftar hitam"; +"room_event_encryption_info_device_not_verified" = "TIDAK terverifikasi"; +"room_event_encryption_info_device_verified" = "Terverifikasi"; +"room_event_encryption_info_device_fingerprint" = "Sidik jari Ed25519\n"; +"room_event_encryption_info_device_verification" = "Verifikasi\n"; +"room_event_encryption_info_device_id" = "ID\n"; +"room_event_encryption_info_device_name" = "Nama Publik\n"; +"room_event_encryption_info_device_unknown" = "sesi tidak dikenal\n"; +"room_event_encryption_info_device" = "\nInformasi sesi pengirim\n"; +"room_event_encryption_info_event_none" = "tidak ada"; +"room_event_encryption_info_event_unencrypted" = "tidak terenkripsi"; +"room_event_encryption_info_event_decryption_error" = "Kesalahan saat mendekripsi\n"; +"room_event_encryption_info_event_session_id" = "ID Sesi\n"; +"room_event_encryption_info_event_algorithm" = "Algoritma\n"; +"room_event_encryption_info_event_fingerprint_key" = "Mendapatkan kunci sidik jari Ed25519\n"; +"room_event_encryption_info_event_identity_key" = "Kunci identitas Curve25519\n"; +"room_event_encryption_info_event_user_id" = "ID Pengguna\n"; +"room_event_encryption_info_event" = "Informasi peristiwa\n"; + +// Encryption information +"room_event_encryption_info_title" = "Informasi enkripsi ujung-ke-ujung\n\n"; +"device_details_delete_prompt_message" = "Operasi ini membutuhkan otentikasi tambahan.\nUntuk melanjutkan, silakan masukkan kata sandi Anda."; +"device_details_delete_prompt_title" = "Otentikasi"; +"device_details_rename_prompt_message" = "Nama publik sesi dapat dilihat oleh orang yang berkomunikasi dengan Anda"; +"device_details_rename_prompt_title" = "Nama Sesi"; +"device_details_last_seen_format" = "%@ @ %@\n"; +"device_details_last_seen" = "Terakhir dilihat\n"; +"device_details_identifier" = "ID\n"; +"device_details_name" = "Nama Publik\n"; + +// Devices +"device_details_title" = "Informasi sesi\n"; +"notification_settings_room_rule_title" = "Ruangan: '%@'"; +"settings_enter_validation_token_for" = "Masukkan token validasi untuk %@:"; +"settings_enable_push_notifications" = "Aktifkan notifikasi push"; +"settings_enable_inapp_notifications" = "Aktifkan notifikasi di dalam aplikasi"; + +// Settings +"settings" = "Pengaturan"; +"room_displayname_all_other_members_left" = "%@ (Keluar)"; +"room_displayname_more_than_two_members" = "%@ dan %@ lainnya"; +"room_displayname_two_members" = "%@ dan %@"; + +// room display name +"room_displayname_empty_room" = "Ruangan kosong"; +"notice_in_reply_to" = "Membalas ke"; +"notice_sticker" = "stiker"; +"notice_crypto_error_unknown_inbound_session_id" = "Sesi pengirim belum mengirim kami kunci untuk pesan ini."; +"notice_crypto_unable_to_decrypt" = "** Tidak dapat mendekripsi: %@ **"; +"notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ membuat pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka bergabung."; +"notice_room_history_visible_to_members_from_invited_point_for_dm" = "%@ membuat sejarah pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka diundang."; +"notice_room_history_visible_to_members_from_joined_point" = "%@ membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruangan, sejak mereka bergabung."; +"notice_room_history_visible_to_anyone" = "%@ membuat sejarah ruangan di masa mendatang dapat dilihat oleh siapa saja."; +"notice_room_history_visible_to_members" = "%@ membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruangan."; +"notice_room_history_visible_to_members_for_dm" = "%@ membuat semua pesan di masa mendatang dapat dilihat oleh semua anggota ruangan."; +"notice_room_history_visible_to_members_from_invited_point" = "%@ membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruang, sejak mereka diundang."; +"notice_error_unknown_event_type" = "Tipe peristiwa yang tidak dikenal"; +"notice_error_unexpected_event" = "Peristiwa yang tidak terduga"; +"notice_error_unsupported_event" = "Peristiwa yang tidak didukung"; +"notice_redaction" = "%@ menghapus sebuah peristiwa (id: %@)"; +"notice_feedback" = "Peristiwa umpan balik (id: %@): %@"; +"notice_unsupported_attachment" = "Lampiran yang tidak didukung: %@"; +"notice_invalid_attachment" = "lampiran tidak valid"; +"notice_file_attachment" = "lampiran file"; +"notice_location_attachment" = "lampiran lokasi"; +"notice_video_attachment" = "lampiran video"; +"notice_audio_attachment" = "lampiran audio"; +"notice_image_attachment" = "lampiran gambar"; +"notice_encryption_enabled_unknown_algorithm" = "%1$@ mengaktifkan enkripsi ujung-ke-ujung (algoritma %2$@ tidak dikenal)."; +"notice_encryption_enabled_ok" = "%@ mengaktifkan enkripsi ujung-ke-ujung."; +"notice_encrypted_message" = "Pesan terenkripsi"; +"notice_room_related_groups" = "Grup yang terkait dengan ruangan ini adalah: %@"; +"notice_room_aliases_for_dm" = "Aliasnya adalah: %@"; +"notice_room_aliases" = "Alias ruangannya adalah: %@"; +"notice_room_power_level_event_requirement" = "Tingkat daya minimum yang terkait dengan peristiwa adalah:"; +"notice_room_power_level_acting_requirement" = "Tingkat daya minimum yang harus dimiliki pengguna sebelum bertindak adalah:"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings index 540b6766e..630520ca6 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings @@ -14,8 +14,8 @@ "login_email_placeholder" = "Indirizzo email"; "login_prompt_email_token" = "Inserisci il token di validazione della tua email:"; "login_error_title" = "Accesso fallito"; -"login_error_no_login_flow" = "Impossibile ottenere i dati di autenticazione da questo Home Server"; -"login_error_do_not_support_login_flows" = "Al momento non è supportato alcuno dei flussi di accesso definiti da questo Home Server"; +"login_error_no_login_flow" = "Impossibile ottenere i dati di autenticazione da questo homeserver"; +"login_error_do_not_support_login_flows" = "Al momento non è supportato alcuno dei flussi di accesso definiti da questo homeserver"; "login_error_registration_is_not_supported" = "La registrazione non è consentita al momento"; "login_error_forbidden" = "Nome utente o password errati"; "login_error_unknown_token" = "Il token di accesso inserito non è stato riconosciuto"; @@ -470,3 +470,9 @@ "attachment_small_with_resolution" = "Piccolo %@ (~%@)"; "attachment_size_prompt_message" = "Puoi disattivarlo nelle impostazioni."; "attachment_size_prompt_title" = "Conferma dimensione da inviare"; +"auth_reset_password_error_not_found" = "Non trovato"; +"auth_reset_password_error_unauthorized" = "Non autorizzato"; +"auth_invalid_user_name" = "Nome utente non valido"; +"room_displayname_all_other_members_left" = "%@ (Uscito)"; +"auth_username_in_use" = "Nome utente in uso"; +"rename" = "Rinomina"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings index 4e2aff510..19b5d5cc3 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings @@ -4,7 +4,7 @@ "login_server_url_placeholder" = "URL (e.g. https://matrix.org)"; "login_home_server_title" = "URL de Servidorcasa:"; "login_home_server_info" = "Seu servidorcasa armazena todas as suas conversas e dados de conta"; -"login_identity_server_title" = "URL de Servidor de Identidade:"; +"login_identity_server_title" = "URL de servidor de identidade:"; "login_identity_server_info" = "Matrix provê servidores de identidade para rastrear quais emails, etc. pertencem a quais IDs Matrix. Somente https://matrix.org existe atualmente."; "login_user_id_placeholder" = "ID Matrix (e.g. @bob:matrix.org ou bob)"; "login_password_placeholder" = "Senha"; @@ -14,9 +14,9 @@ "login_email_placeholder" = "Endereço de email"; "login_prompt_email_token" = "Por favor entre seu token de validação de email:"; "login_error_title" = "Login Falhou"; -"login_error_no_login_flow" = "Nós falhamos para recuperar informação de autenticação deste Servidor de Casa"; +"login_error_no_login_flow" = "Nós falhamos para recuperar informação de autenticação deste servidorcasa"; "view" = "Visualizar"; -"login_error_do_not_support_login_flows" = "Atualmente nós não suportamos qualquer ou todos os fluxos de login definidos por este Servidor de Casa"; +"login_error_do_not_support_login_flows" = "Atualmente nós não suportamos qualquer ou todos os fluxos de login definidos por este servidorcasa"; "back" = "Voltar"; "continue" = "Continuar"; "leave" = "Sair"; @@ -323,7 +323,7 @@ // room details dialog screen "room_details_title" = "Detalhes de Sala"; // contacts list screen -"invitation_message" = "Eu gostaria de fazer chat com você com matrix. Por favor, visite o website http://matrix.org para ter mais informação."; +"invitation_message" = "Eu gostaria de conversar com você com matrix. Por favor, visite o website http://matrix.org para ter mais informação."; // Settings screen "settings_title_config" = "Configuração"; "settings_title_notifications" = "Notificações"; @@ -471,3 +471,9 @@ "attachment_size_prompt_message" = "Você pode desligar isto em configurações."; "attachment_size_prompt_title" = "Confirmar tamanho para enviar"; "room_displayname_all_other_participants_left" = "%@ (Saiu)"; +"auth_reset_password_error_not_found" = "Não encontrado"; +"auth_reset_password_error_unauthorized" = "Não-autorizada(o)"; +"auth_username_in_use" = "Nome de usuária(o) em uso"; +"auth_invalid_user_name" = "Nome de usuária(o) inválido"; +"rename" = "Renomear"; +"room_displayname_all_other_members_left" = "%@ (Saiu)"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/ru.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/ru.lproj/MatrixKit.strings index 0f7fa76c8..53403ae12 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/ru.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/ru.lproj/MatrixKit.strings @@ -4,7 +4,7 @@ "login_server_url_placeholder" = "URL (например https://matrix.org)"; "login_home_server_title" = "URL домашнего сервера:"; "login_home_server_info" = "Ваш домашний сервер хранит все ваши разговоры и данные о аккаунте"; -"login_identity_server_title" = "URL сервера идентификации:"; +"login_identity_server_title" = "Cервер идентификации URL:"; "login_identity_server_info" = "Серверы идентификации Matrix обеспечивают определение соответствия между email и Matrix ID. В настоящее время существует только https://matrix.org."; "login_user_id_placeholder" = "Matrix ID (например, @bob:matrix.org или bob)"; "login_password_placeholder" = "Пароль"; @@ -181,7 +181,7 @@ // Room creation "room_creation_name_title" = "Название комнаты:"; "login_use_fallback" = "Использовать резервную страницу"; -"login_error_do_not_support_login_flows" = "В настоящее время мы не поддерживаем один или несколько потоков авторизации, определенных данным домашним сервером"; +"login_error_do_not_support_login_flows" = "В настоящее время мы не поддерживаем потоки авторизации, определенных данным домашним сервером"; "login_error_forgot_password_is_not_supported" = "\"Забытый пароль\" в настоящее время не поддерживается"; "notice_event_redacted" = "<отредактировано%@>"; "notice_event_redacted_by" = " от %@"; @@ -458,7 +458,7 @@ "notice_declined_video_call" = "%@ отменил(а) этот вызов"; "resume_call" = "Возобновить"; "call_transfer_to_user" = "Передача с %@"; -"call_consulting_with_user" = "Общение с %@"; +"call_consulting_with_user" = "Консультация с %@"; "call_video_with_user" = "Видеовызов с %@"; "call_voice_with_user" = "Голосовой вызов с %@"; "call_ringing" = "Звонок…"; @@ -470,3 +470,9 @@ "attachment_small_with_resolution" = "Маленький %@ (~%@)"; "attachment_size_prompt_message" = "Это можно отключить в настройках."; "attachment_size_prompt_title" = "Подтвердите размер для отправки"; +"auth_reset_password_error_not_found" = "Не найдено"; +"auth_reset_password_error_unauthorized" = "Неавторизованный"; +"auth_invalid_user_name" = "Недопустимое имя пользователя"; +"auth_username_in_use" = "Имя пользователя занято"; +"rename" = "Переименовать"; +"room_displayname_all_other_members_left" = "%@ (Вышел)"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings index 1103320c5..48323eea3 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings @@ -470,3 +470,8 @@ "attachment_small_with_resolution" = "E vogël %@ (~%@)"; "attachment_size_prompt_message" = "Këtë mund ta çaktivizoni te rregullimet."; "attachment_size_prompt_title" = "Ripohoni madhësi për dërgim"; +"auth_reset_password_error_not_found" = "S’u gjet"; +"auth_reset_password_error_unauthorized" = "I paautorizuar"; +"auth_username_in_use" = "Emër përdoruesi i përdorur"; +"auth_invalid_user_name" = "Emër i pavlefshëm përdoruesi"; +"rename" = "Riemërtojeni"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings index eb60f71c5..28bb81299 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings @@ -504,3 +504,18 @@ "notice_answered_video_call" = "%@ відповідає на виклик"; "notice_placed_video_call" = "%@ здійснює відеовиклик"; "notice_placed_voice_call" = "%@ здійснює голосовий виклик"; + +// Room members +"room_member_ignore_prompt" = "Ви впевнені, що хочете сховати всі повідомлення від цього користувача?"; +"room_no_conference_call_in_encrypted_rooms" = "Кімнати з шифруванням не підтримують конференцвиклики"; +"room_error_topic_edition_not_authorized" = "Ви не маєте повноважень змінювати тему цієї кімнати"; +"room_error_name_edition_not_authorized" = "Ви не маєте повноважень змінювати назву цієї кімнати"; +"room_error_join_failed_empty_room" = "На цю мить неможливо приєднатися до порожньої кімнати."; +"room_creation_alias_placeholder_with_homeserver" = "(напр. #foo%@)"; +"room_creation_alias_placeholder" = "(напр. #foo:example.org)"; +"account_email_validation_message" = "Перевірте свою електронну пошту та натисніть на посилання у ній. Після цього натисніть кнопку Продовжити."; +"room_displayname_all_other_members_left" = "%@ (виходять)"; +"auth_username_in_use" = "Ім'я користувача зайняте"; +"rename" = "Перейменувати"; +"room_creation_alias_title" = "Псевдоніми кімнати:"; +"account_email_validation_error" = "Не вдалося перевірити адресу електронної пошти. Перевірте свою електронну пошту та натисніть на посилання в ній. Після цього натисніть продовжити"; diff --git a/MatrixKit/Assets/MatrixKitAssets.bundle/zh_Hans.lproj/MatrixKit.strings b/MatrixKit/Assets/MatrixKitAssets.bundle/zh_Hans.lproj/MatrixKit.strings index d21f5812c..b1a270dd2 100644 --- a/MatrixKit/Assets/MatrixKitAssets.bundle/zh_Hans.lproj/MatrixKit.strings +++ b/MatrixKit/Assets/MatrixKitAssets.bundle/zh_Hans.lproj/MatrixKit.strings @@ -92,8 +92,8 @@ "notice_invalid_attachment" = "无效附件"; "notice_unsupported_attachment" = "不支持的附件:%@"; "login_email_info" = "指定邮箱地址可以让其他 Matrix 用户更容易找到您,并允许您可以在未来重置密码。"; -"login_error_no_login_flow" = "从此主服务器获取认证信息失败"; -"login_error_do_not_support_login_flows" = "当前我们不支持任何或者所有此主服务器定义的登录流"; +"login_error_no_login_flow" = "我们未能从此主服务器获取认证信息"; +"login_error_do_not_support_login_flows" = "当前我们不支持此主服务器定义的任何或者所有登录流"; "notice_feedback" = "反馈事件 (id: %@):%@"; "notice_redaction" = "%@ 取消了一个事件 (id: %@)"; "notice_error_unsupported_event" = "不支持的事件"; @@ -472,3 +472,9 @@ "attachment_size_prompt_message" = "你可以在设置中关闭这个。"; "attachment_size_prompt_title" = "确认要发送的大小"; "room_displayname_all_other_participants_left" = "%@ (离开)"; +"auth_reset_password_error_not_found" = "未找到"; +"auth_reset_password_error_unauthorized" = "未经授权"; +"auth_invalid_user_name" = "用户名无效"; +"room_displayname_all_other_members_left" = "%@ (离开)"; +"auth_username_in_use" = "用户名被占用"; +"rename" = "重命名"; diff --git a/MatrixKit/Controllers/MXKRecentListViewController.m b/MatrixKit/Controllers/MXKRecentListViewController.m index c086358ef..2ba7ae6c2 100644 --- a/MatrixKit/Controllers/MXKRecentListViewController.m +++ b/MatrixKit/Controllers/MXKRecentListViewController.m @@ -440,11 +440,14 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath id recentCellData = (id)cellData; if (recentCellData.isSuggestedRoom) { - [_delegate recentListViewController:self didSelectSuggestedRoom:recentCellData.spaceChildInfo]; + [_delegate recentListViewController:self + didSelectSuggestedRoom:recentCellData.roomSummary.spaceChildInfo]; } else { - [_delegate recentListViewController:self didSelectRoom:recentCellData.roomSummary.roomId inMatrixSession:recentCellData.roomSummary.mxSession]; + [_delegate recentListViewController:self + didSelectRoom:recentCellData.roomIdentifier + inMatrixSession:recentCellData.mxSession]; } } } diff --git a/MatrixKit/Generated/Strings.swift b/MatrixKit/Generated/Strings.swift index eeb79aef1..7f4279e3e 100644 --- a/MatrixKit/Generated/Strings.swift +++ b/MatrixKit/Generated/Strings.swift @@ -519,7 +519,7 @@ public class MatrixKitL10n: NSObject { public static var loginErrorBadJson: String { return MatrixKitL10n.tr("login_error_bad_json") } - /// Currently we do not support any or all login flows defined by this Home Server + /// Currently we do not support any or all login flows defined by this homeserver public static var loginErrorDoNotSupportLoginFlows: String { return MatrixKitL10n.tr("login_error_do_not_support_login_flows") } @@ -543,7 +543,7 @@ public class MatrixKitL10n: NSObject { public static var loginErrorMustStartHttp: String { return MatrixKitL10n.tr("login_error_must_start_http") } - /// We failed to retrieve authentication information from this Home Server + /// We failed to retrieve authentication information from this homeserver public static var loginErrorNoLoginFlow: String { return MatrixKitL10n.tr("login_error_no_login_flow") } @@ -599,7 +599,7 @@ public class MatrixKitL10n: NSObject { public static var loginIdentityServerInfo: String { return MatrixKitL10n.tr("login_identity_server_info") } - /// Identity Server URL: + /// Identity server URL: public static var loginIdentityServerTitle: String { return MatrixKitL10n.tr("login_identity_server_title") } diff --git a/MatrixKit/MatrixKitVersion.m b/MatrixKit/MatrixKitVersion.m index 513bffb4c..7b342370b 100644 --- a/MatrixKit/MatrixKitVersion.m +++ b/MatrixKit/MatrixKitVersion.m @@ -16,4 +16,4 @@ #import -NSString *const MatrixKitVersion = @"0.16.7"; +NSString *const MatrixKitVersion = @"0.16.8"; diff --git a/MatrixKit/Models/Account/MXKAccount.h b/MatrixKit/Models/Account/MXKAccount.h index 1357dd39e..8d21f6e72 100644 --- a/MatrixKit/Models/Account/MXKAccount.h +++ b/MatrixKit/Models/Account/MXKAccount.h @@ -222,12 +222,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer */ @property (nonatomic,getter=isWarnedAboutEncryption) BOOL warnedAboutEncryption; -/** - Flag indicating whether to show decrypted content in notifications. - NO by default - */ -@property (nonatomic) BOOL showDecryptedContentInNotifications; - /** Register the MXKAccountOnCertificateChange block that will be used to handle certificate change during account use. This block is nil by default, any new certificate is ignored/untrusted (this will abort the connection to the server). diff --git a/MatrixKit/Models/Account/MXKAccount.m b/MatrixKit/Models/Account/MXKAccount.m index 5529a01d1..c30867251 100644 --- a/MatrixKit/Models/Account/MXKAccount.m +++ b/MatrixKit/Models/Account/MXKAccount.m @@ -24,6 +24,7 @@ #import "MXKEventFormatter.h" #import "MXKTools.h" +#import "MXKContactManager.h" #import "MXKConstants.h" @@ -227,8 +228,6 @@ - (id)initWithCoder:(NSCoder *)coder _warnedAboutEncryption = [coder decodeBoolForKey:@"warnedAboutEncryption"]; - _showDecryptedContentInNotifications = [coder decodeBoolForKey:@"showDecryptedContentInNotifications"]; - _others = [coder decodeObjectForKey:@"others"]; // Refresh device information @@ -289,8 +288,6 @@ - (void)encodeWithCoder:(NSCoder *)coder [coder encodeBool:_warnedAboutEncryption forKey:@"warnedAboutEncryption"]; - [coder encodeBool:_showDecryptedContentInNotifications forKey:@"showDecryptedContentInNotifications"]; - [coder encodeObject:_others forKey:@"others"]; } @@ -614,14 +611,6 @@ - (void)setWarnedAboutEncryption:(BOOL)warnedAboutEncryption [[MXKAccountManager sharedManager] saveAccounts]; } -- (void)setShowDecryptedContentInNotifications:(BOOL)showDecryptedContentInNotifications -{ - _showDecryptedContentInNotifications = showDecryptedContentInNotifications; - - // Archive updated field - [[MXKAccountManager sharedManager] saveAccounts]; -} - - (NSMutableDictionary> *)others { if(_others == nil) @@ -857,6 +846,11 @@ -(void)openSessionWithStore:(id)store // Complete session registration by launching live stream MXStrongifyAndReturnIfNil(self); + // Validate the availability of local contact sync for any changes to the + // authorization of contacts access that may have occurred since the last launch. + // The session is passed in as the contacts manager may not have had a session added yet. + [MXKContactManager.sharedManager validateSyncLocalContactsStateForSession:self.mxSession]; + // Refresh pusher state [self refreshAPNSPusher]; [self refreshPushKitPusher]; @@ -883,7 +877,7 @@ -(void)openSessionWithStore:(id)store */ - (void)closeSession:(BOOL)clearStore { - MXLogDebug(@"[MXKAccount] closeSession (%tu)", clearStore); + MXLogDebug(@"[MXKAccount] closeSession (%u)", clearStore); if (NSCurrentLocaleDidChangeNotificationObserver) { diff --git a/MatrixKit/Models/Contact/MXKContactManager.h b/MatrixKit/Models/Contact/MXKContactManager.h index 67d66e067..c8b0082b0 100644 --- a/MatrixKit/Models/Contact/MXKContactManager.h +++ b/MatrixKit/Models/Contact/MXKContactManager.h @@ -17,6 +17,7 @@ */ #import +#import #import @@ -156,6 +157,14 @@ typedef void(^MXKContactManagerDiscoverUsersBoundTo3PIDs)(NSArraylocalContactByContactID = nil; + self->localContactsWithMethods = nil; + self->splitLocalContacts = nil; + [self cacheLocalContacts]; + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactManagerDidUpdateLocalContactsNotification object:nil userInfo:nil]; + + MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Complete"); + MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Local contacts access denied"); + } + else + { + self->isLocalContactListRefreshing = YES; + + // Reset the internal contact lists (These arrays will be prepared only if need). + self->localContactsWithMethods = self->splitLocalContacts = nil; + + BOOL isColdStart = NO; + + // Check whether the local contacts sync has been disabled. + if (self->matrixIDBy3PID && ![MXKAppSettings standardAppSettings].syncLocalContacts) { - if ([MXKAppSettings standardAppSettings].syncLocalContacts) - { - // The user authorised syncLocalContacts and allowed access to his contacts - // but he then removed contacts access from app permissions. - // So, reset syncLocalContacts value - [MXKAppSettings standardAppSettings].syncLocalContacts = NO; - } + // The user changed his mind and disabled the local contact sync, remove the cached data. + self->matrixIDBy3PID = nil; + [self cacheMatrixIDsDict]; - // Local contacts list is empty if the access is denied. + // Reload the local contacts from the system self->localContactByContactID = nil; - self->localContactsWithMethods = nil; - self->splitLocalContacts = nil; [self cacheLocalContacts]; - - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactManagerDidUpdateLocalContactsNotification object:nil userInfo:nil]; - - MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Complete"); - MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Local contacts access denied"); } - else + + // Check whether this is a cold start. + if (!self->matrixIDBy3PID) { - self->isLocalContactListRefreshing = YES; - - // Reset the internal contact lists (These arrays will be prepared only if need). - self->localContactsWithMethods = self->splitLocalContacts = nil; + isColdStart = YES; - BOOL isColdStart = NO; - - // Check whether the local contacts sync has been disabled. - if (self->matrixIDBy3PID && ![MXKAppSettings standardAppSettings].syncLocalContacts) - { - // The user changed his mind and disabled the local contact sync, remove the cached data. - self->matrixIDBy3PID = nil; - [self cacheMatrixIDsDict]; - - // Reload the local contacts from the system - self->localContactByContactID = nil; - [self cacheLocalContacts]; - } + // Load the dictionary from the file system. It is cached to improve UX. + [self loadCachedMatrixIDsDict]; + } + + MXWeakify(self); + + dispatch_async(self->processingQueue, ^{ - // Check whether this is a cold start. - if (!self->matrixIDBy3PID) + MXStrongifyAndReturnIfNil(self); + + // In case of cold start, retrieve the data from the file system + if (isColdStart) { - isColdStart = YES; - - // Load the dictionary from the file system. It is cached to improve UX. - [self loadCachedMatrixIDsDict]; - } - - dispatch_async(self->processingQueue, ^{ - - MXStrongifyAndReturnIfNil(self); + [self loadCachedLocalContacts]; + [self loadCachedContactBookInfo]; - // In case of cold start, retrieve the data from the file system - if (isColdStart) + // no local contact -> assume that the last sync date is useless + if (self->localContactByContactID.count == 0) { - [self loadCachedLocalContacts]; - [self loadCachedContactBookInfo]; - - // no local contact -> assume that the last sync date is useless - if (self->localContactByContactID.count == 0) - { - self->lastSyncDate = nil; - } + self->lastSyncDate = nil; } + } - BOOL didContactBookChange = NO; + BOOL didContactBookChange = NO; - NSMutableArray* deletedContactIDs = [NSMutableArray arrayWithArray:[self->localContactByContactID allKeys]]; + NSMutableArray* deletedContactIDs = [NSMutableArray arrayWithArray:[self->localContactByContactID allKeys]]; - // can list local contacts? - if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) - { - NSString* countryCode = [[MXKAppSettings standardAppSettings] phonebookCountryCode]; + // can list local contacts? + if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) + { + NSString* countryCode = [[MXKAppSettings standardAppSettings] phonebookCountryCode]; - ABAddressBookRef ab = ABAddressBookCreateWithOptions(nil, nil); - ABRecordRef contactRecord; - CFIndex index; - CFMutableArrayRef people = (CFMutableArrayRef)ABAddressBookCopyArrayOfAllPeople(ab); + ABAddressBookRef ab = ABAddressBookCreateWithOptions(nil, nil); + ABRecordRef contactRecord; + CFIndex index; + CFMutableArrayRef people = (CFMutableArrayRef)ABAddressBookCopyArrayOfAllPeople(ab); - if (nil != people) - { - CFIndex peopleCount = CFArrayGetCount(people); + if (nil != people) + { + CFIndex peopleCount = CFArrayGetCount(people); - for (index = 0; index < peopleCount; index++) - { - contactRecord = (ABRecordRef)CFArrayGetValueAtIndex(people, index); + for (index = 0; index < peopleCount; index++) + { + contactRecord = (ABRecordRef)CFArrayGetValueAtIndex(people, index); - NSString* contactID = [MXKContact contactID:contactRecord]; + NSString* contactID = [MXKContact contactID:contactRecord]; - // the contact still exists - [deletedContactIDs removeObject:contactID]; + // the contact still exists + [deletedContactIDs removeObject:contactID]; - if (self->lastSyncDate) + if (self->lastSyncDate) + { + // ignore unchanged contacts since the previous sync + CFDateRef lastModifDate = ABRecordCopyValue(contactRecord, kABPersonModificationDateProperty); + if (lastModifDate) { - // ignore unchanged contacts since the previous sync - CFDateRef lastModifDate = ABRecordCopyValue(contactRecord, kABPersonModificationDateProperty); - if (lastModifDate) - { - if (kCFCompareGreaterThan != CFDateCompare(lastModifDate, (__bridge CFDateRef)self->lastSyncDate, nil)) + if (kCFCompareGreaterThan != CFDateCompare(lastModifDate, (__bridge CFDateRef)self->lastSyncDate, nil)) - { - CFRelease(lastModifDate); - continue; - } + { CFRelease(lastModifDate); + continue; } + CFRelease(lastModifDate); } + } - didContactBookChange = YES; + didContactBookChange = YES; - MXKContact* contact = [[MXKContact alloc] initLocalContactWithABRecord:contactRecord]; + MXKContact* contact = [[MXKContact alloc] initLocalContactWithABRecord:contactRecord]; - if (countryCode) - { - contact.defaultCountryCode = countryCode; - } - - // update the local contacts list - [self->localContactByContactID setValue:contact forKey:contactID]; + if (countryCode) + { + contact.defaultCountryCode = countryCode; } - CFRelease(people); + // update the local contacts list + [self->localContactByContactID setValue:contact forKey:contactID]; } - if (ab) - { - CFRelease(ab); - } + CFRelease(people); } - // some contacts have been deleted - for (NSString* contactID in deletedContactIDs) + if (ab) { - didContactBookChange = YES; - [self->localContactByContactID removeObjectForKey:contactID]; + CFRelease(ab); } + } - // something has been modified in the local contact book - if (didContactBookChange) - { - [self cacheLocalContacts]; - } + // some contacts have been deleted + for (NSString* contactID in deletedContactIDs) + { + didContactBookChange = YES; + [self->localContactByContactID removeObjectForKey:contactID]; + } + + // something has been modified in the local contact book + if (didContactBookChange) + { + [self cacheLocalContacts]; + } + + self->lastSyncDate = [NSDate date]; + [self cacheContactBookInfo]; + + // Update loaded contacts with the known dict 3PID -> matrix ID + [self updateAllLocalContactsMatrixIDs]; + + dispatch_async(dispatch_get_main_queue(), ^{ - self->lastSyncDate = [NSDate date]; - [self cacheContactBookInfo]; + // Contacts are loaded, post a notification + self->isLocalContactListRefreshing = NO; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactManagerDidUpdateLocalContactsNotification object:nil userInfo:nil]; - // Update loaded contacts with the known dict 3PID -> matrix ID - [self updateAllLocalContactsMatrixIDs]; + // Check the conditions required before triggering a matrix users lookup. + if (isColdStart || didContactBookChange) + { + [self updateMatrixIDsForAllLocalContacts]; + } - dispatch_async(dispatch_get_main_queue(), ^{ - - // Contacts are loaded, post a notification - self->isLocalContactListRefreshing = NO; - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactManagerDidUpdateLocalContactsNotification object:nil userInfo:nil]; - - // Check the conditions required before triggering a matrix users lookup. - if (isColdStart || didContactBookChange) - { - [self updateMatrixIDsForAllLocalContacts]; - } - - MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Complete"); - MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Refresh %tu local contacts in %.0fms", self->localContactByContactID.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - }); + MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Complete"); + MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Refresh %tu local contacts in %.0fms", self->localContactByContactID.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000); }); - } - }]; + }); + } } - (void)updateMatrixIDsForLocalContact:(MXKContact *)contact diff --git a/MatrixKit/Models/MXKAppSettings.h b/MatrixKit/Models/MXKAppSettings.h index 8dabdcd19..710e1d5db 100644 --- a/MatrixKit/Models/MXKAppSettings.h +++ b/MatrixKit/Models/MXKAppSettings.h @@ -186,11 +186,20 @@ typedef NS_ENUM(NSUInteger, MXKKeyPreSharingStrategy) /** Return YES if the user has been already asked for local contacts sync permission. - This boolean value is defined in shared settings object with the key: `syncLocalContactsRequested`. + This boolean value is defined in shared settings object with the key: `syncLocalContactsPermissionRequested`. Return NO if no value is defined. */ @property (nonatomic) BOOL syncLocalContactsPermissionRequested; +/** + Return YES if after the user has been asked for local contacts sync permission and choose to open + the system's Settings app to enable contacts access. + + This boolean value is defined in shared settings object with the key: `syncLocalContactsPermissionOpenedSystemSettings`. + Return NO if no value is defined. + */ +@property (nonatomic) BOOL syncLocalContactsPermissionOpenedSystemSettings; + /** The current selected country code for the phonebook. diff --git a/MatrixKit/Models/MXKAppSettings.m b/MatrixKit/Models/MXKAppSettings.m index d16b60516..7365fc8c2 100644 --- a/MatrixKit/Models/MXKAppSettings.m +++ b/MatrixKit/Models/MXKAppSettings.m @@ -45,7 +45,7 @@ @implementation MXKAppSettings @synthesize syncWithLazyLoadOfRoomMembers; @synthesize showAllEventsInRoomHistory, showRedactionsInRoomHistory, showUnsupportedEventsInRoomHistory, httpLinkScheme, httpsLinkScheme; @synthesize enableBubbleComponentLinkDetection, firstURLDetectionIgnoredHosts, showLeftMembersInRoomMemberList, sortRoomMembersUsingLastSeenTime; -@synthesize syncLocalContacts, syncLocalContactsPermissionRequested, phonebookCountryCode; +@synthesize syncLocalContacts, syncLocalContactsPermissionRequested, syncLocalContactsPermissionOpenedSystemSettings, phonebookCountryCode; @synthesize presenceColorForOnlineUser, presenceColorForUnavailableUser, presenceColorForOfflineUser; @synthesize enableCallKit; @synthesize sharedUserDefaults; @@ -639,6 +639,30 @@ - (void)setSyncLocalContactsPermissionRequested:(BOOL)theSyncLocalContactsPermis } } +- (BOOL)syncLocalContactsPermissionOpenedSystemSettings +{ + if (self == [MXKAppSettings standardAppSettings]) + { + return [[NSUserDefaults standardUserDefaults] boolForKey:@"syncLocalContactsPermissionOpenedSystemSettings"]; + } + else + { + return syncLocalContactsPermissionOpenedSystemSettings; + } +} + +- (void)setSyncLocalContactsPermissionOpenedSystemSettings:(BOOL)theSyncLocalContactsPermissionOpenedSystemSettings +{ + if (self == [MXKAppSettings standardAppSettings]) + { + [[NSUserDefaults standardUserDefaults] setBool:theSyncLocalContactsPermissionOpenedSystemSettings forKey:@"syncLocalContactsPermissionOpenedSystemSettings"]; + } + else + { + syncLocalContactsPermissionOpenedSystemSettings = theSyncLocalContactsPermissionOpenedSystemSettings; + } +} + - (NSString*)phonebookCountryCode { NSString* res = phonebookCountryCode; diff --git a/MatrixKit/Models/MXKDataSource.h b/MatrixKit/Models/MXKDataSource.h index c8868ed1b..a1332d6e2 100644 --- a/MatrixKit/Models/MXKDataSource.h +++ b/MatrixKit/Models/MXKDataSource.h @@ -64,7 +64,7 @@ typedef enum : NSUInteger { /** The matrix session. */ -@property (nonatomic, readonly) MXSession *mxSession; +@property (nonatomic, weak, readonly) MXSession *mxSession; /** The data source state diff --git a/MatrixKit/Models/Room/MXKAttachment.m b/MatrixKit/Models/Room/MXKAttachment.m index 69d177a95..10355b3c4 100644 --- a/MatrixKit/Models/Room/MXKAttachment.m +++ b/MatrixKit/Models/Room/MXKAttachment.m @@ -671,6 +671,7 @@ - (void)prepareShare:(void (^)(NSURL *fileURL))onReadyToShare failure:(void (^)( if ([[NSFileManager defaultManager] copyItemAtPath:path toPath:self->documentCopyPath error:nil]) { fileUrl = [NSURL fileURLWithPath:self->documentCopyPath]; + [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; } } @@ -678,6 +679,7 @@ - (void)prepareShare:(void (^)(NSURL *fileURL))onReadyToShare failure:(void (^)( { // Use the cached file by default fileUrl = [NSURL fileURLWithPath:path]; + self->documentCopyPath = path; } onReadyToShare (fileUrl); @@ -687,7 +689,6 @@ - (void)prepareShare:(void (^)(NSURL *fileURL))onReadyToShare failure:(void (^)( { [self decryptToTempFile:^(NSString *path) { haveFile(path); - [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; } failure:onFailure]; } else diff --git a/MatrixKit/Models/RoomList/MXKInterleavedRecentsDataSource.m b/MatrixKit/Models/RoomList/MXKInterleavedRecentsDataSource.m index 9e251a40b..28bb4c6ae 100644 --- a/MatrixKit/Models/RoomList/MXKInterleavedRecentsDataSource.m +++ b/MatrixKit/Models/RoomList/MXKInterleavedRecentsDataSource.m @@ -221,9 +221,10 @@ - (CGFloat)cellHeightAtIndexPath:(NSIndexPath *)indexPath id recentCellData = interleavedCellDataArray[indexPath.row]; // Select the related recent data source - MXKSessionRecentsDataSource *recentsDataSource = recentCellData.recentsDataSource; - if (recentsDataSource) + MXKDataSource *dataSource = recentCellData.dataSource; + if ([dataSource isKindOfClass:[MXKSessionRecentsDataSource class]]) { + MXKSessionRecentsDataSource *recentsDataSource = (MXKSessionRecentsDataSource*)dataSource; // Count the index of this cell data in original data source array NSInteger rank = 0; for (NSInteger index = 0; index < indexPath.row; index++) @@ -257,7 +258,7 @@ - (NSIndexPath*)cellIndexPathWithRoomId:(NSString*)roomId andMatrixSession:(MXSe for (NSInteger index = 0; index < recentsDataSource.numberOfCells; index ++) { id recentCellData = [recentsDataSource cellDataAtIndex:index]; - if ([roomId isEqualToString:recentCellData.roomSummary.roomId]) + if ([roomId isEqualToString:recentCellData.roomIdentifier]) { // Got it indexPath = [NSIndexPath indexPathForRow:index inSection:0]; @@ -280,7 +281,7 @@ - (NSIndexPath*)cellIndexPathWithRoomId:(NSString*)roomId andMatrixSession:(MXSe for (NSInteger index = 0; index < interleavedCellDataArray.count; index ++) { id recentCellData = interleavedCellDataArray[index]; - if ([roomId isEqualToString:recentCellData.roomSummary.roomId]) + if ([roomId isEqualToString:recentCellData.roomIdentifier]) { // Got it indexPath = [NSIndexPath indexPathForRow:index inSection:0]; @@ -408,7 +409,7 @@ - (void)dataSource:(MXKDataSource*)dataSource didCellChange:(id)changes id currentCellData = interleavedCellDataArray[currentCellIndex]; // Remove existing cell data of the updated data source - if (currentCellData.recentsDataSource == dataSource) + if (currentCellData.dataSource == dataSource) { [interleavedCellDataArray removeObjectAtIndex:currentCellIndex]; } diff --git a/MatrixKit/Models/RoomList/MXKRecentCellData.m b/MatrixKit/Models/RoomList/MXKRecentCellData.m index d7fa7dd8f..c3cf42f6f 100644 --- a/MatrixKit/Models/RoomList/MXKRecentCellData.m +++ b/MatrixKit/Models/RoomList/MXKRecentCellData.m @@ -17,71 +17,88 @@ #import "MXKRecentCellData.h" -#import "MXKSessionRecentsDataSource.h" +#import "MXKDataSource.h" #import "MXEvent+MatrixKit.h" #import @implementation MXKRecentCellData -@synthesize roomSummary, spaceChildInfo, recentsDataSource, roomDisplayname, lastEventTextMessage, lastEventAttributedTextMessage, lastEventDate; +@synthesize roomSummary, dataSource, lastEventDate; -- (instancetype)initWithRoomSummary:(MXRoomSummary*)theRoomSummary andRecentListDataSource:(MXKSessionRecentsDataSource*)recentListDataSource +- (instancetype)initWithRoomSummary:(id)theRoomSummary + dataSource:(MXKDataSource*)theDataSource; { self = [self init]; if (self) { roomSummary = theRoomSummary; - recentsDataSource = recentListDataSource; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update) name:kMXRoomSummaryDidChangeNotification object:roomSummary]; - - [self update]; + dataSource = theDataSource; } return self; } -- (instancetype)initWithSpaceChildInfo:(MXSpaceChildInfo*)theSpaceChildInfo andRecentListDataSource:(MXKSessionRecentsDataSource*)recentListDataSource +- (void)dealloc { - self = [self init]; - if (self) - { - spaceChildInfo = theSpaceChildInfo; - recentsDataSource = recentListDataSource; + roomSummary = nil; +} - [self update]; - } - return self; +- (MXSession *)mxSession +{ + return dataSource.mxSession; } -- (void)update +- (NSString*)lastEventDate { - // Keep ref on displayed last event - roomDisplayname = spaceChildInfo ? spaceChildInfo.name : roomSummary.displayname; + return (NSString*)roomSummary.lastMessage.others[@"lastEventDate"]; +} - lastEventTextMessage = spaceChildInfo ? spaceChildInfo.topic : roomSummary.lastMessage.text; - lastEventAttributedTextMessage = spaceChildInfo ? nil : roomSummary.lastMessage.attributedText; +- (BOOL)hasUnread +{ + return (roomSummary.localUnreadEventCount != 0); } -- (void)dealloc +- (NSString *)roomIdentifier { - if (roomSummary) + if (self.isSuggestedRoom) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:roomSummary]; + return self.roomSummary.spaceChildInfo.childRoomId; } - roomSummary = nil; - spaceChildInfo = nil; + return roomSummary.roomId; +} - lastEventTextMessage = nil; - lastEventAttributedTextMessage = nil; +- (NSString *)roomDisplayname +{ + if (self.isSuggestedRoom) + { + return self.roomSummary.spaceChildInfo.displayName; + } + return roomSummary.displayname; } -- (NSString*)lastEventDate +- (NSString *)avatarUrl { - return (NSString*)roomSummary.lastMessage.others[@"lastEventDate"]; + if (self.isSuggestedRoom) + { + return self.roomSummary.spaceChildInfo.avatarUrl; + } + return roomSummary.avatar; } -- (BOOL)hasUnread +- (NSString *)lastEventTextMessage { - return (roomSummary.localUnreadEventCount != 0); + if (self.isSuggestedRoom) + { + return roomSummary.spaceChildInfo.topic; + } + return roomSummary.lastMessage.text; +} + +- (NSAttributedString *)lastEventAttributedTextMessage +{ + if (self.isSuggestedRoom) + { + return nil; + } + return roomSummary.lastMessage.attributedText; } - (NSUInteger)notificationCount @@ -99,11 +116,6 @@ - (NSString*)notificationCountStringValue return [NSString stringWithFormat:@"%tu", self.notificationCount]; } -- (void)markAllAsRead -{ - [roomSummary markAllAsRead]; -} - - (NSString*)description { return [NSString stringWithFormat:@"%@ %@: %@ - %@", super.description, self.roomSummary.roomId, self.roomDisplayname, self.lastEventTextMessage]; @@ -112,7 +124,7 @@ - (NSString*)description - (BOOL)isSuggestedRoom { // As off now, we only store MXSpaceChildInfo in case of suggested rooms - return self.spaceChildInfo != nil; + return self.roomSummary.spaceChildInfo != nil; } @end diff --git a/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h b/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h index 7143282a7..8cf046696 100644 --- a/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h +++ b/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h @@ -20,7 +20,7 @@ #import "MXKCellData.h" -@class MXKSessionRecentsDataSource; +@class MXKDataSource; @class MXSpaceChildInfo; /** @@ -34,18 +34,16 @@ /** The original data source of the recent displayed by the cell. */ -@property (nonatomic, readonly) MXKSessionRecentsDataSource *recentsDataSource; +@property (nonatomic, weak, readonly) MXKDataSource *dataSource; /** - The `MXRoomSummary` instance of the room for the recent displayed by the cell. + The `MXRoomSummaryProtocol` instance of the room for the recent displayed by the cell. */ -@property (nonatomic, readonly) MXRoomSummary *roomSummary; -/** - In case of suggested rooms we store the `MXSpaceChildInfo` instance of the room - */ -@property (nonatomic, readonly) MXSpaceChildInfo *spaceChildInfo; +@property (nonatomic, readonly) id roomSummary; +@property (nonatomic, readonly) NSString *roomIdentifier; @property (nonatomic, readonly) NSString *roomDisplayname; +@property (nonatomic, readonly) NSString *avatarUrl; @property (nonatomic, readonly) NSString *lastEventTextMessage; @property (nonatomic, readonly) NSString *lastEventDate; @@ -55,34 +53,18 @@ @property (nonatomic, readonly) NSString *notificationCountStringValue; @property (nonatomic, readonly) BOOL isSuggestedRoom; -#pragma mark - Public methods -/** - Create a new `MXKCellData` object for a new recent cell. - - @param roomSummary the `MXRoomSummary` object that has data about the room. - @param recentListDataSource the `MXKSessionRecentsDataSource` object that will use this instance. - @return the newly created instance. - */ -- (instancetype)initWithRoomSummary:(MXRoomSummary*)roomSummary andRecentListDataSource:(MXKSessionRecentsDataSource*)recentListDataSource; +@property (nonatomic, readonly) MXSession *mxSession; +#pragma mark - Public methods /** Create a new `MXKCellData` object for a new recent cell. - @param spaceChildInfo the `MXSpaceChildInfo` object that has data about the room. - @param recentListDataSource the `MXKSessionRecentsDataSource` object that will use this instance. + @param roomSummary the `id` object that has data about the room. + @param dataSource the `MXKDataSource` object that will use this instance. @return the newly created instance. */ -- (instancetype)initWithSpaceChildInfo:(MXSpaceChildInfo*)spaceChildInfo andRecentListDataSource:(MXKSessionRecentsDataSource*)recentListDataSource; - -/** - The `MXKSessionRecentsDataSource` object calls this method when it detects a change in the room. - */ -- (void)update; - -/** - Mark all messages as read - */ -- (void)markAllAsRead; +- (instancetype)initWithRoomSummary:(id)roomSummary + dataSource:(MXKDataSource*)dataSource; @optional /** diff --git a/MatrixKit/Models/RoomList/MXKRecentsDataSource.h b/MatrixKit/Models/RoomList/MXKRecentsDataSource.h index 150aac2a4..b9de69b4a 100644 --- a/MatrixKit/Models/RoomList/MXKRecentsDataSource.h +++ b/MatrixKit/Models/RoomList/MXKRecentsDataSource.h @@ -76,11 +76,6 @@ */ - (void)removeMatrixSession:(MXSession*)mxSession; -/** - Mark all messages as read in all the displayed recents. - */ -- (void)markAllAsRead; - /** Filter the current recents list according to the provided patterns. diff --git a/MatrixKit/Models/RoomList/MXKRecentsDataSource.m b/MatrixKit/Models/RoomList/MXKRecentsDataSource.m index ab4bb7488..0da982a1d 100644 --- a/MatrixKit/Models/RoomList/MXKRecentsDataSource.m +++ b/MatrixKit/Models/RoomList/MXKRecentsDataSource.m @@ -242,14 +242,6 @@ - (BOOL)hasUnread return NO; } -- (void)markAllAsRead -{ - for (MXKSessionRecentsDataSource *recentsDataSource in displayedRecentsDataSourceArray) - { - [recentsDataSource markAllAsRead]; - } -} - - (void)searchWithPatterns:(NSArray*)patternsList { _searchPatternsList = patternsList; @@ -362,7 +354,7 @@ - (NSIndexPath*)cellIndexPathWithRoomId:(NSString*)roomId andMatrixSession:(MXSe for (NSInteger index = 0; index < recentsDataSource.numberOfCells; index ++) { id recentCellData = [recentsDataSource cellDataAtIndex:index]; - if ([roomId isEqualToString:recentCellData.roomSummary.roomId]) + if ([roomId isEqualToString:recentCellData.roomIdentifier]) { // Got it indexPath = [NSIndexPath indexPathForRow:index inSection:section]; @@ -613,7 +605,7 @@ - (MXRoom*)getRoomAtIndexPath:(NSIndexPath *)indexPath if (recentCellData) { - return recentCellData.roomSummary.room; + return [self.mxSession roomWithRoomId:recentCellData.roomIdentifier]; } return nil; diff --git a/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.h b/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.h index e4a8a4c03..e3b1eb9e6 100644 --- a/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.h +++ b/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.h @@ -18,6 +18,7 @@ #import #import +#import "MXKConstants.h" #import "MXKDataSource.h" #import "MXKRecentCellData.h" @@ -31,6 +32,7 @@ extern NSString *const kMXKRecentCellIdentifier; /** The recents data source based on a unique matrix session. */ +MXK_DEPRECATED_ATTRIBUTE_WITH_MSG("See MXSession.roomListDataManager") @interface MXKSessionRecentsDataSource : MXKDataSource { @protected @@ -61,11 +63,6 @@ extern NSString *const kMXKRecentCellIdentifier; #pragma mark - Life cycle -/** - Mark all messages as read for all the recent cells - */ -- (void)markAllAsRead; - /** Filter the current recents list according to the provided patterns. When patterns are not empty, the search result is stored in `filteredCellDataArray`, diff --git a/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m b/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m index 525d5261f..494dad58c 100644 --- a/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m +++ b/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m @@ -51,7 +51,15 @@ @interface MXKSessionRecentsDataSource () */ NSMutableDictionary *> *lastSuggestedRooms; + /** + Event listener of the current space used to update the UI if an event occurs. + */ id spaceEventsListener; + + /** + Observer used to reload data when the space service is initialised + */ + id spaceServiceDidInitialiseObserver; } /** @@ -79,6 +87,8 @@ - (instancetype)initWithMatrixSession:(MXSession *)matrixSession [self registerCellDataClass:MXKRecentCellData.class forCellIdentifier:kMXKRecentCellIdentifier]; roomSummaryChangeThrottler = [[MXThrottler alloc] initWithMinimumDelay:roomSummaryChangeThrottlerDelay]; + + [[MXKAppSettings standardAppSettings] addObserver:self forKeyPath:@"showAllRoomsInHomeSpace" options:0 context:nil]; } return self; } @@ -91,6 +101,10 @@ - (void)destroy [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil]; + if (spaceServiceDidInitialiseObserver) { + [[NSNotificationCenter defaultCenter] removeObserver:spaceServiceDidInitialiseObserver]; + } + [roomSummaryChangeThrottler cancelAll]; roomSummaryChangeThrottler = nil; @@ -101,6 +115,8 @@ - (void)destroy searchPatternsList = nil; + [[MXKAppSettings standardAppSettings] removeObserver:self forKeyPath:@"showAllRoomsInHomeSpace" context:nil]; + [super destroy]; } @@ -196,16 +212,6 @@ - (BOOL)hasUnread return NO; } -- (void)markAllAsRead -{ - // Clear unread count on all recent cells - for (NSUInteger i = 0; i < self.numberOfCells; i++) - { - id cellData = [self cellDataAtIndex:i]; - [cellData markAllAsRead]; - } -} - - (void)searchWithPatterns:(NSArray*)patternsList { if (patternsList.count) @@ -272,8 +278,11 @@ - (CGFloat)cellHeightAtIndex:(NSInteger)index return 0; } - #pragma mark - Events processing + +/** + Filtering in this method won't have any effect anymore. This class is not maintained. + */ - (void)loadData { [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:nil]; @@ -282,6 +291,14 @@ - (void)loadData [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil]; + if (!self.mxSession.spaceService.isInitialised && !spaceServiceDidInitialiseObserver) { + MXWeakify(self); + spaceServiceDidInitialiseObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MXSpaceService.didInitialise object:self.mxSession.spaceService queue:nil usingBlock:^(NSNotification * _Nonnull note) { + MXStrongifyAndReturnIfNil(self); + [self loadData]; + }]; + } + // Reset the table [internalCellDataArray removeAllObjects]; @@ -297,20 +314,19 @@ - (void)loadData if (!roomSummary.isConferenceUserRoom // @TODO Abstract this condition with roomSummary.hiddenFromUser && !roomSummary.hiddenFromUser) { - id cellData = [[class alloc] initWithRoomSummary:roomSummary andRecentListDataSource:self]; + id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; if (cellData) { - if (self.currentSpace == nil || [self.mxSession.spaceService isRoomWithId:roomSummary.roomId descendantOf:self.currentSpace.spaceId]) - { - [internalCellDataArray addObject:cellData]; - } + [internalCellDataArray addObject:cellData]; } } } for (MXSpaceChildInfo *childInfo in _suggestedRooms) { - id cellData = [[class alloc] initWithSpaceChildInfo:childInfo andRecentListDataSource:self]; + id summary = [[MXRoomSummary alloc] initWithSpaceChildInfo:childInfo]; + id cellData = [[class alloc] initWithRoomSummary:summary + dataSource:self]; if (cellData) { [internalCellDataArray addObject:cellData]; @@ -380,7 +396,7 @@ - (void)didRoomSummaryChanged2:(NSNotification *)notif { // Create a new instance to not modify the content of 'cellDataArray' (the copy is not a deep copy). Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier]; - id cellData = [[class alloc] initWithRoomSummary:roomSummary andRecentListDataSource:self]; + id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; if (cellData) { [internalCellDataArray replaceObjectAtIndex:index withObject:cellData]; @@ -422,7 +438,7 @@ - (void)didMXSessionHaveNewRoom:(NSNotification *)notif Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier]; MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:roomId]; - id cellData = [[class alloc] initWithRoomSummary:roomSummary andRecentListDataSource:self]; + id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; if (cellData) { [internalCellDataArray addObject:cellData]; @@ -514,4 +530,20 @@ - (void)sortCellDataAndNotifyChanges return theRoomData; } +#pragma mark - KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context +{ + if (object == [MXKAppSettings standardAppSettings] && [keyPath isEqualToString:@"showAllRoomsInHomeSpace"]) + { + if (self.currentSpace == nil) + { + [self loadData]; + } + } +} + @end diff --git a/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m index 1ec4daed7..f1dce0891 100644 --- a/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m +++ b/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m @@ -1922,7 +1922,7 @@ - (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary } else if (event.eventType == MXEventTypeRoomJoinRules) { - summary.others[@"mxkEventFormatterisJoinRulePublic"] = @(roomState.isJoinRulePublic); + summary.joinRule = roomState.joinRule; } } diff --git a/MatrixKit/Utils/MXKAnalyticsConstants.h b/MatrixKit/Utils/MXKAnalyticsConstants.h new file mode 100644 index 000000000..97d3c25f2 --- /dev/null +++ b/MatrixKit/Utils/MXKAnalyticsConstants.h @@ -0,0 +1,33 @@ +// +// Copyright 2020 The Matrix.org Foundation C.I.C +// +// 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 + + +typedef NSString *const MXKAnalyticsCategory NS_TYPED_EXTENSIBLE_ENUM; + +/** + The analytics category for local contacts. + */ +static MXKAnalyticsCategory const MXKAnalyticsCategoryContacts = @"localContacts"; + + +typedef NSString *const MXKAnalyticsName NS_TYPED_EXTENSIBLE_ENUM; + +/** + The analytics value for accept/decline of local contacts access. + */ +static MXKAnalyticsName const MXKAnalyticsNameContactsAccessGranted = @"accessGranted"; diff --git a/MatrixKit/Utils/MXKConstants.h b/MatrixKit/Utils/MXKConstants.h index ca855b657..b580d234e 100644 --- a/MatrixKit/Utils/MXKConstants.h +++ b/MatrixKit/Utils/MXKConstants.h @@ -17,6 +17,9 @@ #import +#define MXK_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#define MXK_DEPRECATED_ATTRIBUTE_WITH_MSG(msg) __attribute((deprecated((msg)))) + /** The Matrix iOS Kit version. */ @@ -36,16 +39,3 @@ FOUNDATION_EXPORT NSString *const kMXKErrorNotification; The key in notification userInfo dictionary representating the account userId. */ FOUNDATION_EXPORT NSString *const kMXKErrorUserIdKey; - - -#pragma mark - Analytics - -/** - The analytics category for local contacts. - */ -FOUNDATION_EXPORT NSString *const kMXKAnalyticsContactsCategory; - -/** - The analytics value for accept/decline of local contacts access. - */ -FOUNDATION_EXPORT NSString *const kMXKAnalyticsContactsAccessGranted; diff --git a/MatrixKit/Utils/MXKConstants.m b/MatrixKit/Utils/MXKConstants.m index 29b502805..cf6c87873 100644 --- a/MatrixKit/Utils/MXKConstants.m +++ b/MatrixKit/Utils/MXKConstants.m @@ -21,9 +21,3 @@ NSString *const kMXKErrorNotification = @"kMXKErrorNotification"; NSString *const kMXKErrorUserIdKey = @"kMXKErrorUserIdKey"; - - -#pragma mark - Analytics - -NSString *const kMXKAnalyticsContactsCategory = @"localContacts"; -NSString *const kMXKAnalyticsContactsAccessGranted = @"accessGranted"; diff --git a/MatrixKit/Utils/MXKTools.h b/MatrixKit/Utils/MXKTools.h index e7f9275c6..67232b034 100644 --- a/MatrixKit/Utils/MXKTools.h +++ b/MatrixKit/Utils/MXKTools.h @@ -343,6 +343,25 @@ manualChangeMessageForVideo:(NSString*)manualChangeMessageForVideo showPopUpInViewController:(UIViewController*)viewController completionHandler:(void (^)(BOOL granted))handler; +/** + Check permission to access Contacts. + + @discussion + If the access was not yet granted, a dialog will be shown to the user. + If it is the first attempt to access the media, the dialog is the classic iOS one. + Else, the dialog will ask the user to manually change the permission in the app settings. + + @param manualChangeTitle the title to display if the end user must change the app settings manually. + @param manualChangeMessage the message to display if the end user must change the app settings manually. + If nil, the dialog for displaying manualChangeMessage will not be shown. + @param viewController the view controller to attach the dialog displaying manualChangeMessage. + @param handler the block called with the result of requesting access + */ ++ (void)checkAccessForContacts:(NSString *)manualChangeTitle + withManualChangeMessage:(NSString *)manualChangeMessage + showPopUpInViewController:(UIViewController *)viewController + completionHandler:(void (^)(BOOL granted))handler; + #pragma mark - HTML processing /** diff --git a/MatrixKit/Utils/MXKTools.m b/MatrixKit/Utils/MXKTools.m index fcb3fd05e..e175e6705 100644 --- a/MatrixKit/Utils/MXKTools.m +++ b/MatrixKit/Utils/MXKTools.m @@ -18,14 +18,16 @@ #import "MXKTools.h" @import MatrixSDK; -@import AddressBook; +@import Contacts; @import libPhoneNumber_iOS; @import DTCoreText; #import "MXKConstants.h" #import "NSBundle+MatrixKit.h" +#import "MXKAppSettings.h" #import #import "MXKSwiftHeader.h" +#import "MXKAnalyticsConstants.h" #pragma mark - Constants definitions @@ -862,70 +864,73 @@ + (void)checkAccessForCall:(BOOL)isVideoCall + (void)checkAccessForContacts:(NSString *)manualChangeMessage showPopUpInViewController:(UIViewController *)viewController completionHandler:(void (^)(BOOL granted))handler +{ + [self checkAccessForContacts:nil withManualChangeMessage:manualChangeMessage showPopUpInViewController:viewController completionHandler:handler]; +} + ++ (void)checkAccessForContacts:(NSString *)manualChangeTitle + withManualChangeMessage:(NSString *)manualChangeMessage + showPopUpInViewController:(UIViewController *)viewController + completionHandler:(void (^)(BOOL granted))handler { // Check if the application is allowed to list the contacts - ABAuthorizationStatus cbStatus = ABAddressBookGetAuthorizationStatus(); - if (cbStatus == kABAuthorizationStatusAuthorized) + CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; + if (authStatus == CNAuthorizationStatusAuthorized) { handler(YES); } - else if (cbStatus == kABAuthorizationStatusNotDetermined) + else if (authStatus == CNAuthorizationStatusNotDetermined) { // Request address book access - ABAddressBookRef ab = ABAddressBookCreateWithOptions(nil, nil); - if (ab) - { - ABAddressBookRequestAccessWithCompletion(ab, ^(bool granted, CFErrorRef error) { + [[CNContactStore new] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { + + [MXSDKOptions.sharedInstance.analyticsDelegate trackValue:[NSNumber numberWithBool:granted] + category:MXKAnalyticsCategoryContacts + name:MXKAnalyticsNameContactsAccessGranted]; + + dispatch_async(dispatch_get_main_queue(), ^{ - [MXSDKOptions.sharedInstance.analyticsDelegate trackValue:[NSNumber numberWithBool:granted] - category:kMXKAnalyticsContactsCategory - name:kMXKAnalyticsContactsAccessGranted]; + handler(granted); - dispatch_async(dispatch_get_main_queue(), ^{ - - handler(granted); - - }); }); - - CFRelease(ab); - } - else - { - // No phonebook - handler(YES); - } + }]; } - else if (cbStatus == kABAuthorizationStatusDenied && viewController && manualChangeMessage) + else if (authStatus == CNAuthorizationStatusDenied && viewController && manualChangeMessage) { // Access not granted to the local contacts // Display manualChangeMessage - UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:manualChangeMessage preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:manualChangeTitle message:manualChangeMessage preferredStyle:UIAlertControllerStyleAlert]; - // On iOS >= 8, add a shortcut to the app settings (This requires the shared application instance) + [alert addAction:[UIAlertAction actionWithTitle:MatrixKitL10n.cancel + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + + handler(NO); + + }]]; + + // Add a shortcut to the app settings (This requires the shared application instance) UIApplication *sharedApplication = [UIApplication performSelector:@selector(sharedApplication)]; - if (sharedApplication && UIApplicationOpenSettingsURLString) + if (sharedApplication) { - [alert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n settings] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - - NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - [sharedApplication performSelector:@selector(openURL:) withObject:url]; - - // Note: it does not worth to check if the user changes the permission - // because iOS restarts the app in case of change of app privacy settings - handler(NO); - - }]]; + UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:MatrixKitL10n.settings + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + [MXKAppSettings standardAppSettings].syncLocalContactsPermissionOpenedSystemSettings = YES; + // Wait for the setting to be saved as the app could be killed imminently. + [[NSUserDefaults standardUserDefaults] synchronize]; + + NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; + [sharedApplication performSelector:@selector(openURL:) withObject:url]; + + // Note: it does not worth to check if the user changes the permission + // because iOS restarts the app in case of change of app privacy settings + handler(NO); + }]; + + [alert addAction: settingsAction]; + alert.preferredAction = settingsAction; } - [alert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - - handler(NO); - - }]]; [viewController presentViewController:alert animated:YES completion:nil]; } diff --git a/MatrixKit/Utils/MXKUTI.swift b/MatrixKit/Utils/MXKUTI.swift index b180805f5..aea659556 100644 --- a/MatrixKit/Utils/MXKUTI.swift +++ b/MatrixKit/Utils/MXKUTI.swift @@ -164,10 +164,13 @@ extension MXKUTI { public static let data = MXKUTI(cfRawValue: kUTTypeData)! public static let text = MXKUTI(cfRawValue: kUTTypeText)! public static let audio = MXKUTI(cfRawValue: kUTTypeAudio)! + public static let video = MXKUTI(cfRawValue: kUTTypeVideo)! public static let movie = MXKUTI(cfRawValue: kUTTypeMovie)! public static let image = MXKUTI(cfRawValue: kUTTypeImage)! public static let png = MXKUTI(cfRawValue: kUTTypePNG)! public static let jpeg = MXKUTI(cfRawValue: kUTTypeJPEG)! + public static let url = MXKUTI(cfRawValue: kUTTypeURL)! + public static let fileUrl = MXKUTI(cfRawValue: kUTTypeFileURL)! } // MARK: - Convenients static methods diff --git a/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m b/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m index 72892cbf2..4c3924d96 100644 --- a/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m +++ b/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m @@ -1181,7 +1181,20 @@ - (void)paste:(id)sender NSString* MIMEType = (__bridge_transfer NSString *) UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)key, kUTTagClassMIMEType); if ([MIMEType hasPrefix:@"image/"] && [self.delegate respondsToSelector:@selector(roomInputToolbarView:sendImage:)]) { - UIImage *pasteboardImage = [dict objectForKey:key]; + UIImage *pasteboardImage; + if ([[dict objectForKey:key] isKindOfClass:UIImage.class]) + { + pasteboardImage = [dict objectForKey:key]; + } + // WebP images from Safari appear on the pasteboard as NSData rather than UIImages. + else if ([[dict objectForKey:key] isKindOfClass:NSData.class]) + { + pasteboardImage = [UIImage imageWithData:[dict objectForKey:key]]; + } + else { + MXLogError(@"[MXKRoomInputToolbarView] Unsupported image format %@ for mimetype %@ pasted.", MIMEType, NSStringFromClass([[dict objectForKey:key] class])); + } + if (pasteboardImage) { MXKImageView *imageValidationView = [[MXKImageView alloc] initWithFrame:CGRectZero]; diff --git a/MatrixKit/Views/RoomList/MXKInterleavedRecentTableViewCell.m b/MatrixKit/Views/RoomList/MXKInterleavedRecentTableViewCell.m index 1da9b9f65..a4b17d16e 100644 --- a/MatrixKit/Views/RoomList/MXKInterleavedRecentTableViewCell.m +++ b/MatrixKit/Views/RoomList/MXKInterleavedRecentTableViewCell.m @@ -49,7 +49,7 @@ - (void)render:(MXKCellData *)cellData // Highlight the room owner by using his tint color. if (roomCellData) { - MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:roomCellData.roomSummary.room.mxSession.myUser.userId]; + MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:roomCellData.mxSession.myUserId]; if (account) { _userFlag.backgroundColor = account.userTintColor; diff --git a/MatrixKit/Views/RoomList/MXKRecentTableViewCell.m b/MatrixKit/Views/RoomList/MXKRecentTableViewCell.m index b7fbc43f0..3fdce7f75 100644 --- a/MatrixKit/Views/RoomList/MXKRecentTableViewCell.m +++ b/MatrixKit/Views/RoomList/MXKRecentTableViewCell.m @@ -45,8 +45,7 @@ - (void)render:(MXKCellData *)cellData } // Set in bold public room name - if (roomCellData.roomSummary.others[@"mxkEventFormatterisJoinRulePublic"] - && [(NSNumber*)roomCellData.roomSummary.others[@"mxkEventFormatterisJoinRulePublic"] boolValue]) + if ([roomCellData.roomSummary.joinRule isEqualToString:kMXRoomJoinRulePublic]) { _roomTitle.font = [UIFont boldSystemFontOfSize:20]; } diff --git a/Podfile b/Podfile index 5f7fafbba..7d2bad71f 100644 --- a/Podfile +++ b/Podfile @@ -8,7 +8,7 @@ abstract_target 'MatrixKitSamplePods' do # Different flavours of pods to Matrix SDK # The tagged version on which this version of MatrixKit has been built - pod 'MatrixSDK', '= 0.20.7' + pod 'MatrixSDK', '= 0.20.8' # The lastest release available on the CocoaPods repository #pod 'MatrixSDK' diff --git a/Podfile.lock b/Podfile.lock index 6acb00a1d..327678f5f 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,9 +39,9 @@ PODS: - JSQSystemSoundPlayer (2.0.1) - libbase58 (0.1.4) - libPhoneNumber-iOS (0.9.15) - - MatrixSDK (0.20.7): - - MatrixSDK/Core (= 0.20.7) - - MatrixSDK/Core (0.20.7): + - MatrixSDK (0.20.8): + - MatrixSDK/Core (= 0.20.8) + - MatrixSDK/Core (0.20.8): - AFNetworking (~> 4.0.0) - GZIP (~> 1.3.0) - libbase58 (~> 0.1.4) @@ -65,7 +65,7 @@ DEPENDENCIES: - HPGrowingTextView (~> 1.1) - JSQMessagesViewController (~> 7.3.5) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.20.7) + - MatrixSDK (= 0.20.8) - SwiftGen (~> 6.3) SPEC REPOS: @@ -97,12 +97,12 @@ SPEC CHECKSUMS: JSQSystemSoundPlayer: c5850e77a4363ffd374cd851154b9af93264ed8d libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 - MatrixSDK: 1d7a64d1e25f746e35157a68374b4282b5581188 + MatrixSDK: 4bf48f6b318e082f9d217daf8a90d2f099dd138b OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5 Realm: b6027801398f3743fc222f096faa85281b506e6c SwiftGen: a6d22010845f08fe18fbdf3a07a8e380fd22e0ea SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82 -PODFILE CHECKSUM: a6e8c70e4a2a299ec66f085cbb8b649d9622b08b +PODFILE CHECKSUM: 145bfc50cf1280cad72b972a11f1c3484342fe38 -COCOAPODS: 1.11.2 +COCOAPODS: 1.10.1