From feb7a4549011417378b2f588459e6e087369634a Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:36:17 +0000 Subject: [PATCH 01/51] Added translation using Weblate (Italian) --- Riot/Assets/it.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/it.lproj/InfoPlist.strings diff --git a/Riot/Assets/it.lproj/InfoPlist.strings b/Riot/Assets/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/it.lproj/InfoPlist.strings @@ -0,0 +1 @@ + From a9d8dbbe56e8de42120903ee26514380835afcdf Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:38:05 +0000 Subject: [PATCH 02/51] Translated using Weblate (Italian) Currently translated at 100.0% (4 of 4 strings) Translation: Riot iOS/Riot iOS (Dialogs) Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios-dialogs/it/ --- Riot/Assets/it.lproj/InfoPlist.strings | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/it.lproj/InfoPlist.strings b/Riot/Assets/it.lproj/InfoPlist.strings index 8b1378917..62fa60059 100644 --- a/Riot/Assets/it.lproj/InfoPlist.strings +++ b/Riot/Assets/it.lproj/InfoPlist.strings @@ -1 +1,5 @@ - +// Permissions usage explanations +"NSCameraUsageDescription" = "La fotocamera viene utilizzata per scattare fotografie, registrare video ed eseguire videochiamate."; +"NSPhotoLibraryUsageDescription" = "La libreria fotografica viene utilizzata per inviare foto e video."; +"NSMicrophoneUsageDescription" = "Il microfono viene utilizzato per registrare video ed effettuare chiamate."; +"NSContactsUsageDescription" = "La rubrica viene utilizzata per ricercare utenti tramite email o numero di telefono su Riot."; From 7c510771e0c343204d3f15075adecb17b320b9bb Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:39:41 +0000 Subject: [PATCH 03/51] Added translation using Weblate (Italian) --- Riot/Assets/it.lproj/Localizable.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/it.lproj/Localizable.strings diff --git a/Riot/Assets/it.lproj/Localizable.strings b/Riot/Assets/it.lproj/Localizable.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/it.lproj/Localizable.strings @@ -0,0 +1 @@ + From 36dac48eaa006e843654e457b6711586f232e0f3 Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:45:22 +0000 Subject: [PATCH 04/51] Added translation using Weblate (Italian) --- Riot/Assets/it.lproj/Vector.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/it.lproj/Vector.strings diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/it.lproj/Vector.strings @@ -0,0 +1 @@ + From 02e48e3782b3ed365c41f987b4c965b095764d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Kotous?= Date: Fri, 11 May 2018 20:21:26 +0000 Subject: [PATCH 05/51] Added translation using Weblate (Czech) --- Riot/Assets/cs.lproj/Vector.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/cs.lproj/Vector.strings diff --git a/Riot/Assets/cs.lproj/Vector.strings b/Riot/Assets/cs.lproj/Vector.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/cs.lproj/Vector.strings @@ -0,0 +1 @@ + From 5848e41e0fb6883ec92c15465193989d73edc444 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Sun, 13 May 2018 12:57:35 +0000 Subject: [PATCH 06/51] Translated using Weblate (Chinese (Simplified)) Currently translated at 96.4% (464 of 481 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/zh_Hans/ --- Riot/Assets/zh_Hans.lproj/Vector.strings | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Riot/Assets/zh_Hans.lproj/Vector.strings b/Riot/Assets/zh_Hans.lproj/Vector.strings index eff806971..5f94b21fa 100644 --- a/Riot/Assets/zh_Hans.lproj/Vector.strings +++ b/Riot/Assets/zh_Hans.lproj/Vector.strings @@ -68,7 +68,7 @@ "auth_msisdn_validation_title" = "等待验证中"; "auth_msisdn_validation_message" = "我们通过短信向您发送了一条验证码,请在下方输入它。"; "auth_msisdn_validation_error" = "无法验证此手机号。"; -"auth_recaptcha_message" = "此主服务器想确认你不是机器人"; +"auth_recaptcha_message" = "此主服务器想确保您不是机器人"; "auth_reset_password_message" = "为了重置您的密码,请输入与您帐号关联的邮箱地址:"; "auth_reset_password_missing_email" = "必须输入与您的账户关联的邮箱地址。"; "auth_reset_password_missing_password" = "必须输入新的密码。"; @@ -76,7 +76,7 @@ "auth_reset_password_next_step_button" = "我已经验证了我的邮箱地址"; "auth_reset_password_error_unauthorized" = "验证邮箱地址失败:请确认您已经点击了邮件里的链接"; "auth_reset_password_error_not_found" = "您的邮箱地址貌似没有与此主服务器上的 Matrix ID 绑定。"; -"auth_reset_password_success_message" = "已重置您的密码。\n\n您的所有设备都会被登出并且不会收到推送通知。要想重新收到通知,请在每个设备上重新登录。"; +"auth_reset_password_success_message" = "您的密码已重置。\n\n您的所有设备都会被登出并且不会收到推送通知。要想重新收到通知,请在每个设备上重新登录。"; "auth_add_email_and_phone_warning" = "在 API 出现之前,还不支持使用邮箱地址或手机号码直接注册。只有手机号码会和此账户绑定。您可以在设置中添加邮箱地址。"; // Chat creation "room_creation_title" = "创建聊天"; @@ -198,7 +198,7 @@ "room_delete_unsent_messages" = "删除未发送消息"; "room_event_action_copy" = "复制"; "room_event_action_quote" = "引用"; -"room_event_action_redact" = "移除"; +"room_event_action_redact" = "撤回"; "room_event_action_more" = "移动"; "room_event_action_share" = "分享"; "room_event_action_permalink" = "永久链接"; @@ -398,11 +398,11 @@ // Crash report "google_analytics_use_prompt" = "您打算通过自动报告匿名的崩溃报告和使用数据来帮助提升 %@ 吗?"; // Crypto -"e2e_enabling_on_app_update" = "Riot 目前支持端对端加密但是您需要重新登录来启用。\n\n您可以现在重新登录也可以之后从应用程序设置里选择。"; +"e2e_enabling_on_app_update" = "Riot 目前支持端对端加密,但是您需要重新登录以启用它。\n\n您可以现在重新登录,也可以之后再从应用程序设置中选择开启。"; "e2e_need_log_in_again" = "您需要登录回来以便为此设备生成端对端加密密钥并提交公钥到您的主服务器。\n这只需要做一次;很抱歉造成打扰。"; // Bug report "bug_report_title" = "Bug 报告"; -"bug_report_description" = "请描述此 bug。您做了什么?您期待发生什么?以及实际发生了什么?"; +"bug_report_description" = "请描述此 bug。您做了什么?本来应该发生什么?以及实际发生了什么?"; "bug_crash_report_title" = "崩溃报告"; "bug_crash_report_description" = "请描述崩溃前发生了什么:"; "bug_report_logs_description" = "为了诊断问题,这个客户端的日志会随这个 bug 报告发送。如果你只想发送上面的文字,请取消选择:"; From 3db83896e5432596a5d400059d1a431f20e847db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Kotous?= Date: Fri, 11 May 2018 21:26:40 +0000 Subject: [PATCH 07/51] Translated using Weblate (Czech) Currently translated at 45.5% (219 of 481 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/cs/ --- Riot/Assets/cs.lproj/Vector.strings | 237 +++++++++++++++++++++++++++- 1 file changed, 236 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/cs.lproj/Vector.strings b/Riot/Assets/cs.lproj/Vector.strings index 8b1378917..f1adf0be4 100644 --- a/Riot/Assets/cs.lproj/Vector.strings +++ b/Riot/Assets/cs.lproj/Vector.strings @@ -1 +1,236 @@ - +// Titles +"title_home" = "Domů"; +"title_favourites" = "Oblíbené"; +"title_people" = "Lidé"; +"title_rooms" = "Místnosti"; +"title_groups" = "Komunity"; +"warning" = "Varování!"; +// Actions +"view" = "Zobrazit zdroj"; +"next" = "Další"; +"back" = "Pro zabezpečení se při odhlašování odstraní všechny šifrovací klíče typu end-to-end, a i po přihlašení bude historie šifrovaných kanálů nečitelná.\nZvolte export, chcete-li je zálohovat, než se odhlásíte."; +"continue" = "Pokračovat"; +"create" = "Vytvořit"; +"start" = "Spustit"; +"leave" = "Odejít"; +"remove" = "Odebrat"; +"invite" = "Pozvat"; +"retry" = "Znovu"; +"on" = "Zapnuto"; +"off" = "Vypnuto"; +"cancel" = "Zrušit"; +"save" = "Uložit"; +"join" = "Připojit"; +"decline" = "Odmítnout"; +"accept" = "Přijmout"; +"preview" = "Náhled"; +"camera" = "Kamera"; +"voice" = "Hlas"; +"video" = "Video"; +"active_call" = "Aktivní hovor"; +"active_call_details" = "Aktivní hovor (%@)"; +"later" = "Později"; +"rename" = "Přejmenovat"; +"collapse" = "sbalit"; +"send_to" = "Odeslat do %@"; +"sending" = "Odesílání"; +// Authentication +"auth_login" = "Přihlásit se"; +"auth_register" = "Registrace"; +"auth_submit" = "Potvrdit"; +"auth_skip" = "Přeskočit"; +"auth_send_reset_email" = "Poslat resetovací e-mail"; +"auth_return_to_login" = "Vrátit k přihlašovací obrazovce"; +"auth_user_id_placeholder" = "Email nebo uživatelské jméno"; +"auth_password_placeholder" = "Heslo"; +"auth_new_password_placeholder" = "Nové heslo"; +"auth_user_name_placeholder" = "Uživatelské jméno"; +"auth_optional_email_placeholder" = "E-mailová adresa (nepovinná)"; +"auth_email_placeholder" = "E-mailová adresa"; +"auth_optional_phone_placeholder" = "Číslo mobilního telefonu (nepovinné)"; +"auth_phone_placeholder" = "Telefonní číslo"; +"auth_repeat_password_placeholder" = "Zopakovat heslo"; +"auth_repeat_new_password_placeholder" = "Potvrďte své nové heslo"; +"auth_home_server_placeholder" = "URL (např. https://matrix.org)"; +"auth_identity_server_placeholder" = "URL (např. https://matrix.org)"; +"auth_invalid_login_param" = "Nesprávné uživatelské jméno nebo heslo"; +"auth_invalid_user_name" = "Uživatelské jméno může obsahovat pouze písmena, číslice, tečky, pomlčky a podtržítka"; +"auth_invalid_password" = "Heslo je velmi krátké (min 6)"; +"auth_invalid_email" = "Zdá se, že toto není platná emailová adresa"; +"auth_invalid_phone" = "Zdá se, že toto není platné telefonní číslo"; +"auth_missing_password" = "Chybí heslo"; +"auth_add_email_message" = "Přidat emailovou adresu k vašemu účtu aby vás mohli ostatní uživatelé najít a abyste si mohl vyresetovat heslo."; +"auth_add_phone_message" = "Přidat telefonní číslo k vašemu účtu aby vás mohli ostatní uživatelé najít."; +"auth_missing_email" = "Chybí emailová adresa"; +"auth_missing_phone" = "Chybí telefonní číslo"; +"auth_missing_email_or_phone" = "Chybí emailová adresa nebo telefonní číslo"; +"auth_email_in_use" = "Tato e-mailová adresa je již používaná"; +"auth_phone_in_use" = "Toto číslo se již používá"; +"auth_untrusted_id_server" = "Server identit není důvěryhodný"; +"auth_password_dont_match" = "Hesla se neshodují"; +"auth_username_in_use" = "Uživatelské jméno je použito"; +"auth_forgot_password" = "Zapomenuté heslo?"; +"auth_email_not_found" = "Chyba odeslání emailu: Tato emailová adresa nebyla nalezena"; +"auth_use_server_options" = "Použít vlastní možnosti serveru (pokročilé)"; +"auth_email_validation_message" = "Prosím zkontrolujte své emaily, abyste mohli pokračovat v registraci"; +"auth_msisdn_validation_title" = "Čeká na ověření"; +"auth_recaptcha_message" = "Tento domovský server by se rád přesvědčil, že nejste robot"; +"auth_reset_password_message" = "K resetování hesla vložte e-mailovou adresu spojenou s vaším účtem:"; +"auth_reset_password_missing_email" = "Musíte zadat emailovou adresu spojenou s vaším účtem."; +"auth_reset_password_missing_password" = "Musíte zadat nové heslo."; +"auth_reset_password_email_validation_message" = "Na adresu %@ byla odeslána zpráva. Potom, co přejdete na odkaz z této zprávy, klikněte níže."; +"auth_reset_password_next_step_button" = "Ověřil/a jsem svoji e-mailovou adresu"; +"auth_reset_password_error_unauthorized" = "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz"; +"auth_reset_password_error_not_found" = "Vaše e-mailová adresa zřejmě nepatří k žádnému Matrix ID na tomto domovském serveru."; +// Chat creation +"room_creation_title" = "Nový chat"; +"room_creation_account" = "Účet"; +"room_creation_appearance" = "Přítomnost"; +"room_creation_appearance_name" = "Jméno"; +"room_creation_privacy" = "Soukromí"; +"room_creation_private_room" = "Tento chat je soukromý"; +"room_creation_public_room" = "Tento chat je veřejný"; +"room_creation_make_public" = "Zveřejnit"; +"room_creation_make_public_prompt_title" = "Zveřejnit tento chat?"; +"room_creation_keep_private" = "Zachovat jako soukromí"; +"room_creation_make_private" = "Nastavit jako soukromé"; +"room_creation_wait_for_creation" = "Místnost byla již vytvořena. Prosím vyčkejte."; +"room_creation_invite_another_user" = "Hledat / Pozvat podle uživatelského ID, jména nebo emailu"; +// Room recents +"room_recents_directory_section" = "ADRESÁŘ MÍSTNOSTÍ"; +"room_recents_directory_section_network" = "Síť"; +"room_recents_favourites_section" = "OBLÍBENÉ"; +"room_recents_people_section" = "LIDÉ"; +"room_recents_conversations_section" = "MÍSTNOSTI"; +"room_recents_no_conversation" = "Žádne místností"; +"room_recents_low_priority_section" = "NÍZKÁ PRIORITA"; +"room_recents_invites_section" = "POZVÁNÍ"; +"room_recents_start_chat_with" = "Začít chat"; +"room_recents_create_empty_room" = "Vytvořit místnost"; +"room_recents_join_room" = "Připojit se k místnosti"; +"room_recents_join_room_title" = "Připojit se k místnosti"; +// People tab +"people_invites_section" = "POZVÁNÍ"; +"people_conversation_section" = "KONVERZACE"; +"people_no_conversation" = "Žádné konverzace"; +// Rooms tab +"room_directory_no_public_room" = "Žádné veřejné mistnosti nejsou k dispozici"; +// Groups tab +"group_invite_section" = "POZVÁNÍ"; +"group_section" = "KOMUNITY"; +// Search +"search_rooms" = "Místnosti"; +"search_messages" = "Zprávy"; +"search_people" = "Lidé"; +"search_files" = "Soubory"; +"search_default_placeholder" = "Hledat"; +"search_people_placeholder" = "Hledat dle uživatelského ID, jména nebo emailu"; +"search_no_result" = "Žádné výsledky"; +"search_in_progress" = "Hledání…"; +// Directory +"directory_cell_title" = "Procházet adresář"; +"directory_cell_description" = "%tu místnosti"; +"directory_search_results_title" = "Procházet výsledky výhledávání v adresáři"; +"directory_search_results" = "%tu výsledky nalezeny pro %@"; +"directory_search_results_more_than" = ">%tu výsledky nalezeny pro %@"; +"directory_searching_title" = "Vyhledávání v adresáři…"; +"directory_search_fail" = "Chyba získání dat"; +// Contacts +"contacts_address_book_section" = "LOKÁLNÍ KONTAKTY"; +"contacts_address_book_matrix_users_toggle" = "Pouze Matrix uživatelé"; +"contacts_address_book_no_contact" = "Žádné lokální kontakty"; +"contacts_address_book_permission_denied" = "Nepovolil jste přístup aplikace Riot k místním kontaktům"; +"contacts_user_directory_section" = "UŽIVATELSKÝ ADRESÁŘ"; +"contacts_user_directory_offline_section" = "UŽIVATELSKÝ ADRESÁŘ (offline)"; +// Chat participants +"room_participants_title" = "Účastníci"; +"room_participants_add_participant" = "Přidat účastníka"; +"room_participants_one_participant" = "1 účastník"; +"room_participants_multi_participants" = "%d účastníci"; +"room_participants_leave_prompt_title" = "Odejít z místnosti"; +"room_participants_leave_prompt_msg" = "Opravdu chcete opustit tuto místnost?"; +"room_participants_remove_prompt_title" = "Potvrzení"; +"room_participants_invite_prompt_title" = "Potvrzení"; +"room_participants_filter_room_members" = "Filtrovat členy místnosti"; +"room_participants_invite_malformed_id_title" = "Chyba pozvání"; +"room_participants_invited_section" = "POZVANÍ"; +"room_participants_online" = "Online"; +"room_participants_offline" = "Offline"; +"room_participants_unknown" = "Neznámý"; +"room_participants_idle" = "Nečinný/á"; +"room_participants_now" = "nyní"; +"room_participants_ago" = "před"; +"room_participants_action_section_admin_tools" = "Nástroje pro správce"; +"room_participants_action_section_direct_chats" = "Přímé chaty"; +"room_participants_action_section_devices" = "Zařízení"; +"room_participants_action_section_other" = "Další"; +"room_participants_action_invite" = "Pozvat"; +"room_participants_action_leave" = "Odejít z místnosti"; +"room_participants_action_remove" = "Odebrat z této místnosti"; +"room_participants_action_unban" = "Přijmout zpět"; +"room_participants_action_ignore" = "Schovat všechny zprávy od tohoto uživatele"; +"room_participants_action_unignore" = "Zobrazit všechny zprávy od tohoto uživatele"; +"room_participants_action_set_default_power_level" = "Resetovat na normálního uživatele"; +"room_participants_action_set_moderator" = "Udělit moderátorství"; +"room_participants_action_set_admin" = "Udělit admin práva"; +"room_participants_action_start_new_chat" = "Začít novou konverzaci"; +"room_participants_action_start_voice_call" = "Začít hlasový hovor"; +"room_participants_action_start_video_call" = "Začít video hovor"; +"room_participants_action_mention" = "Zmínka"; +// Chat +"room_jump_to_first_unread" = "Přeskočit na první nepřečtenou zprávu"; +"room_new_message_notification" = "%d nová zpráva"; +"room_new_messages_notification" = "%d nových zpráv"; +"room_one_user_is_typing" = "%@ právě píše…"; +"room_two_users_are_typing" = "%@ & %@ právě píšou…"; +"room_many_users_are_typing" = "%@, %@ a další píší…"; +"room_message_placeholder" = "Odeslat zprávu (nešifrovanou)…"; +"room_do_not_have_permission_to_post" = "Na přispívání do této místnosti nemáte právo"; +"encrypted_room_message_placeholder" = "Odeslat šifrovanou zprávu…"; +"room_message_short_placeholder" = "Odeslat zprávu…"; +"room_offline_notification" = "Spojení se serverem bylo přerušené."; +"room_ongoing_conference_call_close" = "Zavřít"; +"room_prompt_resend" = "Znovu poslat vše"; +"room_prompt_cancel" = "zrušit vše"; +"room_resend_unsent_messages" = "Znovu poslat neodeslané zprávy"; +"room_delete_unsent_messages" = "Smazat neodeslané zprávy"; +"room_event_action_copy" = "Kopírovat"; +"room_event_action_quote" = "Citovat"; +"room_event_action_redact" = "Redigovat"; +"room_event_action_more" = "Víc"; +"room_event_action_share" = "Sdílet"; +"room_event_action_permalink" = "Trvalý odkaz"; +"room_event_action_view_source" = "Zobrazit zdroj"; +"room_event_action_report" = "Nahlasit obsah"; +"room_event_action_report_prompt_reason" = "Důvod proč nahlásit obsah"; +"room_event_action_save" = "Uložit"; +"room_event_action_resend" = "Poslat znovu"; +"room_event_action_delete" = "Odstranit"; +"room_event_action_cancel_send" = "Zrušit odesílání"; +"room_event_action_cancel_download" = "Zrušit stahování"; +"room_event_action_view_encryption" = "Informace o šifrování"; +"room_event_failed_to_send" = "Odeslání se nezdařilo"; +// Unknown devices +"unknown_devices_alert_title" = "V místnosti jsou neznámá zařízení"; +"unknown_devices_send_anyway" = "Přesto poslat"; +"unknown_devices_call_anyway" = "Přesto zavolat"; +"unknown_devices_answer_anyway" = "Přesto přijmout"; +"unknown_devices_verify" = "Ověřit…"; +"unknown_devices_title" = "Neznámá zařízení"; +// Room Title +"room_title_new_room" = "Nová místnost"; +"room_participants_invite_another_user" = "Hledat / Pozvat podle uživatelského ID, jména nebo emailu"; +"room_ongoing_conference_call" = "Probíhající konferenční hovor. Připojit se jako %@ nebo %@."; +"room_ongoing_conference_call_with_close" = "Probíhající konferenční hovor. Připojit se jako %@ nebo %@. %@ to."; +"room_title_invite_members" = "Pozvat členy"; +"room_title_one_member" = "1 člen"; +// Room Preview +"room_preview_invitation_format" = "%@ vás pozval/a ke vstupu do této místnosti"; +"room_preview_subtitle" = "Toto je náhled místnosti. Interakce byly zakázány."; +// Settings +"settings_title" = "Nastavení"; +"account_logout_all" = "Odhlásit všechny účty"; +"settings_report_bug" = "Nahlásit chybu"; +"settings_config_home_server" = "Domácího serveru je %@"; +"settings_config_identity_server" = "Server identit je %@"; +"settings_config_user_id" = "Přihlášen/a jako %@"; From b6d25d747f85826ba59a0b0e36c5df18aa531b07 Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:46:08 +0000 Subject: [PATCH 08/51] Translated using Weblate (Italian) Currently translated at 0.8% (4 of 481 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/it/ --- Riot/Assets/it.lproj/Vector.strings | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings index 8b1378917..2faf46584 100644 --- a/Riot/Assets/it.lproj/Vector.strings +++ b/Riot/Assets/it.lproj/Vector.strings @@ -1 +1,5 @@ - +// Titles +"title_home" = "Home"; +"title_favourites" = "Preferiti"; +"title_people" = "Persone"; +"title_rooms" = "Stanze"; From eb9e7a1751e5cfcbe7bc9cb8f35e1c2f763ddd87 Mon Sep 17 00:00:00 2001 From: Scott Rothrock Date: Wed, 25 Apr 2018 05:58:00 +0000 Subject: [PATCH 09/51] Translated using Weblate (Japanese) Currently translated at 100.0% (4 of 4 strings) Translation: Riot iOS/Riot iOS (Dialogs) Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios-dialogs/ja/ --- Riot/Assets/ja.lproj/InfoPlist.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/ja.lproj/InfoPlist.strings b/Riot/Assets/ja.lproj/InfoPlist.strings index db52412af..27cd8cb99 100644 --- a/Riot/Assets/ja.lproj/InfoPlist.strings +++ b/Riot/Assets/ja.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ // Permissions usage explanations -"NSCameraUsageDescription" = "カメラや写真撮影や動画撮影、映像付き通話のために使用されます。"; +"NSCameraUsageDescription" = "ビデオ通話や写真撮影、動画撮影などを行うときにカメラを使用します。"; "NSPhotoLibraryUsageDescription" = "フォトライブラリは、写真や動画の送信に使用されます。"; "NSMicrophoneUsageDescription" = "マイクは動画撮影や通話に使用されます。"; "NSContactsUsageDescription" = "本体内の連絡先、アドレス帳は、Riotのユーザを電子メールアドレスや電話番号で検索する際に使用します。"; From e28533abae0c615deebc7e23abf518f04222f1a1 Mon Sep 17 00:00:00 2001 From: Simone Salsi Date: Wed, 2 May 2018 20:44:04 +0000 Subject: [PATCH 10/51] Translated using Weblate (Italian) Currently translated at 57.6% (15 of 26 strings) Translation: Riot iOS/Riot iOS (Push) Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios-push/it/ --- Riot/Assets/it.lproj/Localizable.strings | 31 +++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/it.lproj/Localizable.strings b/Riot/Assets/it.lproj/Localizable.strings index 8b1378917..3ca46524d 100644 --- a/Riot/Assets/it.lproj/Localizable.strings +++ b/Riot/Assets/it.lproj/Localizable.strings @@ -1 +1,30 @@ - +/* New message from a specific person, not referencing a room */ +"MSG_FROM_USER" = "Messaggio ricevuto da %@"; +/* New message from a specific person in a named room */ +"MSG_FROM_USER_IN_ROOM" = "%@ ha scritto in %@"; +/* New message from a specific person, not referencing a room. Content included. */ +"MSG_FROM_USER_WITH_CONTENT" = "%@: %@"; +/* New message from a specific person in a named room. Content included. */ +"MSG_FROM_USER_IN_ROOM_WITH_CONTENT" = "%@ in %@: %@"; +/* New action message from a specific person, not referencing a room. */ +"ACTION_FROM_USER" = "* %@ %@"; +/* New action message from a specific person in a named room. */ +"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@"; +/* New action message from a specific person, not referencing a room. */ +"IMAGE_FROM_USER" = "%@ ha inviato un'immagine %@"; +/* New action message from a specific person in a named room. */ +"IMAGE_FROM_USER_IN_ROOM" = "%@ ha inviato un'immagine %@ in %@"; +/* A single unread message in a room */ +"SINGLE_UNREAD_IN_ROOM" = "Hai ricevuto un messaggio in %@"; +/* A single unread message */ +"SINGLE_UNREAD" = "Hai ricevuto un messaggio"; +/* Multiple unread messages in a room */ +"UNREAD_IN_ROOM" = "%@ nuovi messaggi in %@"; +/* Multiple unread messages from a specific person, not referencing a room */ +"MSGS_FROM_USER" = "%@ nuovi messaggi in %@"; +/* Multiple unread messages from two people */ +"MSGS_FROM_TWO_USERS" = "%@ nuovi messaggi da %@ e %@"; +/* Multiple unread messages from three people */ +"MSGS_FROM_THREE_USERS" = "%@ nuovi messaggi da %@, %@ e %@"; +/* Multiple unread messages from two plus people (ie. for 4+ people: 'others' replaces the third person) */ +"MSGS_FROM_TWO_PLUS_USERS" = "%@ nuovi messaggi da %@, %@ e altri"; From 7e8ec597d6a25af9442b7ffe4534d3a74ac653a6 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 24 May 2018 04:40:15 +0000 Subject: [PATCH 11/51] Translated using Weblate (Russian) Currently translated at 100.0% (483 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/ru/ --- Riot/Assets/ru.lproj/Vector.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/ru.lproj/Vector.strings b/Riot/Assets/ru.lproj/Vector.strings index caff4eeec..59a0da223 100644 --- a/Riot/Assets/ru.lproj/Vector.strings +++ b/Riot/Assets/ru.lproj/Vector.strings @@ -518,3 +518,6 @@ "room_details_flair_section" = "Показать настроение для сообществ"; "room_event_action_kick_prompt_reason" = "Причина по которой этот пользователь будет выкинут"; "room_event_action_ban_prompt_reason" = "Причина по которой этот пользователь будет забанен"; +// GDPR +"gdpr_consent_not_given_alert_message" = "Для продолжения использования сервера %@ вы должны принять условия и положения."; +"gdpr_consent_not_given_alert_review_now_action" = "Просмотреть сейчас"; From 68f10e4129cd10ff0ec6583b9a1640d319791d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 24 May 2018 07:40:59 +0000 Subject: [PATCH 12/51] Translated using Weblate (French) Currently translated at 100.0% (483 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/fr/ --- Riot/Assets/fr.lproj/Vector.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index 796fd0f0d..2b66993ad 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -517,3 +517,6 @@ "room_do_not_have_permission_to_post" = "Vous n'avez pas la permission d'envoyer des messages dans ce salon"; "room_event_action_kick_prompt_reason" = "Raison de l'exclusion de l'utilisateur"; "room_event_action_ban_prompt_reason" = "Raison du bannissement de l'utilisateur"; +// GDPR +"gdpr_consent_not_given_alert_message" = "Pour continuer à utiliser le serveur d'accueil %@, vous devez lire et accepter les conditions générales."; +"gdpr_consent_not_given_alert_review_now_action" = "Voir maintenant"; From 4abdabc87e0598a8b634658baf86c15ebbf1bcd5 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Thu, 24 May 2018 07:48:51 +0000 Subject: [PATCH 13/51] Translated using Weblate (Basque) Currently translated at 100.0% (483 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/eu/ --- Riot/Assets/eu.lproj/Vector.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/eu.lproj/Vector.strings b/Riot/Assets/eu.lproj/Vector.strings index bbcd2f139..49dc621a3 100644 --- a/Riot/Assets/eu.lproj/Vector.strings +++ b/Riot/Assets/eu.lproj/Vector.strings @@ -519,3 +519,6 @@ "room_do_not_have_permission_to_post" = "Ez duzu gela honetara mezuak bidaltzeko baimenik"; "room_event_action_kick_prompt_reason" = "Erabiltzaile hau kanporatzeko arrazoia"; "room_event_action_ban_prompt_reason" = "Erabiltzaile hau debekatzeko arrazoia"; +// GDPR +"gdpr_consent_not_given_alert_message" = "%@ hasiera-zerbitzaria erabiltzen jarraitzeko erabilera baldintzak irakurri eta onartu behar dituzu."; +"gdpr_consent_not_given_alert_review_now_action" = "Irakurri orain"; From 9690c5a924ddafd03fc7defcbff9ea1b2966d783 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 11:56:33 +0200 Subject: [PATCH 14/51] Send sticker: UI integration: RoomInputToolbar: Let user choose between "Send photo or video" and "Send sticker" https://github.com/vector-im/riot-ios/issues/1860 --- Riot/Assets/en.lproj/Vector.strings | 4 + .../RoomInputToolbar/RoomInputToolbarView.h | 16 +++ .../RoomInputToolbar/RoomInputToolbarView.m | 120 +++++++++++++----- 3 files changed, 107 insertions(+), 33 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index d17a8f452..eb29d2426 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -267,6 +267,8 @@ "room_event_action_view_encryption" = "Encryption Information"; "room_warning_about_encryption" = "End-to-end encryption is in beta and may not be reliable.\n\nYou should not yet trust it to secure data.\n\nDevices will not yet be able to decrypt history from before they joined the room.\n\nEncrypted messages will not be visible on clients that do not yet implement encryption."; "room_event_failed_to_send" = "Failed to send"; +"room_action_send_photo_or_video" = "Send photo or video"; +"room_action_send_sticker" = "Send sticker"; // Unknown devices "unknown_devices_alert_title" = "Room contains unknown devices"; @@ -568,6 +570,8 @@ // Widget "widget_no_power_to_manage" = "You need permission to manage widgets in this room"; "widget_creation_failure" = "Widget creation has failed"; +"widget_sticker_picker_no_stickerpacks_alert" = "You don't currently have any stickerpacks enabled."; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "Add some now?"; // Widget Integration Manager "widget_integration_need_to_be_able_to_invite" = "You need to be able to invite users to do that."; diff --git a/Riot/Views/RoomInputToolbar/RoomInputToolbarView.h b/Riot/Views/RoomInputToolbar/RoomInputToolbarView.h index 0f5797583..ccf18e143 100644 --- a/Riot/Views/RoomInputToolbar/RoomInputToolbarView.h +++ b/Riot/Views/RoomInputToolbar/RoomInputToolbarView.h @@ -18,12 +18,28 @@ #import "MediaPickerViewController.h" +@protocol RoomInputToolbarViewDelegate + +/** + Tells the delegate that the user wants to display the sticker picker. + + @param toolbarView the room input toolbar view. + */ +- (void)roomInputToolbarViewPresentStickerPicker:(MXKRoomInputToolbarView*)toolbarView; + +@end + /** `RoomInputToolbarView` instance is a view used to handle all kinds of available inputs for a room (message composer, attachments selection...). */ @interface RoomInputToolbarView : MXKRoomInputToolbarViewWithHPGrowingText +/** + The delegate notified when inputs are ready. + */ +@property (nonatomic) id delegate; + @property (weak, nonatomic) IBOutlet UIView *mainToolbarView; @property (weak, nonatomic) IBOutlet UIView *separatorView; diff --git a/Riot/Views/RoomInputToolbar/RoomInputToolbarView.m b/Riot/Views/RoomInputToolbar/RoomInputToolbarView.m index cd30b6802..47c243199 100644 --- a/Riot/Views/RoomInputToolbar/RoomInputToolbarView.m +++ b/Riot/Views/RoomInputToolbar/RoomInputToolbarView.m @@ -29,17 +29,21 @@ #import +#import "WidgetManager.h" +#import "IntegrationManagerViewController.h" + @interface RoomInputToolbarView() { MediaPickerViewController *mediaPicker; - // The call type selection (voice or video) - UIAlertController *callActionSheet; + // The intermediate action sheet + UIAlertController *actionSheet; } @end @implementation RoomInputToolbarView +@dynamic delegate; + (UINib *)nib { @@ -228,24 +232,53 @@ // Check whether media attachment is supported if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:presentViewController:)]) { - // MediaPickerViewController is based on the Photos framework. So it is available only for iOS 8 and later. - Class PHAsset_class = NSClassFromString(@"PHAsset"); - if (PHAsset_class) - { - mediaPicker = [MediaPickerViewController mediaPickerViewController]; - mediaPicker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie]; - mediaPicker.delegate = self; - UINavigationController *navigationController = [UINavigationController new]; - [navigationController pushViewController:mediaPicker animated:NO]; - - [self.delegate roomInputToolbarView:self presentViewController:navigationController]; - } - else - { - // We use UIImagePickerController by default for iOS < 8 - self.leftInputToolbarButton = self.attachMediaButton; - [super onTouchUpInside:self.leftInputToolbarButton]; - } + // Ask the user the kind of the call: voice or video? + actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + + __weak typeof(self) weakSelf = self; + [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_action_send_photo_or_video", @"Vector", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + + if (weakSelf) + { + typeof(self) self = weakSelf; + self->actionSheet = nil; + + [self showMediaPicker]; + } + + }]]; + + [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_action_send_sticker", @"Vector", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + + if (weakSelf) + { + typeof(self) self = weakSelf; + self->actionSheet = nil; + + [self.delegate roomInputToolbarViewPresentStickerPicker:self]; + } + + }]]; + + [actionSheet addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { + + if (weakSelf) + { + typeof(self) self = weakSelf; + self->actionSheet = nil; + } + + }]]; + + [actionSheet popoverPresentationController].sourceView = self.voiceCallButton; + [actionSheet popoverPresentationController].sourceRect = self.voiceCallButton.bounds; + [self.window.rootViewController presentViewController:actionSheet animated:YES completion:nil]; } else { @@ -257,52 +290,52 @@ if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:placeCallWithVideo:)]) { // Ask the user the kind of the call: voice or video? - callActionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; __weak typeof(self) weakSelf = self; - [callActionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"voice", @"Vector", nil) + [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"voice", @"Vector", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { typeof(self) self = weakSelf; - self->callActionSheet = nil; + self->actionSheet = nil; [self.delegate roomInputToolbarView:self placeCallWithVideo:NO]; } }]]; - [callActionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"video", @"Vector", nil) + [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"video", @"Vector", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { typeof(self) self = weakSelf; - self->callActionSheet = nil; + self->actionSheet = nil; [self.delegate roomInputToolbarView:self placeCallWithVideo:YES]; } }]]; - [callActionSheet addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + [actionSheet addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { if (weakSelf) { typeof(self) self = weakSelf; - self->callActionSheet = nil; + self->actionSheet = nil; } }]]; - [callActionSheet popoverPresentationController].sourceView = self.voiceCallButton; - [callActionSheet popoverPresentationController].sourceRect = self.voiceCallButton.bounds; - [self.window.rootViewController presentViewController:callActionSheet animated:YES completion:nil]; + [actionSheet popoverPresentationController].sourceView = self.voiceCallButton; + [actionSheet popoverPresentationController].sourceRect = self.voiceCallButton.bounds; + [self.window.rootViewController presentViewController:actionSheet animated:YES completion:nil]; } } else if (button == self.hangupCallButton) @@ -316,15 +349,36 @@ [super onTouchUpInside:button]; } +- (void)showMediaPicker +{ + // MediaPickerViewController is based on the Photos framework. So it is available only for iOS 8 and later. + Class PHAsset_class = NSClassFromString(@"PHAsset"); + if (PHAsset_class) + { + mediaPicker = [MediaPickerViewController mediaPickerViewController]; + mediaPicker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie]; + mediaPicker.delegate = self; + UINavigationController *navigationController = [UINavigationController new]; + [navigationController pushViewController:mediaPicker animated:NO]; + + [self.delegate roomInputToolbarView:self presentViewController:navigationController]; + } + else + { + // We use UIImagePickerController by default for iOS < 8 + self.leftInputToolbarButton = self.attachMediaButton; + [super onTouchUpInside:self.leftInputToolbarButton]; + } +} - (void)destroy { [self dismissMediaPicker]; - if (callActionSheet) + if (actionSheet) { - [callActionSheet dismissViewControllerAnimated:NO completion:nil]; - callActionSheet = nil; + [actionSheet dismissViewControllerAnimated:NO completion:nil]; + actionSheet = nil; } [super destroy]; From 80e6502aeb727da764518e000a0cc2ec2694cd05 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 14:36:09 +0200 Subject: [PATCH 15/51] Send sticker: WidgetManager: add userWidgets:ofTypes method https://github.com/vector-im/riot-ios/issues/1860 --- Riot/Utils/Widgets/WidgetManager.h | 10 ++++++++++ Riot/Utils/Widgets/WidgetManager.m | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Riot/Utils/Widgets/WidgetManager.h b/Riot/Utils/Widgets/WidgetManager.h index 655a88aba..315e363e8 100644 --- a/Riot/Utils/Widgets/WidgetManager.h +++ b/Riot/Utils/Widgets/WidgetManager.h @@ -35,6 +35,7 @@ FOUNDATION_EXPORT NSString *const kWidgetModularEventTypeString; Known types widgets. */ FOUNDATION_EXPORT NSString *const kWidgetTypeJitsi; +FOUNDATION_EXPORT NSString *const kWidgetTypeStickerPicker; /** Posted when a widget has been created, updated or disabled. @@ -101,6 +102,15 @@ WidgetManagerErrorCode; */ - (NSArray *)userWidgets:(MXSession*)mxSession; +/** + List all widgets of a given type of an account. + + @param mxSession the session of the user account. + @param widgetTypes the types of widget to search. Nil means all types. + @return a list of widgets. + */ +- (NSArray *)userWidgets:(MXSession*)mxSession ofTypes:(NSArray*)widgetTypes; + /** Add a modular widget to a room. diff --git a/Riot/Utils/Widgets/WidgetManager.m b/Riot/Utils/Widgets/WidgetManager.m index 48f753e64..cdbfb9835 100644 --- a/Riot/Utils/Widgets/WidgetManager.m +++ b/Riot/Utils/Widgets/WidgetManager.m @@ -23,6 +23,7 @@ NSString *const kWidgetMatrixEventTypeString = @"m.widget"; NSString *const kWidgetModularEventTypeString = @"im.vector.modular.widgets"; NSString *const kWidgetTypeJitsi = @"jitsi"; +NSString *const kWidgetTypeStickerPicker = @"m.stickerpicker"; NSString *const kWidgetManagerDidUpdateWidgetNotification = @"kWidgetManagerDidUpdateWidgetNotification"; @@ -173,12 +174,23 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain"; } - (NSArray *)userWidgets:(MXSession*)mxSession +{ + return [self userWidgets:mxSession ofTypes:nil]; +} + +- (NSArray *)userWidgets:(MXSession*)mxSession ofTypes:(NSArray*)widgetTypes { // Get all widgets in the user account data NSMutableArray *userWidgets = [NSMutableArray array]; - for (NSDictionary *widgetEventContent in [mxSession.accountData accountDataForEventType:@"m.widgets"].allValues) + for (NSDictionary *widgetEventContent in [mxSession.accountData accountDataForEventType:kMXAccountDataTypeUserWidgets].allValues) { - // Patch: Modular uses a malformed key: "stateKey" instead of "state_key" + if (![widgetEventContent isKindOfClass:NSDictionary.class]) + { + NSLog(@"[WidgetManager] userWidgets: ERROR: invalid user widget format: %@", widgetEventContent); + continue; + } + + // Patch: Modular used a malformed key: "stateKey" instead of "state_key" // TODO: To remove once fixed server side NSDictionary *widgetEventContentFixed = widgetEventContent; if (!widgetEventContent[@"state_key"] && widgetEventContent[@"stateKey"]) @@ -189,7 +201,8 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain"; } MXEvent *widgetEvent = [MXEvent modelFromJSON:widgetEventContentFixed]; - if (widgetEvent) + if (widgetEvent + && (!widgetTypes || [widgetTypes containsObject:widgetEvent.content[@"type"]])) { Widget *widget = [[Widget alloc] initWithWidgetEvent:widgetEvent inMatrixSession:mxSession]; if (widget) From 3891c3ce50648f238d9706544241facf18e1141c Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 14:42:49 +0200 Subject: [PATCH 16/51] Send sticker: IntegrationManagerVC: add the ability to set a user widget https://github.com/vector-im/riot-ios/issues/1860 --- .../IntegrationManagerViewController.h | 8 + .../IntegrationManagerViewController.m | 178 ++++++++++++------ 2 files changed, 130 insertions(+), 56 deletions(-) diff --git a/Riot/ViewController/Widgets/IntegrationManagerViewController.h b/Riot/ViewController/Widgets/IntegrationManagerViewController.h index 3087c57f1..8edc670ce 100644 --- a/Riot/ViewController/Widgets/IntegrationManagerViewController.h +++ b/Riot/ViewController/Widgets/IntegrationManagerViewController.h @@ -37,4 +37,12 @@ FOUNDATION_EXPORT NSString *const kIntegrationManagerAddIntegrationScreen; */ - (instancetype)initForMXSession:(MXSession*)mxSession inRoom:(NSString*)roomId screen:(NSString*)screen widgetId:(NSString*)widgetId; +/** + Get the integration manager settings screen for a given widget type. + + @param widgetType the widget type. + @return the screen id for that widget type. + */ ++ (NSString*)screenForWidget:(NSString*)widgetType; + @end diff --git a/Riot/ViewController/Widgets/IntegrationManagerViewController.m b/Riot/ViewController/Widgets/IntegrationManagerViewController.m index 86e118ecb..e00ac8f7b 100644 --- a/Riot/ViewController/Widgets/IntegrationManagerViewController.m +++ b/Riot/ViewController/Widgets/IntegrationManagerViewController.m @@ -50,6 +50,11 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; return self; } ++ (NSString*)screenForWidget:(NSString*)widgetType +{ + return [NSString stringWithFormat:@"type_%@", widgetType]; +} + - (void)destroy { [super destroy]; @@ -147,8 +152,25 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; if (!roomIdInEvent) { - [self sendLocalisedError:@"widget_integration_missing_room_id" toRequest:requestId]; - return; + // These APIs don't require roomId + // Get and set user widgets (not associated with a specific room) + // If roomId is specified, it must be validated, so room-based widgets agreed + // handled further down. + if ([@"set_widget" isEqualToString:action]) + { + [self setWidget:requestId data:requestData]; + return; + } + else if ([@"get_widgets" isEqualToString:action]) + { + [self getWidgets:requestId data:requestData]; + return; + } + else + { + [self sendLocalisedError:@"widget_integration_missing_room_id" toRequest:requestId]; + return; + } } if (![roomIdInEvent isEqualToString:roomId]) @@ -157,7 +179,6 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; return; } - // These APIs don't require userId if ([@"join_rules_state" isEqualToString:action]) { @@ -281,75 +302,120 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; - (void)setWidget:(NSString*)requestId data:(NSDictionary*)requestData { - NSLog(@"[IntegrationManagerVC] Received request to set widget in room %@.", roomId); + NSLog(@"[IntegrationManagerVC] Received request to set widget"); - MXRoom *room = [self roomCheckForRequest:requestId data:requestData]; + NSString *widget_id, *widgetType, *widgetUrl; + NSString *widgetName; // optional + NSDictionary *widgetData ; // optional + BOOL userWidget = NO; - if (room) + MXJSONModelSetString(widget_id, requestData[@"widget_id"]); + MXJSONModelSetString(widgetType, requestData[@"type"]); + MXJSONModelSetString(widgetUrl, requestData[@"url"]); + MXJSONModelSetString(widgetName, requestData[@"name"]); + MXJSONModelSetDictionary(widgetData, requestData[@"data"]); + MXJSONModelSetBoolean(userWidget, requestData[@"userWidget"]); + + if (!widget_id) { - NSString *widget_id, *widgetType, *widgetUrl; - NSString *widgetName; // optional - NSDictionary *widgetData ; // optional + [self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; // new Error("Missing required widget fields.")); + return; + } - MXJSONModelSetString(widget_id, requestData[@"widget_id"]); - MXJSONModelSetString(widgetType, requestData[@"type"]); - MXJSONModelSetString(widgetUrl, requestData[@"url"]); - MXJSONModelSetString(widgetName, requestData[@"name"]); - MXJSONModelSetDictionary(widgetData, requestData[@"data"]); + if (!widgetType) + { + [self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; + return; + } - if (!widget_id) + NSMutableDictionary *widgetEventContent = [NSMutableDictionary dictionary]; + if (widgetUrl) + { + widgetEventContent[@"type"] = widgetType; + widgetEventContent[@"url"] = widgetUrl; + + if (widgetName) { - [self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; // new Error("Missing required widget fields.")); - return; + widgetEventContent[@"name"] = widgetName; } + if (widgetData) + { + widgetEventContent[@"data"] = widgetData; + } + } + // else this is a deletion - NSMutableDictionary *widgetEventContent = [NSMutableDictionary dictionary]; + __weak __typeof__(self) weakSelf = self; + + if (userWidget) + { + // Update the user account data + NSMutableDictionary *userWidgets = [NSMutableDictionary dictionaryWithDictionary:[mxSession.accountData accountDataForEventType:kMXAccountDataTypeUserWidgets]]; + + // Delete existing widget with ID + [userWidgets removeObjectForKey:widget_id]; + + // Add new widget / update if (widgetUrl) { - if (!widgetType) - { - [self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; - return; - } - - widgetEventContent[@"type"] = widgetType; - widgetEventContent[@"url"] = widgetUrl; - - if (widgetName) - { - widgetEventContent[@"name"] = widgetName; - } - if (widgetData) - { - widgetEventContent[@"data"] = widgetData; - } + userWidgets[widget_id] = @{ + @"content": widgetEventContent, + @"sender": mxSession.myUser.userId, + @"state_key": widget_id, + @"type": kWidgetMatrixEventTypeString, + @"id": widget_id, + }; } - __weak __typeof__(self) weakSelf = self; + [mxSession setAccountData:userWidgets forType:kMXAccountDataTypeUserWidgets success:^{ - // TODO: Move to kWidgetMatrixEventTypeString ("m.widget") type but when? - [room sendStateEventOfType:kWidgetModularEventTypeString - content:widgetEventContent - stateKey:widget_id - success:^(NSString *eventId) { + typeof(self) self = weakSelf; + if (self) + { + [self sendNSObjectResponse:@{ + @"success": @(YES) + } + toRequest:requestId]; + } + } failure:^(NSError *error) { - typeof(self) self = weakSelf; - if (self) - { - [self sendNSObjectResponse:@{ - @"success": @(YES) - } - toRequest:requestId]; + typeof(self) self = weakSelf; + if (self) + { + [self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; + } + }]; + } + else + { + // Room widget + MXRoom *room = [self roomCheckForRequest:requestId data:requestData]; + if (room) + { + // TODO: Move to kWidgetMatrixEventTypeString ("m.widget") type but when? + [room sendStateEventOfType:kWidgetModularEventTypeString + content:widgetEventContent + stateKey:widget_id + success:^(NSString *eventId) { + + typeof(self) self = weakSelf; + if (self) + { + [self sendNSObjectResponse:@{ + @"success": @(YES) + } + toRequest:requestId]; + } } - } - failure:^(NSError *error) { + failure:^(NSError *error) { - typeof(self) self = weakSelf; - if (self) - { - [self sendLocalisedError:@"widget_integration_failed_to_send_request" toRequest:requestId]; - } - }]; + typeof(self) self = weakSelf; + if (self) + { + [self sendLocalisedError:@"widget_integration_failed_to_send_request" toRequest:requestId]; + } + }]; + } } } From ee21d5490a6be6de42a0c24bc9f55875ea9ba7f6 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 15:31:27 +0200 Subject: [PATCH 17/51] Send sticker: Create StickerPickerVC and use it from the RoomVC https://github.com/vector-im/riot-ios/issues/1860 --- Riot.xcodeproj/project.pbxproj | 6 ++ Riot/ViewController/RoomViewController.m | 38 ++++++++++++ .../Widgets/StickerPickerViewController.h | 21 +++++++ .../Widgets/StickerPickerViewController.m | 60 +++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 Riot/ViewController/Widgets/StickerPickerViewController.h create mode 100644 Riot/ViewController/Widgets/StickerPickerViewController.m diff --git a/Riot.xcodeproj/project.pbxproj b/Riot.xcodeproj/project.pbxproj index 2908c6779..10fe0e0ac 100644 --- a/Riot.xcodeproj/project.pbxproj +++ b/Riot.xcodeproj/project.pbxproj @@ -97,6 +97,7 @@ 32E84FA11F6BD32700CA0B89 /* apps-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84F9E1F6BD32700CA0B89 /* apps-icon.png */; }; 32E84FA21F6BD32700CA0B89 /* apps-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84F9F1F6BD32700CA0B89 /* apps-icon@2x.png */; }; 32E84FA31F6BD32700CA0B89 /* apps-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84FA01F6BD32700CA0B89 /* apps-icon@3x.png */; }; + 32EF474920B6EE990031695C /* StickerPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32EF474820B6EE990031695C /* StickerPickerViewController.m */; }; 32F3AE1A1F6FF4E600F0F004 /* WidgetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32F3AE191F6FF4E600F0F004 /* WidgetViewController.m */; }; 32FD0A3D1EB0CD9B0072B066 /* BugReportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32FD0A3B1EB0CD9B0072B066 /* BugReportViewController.m */; }; 32FD0A3E1EB0CD9B0072B066 /* BugReportViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32FD0A3C1EB0CD9B0072B066 /* BugReportViewController.xib */; }; @@ -766,6 +767,8 @@ 32E84F9E1F6BD32700CA0B89 /* apps-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon.png"; sourceTree = ""; }; 32E84F9F1F6BD32700CA0B89 /* apps-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon@2x.png"; sourceTree = ""; }; 32E84FA01F6BD32700CA0B89 /* apps-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon@3x.png"; sourceTree = ""; }; + 32EF474720B6EE990031695C /* StickerPickerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StickerPickerViewController.h; sourceTree = ""; }; + 32EF474820B6EE990031695C /* StickerPickerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StickerPickerViewController.m; sourceTree = ""; }; 32F3AE181F6FF4E600F0F004 /* WidgetViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetViewController.h; sourceTree = ""; }; 32F3AE191F6FF4E600F0F004 /* WidgetViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WidgetViewController.m; sourceTree = ""; }; 32FD0A3A1EB0CD9B0072B066 /* BugReportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugReportViewController.h; sourceTree = ""; }; @@ -1562,6 +1565,8 @@ 3233F7301F31F4BF006ACA81 /* JitsiViewController.xib */, 32C2356D1F7B871800E38FC5 /* WidgetPickerViewController.h */, 32C2356E1F7B871800E38FC5 /* WidgetPickerViewController.m */, + 32EF474720B6EE990031695C /* StickerPickerViewController.h */, + 32EF474820B6EE990031695C /* StickerPickerViewController.m */, ); path = Widgets; sourceTree = ""; @@ -3510,6 +3515,7 @@ F083BE661E7009ED00A9B29C /* RoomIncomingTextMsgWithPaginationTitleBubbleCell.m in Sources */, F083BE141E7009ED00A9B29C /* HomeViewController.m in Sources */, F083BDFB1E7009ED00A9B29C /* RoomSearchDataSource.m in Sources */, + 32EF474920B6EE990031695C /* StickerPickerViewController.m in Sources */, 3233F73C1F3306A7006ACA81 /* WidgetManager.m in Sources */, F0B8D0D31FDFECB200F34524 /* GroupTableViewCell.m in Sources */, F083BE281E7009ED00A9B29C /* StartChatViewController.m in Sources */, diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 71472f311..eca0667cf 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -115,6 +115,7 @@ #import "IntegrationManagerViewController.h" #import "WidgetPickerViewController.h" +#import "StickerPickerViewController.h" @interface RoomViewController () { @@ -2854,6 +2855,43 @@ self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; } +#pragma mark - RoomInputToolbarViewDelegate + +- (void)roomInputToolbarViewPresentStickerPicker:(MXKRoomInputToolbarView*)toolbarView +{ + // Search for the sticker picker widget in the user account + Widget *widget = [[WidgetManager sharedManager] userWidgets:self.roomDataSource.mxSession ofTypes:@[kWidgetTypeStickerPicker]].firstObject; + + if (widget) + { + // Display the widget + [widget widgetUrl:^(NSString * _Nonnull widgetUrl) { + + StickerPickerViewController *stickerPickerVC = [[StickerPickerViewController alloc] initWithUrl:widgetUrl forWidget:widget]; + + stickerPickerVC.roomDataSource = self.roomDataSource; + + [self.navigationController pushViewController:stickerPickerVC animated:YES]; + } failure:^(NSError * _Nonnull error) { + + NSLog(@"[RoomVC] Cannot display widget %@", widget); + [[AppDelegate theDelegate] showErrorAsAlert:error]; + }]; + } + else + { + // The Sticker picker widget is not installed yet. Propose the user to install it + // TODO + IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] + initForMXSession:self.roomDataSource.mxSession + inRoom:self.roomDataSource.roomId + screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] + widgetId:kWidgetTypeStickerPicker]; + + [self presentViewController:modularVC animated:NO completion:nil]; + } +} + #pragma mark - MXKRoomInputToolbarViewDelegate - (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView isTyping:(BOOL)typing diff --git a/Riot/ViewController/Widgets/StickerPickerViewController.h b/Riot/ViewController/Widgets/StickerPickerViewController.h new file mode 100644 index 000000000..036ac09d6 --- /dev/null +++ b/Riot/ViewController/Widgets/StickerPickerViewController.h @@ -0,0 +1,21 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "WidgetViewController.h" + +@interface StickerPickerViewController : WidgetViewController + +@end diff --git a/Riot/ViewController/Widgets/StickerPickerViewController.m b/Riot/ViewController/Widgets/StickerPickerViewController.m new file mode 100644 index 000000000..80609ecb4 --- /dev/null +++ b/Riot/ViewController/Widgets/StickerPickerViewController.m @@ -0,0 +1,60 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "StickerPickerViewController.h" + +#import "IntegrationManagerViewController.h" + +@interface StickerPickerViewController () + +@end + +@implementation StickerPickerViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.navigationItem.title = NSLocalizedStringFromTable(@"room_action_send_sticker", @"Vector", nil); + + // Hide back button title + self.parentViewController.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; + + UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(onEditButtonPressed)]; + [self.navigationItem setRightBarButtonItem: editButton animated:YES]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Make sure the content is up-to-date when we come back from the sticker picker settings screen + [webView reload]; +} + +- (void)onEditButtonPressed +{ + // Show the sticker picker settings screen + IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] + initForMXSession:self.roomDataSource.mxSession + inRoom:self.roomDataSource.roomId + screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] + widgetId:kWidgetTypeStickerPicker]; + + [self presentViewController:modularVC animated:NO completion:nil]; +} + +@end From 75a4e125e25249a924e6916c6aa4d8fcf4464991 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 16:02:51 +0200 Subject: [PATCH 18/51] Send sticker: Do not list anymore user's widgets (the sticker picker atm) in the WidgetPickerVC https://github.com/vector-im/riot-ios/issues/1860 --- Riot/ViewController/RoomViewController.m | 2 +- Riot/ViewController/Widgets/WidgetPickerViewController.m | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index eca0667cf..7ffe4f630 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -3102,7 +3102,7 @@ // Matrix Apps button else if (self.navigationItem.rightBarButtonItems.count == 2 && sender == self.navigationItem.rightBarButtonItems[1]) { - if ([self widgetsCount:YES]) + if ([self widgetsCount:NO]) { WidgetPickerViewController *widgetPicker = [[WidgetPickerViewController alloc] initForMXSession:self.roomDataSource.mxSession inRoom:self.roomDataSource.roomId]; diff --git a/Riot/ViewController/Widgets/WidgetPickerViewController.m b/Riot/ViewController/Widgets/WidgetPickerViewController.m index 72b4665ee..fb663c1b0 100644 --- a/Riot/ViewController/Widgets/WidgetPickerViewController.m +++ b/Riot/ViewController/Widgets/WidgetPickerViewController.m @@ -53,15 +53,9 @@ MXRoom *room = [mxSession roomWithRoomId:roomId]; - NSArray *roomWidgets = [[WidgetManager sharedManager] widgetsNotOfTypes:@[kWidgetTypeJitsi] + NSArray *widgets = [[WidgetManager sharedManager] widgetsNotOfTypes:@[kWidgetTypeJitsi] inRoom:room]; - NSArray *userWidgets = [[WidgetManager sharedManager] userWidgets:room.mxSession]; - - NSMutableArray *widgets = [NSMutableArray array]; - [widgets addObjectsFromArray:roomWidgets]; - [widgets addObjectsFromArray:userWidgets]; - // List widgets for (Widget *widget in widgets) { From e0ef5262044aab1fc47d177dae40bea660c33a38 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 16:43:38 +0200 Subject: [PATCH 19/51] Scalar API: Add support of "get_room_enc_state" --- .../IntegrationManagerViewController.m | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Riot/ViewController/Widgets/IntegrationManagerViewController.m b/Riot/ViewController/Widgets/IntegrationManagerViewController.m index e00ac8f7b..e0568f5f0 100644 --- a/Riot/ViewController/Widgets/IntegrationManagerViewController.m +++ b/Riot/ViewController/Widgets/IntegrationManagerViewController.m @@ -179,6 +179,18 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; return; } + // Get and set room-based widgets + if ([@"set_widget" isEqualToString:action]) + { + [self setWidget:requestId data:requestData]; + return; + } + else if ([@"get_widgets" isEqualToString:action]) + { + [self getWidgets:requestId data:requestData]; + return; + } + // These APIs don't require userId if ([@"join_rules_state" isEqualToString:action]) { @@ -195,14 +207,9 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; [self getMembershipCount:requestId data:requestData]; return; } - else if ([@"set_widget" isEqualToString:action]) + else if ([@"get_room_enc_state" isEqualToString:action]) { - [self setWidget:requestId data:requestData]; - return; - } - else if ([@"get_widgets" isEqualToString:action]) - { - [self getWidgets:requestId data:requestData]; + [self getRoomEncState:requestId data:requestData]; return; } else if ([@"can_send_event" isEqualToString:action]) @@ -442,6 +449,15 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; [self sendNSObjectResponse:widgetStateEvents toRequest:requestId]; } +- (void)getRoomEncState:(NSString*)requestId data:(NSDictionary*)requestData +{ + MXRoom *room = [self roomCheckForRequest:requestId data:requestData]; + if (room) + { + [self sendBoolResponse:room.state.isEncrypted toRequest:requestId]; + } +} + - (void)canSendEvent:(NSString*)requestId data:(NSDictionary*)requestData { NSString *eventType; From fb24d4b9762694d7b07d95b877a5f97bb623c5e7 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 18:22:59 +0200 Subject: [PATCH 20/51] Send sticker: Fix the missing delete button on a sticker pack https://github.com/vector-im/riot-ios/issues/1860 --- Riot/ViewController/RoomViewController.m | 2 +- Riot/ViewController/Widgets/StickerPickerViewController.m | 2 +- Riot/ViewController/Widgets/WidgetViewController.h | 5 +++++ Riot/ViewController/Widgets/WidgetViewController.m | 4 +--- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 7ffe4f630..cd5483a15 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -2886,7 +2886,7 @@ initForMXSession:self.roomDataSource.mxSession inRoom:self.roomDataSource.roomId screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] - widgetId:kWidgetTypeStickerPicker]; + widgetId:nil]; [self presentViewController:modularVC animated:NO completion:nil]; } diff --git a/Riot/ViewController/Widgets/StickerPickerViewController.m b/Riot/ViewController/Widgets/StickerPickerViewController.m index 80609ecb4..c4270bddc 100644 --- a/Riot/ViewController/Widgets/StickerPickerViewController.m +++ b/Riot/ViewController/Widgets/StickerPickerViewController.m @@ -52,7 +52,7 @@ initForMXSession:self.roomDataSource.mxSession inRoom:self.roomDataSource.roomId screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] - widgetId:kWidgetTypeStickerPicker]; + widgetId:self.widget.widgetId]; [self presentViewController:modularVC animated:NO completion:nil]; } diff --git a/Riot/ViewController/Widgets/WidgetViewController.h b/Riot/ViewController/Widgets/WidgetViewController.h index 0f9a70685..70c280c93 100644 --- a/Riot/ViewController/Widgets/WidgetViewController.h +++ b/Riot/ViewController/Widgets/WidgetViewController.h @@ -27,6 +27,11 @@ */ @interface WidgetViewController : WebViewViewController +/** + The displayed widget. + */ +@property (nonatomic, readonly) Widget *widget; + /** The room data source. Required if the widget needs to post messages. diff --git a/Riot/ViewController/Widgets/WidgetViewController.m b/Riot/ViewController/Widgets/WidgetViewController.m index aad876a52..e1440bc66 100644 --- a/Riot/ViewController/Widgets/WidgetViewController.m +++ b/Riot/ViewController/Widgets/WidgetViewController.m @@ -21,13 +21,11 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse('%@', %@);"; @interface WidgetViewController () -{ - Widget *widget; -} @end @implementation WidgetViewController +@synthesize widget; - (instancetype)initWithUrl:(NSString*)widgetUrl forWidget:(Widget*)theWidget { From 062c60a738ff76ffe965d051e5c830e1a1fe9e3d Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 18:40:19 +0200 Subject: [PATCH 21/51] Send sticker: Show the "You don't currently have any stickerpacks enabled" popup https://github.com/vector-im/riot-ios/issues/1860 --- Riot/ViewController/RoomViewController.m | 51 ++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index cd5483a15..b41177142 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -2881,14 +2881,51 @@ else { // The Sticker picker widget is not installed yet. Propose the user to install it - // TODO - IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] - initForMXSession:self.roomDataSource.mxSession - inRoom:self.roomDataSource.roomId - screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] - widgetId:nil]; + __weak typeof(self) weakSelf = self; - [self presentViewController:modularVC animated:NO completion:nil]; + [currentAlert dismissViewControllerAnimated:NO completion:nil]; + + NSString *alertMessage = [NSString stringWithFormat:@"%@\n%@", + NSLocalizedStringFromTable(@"widget_sticker_picker_no_stickerpacks_alert", @"Vector", nil), + NSLocalizedStringFromTable(@"widget_sticker_picker_no_stickerpacks_alert_add_now", @"Vector", nil) + ]; + + currentAlert = [UIAlertController alertControllerWithTitle:nil message:alertMessage preferredStyle:UIAlertControllerStyleAlert]; + + [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) + { + if (weakSelf) + { + typeof(self) self = weakSelf; + self->currentAlert = nil; + } + + }]]; + + [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) + { + if (weakSelf) + { + typeof(self) self = weakSelf; + self->currentAlert = nil; + + // Show the sticker picker settings screen + IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] + initForMXSession:self.roomDataSource.mxSession + inRoom:self.roomDataSource.roomId + screen:[IntegrationManagerViewController screenForWidget:kWidgetTypeStickerPicker] + widgetId:nil]; + + [self presentViewController:modularVC animated:NO completion:nil]; + } + }]]; + + [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"]; + [self presentViewController:currentAlert animated:YES completion:nil]; } } From edaf12056114f5a829e38bfeacda7b88c2bb1540 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 24 May 2018 19:01:19 +0200 Subject: [PATCH 22/51] BF: The app does not list widgets anymore --- Riot/ViewController/RoomViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 71472f311..e8a3c03b7 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -3650,7 +3650,7 @@ inRoom:self.roomDataSource.room].count; if (includeUserWidgets) { - widgetsCount = [[WidgetManager sharedManager] userWidgets:self.roomDataSource.room.mxSession].count; + widgetsCount += [[WidgetManager sharedManager] userWidgets:self.roomDataSource.room.mxSession].count; } return widgetsCount; From ae8e42931049367c424ef19e92de0e0f91a2ebe4 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 25 May 2018 14:41:41 +0200 Subject: [PATCH 23/51] Update Authors --- AUTHORS.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 5253de51c..47857b64a 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -42,4 +42,6 @@ Joey Watts Arash Tabrizian * PR #1828 Fix issue #1793 Confirmation popup when leaving room * PR #1824 Fix issue #1816 Support specifying kick and ban msgs - \ No newline at end of file + +Doug Earnshaw + * PR #1865 Fix timezone interval \ No newline at end of file From 4140bd53e432a3642516071e47e8f22ffdff42b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Mon, 28 May 2018 06:51:10 +0000 Subject: [PATCH 24/51] Translated using Weblate (Icelandic) Currently translated at 85.7% (414 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/is/ --- Riot/Assets/is.lproj/Vector.strings | 55 ++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/is.lproj/Vector.strings b/Riot/Assets/is.lproj/Vector.strings index a88f25b7b..8a533ef43 100644 --- a/Riot/Assets/is.lproj/Vector.strings +++ b/Riot/Assets/is.lproj/Vector.strings @@ -380,7 +380,7 @@ "room_event_action_kick_prompt_reason" = "Ástæða fyrir að sparka þessum notanda"; "room_event_action_ban_prompt_reason" = "Ástæða fyrir að banna þennan notanda"; "settings_unignore_user" = "Sýna öll skilaboð frá %@?"; -"settings_labs_create_conference_with_jitsi" = "Búa til ráðstefnusamtöl með Jitsi"; +"settings_labs_create_conference_with_jitsi" = "Búa til símafundi með Jitsi"; "room_details_history_section_members_only" = "Einungis meðlimir (síðan þessi kostur var valinn)"; "room_details_history_section_members_only_since_invited" = "Einungis meðlimir (síðan þeim var boðið)"; "room_details_history_section_members_only_since_joined" = "Einungis meðlimir (síðan þeir skráðu sig)"; @@ -391,3 +391,56 @@ "group_participants_leave_prompt_msg" = "Ertu viss um að þú viljir fara út úr hópnum?"; "group_participants_remove_prompt_msg" = "Ertu viss um að þú viljir fjarlægja %@ úr hópnum ?"; "group_participants_invite_another_user" = "Leita/Bjóða eftir notandaauðkenni eða nafni"; +"auth_add_email_message" = "Bættu tölvupóstfangi við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig og einnig til að endurstilla lykilorðið þitt."; +"auth_add_phone_message" = "Bættu símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig."; +"auth_add_email_phone_message" = "Bættu tölvupóstfangi og/eða símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig. Tölvupóstfang nýtist einnig til að endurstilla lykilorðið þitt."; +"auth_add_email_and_phone_message" = "Bættu tölvupóstfangi og símanúmeri við notandaaðganginn þinn til að gera öðrum notendum kleift að finna þig. Tölvupóstfang nýtist einnig til að endurstilla lykilorðið þitt."; +"auth_recaptcha_message" = "Þessi heimavefþjónn vill ganga úr skugga um að þú sért ekki vélmenni"; +"auth_reset_password_message" = "Til að endursetja lykilorðið þitt, settu þá inn tölvupóstfangið sem tengt er notandaaðgangnum þínum:"; +"auth_reset_password_missing_email" = "Það þarf að setja inn tölvupóstfangið sem tengt er notandaaðgangnum þínum."; +"auth_reset_password_email_validation_message" = "Tölvupóstur hefur verið sendur á %@ Þegar þú ert búin/n að fylgja tenglinum sem sá póstur inniheldur, smelltu þá hér fyrir neðan."; +"auth_reset_password_error_unauthorized" = "Gat ekki sannprófað tölvupóstfang: gakktu úr skugga um að þú hafir smellt á tengilinn í tölvupóstinum"; +"auth_reset_password_success_message" = "Lykilorðið þitt hefur verið endurstillt.\n\nÞú hefur verið skráður út af öllum tækjum og munt ekki lengur fá ýti-tilkynningar. Til að endurvirkja tilkynningar, þarf að skrá sig aftur inn á hverju tæki fyrir sig."; +"directory_search_results" = "%tu niðurstöður fundust fyrir %@"; +"directory_search_results_more_than" = ">%tu niðurstöður fundust fyrir %@"; +"contacts_address_book_permission_denied" = "Þú heimilaðir Riot ekki aðgang að tengiliðum á tækinu"; +"room_participants_remove_prompt_msg" = "Ertu viss um að þú viljir fjarlægja %@ úr þessu spjalli?"; +"room_participants_invite_prompt_msg" = "Ertu viss um að þú viljir bjóða %@ á þetta spjall?"; +"room_participants_invite_malformed_id" = "Rangt formað auðkenni. Ætti að vera tölvupóstfang eða Matrix-auðkenni á borð við'@sérheiti:lén'"; +"room_unsent_messages_notification" = "Skilaboð ekki send. %@ eða %@ núna?"; +"room_unsent_messages_unknown_devices_notification" = "Skilaboð ekki send vegna þess að vart var við óþekkt tæki. %@ eða %@ núna?"; +"room_ongoing_conference_call" = "Símafundur í gangi. Taka þátt með %@ eða %@."; +"room_ongoing_conference_call_with_close" = "Símafundur í gangi. Taka þátt með %@ eða %@. %@ því."; +"room_conference_call_no_power" = "Þú þarft aðgangsheimildir til að sýsla með símafundi á þessari spjallrás"; +"settings_contacts_phonebook_country" = "Land símaskrár"; +"settings_enable_rageshake" = "Hristu ákveðið til að senda villutilkynningu"; +"settings_crypto_blacklist_unverified_devices" = "Aðeins dulrita til sannvottaðra tækja"; +"room_details_access_section_invited_only" = "Aðeins fólk sem hefur verið boðið"; +"room_details_access_section_no_address_warning" = "Til að tengja við spjallrás verður hún að vera með vistfang"; +"room_details_access_section_directory_toggle" = "Setja þessa spjallrás á skrá yfir spjallrásir"; +"room_details_addresses_invalid_address_prompt_title" = "Ógilt snið samnefnis"; +"room_details_advanced_e2e_encryption_blacklist_unverified_devices" = "Aðeins dulrita til sannvottaðra tækja"; +// Read Receipts +"read_receipts_list" = "Listi yfir leskvittanir"; +"directory_server_type_homeserver" = "Skrifaðu heimanetþjón til að telja upp opinberar spjallrásir á"; +"bug_report_prompt" = "Forritið hrundi síðast. Myndirðu vilja senda inn villuskýrslu?"; +"rage_shake_prompt" = "Það er eins og þú sért að hrista símann ákveðið. Myndirðu vilja senda villuskýrslu?"; +// room display name +"room_displayname_invite_from" = "Boð frá %@"; +"room_displayname_room_invite" = "Boð á spjallrás"; +"call_jitsi_error" = "Mistókst að taka þátt í símafundi."; +"bug_report_description" = "Lýstu villunni. Hvað varstu að gera? Hverju áttirðu von á? Hvað gerðist í raun?"; +"bug_crash_report_description" = "Lýstu því hvað þú varst að gera þegar forritið hrundi (á ensku):"; +"bug_report_logs_description" = "Til að geta greint vandamál eru atvikaskrár þessa forrits sendar með þessari villuskýrslu. Ef þú vilt einungis senda textann hér fyrir ofan, taktu þá gátmerkið úr reitnum:"; +// Widget +"widget_no_power_to_manage" = "Þú þarft aðgangsheimildir til að sýsla með viðmótshluta á þessari spjallrás"; +"widget_creation_failure" = "Gerð viðmótshluta mistókst"; +"widget_integration_unable_to_create" = "Gat ekki búið til viðmótshluta."; +"widget_integration_failed_to_send_request" = "Mistókst að senda beiðni."; +"widget_integration_positive_power_level" = "Völd verða að vera jákvæð heiltala."; +"widget_integration_missing_room_id" = "Vantar spjallrásarauðkenni í beiðni."; +"widget_integration_missing_user_id" = "Vantar notandaauðkenni í beiðni."; +"widget_integration_room_not_visible" = "Spjallrásin %@ er ekki sýnileg."; +// Room key request dialog +"e2e_room_key_request_title" = "Beiðni um dulritunarlykil"; +"gdpr_consent_not_given_alert_review_now_action" = "Yfirfara núna"; From 959974b0993f81b42aaf3179628c497ea625c3b8 Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Mon, 28 May 2018 07:10:09 +0000 Subject: [PATCH 25/51] Translated using Weblate (Dutch) Currently translated at 100.0% (483 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/nl/ --- Riot/Assets/nl.lproj/Vector.strings | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Riot/Assets/nl.lproj/Vector.strings b/Riot/Assets/nl.lproj/Vector.strings index 5c5fae6a3..af7887b1d 100644 --- a/Riot/Assets/nl.lproj/Vector.strings +++ b/Riot/Assets/nl.lproj/Vector.strings @@ -541,3 +541,8 @@ // Group rooms "group_rooms_filter_rooms" = "Gemeenschapsruimtes filteren"; "e2e_room_key_request_message_new_device" = "Je hebt een nieuwe apparaat '%@' toegevoegd, die een verzoek doet naar versleutelingssleutels."; +"room_event_action_kick_prompt_reason" = "Reden voor het verwijderen van deze gebruiker"; +"room_event_action_ban_prompt_reason" = "Reden voor het verbannen van deze gebruiker"; +// GDPR +"gdpr_consent_not_given_alert_message" = "Om de %@ thuisserver te blijven gebruiken moet je de algemeen voorwaarden lezen en daarmee akkoord gaan."; +"gdpr_consent_not_given_alert_review_now_action" = "Nu doorlezen"; From 267993f0b8e33a80d9c82e7ad26e03848e4f5e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Mon, 28 May 2018 07:58:49 +0000 Subject: [PATCH 26/51] Translated using Weblate (Icelandic) Currently translated at 94.6% (457 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/is/ --- Riot/Assets/is.lproj/Vector.strings | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Riot/Assets/is.lproj/Vector.strings b/Riot/Assets/is.lproj/Vector.strings index 8a533ef43..2a0be5a92 100644 --- a/Riot/Assets/is.lproj/Vector.strings +++ b/Riot/Assets/is.lproj/Vector.strings @@ -444,3 +444,48 @@ // Room key request dialog "e2e_room_key_request_title" = "Beiðni um dulritunarlykil"; "gdpr_consent_not_given_alert_review_now_action" = "Yfirfara núna"; +"room_creation_make_public_prompt_msg" = "Ertu viss um að þú viljir gera þetta spjall opinbert? Hver sem er gæti þá lesið skilaboðin þín og tekið þátt í spjallinu."; +"contacts_address_book_permission_required" = "Heimild þarf til að fá aðgang að tengiliðum á tækinu"; +"room_participants_invite_malformed_id_title" = "Villa við boð"; +"room_preview_subtitle" = "Þetta er forskoðun á spjallrásinni. Samskipti spjallrásarinnar hafa verið gerð óvirk."; +"room_preview_try_join_an_unknown_room" = "Þú ert að reyna að tengjast %@ Myndirðu vilja gerast meðlimur til að geta tekið þátt í samræðunni?"; +"settings_fail_to_update_profile" = "Mistókst að uppfæra notandasnið"; +"settings_pin_rooms_with_missed_notif" = "Festa spjallrásir með óskoðuðum tilkynningum"; +"settings_pin_rooms_with_unread" = "Festa spjallrásir með ólesnum skilaboðum"; +"settings_on_denied_notification" = "Tilkynningum er hafnað fyrir %@, leyfðu þær í stillingum tækisins"; +"settings_ui_theme_picker_message" = "\"Sjálfvirkt\" notar \"Umsnúa litum\" stillingar tækisins"; +"settings_contacts_discover_matrix_users" = "Notaðu tölvupóstföng og símanúmer til að finna notendur"; +"settings_labs_e2e_encryption_prompt_message" = "Til að ljúka við uppsetningu á dulritun verðurðu að skrá þig inn aftur."; +"room_details_access_section_anyone_apart_from_guest" = "Hver sá sem þekkir slóðina á spjallrásina, fyrir utan gesti"; +"room_details_access_section_anyone" = "Hver sá sem þekkir slóðina á spjallrásina, fyrir utan gesti"; +"room_details_new_address_placeholder" = "Bæta við nýju vistfangi (t.d. #foo%@)"; +"room_details_addresses_invalid_address_prompt_msg" = "%@ er ekki gilt snið fyrir samnefni"; +"room_details_addresses_disable_main_address_prompt_title" = "Aðvaranir vegna aðalvistfangs"; +"room_details_advanced_enable_e2e_encryption" = "Virkja dulritun (aðvörun: er ekki hægt að gera aftur óvirkt!)"; +"room_details_fail_to_update_avatar" = "Mistókst að uppfæra mynd spjallrásar"; +"room_details_fail_to_update_room_name" = "Mistókst að uppfæra heiti spjallrásar"; +"room_details_fail_to_update_topic" = "Mistókst að uppfæra umræðuefnið"; +"room_details_fail_to_update_room_guest_access" = "Mistókst að uppfæra gestaaðgang spjallrásar"; +"room_details_fail_to_update_room_join_rule" = "Mistókst að uppfæra reglu fyrir þátttöku"; +"room_details_fail_to_update_room_directory_visibility" = "Mistókst að uppfæra sýnileika spjallrásarskrár"; +"room_details_fail_to_update_history_visibility" = "Mistókst að uppfæra sýnileika ferilskráningar"; +"room_details_fail_to_update_room_canonical_alias" = "Mistókst að uppfæra aðalvistfangið"; +"room_details_fail_to_enable_encryption" = "Mistókst að virkja dulritun á þessari spjallrás"; +"room_details_set_main_address" = "Setja sem aðalvistfang"; +"room_details_unset_main_address" = "Ekki setja sem aðalvistfang"; +"group_participants_invite_prompt_msg" = "Ertu viss um að þú viljir bjóða %@ í þennan hóp?"; +"group_participants_invite_malformed_id_title" = "Villa við boð"; +"group_participants_invite_malformed_id" = "Rangt formað auðkenni. Ætti að vera Matrix-auðkenni á borð við'@sérheiti:lén'"; +"directory_server_placeholder" = "matrix.org"; +// Events formatter +"event_formatter_member_updates" = "%tu breytingar á aðild"; +"event_formatter_widget_added" = "%@ viðmótshluta bætt við af %@"; +"event_formatter_widget_removed" = "%@ viðmótshluti fjarlægður af %@"; +"event_formatter_jitsi_widget_added" = "VoIP-símafundi bætt við af %@"; +"event_formatter_jitsi_widget_removed" = "VoIP-símafundur fjarlægður af %@"; +"public_room_section_title" = "Opinberar spjallrásir (á %@):"; +"widget_integration_room_not_recognised" = "Spjallrás er ekki þekkt."; +// Share extension +"share_extension_auth_prompt" = "Skráðu inn í aðalforrit til að deila efni"; +"e2e_room_key_request_message_new_device" = "Þú bættir við nýju tæki '%@', sem er að krefjast dulritunarlykla."; +"e2e_room_key_request_message" = "Ósannvottaða tækið þitt '%@' er að krefjast dulritunarlykla."; From b1cbef42e590a71be2799d7712a2bfe5d6ff0e04 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 28 May 2018 14:51:51 +0200 Subject: [PATCH 27/51] Add deactivate account english string localizations --- Riot/Assets/en.lproj/Vector.strings | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 949c079a6..cc7f7e7dd 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -316,6 +316,7 @@ "settings_flair" = "Show flair where allowed"; "settings_devices" = "DEVICES"; "settings_cryptography" = "CRYPTOGRAPHY"; +"settings_deactivate_account" = "DEACTIVATE ACCOUNT"; "settings_sign_out" = "Sign Out"; "settings_sign_out_confirmation" = "Are you sure?"; @@ -396,6 +397,8 @@ "settings_crypto_export" = "Export keys"; "settings_crypto_blacklist_unverified_devices" = "Encrypt to verified devices only"; +"settings_deactivate_my_account" = "Deactivate my account"; + // Room Details "room_details_title" = "Room Details"; "room_details_people" = "Members"; @@ -596,3 +599,22 @@ // GDPR "gdpr_consent_not_given_alert_message" = "To continue using the %@ homeserver you must review and agree to the terms and conditions."; "gdpr_consent_not_given_alert_review_now_action" = "Review now"; + +// Deactivate account + +"deactivate_account_title" = "Deactivate Account"; + +"deactivate_account_informations_part1" = "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. "; +"deactivate_account_informations_part2_emphasize" = "This action is irreversible."; +"deactivate_account_informations_part3" = "\n\nDeactivating your account "; +"deactivate_account_informations_part4_emphasize" = "does not by default cause us to forget messages you have sent. "; +"deactivate_account_informations_part5" = "If you would like us to forget your messages, please tick the box below\n\nMessage visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy."; + +"deactivate_account_forget_messages_information_part1" = "Please forget all messages I have sent when my account is deactivated ("; +"deactivate_account_forget_messages_information_part2_emphasize" = "Warning"; +"deactivate_account_forget_messages_information_part3" = ": this will cause future users to see an incomplete view of conversations)"; + +"deactivate_account_validate_action" = "Deactivate account"; + +"deactivate_account_password_alert_title" = "Deactivate Account"; +"deactivate_account_password_alert_message" = "To continue, please enter your password"; From 048739c7f4bb04669fd58faf33d941929ee05208 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 29 May 2018 14:50:34 +0200 Subject: [PATCH 28/51] PostMessage API: better manage _id --- Riot/Assets/js/postMessageAPI.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Riot/Assets/js/postMessageAPI.js b/Riot/Assets/js/postMessageAPI.js index 2b145debe..81b1fe9cb 100644 --- a/Riot/Assets/js/postMessageAPI.js +++ b/Riot/Assets/js/postMessageAPI.js @@ -31,15 +31,6 @@ window.riotIOS.events = {}; // Listen to messages posted by the widget window.riotIOS.onMessage = function(event) { - // Do not SPAM ObjC with event already managed - if (riotIOS.events[event.data._id]) { - return; - } - - if (!event.origin) { // stupid chrome - event.origin = event.originalEvent.origin; - } - // Use an internal "_id" field for matching onMessage events and requests // _id was originally used by the Modular API. Keep it if (!event.data._id) { @@ -52,6 +43,15 @@ window.riotIOS.onMessage = function(event) { if (!event.data._id) { event.data._id = Date.now() + "-" + Math.random().toString(36); } + + // Do not SPAM ObjC with event already managed + if (riotIOS.events[event.data._id]) { + return; + } + + if (!event.origin) { // stupid chrome + event.origin = event.originalEvent.origin; + } // Keep this event for future usage riotIOS.events[event.data._id] = event; From 896529c8ee563e7070816195e852304fdee67c28 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 29 May 2018 15:20:39 +0200 Subject: [PATCH 29/51] PostMessage API: Add support of integration_manager_open --- .../Widgets/WidgetViewController.m | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Riot/ViewController/Widgets/WidgetViewController.m b/Riot/ViewController/Widgets/WidgetViewController.m index e1440bc66..8cc7cd6d6 100644 --- a/Riot/ViewController/Widgets/WidgetViewController.m +++ b/Riot/ViewController/Widgets/WidgetViewController.m @@ -17,6 +17,7 @@ #import "WidgetViewController.h" #import "AppDelegate.h" +#import "IntegrationManagerViewController.h" NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse('%@', %@);"; @@ -214,6 +215,37 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse // Consider we are done with the sticker picker widget [self withdrawViewControllerAnimated:YES completion:nil]; } + else if ([@"integration_manager_open" isEqualToString:action]) + { + NSDictionary *widgetData; + NSString *integType, *integId; + MXJSONModelSetDictionary(widgetData, requestData[@"widgetData"]); + if (widgetData) + { + MXJSONModelSetString(integType, widgetData[@"integType"]); + MXJSONModelSetString(integId, widgetData[@"integId"]); + } + + if (integType && integId) + { + // Open the integration manager requested page + IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] + initForMXSession:self.roomDataSource.mxSession + inRoom:self.roomDataSource.roomId + screen:[IntegrationManagerViewController screenForWidget:integType] + widgetId:integId]; + + [self presentViewController:modularVC animated:NO completion:nil]; + } + else + { + NSLog(@"[WidgetVC] onPostMessageRequest: ERROR: Invalid content for integration_manager_open: %@", requestData); + } + } + else + { + NSLog(@"[WidgetVC] onPostMessageRequest: ERROR: Unsupported action: %@: %@", action, requestData); + } } - (void)sendBoolResponse:(BOOL)response toRequest:(NSString*)requestId From b113d59761bd9b01f9f602839d70325feff0030f Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Tue, 29 May 2018 15:17:51 +0000 Subject: [PATCH 30/51] Translated using Weblate (Bulgarian) Currently translated at 100.0% (483 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/bg/ --- Riot/Assets/bg.lproj/Vector.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/bg.lproj/Vector.strings b/Riot/Assets/bg.lproj/Vector.strings index 4892436f7..57f76edd8 100644 --- a/Riot/Assets/bg.lproj/Vector.strings +++ b/Riot/Assets/bg.lproj/Vector.strings @@ -516,3 +516,6 @@ "settings_config_no_build_info" = "Няма build информация"; "room_event_action_kick_prompt_reason" = "Причина за изгонване на потребителя"; "room_event_action_ban_prompt_reason" = "Причина за блокиране на потребителя"; +// GDPR +"gdpr_consent_not_given_alert_message" = "За да продължите да използвате %@ трябва да се съгласите с условията за ползване."; +"gdpr_consent_not_given_alert_review_now_action" = "Прегледай сега"; From a577bb92a609dc67396391a2e1f433df5e5b0e26 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 30 May 2018 11:54:35 +0200 Subject: [PATCH 31/51] Send sticker: Update after Giom's remark https://github.com/vector-im/riot-ios/issues/1860 --- Riot/ViewController/RoomViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 5f2d0ab4b..093f89e17 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -2924,7 +2924,7 @@ } }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"]; + [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCStickerPickerAlert"]; [self presentViewController:currentAlert animated:YES completion:nil]; } } From 760f3b7f6c3b9457713b33e0b868fb35cb0bfea5 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 30 May 2018 14:15:32 +0200 Subject: [PATCH 32/51] WidgetVC: Update UIWebView by WKWebview to improve Sticker Picker performance --- .../Widgets/WidgetViewController.m | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/Riot/ViewController/Widgets/WidgetViewController.m b/Riot/ViewController/Widgets/WidgetViewController.m index 8cc7cd6d6..64e9be433 100644 --- a/Riot/ViewController/Widgets/WidgetViewController.m +++ b/Riot/ViewController/Widgets/WidgetViewController.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -42,7 +43,6 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse { [super viewDidLoad]; - webView.scalesPageToFit = NO; webView.scrollView.bounces = NO; // Disable opacity so that the webview background uses the current interface theme @@ -91,16 +91,16 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse [self presentViewController:alert animated:YES completion:nil]; } -#pragma mark - UIWebViewDelegate +#pragma mark - WKNavigationDelegate --(void)webViewDidFinishLoad:(UIWebView *)theWebView +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { [self enableDebug]; // Setup js code NSString *path = [[NSBundle mainBundle] pathForResource:@"postMessageAPI" ofType:@"js"]; NSString *js = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; - [webView stringByEvaluatingJavaScriptFromString:js]; + [webView evaluateJavaScript:js completionHandler:nil]; [self stopActivityIndicator]; @@ -119,14 +119,16 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse } } -- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { - NSString *urlString = [[request URL] absoluteString]; + NSString *urlString = navigationAction.request.URL.absoluteString; + // TODO: We should use the WebKit PostMessage API and the + // `didReceiveScriptMessage` delegate to manage the JS<->Native bridge if ([urlString hasPrefix:@"js:"]) { - // Listen only to scheme of the JS-UIWebView bridge - NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding]; + // Listen only to the scheme of the JS<->Native bridge + NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByRemovingPercentEncoding]; NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; @@ -151,20 +153,22 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse } } - return NO; + decisionHandler(WKNavigationActionPolicyCancel); + return; } - if (navigationType == UIWebViewNavigationTypeLinkClicked ) + if (navigationAction.navigationType == WKNavigationTypeLinkActivated) { // Open links outside the app - [[UIApplication sharedApplication] openURL:[request URL]]; - return NO; + [[UIApplication sharedApplication] openURL:navigationAction.request.URL]; + decisionHandler(WKNavigationActionPolicyCancel); + return; } - return YES; + decisionHandler(WKNavigationActionPolicyAllow); } -- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { // Filter out the users's scalar token NSString *errorDescription = error.description; @@ -255,7 +259,7 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse requestId, response ? @"true" : @"false"]; - [webView stringByEvaluatingJavaScriptFromString:js]; + [webView evaluateJavaScript:js completionHandler:nil]; } - (void)sendIntegerResponse:(NSUInteger)response toRequest:(NSString*)requestId @@ -264,7 +268,7 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse requestId, @(response)]; - [webView stringByEvaluatingJavaScriptFromString:js]; + [webView evaluateJavaScript:js completionHandler:nil]; } - (void)sendNSObjectResponse:(NSObject*)response toRequest:(NSString*)requestId @@ -290,7 +294,7 @@ NSString *const kJavascriptSendResponseToPostMessageAPI = @"riotIOS.sendResponse requestId, jsString]; - [webView stringByEvaluatingJavaScriptFromString:js]; + [webView evaluateJavaScript:js completionHandler:nil]; } - (void)sendError:(NSString*)message toRequest:(NSString*)requestId From 2efefc530aa0db3f432de94aa7e3bfcd0c0bc9db Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 30 May 2018 16:59:18 +0200 Subject: [PATCH 33/51] Add DeactivateAccountViewController allowing to deactivate a user account from given Matrix session --- Riot.xcodeproj/project.pbxproj | 18 ++ .../DeactivateAccountViewController.h | 45 +++ .../DeactivateAccountViewController.m | 287 ++++++++++++++++++ ...DeactivateAccountViewController.storyboard | 130 ++++++++ 4 files changed, 480 insertions(+) create mode 100644 Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.h create mode 100644 Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m create mode 100644 Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard diff --git a/Riot.xcodeproj/project.pbxproj b/Riot.xcodeproj/project.pbxproj index 2908c6779..ea0bbd8d1 100644 --- a/Riot.xcodeproj/project.pbxproj +++ b/Riot.xcodeproj/project.pbxproj @@ -109,6 +109,8 @@ 92726A4B1F58737A004AD26F /* SiriIntents.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 92726A431F58737A004AD26F /* SiriIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 92726A511F587410004AD26F /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92726A501F587410004AD26F /* Intents.framework */; }; 9D686B069F967C4D4BBC610F /* Pods_RiotPods_SiriIntents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB50EEBE8214352B9EBD6394 /* Pods_RiotPods_SiriIntents.framework */; }; + B19A173920B7F94800DF0BB0 /* DeactivateAccountViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B19A173820B7F94800DF0BB0 /* DeactivateAccountViewController.m */; }; + B19A173B20B7F96700DF0BB0 /* DeactivateAccountViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B19A173A20B7F96700DF0BB0 /* DeactivateAccountViewController.storyboard */; }; DDDE2AB95F865F2292B1D315 /* Pods_RiotPods_RiotShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23D7292481328A48B8D5D4ED /* Pods_RiotPods_RiotShareExtension.framework */; }; F0131DE51F2200D600CBF707 /* RiotSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0131DE41F2200D600CBF707 /* RiotSplitViewController.m */; }; F0173EB51FCF346800B5F6A3 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = F0173EAF1FCF346800B5F6A3 /* Vector.strings */; }; @@ -794,6 +796,9 @@ 92726A501F587410004AD26F /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; }; A5030B7C3C0B6EB83A9257BD /* Pods-RiotPods-Riot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-Riot.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RiotPods-Riot/Pods-RiotPods-Riot.debug.xcconfig"; sourceTree = ""; }; B0FAA1A49F76B0CE15C5CBD8 /* Pods_RiotPods_Riot.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_Riot.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B19A173720B7F94800DF0BB0 /* DeactivateAccountViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeactivateAccountViewController.h; sourceTree = ""; }; + B19A173820B7F94800DF0BB0 /* DeactivateAccountViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeactivateAccountViewController.m; sourceTree = ""; }; + B19A173A20B7F96700DF0BB0 /* DeactivateAccountViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = DeactivateAccountViewController.storyboard; sourceTree = ""; }; C195C53961EA28E6900AEB68 /* Pods-Riot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Riot.release.xcconfig"; path = "Pods/Target Support Files/Pods-Riot/Pods-Riot.release.xcconfig"; sourceTree = ""; }; C5258DFF261AA3AB228A3F11 /* Pods-RiotPods-RiotShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-RiotShareExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RiotPods-RiotShareExtension/Pods-RiotPods-RiotShareExtension.debug.xcconfig"; sourceTree = ""; }; DB50EEBE8214352B9EBD6394 /* Pods_RiotPods_SiriIntents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_SiriIntents.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1717,6 +1722,16 @@ path = SiriIntents; sourceTree = ""; }; + B19A173520B6F89900DF0BB0 /* DeactivateAccount */ = { + isa = PBXGroup; + children = ( + B19A173720B7F94800DF0BB0 /* DeactivateAccountViewController.h */, + B19A173820B7F94800DF0BB0 /* DeactivateAccountViewController.m */, + B19A173A20B7F96700DF0BB0 /* DeactivateAccountViewController.storyboard */, + ); + path = DeactivateAccount; + sourceTree = ""; + }; F0173EAE1FCF346800B5F6A3 /* vi.lproj */ = { isa = PBXGroup; children = ( @@ -2283,6 +2298,7 @@ 24B5103F1EFA88CC004C6AD2 /* ReadReceiptsViewController.xib */, F0B4CBA31F418D0B008E99C5 /* WebViewViewController.h */, F0B4CBA41F418D0B008E99C5 /* WebViewViewController.m */, + B19A173520B6F89900DF0BB0 /* DeactivateAccount */, ); path = ViewController; sourceTree = ""; @@ -3151,6 +3167,7 @@ F083BDDA1E7009ED00A9B29C /* typing.png in Resources */, F083BE831E7009ED00A9B29C /* RecentTableViewCell.xib in Resources */, F046DC731FE1786500E3DAF0 /* GroupHomeViewController.xib in Resources */, + B19A173B20B7F96700DF0BB0 /* DeactivateAccountViewController.storyboard in Resources */, F0E5D9141FF6FF3F00560D7F /* GroupRoomTableViewCell.xib in Resources */, F083BDB71E7009ED00A9B29C /* remove_icon@2x.png in Resources */, F083BDD31E7009ED00A9B29C /* settings_icon@3x.png in Resources */, @@ -3630,6 +3647,7 @@ F0E05A021E963103004B83FB /* FavouritesViewController.m in Sources */, F083BE941E7009ED00A9B29C /* FilesSearchTableViewCell.m in Sources */, F083BE921E7009ED00A9B29C /* SimpleRoomTitleView.m in Sources */, + B19A173920B7F94800DF0BB0 /* DeactivateAccountViewController.m in Sources */, F083BE981E7009ED00A9B29C /* MessagesSearchResultTextMsgBubbleCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.h b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.h new file mode 100644 index 000000000..4d403aa40 --- /dev/null +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.h @@ -0,0 +1,45 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +@import UIKit; +@import MatrixKit; + +#pragma mark - Types + +@class DeactivateAccountViewController; + +#pragma mark - Protocol + +@protocol DeactivateAccountViewControllerDelegate + +- (void)deactivateAccountViewControllerDidCancel:(DeactivateAccountViewController*)deactivateAccountViewController; +- (void)deactivateAccountViewControllerDidDeactivateWithSuccess:(DeactivateAccountViewController*)deactivateAccountViewController; + +@end + +#pragma mark - Interface + +@interface DeactivateAccountViewController : MXKViewController + +#pragma mark - Properties + +@property (nonatomic, weak) id delegate; + +#pragma mark - Class Methods + ++ (DeactivateAccountViewController*)instantiateWithMatrixSession:(MXSession*)matrixSession; + +@end diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m new file mode 100644 index 000000000..c1aa43ceb --- /dev/null +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m @@ -0,0 +1,287 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "DeactivateAccountViewController.h" + +#import "RiotDesignValues.h" + +#pragma mark - Defines & Constants + +static CGFloat const kButtonCornerRadius = 5.0; +static CGFloat const kTextFontSize = 15.0; +static NSTimeInterval const kActivityIndicatorAnimationDuration = 0.3; +static CGFloat const kActivityContainerViewCornerRadius = 5.0; + +#pragma mark - Private Interface + +@interface DeactivateAccountViewController () + +#pragma mark - Outlets + +@property (weak, nonatomic) IBOutlet UILabel *deactivateAccountInfosLabel; + +@property (weak, nonatomic) IBOutlet UILabel *forgetMessagesInfoLabel; +@property (weak, nonatomic) IBOutlet UIButton *forgetMessageButton; + +@property (weak, nonatomic) IBOutlet UIButton *deactivateAcccountButton; + + +#pragma mark - Private Properties + +@property (strong, nonatomic) NSDictionary *normalStringAttributes; +@property (strong, nonatomic) NSDictionary *emphasizeStringAttributes; + +@property (strong, nonatomic) MXKErrorAlertPresentation *errorPresentation; + +@end + +#pragma mark - Implementation + +@implementation DeactivateAccountViewController + +#pragma mark - Setup & Teardown + ++ (DeactivateAccountViewController*)instantiateWithMatrixSession:(MXSession*)matrixSession +{ + DeactivateAccountViewController* viewController = [[UIStoryboard storyboardWithName:NSStringFromClass([DeactivateAccountViewController class]) bundle:[NSBundle mainBundle]] instantiateInitialViewController]; + [viewController addMatrixSession:matrixSession]; + return viewController; +} + +#pragma mark - View life cycle + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view. + + self.title = NSLocalizedStringFromTable(@"deactivate_account_title", @"Vector", nil); + + self.errorPresentation = [[MXKErrorAlertPresentation alloc] init]; + [self setupStringAttributes]; + [self setupViews]; +} + +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; + +// [self.activityIndicatorContainerView.layer setCornerRadius:kActivityContainerViewCornerRadius]; + [self.deactivateAcccountButton.layer setCornerRadius:kButtonCornerRadius]; +} + +#pragma mark - Private + +- (void)setupStringAttributes +{ + self.normalStringAttributes = @{ + NSFontAttributeName: [UIFont systemFontOfSize:kTextFontSize], + NSForegroundColorAttributeName: kRiotPrimaryTextColor + }; + + + self.emphasizeStringAttributes = @{ + NSFontAttributeName: [UIFont systemFontOfSize:kTextFontSize weight:UIFontWeightBold], + NSForegroundColorAttributeName: kRiotPrimaryTextColor + }; +} + +- (void)setupViews +{ + [self setupNavigationBar]; + [self setupDeactivateAcccountButton]; + [self setupDeactivateAccountInfosLabel]; + [self setupForgetMessagesInfoLabel]; +} + +- (void)setupNavigationBar +{ + self.navigationController.navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName: kRiotColorRed }; + + UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedStringFromTable(@"cancel", @"Vector", nil) style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonAction:)]; + self.navigationItem.rightBarButtonItem = cancelBarButtonItem; +} + +- (void)setupDeactivateAcccountButton +{ + // Adjust button font size for small devices + self.deactivateAcccountButton.titleLabel.adjustsFontSizeToFitWidth = YES; + self.deactivateAcccountButton.titleLabel.minimumScaleFactor = 0.5; + self.deactivateAcccountButton.titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; + + self.deactivateAcccountButton.layer.masksToBounds = YES; + self.deactivateAcccountButton.backgroundColor = kRiotColorGreen; + [self.deactivateAcccountButton setTitle:NSLocalizedStringFromTable(@"deactivate_account_validate_action", @"Vector", nil) forState:UIControlStateNormal]; + [self.deactivateAcccountButton setTitleColor:kRiotColorSilver forState:UIControlStateDisabled]; +} + +- (void)setupDeactivateAccountInfosLabel +{ + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_informations_part1", @"Vector", nil) attributes:self.normalStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_informations_part2_emphasize", @"Vector", nil) attributes:self.emphasizeStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_informations_part3", @"Vector", nil) attributes:self.normalStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_informations_part4_emphasize", @"Vector", nil) attributes:self.emphasizeStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_informations_part5", @"Vector", nil) attributes:self.normalStringAttributes]]; + + [self.deactivateAccountInfosLabel setAttributedText:attributedString]; +} + +- (void)setupForgetMessagesInfoLabel +{ + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_forget_messages_information_part1", @"Vector", nil) attributes:self.normalStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_forget_messages_information_part2_emphasize", @"Vector", nil) attributes:self.emphasizeStringAttributes]]; + + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"deactivate_account_forget_messages_information_part3", @"Vector", nil) attributes:self.normalStringAttributes]]; + + [self.forgetMessagesInfoLabel setAttributedText:attributedString]; +} + +- (void)enableUserActions:(BOOL)enableUserActions +{ + self.navigationItem.rightBarButtonItem.enabled = enableUserActions; + self.forgetMessageButton.enabled = enableUserActions; + self.deactivateAcccountButton.enabled = enableUserActions; +} + +- (void)presentPasswordRequiredAlertWithSubmitHandler:(void (^)(NSString *password))submitHandler + cancelHandler:(dispatch_block_t)cancelHandler +{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"deactivate_account_password_alert_title", @"Vector", nil) + message:NSLocalizedStringFromTable(@"deactivate_account_password_alert_message", @"Vector", nil) preferredStyle:UIAlertControllerStyleAlert]; + + [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.secureTextEntry = YES; + textField.placeholder = nil; + textField.keyboardType = UIKeyboardTypeDefault; + }]; + + [alert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { + if (cancelHandler) + { + cancelHandler(); + } + }]]; + + __weak typeof(self) weakSelf = self; + + [alert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"submit"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + UITextField *textField = alert.textFields.firstObject; + + typeof(weakSelf) strongSelf = weakSelf; + + if (strongSelf) + { + NSString *password = textField.text; + + if (submitHandler) + { + submitHandler(password); + } + } + }]]; + + [self presentViewController:alert animated:YES completion:nil]; +} + +- (void)deactivateAccountWithUserId:(NSString*)userId + andPassword:(NSString*)password + eraseAllMessages:(BOOL)eraseAllMessages +{ + if (password && userId) + { + [self enableUserActions:NO]; + [self startActivityIndicator]; + + // This assumes that the homeserver requires password UI auth + // for this endpoint. In reality it could be any UI auth. + + __weak typeof(self) weakSelf = self; + + NSDictionary *authParameters = @{@"user": userId, + @"password": password, + @"type": kMXLoginFlowTypePassword}; + + [self.mainSession deactivateAccountWithAuthParameters:authParameters eraseAccount:eraseAllMessages success:^{ + NSLog(@"[SettingsViewController] Deactivate account with success"); + + [weakSelf stopActivityIndicator]; + [weakSelf enableUserActions:YES]; + } failure:^(NSError *error) { + + NSLog(@"[SettingsViewController] Failed to deactivate account"); + + typeof(weakSelf) strongSelf = weakSelf; + + if (strongSelf) + { + [strongSelf stopActivityIndicator]; + [strongSelf enableUserActions:YES]; + [strongSelf.errorPresentation presentErrorFromViewController:strongSelf forError:error animated:YES handler:nil]; + } + }]; + } + else + { + NSLog(@"[SettingsViewController] Failed to deactivate account"); + [self.errorPresentation presentGenericErrorFromViewController:self animated:YES handler:nil]; + } +} + +#pragma mark - Actions + +- (void)cancelButtonAction:(id)sender +{ + [self.delegate deactivateAccountViewControllerDidCancel:self]; +} + +- (IBAction)forgetMessagesButtonAction:(UIButton*)sender +{ + self.forgetMessageButton.selected = !self.forgetMessageButton.selected; +} + +- (IBAction)deactivateAccountButtonAction:(id)sender +{ + __weak typeof(self) weakSelf = self; + + [self presentPasswordRequiredAlertWithSubmitHandler:^(NSString *password) { + + typeof(weakSelf) strongSelf = weakSelf; + + if (strongSelf) + { + NSString *userId = strongSelf.mainSession.myUser.userId; + [strongSelf deactivateAccountWithUserId:userId andPassword:password eraseAllMessages:strongSelf.forgetMessageButton.isEnabled]; + } + + } cancelHandler:^{ + + }]; +} + +@end diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard new file mode 100644 index 000000000..0f1ec1012 --- /dev/null +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5d68e0aa18047362d9ddc1c0246d4a49a8e46ceb Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 30 May 2018 17:04:58 +0200 Subject: [PATCH 34/51] Factorization of data user clear on logout. Reuse it for account deactivation. --- Riot/AppDelegate.h | 8 ++++++++ Riot/AppDelegate.m | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/Riot/AppDelegate.h b/Riot/AppDelegate.h index c13524eac..872fa21a4 100644 --- a/Riot/AppDelegate.h +++ b/Riot/AppDelegate.h @@ -113,6 +113,14 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification; */ - (void)logoutWithConfirmation:(BOOL)askConfirmation completion:(void (^)(BOOL isLoggedOut))completion; +/** + Log out all the accounts without confirmation. + Show the authentication screen on successful logout. + + @param completion the block to execute at the end of the operation. + */ +- (void)logoutWithCompletion:(void (^)(BOOL isLoggedOut))completion; + #pragma mark - Matrix Accounts handling - (void)selectMatrixAccount:(void (^)(MXKAccount *selectedAccount))onSelection; diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index f0bfa3f95..29ffe0f65 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -2667,6 +2667,16 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN [topVC startActivityIndicator]; } + [self logoutWithCompletion:^(BOOL isLoggedOut) { + if (completion) + { + completion (YES); + } + }]; +} + +- (void)logoutWithCompletion:(void (^)(BOOL isLoggedOut))completion +{ self.pushRegistry = nil; isPushRegistered = NO; From 162547d95083f860970e4692c19f2b4221fe3615 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 30 May 2018 17:05:42 +0200 Subject: [PATCH 35/51] Handle account deactivation from settings --- Riot/ViewController/SettingsViewController.m | 84 +++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/Riot/ViewController/SettingsViewController.m b/Riot/ViewController/SettingsViewController.m index acb4c8126..4db9a4540 100644 --- a/Riot/ViewController/SettingsViewController.m +++ b/Riot/ViewController/SettingsViewController.m @@ -34,6 +34,7 @@ #import "CountryPickerViewController.h" #import "LanguagePickerViewController.h" +#import "DeactivateAccountViewController.h" #import "NBPhoneNumberUtil.h" #import "RageShakeManager.h" @@ -62,6 +63,7 @@ enum SETTINGS_SECTION_CRYPTOGRAPHY_INDEX, SETTINGS_SECTION_FLAIR_INDEX, SETTINGS_SECTION_DEVICES_INDEX, + SETTINGS_SECTION_DEACTIVATE_ACCOUNT_INDEX, SETTINGS_SECTION_COUNT }; @@ -130,7 +132,7 @@ enum { typedef void (^blockSettingsViewController_onReadyToDestroy)(); -@interface SettingsViewController () +@interface SettingsViewController () { // Current alert (if any). UIAlertController *currentAlert; @@ -234,6 +236,10 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); */ @property (nonatomic) BOOL newPhoneEditingEnabled; +@property (weak, nonatomic) DeactivateAccountViewController *deactivateAccountViewController; + +//@property (strong, nonatomic) ErrorPresenter *errorPresenter; + @end @implementation SettingsViewController @@ -258,6 +264,9 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); self.navigationItem.title = NSLocalizedStringFromTable(@"settings_title", @"Vector", nil); + // Remove back bar button title when pushing a view controller + self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; @@ -310,6 +319,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(onSave:)]; self.navigationItem.rightBarButtonItem.accessibilityIdentifier=@"SettingsVCNavBarSaveButton"; + // Observe user interface theme change. kRiotDesignValuesDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { @@ -1268,6 +1278,10 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); count = CRYPTOGRAPHY_COUNT; } } + else if (section == SETTINGS_SECTION_DEACTIVATE_ACCOUNT_INDEX) + { + count = 1; + } return count; } @@ -2151,6 +2165,32 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); cell = exportKeysBtnCell; } } + else if (section == SETTINGS_SECTION_DEACTIVATE_ACCOUNT_INDEX) + { + MXKTableViewCellWithButton *deactivateAccountBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; + + if (!deactivateAccountBtnCell) + { + deactivateAccountBtnCell = [[MXKTableViewCellWithButton alloc] init]; + } + else + { + // Fix https://github.com/vector-im/riot-ios/issues/1354 + deactivateAccountBtnCell.mxkButton.titleLabel.text = nil; + } + + NSString *btnTitle = NSLocalizedStringFromTable(@"settings_deactivate_my_account", @"Vector", nil); + [deactivateAccountBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal]; + [deactivateAccountBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted]; + [deactivateAccountBtnCell.mxkButton setTintColor:kRiotColorRed]; + deactivateAccountBtnCell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17]; + + [deactivateAccountBtnCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; + [deactivateAccountBtnCell.mxkButton addTarget:self action:@selector(deactivateAccountAction) forControlEvents:UIControlEventTouchUpInside]; + deactivateAccountBtnCell.mxkButton.accessibilityIdentifier = nil; + + cell = deactivateAccountBtnCell; + } return cell; } @@ -2228,6 +2268,18 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); return NSLocalizedStringFromTable(@"settings_cryptography", @"Vector", nil); } } + else if (section == SETTINGS_SECTION_CRYPTOGRAPHY_INDEX) + { + // Check whether this section is visible + if (self.mainSession.crypto) + { + return NSLocalizedStringFromTable(@"settings_cryptography", @"Vector", nil); + } + } + else if (section == SETTINGS_SECTION_DEACTIVATE_ACCOUNT_INDEX) + { + return NSLocalizedStringFromTable(@"settings_deactivate_my_account", @"Vector", nil); + } return nil; } @@ -3673,6 +3725,20 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); [self presentViewController:themePicker animated:YES completion:nil]; } +- (void)deactivateAccountAction +{ + DeactivateAccountViewController *deactivateAccountViewController = [DeactivateAccountViewController instantiateWithMatrixSession:self.mainSession]; + + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:deactivateAccountViewController]; + navigationController.modalPresentationStyle = UIModalPresentationFormSheet; + + [self presentViewController:navigationController animated:YES completion:nil]; + + deactivateAccountViewController.delegate = self; + + self.deactivateAccountViewController = deactivateAccountViewController; +} + #pragma mark - MediaPickerViewController Delegate - (void)dismissMediaPicker @@ -4033,4 +4099,20 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); [self refreshSettings]; } +#pragma mark - DeactivateAccountViewControllerDelegate + +- (void)deactivateAccountViewControllerDidDeactivateWithSuccess:(DeactivateAccountViewController *)deactivateAccountViewController +{ + NSLog(@"[SettingsViewController] Deactivate account with success"); + + [[AppDelegate theDelegate] logoutWithCompletion:^(BOOL isLoggedOut) { + NSLog(@"[SettingsViewController] Complete clear user data after account deactivation"); + }]; +} + +- (void)deactivateAccountViewControllerDidCancel:(DeactivateAccountViewController *)deactivateAccountViewController +{ + [deactivateAccountViewController dismissViewControllerAnimated:YES completion:nil]; +} + @end From 1fce6673369ad788223219ceaa540611047c5844 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 31 May 2018 12:14:13 +0200 Subject: [PATCH 36/51] Handle theme change and analytics in DeactivateAccountViewController --- .../DeactivateAccountViewController.m | 48 +++++++++++++++++-- ...DeactivateAccountViewController.storyboard | 2 +- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m index c1aa43ceb..480cad6f4 100644 --- a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m @@ -17,13 +17,12 @@ #import "DeactivateAccountViewController.h" #import "RiotDesignValues.h" +#import "AppDelegate.h" #pragma mark - Defines & Constants static CGFloat const kButtonCornerRadius = 5.0; static CGFloat const kTextFontSize = 15.0; -static NSTimeInterval const kActivityIndicatorAnimationDuration = 0.3; -static CGFloat const kActivityContainerViewCornerRadius = 5.0; #pragma mark - Private Interface @@ -46,6 +45,8 @@ static CGFloat const kActivityContainerViewCornerRadius = 5.0; @property (strong, nonatomic) MXKErrorAlertPresentation *errorPresentation; +@property (weak, nonatomic) id themeDidChangeNotificationObserver; + @end #pragma mark - Implementation @@ -61,6 +62,19 @@ static CGFloat const kActivityContainerViewCornerRadius = 5.0; return viewController; } +- (void)destroy +{ + id notificationObserver = self.themeDidChangeNotificationObserver; + + if (notificationObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:notificationObserver]; + } + + [super destroy]; +} + + #pragma mark - View life cycle - (void)viewDidLoad @@ -73,18 +87,46 @@ static CGFloat const kActivityContainerViewCornerRadius = 5.0; self.errorPresentation = [[MXKErrorAlertPresentation alloc] init]; [self setupStringAttributes]; [self setupViews]; + [self userInterfaceThemeDidChange]; + [self registerThemeNotification]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Screen tracking + [[AppDelegate theDelegate] trackScreen:@"DeactivateAccount"]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; -// [self.activityIndicatorContainerView.layer setCornerRadius:kActivityContainerViewCornerRadius]; [self.deactivateAcccountButton.layer setCornerRadius:kButtonCornerRadius]; } +- (UIStatusBarStyle)preferredStatusBarStyle +{ + return kRiotDesignStatusBarStyle; +} + #pragma mark - Private +- (void)registerThemeNotification +{ + self.themeDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + [self userInterfaceThemeDidChange]; + }]; +} + +- (void)userInterfaceThemeDidChange +{ + self.view.backgroundColor = kRiotPrimaryBgColor; + self.defaultBarTintColor = kRiotSecondaryBgColor; + self.activityIndicator.backgroundColor = kRiotOverlayColor; +} + - (void)setupStringAttributes { self.normalStringAttributes = @{ diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard index 0f1ec1012..63668b7b6 100644 --- a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.storyboard @@ -75,7 +75,7 @@ Message visibility in Matrix is similar to email. Our forgetting your messages m - + From 0cefca3d4c72d783cf879360a5a0c5dfc28ddf24 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 31 May 2018 12:15:13 +0200 Subject: [PATCH 37/51] Remove useless commented code in SettingsViewController --- Riot/ViewController/SettingsViewController.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/Riot/ViewController/SettingsViewController.m b/Riot/ViewController/SettingsViewController.m index 4db9a4540..fb90398b1 100644 --- a/Riot/ViewController/SettingsViewController.m +++ b/Riot/ViewController/SettingsViewController.m @@ -238,8 +238,6 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); @property (weak, nonatomic) DeactivateAccountViewController *deactivateAccountViewController; -//@property (strong, nonatomic) ErrorPresenter *errorPresenter; - @end @implementation SettingsViewController From 6bea87eef7f3c65c2c984bc46bd1ea678954d7d5 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 31 May 2018 13:33:17 +0200 Subject: [PATCH 38/51] DeactivateAccountViewController: For password alert, remove empty cancel handler and use nil instead --- .../DeactivateAccount/DeactivateAccountViewController.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m index 480cad6f4..0ff6d3b68 100644 --- a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m @@ -321,9 +321,7 @@ static CGFloat const kTextFontSize = 15.0; [strongSelf deactivateAccountWithUserId:userId andPassword:password eraseAllMessages:strongSelf.forgetMessageButton.isEnabled]; } - } cancelHandler:^{ - - }]; + } cancelHandler:nil]; } @end From 4b2d430dbfa03253ec5d0b48c043635cfeca638e Mon Sep 17 00:00:00 2001 From: "Pablo M. Rivas" Date: Wed, 30 May 2018 22:04:53 +0000 Subject: [PATCH 39/51] Translated using Weblate (Spanish) Currently translated at 12.4% (60 of 483 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/es/ --- Riot/Assets/es.lproj/Vector.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/es.lproj/Vector.strings b/Riot/Assets/es.lproj/Vector.strings index 9e10ff77c..0ec235dd1 100644 --- a/Riot/Assets/es.lproj/Vector.strings +++ b/Riot/Assets/es.lproj/Vector.strings @@ -60,3 +60,4 @@ "auth_missing_password" = "Contraseña ausente"; "auth_add_email_message" = "Añade un correo electrónico a tu cuenta para poder ser descubierto por otros usuarios, y ser capaz de recomponer tu contraseña."; "auth_add_phone_message" = "Añade un número telefónico a tu cuenta para ser descubierto por otros usuarios."; +"title_groups" = "Comunidades"; From d01b10b18dae57cf80dcdea5f1e13ef59708fa83 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 31 May 2018 17:26:43 +0200 Subject: [PATCH 40/51] Add Icelandic --- Riot.xcodeproj/project.pbxproj | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Riot.xcodeproj/project.pbxproj b/Riot.xcodeproj/project.pbxproj index 9565c7b41..f3a963be3 100644 --- a/Riot.xcodeproj/project.pbxproj +++ b/Riot.xcodeproj/project.pbxproj @@ -92,6 +92,7 @@ 32BB89EF204D86DA002F3AEC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32BB89EA204D86DA002F3AEC /* Localizable.strings */; }; 32BB89F0204D86DA002F3AEC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32BB89EC204D86DA002F3AEC /* InfoPlist.strings */; }; 32C2356F1F7B871800E38FC5 /* WidgetPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32C2356E1F7B871800E38FC5 /* WidgetPickerViewController.m */; }; + 32C699CD20C04AD100D1C5A4 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32C699CB20C04AD100D1C5A4 /* Vector.strings */; }; 32D392181EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 32D392161EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m */; }; 32D392191EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32D392171EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib */; }; 32E84FA11F6BD32700CA0B89 /* apps-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84F9E1F6BD32700CA0B89 /* apps-icon.png */; }; @@ -763,6 +764,7 @@ 32BB89ED204D86DA002F3AEC /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = InfoPlist.strings; sourceTree = ""; }; 32C2356D1F7B871800E38FC5 /* WidgetPickerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WidgetPickerViewController.h; sourceTree = ""; }; 32C2356E1F7B871800E38FC5 /* WidgetPickerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WidgetPickerViewController.m; sourceTree = ""; }; + 32C699CC20C04AD100D1C5A4 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = Vector.strings; sourceTree = ""; }; 32D392151EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryServerDetailTableViewCell.h; sourceTree = ""; }; 32D392161EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryServerDetailTableViewCell.m; sourceTree = ""; }; 32D392171EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DirectoryServerDetailTableViewCell.xib; sourceTree = ""; }; @@ -1672,6 +1674,14 @@ path = bg.lproj; sourceTree = ""; }; + 32C699CA20C04AD100D1C5A4 /* is.lproj */ = { + isa = PBXGroup; + children = ( + 32C699CB20C04AD100D1C5A4 /* Vector.strings */, + ); + path = is.lproj; + sourceTree = ""; + }; 5FC42FA41F5186AFFB6A2404 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -1817,6 +1827,7 @@ F083BB0E1E7009EC00A9B29C /* Assets */ = { isa = PBXGroup; children = ( + 32C699CA20C04AD100D1C5A4 /* is.lproj */, 32A9B3B32089CA400087E7A3 /* vi.lproj */, 32BB89E7204D86DA002F3AEC /* bg.lproj */, 3211717B203ACD32002C16C6 /* ca.lproj */, @@ -2892,6 +2903,7 @@ vi, ca, bg, + is, ); mainGroup = F094A9991B78D8F000B1FBBF; productRefGroup = F094A9A31B78D8F000B1FBBF /* Products */; @@ -3299,6 +3311,7 @@ F083BE3B1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentBubbleCell.xib in Resources */, F083BD341E7009ED00A9B29C /* call_audio_mute_off_icon@2x.png in Resources */, F083BD6E1E7009ED00A9B29C /* e2e_blocked.png in Resources */, + 32C699CD20C04AD100D1C5A4 /* Vector.strings in Resources */, F0E05A3A1EA0F9EB004B83FB /* tab_home@2x.png in Resources */, F083BE091E7009ED00A9B29C /* AuthenticationViewController.xib in Resources */, F083BD381E7009ED00A9B29C /* call_audio_mute_on_icon@3x.png in Resources */, @@ -3879,6 +3892,14 @@ name = InfoPlist.strings; sourceTree = ""; }; + 32C699CB20C04AD100D1C5A4 /* Vector.strings */ = { + isa = PBXVariantGroup; + children = ( + 32C699CC20C04AD100D1C5A4 /* is */, + ); + name = Vector.strings; + sourceTree = ""; + }; F0173EAF1FCF346800B5F6A3 /* Vector.strings */ = { isa = PBXVariantGroup; children = ( From 7360663a67fbe661db4d3139dd7e945deebeec13 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 31 May 2018 17:33:20 +0200 Subject: [PATCH 41/51] Put close action to left in navigation bar of GDPR consent screen --- Riot/AppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index f0bfa3f95..2eb7b8ea0 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -4048,7 +4048,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN target:self action:@selector(dismissGDPRConsent)]; - webViewViewController.navigationItem.rightBarButtonItem = closeBarButtonItem; + webViewViewController.navigationItem.leftBarButtonItem = closeBarButtonItem; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:webViewViewController]; From 935ba57839485b067806986cd1d78f8c23c89662 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 31 May 2018 15:45:50 +0000 Subject: [PATCH 42/51] Translated using Weblate (Russian) Currently translated at 100.0% (501 of 501 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/ru/ --- Riot/Assets/ru.lproj/Vector.strings | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Riot/Assets/ru.lproj/Vector.strings b/Riot/Assets/ru.lproj/Vector.strings index 59a0da223..28ca66b2a 100644 --- a/Riot/Assets/ru.lproj/Vector.strings +++ b/Riot/Assets/ru.lproj/Vector.strings @@ -521,3 +521,21 @@ // GDPR "gdpr_consent_not_given_alert_message" = "Для продолжения использования сервера %@ вы должны принять условия и положения."; "gdpr_consent_not_given_alert_review_now_action" = "Просмотреть сейчас"; +"room_action_send_photo_or_video" = "Отправить фото или видео"; +"room_action_send_sticker" = "Отправить стикер"; +"settings_deactivate_account" = "ДЕАКТИВАЦИЯ АККАУНТА"; +"settings_deactivate_my_account" = "Деактивировать мой аккаунт"; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "Добавить сейчас?"; +"deactivate_account_title" = "Деактивировать аккаунт"; +"deactivate_account_informations_part1" = "Это действие сделает вашу учетную запись непригодной для дальнейшего использования. Вы не сможете войти в систему и никто другой не сможет заново зарегистрировать учетную запись с вашим идентификатором. Также, это приведет к тому, что вы покинете все комнаты, в которых участвовали и данные о вашей учетной записи будут удалены с сервера идентификации. "; +"deactivate_account_informations_part2_emphasize" = "Это действие необратимо."; +"deactivate_account_informations_part3" = "\n\nДеактивация вашего аккаунта "; +"deactivate_account_informations_part4_emphasize" = "по умолчанию не удаляет отправленные вами сообщения. "; +"deactivate_account_informations_part5" = "Если вы хотите, чтобы мы удалили все ваши сообщения - поставьте отметку в поле ниже.\n\nВидимость сообщений в Matrix похожа на электронную почту. Удаление ваших сообщений означает, что отправленные вами сообщения не будут показаны новым или не зарегистрированным пользователям, но те пользователи, которые уже получили эти сообщения - по прежнему будут их видеть."; +"deactivate_account_forget_messages_information_part1" = "Пожалуйста, удалите все сообщения, которые я отправил ("; +"deactivate_account_forget_messages_information_part2_emphasize" = "Внимание"; +"deactivate_account_forget_messages_information_part3" = ": будущие участники увидят неполное представление разговоров)"; +"deactivate_account_validate_action" = "Деактивировать аккаунт"; +"deactivate_account_password_alert_title" = "Деактивировать аккаунт"; +"deactivate_account_password_alert_message" = "Чтобы продолжить, введите пароль"; +"widget_sticker_picker_no_stickerpacks_alert" = "У вас пока нет включенных пакетов стикеров."; From 081dd3155359b25aaa3da814f31e19e4158a0b79 Mon Sep 17 00:00:00 2001 From: Krombel Date: Thu, 31 May 2018 16:10:13 +0000 Subject: [PATCH 43/51] Translated using Weblate (German) Currently translated at 100.0% (501 of 501 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index fbf6164b6..2da915898 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -517,3 +517,24 @@ "room_do_not_have_permission_to_post" = "Du hast keine Berechtigung in diesem Raum zu posten"; "room_event_action_kick_prompt_reason" = "Grund für den Rauswurf des Benutzers"; "room_event_action_ban_prompt_reason" = "Grund für die Verbannung des Benutzers"; +"room_action_send_photo_or_video" = "Sende Foto oder Video"; +"room_action_send_sticker" = "Sende Sticker"; +"settings_deactivate_account" = "DEAKTIVIERE ACCOUNT"; +"settings_deactivate_my_account" = "Deaktivere meinen Account"; +"widget_sticker_picker_no_stickerpacks_alert" = "Du hast aktuell keine Sticker-Packete aktiviert."; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "Welche hinzufügen?"; +// GDPR +"gdpr_consent_not_given_alert_message" = "Um den %@ -Heimserver weiter zu verwenden, musst du die Geschäftsbedingungen sichten und ihnen zustimmen."; +"gdpr_consent_not_given_alert_review_now_action" = "Jetzt sichten"; +"deactivate_account_title" = "Deaktiviere Account"; +"deactivate_account_informations_part1" = "Dies wird deinen Account permanent unbenutzbar machen. Du wirst dich nicht erneut anmelden können und keiner wird dieselbe Nutzer-ID erneut registrieren. Alle Räume, in denen dein Account ist, werden verlassen werden und deine Account-Daten werden vom Identitätsserver gelöscht werden. "; +"deactivate_account_informations_part2_emphasize" = "Diese Aktion ist irreversibel."; +"deactivate_account_informations_part3" = "\n\nDeinen Account deaktivieren "; +"deactivate_account_informations_part4_emphasize" = "wird standardmäßig nicht dafür sorgen, dass wir alle Nachrichten löschen, die du gesendet hast. "; +"deactivate_account_informations_part5" = "Wenn du möchtest, dass wir deine Nachrichten löschen, wähle das Auswahlfeld unten aus.\n\nDie Sichtbarkeit der Nachrichten in Matrix ist wie bei E-Mails: Wenn wir deine Nachrichten löschen, werden sie nicht mehr mit neuen oder nicht registrierten Benutzern geteilt, aber bereits registrierte Nutzer werden den Zugriff auf ihre Kopie deiner Nachrichten behalten."; +"deactivate_account_forget_messages_information_part1" = "Bitte vergesst alle Nachrichten, die ich gesendet habe, wenn mein Account deaktiviert wird ("; +"deactivate_account_forget_messages_information_part2_emphasize" = "Warnung"; +"deactivate_account_forget_messages_information_part3" = ": Dies wird dafür sorgen, dass zukünftige Nutzer eine unvollständige Konversation sehen)"; +"deactivate_account_validate_action" = "Account deaktiveren"; +"deactivate_account_password_alert_title" = "Account deaktivieren"; +"deactivate_account_password_alert_message" = "Zum Fortfahren, Password eingeben"; From a98212e506a5f26d121365ab82e28ff07d9de161 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 31 May 2018 18:39:15 +0200 Subject: [PATCH 44/51] Do not display default error alert when receiving GDPR Consent not given error --- Riot/AppDelegate.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 29ffe0f65..c1b19c0c3 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -850,6 +850,16 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN return nil; } + // Ignore GDPR Consent not given error. Already caught by kMXHTTPClientUserConsentNotGivenErrorNotification observation + if ([MXError isMXError:error]) + { + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if ([mxError.errcode isEqualToString:kMXErrCodeStringConsentNotGiven]) + { + return nil; + } + } + [_errorNotification dismissViewControllerAnimated:NO completion:nil]; NSString *title = [error.userInfo valueForKey:NSLocalizedFailureReasonErrorKey]; From 26227cd8a03b6cee42ffb4dccfe4a3d7d1051f1e Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 1 Jun 2018 09:46:11 +0200 Subject: [PATCH 45/51] Fix GDPR consent alert not shown after account creation --- Riot/AppDelegate.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 378af11ef..67a5044b0 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -4019,9 +4019,12 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN { NSString *consentURI = notification.userInfo[kMXHTTPClientUserConsentNotGivenErrorNotificationConsentURIKey]; if (consentURI - && self.gdprConsentNotGivenAlertController == nil - && self.gdprConsentViewController == nil) + && self.gdprConsentNotGivenAlertController.presentingViewController == nil + && self.gdprConsentViewController.presentingViewController == nil) { + self.gdprConsentNotGivenAlertController = nil; + self.gdprConsentViewController = nil; + UIViewController *presentingViewController = self.window.rootViewController.presentedViewController ?: self.window.rootViewController; __weak typeof(self) weakSelf = self; From a628b2c62ca0b50efd31c734482e348964f0f91e Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 1 Jun 2018 08:58:06 +0000 Subject: [PATCH 46/51] Translated using Weblate (Bulgarian) Currently translated at 100.0% (501 of 501 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/bg/ --- Riot/Assets/bg.lproj/Vector.strings | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Riot/Assets/bg.lproj/Vector.strings b/Riot/Assets/bg.lproj/Vector.strings index 57f76edd8..7ae92bd2c 100644 --- a/Riot/Assets/bg.lproj/Vector.strings +++ b/Riot/Assets/bg.lproj/Vector.strings @@ -519,3 +519,21 @@ // GDPR "gdpr_consent_not_given_alert_message" = "За да продължите да използвате %@ трябва да се съгласите с условията за ползване."; "gdpr_consent_not_given_alert_review_now_action" = "Прегледай сега"; +"room_action_send_photo_or_video" = "Изпрати снимка или видео"; +"room_action_send_sticker" = "Изпрати стикер"; +"settings_deactivate_account" = "ДЕАКТИВАЦИЯ НА АКАУНТ"; +"settings_deactivate_my_account" = "Деактивирай акаунта ми"; +"widget_sticker_picker_no_stickerpacks_alert" = "В момента нямате активирани пакети със стикери."; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "Добави сега?"; +"deactivate_account_title" = "Деактивиране на акаунт"; +"deactivate_account_informations_part1" = "Това ще направи акаунта Ви неизползваем завинаги. Няма да можете да влезете пак, а регистрирането повторно на същия потребителски идентификатор няма да е възможно. Акаунтът Ви да напусне всички стаи, в които участва. Ще бъдат премахнати и данните за акаунта Ви от сървъра за самоличност. "; +"deactivate_account_informations_part2_emphasize" = "Действието е необратимо."; +"deactivate_account_informations_part3" = "\n\nДеактивирането на акаунта Ви "; +"deactivate_account_informations_part4_emphasize" = "по подразбиране не прави така, че изпратените съобщения да бъдат забравени. "; +"deactivate_account_informations_part5" = "Ако искате да забравим съобщенията Ви, моля отбележете с отметка по-долу\n\nВидимостта на съобщенията в Matrix е подобно на имейл системата. Нашето забравяне означава, че: изпратените от Вас съобщения няма да бъдат споделяни с нови или нерегистрирани потребители, но регистрираните потребители имащи достъп до тях ще продължат да имат достъп до своето копие."; +"deactivate_account_forget_messages_information_part1" = "Моля, забравете всички изпратени от мен съобщения, когато акаунта ми се деактивира ("; +"deactivate_account_forget_messages_information_part2_emphasize" = "Внимание"; +"deactivate_account_forget_messages_information_part3" = ": това ще направи бъдещите потребители да имат само частичен поглед върху кореспонденцията)"; +"deactivate_account_validate_action" = "Деактивирай акаунта"; +"deactivate_account_password_alert_title" = "Деактивиране на акаунт"; +"deactivate_account_password_alert_message" = "За да продължите, моля въведете паролата си"; From 49bfaf817fefba3b47a81059d80bd164564e0a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 1 Jun 2018 09:40:26 +0000 Subject: [PATCH 47/51] Translated using Weblate (French) Currently translated at 100.0% (501 of 501 strings) Translation: Riot iOS/Riot iOS Translate-URL: https://translate.riot.im/projects/riot-ios/riot-ios/fr/ --- Riot/Assets/fr.lproj/Vector.strings | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index 2b66993ad..7f10f1756 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -520,3 +520,21 @@ // GDPR "gdpr_consent_not_given_alert_message" = "Pour continuer à utiliser le serveur d'accueil %@, vous devez lire et accepter les conditions générales."; "gdpr_consent_not_given_alert_review_now_action" = "Voir maintenant"; +"room_action_send_photo_or_video" = "Envoyer une photo ou une vidéo"; +"room_action_send_sticker" = "Envoyer un sticker"; +"settings_deactivate_account" = "DÉSACTIVER LE COMPTE"; +"settings_deactivate_my_account" = "Désactiver mon compte"; +"widget_sticker_picker_no_stickerpacks_alert" = "Vous n'avez aucun pack de stickers activé."; +"widget_sticker_picker_no_stickerpacks_alert_add_now" = "En ajouter maintenant ?"; +"deactivate_account_title" = "Désactiver le compte"; +"deactivate_account_informations_part1" = "Votre compte sera inutilisable de façon permanente. Vous ne pourrez plus vous connecter et personne ne pourra se réenregistrer avec le même identifiant d'utilisateur. Votre compte quittera tous les salons auxquels il participe, et tous les détails du compte seront supprimés du serveur d'identité. "; +"deactivate_account_informations_part2_emphasize" = "Cette action est irréversible."; +"deactivate_account_informations_part3" = "\n\nLa désactivation de votre compte "; +"deactivate_account_informations_part4_emphasize" = "ne nous fait pas oublier les messages que vous avez envoyés par défaut. "; +"deactivate_account_informations_part5" = "Si vous souhaitez que nous oubliions vos messages, cochez la case ci-dessous\n\nLa visibilité des messages dans Matrix est similaire à celle des e-mails. Notre oubli des messages signifie que les messages que vous avez envoyés ne seront pas partagés avec les nouveaux utilisateurs ou les utilisateurs non enregistrés, mais les utilisateurs qui ont déjà accès à ces messages auront toujours accès à leur copie."; +"deactivate_account_forget_messages_information_part1" = "Veuillez oublier tous les messages que j'ai envoyé quand mon compte sera désactivé ("; +"deactivate_account_forget_messages_information_part2_emphasize" = "Avertissement"; +"deactivate_account_forget_messages_information_part3" = ": les futurs utilisateurs auront alors une vue incomplète des conversations)"; +"deactivate_account_validate_action" = "Désactiver le compte"; +"deactivate_account_password_alert_title" = "Désactiver le compte"; +"deactivate_account_password_alert_message" = "Pour continuer, veuillez renseigner votre mot de passe"; From d14a0f583dc011a10f8b4f32960de75559883236 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 1 Jun 2018 16:01:21 +0200 Subject: [PATCH 48/51] Add call to account deactivation success delegate method in DeactivateAccountViewController --- .../DeactivateAccountViewController.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m index 0ff6d3b68..a8fe4b6ca 100644 --- a/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m +++ b/Riot/ViewController/DeactivateAccount/DeactivateAccountViewController.m @@ -203,7 +203,7 @@ static CGFloat const kTextFontSize = 15.0; - (void)enableUserActions:(BOOL)enableUserActions { self.navigationItem.rightBarButtonItem.enabled = enableUserActions; - self.forgetMessageButton.enabled = enableUserActions; + self.forgetMessageButton.userInteractionEnabled = enableUserActions; self.deactivateAcccountButton.enabled = enableUserActions; } @@ -272,8 +272,15 @@ static CGFloat const kTextFontSize = 15.0; [self.mainSession deactivateAccountWithAuthParameters:authParameters eraseAccount:eraseAllMessages success:^{ NSLog(@"[SettingsViewController] Deactivate account with success"); - [weakSelf stopActivityIndicator]; - [weakSelf enableUserActions:YES]; + typeof(weakSelf) strongSelf = weakSelf; + + if (strongSelf) + { + [strongSelf stopActivityIndicator]; + [strongSelf enableUserActions:YES]; + [strongSelf.delegate deactivateAccountViewControllerDidDeactivateWithSuccess:strongSelf]; + } + } failure:^(NSError *error) { NSLog(@"[SettingsViewController] Failed to deactivate account"); From 6d37f66b98f6f7b17ccca4303fe52e655a98a189 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 1 Jun 2018 16:07:42 +0200 Subject: [PATCH 49/51] Update logout method in AppDelegate, add possibility to send or not logout request to home server --- Riot/AppDelegate.h | 5 ++++- Riot/AppDelegate.m | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Riot/AppDelegate.h b/Riot/AppDelegate.h index 872fa21a4..ede68dacd 100644 --- a/Riot/AppDelegate.h +++ b/Riot/AppDelegate.h @@ -117,9 +117,12 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification; Log out all the accounts without confirmation. Show the authentication screen on successful logout. + @param sendLogoutRequest Indicate whether send logout request to home server. @param completion the block to execute at the end of the operation. */ -- (void)logoutWithCompletion:(void (^)(BOOL isLoggedOut))completion; +- (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest + completion:(void (^)(BOOL isLoggedOut))completion; + #pragma mark - Matrix Accounts handling diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 378af11ef..db6b5815f 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -2677,7 +2677,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN [topVC startActivityIndicator]; } - [self logoutWithCompletion:^(BOOL isLoggedOut) { + [self logoutSendingRequestServer:YES completion:^(BOOL isLoggedOut) { if (completion) { completion (YES); @@ -2685,7 +2685,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN }]; } -- (void)logoutWithCompletion:(void (^)(BOOL isLoggedOut))completion +- (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest + completion:(void (^)(BOOL isLoggedOut))completion { self.pushRegistry = nil; isPushRegistered = NO; From bd5428cfdb19d39a99c41bad7b439c8f919fef45 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 1 Jun 2018 16:08:55 +0200 Subject: [PATCH 50/51] Update account deactivation success handling in SettingsViewController. Do not send logout request to home server. --- Riot/ViewController/SettingsViewController.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/ViewController/SettingsViewController.m b/Riot/ViewController/SettingsViewController.m index fb90398b1..5c7e2d5d5 100644 --- a/Riot/ViewController/SettingsViewController.m +++ b/Riot/ViewController/SettingsViewController.m @@ -4102,8 +4102,9 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); - (void)deactivateAccountViewControllerDidDeactivateWithSuccess:(DeactivateAccountViewController *)deactivateAccountViewController { NSLog(@"[SettingsViewController] Deactivate account with success"); + - [[AppDelegate theDelegate] logoutWithCompletion:^(BOOL isLoggedOut) { + [[AppDelegate theDelegate] logoutSendingRequestServer:NO completion:^(BOOL isLoggedOut) { NSLog(@"[SettingsViewController] Complete clear user data after account deactivation"); }]; } From 1ed9dc42fd4c8a122e872b9a6ba7076842df0b81 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 1 Jun 2018 16:56:05 +0200 Subject: [PATCH 51/51] version++ --- CHANGES.rst | 17 +++++++++++++++++ Podfile | 2 +- Podfile.lock | 36 +++++++++++++++++------------------ Riot/Info.plist | 4 ++-- RiotShareExtension/Info.plist | 2 +- SiriIntents/Info.plist | 2 +- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 72a325281..3be965fab 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,20 @@ +Changes in 0.6.17 (2018-06-01) +=============================================== + +Improvements: + * Upgrade MatrixKit version (v0.7.14). + * Send Stickers (#1860). + * Settings: Add deactivate account (#1870). + * Widgets: Update from UIWebView to WKWebView to improve performance. + +Bug fix: + * Quotes (by themselves) render as white blocks (#1877). + * GDPR: consent screen could not be closed (#1883). + * GDPR: Do not display error alert when receiving GDPR Consent not given (#1886). + +Translations: + * Enable Icelandic. + Changes in 0.6.16 (2018-05-23) =============================================== diff --git a/Podfile b/Podfile index f00ef7e3f..8901c7ffc 100644 --- a/Podfile +++ b/Podfile @@ -9,7 +9,7 @@ source 'https://github.com/CocoaPods/Specs.git' # Different flavours of pods to MatrixKit # The current MatrixKit pod version -$matrixKitVersion = '0.7.12' +$matrixKitVersion = '0.7.14' # The develop branch version #$matrixKitVersion = 'develop' diff --git a/Podfile.lock b/Podfile.lock index f99897a29..01b0c1cae 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -43,34 +43,34 @@ PODS: - GZIP (1.2.1) - HPGrowingTextView (1.1) - libPhoneNumber-iOS (0.9.13) - - MatrixKit (0.7.12): + - MatrixKit (0.7.14): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixKit/Core (= 0.7.12) - - MatrixSDK (= 0.10.10) - - MatrixKit/AppExtension (0.7.12): + - MatrixKit/Core (= 0.7.14) + - MatrixSDK (= 0.10.11) + - MatrixKit/AppExtension (0.7.14): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - DTCoreText/Extension - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.10.10) - - MatrixKit/Core (0.7.12): + - MatrixSDK (= 0.10.11) + - MatrixKit/Core (0.7.14): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.10.10) - - MatrixSDK (0.10.10): - - MatrixSDK/Core (= 0.10.10) - - MatrixSDK/Core (0.10.10): + - MatrixSDK (= 0.10.11) + - MatrixSDK (0.10.11): + - MatrixSDK/Core (= 0.10.11) + - MatrixSDK/Core (0.10.11): - AFNetworking (~> 3.2.0) - GZIP (~> 1.2.1) - OLMKit (~> 2.2.2) - Realm (~> 3.3.2) - - MatrixSDK/JingleCallStack (0.10.10): + - MatrixSDK/JingleCallStack (0.10.11): - MatrixSDK/Core - WebRTC (= 63.11.20455) - OLMKit (2.2.2): @@ -90,14 +90,14 @@ DEPENDENCIES: - cmark - DTCoreText - GBDeviceInfo (~> 5.1.0) - - MatrixKit (= 0.7.12) - - MatrixKit/AppExtension (= 0.7.12) + - MatrixKit (= 0.7.14) + - MatrixKit/AppExtension (= 0.7.14) - MatrixSDK/JingleCallStack - OLMKit - PiwikTracker (from `https://github.com/manuroe/matomo-sdk-ios.git`, branch `feature/CustomVariables`) SPEC REPOS: - https://github.com/CocoaPods/Specs.git: + https://github.com/cocoapods/specs.git: - AFNetworking - cmark - DTCoreText @@ -131,13 +131,13 @@ SPEC CHECKSUMS: GZIP: 7ee835f989fb3c6ea79005fc90b8fa6af710a70d HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19 libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa - MatrixKit: ac91b2667d1be1895994ee78654d6193a6644b09 - MatrixSDK: c74ed8b41e3e55b7510d7bddf612ed1985816e04 + MatrixKit: ca192403abc03229f5cc5c193bd24a292e302304 + MatrixSDK: abb44d24e0426f3734630362c736d96446a629a3 OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd PiwikTracker: 42862c7b13028065c3dfd36b4dc38db8a5765acf Realm: d927fbf66df5532cfafc08afb5f7e53ded37b894 WebRTC: f2a6203584745fe53532633397557876b5d71640 -PODFILE CHECKSUM: ba3cdb1f77ff6463e50f031aefd807535f5612ad +PODFILE CHECKSUM: f62acabc542b9493f2d704d8c5163a53051b1979 -COCOAPODS: 1.5.0 +COCOAPODS: 1.5.3 diff --git a/Riot/Info.plist b/Riot/Info.plist index d00816a35..cbd7ee6ea 100644 --- a/Riot/Info.plist +++ b/Riot/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.16 + 0.6.17 CFBundleSignature ???? CFBundleVersion - 0.6.16 + 0.6.17 ITSAppUsesNonExemptEncryption ITSEncryptionExportComplianceCode diff --git a/RiotShareExtension/Info.plist b/RiotShareExtension/Info.plist index 3a95c6092..733c119fa 100644 --- a/RiotShareExtension/Info.plist +++ b/RiotShareExtension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 0.6.16 + 0.6.17 CFBundleVersion 1 NSExtension diff --git a/SiriIntents/Info.plist b/SiriIntents/Info.plist index c914d2e10..b9785df49 100644 --- a/SiriIntents/Info.plist +++ b/SiriIntents/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 0.6.16 + 0.6.17 CFBundleVersion 1 NSExtension