From 801e7f75a3c5ef35353139572061fb1c0cdd5c26 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 9448fc79f581690a9096c299dca3953a5788a711 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 974faaef3f0306af2d75c3c9241ce2676f91b1d4 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 f95f33551ebab2e9445d1b90d2e36fdf2fe37a8d 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 c1e103cc9267297bea7b1128d9e71e326cdca1f9 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 3930bef07b3c825c686e99fb5c890e8003353792 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 3ffd5fe9ac668fdd5ffef6a06c2316d737f8ed8e 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 9f47fea47b25aeba434852eb0a02750489267ac8 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 b5a0069c48052605381f7eb5bf56709479705159 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 66d2001718a983a78486407c3c61719e90d7a8e5 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 8cdcbfa0bb06b534424b43ddb480caf2db6d751c 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 360bd3c6301bf222259219e1c2bfe933f704972d 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 c764bb7ef3573fb133ae55a41fed5155eabc8284 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 ee0c18ae6a5c0c40d19d30e335488e733df2c11f 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 86e012026bb83ede08142c7a13a30d69f858a6b1 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 bba11ff74449cb7b85e347578486ef52be22329f 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 cfc7830f86f86e2286632d8ab5f2e6053d8ebc28 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 68fb1f16bf36081afddab92103d9b309c196d716 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 ce48b54784e064b54ece1586f46b2ca033bb2d99 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 16419eb6e8f6423d3ebb3916bb0abbd5f16154d2 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 7eb8fb376ede91998cb7da9bfe214f522c53667a 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 d44867cfdead7250d669990a342091ef73b582a4 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 38ba63d916527d4cee90c4bdc8845eef578380af 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 d161e9ca19b703431c704fe509a6bad751176083 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 d026478d99ff3c8cb0f8887c75817b66d322ec85 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 41c3dc711c3bc90410df87285ef3d54953d6a2af 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 0aac1835c5faad46fe314c3db3fd84b012c2c937 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 098c95c8226c47664fb6c5de4fa5dda0a3bdff05 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 5f199d6a8a3d80c582f44fcb81e23309d0b27dfe 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 92b9adf6eb9f3a8f7a0353f560d4b9c9e81dd706 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 9c5eaa088fb394760e8c18a5553213d600096250 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 d6a1477cdd5df962fbf6243d8b3042823d20782a 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 c2259fdb04cf5c84aca35cfd21b69f0ce2542543 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 ff199a99f9ae0415c0b30c66b31fa85902287afd 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 d9ed6c4a84438abc8871e3a9a7afbcce80bb58b9 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 60634cee099c9d016023ae80d42b2c09d4b71a91 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 a572ec1c7c6bbda7937a98e24dfee988becd03b6 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 446592c97c86cf55b1b9bd6354a67c871d05852a 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 e357fd0ccf6e0a9888b4d227552352ff7165dc29 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 1bf0a76ffc2532df0946b8b87bef118a9e9a68e3 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 e4d020d9cd4fbaf64b349004542e5cfd22918306 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 1d926c68702624ad89d6842eeb7ea03ca0f7d990 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 9f64a856da3f3a564b3dc01ff5a51779fed2f40d 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 4bcfaa46e89287a861d2c0faf834d496e284d047 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 d26b954d7de0c45a9f24c32d166586bc0068ad14 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 4a06d76ccf2b7b9819f32d739c0899919d36c782 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 43d4453cbd31a07b45018397ba8ce4a179e277ae 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 38ac909955d0e91c8e2912132db4f52f99c91b76 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 c0e086d294edd9d0fd017c0404962da9c661ddcd 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 9abb8ab6f8fd86b8d43a317eaf09cd2f2e95ef87 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 881ead2bcca2206af19db820ad265fe965606c56 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