From f5a3ece31865b99157e03c47cf6eb06b63e218b4 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 2 Jan 2024 11:18:51 +0100 Subject: [PATCH 01/91] GH actions: remove triaging process and old GH projects --- .github/workflows/triage-incoming.yml | 37 ---------- .github/workflows/triage-move-labelled.yml | 72 -------------------- .github/workflows/triage-move-unlabelled.yml | 61 ----------------- 3 files changed, 170 deletions(-) delete mode 100644 .github/workflows/triage-incoming.yml delete mode 100644 .github/workflows/triage-move-unlabelled.yml diff --git a/.github/workflows/triage-incoming.yml b/.github/workflows/triage-incoming.yml deleted file mode 100644 index 11f3280cc9..0000000000 --- a/.github/workflows/triage-incoming.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Move new issues onto Issue triage board - -on: - issues: - types: [opened] - -jobs: - automate-project-columns: - runs-on: ubuntu-latest - steps: - - uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488 - with: - project: Issue triage - column: Incoming - repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - add_to_triage: - runs-on: ubuntu-latest - if: > - github.repository == 'element-hq/element-ios' - steps: - - uses: octokit/graphql-action@v2.x - with: - headers: '{"GraphQL-Features": "projects_next_graphql"}' - query: | - mutation add_to_project($projectid:ID!,$contentid:ID!) { - addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) { - item { - id - } - } - } - projectid: ${{ env.PROJECT_ID }} - contentid: ${{ github.event.issue.node_id }} - env: - PROJECT_ID: "PVT_kwDOAM0swc4AMlHr" - GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} diff --git a/.github/workflows/triage-move-labelled.yml b/.github/workflows/triage-move-labelled.yml index 4282571424..b14355db80 100644 --- a/.github/workflows/triage-move-labelled.yml +++ b/.github/workflows/triage-move-labelled.yml @@ -30,17 +30,6 @@ jobs: labels: ['Z-Labs'] }) - move_needs_info_issues: - name: X-Needs-Info issues to Need info column on triage board - runs-on: ubuntu-latest - steps: - - uses: konradpabjan/move-labeled-or-milestoned-issue@219d384e03fa4b6460cd24f9f37d19eb033a4338 - with: - action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}" - project-url: "https://github.com/element-hq/element-ios/projects/12" - column-name: "Need info" - label-name: "X-Needs-Info" - add_priority_design_issues_to_project: name: P1 X-Needs-Design to Design project board runs-on: ubuntu-latest @@ -68,64 +57,3 @@ jobs: with: project-url: https://github.com/orgs/element-hq/projects/28 github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - ex_plorers: - name: Add labelled issues to X-Plorer project - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'Team: Element X Feature') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/73 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - ps_features1: - name: Add labelled issues to PS features team 1 - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'A-Polls') || - contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || - (contains(github.event.issue.labels.*.name, 'A-Voice-Messages') && - !contains(github.event.issue.labels.*.name, 'A-Broadcast')) || - (contains(github.event.issue.labels.*.name, 'A-Session-Mgmt') && - contains(github.event.issue.labels.*.name, 'A-User-Settings')) - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/56 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - ps_features2: - name: Add labelled issues to PS features team 2 - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'A-DM-Start') || - contains(github.event.issue.labels.*.name, 'A-Broadcast') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/58 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - ps_features3: - name: Add labelled issues to PS features team 3 - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/57 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - voip: - name: Add labelled issues to VoIP project board - runs-on: ubuntu-latest - if: > - contains(github.event.issue.labels.*.name, 'Team: VoIP') - steps: - - uses: actions/add-to-project@main - with: - project-url: https://github.com/orgs/element-hq/projects/41 - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} diff --git a/.github/workflows/triage-move-unlabelled.yml b/.github/workflows/triage-move-unlabelled.yml deleted file mode 100644 index 453fafe542..0000000000 --- a/.github/workflows/triage-move-unlabelled.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Move unlabelled from needs info columns to triaged - -on: - issues: - types: [unlabeled] - -jobs: - Move_Unabeled_Issue_On_Project_Board: - name: Move no longer X-Needs-Info issues to Triaged - runs-on: ubuntu-latest - if: > - ${{ - !contains(github.event.issue.labels.*.name, 'X-Needs-Info') }} - env: - BOARD_NAME: "Issue triage" - OWNER: ${{ github.repository_owner }} - REPO: ${{ github.event.repository.name }} - ISSUE: ${{ github.event.issue.number }} - steps: - - name: Check if issue is already in "${{ env.BOARD_NAME }}" - run: | - if curl -i -H 'Content-Type: application/json' -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -X POST -d '{"query": "query($issue: Int!, $owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { issue(number: $issue) { projectCards { nodes { project { name } } } } } } ", "variables" : "{ \"issue\": '${ISSUE}', \"owner\": \"'${OWNER}'\", \"repo\": \"'${REPO}'\" }" }' https://api.github.com/graphql | grep "\b$BOARD_NAME\b"; then - echo "Issue is already in Project '$BOARD_NAME', proceeding"; - echo "ALREADY_IN_BOARD=true" >> $GITHUB_ENV - else - echo "Issue is not in project '$BOARD_NAME', cancelling this workflow" - echo "ALREADY_IN_BOARD=false" >> $GITHUB_ENV - fi - - name: Move issue - uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488 - if: ${{ env.ALREADY_IN_BOARD == 'true' }} - with: - project: Issue triage - column: Triaged - repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - - remove_Z-Labs_label: - name: Remove Z-Labs label when features behind labs flags are removed - runs-on: ubuntu-latest - if: > - !(contains(github.event.issue.labels.*.name, 'A-Maths') || - contains(github.event.issue.labels.*.name, 'A-Message-Pinning') || - contains(github.event.issue.labels.*.name, 'A-Threads') || - contains(github.event.issue.labels.*.name, 'A-Polls') || - contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || - contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') || - contains(github.event.issue.labels.*.name, 'Z-IA') || - contains(github.event.issue.labels.*.name, 'A-Themes-Custom') || - contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || - contains(github.event.issue.labels.*.name, 'A-Tags')) && - contains(github.event.issue.labels.*.name, 'Z-Labs') - steps: - - uses: actions/github-script@v5 - with: - script: | - github.rest.issues.removeLabel({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - name: ['Z-Labs'] - }) From 19606ae08d985d817048631be8dace5d367ac733 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 8 Jan 2024 21:14:11 +0100 Subject: [PATCH 02/91] Change RiotNSE product name to TchapNSE for user-agent in backend logs. --- RiotNSE/Common.xcconfig | 10 ++++++++-- TchapNSE/Common.xcconfig | 10 ++++++++-- changelog.d/664.change | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 changelog.d/664.change diff --git a/RiotNSE/Common.xcconfig b/RiotNSE/Common.xcconfig index 5fb618d128..19b42ed0c8 100644 --- a/RiotNSE/Common.xcconfig +++ b/RiotNSE/Common.xcconfig @@ -19,7 +19,10 @@ #include "Tchap/SupportingFiles/App-Common.xcconfig" -PRODUCT_NAME = RiotNSE + +// Tchap: Customize TchapNSE user-agent for back-end logs. +// PRODUCT_NAME = RiotNSE +PRODUCT_NAME = TchapNSE PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER).nse INFOPLIST_FILE = RiotNSE/Info.plist @@ -27,5 +30,8 @@ INFOPLIST_FILE = RiotNSE/Info.plist CODE_SIGN_ENTITLEMENTS = RiotNSE/RiotNSE.entitlements SKIP_INSTALL = YES -SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/$(PRODUCT_NAME)/SupportingFiles/RiotNSE-Bridging-Header.h + +// Tchap: Customize TchapNSE user-agent for back-end logs. +// SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/$(PRODUCT_NAME)/SupportingFiles/RiotNSE-Bridging-Header.h +SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h diff --git a/TchapNSE/Common.xcconfig b/TchapNSE/Common.xcconfig index 5fb618d128..19b42ed0c8 100644 --- a/TchapNSE/Common.xcconfig +++ b/TchapNSE/Common.xcconfig @@ -19,7 +19,10 @@ #include "Tchap/SupportingFiles/App-Common.xcconfig" -PRODUCT_NAME = RiotNSE + +// Tchap: Customize TchapNSE user-agent for back-end logs. +// PRODUCT_NAME = RiotNSE +PRODUCT_NAME = TchapNSE PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER).nse INFOPLIST_FILE = RiotNSE/Info.plist @@ -27,5 +30,8 @@ INFOPLIST_FILE = RiotNSE/Info.plist CODE_SIGN_ENTITLEMENTS = RiotNSE/RiotNSE.entitlements SKIP_INSTALL = YES -SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/$(PRODUCT_NAME)/SupportingFiles/RiotNSE-Bridging-Header.h + +// Tchap: Customize TchapNSE user-agent for back-end logs. +// SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/$(PRODUCT_NAME)/SupportingFiles/RiotNSE-Bridging-Header.h +SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h diff --git a/changelog.d/664.change b/changelog.d/664.change new file mode 100644 index 0000000000..8f88ad983e --- /dev/null +++ b/changelog.d/664.change @@ -0,0 +1 @@ +Rename RiotNSE extension product name to TchapNSE. It will change user-agent of requests in backend logs. \ No newline at end of file From 61b93999f650df4e6959c9995fe30f98d0fb1a77 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 9 Jan 2024 15:06:17 +0100 Subject: [PATCH 03/91] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 3954513c8b..b0122b592b 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.6 -CURRENT_PROJECT_VERSION = 1.11.6 +MARKETING_VERSION = 1.11.7 +CURRENT_PROJECT_VERSION = 1.11.7 From 9ed3a7fd5beef33af4bf0f1cfb92b238d76a3c0c Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Mon, 29 Jan 2024 15:35:47 +0100 Subject: [PATCH 04/91] fix --- Riot/Assets/en.lproj/Vector.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index e1244e81ef..6a7f09c6e9 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2617,8 +2617,8 @@ To enable access, tap Settings> Location and select Always"; // Formatting Actions "wysiwyg_composer_format_action_bold" = "Apply bold format"; "wysiwyg_composer_format_action_italic" = "Apply italic format"; -"wysiwyg_composer_format_action_underline" = "Apply strikethrough format"; -"wysiwyg_composer_format_action_strikethrough" = "Apply underline format"; +"wysiwyg_composer_format_action_underline" = "Apply underline format"; +"wysiwyg_composer_format_action_strikethrough" = "Apply strikethrough format"; "wysiwyg_composer_format_action_link" = "Apply link format"; "wysiwyg_composer_format_action_inline_code" = "Apply inline code format"; "wysiwyg_composer_format_action_unordered_list" = "Toggle bulleted list"; From 4bfebda7fa3fd393a442c02b9c027f89d7dd53bb Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Mon, 29 Jan 2024 15:44:27 +0100 Subject: [PATCH 05/91] changelog --- changelog.d/pr-7743.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/pr-7743.bugfix diff --git a/changelog.d/pr-7743.bugfix b/changelog.d/pr-7743.bugfix new file mode 100644 index 0000000000..8d0a13e420 --- /dev/null +++ b/changelog.d/pr-7743.bugfix @@ -0,0 +1 @@ +Fix swapped accessibility label between strikethrough and underline format buttons in RTE. \ No newline at end of file From 5f8ef6713c9d519d34b90e6cfe5d679cb2bad1ed Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 9 Jan 2024 12:54:31 +0000 Subject: [PATCH 06/91] Translated using Weblate (Albanian) Currently translated at 99.6% (2407 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sq/ --- Riot/Assets/sq.lproj/Vector.strings | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings index 1dc4968b50..4b123786ec 100644 --- a/Riot/Assets/sq.lproj/Vector.strings +++ b/Riot/Assets/sq.lproj/Vector.strings @@ -127,8 +127,8 @@ "contacts_user_directory_offline_section" = "DREJTORI PËRDORUESISH (jashtë linje)"; // Chat participants "room_participants_title" = "Pjesëmarrës"; -"room_participants_add_participant" = "Shtoni pjesmarrës"; -"room_participants_one_participant" = "1 pjesmarrës"; +"room_participants_add_participant" = "Shtoni pjesëmarrës"; +"room_participants_one_participant" = "1 pjesëmarrës"; "room_participants_multi_participants" = "%d pjesëmarrës"; "room_participants_leave_prompt_title" = "Dilni nga dhomë"; "room_participants_leave_prompt_msg" = "Jeni i sigurt se doni të ikni nga dhoma?"; @@ -317,7 +317,7 @@ "group_home_one_room_format" = "1 dhomë"; "group_invitation_format" = "%@ ju ftoi të bëheni pjesë e kësaj bashkësie"; // Group participants -"group_participants_add_participant" = "Shtoni pjesmarrës"; +"group_participants_add_participant" = "Shtoni pjesëmarrës"; "group_participants_leave_prompt_title" = "Braktiseni grupin"; "group_participants_leave_prompt_msg" = "Jeni i sigurt se doni ta braktisni grupin?"; "group_participants_remove_prompt_title" = "Ripohim"; @@ -398,7 +398,7 @@ "auth_add_email_and_phone_warning" = "Regjistrimi me email dhe me numër telefoni njëherazi nuk mbulohet ende, deri sa të ketë API. Do të merret parasysh vetëm numri i telefonit. Email-in tuaj mund ta shtoni te profili juaj, te rregullimet."; "room_creation_appearance_picture" = "Foto fjalosjeje (në daçi)"; "room_creation_invite_another_user" = "ID Përdoruesi, emër ose email"; -"room_recents_favourites_section" = "TË PARAPALQYERA"; +"room_recents_favourites_section" = "TË PARAPËLQYERA"; "room_recents_server_notice_section" = "SINJALIZIME SISTEMI"; "room_recents_join_room_title" = "Hyni në një dhomë"; "room_participants_invite_another_user" = "Kërkoni / ftoni sipas ID-je Përdoruesi, Emri ose email-i"; @@ -507,7 +507,7 @@ "room_details_history_section_members_only" = "Vetëm anëtarët (që nga çasti i përzgjedhjes së kësaj mundësie)"; "room_details_history_section_prompt_msg" = "Ndryshime se cilët mund të lexojnë historikun do të vlejnë vetëm për mesazhe të ardhshëm në këtë dhomë. Dukshmëria e historikut ekzistues nuk do të ndryshohet."; "room_details_addresses_disable_main_address_prompt_msg" = "S’do të keni adresë kryesore të specifikuar. Adresa kryesore parazgjedhje për këtë dhomë do të zgjidhet në tym"; -"room_details_advanced_enable_e2e_encryption" = "Aktivizo fshehtëzim (kujdes: s’mund të çaktizohet më!)"; +"room_details_advanced_enable_e2e_encryption" = "Aktivizo fshehtëzim (kujdes: s’mund të çaktivizohet më!)"; "room_details_advanced_e2e_encryption_prompt_message" = "Fshehtëzimi skaj-më-skaj është eksperimental dhe mund të mos jetë i qëndrueshëm.\n\nS’duhet t’i zini ende besë për sigurim të dhënash.\n\nPajisjet s’do të jenë ende në gjendje të shfshehtëzojnë historik nga periudha përpara se të merrnin pjesë te dhomë.\n\nPasi të jetë aktivizuar fshehtëzimi për një dhomë, s’mund të çaktivizohet më (hëpërhë).\n\nMesazhet e fshehtëzuar s’do të jenë të dukshëm në klientë që nuk sendërtojnë ende fshehtëzimin."; "room_details_fail_to_update_room_guest_access" = "S’arrihet të përditësohet mundësia e hyrjes në dhomë të vizitorëve"; "group_participants_invite_malformed_id" = "ID e keqformuar. Duhet të jetë një ID Matrix, si '@localpart:domain'"; @@ -619,7 +619,7 @@ "key_backup_setup_intro_setup_action_without_existing_backup" = "Fillo të përdorësh Kopjeruajtje Kyçesh"; "key_backup_setup_intro_setup_action_with_existing_backup" = "Përdor Kopjeruajtje Kyçesh"; "key_backup_setup_passphrase_title" = "Sigurojeni kopjeruajtjen tuaj me një Frazë Sigurie"; -"key_backup_setup_passphrase_setup_recovery_key_info" = "Ose, sigurojeni kopjeruajtjen tuaj me një Kyç Sigurie, duke e ruajtur këtë diku të parrezikuar."; +"key_backup_setup_passphrase_setup_recovery_key_info" = "Ose, sigurojeni kopjeruajtjen tuaj me një Kyç Sigurie, duke e ruajtur këtë diku të parrezik."; "key_backup_setup_passphrase_setup_recovery_key_action" = "(Të mëtejshme) Rregullojeni me një Kyç Sigurie"; "key_backup_setup_success_title" = "Sukses!"; // Success from passphrase @@ -627,7 +627,7 @@ "key_backup_setup_success_from_passphrase_save_recovery_key_action" = "Ruani Kyç Sigurie"; "key_backup_setup_success_from_passphrase_done_action" = "U krye"; // Success from recovery key -"key_backup_setup_success_from_recovery_key_info" = "Po bëhet kopjeruajtja për kyçet tuaj.\n\nBëni një kopje të këtij Kyçi Sigurie dhe mbajeni të parrezikuar."; +"key_backup_setup_success_from_recovery_key_info" = "Po bëhet kopjeruajtja për kyçet tuaj.\n\nBëni një kopje të këtij Kyçi Sigurie dhe mbajeni të parrezik."; "key_backup_setup_success_from_recovery_key_recovery_key_title" = "Kyç Sigurie"; "key_backup_setup_success_from_recovery_key_make_copy_action" = "Bëni një Kopje"; "key_backup_setup_success_from_recovery_key_made_copy_action" = "Kam bërë një kopje"; @@ -1129,7 +1129,7 @@ "secure_key_backup_setup_existing_backup_error_info" = "Shkyçeni, që ta ripërdorni te kopjeruajtja e sigurt ose për ta fshirë që të krijoni një kopjeruajtje të re mesazhesh te kopjeruajtja e sigurt."; "secure_key_backup_setup_existing_backup_error_unlock_it" = "Shkyçe"; "secure_key_backup_setup_existing_backup_error_delete_it" = "Fshije"; -"sign_out_non_existing_key_backup_alert_setup_secure_backup_action" = "Fillo të përdorësh Kojperuajtje të Sigurt"; +"sign_out_non_existing_key_backup_alert_setup_secure_backup_action" = "Fillo të përdorësh Kopjeruajtje të Sigurt"; "security_settings_crypto_sessions_description_2" = "Nëse nuk njihni një palë kredenciale, ndryshoni fjalëkalimin tuaj Matrix dhe riujdisni Kopjeruajtjen e Sigurt."; "cross_signing_setup_banner_title" = "Ujdisni fshehtëzim"; "cross_signing_setup_banner_subtitle" = "Verifikoni më me lehtësi pajisje të tjera"; @@ -1517,7 +1517,7 @@ "poll_timeline_vote_not_registered_action" = "OK"; "poll_timeline_vote_not_registered_subtitle" = "Na ndjeni, vota juaj s’u regjistrua, ju lutemi, riprovoni"; "poll_timeline_vote_not_registered_title" = "Votë e paregjistruar"; -"poll_timeline_total_final_results" = "Rezultati përfundimtar, bazua në %lu votë"; +"poll_timeline_total_final_results" = "Rezultati përfundimtar, bazua në %lu vota"; "poll_timeline_total_final_results_one_vote" = "Rezultati përfundimtar, bazua në 1 votë"; "poll_timeline_total_votes_not_voted" = "%lu vota të hedhura. Që të shihni përfundimet, votoni"; "poll_timeline_total_one_vote_not_voted" = "1 votë e hedhur. Që të shihni përfundimet, votoni"; @@ -1975,9 +1975,9 @@ // Room members "room_member_ignore_prompt" = "Doni të fshihen krejt mesazhet nga ky përdorues?"; "room_member_power_level_prompt" = "S’do të jeni në gjendje ta zhbëni këtë ndryshim, ngaqë po e promovoni përdoruesin të ketë të njëjtën shkallë pushteti si ju vetë.\nJeni i sigurt?"; -"attachment_e2e_keys_file_prompt" = "Kjo kartelë përmban kyçe fshehtëzimi të eksportur nga një klient Matrix.\nDoni të shihni lëndën e kartelës apo të importoni kyçet që ajo përmban?"; +"attachment_e2e_keys_file_prompt" = "Kjo kartelë përmban kyçe fshehtëzimi të eksportuar nga një klient Matrix.\nDoni të shihni lëndën e kartelës apo të importoni kyçet që ajo përmban?"; "e2e_import_prompt" = "Ky proces ju lejon të importoni kyçe fshehtëzimi që keni eksportuar më parë nga një tjetër klient Matrix. Mandej do të jeni në gjendje të shfshehtëzoni çfarëdo mesazhesh që mund të shfshehtëzojë ai klient tjetër.\nKartela e eksportit është e mbrojtur me një frazëkalim. Që të shfshehtëzoni kartelën, duhet ta jepni frazëkalimin këtu."; -"e2e_export_prompt" = "Ky proces ju lejon të eksportoni te një kartelë vendore kyçet për mesazhe që keni marrë në dhoma të fshehtëzuara. Mandej do të jeni në gjendje ta importoni kartelën te një tjetër klient Matrix në të ardhmen, që kështu ai klient të jetë në gjendje t’i fshehtëzojë këto mesazhe.\nKartela e eksportuar do t’i lejojë, cilitdo që mund ta lexojë, të shfshehtëzojë çfarëdo mesazhesh të fshehtëzuar që mund të shihni ju, ndaj duhet të bëni kujdes ta mbani të parrezikuar."; +"e2e_export_prompt" = "Ky proces ju lejon të eksportoni te një kartelë vendore kyçet për mesazhe që keni marrë në dhoma të fshehtëzuara. Mandej do të jeni në gjendje ta importoni kartelën te një tjetër klient Matrix në të ardhmen, që kështu ai klient të jetë në gjendje t’i fshehtëzojë këto mesazhe.\nKartela e eksportuar do t’i lejojë, cilitdo që mund ta lexojë, të shfshehtëzojë çfarëdo mesazhesh të fshehtëzuar që mund të shihni ju, ndaj duhet të bëni kujdes ta mbani të parrezik."; "error_common_message" = "Ndodhi një gabim. Ju lutemi, riprovoni më vonë."; // Permissions "camera_access_not_granted_for_call" = "Thirrjet video lypin përdorim të Kamerës, por %@ s’ka leje për ta përdorur"; @@ -1988,7 +1988,7 @@ "redact" = "Hiqe"; // contacts list screen "invitation_message" = "Do të doja të bisedoja me ju me Matrix. Për të pasur më tepër itë dhëna, ju lutem, vizitoni sajtin http://matrix.org."; -"notification_settings_global_info" = "Rregullimet mbi njoftimet ruhen te llogaria juaj e përdoruesit dhe ndahen me krejt klientët që i mbulojnë ato (përfshi njoftimet në desktop).\n\nRregullat zbatohen sipas një radhe; rregulli i parë që ka përputhje përcakton lëndën për mesazhin.\nKështu: njoftimet sipas fjalësh janë më të rëndësishme se njoftimet sipas dhomash të cilat janë më të rëndësishme se njoftimet sipas dërguesish.\nFor multiple rules of the same kind, the first one in the list that matches takes priority."; +"notification_settings_global_info" = "Rregullimet mbi njoftimet ruhen te llogaria juaj e përdoruesit dhe ndahen me krejt klientët që i mbulojnë ato (përfshi njoftimet në desktop).\n\nRregullat zbatohen sipas një radhe; rregulli i parë që ka përputhje përcakton lëndën për mesazhin.\nKështu: njoftimet sipas fjalësh janë më të rëndësishme se njoftimet sipas dhomash të cilat janë më të rëndësishme se njoftimet sipas dërguesish.\nPër rregulla të shumta të të njëjtit lloj, i pari në listë që ka përputhje ka përparësinë."; "notification_settings_per_word_notifications" = "Njoftime sipas fjale"; "notification_settings_per_word_info" = "Për fjalët përputhjet gjenden pa marrë parasysh shkrimin me të madhe apo të vogël, dhe mund të përfshijnë një shenjë të gjithëpushtetshme *. Kështu:\nkot përputhet me vargun kot të rrethuar nga përkufizues fjalësh (p.sh. shenja pikësimi apo hapësira, ose fillim/fund rreshti).\nkot* përputhet me çfarëdo fjale që fillon me kot.\n*kot* përputhet me çfarëdo fjale që përfshin 3 shkronjat kot."; "notification_settings_per_room_notifications" = "Njoftime sipas dhome"; @@ -2422,7 +2422,7 @@ "deselect_all" = "Shpërzgjidhi Krejt"; "wysiwyg_composer_format_action_strikethrough" = "Apliko format me të nënvizuara"; "wysiwyg_composer_format_action_underline" = "Apliko format me të hequravije"; -"wysiwyg_composer_format_action_italic" = "Apliko format me të pjerrta"; +"wysiwyg_composer_format_action_italic" = "Apliko format me të pjerrëta"; // Formatting Actions "wysiwyg_composer_format_action_bold" = "Apliko format me të trasha"; @@ -2448,7 +2448,7 @@ "user_session_details_device_os" = "Sistem Operativ"; "user_session_details_device_browser" = "Shfletues"; "user_session_details_device_model" = "Model"; -"user_session_details_device_ip_location" = "Venndodhje IP-je"; +"user_session_details_device_ip_location" = "Vendndodhje IP-je"; "user_session_details_device_ip_address" = "Adresë IP"; "user_session_details_last_activity" = "Veprimtaria e fundit"; "user_session_details_session_section_footer" = "Kopjoni çfarëdo të dhëne duke prekur mbi të dhe duke e mbajtur të shtypur."; @@ -2660,7 +2660,7 @@ "wysiwyg_composer_format_action_link" = "Apliko formatim lidhjeje"; "notice_voice_broadcast_ended_by_you" = "Përfunduar një transmetim zanor."; "notice_voice_broadcast_ended" = "%@ përfundoi një transmetim zanor."; -"notice_voice_broadcast_live" = "Transmetim i drejtëpërdrejtë"; +"notice_voice_broadcast_live" = "Transmetim i drejtpërdrejtë"; "user_other_session_security_recommendation_title" = "Sesione të tjerë"; "poll_timeline_ended_text" = "Përfundoi pyetësori"; "poll_timeline_decryption_error" = "Për shkak gabimesh shfshehtëzimi, mund të mos jenë numëruar disa vota"; From b2055d51b8b167e912e6578d94f425104bb46aa6 Mon Sep 17 00:00:00 2001 From: Hubert Chen Date: Wed, 10 Jan 2024 14:51:23 +0000 Subject: [PATCH 07/91] Translated using Weblate (Chinese (Simplified)) Currently translated at 86.0% (2078 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/zh_Hans/ --- Riot/Assets/zh_Hans.lproj/Vector.strings | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/zh_Hans.lproj/Vector.strings b/Riot/Assets/zh_Hans.lproj/Vector.strings index 79177b974e..e3e3194b9c 100644 --- a/Riot/Assets/zh_Hans.lproj/Vector.strings +++ b/Riot/Assets/zh_Hans.lproj/Vector.strings @@ -928,7 +928,7 @@ // MARK: Emoji picker "emoji_picker_title" = "反应"; "emoji_picker_people_category" = "表情和人物"; -"emoji_picker_nature_category" = "动物和自热"; +"emoji_picker_nature_category" = "动物和自然"; "emoji_picker_foods_category" = "食物和饮料"; "emoji_picker_activity_category" = "活动"; "emoji_picker_places_category" = "旅游和景点"; @@ -2405,3 +2405,4 @@ "room_access_space_chooser_known_spaces_section" = "您知道的包含 %@ 的空间"; "room_access_space_chooser_other_spaces_section_info" = "这些很可能是 %@ 的管理员参与。"; "room_access_space_chooser_other_spaces_section" = "其他空间或房间"; +"event_formatter_message_deleted" = "消息已删除"; From 3ed37aa2d8b3b1e67c624abe5bc5c283045715d0 Mon Sep 17 00:00:00 2001 From: Hubert Chen Date: Wed, 10 Jan 2024 14:52:16 +0000 Subject: [PATCH 08/91] Translated using Weblate (Chinese (Simplified)) Currently translated at 86.5% (2090 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/zh_Hans/ --- Riot/Assets/zh_Hans.lproj/Vector.strings | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/zh_Hans.lproj/Vector.strings b/Riot/Assets/zh_Hans.lproj/Vector.strings index e3e3194b9c..50d43aed9a 100644 --- a/Riot/Assets/zh_Hans.lproj/Vector.strings +++ b/Riot/Assets/zh_Hans.lproj/Vector.strings @@ -952,7 +952,7 @@ "key_verification_tile_request_incoming_approval_decline" = "拒绝"; "key_verification_tile_conclusion_done_title" = "已验证"; "key_verification_tile_conclusion_warning_title" = "不被信任的登录"; -"key_verification_incoming_request_incoming_alert_message" = "%@想要验证"; +"key_verification_incoming_request_incoming_alert_message" = "%@ 想要进行验证"; "user_verification_start_verify_action" = "开始验证"; "user_verification_start_information_part1" = "为了额外的安全性,请验证: "; "user_verification_start_information_part2" = " 检查在你的两个设备上的一次性代码。"; @@ -2406,3 +2406,23 @@ "room_access_space_chooser_other_spaces_section_info" = "这些很可能是 %@ 的管理员参与。"; "room_access_space_chooser_other_spaces_section" = "其他空间或房间"; "event_formatter_message_deleted" = "消息已删除"; +"network_offline_title" = "您已离线"; + +// MARK: Sign out warning + +"sign_out" = "登出"; + +// Unverified sessions +"key_verification_alert_title" = "您有未验证的会话"; +"pill_message_in" = "在 %@ 里的消息"; + +// Legacy to Rust security upgrade + +"key_verification_self_verify_security_upgrade_alert_title" = "应用已更新"; +"sign_out_confirmation_message" = "您确定要登出吗?"; +"device_verification_self_verify_open_on_other_device_title" = "在您的另一台设备上打开 %@"; +"device_verification_self_verify_open_on_other_device_information" = "您需要先验证此会话才能读取加密信息。\n\n在您的其他设备上打开 Element 并按照说明进行操作。"; +"device_verification_self_verify_wait_recover_secrets_additional_help" = "已无法访问 %@ 会话?"; +"network_offline_message" = "您已离线,请检查您的网络链接。"; +"key_verification_alert_body" = "重新检查以确保您的账户安全。"; +"key_verification_scan_qr_code_title" = "扫描 QR Code"; From 4a553a611c4b0e7047d941b68485c070dc559c92 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 9 Jan 2024 12:55:34 +0000 Subject: [PATCH 09/91] Translated using Weblate (Albanian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/sq/ --- Riot/Assets/sq.lproj/InfoPlist.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/sq.lproj/InfoPlist.strings b/Riot/Assets/sq.lproj/InfoPlist.strings index a4d354d560..e2f9af626f 100644 --- a/Riot/Assets/sq.lproj/InfoPlist.strings +++ b/Riot/Assets/sq.lproj/InfoPlist.strings @@ -5,5 +5,5 @@ "NSContactsUsageDescription" = "Do t’i jepen shërbyesit tuaj të identiteteve, për ta ndihmuar të gjejë kontakte tuajt në Matrix."; "NSCalendarsUsageDescription" = "Shihini te aplikacioni takimet tuaja të planifikuara."; "NSFaceIDUsageDescription" = "Face ID përdoret që të hyni në aplikacionin tuaj."; -"NSLocationWhenInUseUsageDescription" = "Kur ndani vendndodhjen tuaj me persona, Element-i ka nevojë për hyrje në të, që t’u trgojë atyre një hartë."; +"NSLocationWhenInUseUsageDescription" = "Kur u tregoni vendndodhjen tuaj të tjerëve, Element-i ka nevojë për hyrje në të, që t’u tregojë atyre një hartë."; "NSLocationAlwaysAndWhenInUseUsageDescription" = "Kur u tregoni vendndodhjen tuaj të tjerëve, Element-it i duhet hyrje për t’u shfaqur një hartë."; From 7dfdb8334f5bc40a2c8cb66febf23b8657326bdd Mon Sep 17 00:00:00 2001 From: Mojtaba Date: Fri, 26 Jan 2024 07:26:29 +0000 Subject: [PATCH 10/91] Added translation using Weblate (Persian (Old)) --- Riot/Assets/peo.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/peo.lproj/InfoPlist.strings diff --git a/Riot/Assets/peo.lproj/InfoPlist.strings b/Riot/Assets/peo.lproj/InfoPlist.strings new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Riot/Assets/peo.lproj/InfoPlist.strings @@ -0,0 +1 @@ + From e24abbaba4a870ac6e58156f026a222d3f6eeef0 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Mon, 29 Jan 2024 16:26:59 +0100 Subject: [PATCH 11/91] corrected translations --- Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- Riot/Assets/de.lproj/Vector.strings | 4 ++-- Riot/Assets/et.lproj/Vector.strings | 4 ++-- Riot/Assets/fr.lproj/Vector.strings | 4 ++-- Riot/Assets/hu.lproj/Vector.strings | 4 ++-- Riot/Assets/id.lproj/Vector.strings | 4 ++-- Riot/Assets/it.lproj/Vector.strings | 4 ++-- Riot/Assets/ja.lproj/Vector.strings | 4 ++-- Riot/Assets/nl.lproj/Vector.strings | 4 ++-- Riot/Assets/pl.lproj/Vector.strings | 4 ++-- Riot/Assets/pt_BR.lproj/Vector.strings | 4 ++-- Riot/Assets/sk.lproj/Vector.strings | 4 ++-- Riot/Assets/sq.lproj/Vector.strings | 4 ++-- Riot/Assets/sv.lproj/Vector.strings | 4 ++-- Riot/Assets/uk.lproj/Vector.strings | 4 ++-- Riot/Assets/zh_Hant.lproj/Vector.strings | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index f406af44f5..47f1e5fe62 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -84,7 +84,7 @@ { "identity" : "swift-ogg", "kind" : "remoteSourceControl", - "location" : "https://github.com/vector-im/swift-ogg", + "location" : "https://github.com/element-hq/swift-ogg", "state" : { "branch" : "0.0.1", "revision" : "e9a9e7601da662fd8b97d93781ff5c60b4becf88" diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index 80eb951724..331614eca2 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -2616,8 +2616,8 @@ "manage_session_name_info" = "Sei dir bitte bewusst, dass Sitzungsnamen auch für Personen, mit denen du kommunizierst, sichtbar sind. %@"; "manage_session_name_hint" = "Individuelle Sitzungsnamen können dir helfen, deine Geräte einfacher zu erkennen."; "user_other_session_filter" = "Filtern"; -"wysiwyg_composer_format_action_strikethrough" = "Unterstrichen formatieren"; -"wysiwyg_composer_format_action_underline" = "Durchgestrichen formatieren"; +"wysiwyg_composer_format_action_strikethrough" = "Durchgestrichen formatieren"; +"wysiwyg_composer_format_action_underline" = "Unterstrichen formatieren"; "wysiwyg_composer_format_action_italic" = "Kursiv formatieren"; // Formatting Actions diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings index 5080a7ea52..3df4d23b9b 100644 --- a/Riot/Assets/et.lproj/Vector.strings +++ b/Riot/Assets/et.lproj/Vector.strings @@ -2499,8 +2499,8 @@ "authentication_qr_login_start_title" = "Loe QR-koodi"; "authentication_login_with_qr" = "Logi sisse QR-koodi abil"; "wysiwyg_composer_format_action_strikethrough" = "Kasuta allajoonitud kirja"; -"wysiwyg_composer_format_action_underline" = "Kasuta läbijoonitud kirja"; -"wysiwyg_composer_format_action_italic" = "Kasuta kaldkirja"; +"wysiwyg_composer_format_action_italic" = "Kasuta läbijoonitud kirja"; +"wysiwyg_composer_format_action_underline" = "Kasuta kaldkirja"; // Formatting Actions "wysiwyg_composer_format_action_bold" = "Kasuta paksu kirja"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index 5dfc717c94..ee14358945 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -2631,8 +2631,8 @@ "wysiwyg_composer_format_action_unordered_list" = "Liste à puces"; "wysiwyg_composer_format_action_inline_code" = "Formater comme code informatique"; "wysiwyg_composer_format_action_link" = "Formater comme lien"; -"wysiwyg_composer_format_action_strikethrough" = "Souligner"; -"wysiwyg_composer_format_action_underline" = "Barrer"; +"wysiwyg_composer_format_action_strikethrough" = "Barrer"; +"wysiwyg_composer_format_action_underline" = "Souligner"; "wysiwyg_composer_format_action_italic" = "Mettre en italique"; // Formatting Actions diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings index a77322f083..274042639a 100644 --- a/Riot/Assets/hu.lproj/Vector.strings +++ b/Riot/Assets/hu.lproj/Vector.strings @@ -2501,8 +2501,8 @@ "room_first_message_placeholder" = "Küld el az első üzenetedet…"; "authentication_qr_login_confirm_title" = "Biztonságos kapcsolat beállítva"; "room_event_encryption_info_key_authenticity_not_guaranteed" = "A titkosított üzenetek valódiságát ezen az eszközön nem lehet garantálni."; -"wysiwyg_composer_format_action_strikethrough" = "Aláhúzott"; -"wysiwyg_composer_format_action_underline" = "Áthúzott"; +"wysiwyg_composer_format_action_underline" = "Aláhúzott"; +"wysiwyg_composer_format_action_strikethrough" = "Áthúzott"; "wysiwyg_composer_format_action_italic" = "Dőlt"; // Formatting Actions diff --git a/Riot/Assets/id.lproj/Vector.strings b/Riot/Assets/id.lproj/Vector.strings index 0a43411c32..5e8e1c027e 100644 --- a/Riot/Assets/id.lproj/Vector.strings +++ b/Riot/Assets/id.lproj/Vector.strings @@ -2782,8 +2782,8 @@ "authentication_qr_login_start_subtitle" = "Gunakan kamera pada perangkat ini untuk memindai kode QR yang ditampilkan di perangkat Anda yang lain:"; "authentication_qr_login_start_title" = "Pindai kode QR"; "authentication_login_with_qr" = "Masuk dengan kode QR"; -"wysiwyg_composer_format_action_strikethrough" = "Terapkan format garis bawah"; -"wysiwyg_composer_format_action_underline" = "Terapkan format coret"; +"wysiwyg_composer_format_action_underline" = "Terapkan format garis bawah"; +"wysiwyg_composer_format_action_strikethrough" = "Terapkan format coret"; "wysiwyg_composer_format_action_italic" = "Terapkan format miring"; // Formatting Actions diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings index 5658e74789..0e893b97cb 100644 --- a/Riot/Assets/it.lproj/Vector.strings +++ b/Riot/Assets/it.lproj/Vector.strings @@ -2555,8 +2555,8 @@ "authentication_qr_login_start_subtitle" = "Usa la fotocamera di questo dispositivo per scansionare il codice QR mostrato nell'altro dispositivo:"; "authentication_qr_login_start_title" = "Scansiona codice QR"; "authentication_login_with_qr" = "Accedi con codice QR"; -"wysiwyg_composer_format_action_strikethrough" = "Applica formato sottolineato"; -"wysiwyg_composer_format_action_underline" = "Applica formato sbarrato"; +"wysiwyg_composer_format_action_underline" = "Applica formato sottolineato"; +"wysiwyg_composer_format_action_strikethrough" = "Applica formato sbarrato"; "wysiwyg_composer_format_action_italic" = "Applica formato corsivo"; // Formatting Actions diff --git a/Riot/Assets/ja.lproj/Vector.strings b/Riot/Assets/ja.lproj/Vector.strings index c1d7678303..0dfb2562ba 100644 --- a/Riot/Assets/ja.lproj/Vector.strings +++ b/Riot/Assets/ja.lproj/Vector.strings @@ -2752,8 +2752,8 @@ "notice_error_unformattable_event" = "** メッセージを描画できません。不具合を報告してください"; "wysiwyg_composer_format_action_un_indent" = "インデントを減らす"; "wysiwyg_composer_format_action_indent" = "インデントを増やす"; -"wysiwyg_composer_format_action_strikethrough" = "下線で装飾"; -"wysiwyg_composer_format_action_underline" = "打ち消し線で装飾"; +"wysiwyg_composer_format_action_underline" = "下線で装飾"; +"wysiwyg_composer_format_action_strikethrough" = "打ち消し線で装飾"; // MARK: - WYSIWYG Composer diff --git a/Riot/Assets/nl.lproj/Vector.strings b/Riot/Assets/nl.lproj/Vector.strings index a814c281b5..f0ddd9d106 100644 --- a/Riot/Assets/nl.lproj/Vector.strings +++ b/Riot/Assets/nl.lproj/Vector.strings @@ -2646,8 +2646,8 @@ "invite_to" = "Uitnodigen %@"; "room_event_encryption_info_key_authenticity_not_guaranteed" = "De authenticiteit van dit versleutelde bericht kan niet worden gegarandeerd op dit apparaat."; "deselect_all" = "Deselecteer alles"; -"wysiwyg_composer_format_action_strikethrough" = "Onderstrepen formaat toepassen"; -"wysiwyg_composer_format_action_underline" = "Doorstrepen formaat toepassen"; +"wysiwyg_composer_format_action_underline" = "Onderstrepen formaat toepassen"; +"wysiwyg_composer_format_action_strikethrough" = "Doorstrepen formaat toepassen"; "wysiwyg_composer_format_action_italic" = "Cursief formaat toepassen"; // Formatting Actions diff --git a/Riot/Assets/pl.lproj/Vector.strings b/Riot/Assets/pl.lproj/Vector.strings index 21be89f5de..ba5a2bc091 100644 --- a/Riot/Assets/pl.lproj/Vector.strings +++ b/Riot/Assets/pl.lproj/Vector.strings @@ -2694,8 +2694,8 @@ "wysiwyg_composer_format_action_unordered_list" = "Przełącz listę punktorów"; "wysiwyg_composer_format_action_inline_code" = "Zastosuj kod w tekście"; "wysiwyg_composer_format_action_link" = "Zastosuj link"; -"wysiwyg_composer_format_action_strikethrough" = "Zastosuj podkreślenie"; -"wysiwyg_composer_format_action_underline" = "Zastosuj przekreślenie"; +"wysiwyg_composer_format_action_underline" = "Zastosuj podkreślenie"; +"wysiwyg_composer_format_action_strikethrough" = "Zastosuj przekreślenie"; "wysiwyg_composer_format_action_italic" = "Zastosuj kursywę"; // Formatting Actions diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index d60ed99b62..991716cd9f 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -2556,8 +2556,8 @@ "authentication_qr_login_start_subtitle" = "Use a câmera neste dispositivo para scannar o QR code mostrado em seu outro dispositivo:"; "authentication_qr_login_start_title" = "Scannar QR code"; "authentication_login_with_qr" = "Fazer signin com QR code"; -"wysiwyg_composer_format_action_strikethrough" = "Aplicar formato sublinhar"; -"wysiwyg_composer_format_action_underline" = "Aplicar formato tachar"; +"wysiwyg_composer_format_action_underline" = "Aplicar formato sublinhar"; +"wysiwyg_composer_format_action_strikethrough" = "Aplicar formato tachar"; "wysiwyg_composer_format_action_italic" = "Aplicar formato itálico"; // Formatting Actions diff --git a/Riot/Assets/sk.lproj/Vector.strings b/Riot/Assets/sk.lproj/Vector.strings index 6f4eda6a4a..a18873e4d8 100644 --- a/Riot/Assets/sk.lproj/Vector.strings +++ b/Riot/Assets/sk.lproj/Vector.strings @@ -2778,8 +2778,8 @@ "authentication_qr_login_start_subtitle" = "Pomocou fotoaparátu na tomto zariadení naskenujte QR kód zobrazený na vašom druhom zariadení:"; "authentication_qr_login_start_title" = "Skenovať QR kód"; "authentication_login_with_qr" = "Prihlásiť sa pomocou QR kódu"; -"wysiwyg_composer_format_action_strikethrough" = "Použiť formát podčiarknutia"; -"wysiwyg_composer_format_action_underline" = "Použiť formát prečiarknutia"; +"wysiwyg_composer_format_action_underline" = "Použiť formát podčiarknutia"; +"wysiwyg_composer_format_action_strikethrough" = "Použiť formát prečiarknutia"; "wysiwyg_composer_format_action_italic" = "Použiť formát kurzívou"; // Formatting Actions diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings index 4b123786ec..cd338d626b 100644 --- a/Riot/Assets/sq.lproj/Vector.strings +++ b/Riot/Assets/sq.lproj/Vector.strings @@ -2420,8 +2420,8 @@ "all_chats_edit_layout_add_section_message" = "Fiksoni ndarje te kreu, për hyrje të lehtë në ta"; "room_event_encryption_info_key_authenticity_not_guaranteed" = "S’mund të garantohet mirëfilltësia e këtij mesazhi të fshehtëzuar në këtë pajisje."; "deselect_all" = "Shpërzgjidhi Krejt"; -"wysiwyg_composer_format_action_strikethrough" = "Apliko format me të nënvizuara"; -"wysiwyg_composer_format_action_underline" = "Apliko format me të hequravije"; +"wysiwyg_composer_format_action_underline" = "Apliko format me të nënvizuara"; +"wysiwyg_composer_format_action_strikethrough" = "Apliko format me të hequravije"; "wysiwyg_composer_format_action_italic" = "Apliko format me të pjerrëta"; // Formatting Actions diff --git a/Riot/Assets/sv.lproj/Vector.strings b/Riot/Assets/sv.lproj/Vector.strings index cb9918a3a4..85662f0292 100644 --- a/Riot/Assets/sv.lproj/Vector.strings +++ b/Riot/Assets/sv.lproj/Vector.strings @@ -2485,8 +2485,8 @@ "wysiwyg_composer_format_action_unordered_list" = "Växla punktlista"; "wysiwyg_composer_format_action_inline_code" = "Tillämpa inline-kodstil"; "wysiwyg_composer_format_action_link" = "Tillämpa länkformat"; -"wysiwyg_composer_format_action_strikethrough" = "Tillämpa understruken stil"; -"wysiwyg_composer_format_action_underline" = "Tillämpa genomstruken stil"; +"wysiwyg_composer_format_action_underline" = "Tillämpa understruken stil"; +"wysiwyg_composer_format_action_strikethrough" = "Tillämpa genomstruken stil"; "wysiwyg_composer_format_action_italic" = "Tillämpa kursiv stil"; // Formatting Actions diff --git a/Riot/Assets/uk.lproj/Vector.strings b/Riot/Assets/uk.lproj/Vector.strings index 04e9b75d54..7c18d9f8b7 100644 --- a/Riot/Assets/uk.lproj/Vector.strings +++ b/Riot/Assets/uk.lproj/Vector.strings @@ -2780,8 +2780,8 @@ "authentication_qr_login_start_subtitle" = "Використовуйте камеру на цьому пристрої, щоб зісканувати QR-код, показаний на іншому пристрої:"; "authentication_qr_login_start_title" = "Сканувати QR-код"; "authentication_login_with_qr" = "Увійти використавши QR-код"; -"wysiwyg_composer_format_action_strikethrough" = "Застосувати форматування підкресленим"; -"wysiwyg_composer_format_action_underline" = "Застосувати форматування перекресленим"; +"wysiwyg_composer_format_action_underline" = "Застосувати форматування підкресленим"; +"wysiwyg_composer_format_action_strikethrough" = "Застосувати форматування перекресленим"; // Formatting Actions "wysiwyg_composer_format_action_bold" = "Застосувати форматування жирним"; diff --git a/Riot/Assets/zh_Hant.lproj/Vector.strings b/Riot/Assets/zh_Hant.lproj/Vector.strings index f92adb766d..f7818a7907 100644 --- a/Riot/Assets/zh_Hant.lproj/Vector.strings +++ b/Riot/Assets/zh_Hant.lproj/Vector.strings @@ -2026,8 +2026,8 @@ // Links "wysiwyg_composer_link_action_text" = "文字"; "wysiwyg_composer_format_action_link" = "套用連結格式"; -"wysiwyg_composer_format_action_strikethrough" = "套用底線格式"; -"wysiwyg_composer_format_action_underline" = "套用刪除線格式"; +"wysiwyg_composer_format_action_underline" = "套用底線格式"; +"wysiwyg_composer_format_action_strikethrough" = "套用刪除線格式"; "wysiwyg_composer_format_action_italic" = "套用義式斜體格式"; // Formatting Actions From bb9b21d75de9e247a0c916d7392f395ac8d7bbea Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 7 Feb 2024 13:37:31 +0200 Subject: [PATCH 12/91] changelog.d: Upgrade MatrixSDK version ([v0.27.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.6)). --- Podfile | 2 +- changelog.d/x-nolink-0.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/x-nolink-0.change diff --git a/Podfile b/Podfile index 4905b302d7..f158719fd9 100644 --- a/Podfile +++ b/Podfile @@ -16,7 +16,7 @@ use_frameworks! # - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI # # Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixSDKVersion = '= 0.27.5' +$matrixSDKVersion = '= 0.27.6' # $matrixSDKVersion = :local # $matrixSDKVersion = { :branch => 'develop'} # $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } } diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change new file mode 100644 index 0000000000..611e8ba0da --- /dev/null +++ b/changelog.d/x-nolink-0.change @@ -0,0 +1 @@ +Upgrade MatrixSDK version ([v0.27.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.6)). \ No newline at end of file From 2e618b8e1eca8661a87bc5fe7bb499afe64dd408 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 7 Feb 2024 13:37:31 +0200 Subject: [PATCH 13/91] version++ --- CHANGES.md | 11 +++++++++++ changelog.d/pr-7743.bugfix | 1 - changelog.d/x-nolink-0.change | 1 - 3 files changed, 11 insertions(+), 2 deletions(-) delete mode 100644 changelog.d/pr-7743.bugfix delete mode 100644 changelog.d/x-nolink-0.change diff --git a/CHANGES.md b/CHANGES.md index b2a673e097..f6dc2d35a7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,14 @@ +## Changes in 1.11.7 (2024-02-07) + +🙌 Improvements + +- Upgrade MatrixSDK version ([v0.27.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.6)). + +🐛 Bugfixes + +- Fix swapped accessibility label between strikethrough and underline format buttons in RTE. ([#7743](https://github.com/element-hq/element-ios/pull/7743)) + + ## Changes in 1.11.6 (2024-01-09) 🙌 Improvements diff --git a/changelog.d/pr-7743.bugfix b/changelog.d/pr-7743.bugfix deleted file mode 100644 index 8d0a13e420..0000000000 --- a/changelog.d/pr-7743.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix swapped accessibility label between strikethrough and underline format buttons in RTE. \ No newline at end of file diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change deleted file mode 100644 index 611e8ba0da..0000000000 --- a/changelog.d/x-nolink-0.change +++ /dev/null @@ -1 +0,0 @@ -Upgrade MatrixSDK version ([v0.27.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.6)). \ No newline at end of file From 640261331833b62d7de264623848636c8f08a514 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 7 Feb 2024 14:27:48 +0200 Subject: [PATCH 14/91] finish version++ --- Podfile.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 68fc740a5e..f1159231eb 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,9 +39,9 @@ PODS: - LoggerAPI (1.9.200): - Logging (~> 1.1) - Logging (1.4.0) - - MatrixSDK (0.27.5): - - MatrixSDK/Core (= 0.27.5) - - MatrixSDK/Core (0.27.5): + - MatrixSDK (0.27.6): + - MatrixSDK/Core (= 0.27.6) + - MatrixSDK/Core (0.27.6): - AFNetworking (~> 4.0.0) - GZIP (~> 1.3.0) - libbase58 (~> 0.1.4) @@ -49,7 +49,7 @@ PODS: - OLMKit (~> 3.2.5) - Realm (= 10.27.0) - SwiftyBeaver (= 1.9.5) - - MatrixSDK/JingleCallStack (0.27.5): + - MatrixSDK/JingleCallStack (0.27.6): - JitsiMeetSDKLite (= 8.1.2-lite) - MatrixSDK/Core - MatrixSDKCrypto (0.3.13) @@ -102,8 +102,8 @@ DEPENDENCIES: - KeychainAccess (~> 4.2.2) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.27.5) - - MatrixSDK/JingleCallStack (= 0.27.5) + - MatrixSDK (= 0.27.6) + - MatrixSDK/JingleCallStack (= 0.27.6) - OLMKit - PostHog (~> 2.0.0) - ReadMoreTextView (~> 3.0.1) @@ -187,7 +187,7 @@ SPEC CHECKSUMS: libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d Logging: beeb016c9c80cf77042d62e83495816847ef108b - MatrixSDK: f92ffead50eda83c99786afefed9be739987f338 + MatrixSDK: 4129ab9c0acda1d0aad50b1c9765bd795b8d70b9 MatrixSDKCrypto: bf08b72f2cd015d8749420a2b8b92fc0536bedf4 OLMKit: da115f16582e47626616874e20f7bb92222c7a51 PostHog: 660ec6c9d80cec17b685e148f17f6785a88b597d @@ -208,6 +208,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: dd877be9e7d8dbc03dfcb3372d76e2eb0bdfbc34 +PODFILE CHECKSUM: 9245f34ec35d24a0993d1a16faa145cf3094a1b2 COCOAPODS: 1.14.3 From 2a6677cdd58fae9adf08225884dd31bc625c4d9e Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 7 Feb 2024 14:27:55 +0200 Subject: [PATCH 15/91] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index b0122b592b..b1d7c33ed5 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.7 -CURRENT_PROJECT_VERSION = 1.11.7 +MARKETING_VERSION = 1.11.8 +CURRENT_PROJECT_VERSION = 1.11.8 From 1dc609bce51eb96fdffae5f0d1e02abcf2b7fa44 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:19:33 +0000 Subject: [PATCH 16/91] Fix dictation when using the Rich Text Editor. (#7752) --- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- Riot/Generated/Strings.swift | 4 ++-- .../Modules/Room/Composer/View/Composer.swift | 18 ++++++++---------- changelog.d/7752.bugfix | 1 + project.yml | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 changelog.d/7752.bugfix diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index 47f1e5fe62..2f19e2ddc5 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-wysiwyg-composer-swift", "state" : { - "revision" : "0aa1308c43451fd077e332f72d6a32135f258834", - "version" : "2.19.0" + "revision" : "f788fe2482c0b89019f679a1f43dccf9c25a0782", + "version" : "2.29.0" } }, { diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index aa3ca9d725..f5cc6ae5be 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -9599,7 +9599,7 @@ public class VectorL10n: NSObject { public static var wysiwygComposerFormatActionQuote: String { return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_quote") } - /// Apply underline format + /// Apply strikethrough format public static var wysiwygComposerFormatActionStrikethrough: String { return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_strikethrough") } @@ -9607,7 +9607,7 @@ public class VectorL10n: NSObject { public static var wysiwygComposerFormatActionUnIndent: String { return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_un_indent") } - /// Apply strikethrough format + /// Apply underline format public static var wysiwygComposerFormatActionUnderline: String { return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_underline") } diff --git a/RiotSwiftUI/Modules/Room/Composer/View/Composer.swift b/RiotSwiftUI/Modules/Room/Composer/View/Composer.swift index f2a60ce066..5850980920 100644 --- a/RiotSwiftUI/Modules/Room/Composer/View/Composer.swift +++ b/RiotSwiftUI/Modules/Room/Composer/View/Composer.swift @@ -137,7 +137,7 @@ struct Composer: View { placeholder: viewModel.viewState.placeholder ?? "", viewModel: wysiwygViewModel, itemProviderHelper: nil, - keyCommandHandler: handleKeyCommand, + keyCommands: keyCommands, pasteHandler: nil ) .clipped() @@ -228,15 +228,13 @@ struct Composer: View { } } - func handleKeyCommand(_ keyCommand: WysiwygKeyCommand) -> Bool { - switch keyCommand { - case .enter: - sendMessageAction(wysiwygViewModel.content) - wysiwygViewModel.clearContent() - return true - case .shiftEnter: - return false - } + var keyCommands: [WysiwygKeyCommand] { + [ + .enter { + sendMessageAction(wysiwygViewModel.content) + wysiwygViewModel.clearContent() + } + ] } /// Computes the total height of the composer (excluding the RTE formatting bar). diff --git a/changelog.d/7752.bugfix b/changelog.d/7752.bugfix new file mode 100644 index 0000000000..d7660edc8d --- /dev/null +++ b/changelog.d/7752.bugfix @@ -0,0 +1 @@ +Fix dictation when using the Rich Text Editor \ No newline at end of file diff --git a/project.yml b/project.yml index 55f31044e6..3d410864a3 100644 --- a/project.yml +++ b/project.yml @@ -59,7 +59,7 @@ packages: branch: 0.0.1 WysiwygComposer: url: https://github.com/matrix-org/matrix-wysiwyg-composer-swift - version: 2.19.0 + version: 2.29.0 DeviceKit: url: https://github.com/devicekit/DeviceKit majorVersion: 4.7.0 From c8c6f55a8680994c3cf43bf916556f76daffbfae Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 21 Feb 2024 14:33:19 +0200 Subject: [PATCH 17/91] element-hq/element-meta/issues/2201 - Disable mark as unread - relates to element-hq/element-meta/issues/891 - relates to element-hq/element-ios/issues/7253 --- Riot/Modules/Common/Recents/Views/RecentTableViewCell.m | 8 +------- .../ContextMenu/ActionProviders/RoomActionProvider.swift | 2 +- .../ContextMenu/Services/RoomContextActionService.swift | 2 +- changelog.d/pr-7758.change | 1 + 4 files changed, 4 insertions(+), 9 deletions(-) create mode 100644 changelog.d/pr-7758.change diff --git a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m index afd3f5c880..9df1210109 100644 --- a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m +++ b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m @@ -93,13 +93,7 @@ - (void)render:(MXKCellData *)cellData self.lastEventDecriptionLabelTrailingConstraint.constant = self.unsentImageView.hidden ? 10 : 30; // Notify unreads and bing - if (roomCellData.isRoomMarkedAsUnread) - { - self.missedNotifAndUnreadBadgeBgView.hidden = NO; - self.missedNotifAndUnreadBadgeBgView.backgroundColor = ThemeService.shared.theme.tintColor; - self.missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 20; - } - else if (roomCellData.hasUnread) + if (roomCellData.hasUnread) { self.missedNotifAndUnreadIndicator.hidden = NO; if (0 < roomCellData.notificationCount) diff --git a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift index c019aae9c0..d9cde9dbe6 100644 --- a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift +++ b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift @@ -34,7 +34,7 @@ class RoomActionProvider: RoomActionProviderProtocol { var menu: UIMenu { if service.isRoomJoined { - var children = service.hasUnread ? [self.markAsReadAction] : [self.markAsUnreadAction] + var children = service.hasUnread ? [self.markAsReadAction] : [] children.append(contentsOf: [ self.directChatAction, self.notificationsAction, diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift index 12c02c9381..eb49328250 100644 --- a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift +++ b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift @@ -38,7 +38,7 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol { self.room = room self.delegate = delegate self.isRoomJoined = room.summary?.isJoined ?? false - self.hasUnread = (room.summary?.hasAnyUnread ?? false) || room.isMarkedAsUnread + self.hasUnread = room.summary?.hasAnyUnread ?? false self.roomMembership = room.summary?.membership ?? .unknown self.session = room.mxSession self.unownedRoomService = UnownedRoomContextActionService(roomId: room.roomId, canonicalAlias: room.summary?.aliases?.first, session: self.session, delegate: delegate) diff --git a/changelog.d/pr-7758.change b/changelog.d/pr-7758.change new file mode 100644 index 0000000000..28d7addb71 --- /dev/null +++ b/changelog.d/pr-7758.change @@ -0,0 +1 @@ +Disable the mark as unread feature to avoid it clashing with the new MSC2876 based one \ No newline at end of file From 24144d69e960363c235c6a0fc42792e9861d60db Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 27 Feb 2024 11:18:00 +0100 Subject: [PATCH 18/91] =?UTF-8?q?MAJ=20icone=20du=20bouton=20"Signaler=20u?= =?UTF-8?q?n=20probl=C3=A8me"=20pour=20un=20call=20VoIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Call/Direct/RoomDirectCallStatusCell.swift | 7 ++++++- changelog.d/974.change | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changelog.d/974.change diff --git a/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift b/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift index 84e3973e46..94c0b8855c 100644 --- a/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift +++ b/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift @@ -111,6 +111,11 @@ class RoomDirectCallStatusCell: RoomCallBaseCell { } } + // Tchap: report VoIP problem button icon 􀌭 + private var reportVoIPProblemButtonIcon: UIImage { + return UIImage(systemName: "exclamationmark.bubble.fill")! + } + private var actionUserInfo: [AnyHashable: Any]? { if let event = callInviteEvent { return [kMXKRoomBubbleCellEventKey: event] @@ -179,7 +184,7 @@ class RoomDirectCallStatusCell: RoomCallBaseCell { view.firstButton.style = .positive view.firstButton.setTitle(TchapL10n.eventFormatterReportIncident, for: .normal) - view.firstButton.setImage(callButtonIcon, for: .normal) + view.firstButton.setImage(reportVoIPProblemButtonIcon, for: .normal) view.firstButton.removeTarget(nil, action: nil, for: .touchUpInside) view.firstButton.addTarget(self, action: #selector(reportIncidentAction(_:)), for: .touchUpInside) diff --git a/changelog.d/974.change b/changelog.d/974.change new file mode 100644 index 0000000000..335b2cdcb4 --- /dev/null +++ b/changelog.d/974.change @@ -0,0 +1 @@ +Mettre une icône plus adaptée sur le bouton "Signaler un problème" lors d'un appel VoIP \ No newline at end of file From c422eea0b50ba97d197086e254403d53778c405b Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 27 Feb 2024 15:40:59 +0100 Subject: [PATCH 19/91] =?UTF-8?q?Changer=20le=20message=20d'erreur=20en=20?= =?UTF-8?q?cas=20de=20probl=C3=A8me=20de=20d=C3=A9chiffrement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/fr.lproj/Vector.strings | 3 +-- Riot/Utils/EventFormatter.m | 9 ++++++++- Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 2 +- changelog.d/976.change | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 changelog.d/976.change diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index e48f772de3..ed7b5359ef 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -1807,7 +1807,7 @@ "notice_room_history_visible_to_members_from_invited_point" = "%@ a rendu l’historique futur du salon visible à tous les membres, à partir du moment où ils ont été invités."; "notice_room_history_visible_to_members_from_joined_point" = "%@ a rendu l’historique futur du salon visible à tous les membres, à partir de leur arrivée."; "notice_crypto_unable_to_decrypt" = "** Déchiffrement impossible : %@ **"; -"notice_crypto_error_unknown_inbound_session_id" = "La session de l’expéditeur ne nous a pas envoyé les clés pour ce message."; +"notice_crypto_error_unknown_inbound_session_id" = "Déchiffrement en cours. Patientez…"; // Tchap "notice_sticker" = "autocollant"; // room display name "room_displayname_empty_room" = "Salon vide"; @@ -2797,4 +2797,3 @@ "local_contacts_access_discovery_warning" = "Afin d’afficher qui parmi vos contacts utilise déjà Tchap, nous pouvons exploiter les adresses e-mails de votre carnet d'adresse. Ces données ne seront pas mémorisées. Pour plus d'informations, veuillez consulter les Termes et Conditions disponibles dans les paramètres de l'application."; // Events formatter "notice_crypto_unable_to_decrypt" = "Message verrouillé."; // Tchap -"notice_crypto_error_unknown_inbound_session_id" = "Ouvrez Tchap sur un autre appareil pour récupérer vos messages."; // Tchap diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index 27b6a99065..6db1716ba2 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -370,8 +370,10 @@ - (NSAttributedString *)unsafeAttributedStringFromEvent:(MXEvent *)event // }]]; NSMutableAttributedString *attributedStringWithRerequestMessage = [attributedString mutableCopy]; + // Tchap: Reset initial String to optimize error message for user + [attributedStringWithRerequestMessage.mutableString setString: [NSString stringWithFormat:@"%@\n", VectorL10n.noticeCryptoErrorUnknownInboundSessionId]]; - [attributedStringWithRerequestMessage appendString:[NSString stringWithFormat:@" %@\n", VectorL10n.noticeCryptoErrorUnknownInboundSessionId]]; +// [attributedStringWithRerequestMessage appendString:[NSString stringWithFormat:@" %@\n", VectorL10n.noticeCryptoErrorUnknownInboundSessionId]]; NSString *linkActionString = [NSString stringWithFormat:@"%@%@%@", EventFormatterFaqLinkAction, EventFormatterLinkActionSeparator, @"https://aide.tchap.beta.gouv.fr/fr/article/dechiffrement-impossible-de-mes-messages-comment-y-remedier-iphone-xotgv1"]; @@ -385,6 +387,11 @@ - (NSAttributedString *)unsafeAttributedStringFromEvent:(MXEvent *)event NSUnderlineStyleAttributeName: [NSNumber numberWithInt:NSUnderlineStyleSingle] }]]; + [attributedStringWithRerequestMessage addAttributes:@{ + NSForegroundColorAttributeName: [UIColor colorWithRed:106.0/255.0 green:106.0/255.0 blue:106.0/255.0 alpha:1.0], + NSFontAttributeName: self.encryptedMessagesTextFont, + } range:NSMakeRange(0, attributedStringWithRerequestMessage.length)]; + attributedString = attributedStringWithRerequestMessage; } } diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index d4b803f5fb..0c048fd7e5 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -316,7 +316,7 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Room Decryption error -"room_decryption_error_faq_link_message" = "Sinon, consulter cet article de FAQ."; +"room_decryption_error_faq_link_message" = "En savoir plus."; //////////////////////////////////////////////////////////////////////////////// // MARK: Room Invite diff --git a/changelog.d/976.change b/changelog.d/976.change new file mode 100644 index 0000000000..4096bfa5f9 --- /dev/null +++ b/changelog.d/976.change @@ -0,0 +1 @@ +Changer le message d'erreur affiché en cas de problème de déchiffrement \ No newline at end of file From fba61750115a078e571996b8bf2729aeb72662db Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 27 Feb 2024 17:11:42 +0100 Subject: [PATCH 20/91] =?UTF-8?q?R=C3=A9activation=20des=20parties=20de=20?= =?UTF-8?q?code=20Live=20Location=20Sharing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/RoomCoordinator.swift | 324 ++++++++++++------------ Riot/Modules/Room/RoomViewController.h | 22 +- Riot/Modules/Room/RoomViewController.m | 8 +- Tchap/target.yml | 14 +- 4 files changed, 184 insertions(+), 184 deletions(-) diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index c94cdfb178..a988fef4fe 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -315,166 +315,166 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { } // Tchap: Disable Live location sharing -// private func showLiveLocationViewer() { -// guard let roomId = self.roomId else { -// return -// } -// -// self.showLiveLocationViewer(for: roomId) -// } -// -// private func showLiveLocationViewer(for roomId: String) { -// -// guard let mxSession = self.mxSession, let navigationRouter = self.navigationRouter else { -// return -// } -// -// guard mxSession.locationService.isSomeoneSharingDisplayableLocation(inRoomWithId: roomId) else { -// return -// } -// -// let parameters = LiveLocationSharingViewerCoordinatorParameters(session: mxSession, roomId: roomId, navigationRouter: nil) -// -// let coordinator = LiveLocationSharingViewerCoordinator(parameters: parameters) -// -// coordinator.completion = { [weak self, weak coordinator] in -// guard let self = self, let coordinator = coordinator else { -// return -// } -// -// self.navigationRouter?.dismissModule(animated: true, completion: nil) -// self.remove(childCoordinator: coordinator) -// } -// -// add(childCoordinator: coordinator) -// -// navigationRouter.present(coordinator, animated: true) -// coordinator.start() -// } -// -// private func stopLiveLocationSharing(forBeaconInfoEventId beaconInfoEventId: String? = nil, inRoomWithId roomId: String) { -// guard let session = self.mxSession else { -// return -// } -// -// let errorHandler: (Error) -> Void = { error in -// -// let viewController = self.roomViewController -// -// viewController.errorPresenter.presentError(from: viewController, title: VectorL10n.error, message: VectorL10n.locationSharingLiveStopSharingError, animated: true) { -// } -// } -// -// // TODO: Handle loading state on the banner by replacing stop button with a spinner -// self.showLocationSharingIndicator(withMessage: VectorL10n.locationSharingLiveStopSharingProgress) -// -// if let beaconInfoEventId = beaconInfoEventId { -// session.locationService.stopUserLocationSharing(withBeaconInfoEventId: beaconInfoEventId, roomId: roomId) { -// [weak self] response in -// -// self?.hideLocationSharingIndicator() -// -// switch response { -// case .success: -// break -// case .failure(let error): -// errorHandler(error) -// } -// } -// } else { -// session.locationService.stopUserLocationSharing(inRoomWithId: roomId) { [weak self] response in -// -// self?.hideLocationSharingIndicator() -// -// switch response { -// case .success: -// break -// case .failure(let error): -// errorHandler(error) -// } -// } -// } -// } -// -// private func showLocationCoordinatorWithEvent(_ event: MXEvent, bubbleData: MXKRoomBubbleCellDataStoring) { -// guard let mxSession = self.mxSession, -// let navigationRouter = self.navigationRouter, -// let mediaManager = mxSession.mediaManager, -// let locationContent = event.location else { -// MXLog.error("[RoomCoordinator] Invalid location showing coordinator parameters. Returning.") -// return -// } -// -// let avatarData = AvatarInput(mxContentUri: bubbleData.senderAvatarUrl, -// matrixItemId: bubbleData.senderId, -// displayName: bubbleData.senderDisplayName) -// -// -// let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude) -// let coordinateType = locationContent.assetType -// -// guard let locationSharingCoordinatetype = coordinateType.locationSharingCoordinateType() else { -// fatalError("[LocationSharingCoordinator] event asset type is not supported: \(coordinateType)") -// } -// -// let parameters = StaticLocationViewingCoordinatorParameters( -// session: mxSession, -// mediaManager: mediaManager, -// avatarData: avatarData, -// location: location, -// coordinateType: locationSharingCoordinatetype) -// -// let coordinator = StaticLocationViewingCoordinator(parameters: parameters) -// -// coordinator.completion = { [weak self, weak coordinator] in -// guard let self = self, let coordinator = coordinator else { -// return -// } -// -// self.navigationRouter?.dismissModule(animated: true, completion: nil) -// self.remove(childCoordinator: coordinator) -// } -// -// add(childCoordinator: coordinator) -// -// navigationRouter.present(coordinator, animated: true) -// coordinator.start() -// } -// -// private func startLocationCoordinator() { -// guard let mxSession = mxSession, -// let navigationRouter = self.navigationRouter, -// let mediaManager = mxSession.mediaManager, -// let user = mxSession.myUser else { -// MXLog.error("[RoomCoordinator] Invalid location sharing coordinator parameters. Returning.") -// return -// } -// -// let avatarData = AvatarInput(mxContentUri: user.avatarUrl, -// matrixItemId: user.userId, -// displayName: user.displayname) -// -// let parameters = LocationSharingCoordinatorParameters(session: mxSession, -// roomDataSource: roomViewController.roomDataSource, -// mediaManager: mediaManager, -// avatarData: avatarData) -// -// let coordinator = LocationSharingCoordinator(parameters: parameters) -// -// coordinator.completion = { [weak self, weak coordinator] in -// guard let self = self, let coordinator = coordinator else { -// return -// } -// -// self.navigationRouter?.dismissModule(animated: true, completion: nil) -// self.remove(childCoordinator: coordinator) -// } -// -// add(childCoordinator: coordinator) -// -// navigationRouter.present(coordinator, animated: true) -// coordinator.start() -// } + private func showLiveLocationViewer() { + guard let roomId = self.roomId else { + return + } + + self.showLiveLocationViewer(for: roomId) + } + + private func showLiveLocationViewer(for roomId: String) { + + guard let mxSession = self.mxSession, let navigationRouter = self.navigationRouter else { + return + } + + guard mxSession.locationService.isSomeoneSharingDisplayableLocation(inRoomWithId: roomId) else { + return + } + + let parameters = LiveLocationSharingViewerCoordinatorParameters(session: mxSession, roomId: roomId, navigationRouter: nil) + + let coordinator = LiveLocationSharingViewerCoordinator(parameters: parameters) + + coordinator.completion = { [weak self, weak coordinator] in + guard let self = self, let coordinator = coordinator else { + return + } + + self.navigationRouter?.dismissModule(animated: true, completion: nil) + self.remove(childCoordinator: coordinator) + } + + add(childCoordinator: coordinator) + + navigationRouter.present(coordinator, animated: true) + coordinator.start() + } + + private func stopLiveLocationSharing(forBeaconInfoEventId beaconInfoEventId: String? = nil, inRoomWithId roomId: String) { + guard let session = self.mxSession else { + return + } + + let errorHandler: (Error) -> Void = { error in + + let viewController = self.roomViewController + + viewController.errorPresenter.presentError(from: viewController, title: VectorL10n.error, message: VectorL10n.locationSharingLiveStopSharingError, animated: true) { + } + } + + // TODO: Handle loading state on the banner by replacing stop button with a spinner + self.showLocationSharingIndicator(withMessage: VectorL10n.locationSharingLiveStopSharingProgress) + + if let beaconInfoEventId = beaconInfoEventId { + session.locationService.stopUserLocationSharing(withBeaconInfoEventId: beaconInfoEventId, roomId: roomId) { + [weak self] response in + + self?.hideLocationSharingIndicator() + + switch response { + case .success: + break + case .failure(let error): + errorHandler(error) + } + } + } else { + session.locationService.stopUserLocationSharing(inRoomWithId: roomId) { [weak self] response in + + self?.hideLocationSharingIndicator() + + switch response { + case .success: + break + case .failure(let error): + errorHandler(error) + } + } + } + } + + private func showLocationCoordinatorWithEvent(_ event: MXEvent, bubbleData: MXKRoomBubbleCellDataStoring) { + guard let mxSession = self.mxSession, + let navigationRouter = self.navigationRouter, + let mediaManager = mxSession.mediaManager, + let locationContent = event.location else { + MXLog.error("[RoomCoordinator] Invalid location showing coordinator parameters. Returning.") + return + } + + let avatarData = AvatarInput(mxContentUri: bubbleData.senderAvatarUrl, + matrixItemId: bubbleData.senderId, + displayName: bubbleData.senderDisplayName) + + + let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude) + let coordinateType = locationContent.assetType + + guard let locationSharingCoordinatetype = coordinateType.locationSharingCoordinateType() else { + fatalError("[LocationSharingCoordinator] event asset type is not supported: \(coordinateType)") + } + + let parameters = StaticLocationViewingCoordinatorParameters( + session: mxSession, + mediaManager: mediaManager, + avatarData: avatarData, + location: location, + coordinateType: locationSharingCoordinatetype) + + let coordinator = StaticLocationViewingCoordinator(parameters: parameters) + + coordinator.completion = { [weak self, weak coordinator] in + guard let self = self, let coordinator = coordinator else { + return + } + + self.navigationRouter?.dismissModule(animated: true, completion: nil) + self.remove(childCoordinator: coordinator) + } + + add(childCoordinator: coordinator) + + navigationRouter.present(coordinator, animated: true) + coordinator.start() + } + + private func startLocationCoordinator() { + guard let mxSession = mxSession, + let navigationRouter = self.navigationRouter, + let mediaManager = mxSession.mediaManager, + let user = mxSession.myUser else { + MXLog.error("[RoomCoordinator] Invalid location sharing coordinator parameters. Returning.") + return + } + + let avatarData = AvatarInput(mxContentUri: user.avatarUrl, + matrixItemId: user.userId, + displayName: user.displayname) + + let parameters = LocationSharingCoordinatorParameters(session: mxSession, + roomDataSource: roomViewController.roomDataSource, + mediaManager: mediaManager, + avatarData: avatarData) + + let coordinator = LocationSharingCoordinator(parameters: parameters) + + coordinator.completion = { [weak self, weak coordinator] in + guard let self = self, let coordinator = coordinator else { + return + } + + self.navigationRouter?.dismissModule(animated: true, completion: nil) + self.remove(childCoordinator: coordinator) + } + + add(childCoordinator: coordinator) + + navigationRouter.present(coordinator, animated: true) + coordinator.start() + } private func startEditPollCoordinator(startEvent: MXEvent? = nil) { let parameters = PollEditFormCoordinatorParameters(room: roomViewController.roomDataSource.room, pollStartEvent: startEvent) @@ -635,7 +635,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { } // Tchap: Disable Live location sharing -// showLiveLocationViewer(for: roomId) + showLiveLocationViewer(for: roomId) } func roomViewController(_ roomViewController: RoomViewController, locationShareActivityViewControllerFor event: MXEvent) -> UIActivityViewController? { @@ -682,7 +682,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { return } -// self.stopLiveLocationSharing(forBeaconInfoEventId: beaconInfoEventId, inRoomWithId: roomId) + self.stopLiveLocationSharing(forBeaconInfoEventId: beaconInfoEventId, inRoomWithId: roomId) } func threadsCoordinator(for roomViewController: RoomViewController, threadId: String?) -> ThreadsCoordinatorBridgePresenter? { diff --git a/Riot/Modules/Room/RoomViewController.h b/Riot/Modules/Room/RoomViewController.h index 9029e33e72..a05b3a0156 100644 --- a/Riot/Modules/Room/RoomViewController.h +++ b/Riot/Modules/Room/RoomViewController.h @@ -32,9 +32,9 @@ @protocol RoomViewControllerDelegate; @class RoomDisplayConfiguration; // Tchap: Disable Threads -// Tchap: Disable Live location sharing //@class ThreadsCoordinatorBridgePresenter; -//@class LiveLocationSharingBannerView; +// Tchap: Disable Live location sharing +@class LiveLocationSharingBannerView; @class VoiceBroadcastService; @class ComposerLinkActionBridgePresenter; @@ -108,11 +108,11 @@ extern NSTimeInterval const kResizeComposerAnimationDuration; @property (weak, nonatomic, nullable) IBOutlet UIStackView *topBannersStackView; // Tchap: Disable Live location sharing -// /// Indicate YES to show live location sharing banner -//@property (nonatomic, readonly) BOOL shouldShowLiveLocationSharingBannerView; -// -// /// Displayed live location sharing banner if any -//@property (nonatomic, weak) LiveLocationSharingBannerView *liveLocationSharingBannerView; + /// Indicate YES to show live location sharing banner +@property (nonatomic, readonly) BOOL shouldShowLiveLocationSharingBannerView; + + /// Displayed live location sharing banner if any +@property (nonatomic, weak) LiveLocationSharingBannerView *liveLocationSharingBannerView; // The customized room data source for Vector @property (nonatomic, nullable) RoomDataSource *customizedRoomDataSource; @@ -312,9 +312,9 @@ didRequestLocationPresentationForEvent:(MXEvent *)event bubbleData:(id)bubbleData; // Tchap: Disable Live location sharing -/// Ask the coordinator to present the live location sharing viewer. -//- (void)roomViewController:(RoomViewController *)roomViewController -//didRequestLiveLocationPresentationForBubbleData:(id)bubbleData; +// Ask the coordinator to present the live location sharing viewer. +- (void)roomViewController:(RoomViewController *)roomViewController +didRequestLiveLocationPresentationForBubbleData:(id)bubbleData; - (nullable UIActivityViewController *)roomViewController:(RoomViewController *)roomViewController locationShareActivityViewControllerForEvent:(MXEvent *)event; @@ -349,7 +349,7 @@ didRequestEditForPollWithStartEvent:(MXEvent *)startEvent; // Tchap: Disable Live location sharing /// User tap live location sharing stop action -//- (void)roomViewControllerDidStopLiveLocationSharing:(RoomViewController *)roomViewController beaconInfoEventId:(nullable NSString*)beaconInfoEventId; +- (void)roomViewControllerDidStopLiveLocationSharing:(RoomViewController *)roomViewController beaconInfoEventId:(nullable NSString*)beaconInfoEventId; /// User tap live location sharing banner - (void)roomViewControllerDidTapLiveLocationSharingBanner:(RoomViewController *)roomViewController; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index b0024715e8..28b0670170 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -1657,10 +1657,10 @@ - (void)setMissedDiscussionsBadgeHidden:(BOOL)missedDiscussionsBadgeHidden{ } // Tchap: Disable Live location sharing -//- (BOOL)shouldShowLiveLocationSharingBannerView -//{ -// return self.customizedRoomDataSource.isCurrentUserSharingActiveLocation; -//} +- (BOOL)shouldShowLiveLocationSharingBannerView +{ + return self.customizedRoomDataSource.isCurrentUserSharingActiveLocation; +} - (void)setForceHideInputToolBar:(BOOL)forceHideInputToolBar { diff --git a/Tchap/target.yml b/Tchap/target.yml index b94a4cfd3c..ca217337ce 100644 --- a/Tchap/target.yml +++ b/Tchap/target.yml @@ -257,13 +257,13 @@ targetTemplates: - path: ../Riot/Modules/Rendezvous - path: ../Riot/Modules/Room excludes: - - "Location" - - "RoomViewController+LocationSharing.swift" - - "TimelineCells/LocationView" - - "TimelineCells/Styles/Plain/Cells/Location" - - "TimelineCells/Styles/Bubble/Cells/Location" - - "Views/BubbleCells/KeyVerification/SizingViewHeight.swift" - - "Views/BubbleCells/Location" +# - "Location" +# - "RoomViewController+LocationSharing.swift" +# - "TimelineCells/LocationView" +# - "TimelineCells/Styles/Plain/Cells/Location" +# - "TimelineCells/Styles/Bubble/Cells/Location" +# - "Views/BubbleCells/KeyVerification/SizingViewHeight.swift" +# - "Views/BubbleCells/Location" - path: ../Riot/Modules/Rooms - path: ../Riot/Modules/Secrets - path: ../Riot/Modules/SecureBackup From fb3571b0e8b5bd97504f011aa446f7474b537da3 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 28 Feb 2024 16:13:32 +0100 Subject: [PATCH 21/91] =?UTF-8?q?Int=C3=A9gration=20des=20fichiers=20Eleme?= =?UTF-8?q?nt=20n=C3=A9cessaires=20=C3=A0=20la=20compilation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeserverConfiguration.swift | 8 +++---- .../HomeserverConfigurationBuilder.swift | 22 +++++++++---------- Riot/Modules/Room/RoomCoordinator.swift | 2 +- RiotSwiftUI/target.yml | 2 +- .../RoomPreview/RoomPreviewCoordinator.swift | 9 ++++++++ Tchap/target.yml | 4 +++- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Riot/Model/HomeserverConfiguration/HomeserverConfiguration.swift b/Riot/Model/HomeserverConfiguration/HomeserverConfiguration.swift index a3bee4c8f3..994e4fb2c6 100644 --- a/Riot/Model/HomeserverConfiguration/HomeserverConfiguration.swift +++ b/Riot/Model/HomeserverConfiguration/HomeserverConfiguration.swift @@ -23,13 +23,13 @@ final class HomeserverConfiguration: NSObject { // Note: Use an object per configuration subject when there is multiple properties related let jitsi: HomeserverJitsiConfiguration let encryption: HomeserverEncryptionConfiguration -// let tileServer: HomeserverTileServerConfiguration + let tileServer: HomeserverTileServerConfiguration init(jitsi: HomeserverJitsiConfiguration, - encryption: HomeserverEncryptionConfiguration/*, - tileServer: HomeserverTileServerConfiguration*/) { + encryption: HomeserverEncryptionConfiguration, + tileServer: HomeserverTileServerConfiguration) { self.jitsi = jitsi self.encryption = encryption -// self.tileServer = tileServer + self.tileServer = tileServer } } diff --git a/Riot/Model/HomeserverConfiguration/HomeserverConfigurationBuilder.swift b/Riot/Model/HomeserverConfiguration/HomeserverConfigurationBuilder.swift index 494b50d0a0..bc6182faac 100644 --- a/Riot/Model/HomeserverConfiguration/HomeserverConfigurationBuilder.swift +++ b/Riot/Model/HomeserverConfiguration/HomeserverConfigurationBuilder.swift @@ -78,15 +78,15 @@ final class HomeserverConfigurationBuilder: NSObject { // Tile server configuration -// let tileServerMapStyleURL: URL -// if let mapStyleURLString = wellKnown?.tileServer?.mapStyleURLString, -// let mapStyleURL = URL(string: mapStyleURLString) { -// tileServerMapStyleURL = mapStyleURL -// } else { -// tileServerMapStyleURL = BuildSettings.defaultTileServerMapStyleURL -// } -// -// let tileServerConfiguration = HomeserverTileServerConfiguration(mapStyleURL: tileServerMapStyleURL) + let tileServerMapStyleURL: URL + if let mapStyleURLString = wellKnown?.tileServer?.mapStyleURLString, + let mapStyleURL = URL(string: mapStyleURLString) { + tileServerMapStyleURL = mapStyleURL + } else { + tileServerMapStyleURL = BuildSettings.defaultTileServerMapStyleURL + } + + let tileServerConfiguration = HomeserverTileServerConfiguration(mapStyleURL: tileServerMapStyleURL) // Create HomeserverConfiguration @@ -95,8 +95,8 @@ final class HomeserverConfigurationBuilder: NSObject { useFor1To1Calls: useJitsiFor1To1Calls) return HomeserverConfiguration(jitsi: jitsiConfiguration, - encryption: encryptionConfiguration/*, - tileServer: tileServerConfiguration*/) + encryption: encryptionConfiguration, + tileServer: tileServerConfiguration) } // MARK: - Private diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index a988fef4fe..cd09ddaa08 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -579,7 +579,7 @@ extension RoomCoordinator: UIAdaptivePresentationControllerDelegate { // MARK: - RoomViewControllerDelegate extension RoomCoordinator: RoomViewControllerDelegate { - + func roomViewController(_ roomViewController: RoomViewController, showRoomWithId roomID: String, eventId eventID: String?) { self.delegate?.roomCoordinator(self, didSelectRoomWithId: roomID, eventId: eventID) } diff --git a/RiotSwiftUI/target.yml b/RiotSwiftUI/target.yml index d7f17f313f..ca8d623c7d 100644 --- a/RiotSwiftUI/target.yml +++ b/RiotSwiftUI/target.yml @@ -65,7 +65,7 @@ targets: - path: ../Riot/Categories/Codable.swift - path: ../Riot/Assets/en.lproj/Vector.strings - path: ../Riot/Modules/Analytics/AnalyticsScreen.swift - - path: ../Riot/Modules/LocationSharing/LocationAuthorizationStatus.swift + - path: ../Riot/Modules/LocationSharing/ - path: ../Riot/Modules/QRCode/QRCodeGenerator.swift - path: ../Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/MatrixSDK/VoiceBroadcastInfoState.swift - path: ../Riot/Assets/en.lproj/Untranslated.strings diff --git a/Tchap/Modules/RoomPreview/RoomPreviewCoordinator.swift b/Tchap/Modules/RoomPreview/RoomPreviewCoordinator.swift index c0103af40e..5c345ebed2 100644 --- a/Tchap/Modules/RoomPreview/RoomPreviewCoordinator.swift +++ b/Tchap/Modules/RoomPreview/RoomPreviewCoordinator.swift @@ -220,6 +220,15 @@ final class RoomPreviewCoordinator: NSObject, RoomPreviewCoordinatorType { // MARK: - RoomViewControllerDelegate extension RoomPreviewCoordinator: RoomViewControllerDelegate { + + func roomViewController(_ roomViewController: RoomViewController, didRequestLiveLocationPresentationForBubbleData bubbleData: MXKRoomBubbleCellDataStoring) { + // + } + + func roomViewControllerDidStopLiveLocationSharing(_ roomViewController: RoomViewController, beaconInfoEventId: String?) { + // + } + func roomViewController(_ roomViewController: RoomViewController, showRoomWithId roomID: String, eventId eventID: String?) { // } diff --git a/Tchap/target.yml b/Tchap/target.yml index ca217337ce..9f497793c1 100644 --- a/Tchap/target.yml +++ b/Tchap/target.yml @@ -53,6 +53,7 @@ targetTemplates: - package: SwiftOGG - package: WysiwygComposer - package: AnalyticsEvents + - package: Mapbox preBuildScripts: - name: 🛠 Environment @@ -245,6 +246,7 @@ targetTemplates: - path: ../Riot/Modules/KeyBackup - path: ../Riot/Modules/KeyVerification - path: ../Riot/Modules/LaunchLoading + - path: ../Riot/Modules/LocationSharing - path: ../Riot/Modules/MatrixKit - path: ../Riot/Modules/MediaPicker - path: ../Riot/Modules/MediaPickerV2 @@ -294,7 +296,7 @@ targetTemplates: excludes: - "**/Test/**" - "Common/Locale/LocaleProvider.swift" - - "LocationSharing" +# - "LocationSharing" - "Room/LiveLocationSharingViewer" - "Room/LocationSharing" - "Room/StaticLocationSharingViewer" From 1c244636dfe38329f03e153d4b41acee3d6fff6a Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 4 Mar 2024 14:50:52 +0100 Subject: [PATCH 22/91] Simplification du message d'attente --- Riot/Assets/en.lproj/Vector.strings | 2 +- Riot/Assets/fr.lproj/Vector.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 0cb9b07a5b..9f527b8209 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2773,7 +2773,7 @@ To enable access, tap Settings> Location and select Always"; "notice_room_history_visible_to_members_from_joined_point" = "%@ made future room history visible to all room members, from the point they joined."; "notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ made future messages visible to everyone, from when they joined."; "notice_crypto_unable_to_decrypt" = "** Unable to decrypt: %@ **"; -"notice_crypto_error_unknown_inbound_session_id" = "The sender's session has not sent us the keys for this message."; +"notice_crypto_error_unknown_inbound_session_id" = "Deciphering…"; // Tchap "notice_sticker" = "sticker"; "notice_in_reply_to" = "In reply to"; "notice_voice_broadcast_live" = "Live broadcast"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index ed7b5359ef..e51ab378af 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -1807,7 +1807,7 @@ "notice_room_history_visible_to_members_from_invited_point" = "%@ a rendu l’historique futur du salon visible à tous les membres, à partir du moment où ils ont été invités."; "notice_room_history_visible_to_members_from_joined_point" = "%@ a rendu l’historique futur du salon visible à tous les membres, à partir de leur arrivée."; "notice_crypto_unable_to_decrypt" = "** Déchiffrement impossible : %@ **"; -"notice_crypto_error_unknown_inbound_session_id" = "Déchiffrement en cours. Patientez…"; // Tchap +"notice_crypto_error_unknown_inbound_session_id" = "Déchiffrement en cours…"; // Tchap "notice_sticker" = "autocollant"; // room display name "room_displayname_empty_room" = "Salon vide"; From adada0e86032032f86596282fd4baffbfde8ca68 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:17:27 +0000 Subject: [PATCH 23/91] Fix a bug where QR codes aren't detected if the camera is too close. (#7762) --- Podfile | 2 +- Podfile.lock | 12 ++--- .../QRCode/Reader/QRCodeReaderView.swift | 51 +------------------ changelog.d/pr-7762.bugfix | 1 + 4 files changed, 10 insertions(+), 56 deletions(-) create mode 100644 changelog.d/pr-7762.bugfix diff --git a/Podfile b/Podfile index f158719fd9..9ad4fefa28 100644 --- a/Podfile +++ b/Podfile @@ -59,7 +59,7 @@ end def import_SwiftUI_pods pod 'Introspect', '~> 0.1' pod 'DSBottomSheet', '~> 0.3' - pod 'ZXingObjC', '~> 3.6.5' + pod 'ZXingObjC', '~> 3.6.9' end abstract_target 'RiotPods' do diff --git a/Podfile.lock b/Podfile.lock index f1159231eb..abe637e538 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -87,9 +87,9 @@ PODS: - UICollectionViewRightAlignedLayout (0.0.3) - WeakDictionary (2.0.2) - zxcvbn-ios (1.0.4) - - ZXingObjC (3.6.5): - - ZXingObjC/All (= 3.6.5) - - ZXingObjC/All (3.6.5) + - ZXingObjC (3.6.9): + - ZXingObjC/All (= 3.6.9) + - ZXingObjC/All (3.6.9) DEPENDENCIES: - Down (~> 0.11.0) @@ -119,7 +119,7 @@ DEPENDENCIES: - UICollectionViewRightAlignedLayout (~> 0.0.3) - WeakDictionary (~> 2.0) - zxcvbn-ios - - ZXingObjC (~> 3.6.5) + - ZXingObjC (~> 3.6.9) SPEC REPOS: trunk: @@ -206,8 +206,8 @@ SPEC CHECKSUMS: UICollectionViewRightAlignedLayout: 823eef8c567eba4a44c21bc2ffcb0d0d5f361e2d WeakDictionary: 8cd038acd77e5d54ca4ebaec3d20853d732b45e0 zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c - ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb + ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 9245f34ec35d24a0993d1a16faa145cf3094a1b2 +PODFILE CHECKSUM: c87b532985dd755b373732f841e3bcfe616f4e4f COCOAPODS: 1.14.3 diff --git a/Riot/Modules/QRCode/Reader/QRCodeReaderView.swift b/Riot/Modules/QRCode/Reader/QRCodeReaderView.swift index 21f1b8497c..302cd63104 100644 --- a/Riot/Modules/QRCode/Reader/QRCodeReaderView.swift +++ b/Riot/Modules/QRCode/Reader/QRCodeReaderView.swift @@ -113,7 +113,6 @@ final class QRCodeReaderView: UIView { } private func applyOrientation() { - let orientation = UIApplication.shared.statusBarOrientation let captureRotation: Double let scanRectRotation: Double @@ -136,59 +135,13 @@ final class QRCodeReaderView: UIView { scanRectRotation = 90 } - applyRectOfInterest(orientation: orientation) - let angleRadius = captureRotation / 180.0 * Double.pi - let captureTranform = CGAffineTransform(rotationAngle: CGFloat(angleRadius)) + let captureTransform = CGAffineTransform(rotationAngle: CGFloat(angleRadius)) - zxCapture.transform = captureTranform + zxCapture.transform = captureTransform zxCapture.rotation = CGFloat(scanRectRotation) zxCapture.layer.frame = self.bounds } - - private func applyRectOfInterest(orientation: UIInterfaceOrientation) { - var transformedVideoRect = self.frame - let cameraSessionPreset = zxCapture.sessionPreset - - var scaleVideoX, scaleVideoY: CGFloat - var videoHeight, videoWidth: CGFloat - - // Currently support only for 1920x1080 || 1280x720 - if cameraSessionPreset == AVCaptureSession.Preset.hd1920x1080.rawValue { - videoHeight = 1080.0 - videoWidth = 1920.0 - } else { - videoHeight = 720.0 - videoWidth = 1280.0 - } - - if orientation == UIInterfaceOrientation.portrait { - scaleVideoX = self.frame.width / videoHeight - scaleVideoY = self.frame.height / videoWidth - - // Convert CGPoint under portrait mode to map with orientation of image - // because the image will be cropped before rotate - // reference: https://github.com/TheLevelUp/ZXingObjC/issues/222 - let realX = transformedVideoRect.origin.y - let realY = self.frame.size.width - transformedVideoRect.size.width - transformedVideoRect.origin.x - let realWidth = transformedVideoRect.size.height - let realHeight = transformedVideoRect.size.width - transformedVideoRect = CGRect(x: realX, y: realY, width: realWidth, height: realHeight) - - } else { - scaleVideoX = self.frame.width / videoWidth - scaleVideoY = self.frame.height / videoHeight - } - - captureSizeTransform = CGAffineTransform(scaleX: 1.0/scaleVideoX, y: 1.0/scaleVideoY) - - guard let _captureSizeTransform = captureSizeTransform else { - return - } - - let transformRect = transformedVideoRect.applying(_captureSizeTransform) - zxCapture.scanRect = transformRect - } } diff --git a/changelog.d/pr-7762.bugfix b/changelog.d/pr-7762.bugfix new file mode 100644 index 0000000000..ba4b1b87cc --- /dev/null +++ b/changelog.d/pr-7762.bugfix @@ -0,0 +1 @@ +Fix a bug where QR codes aren't detected if the camera is too close. \ No newline at end of file From 3d304571bf7fbb9d93b4b070c0052bbdc5333cc3 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 5 Mar 2024 09:26:37 +0000 Subject: [PATCH 24/91] version++ --- CHANGES.md | 12 ++++++++++++ changelog.d/7752.bugfix | 1 - changelog.d/pr-7758.change | 1 - changelog.d/pr-7762.bugfix | 1 - 4 files changed, 12 insertions(+), 3 deletions(-) delete mode 100644 changelog.d/7752.bugfix delete mode 100644 changelog.d/pr-7758.change delete mode 100644 changelog.d/pr-7762.bugfix diff --git a/CHANGES.md b/CHANGES.md index f6dc2d35a7..174be9ac8a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,15 @@ +## Changes in 1.11.8 (2024-03-05) + +🙌 Improvements + +- Disable the mark as unread feature to avoid it clashing with the new MSC2876 based one ([#7758](https://github.com/element-hq/element-ios/pull/7758)) + +🐛 Bugfixes + +- Fix a bug where QR codes aren't detected if the camera is too close. ([#7762](https://github.com/element-hq/element-ios/pull/7762)) +- Fix dictation when using the Rich Text Editor ([#7752](https://github.com/element-hq/element-ios/issues/7752)) + + ## Changes in 1.11.7 (2024-02-07) 🙌 Improvements diff --git a/changelog.d/7752.bugfix b/changelog.d/7752.bugfix deleted file mode 100644 index d7660edc8d..0000000000 --- a/changelog.d/7752.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix dictation when using the Rich Text Editor \ No newline at end of file diff --git a/changelog.d/pr-7758.change b/changelog.d/pr-7758.change deleted file mode 100644 index 28d7addb71..0000000000 --- a/changelog.d/pr-7758.change +++ /dev/null @@ -1 +0,0 @@ -Disable the mark as unread feature to avoid it clashing with the new MSC2876 based one \ No newline at end of file diff --git a/changelog.d/pr-7762.bugfix b/changelog.d/pr-7762.bugfix deleted file mode 100644 index ba4b1b87cc..0000000000 --- a/changelog.d/pr-7762.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix a bug where QR codes aren't detected if the camera is too close. \ No newline at end of file From fc00b101ba6cc7d4070a51ec69befd2f13f9f766 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 5 Mar 2024 11:07:37 +0100 Subject: [PATCH 25/91] =?UTF-8?q?M=C3=AAme=20traduction=20EN=20que=20le=20?= =?UTF-8?q?web=20et=20Android?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/Vector.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 9f527b8209..1a9c520e1a 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2773,7 +2773,7 @@ To enable access, tap Settings> Location and select Always"; "notice_room_history_visible_to_members_from_joined_point" = "%@ made future room history visible to all room members, from the point they joined."; "notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ made future messages visible to everyone, from when they joined."; "notice_crypto_unable_to_decrypt" = "** Unable to decrypt: %@ **"; -"notice_crypto_error_unknown_inbound_session_id" = "Deciphering…"; // Tchap +"notice_crypto_error_unknown_inbound_session_id" = "Decrypting…"; // Tchap "notice_sticker" = "sticker"; "notice_in_reply_to" = "In reply to"; "notice_voice_broadcast_live" = "Live broadcast"; From d83409ce4ca5de602c3edbdbf301d4327ffd106a Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 5 Mar 2024 10:19:27 +0000 Subject: [PATCH 26/91] finish version++ From 2ec3ae1630727cb57f999dc95472f29e5fd7ccf1 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 5 Mar 2024 10:19:33 +0000 Subject: [PATCH 27/91] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index b1d7c33ed5..4cf4cbfbe3 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.8 -CURRENT_PROJECT_VERSION = 1.11.8 +MARKETING_VERSION = 1.11.9 +CURRENT_PROJECT_VERSION = 1.11.9 From 7cb492eb19e62a7306247ebed9a42318573c8c0f Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 5 Mar 2024 11:45:27 +0100 Subject: [PATCH 28/91] =?UTF-8?q?Utiliser=20la=20m=C3=AAme=20icone=20que?= =?UTF-8?q?=20sur=20web?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift b/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift index 94c0b8855c..5dc216d027 100644 --- a/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift +++ b/Riot/Modules/Room/TimelineCells/Call/Direct/RoomDirectCallStatusCell.swift @@ -113,7 +113,7 @@ class RoomDirectCallStatusCell: RoomCallBaseCell { // Tchap: report VoIP problem button icon 􀌭 private var reportVoIPProblemButtonIcon: UIImage { - return UIImage(systemName: "exclamationmark.bubble.fill")! + return UIImage(systemName: "exclamationmark.circle.fill")! } private var actionUserInfo: [AnyHashable: Any]? { From dbc13963711405a928070ac5ed7e2cbec792a66a Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 5 Mar 2024 17:01:27 +0100 Subject: [PATCH 29/91] =?UTF-8?q?Changement=20de=20la=20formulation=20du?= =?UTF-8?q?=20bouton=20des=20r=C3=A9glages=20pour=20autoriser=20les=20noti?= =?UTF-8?q?fications=20sur=20l'appareil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/Vector.strings | 2 +- Riot/Assets/fr.lproj/Vector.strings | 2 +- Riot/Modules/Settings/SettingsViewController.m | 17 ++++++++++++++--- .../Assets/Localizations/fr.lproj/Tchap.strings | 6 +++++- changelog.d/975.change | 1 + 5 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 changelog.d/975.change diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 1a9c520e1a..32c82558e9 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -759,7 +759,7 @@ Tap the + to start adding people."; "settings_security" = "SECURITY"; -"settings_enable_push_notif" = "Notifications on this device"; +"settings_enable_push_notif" = "Enable notifications on this device"; // Tchap "settings_device_notifications" = "Device notifications"; "settings_show_decrypted_content" = "Show decrypted content"; "settings_global_settings_info" = "Global notification settings are available on your %@ web client"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index e51ab378af..2c975b2c40 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -279,7 +279,7 @@ "settings_add_phone_number" = "Ajouter un numéro de téléphone"; "settings_night_mode" = "Mode nuit"; "settings_fail_to_update_profile" = "Échec de la mise à jour du profil"; -"settings_enable_push_notif" = "Notifications sur cet appareil"; +"settings_enable_push_notif" = "Autoriser les notifications sur cet appareil"; // Tchap "settings_global_settings_info" = "Les paramètres de notification globaux sont disponibles sur votre client web %@"; "settings_pin_rooms_with_missed_notif" = "Épingler les salons avec des notifications non lues"; "settings_pin_rooms_with_unread" = "Épingler les salons avec des messages non lus"; diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index e76ab67acb..07385901df 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -2107,8 +2107,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N // Tchap: Add Hide User from directory MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; - NSString *title = NSLocalizedStringFromTable(@"settings_hide_from_users_directory_title", @"Tchap", nil); - NSString *summary = NSLocalizedStringFromTable(@"settings_hide_from_users_directory_summary", @"Tchap", nil); + NSString *title = TchapL10n.settingsHideFromUsersDirectoryTitle; + NSString *summary = TchapL10n.settingsHideFromUsersDirectorySummary; NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString: title attributes:@{NSForegroundColorAttributeName : ThemeService.shared.theme.textPrimaryColor, NSFontAttributeName: [UIFont systemFontOfSize:17.0]}]; @@ -2171,7 +2171,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; - labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsEnablePushNotif]; + // Tchap: adapt "Enable notifications" label and text. +// labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsEnablePushNotif]; + + NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString: VectorL10n.settingsEnablePushNotif + attributes:@{NSForegroundColorAttributeName : ThemeService.shared.theme.textPrimaryColor, + NSFontAttributeName: [UIFont systemFontOfSize:17.0]}]; + [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n" attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:4]}]]; + [attributedText appendAttributedString:[[NSMutableAttributedString alloc] initWithString: TchapL10n.settingsEnablePushNotifText + attributes:@{NSForegroundColorAttributeName : ThemeService.shared.theme.textSecondaryColor, + NSFontAttributeName: [UIFont systemFontOfSize:14.0]}]]; + + labelAndSwitchCell.mxkLabel.attributedText = attributedText; labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; labelAndSwitchCell.mxkSwitch.enabled = YES; [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(togglePushNotifications:) forControlEvents:UIControlEventTouchUpInside]; diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 0c048fd7e5..5b952e4bc7 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -326,7 +326,7 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Room Invite "security_cross_signing_setup_title" = "Activer la signature croisée"; -"security_cross_signing_reset_title" = "Êtes-vous sur ?"; +"security_cross_signing_reset_title" = "Êtes-vous sûr ?"; "security_cross_signing_reset_message" = "Faites cette opération seulement si vous avez perdu tous vos autres appareils vérifiés."; "security_cross_signing_reset_action_title" = "Réinitialiser"; @@ -335,3 +335,7 @@ "event_formatter_report_incident" = "Signaler un problème"; "void_report_incident_title" = "Signaler un problème VoIP"; "void_report_incident_description" = "Vous avez rencontré un souci durant votre appel VoIP. Dites-nous ce qui s'est passé :"; + +//////////////////////////////////////////////////////////////////////////////// +// MARK: Settings +"settings_enable_push_notif_text" = "Sans cette autorisation, les appels entrants ne seront pas notifiés."; diff --git a/changelog.d/975.change b/changelog.d/975.change new file mode 100644 index 0000000000..fe7becb748 --- /dev/null +++ b/changelog.d/975.change @@ -0,0 +1 @@ +Changement de la formulation du bouton des réglages pour autoriser les notifications sur l'appareil. Ajout d'un texte explicatif. \ No newline at end of file From a1d59b32b7eaba3253215ea9cf935b473ba37d74 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 Mar 2024 11:18:00 +0100 Subject: [PATCH 30/91] Increase decryption failure grace period --- Riot/Modules/Analytics/DecryptionFailureTracker.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.m b/Riot/Modules/Analytics/DecryptionFailureTracker.m index 4a749b71aa..86b847f221 100644 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.m +++ b/Riot/Modules/Analytics/DecryptionFailureTracker.m @@ -19,11 +19,11 @@ // Call `checkFailures` every `CHECK_INTERVAL` -#define CHECK_INTERVAL 2 +#define CHECK_INTERVAL 10 // Give events a chance to be decrypted by waiting `GRACE_PERIOD` before counting // and reporting them as failures -#define GRACE_PERIOD 4 +#define GRACE_PERIOD 30 // E2E failures analytics category. NSString *const kDecryptionFailureTrackerAnalyticsCategory = @"e2e.failure"; From 64913dbe19f533b6d29b4467b811c4ce17c202e6 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 11:34:35 +0100 Subject: [PATCH 31/91] Activer le partage de localisation dans les settings et renseigner le bon fournisseur de fonds de carte --- Btchap/Config/BuildSettings.swift | 4 ++-- Config/BuildSettings.swift | 6 +++--- DevTchap/Config/BuildSettings.swift | 6 +++--- RiotNSE/BuildSettings.swift | 6 +++--- RiotShareExtension/BuildSettings.swift | 6 +++--- Tchap/Config/BuildSettings.swift | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Btchap/Config/BuildSettings.swift b/Btchap/Config/BuildSettings.swift index f577db02a8..7616ed7bdc 100644 --- a/Btchap/Config/BuildSettings.swift +++ b/Btchap/Config/BuildSettings.swift @@ -413,9 +413,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index b73ee1f6a7..62b061671b 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -423,9 +423,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! - - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 diff --git a/DevTchap/Config/BuildSettings.swift b/DevTchap/Config/BuildSettings.swift index 58ee2009f4..3c6e0c6d8a 100644 --- a/DevTchap/Config/BuildSettings.swift +++ b/DevTchap/Config/BuildSettings.swift @@ -414,9 +414,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! - - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 diff --git a/RiotNSE/BuildSettings.swift b/RiotNSE/BuildSettings.swift index 15bd01100e..a43c9911b3 100644 --- a/RiotNSE/BuildSettings.swift +++ b/RiotNSE/BuildSettings.swift @@ -452,9 +452,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! - - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 diff --git a/RiotShareExtension/BuildSettings.swift b/RiotShareExtension/BuildSettings.swift index 15bd01100e..a43c9911b3 100644 --- a/RiotShareExtension/BuildSettings.swift +++ b/RiotShareExtension/BuildSettings.swift @@ -452,9 +452,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! - - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 diff --git a/Tchap/Config/BuildSettings.swift b/Tchap/Config/BuildSettings.swift index 15bd01100e..a43c9911b3 100644 --- a/Tchap/Config/BuildSettings.swift +++ b/Tchap/Config/BuildSettings.swift @@ -452,9 +452,9 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=")! - - static let locationSharingEnabled = false // Currently disabled in Tchap. + static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + + static let locationSharingEnabled = true // MARK: - Voice Broadcast static let voiceBroadcastChunkLength: Int = 120 From 1863e8382b78fe1946bcf882ff95e812a46198ae Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 11:35:24 +0100 Subject: [PATCH 32/91] =?UTF-8?q?Renseigner=20les=20alertes=20utilisateurs?= =?UTF-8?q?=20iOS=20d'activation=20de=20g=C3=A9olocalisation=20(=C3=A0=20c?= =?UTF-8?q?ompl=C3=A9ter)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tchap/SupportingFiles/Info.plist | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tchap/SupportingFiles/Info.plist b/Tchap/SupportingFiles/Info.plist index 87e719493e..badb92e61f 100644 --- a/Tchap/SupportingFiles/Info.plist +++ b/Tchap/SupportingFiles/Info.plist @@ -53,12 +53,19 @@ In order to show who among your contacts already uses Tchap, we can exploit the e-mail addresses of your address book. These data will not be stored. For more information, please visit the privacy policy page in the app settings NSFaceIDUsageDescription Face ID is used to access your app. + NSLocationAlwaysAndWhenInUseUsageDescription + Please, allow Tchap to share your location + NSLocationAlwaysUsageDescription + Please, allow Tchap to share your location + NSLocationWhenInUseUsageDescription + Please, allow Tchap to share your location NSMicrophoneUsageDescription Tchap needs to access your microphone to take videos, and record voice messages. NSPhotoLibraryUsageDescription This allows you to select pictures or videos from the photo library, and send them in your conversations. You can also use one of these pictures to set your profile picture. UIBackgroundModes + location remote-notification voip From 2eceef5e89b39c4fcd16df6b650c7decf0a12e74 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 11:36:05 +0100 Subject: [PATCH 33/91] =?UTF-8?q?Activer=20les=20callbacks=20de=20g=C3=A9o?= =?UTF-8?q?localisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/RoomCoordinator.swift | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index cd09ddaa08..40dede1629 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -621,11 +621,11 @@ extension RoomCoordinator: RoomViewControllerDelegate { } func roomViewControllerDidRequestLocationSharingFormPresentation(_ roomViewController: RoomViewController) { -// startLocationCoordinator() + startLocationCoordinator() } func roomViewController(_ roomViewController: RoomViewController, didRequestLocationPresentationFor event: MXEvent, bubbleData: MXKRoomBubbleCellDataStoring) { -// showLocationCoordinatorWithEvent(event, bubbleData: bubbleData) + showLocationCoordinatorWithEvent(event, bubbleData: bubbleData) } func roomViewController(_ roomViewController: RoomViewController, didRequestLiveLocationPresentationForBubbleData bubbleData: MXKRoomBubbleCellDataStoring) { @@ -643,8 +643,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { return nil } - // Tchap: Location Sharing is disabled in Tchap - return nil// LocationSharingCoordinator.shareLocationActivityController(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)) + return LocationSharingCoordinator.shareLocationActivityController(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)) } func roomViewController(_ roomViewController: RoomViewController, canEndPollWithEventIdentifier eventIdentifier: String) -> Bool { @@ -672,8 +671,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { } func roomViewControllerDidTapLiveLocationSharingBanner(_ roomViewController: RoomViewController) { - -// showLiveLocationViewer() + showLiveLocationViewer() } func roomViewControllerDidStopLiveLocationSharing(_ roomViewController: RoomViewController, beaconInfoEventId: String?) { From b2d4453364ca92a051210f5f6296c00e53d00cc7 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 11:37:22 +0100 Subject: [PATCH 34/91] =?UTF-8?q?Activer=20les=20mod=C3=A8les=20d'affichag?= =?UTF-8?q?e=20des=20cellules=20de=20g=C3=A9olocalisation=20dans=20la=20ti?= =?UTF-8?q?meline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Bubble/BubbleRoomTimelineCellProvider.m | 20 +++++++++---------- .../Plain/PlainRoomTimelineCellProvider.m | 12 +++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m b/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m index 2dc24aa911..1e2acac960 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m @@ -110,14 +110,14 @@ - (void)registerPollCellsForTableView:(UITableView *)tableView - (void)registerLocationCellsForTableView:(UITableView*)tableView { -// // Incoming -// [tableView registerClass:LocationIncomingBubbleCell.class forCellReuseIdentifier:LocationIncomingBubbleCell.defaultReuseIdentifier]; -// [tableView registerClass:LocationIncomingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationIncomingWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; -// [tableView registerClass:LocationIncomingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationIncomingWithPaginationTitleBubbleCell.defaultReuseIdentifier]; -// -// // Outgoing -// [tableView registerClass:LocationOutgoingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; -// [tableView registerClass:LocationOutgoingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + // Incoming + [tableView registerClass:LocationIncomingBubbleCell.class forCellReuseIdentifier:LocationIncomingBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationIncomingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationIncomingWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationIncomingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationIncomingWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + + // Outgoing + [tableView registerClass:LocationOutgoingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationOutgoingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithPaginationTitleBubbleCell.defaultReuseIdentifier]; } - (void)registerFileWithoutThumbnailCellsForTableView:(UITableView*)tableView @@ -299,7 +299,7 @@ - (void)registerVoiceBroadcastRecorderCellsForTableView:(UITableView*)tableView - (NSDictionary*)locationCellsMapping { - return @{/* + return @{ // Incoming @(RoomTimelineCellIdentifierIncomingLocation) : LocationIncomingBubbleCell.class, @(RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo) : LocationIncomingWithoutSenderInfoBubbleCell.class, @@ -307,7 +307,7 @@ - (void)registerVoiceBroadcastRecorderCellsForTableView:(UITableView*)tableView // Outgoing @(RoomTimelineCellIdentifierOutgoingLocation) : LocationOutgoingWithoutSenderInfoBubbleCell.class, @(RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo) : LocationOutgoingWithoutSenderInfoBubbleCell.class, - @(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationOutgoingWithPaginationTitleBubbleCell.class*/ + @(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationOutgoingWithPaginationTitleBubbleCell.class }; } diff --git a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m index e178d77235..b53aa3a9ba 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -580,13 +580,13 @@ - (void)registerVoiceBroadcastRecorderCellsForTableView:(UITableView*)tableView { return @{ // Incoming -// @(RoomTimelineCellIdentifierIncomingLocation) : LocationPlainCell.class, -// @(RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo) : LocationWithoutSenderInfoPlainCell.class, -// @(RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle) : LocationWithPaginationTitlePlainCell.class, + @(RoomTimelineCellIdentifierIncomingLocation) : LocationPlainCell.class, + @(RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo) : LocationWithoutSenderInfoPlainCell.class, + @(RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle) : LocationWithPaginationTitlePlainCell.class, // Outgoing -// @(RoomTimelineCellIdentifierOutgoingLocation) : LocationPlainCell.class, -// @(RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo) : LocationWithoutSenderInfoPlainCell.class, -// @(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationWithPaginationTitlePlainCell.class + @(RoomTimelineCellIdentifierOutgoingLocation) : LocationPlainCell.class, + @(RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo) : LocationWithoutSenderInfoPlainCell.class, + @(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationWithPaginationTitlePlainCell.class }; } From 53193df7faaaad0c7ebaaed72e3bd0e01604ba37 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 11:38:02 +0100 Subject: [PATCH 35/91] =?UTF-8?q?Activer=20les=20appels=20d'affichage=20de?= =?UTF-8?q?s=20cellules=20de=20g=C3=A9olocalisation=20dans=20la=20timeline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/RoomViewController.m | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 28b0670170..d8ddf730a0 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -3330,39 +3330,39 @@ - (RoomTimelineCellIdentifier)cellIdentifierForCellData:(MXKCellData*)cellData a } } } -// else if (bubbleData.tag == RoomBubbleCellDataTagLocation || bubbleData.tag == RoomBubbleCellDataTagLiveLocation) -// { -// if (bubbleData.isIncoming) -// { -// if (bubbleData.isPaginationFirstBubble) -// { -// cellIdentifier = RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle; -// } -// else if (bubbleData.shouldHideSenderInformation) -// { -// cellIdentifier = RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo; -// } -// else -// { -// cellIdentifier = RoomTimelineCellIdentifierIncomingLocation; -// } -// } -// else -// { -// if (bubbleData.isPaginationFirstBubble) -// { -// cellIdentifier = RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle; -// } -// else if (bubbleData.shouldHideSenderInformation) -// { -// cellIdentifier = RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo; -// } -// else -// { -// cellIdentifier = RoomTimelineCellIdentifierOutgoingLocation; -// } -// } -// } + else if (bubbleData.tag == RoomBubbleCellDataTagLocation || bubbleData.tag == RoomBubbleCellDataTagLiveLocation) + { + if (bubbleData.isIncoming) + { + if (bubbleData.isPaginationFirstBubble) + { + cellIdentifier = RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle; + } + else if (bubbleData.shouldHideSenderInformation) + { + cellIdentifier = RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo; + } + else + { + cellIdentifier = RoomTimelineCellIdentifierIncomingLocation; + } + } + else + { + if (bubbleData.isPaginationFirstBubble) + { + cellIdentifier = RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle; + } + else if (bubbleData.shouldHideSenderInformation) + { + cellIdentifier = RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo; + } + else + { + cellIdentifier = RoomTimelineCellIdentifierOutgoingLocation; + } + } + } // else if (bubbleData.tag == RoomBubbleCellDataTagVoiceBroadcastPlayback) // { // if (bubbleData.isIncoming) From 86f62c130ff42e24880aa096e7c24f2e6fd5ef8b Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 15:30:34 +0100 Subject: [PATCH 36/91] =?UTF-8?q?Activer=20le=20partage=20de=20g=C3=A9oloc?= =?UTF-8?q?alisation=20par=20featureFlag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Btchap/Config/BuildSettings.swift | 1 + DevTchap/Config/BuildSettings.swift | 1 + Riot/Modules/Room/RoomViewController.m | 5 ++++- RiotNSE/BuildSettings.swift | 6 +++++- RiotShareExtension/BuildSettings.swift | 6 +++++- Tchap/Config/BuildSettings.swift | 6 +++++- 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Btchap/Config/BuildSettings.swift b/Btchap/Config/BuildSettings.swift index 7616ed7bdc..f36a276640 100644 --- a/Btchap/Config/BuildSettings.swift +++ b/Btchap/Config/BuildSettings.swift @@ -237,6 +237,7 @@ final class BuildSettings: NSObject { static let tchapFeatureNotificationByEmail = "tchapFeatureNotificationByEmail" static let tchapFeatureVoiceOverIP = "tchapFeatureVoiceOverIP" static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" // Tchap: in pre-prod, allow any feature to any instance. + static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureAnyFeature: [ tchapFeatureAnyHomeServer ] ] diff --git a/DevTchap/Config/BuildSettings.swift b/DevTchap/Config/BuildSettings.swift index 3c6e0c6d8a..d064555b35 100644 --- a/DevTchap/Config/BuildSettings.swift +++ b/DevTchap/Config/BuildSettings.swift @@ -238,6 +238,7 @@ final class BuildSettings: NSObject { static let tchapFeatureNotificationByEmail = "tchapFeatureNotificationByEmail" static let tchapFeatureVoiceOverIP = "tchapFeatureVoiceOverIP" static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" // Tchap: in Dev, allow any feature to any instance. + static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureAnyFeature: [ tchapFeatureAnyHomeServer ] ] diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index d8ddf730a0..2103286cae 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2425,7 +2425,10 @@ - (void)setupActions { [self.delegate roomViewControllerDidRequestPollCreationFormPresentation:self]; }]]; } - if (BuildSettings.locationSharingEnabled && !self.isNewDirectChat) + // Tchap: allow location sharing by feature flag +// if (BuildSettings.locationSharingEnabled && !self.isNewDirectChat) + MXKAccount *account = MXKAccountManager.sharedManager.activeAccounts.firstObject; + if ([account isFeatureActivated:BuildSettings.tchapFeatureGeolocationSharing] && BuildSettings.locationSharingEnabled && !self.isNewDirectChat) { [actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionLocation.image andAction:^{ MXStrongifyAndReturnIfNil(self); diff --git a/RiotNSE/BuildSettings.swift b/RiotNSE/BuildSettings.swift index a43c9911b3..0c5d9ff411 100644 --- a/RiotNSE/BuildSettings.swift +++ b/RiotNSE/BuildSettings.swift @@ -267,17 +267,21 @@ final class BuildSettings: NSObject { static let tchapFeatureNotificationByEmail = "tchapFeatureNotificationByEmail" static let tchapFeatureVoiceOverIP = "tchapFeatureVoiceOverIP" static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" + static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ "agent.dinum.tchap.gouv.fr" ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" - ] + ], // No activation of video calls actually in Tchap Production. // tchapFeatureVideoOverIP: [ // "agent.dinum.tchap.gouv.fr" // ], + tchapFeatureGeolocationSharing: [ + tchapFeatureAnyHomeServer + ] ] // MARK: - Side Menu diff --git a/RiotShareExtension/BuildSettings.swift b/RiotShareExtension/BuildSettings.swift index a43c9911b3..0c5d9ff411 100644 --- a/RiotShareExtension/BuildSettings.swift +++ b/RiotShareExtension/BuildSettings.swift @@ -267,17 +267,21 @@ final class BuildSettings: NSObject { static let tchapFeatureNotificationByEmail = "tchapFeatureNotificationByEmail" static let tchapFeatureVoiceOverIP = "tchapFeatureVoiceOverIP" static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" + static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ "agent.dinum.tchap.gouv.fr" ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" - ] + ], // No activation of video calls actually in Tchap Production. // tchapFeatureVideoOverIP: [ // "agent.dinum.tchap.gouv.fr" // ], + tchapFeatureGeolocationSharing: [ + tchapFeatureAnyHomeServer + ] ] // MARK: - Side Menu diff --git a/Tchap/Config/BuildSettings.swift b/Tchap/Config/BuildSettings.swift index a43c9911b3..0c5d9ff411 100644 --- a/Tchap/Config/BuildSettings.swift +++ b/Tchap/Config/BuildSettings.swift @@ -267,17 +267,21 @@ final class BuildSettings: NSObject { static let tchapFeatureNotificationByEmail = "tchapFeatureNotificationByEmail" static let tchapFeatureVoiceOverIP = "tchapFeatureVoiceOverIP" static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" + static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ "agent.dinum.tchap.gouv.fr" ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" - ] + ], // No activation of video calls actually in Tchap Production. // tchapFeatureVideoOverIP: [ // "agent.dinum.tchap.gouv.fr" // ], + tchapFeatureGeolocationSharing: [ + tchapFeatureAnyHomeServer + ] ] // MARK: - Side Menu From 3e9c498767c581cfbc9aa2c1dd0041d41baf4f7f Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 15:31:09 +0100 Subject: [PATCH 37/91] =?UTF-8?q?R=C3=A9activer=20la=20fonction=20LABS=20E?= =?UTF-8?q?lement=20de=20g=C3=A9olocalisation=20(pr=C3=A9-accord=20de=20pa?= =?UTF-8?q?rtage=20de=20localisation=20en=20temps=20r=C3=A9el)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Settings/SettingsViewController.m | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index e76ab67acb..1d8bc5614d 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -190,8 +190,7 @@ typedef NS_ENUM(NSUInteger, LABS_ENABLE) LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX = 0, LABS_ENABLE_THREADS_INDEX, LABS_ENABLE_AUTO_REPORT_DECRYPTION_ERRORS, - // Tchap: Location sharing is disabled in Tchap -// LABS_ENABLE_LIVE_LOCATION_SHARING, + LABS_ENABLE_LIVE_LOCATION_SHARING, LABS_ENABLE_NEW_SESSION_MANAGER, LABS_ENABLE_NEW_CLIENT_INFO_FEATURE, LABS_ENABLE_WYSIWYG_COMPOSER, @@ -681,8 +680,7 @@ - (void)updateSections [sectionLabs addRowWithTag:LABS_ENABLE_AUTO_REPORT_DECRYPTION_ERRORS]; if (BuildSettings.locationSharingEnabled) { - // Tchap: Location sharing is disabled in Tchap -// [sectionLabs addRowWithTag:LABS_ENABLE_LIVE_LOCATION_SHARING]; + [sectionLabs addRowWithTag:LABS_ENABLE_LIVE_LOCATION_SHARING]; } [sectionLabs addRowWithTag:LABS_ENABLE_NEW_SESSION_MANAGER]; [sectionLabs addRowWithTag:LABS_ENABLE_NEW_CLIENT_INFO_FEATURE]; @@ -2691,11 +2689,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { cell = [self buildAutoReportDecryptionErrorsCellForTableView:tableView atIndexPath:indexPath]; } - // Tchap: Location sharing is disabled in Tchap -// else if (row == LABS_ENABLE_LIVE_LOCATION_SHARING) -// { -// cell = [self buildLiveLocationSharingCellForTableView:tableView atIndexPath:indexPath]; -// } + else if (row == LABS_ENABLE_LIVE_LOCATION_SHARING) + { + cell = [self buildLiveLocationSharingCellForTableView:tableView atIndexPath:indexPath]; + } else if (row == LABS_ENABLE_NEW_SESSION_MANAGER) { MXKTableViewCellWithLabelAndSwitch *labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; From 27412688ec2b2e5c1e86bc4bb0cdd124fd3714c1 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 15:47:54 +0100 Subject: [PATCH 38/91] =?UTF-8?q?Traduction=20des=20messages=20d'autorisat?= =?UTF-8?q?ion=20pour=20activer=20la=20g=C3=A9olocalisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/InfoPlist.strings | 4 ++-- Riot/Assets/fr.lproj/InfoPlist.strings | 2 ++ RiotSwiftUI/Info.plist | 4 ++-- Tchap/SupportingFiles/Info.plist | 6 ++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Riot/Assets/en.lproj/InfoPlist.strings b/Riot/Assets/en.lproj/InfoPlist.strings index edab7c3751..c26e49651f 100644 --- a/Riot/Assets/en.lproj/InfoPlist.strings +++ b/Riot/Assets/en.lproj/InfoPlist.strings @@ -21,5 +21,5 @@ "NSContactsUsageDescription" = "In order to show who among your contacts already uses Tchap, we can exploit the e-mail addresses of your address book. These data will not be stored. For more information, please visit the privacy policy page in the app settings."; "NSCalendarsUsageDescription" = "See your scheduled meetings in the app."; "NSFaceIDUsageDescription" = "Face ID is used to access your app."; -"NSLocationWhenInUseUsageDescription" = "When you share your location to people, Element needs access to show them a map."; -"NSLocationAlwaysAndWhenInUseUsageDescription" = "When you share your location to people, Element needs access to show them a map."; +"NSLocationWhenInUseUsageDescription" = "When you share your location to people, Tchap needs access to show them a map."; +"NSLocationAlwaysAndWhenInUseUsageDescription" = "When you share your location to people, Tchap needs access to show them a map."; diff --git a/Riot/Assets/fr.lproj/InfoPlist.strings b/Riot/Assets/fr.lproj/InfoPlist.strings index 74885bea35..be710f7e8a 100644 --- a/Riot/Assets/fr.lproj/InfoPlist.strings +++ b/Riot/Assets/fr.lproj/InfoPlist.strings @@ -4,3 +4,5 @@ "NSMicrophoneUsageDescription" = "Tchap nécessite l'accès au microphone pour réaliser des vidéos avec la caméra, ou pour enregistrer des messages vocaux."; "NSContactsUsageDescription" = "Afin d’afficher qui parmi vos contacts utilise déjà Tchap, nous pouvons exploiter les adresses e-mails de votre carnet d'adresse. Ces données ne seront pas mémorisées. Pour plus d'informations, veuillez consulter les Termes et Conditions disponibles dans les paramètres de l'application."; "NSFaceIDUsageDescription" = "Face ID est utilisé pour accéder à votre application."; +"NSLocationWhenInUseUsageDescription" = "Lorsque vous partagez votre position, Tchap a besoin de votre autorisation pour l'afficher sur une carte."; +"NSLocationAlwaysAndWhenInUseUsageDescription" = "Lorsque vous partagez votre position, Tchap a besoin de votre autorisation pour l'afficher sur une carte."; diff --git a/RiotSwiftUI/Info.plist b/RiotSwiftUI/Info.plist index a74d218642..df3ec702a8 100644 --- a/RiotSwiftUI/Info.plist +++ b/RiotSwiftUI/Info.plist @@ -23,8 +23,8 @@ CFBundleDisplayName RiotSwiftUI NSLocationWhenInUseUsageDescription - When you share your location to people, Element needs access to show them a map. + When you share your location to people, Tchap needs access to show them a map. NSLocationAlwaysAndWhenInUseUsageDescription - When you share your location to people, Element needs access to show them a map. + When you share your location to people, Tchap needs access to show them a map. diff --git a/Tchap/SupportingFiles/Info.plist b/Tchap/SupportingFiles/Info.plist index badb92e61f..666cd98359 100644 --- a/Tchap/SupportingFiles/Info.plist +++ b/Tchap/SupportingFiles/Info.plist @@ -54,11 +54,9 @@ NSFaceIDUsageDescription Face ID is used to access your app. NSLocationAlwaysAndWhenInUseUsageDescription - Please, allow Tchap to share your location - NSLocationAlwaysUsageDescription - Please, allow Tchap to share your location + When you share your location to people, Tchap needs access to show them a map. NSLocationWhenInUseUsageDescription - Please, allow Tchap to share your location + When you share your location to people, Tchap needs access to show them a map. NSMicrophoneUsageDescription Tchap needs to access your microphone to take videos, and record voice messages. NSPhotoLibraryUsageDescription From a6683f505515faaf03578cdebbd0d8ee230d9f6e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 17:56:42 +0100 Subject: [PATCH 39/91] Ajout du changelog --- changelog.d/970.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/970.change diff --git a/changelog.d/970.change b/changelog.d/970.change new file mode 100644 index 0000000000..03d602ea1d --- /dev/null +++ b/changelog.d/970.change @@ -0,0 +1 @@ +Activation du partage de géolocalisation \ No newline at end of file From e2ad23df8e23236a7de4a0e92e64693719a6217d Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 11 Mar 2024 18:25:49 +0100 Subject: [PATCH 40/91] Traduction de "Element" en "Tchap" dans un message d'alerte --- Riot/Assets/en.lproj/Vector.strings | 4 ++-- Riot/Assets/fr.lproj/Vector.strings | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 0cb9b07a5b..805a5881ef 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2453,8 +2453,8 @@ Tap the + to start adding people."; "location_sharing_settings_toggle_title" = "Enable location sharing"; "location_sharing_allow_background_location_title" = "Allow access"; -"location_sharing_allow_background_location_message" = "If you’d like to share your Live location, Element needs location access when the app is in the background. -To enable access, tap Settings> Location and select Always"; +"location_sharing_allow_background_location_message" = "If you’d like to share your Live location, Tchap needs location access when the app is in the background. +To enable access, tap Settings> Location and select Always"; // Tchap "location_sharing_allow_background_location_validate_action" = "Settings"; "location_sharing_allow_background_location_cancel_action" = "Not now"; "location_sharing_map_credits_title" = "© Copyright"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index e48f772de3..87430368cb 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -2324,7 +2324,7 @@ "authentication_registration_title" = "Créez votre compte"; "room_access_settings_screen_upgrade_alert_title" = "Mettre à niveau le salon"; "room_access_settings_screen_upgrade_required" = "Mise à niveau requise"; -"location_sharing_allow_background_location_message" = "Si vous voulez partager votre localisation en temps réel, Element doit avoir accès à vos données de localisation lorsque l’application est en arrière-plan. Pour lui donner accès, rendez-vous dans Réglages > Position et sélectionnez Toujours"; +"location_sharing_allow_background_location_message" = "Si vous voulez partager votre localisation en temps réel, Tchap doit avoir accès à vos données de localisation lorsque l’application est en arrière-plan. Pour lui donner accès, rendez-vous dans Réglages > Position et sélectionnez Toujours"; // Tchap "settings_timeline" = "HISTORIQUE"; "authentication_server_selection_login_title" = "Connexion à un serveur d’accueil"; "message_reply_to_sender_sent_their_live_location" = "Localisation en temps réel."; From 14b437a0dc9445f3b03e6ef1e986046749dc23c6 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 12 Mar 2024 15:12:48 +0100 Subject: [PATCH 41/91] =?UTF-8?q?Modifier=20l'intitul=C3=A9=20de=20d=C3=A9?= =?UTF-8?q?sactivation=20de=20compte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/Vector.strings | 14 +++++++------- Riot/Assets/fr.lproj/Vector.strings | 14 +++++++------- changelog.d/982.change | 1 + 3 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 changelog.d/982.change diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 32c82558e9..d1ed0d8ef5 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -727,7 +727,7 @@ Tap the + to start adding people."; "settings_devices" = "SESSIONS"; "settings_cryptography" = "CRYPTOGRAPHY"; "settings_key_backup" = "KEY BACKUP"; -"settings_deactivate_account" = "DEACTIVATE ACCOUNT"; +"settings_deactivate_account" = "CLOSE ACCOUNT"; // Tchap "settings_sign_out" = "Sign Out"; "settings_sign_out_confirmation" = "Are you sure?"; @@ -860,7 +860,7 @@ Tap the + to start adding people."; "settings_crypto_export" = "Export keys"; "settings_crypto_blacklist_unverified_devices" = "Encrypt to verified sessions only"; -"settings_deactivate_my_account" = "Deactivate account permanently"; +"settings_deactivate_my_account" = "Close account permanently"; // Tchap "settings_key_backup_info" = "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages."; "settings_key_backup_info_checking" = "Checking…"; @@ -1384,21 +1384,21 @@ Tap the + to start adding people."; // Deactivate account -"deactivate_account_title" = "Deactivate Account"; +"deactivate_account_title" = "Close Account"; // Tchap "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_part3" = "\n\nClosing your account "; // Tchap "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_part1" = "Please forget all messages I have sent when my account is closed ("; // Tchap "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_validate_action" = "Close account"; // Tchap -"deactivate_account_password_alert_title" = "Deactivate Account"; +"deactivate_account_password_alert_title" = "Close Account"; // Tchap "deactivate_account_password_alert_message" = "To continue, please enter your Matrix account password"; // Re-request confirmation dialog diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index 2c975b2c40..b26ee05ce0 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -520,21 +520,21 @@ "room_action_send_photo_or_video" = "Envoyer une photo ou une vidéo"; "room_action_send_sticker" = "Envoyer un autocollant"; "room_action_send_file" = "Envoyer un fichier"; -"settings_deactivate_account" = "DÉSACTIVER LE COMPTE"; -"settings_deactivate_my_account" = "Désactiver le compte pour toujours"; +"settings_deactivate_account" = "FERMER LE COMPTE"; // Tchap +"settings_deactivate_my_account" = "Fermer le compte pour toujours"; // Tchap "widget_sticker_picker_no_stickerpacks_alert" = "Vous n’avez aucun jeu d’autocollants activé."; "widget_sticker_picker_no_stickerpacks_alert_add_now" = "En ajouter maintenant ?"; -"deactivate_account_title" = "Désactiver le compte"; +"deactivate_account_title" = "Fermer le compte"; // Tchap "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 toutes les informations 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_part3" = "\n\nLa fermeture de votre compte "; // Tchap "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és quand mon compte sera désactivé ("; +"deactivate_account_forget_messages_information_part1" = "Veuillez oublier tous les messages que j’ai envoyés quand mon compte sera fermé ("; // Tchap "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_validate_action" = "Fermer le compte"; // Tchap +"deactivate_account_password_alert_title" = "Fermer le compte"; // Tchap "deactivate_account_password_alert_message" = "Pour continuer, veuillez renseigner votre mot de passe"; "event_formatter_rerequest_keys_part1" = "Demande envoyée.\U00A0"; "event_formatter_rerequest_keys_part2_link" = "Renvoyer"; diff --git a/changelog.d/982.change b/changelog.d/982.change new file mode 100644 index 0000000000..c08f1a0a0a --- /dev/null +++ b/changelog.d/982.change @@ -0,0 +1 @@ +Modifier l'intitulé de désactivation de compte \ No newline at end of file From a84f18dec09bfbec33de074268f72a13c206d031 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 12 Mar 2024 16:45:09 +0100 Subject: [PATCH 42/91] =?UTF-8?q?Utiliser=20le=20bouton=20de=20validation?= =?UTF-8?q?=20Tchap=20en=20=C3=A9dition=20de=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m | 4 +++- changelog.d/986.change | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelog.d/986.change diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m index 06a4e1ee1a..1bdbdf03ae 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m @@ -234,7 +234,9 @@ - (void)updateToolbarButtonLabelWithPreviousMode:(RoomInputToolbarViewSendMode)p self.textView.maxHeight -= kContextBarHeight; break; case RoomInputToolbarViewSendModeEdit: - buttonImage = AssetImages.saveIcon.image; + // Tchap: use Tchap icon to save edited message. + // buttonImage = AssetImages.saveIcon.image; + buttonImage = AssetImages_tchap.sendIconTchap.image ; self.inputContextImageView.image = AssetImages.inputEditIcon.image; self.inputContextLabel.text = [VectorL10n roomMessageEditing]; diff --git a/changelog.d/986.change b/changelog.d/986.change new file mode 100644 index 0000000000..02643d852a --- /dev/null +++ b/changelog.d/986.change @@ -0,0 +1 @@ +Utiliser le bouton de validation Tchap en édition de message. \ No newline at end of file From 34559b0e1e58b9de8c1f9d09fa6f50aeba4a1078 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 12 Mar 2024 18:42:33 +0100 Subject: [PATCH 43/91] =?UTF-8?q?R=C3=A9activer=20l'arr=C3=AAt=20du=20part?= =?UTF-8?q?age=20de=20localisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/RoomViewController.m | 48 +++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 2103286cae..653d5899ba 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -3633,26 +3633,26 @@ - (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)ac [self mention:roomMember]; } } -// else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellStopShareButtonPressed]) -// { -// NSString *beaconInfoEventId; -// -// if ([bubbleData isKindOfClass:[RoomBubbleCellData class]]) -// { -// RoomBubbleCellData *roomBubbleCellData = (RoomBubbleCellData*)bubbleData; -// beaconInfoEventId = roomBubbleCellData.beaconInfoSummary.id; -// } -// -// [self.delegate roomViewControllerDidStopLiveLocationSharing:self beaconInfoEventId:beaconInfoEventId]; -// } -// else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellRetryShareButtonPressed]) -// { -// MXEvent *selectedEvent = userInfo[kMXKRoomBubbleCellEventKey]; -// if (selectedEvent) -// { -// // TODO: - Implement retry live location action -// } -// } + else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellStopShareButtonPressed]) + { + NSString *beaconInfoEventId; + + if ([bubbleData isKindOfClass:[RoomBubbleCellData class]]) + { + RoomBubbleCellData *roomBubbleCellData = (RoomBubbleCellData*)bubbleData; + beaconInfoEventId = roomBubbleCellData.beaconInfoSummary.id; + } + + [self.delegate roomViewControllerDidStopLiveLocationSharing:self beaconInfoEventId:beaconInfoEventId]; + } + else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellRetryShareButtonPressed]) + { + MXEvent *selectedEvent = userInfo[kMXKRoomBubbleCellEventKey]; + if (selectedEvent) + { + // TODO: - Implement retry live location action + } + } else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnMessageTextView] || [actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnContentView]) { // Retrieve the tapped event @@ -3663,10 +3663,10 @@ - (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)ac { [self cancelEventSelection]; } -// else if (bubbleData.tag == RoomBubbleCellDataTagLiveLocation) -// { -// [self.delegate roomViewController:self didRequestLiveLocationPresentationForBubbleData:bubbleData]; -// } + else if (bubbleData.tag == RoomBubbleCellDataTagLiveLocation) + { + [self.delegate roomViewController:self didRequestLiveLocationPresentationForBubbleData:bubbleData]; + } else if (tappedEvent) { if (tappedEvent.eventType == MXEventTypeRoomCreate) From f893a76464025596fd51fbabe6891adf4ba69d12 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 13 Mar 2024 11:23:28 +0100 Subject: [PATCH 44/91] Simplifier la formulation du bouton --- Riot/Assets/fr.lproj/Vector.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index b26ee05ce0..0a4d93c060 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -521,7 +521,7 @@ "room_action_send_sticker" = "Envoyer un autocollant"; "room_action_send_file" = "Envoyer un fichier"; "settings_deactivate_account" = "FERMER LE COMPTE"; // Tchap -"settings_deactivate_my_account" = "Fermer le compte pour toujours"; // Tchap +"settings_deactivate_my_account" = "Fermer le compte"; // Tchap "widget_sticker_picker_no_stickerpacks_alert" = "Vous n’avez aucun jeu d’autocollants activé."; "widget_sticker_picker_no_stickerpacks_alert_add_now" = "En ajouter maintenant ?"; "deactivate_account_title" = "Fermer le compte"; // Tchap From c7ce4f553fe1bba3528eff03a51a28b4d093647b Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 14 Mar 2024 21:25:49 +0100 Subject: [PATCH 45/91] Activation du partage de localisation --- Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift index a5cde02ff3..24125ae49c 100644 --- a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift +++ b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift @@ -428,8 +428,7 @@ extension ExploreRoomCoordinator: RoomViewControllerDelegate { guard let location = event.location else { return nil } - // Tchap: No location sharing available in Tchap - return nil// LocationSharingCoordinator.shareLocationActivityController(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)) + return LocationSharingCoordinator.shareLocationActivityController(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)) } func roomViewController(_ roomViewController: RoomViewController, canEditPollWithEventIdentifier eventIdentifier: String) -> Bool { From 5a85651e6b4cf0afe8213f3020cbf527c5a39534 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 10:01:19 +0200 Subject: [PATCH 46/91] Add .xcprivacy info files to the main app, the notification service extension and the broadcast upload one --- .../SupportingFiles/PrivacyInfo.xcprivacy | 33 +++++++++++++++++++ Riot/SupportingFiles/PrivacyInfo.xcprivacy | 33 +++++++++++++++++++ RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy | 33 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy create mode 100644 Riot/SupportingFiles/PrivacyInfo.xcprivacy create mode 100644 RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy diff --git a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..04e9182243 --- /dev/null +++ b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,33 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + + diff --git a/Riot/SupportingFiles/PrivacyInfo.xcprivacy b/Riot/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..04e9182243 --- /dev/null +++ b/Riot/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,33 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + + diff --git a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..04e9182243 --- /dev/null +++ b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,33 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + + From 92be17d80548c2adf2da7f246b0389502eef2f18 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 12:13:16 +0200 Subject: [PATCH 47/91] Add privacy accessed API declaration for system boot time --- .../SupportingFiles/PrivacyInfo.xcprivacy | 8 ++++++++ Riot/SupportingFiles/PrivacyInfo.xcprivacy | 8 ++++++++ RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy | 8 ++++++++ fastlane/Fastfile | 2 +- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy index 04e9182243..500ae9affe 100644 --- a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy +++ b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy @@ -28,6 +28,14 @@ 7D9E.1 + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + diff --git a/Riot/SupportingFiles/PrivacyInfo.xcprivacy b/Riot/SupportingFiles/PrivacyInfo.xcprivacy index 04e9182243..500ae9affe 100644 --- a/Riot/SupportingFiles/PrivacyInfo.xcprivacy +++ b/Riot/SupportingFiles/PrivacyInfo.xcprivacy @@ -28,6 +28,14 @@ 7D9E.1 + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + diff --git a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy index 04e9182243..500ae9affe 100644 --- a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy +++ b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy @@ -28,6 +28,14 @@ 7D9E.1 + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 90d3ff0d79..aea8743105 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -21,7 +21,7 @@ platform :ios do before_all do # Ensure used Xcode version - xcversion(version: "14.2") + xcversion(version: "15.2") end #### Public #### From 4d3d82fa337fdbf3efa45d5a9a8908401ae3508e Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 12:46:29 +0200 Subject: [PATCH 48/91] Switch the github actions to the macos-14 runner --- .github/workflows/ci-build.yml | 2 +- .github/workflows/ci-tests.yml | 2 +- .github/workflows/ci-ui-tests.yml | 2 +- .github/workflows/release-alpha.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index e11eca47af..6cac438d5c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -15,7 +15,7 @@ env: jobs: build: name: Build - runs-on: macos-12 + runs-on: macos-14 # Concurrency group not needed as this workflow only runs on develop which we always want to test. diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index d5a9d105d4..f78a5aba9c 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -16,7 +16,7 @@ env: jobs: tests: name: Tests - runs-on: macos-12 + runs-on: macos-14 concurrency: # When running on develop, use the sha to allow all runs of this workflow to run concurrently. diff --git a/.github/workflows/ci-ui-tests.yml b/.github/workflows/ci-ui-tests.yml index 39c90d5097..b13272947f 100644 --- a/.github/workflows/ci-ui-tests.yml +++ b/.github/workflows/ci-ui-tests.yml @@ -12,7 +12,7 @@ env: jobs: tests: name: UI Tests - runs-on: macos-12 + runs-on: macos-14 concurrency: # Only allow a single run of this workflow on each branch, automatically cancelling older runs. diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml index 4f6a1b3e3e..e610628b45 100644 --- a/.github/workflows/release-alpha.yml +++ b/.github/workflows/release-alpha.yml @@ -17,7 +17,7 @@ jobs: if: contains(github.event.pull_request.labels.*.name, 'Trigger-PR-Build') name: Release - runs-on: macos-12 + runs-on: macos-14 concurrency: # Only allow a single run of this workflow on each branch, automatically cancelling older runs. From 0476ecec5cc01f16b9473e36ed228d8249e3dad2 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 19 Mar 2024 11:58:59 +0100 Subject: [PATCH 49/91] Update version to 2.7.3 --- Config/AppVersion.xcconfig | 2 +- towncrier.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index e00105df8c..a07aa00f82 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 2.7.2 +MARKETING_VERSION = 2.7.3 CURRENT_PROJECT_VERSION = 1 diff --git a/towncrier.toml b/towncrier.toml index 1e863f51a2..371e14b76d 100644 --- a/towncrier.toml +++ b/towncrier.toml @@ -1,6 +1,6 @@ [tool.towncrier] name = "Changes in" -version = "2.7.2" +version = "2.7.3" filename = "TCHAP_CHANGES.md" directory = "changelog.d" template = "changelog.d/_template.md.jinja" From c1036cb7bb795643305402a24d225bee75fbe7e9 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 13:05:57 +0200 Subject: [PATCH 50/91] Use the latest version of the sonarcloud github action --- .github/workflows/sonarcloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index f46144c760..d902ca1368 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -18,7 +18,7 @@ jobs: - name: Analyze with SonarCloud # You can pin the exact commit or the version. - uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049 + uses: SonarSource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate the token on Sonarcloud.io, add it to the secrets of this repo From b1c6ac435d9462406c8dbc36b5ed5e5559fa7cb1 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 13:29:27 +0200 Subject: [PATCH 51/91] Remove inherently broken tests --- .../NotificationSettingsViewModelTests.swift | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift index 95b5e08fad..b241dcfcee 100644 --- a/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift +++ b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift @@ -41,37 +41,6 @@ final class NotificationSettingsViewModelTests: XCTestCase { XCTAssertEqual(viewModel.viewState.selectionState[.encrypted], false) } - func testUpdateOneToOneRuleAlsoUpdatesPollRules() async { - setupWithPollRules() - - await viewModel.update(ruleID: .oneToOneRoom, isChecked: false) - - XCTAssertEqual(viewModel.viewState.selectionState.count, 8) - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOneRoom], false) - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollStart], false) - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollEnd], false) - - // unrelated poll rules stay the same - XCTAssertEqual(viewModel.viewState.selectionState[.allOtherMessages], true) - XCTAssertEqual(viewModel.viewState.selectionState[.pollStart], true) - XCTAssertEqual(viewModel.viewState.selectionState[.pollEnd], true) - } - - func testUpdateMessageRuleAlsoUpdatesPollRules() async { - setupWithPollRules() - - await viewModel.update(ruleID: .allOtherMessages, isChecked: false) - XCTAssertEqual(viewModel.viewState.selectionState.count, 8) - XCTAssertEqual(viewModel.viewState.selectionState[.allOtherMessages], false) - XCTAssertEqual(viewModel.viewState.selectionState[.pollStart], false) - XCTAssertEqual(viewModel.viewState.selectionState[.pollEnd], false) - - // unrelated poll rules stay the same - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOneRoom], true) - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollStart], true) - XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollEnd], true) - } - func testMismatchingRulesAreHandled() async { setupWithPollRules() From 608f760be83f24de87afbcd37b8080ec8ba574f7 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 19 Mar 2024 15:15:11 +0200 Subject: [PATCH 52/91] Switch UI tests to iPhone 15, fix the broken ones --- Gemfile.lock | 92 ++++++++++--------- Podfile.lock | 2 +- .../Modules/Common/Test/UI/XCUIElement.swift | 28 ++++++ .../Test/UI/UserOtherSessionsUITests.swift | 10 +- .../View/UserOtherSessionsToolbar.swift | 46 +++++----- .../Test/UI/UserSessionOverviewUITests.swift | 2 +- fastlane/Fastfile | 2 +- 7 files changed, 105 insertions(+), 77 deletions(-) create mode 100644 RiotSwiftUI/Modules/Common/Test/UI/XCUIElement.swift diff --git a/Gemfile.lock b/Gemfile.lock index 02bb363639..519e1f087e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,9 +7,11 @@ GIT GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml - activesupport (7.1.2) + activesupport (7.1.3.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -19,32 +21,32 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) - artifactory (3.0.15) + artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.859.0) - aws-sdk-core (3.188.0) - aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (1.899.0) + aws-sdk-core (3.191.4) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.73.0) - aws-sdk-core (~> 3, >= 3.188.0) + aws-sdk-kms (1.78.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.140.0) - aws-sdk-core (~> 3, >= 3.188.0) + aws-sdk-s3 (1.146.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.6) - aws-sigv4 (1.7.0) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) - bigdecimal (3.1.4) + bigdecimal (3.1.7) claide (1.1.0) clamp (1.3.2) cocoapods (1.14.3) @@ -88,20 +90,19 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.2.2) + concurrent-ruby (1.2.3) connection_pool (2.4.1) declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20231109) + domain_name (0.6.20240107) dotenv (2.8.1) - drb (2.2.0) - ruby2_keywords + drb (2.2.1) emoji_regex (3.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - excon (0.104.0) + excon (0.110.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -130,8 +131,8 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.7) - fastlane (2.217.0) + fastimage (2.3.0) + fastlane (2.219.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -150,6 +151,7 @@ GEM gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-env (>= 1.6.0, < 2.0.0) google-cloud-storage (~> 1.31) highline (~> 2.0) http-cookie (~> 1.0.5) @@ -158,7 +160,7 @@ GEM mini_magick (>= 4.9.4, < 5.0.0) multipart-post (>= 2.0.0, < 3.0.0) naturally (~> 2.2) - optparse (~> 0.1.1) + optparse (>= 0.1.1) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) @@ -172,7 +174,7 @@ GEM xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) fastlane-plugin-brew (0.1.1) - fastlane-plugin-sentry (1.16.0) + fastlane-plugin-sentry (1.20.0) os (~> 1.1, >= 1.1.4) fastlane-plugin-versioning (0.5.2) fastlane-plugin-xcodegen (1.1.0) @@ -181,9 +183,9 @@ GEM fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.53.0) + google-apis-androidpublisher_v3 (0.54.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.2) + google-apis-core (0.11.3) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -191,24 +193,23 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.a) rexml - webrick google-apis-iamcredentials_v1 (0.17.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.29.0) + google-apis-storage_v1 (0.31.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.6.0) - google-cloud-env (~> 1.0) + google-cloud-core (1.7.0) + google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.3.1) - google-cloud-storage (1.45.0) + google-cloud-errors (1.4.0) + google-cloud-storage (1.47.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.29.0) + google-apis-storage_v1 (~> 0.31.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -222,29 +223,31 @@ GEM http-cookie (1.0.5) domain_name (~> 0.5) httpclient (2.8.3) - i18n (1.14.1) + i18n (1.14.4) concurrent-ruby (~> 1.0) jmespath (1.6.2) - json (2.6.3) - jwt (2.7.1) + json (2.7.1) + jwt (2.8.1) + base64 mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.20.0) + minitest (5.22.3) molinillo (0.8.0) multi_json (1.15.0) - multipart-post (2.3.0) + multipart-post (2.4.0) mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) naturally (2.2.1) netrc (0.11.0) - nokogiri (1.15.5) + nkf (0.2.0) + nokogiri (1.15.6) mini_portile2 (~> 2.8.2) racc (~> 1.4) - optparse (0.1.1) + optparse (0.4.0) os (1.1.4) - plist (3.7.0) + plist (3.7.1) public_suffix (4.0.7) racc (1.7.3) rake (13.1.0) @@ -259,7 +262,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.18.0) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -278,7 +281,7 @@ GEM unicode-display_width (>= 1.1.1, < 3) trailblazer-option (0.1.2) tty-cursor (0.7.1) - tty-screen (0.8.1) + tty-screen (0.8.2) tty-spinner (0.9.3) tty-cursor (~> 0.7) typhoeus (1.4.1) @@ -287,12 +290,11 @@ GEM concurrent-ruby (~> 1.0) uber (0.1.0) unicode-display_width (2.5.0) - webrick (1.8.1) word_wrap (1.0.0) xcode-install (2.8.1) claide (>= 0.9.1) fastlane (>= 2.1.0, < 3.0.0) - xcodeproj (1.23.0) + xcodeproj (1.24.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/Podfile.lock b/Podfile.lock index abe637e538..8ca318a662 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -210,4 +210,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: c87b532985dd755b373732f841e3bcfe616f4e4f -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/RiotSwiftUI/Modules/Common/Test/UI/XCUIElement.swift b/RiotSwiftUI/Modules/Common/Test/UI/XCUIElement.swift new file mode 100644 index 0000000000..db41a603ef --- /dev/null +++ b/RiotSwiftUI/Modules/Common/Test/UI/XCUIElement.swift @@ -0,0 +1,28 @@ +// +// Copyright 2024 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 XCTest + +extension XCUIElement { + func forceTap() { + if isHittable { + tap() + } else { + let coordinate: XCUICoordinate = coordinate(withNormalizedOffset: .init(dx: 0.5, dy: 0.5)) + coordinate.tap() + } + } +} diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift index 71a6516592..3fcf2a8ccd 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift @@ -56,7 +56,7 @@ class UserOtherSessionsUITests: MockScreenTestCase { func test_whenOtherSessionsMoreMenuButtonSelected_moreMenuIsCorrect() { app.goToScreenWithIdentifier(MockUserOtherSessionsScreenState.all.title) - app.buttons["More"].tap() + app.buttons["More"].forceTap() XCTAssertTrue(app.buttons["Select sessions"].exists) XCTAssertTrue(app.buttons["Sign out of 6 sessions"].exists) } @@ -64,7 +64,7 @@ class UserOtherSessionsUITests: MockScreenTestCase { func test_whenOtherSessionsSelectSessionsSelected_navBarContainsCorrectButtons() { app.goToScreenWithIdentifier(MockUserOtherSessionsScreenState.all.title) - app.buttons["More"].tap() + app.buttons["More"].forceTap() app.buttons["Select sessions"].tap() let signOutButton = app.buttons["Sign out"] XCTAssertTrue(signOutButton.exists) @@ -76,7 +76,7 @@ class UserOtherSessionsUITests: MockScreenTestCase { func test_whenOtherSessionsSelectAllSelected_navBarContainsCorrectButtons() { app.goToScreenWithIdentifier(MockUserOtherSessionsScreenState.all.title) - app.buttons["More"].tap() + app.buttons["More"].forceTap() app.buttons["Select sessions"].tap() app.buttons["Select All"].tap() XCTAssertTrue(app.buttons["Deselect All"].exists) @@ -85,7 +85,7 @@ class UserOtherSessionsUITests: MockScreenTestCase { func test_whenAllOtherSessionsAreSelected_navBarContainsCorrectButtons() { app.goToScreenWithIdentifier(MockUserOtherSessionsScreenState.all.title) - app.buttons["More"].tap() + app.buttons["More"].forceTap() app.buttons["Select sessions"].tap() for i in 0...MockUserOtherSessionsScreenState.all.allSessions().count - 1 { app.buttons["UserSessionListItem_\(i)"].tap() @@ -95,7 +95,7 @@ class UserOtherSessionsUITests: MockScreenTestCase { func test_whenChangingSessionSelection_signOutButtonChangesItState() { app.goToScreenWithIdentifier(MockUserOtherSessionsScreenState.all.title) - app.buttons["More"].tap() + app.buttons["More"].forceTap() app.buttons["Select sessions"].tap() let signOutButton = app.buttons["Sign out"] XCTAssertTrue(signOutButton.exists) diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift index ba844904ec..39970240d9 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift @@ -80,35 +80,33 @@ struct UserOtherSessionsToolbar: ToolbarContent { } private func optionsMenu() -> some View { - Button { } label: { - Menu { - if showDeviceLogout { // As you can only sign out the selected sessions, we don't allow selection when you're unable to sign out devices. - Button { - isEditModeEnabled = true - } label: { - Label(VectorL10n.userOtherSessionMenuSelectSessions, systemImage: "checkmark.circle") - } - .disabled(sessionCount == 0) - } - + Menu { + if showDeviceLogout { // As you can only sign out the selected sessions, we don't allow selection when you're unable to sign out devices. Button { - isShowLocationEnabled.toggle() + isEditModeEnabled = true } label: { - Label(showLocationInfo: isShowLocationEnabled) - } - - if sessionCount > 0, showDeviceLogout { - DestructiveButton { - onSignOut() - } label: { - Label(VectorL10n.userOtherSessionMenuSignOutSessions(String(sessionCount)), systemImage: "rectangle.portrait.and.arrow.forward.fill") - } + Label(VectorL10n.userOtherSessionMenuSelectSessions, systemImage: "checkmark.circle") } + .disabled(sessionCount == 0) + } + + Button { + isShowLocationEnabled.toggle() } label: { - Image(systemName: "ellipsis") - .padding(.horizontal, 4) - .padding(.vertical, 12) + Label(showLocationInfo: isShowLocationEnabled) + } + + if sessionCount > 0, showDeviceLogout { + DestructiveButton { + onSignOut() + } label: { + Label(VectorL10n.userOtherSessionMenuSignOutSessions(String(sessionCount)), systemImage: "rectangle.portrait.and.arrow.forward.fill") + } } + } label: { + Image(systemName: "ellipsis") + .padding(.horizontal, 4) + .padding(.vertical, 12) } .accessibilityIdentifier("More") } diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift index 643c28cbe9..93938057ca 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift @@ -67,7 +67,7 @@ class UserSessionOverviewUITests: MockScreenTestCase { let navTitle = VectorL10n.userSessionOverviewSessionTitle let barButton = app.navigationBars[navTitle].buttons["Menu"] XCTAssertTrue(barButton.exists) - barButton.tap() + barButton.forceTap() XCTAssertTrue(app.buttons[VectorL10n.signOut].exists) XCTAssertTrue(app.buttons[VectorL10n.manageSessionRename].exists) } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index aea8743105..51e23fe9dc 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -197,7 +197,7 @@ platform :ios do run_tests( workspace: "Riot.xcworkspace", scheme: "RiotSwiftUITests", - device: "iPhone 14", + device: "iPhone 15", code_coverage: true, # Test result configuration result_bundle: true, From 094e4f16a5a65a403e99bed40f97d516be27bc42 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 25 Mar 2024 15:12:27 +0100 Subject: [PATCH 53/91] =?UTF-8?q?Initialise=20`antivirusServerUrl`=20?= =?UTF-8?q?=C3=A0=20la=20m=C3=AAme=20valeur=20que=20le=20homeServerUrl=20c?= =?UTF-8?q?omme=20sur=20Tchap=20Android?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/MatrixKit/Models/Account/MXKAccount.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index b67c5b78b6..8b297e221e 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -998,7 +998,11 @@ -(void)openSessionWithStore:(id)store // Enable the antivirus scanner in the current session. [mxSession setAntivirusServerURL:_antivirusServerURL]; } - + // Tchap: else hard code antivirus server URL with homeServer URL like in Tchap Android. + else { + [mxSession setAntivirusServerURL:self.mxCredentials.homeServer]; + } + // Set default MXEvent -> NSString formatter MXKEventFormatter *eventFormatter = [[MXKEventFormatter alloc] initWithMatrixSession:self.mxSession]; eventFormatter.isForSubtitle = YES; From 9f1dcc08acf591aed1920ac9098e11ba6e64b2b4 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 25 Mar 2024 15:12:27 +0100 Subject: [PATCH 54/91] =?UTF-8?q?Initialise=20`antivirusServerUrl`=20?= =?UTF-8?q?=C3=A0=20la=20m=C3=AAme=20valeur=20que=20le=20homeServerUrl=20c?= =?UTF-8?q?omme=20sur=20Tchap=20Android?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/MatrixKit/Models/Account/MXKAccount.m | 6 +++++- changelog.d/887.change | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog.d/887.change diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index b67c5b78b6..8b297e221e 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -998,7 +998,11 @@ -(void)openSessionWithStore:(id)store // Enable the antivirus scanner in the current session. [mxSession setAntivirusServerURL:_antivirusServerURL]; } - + // Tchap: else hard code antivirus server URL with homeServer URL like in Tchap Android. + else { + [mxSession setAntivirusServerURL:self.mxCredentials.homeServer]; + } + // Set default MXEvent -> NSString formatter MXKEventFormatter *eventFormatter = [[MXKEventFormatter alloc] initWithMatrixSession:self.mxSession]; eventFormatter.isForSubtitle = YES; diff --git a/changelog.d/887.change b/changelog.d/887.change new file mode 100644 index 0000000000..39f48c2176 --- /dev/null +++ b/changelog.d/887.change @@ -0,0 +1 @@ +Réactivation de l'antivirus \ No newline at end of file From 0eaf27735c76ee572bf8fd6a0041a60ff162afb4 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 26 Mar 2024 15:13:47 +0100 Subject: [PATCH 55/91] =?UTF-8?q?Rendre=20la=20"notification=20par=20email?= =?UTF-8?q?"=20disponible=20=C3=A0=20tout=20le=20monde.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tchap/Config/BuildSettings.swift | 2 +- changelog.d/995.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/995.change diff --git a/Tchap/Config/BuildSettings.swift b/Tchap/Config/BuildSettings.swift index 15bd01100e..af771f7e2e 100644 --- a/Tchap/Config/BuildSettings.swift +++ b/Tchap/Config/BuildSettings.swift @@ -269,7 +269,7 @@ final class BuildSettings: NSObject { static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ - "agent.dinum.tchap.gouv.fr" + "*" ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" diff --git a/changelog.d/995.change b/changelog.d/995.change new file mode 100644 index 0000000000..61281cbc49 --- /dev/null +++ b/changelog.d/995.change @@ -0,0 +1 @@ +La "notification par email" est rendue disponible à tout le monde. \ No newline at end of file From 73fcf2cfb402d94b697d8f41b40beb45a4fe80b6 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 26 Mar 2024 15:22:25 +0100 Subject: [PATCH 56/91] =?UTF-8?q?Utiliser=20la=20constante=20pr=C3=A9d?= =?UTF-8?q?=C3=A9finie=20`tchapFeatureAnyHomeServer`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tchap/Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tchap/Config/BuildSettings.swift b/Tchap/Config/BuildSettings.swift index af771f7e2e..740afb882f 100644 --- a/Tchap/Config/BuildSettings.swift +++ b/Tchap/Config/BuildSettings.swift @@ -269,7 +269,7 @@ final class BuildSettings: NSObject { static let tchapFeatureVideoOverIP = "tchapFeatureVideoOverIP" static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ - "*" + tchapFeatureAnyHomeServer ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" From d308851b48dfab6ab09847e938c0ec3e421201a0 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 26 Mar 2024 15:31:20 +0100 Subject: [PATCH 57/91] =?UTF-8?q?Possibilit=C3=A9=20de=20choisir=20=C3=A0?= =?UTF-8?q?=20la=20compilation=20entre=202=20provider=20de=20map=20(seul?= =?UTF-8?q?=20geo.data.gouv.fr=20est=20valid=C3=A9=20=C3=A0=20aujourd'hui)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Btchap/Config/BuildSettings.swift | 9 +++++++-- Config/BuildSettings.swift | 7 ++++++- DevTchap/Config/BuildSettings.swift | 7 ++++++- Tchap/Config/BuildSettings.swift | 7 ++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Btchap/Config/BuildSettings.swift b/Btchap/Config/BuildSettings.swift index f36a276640..32ddc2f784 100644 --- a/Btchap/Config/BuildSettings.swift +++ b/Btchap/Config/BuildSettings.swift @@ -414,8 +414,13 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! - + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! + static let locationSharingEnabled = true // MARK: - Voice Broadcast diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 62b061671b..9abdd1f5f4 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -423,7 +423,12 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! static let locationSharingEnabled = true diff --git a/DevTchap/Config/BuildSettings.swift b/DevTchap/Config/BuildSettings.swift index d064555b35..08f236910a 100644 --- a/DevTchap/Config/BuildSettings.swift +++ b/DevTchap/Config/BuildSettings.swift @@ -415,7 +415,12 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! static let locationSharingEnabled = true diff --git a/Tchap/Config/BuildSettings.swift b/Tchap/Config/BuildSettings.swift index 0c5d9ff411..21d774684a 100644 --- a/Tchap/Config/BuildSettings.swift +++ b/Tchap/Config/BuildSettings.swift @@ -456,7 +456,12 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! static let locationSharingEnabled = true From b6b765242ee30553d3ba600c6b590ad52388834a Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 27 Mar 2024 15:13:05 +0100 Subject: [PATCH 58/91] Bump analytics event to v0.15.0 --- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- Riot/Modules/Analytics/Analytics.swift | 14 ++++++++++++-- project.yml | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2f19e2ddc5..511ea29a7b 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-analytics-events", "state" : { - "revision" : "2f5fa5f1e2f6c6ae1a47c33d953a3ce289167eb0", - "version" : "0.5.0" + "revision" : "44d5a0e898a71f8abbbe12afe9d73e82d370a9a1", + "version" : "0.15.0" } }, { diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 1a30841b98..c04a291de3 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -275,8 +275,16 @@ extension Analytics { let event = AnalyticsEvent.Error( context: context, cryptoModule: .Rust, + cryptoSDK: AnalyticsEvent.Error.CryptoSDK.Rust, domain: .E2EE, - name: reason.errorName + // XXX not yet supported. + eventLocalAgeMillis: nil, + isFederated: nil, + isMatrixDotOrg: nil, + name: reason.errorName, + timeToDecryptMillis: nil, + userTrustsOwnIdentity: nil, + wasVisibleToUser: nil ) capture(event: event) } @@ -355,7 +363,8 @@ extension Analytics: MXAnalyticsDelegate { func trackCallError(with reason: __MXCallHangupReason, video isVideo: Bool, numberOfParticipants: Int, incoming isIncoming: Bool) { let callEvent = AnalyticsEvent.CallError(isVideo: isVideo, numParticipants: numberOfParticipants, placed: !isIncoming) - let event = AnalyticsEvent.Error(context: nil, cryptoModule: nil, domain: .VOIP, name: reason.errorName) + let event = AnalyticsEvent.Error(context: nil, cryptoModule: nil, cryptoSDK: nil, domain: .VOIP, eventLocalAgeMillis: nil, + isFederated: nil, isMatrixDotOrg: nil, name: reason.errorName, timeToDecryptMillis: nil, userTrustsOwnIdentity: nil, wasVisibleToUser: nil) capture(event: callEvent) capture(event: event) } @@ -386,6 +395,7 @@ extension Analytics: MXAnalyticsDelegate { let event = AnalyticsEvent.Composer(inThread: inThread, isEditing: isEditing, isReply: isReply, + messageType: AnalyticsEvent.Composer.MessageType.Text, startsThread: startsThread) capture(event: event) } diff --git a/project.yml b/project.yml index 3d410864a3..72c0ff8d41 100644 --- a/project.yml +++ b/project.yml @@ -45,7 +45,7 @@ include: packages: AnalyticsEvents: url: https://github.com/matrix-org/matrix-analytics-events - exactVersion: 0.5.0 + exactVersion: 0.15.0 Mapbox: url: https://github.com/maplibre/maplibre-gl-native-distribution minVersion: 5.12.2 From 6945e3fdd81ac6306c0bebe926e78b6baaffa300 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 27 Mar 2024 15:16:10 +0100 Subject: [PATCH 59/91] Update changelog --- changelog.d/7768.misc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.d/7768.misc diff --git a/changelog.d/7768.misc b/changelog.d/7768.misc new file mode 100644 index 0000000000..042654b879 --- /dev/null +++ b/changelog.d/7768.misc @@ -0,0 +1,2 @@ + +Update matrix-analytics-events to version 0.15.0 From 0d5380acab22259cd4b50569b48ed352e26130b0 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 27 Mar 2024 18:53:44 +0100 Subject: [PATCH 60/91] =?UTF-8?q?Ajout=20des=20textes=20d'alerte=20d'activ?= =?UTF-8?q?ation=20de=20la=20g=C3=A9olocalisation=20dans=20les=20targets?= =?UTF-8?q?=20Btchap=20et=20DevTchap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Btchap/SupportingFiles/Info.plist | 4 ++++ DevTchap/SupportingFiles/Info.plist | 4 ++++ changelog.d/998.change | 1 + 3 files changed, 9 insertions(+) create mode 100644 changelog.d/998.change diff --git a/Btchap/SupportingFiles/Info.plist b/Btchap/SupportingFiles/Info.plist index ec38ef38e4..c4cf1f06d9 100644 --- a/Btchap/SupportingFiles/Info.plist +++ b/Btchap/SupportingFiles/Info.plist @@ -53,6 +53,10 @@ In order to show who among your contacts already uses Tchap, we can exploit the e-mail addresses of your address book. These data will not be stored. For more information, please visit the privacy policy page in the app settings NSFaceIDUsageDescription Face ID is used to access your app. + NSLocationAlwaysAndWhenInUseUsageDescription + When you share your location to people, Tchap needs access to show them a map. + NSLocationWhenInUseUsageDescription + When you share your location to people, Tchap needs access to show them a map. NSMicrophoneUsageDescription Tchap needs to access your microphone to take videos, and record voice messages. NSPhotoLibraryUsageDescription diff --git a/DevTchap/SupportingFiles/Info.plist b/DevTchap/SupportingFiles/Info.plist index cbd3ec180b..d819fc0835 100644 --- a/DevTchap/SupportingFiles/Info.plist +++ b/DevTchap/SupportingFiles/Info.plist @@ -51,6 +51,10 @@ In order to show who among your contacts already uses Tchap, we can exploit the e-mail addresses of your address book. These data will not be stored. For more information, please visit the privacy policy page in the app settings NSFaceIDUsageDescription Face ID is used to access your app. + NSLocationAlwaysAndWhenInUseUsageDescription + When you share your location to people, Tchap needs access to show them a map. + NSLocationWhenInUseUsageDescription + When you share your location to people, Tchap needs access to show them a map. NSMicrophoneUsageDescription Tchap needs to access your microphone to take videos, and record voice messages. NSPhotoLibraryUsageDescription diff --git a/changelog.d/998.change b/changelog.d/998.change new file mode 100644 index 0000000000..c6978091c7 --- /dev/null +++ b/changelog.d/998.change @@ -0,0 +1 @@ +Ajout des textes d'alerte d'activation de la géolocalisation dans les targets Btchap et DevTchap \ No newline at end of file From 27e50958453fa801b22a0698e3a9b57ed7badae9 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 28 Mar 2024 18:10:55 +0100 Subject: [PATCH 61/91] =?UTF-8?q?Renommer=20la=20section=20"Alertes=20syst?= =?UTF-8?q?=C3=A8me"=20en=20"Tchap=20Annonces"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/Vector.strings | 2 +- Riot/Assets/fr.lproj/Vector.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index a0a040ef95..24297b0c71 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -378,7 +378,7 @@ "room_recents_conversations_section" = "ROOMS"; "room_recents_no_conversation" = "No rooms"; "room_recents_low_priority_section" = "LOW PRIORITY"; -"room_recents_server_notice_section" = "SYSTEM ALERTS"; +"room_recents_server_notice_section" = "Tchap Announcements"; // Tchap "room_recents_invites_section" = "INVITES"; "room_recents_suggested_rooms_section" = "SUGGESTED ROOMS"; "room_recents_start_chat_with" = "Start chat"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index 8685a163d0..4f5392ff72 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -551,7 +551,7 @@ "settings_labs_room_members_lazy_loading" = "Chargement différé des participants des salons"; "settings_labs_room_members_lazy_loading_error_message" = "Votre serveur d'accueil ne prend pas en charge le chargement différé des participants des salons. Réessayez plus tard."; "room_event_action_view_decrypted_source" = "Voir la source déchiffrée"; -"room_recents_server_notice_section" = "ALERTES SYSTÈME"; +"room_recents_server_notice_section" = "Tchap Annonces"; // Tchap "room_resource_limit_exceeded_message_contact_1" = " Veuillez "; "room_resource_limit_exceeded_message_contact_2_link" = "contacter l’administrateur de votre service"; "room_resource_limit_exceeded_message_contact_3" = " pour continuer à l’utiliser."; From 31a2b123abf40205fbd75bc1af387ef8383ed82a Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 28 Mar 2024 21:52:06 +0100 Subject: [PATCH 62/91] code review --- Riot/Modules/Analytics/Analytics.swift | 4 ++-- changelog.d/7768.misc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index c04a291de3..123b09cd5a 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -275,7 +275,7 @@ extension Analytics { let event = AnalyticsEvent.Error( context: context, cryptoModule: .Rust, - cryptoSDK: AnalyticsEvent.Error.CryptoSDK.Rust, + cryptoSDK: .Rust, domain: .E2EE, // XXX not yet supported. eventLocalAgeMillis: nil, @@ -395,7 +395,7 @@ extension Analytics: MXAnalyticsDelegate { let event = AnalyticsEvent.Composer(inThread: inThread, isEditing: isEditing, isReply: isReply, - messageType: AnalyticsEvent.Composer.MessageType.Text, + messageType: .Text, startsThread: startsThread) capture(event: event) } diff --git a/changelog.d/7768.misc b/changelog.d/7768.misc index 042654b879..053b12b375 100644 --- a/changelog.d/7768.misc +++ b/changelog.d/7768.misc @@ -1,2 +1 @@ - Update matrix-analytics-events to version 0.15.0 From 09af055fa6a4eb5aff0a183e19c836c1f24ba773 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 28 Mar 2024 22:38:57 +0100 Subject: [PATCH 63/91] rename changelog --- changelog.d/{7768.misc => pr-7768.misc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{7768.misc => pr-7768.misc} (100%) diff --git a/changelog.d/7768.misc b/changelog.d/pr-7768.misc similarity index 100% rename from changelog.d/7768.misc rename to changelog.d/pr-7768.misc From 95fd61f1016d28996c74ac65a621749f118145ec Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 29 Mar 2024 11:03:28 +0100 Subject: [PATCH 64/91] convert DecryptionFailureTracker to swift + tests --- Riot/Modules/Analytics/Analytics.swift | 55 +++-- .../Modules/Analytics/DecryptionFailure.swift | 5 +- .../Analytics/DecryptionFailureTracker.h | 55 ----- .../Analytics/DecryptionFailureTracker.m | 174 ---------------- .../Analytics/DecryptionFailureTracker.swift | 138 ++++++++++++ Riot/Modules/Application/LegacyAppDelegate.m | 1 - Riot/Utils/EventFormatter.m | 1 - RiotTests/DecryptionFailureTrackerTests.swift | 196 ++++++++++++++++++ RiotTests/FakeUtils.swift | 109 ++++++++++ 9 files changed, 479 insertions(+), 255 deletions(-) delete mode 100644 Riot/Modules/Analytics/DecryptionFailureTracker.h delete mode 100644 Riot/Modules/Analytics/DecryptionFailureTracker.m create mode 100644 Riot/Modules/Analytics/DecryptionFailureTracker.swift create mode 100644 RiotTests/DecryptionFailureTrackerTests.swift create mode 100644 RiotTests/FakeUtils.swift diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 123b09cd5a..849efd0b87 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -213,6 +213,38 @@ import AnalyticsEvents } } +@objc +protocol E2EAnalytics { + func trackE2EEError(_ reason: DecryptionFailureReason, context: String) +} + + +@objc extension Analytics: E2EAnalytics { + + /// Track an E2EE error that occurred + /// - Parameters: + /// - reason: The error that occurred. + /// - context: Additional context of the error that occured + func trackE2EEError(_ reason: DecryptionFailureReason, context: String) { + let event = AnalyticsEvent.Error( + context: context, + cryptoModule: .Rust, + cryptoSDK: AnalyticsEvent.Error.CryptoSDK.Rust, + domain: .E2EE, + // XXX not yet supported. + eventLocalAgeMillis: nil, + isFederated: nil, + isMatrixDotOrg: nil, + name: reason.errorName, + timeToDecryptMillis: nil, + userTrustsOwnIdentity: nil, + wasVisibleToUser: nil + ) + capture(event: event) + } + +} + // MARK: - Public tracking methods // The following methods are exposed for compatibility with Objective-C as // the `capture` method and the generated events cannot be bridged from Swift. @@ -266,28 +298,7 @@ extension Analytics { func trackInteraction(_ uiElement: AnalyticsUIElement) { trackInteraction(uiElement, interactionType: .Touch, index: nil) } - - /// Track an E2EE error that occurred - /// - Parameters: - /// - reason: The error that occurred. - /// - context: Additional context of the error that occured - func trackE2EEError(_ reason: DecryptionFailureReason, context: String) { - let event = AnalyticsEvent.Error( - context: context, - cryptoModule: .Rust, - cryptoSDK: .Rust, - domain: .E2EE, - // XXX not yet supported. - eventLocalAgeMillis: nil, - isFederated: nil, - isMatrixDotOrg: nil, - name: reason.errorName, - timeToDecryptMillis: nil, - userTrustsOwnIdentity: nil, - wasVisibleToUser: nil - ) - capture(event: event) - } + /// Track when a user becomes unauthenticated without pressing the `sign out` button. /// - Parameters: diff --git a/Riot/Modules/Analytics/DecryptionFailure.swift b/Riot/Modules/Analytics/DecryptionFailure.swift index 1c991db88f..b5804d258a 100644 --- a/Riot/Modules/Analytics/DecryptionFailure.swift +++ b/Riot/Modules/Analytics/DecryptionFailure.swift @@ -38,15 +38,16 @@ import AnalyticsEvents /// The id of the event that was unabled to decrypt. let failedEventId: String /// The time the failure has been reported. - let ts: TimeInterval = Date().timeIntervalSince1970 + let ts: TimeInterval /// Decryption failure reason. let reason: DecryptionFailureReason /// Additional context of failure let context: String - init(failedEventId: String, reason: DecryptionFailureReason, context: String) { + init(failedEventId: String, reason: DecryptionFailureReason, context: String, ts: TimeInterval) { self.failedEventId = failedEventId self.reason = reason self.context = context + self.ts = ts } } diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.h b/Riot/Modules/Analytics/DecryptionFailureTracker.h deleted file mode 100644 index b8f9ca467e..0000000000 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - 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 - -@class DecryptionFailureTracker; - -@class Analytics; -@import MatrixSDK; - -@interface DecryptionFailureTracker : NSObject - -/** - Returns the shared tracker. - - @return the shared tracker. - */ -+ (instancetype)sharedInstance; - -/** - The delegate object to receive analytics events. - */ -@property (nonatomic, weak) Analytics *delegate; - -/** - Report an event unable to decrypt. - - This error can be momentary. The DecryptionFailureTracker will check if it gets - fixed. Else, it will generate a failure (@see `trackFailures`). - - @param event the event. - @param roomState the room state when the event was received. - @param userId my user id. - */ -- (void)reportUnableToDecryptErrorForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState myUser:(NSString*)userId; - -/** - Flush current data. - */ -- (void)dispatch; - -@end diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.m b/Riot/Modules/Analytics/DecryptionFailureTracker.m deleted file mode 100644 index 4a749b71aa..0000000000 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.m +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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 "DecryptionFailureTracker.h" -#import "GeneratedInterface-Swift.h" - - -// Call `checkFailures` every `CHECK_INTERVAL` -#define CHECK_INTERVAL 2 - -// Give events a chance to be decrypted by waiting `GRACE_PERIOD` before counting -// and reporting them as failures -#define GRACE_PERIOD 4 - -// E2E failures analytics category. -NSString *const kDecryptionFailureTrackerAnalyticsCategory = @"e2e.failure"; - -@interface DecryptionFailureTracker() -{ - // Reported failures - // Every `CHECK_INTERVAL`, this list is checked for failures that happened - // more than`GRACE_PERIOD` ago. Those that did are reported to the delegate. - NSMutableDictionary *reportedFailures; - - // Event ids of failures that were tracked previously - NSMutableSet *trackedEvents; - - // Timer for periodic check - NSTimer *checkFailuresTimer; -} -@end - -@implementation DecryptionFailureTracker - -+ (instancetype)sharedInstance -{ - static DecryptionFailureTracker *sharedInstance = nil; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - sharedInstance = [[DecryptionFailureTracker alloc] init]; - }); - - return sharedInstance; -} - -- (instancetype)init -{ - self = [super init]; - if (self) - { - reportedFailures = [NSMutableDictionary dictionary]; - trackedEvents = [NSMutableSet set]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eventDidDecrypt:) name:kMXEventDidDecryptNotification object:nil]; - - checkFailuresTimer = [NSTimer scheduledTimerWithTimeInterval:CHECK_INTERVAL - target:self - selector:@selector(checkFailures) - userInfo:nil - repeats:YES]; - } - return self; -} - -- (void)reportUnableToDecryptErrorForEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState myUser:(NSString *)userId -{ - if (reportedFailures[event.eventId] || [trackedEvents containsObject:event.eventId]) - { - return; - } - - // Filter out "expected" UTDs - // We cannot decrypt messages sent before the user joined the room - MXRoomMember *myUser = [roomState.members memberWithUserId:userId]; - if (!myUser || myUser.membership != MXMembershipJoin) - { - return; - } - - NSString *failedEventId = event.eventId; - DecryptionFailureReason reason; - - // Categorise the error - switch (event.decryptionError.code) - { - case MXDecryptingErrorUnknownInboundSessionIdCode: - reason = DecryptionFailureReasonOlmKeysNotSent; - break; - - case MXDecryptingErrorOlmCode: - reason = DecryptionFailureReasonOlmIndexError; - break; - - default: - // All other error codes will be tracked as `OlmUnspecifiedError` and will include `context` containing - // the actual error code and localized description - reason = DecryptionFailureReasonUnspecified; - break; - } - - NSString *context = [NSString stringWithFormat:@"code: %ld, description: %@", event.decryptionError.code, event.decryptionError.localizedDescription]; - reportedFailures[event.eventId] = [[DecryptionFailure alloc] initWithFailedEventId:failedEventId - reason:reason - context:context]; -} - -- (void)dispatch -{ - [self checkFailures]; -} - -#pragma mark - Private methods - -/** - Mark reported failures that occured before tsNow - GRACE_PERIOD as failures that should be - tracked. - */ -- (void)checkFailures -{ - if (!_delegate) - { - return; - } - - NSTimeInterval tsNow = [NSDate date].timeIntervalSince1970; - - NSMutableArray *failuresToTrack = [NSMutableArray array]; - - for (DecryptionFailure *reportedFailure in reportedFailures.allValues) - { - if (reportedFailure.ts < tsNow - GRACE_PERIOD) - { - [failuresToTrack addObject:reportedFailure]; - [reportedFailures removeObjectForKey:reportedFailure.failedEventId]; - [trackedEvents addObject:reportedFailure.failedEventId]; - } - } - - if (failuresToTrack.count) - { - // Sort failures by error reason - NSMutableDictionary *failuresCounts = [NSMutableDictionary dictionary]; - for (DecryptionFailure *failure in failuresToTrack) - { - failuresCounts[@(failure.reason)] = @(failuresCounts[@(failure.reason)].unsignedIntegerValue + 1); - [self.delegate trackE2EEError:failure.reason context:failure.context]; - } - - MXLogDebug(@"[DecryptionFailureTracker] trackFailures: %@", failuresCounts); - } -} - -- (void)eventDidDecrypt:(NSNotification *)notif -{ - // Could be an event in the reportedFailures, remove it - MXEvent *event = notif.object; - [reportedFailures removeObjectForKey:event.eventId]; -} - -@end diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.swift b/Riot/Modules/Analytics/DecryptionFailureTracker.swift new file mode 100644 index 0000000000..f33f2b7c52 --- /dev/null +++ b/Riot/Modules/Analytics/DecryptionFailureTracker.swift @@ -0,0 +1,138 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + + +// Protocol to get the current time. Used for easy testing +protocol TimeProvider { + func nowTs() -> TimeInterval +} + +class DefaultTimeProvider: TimeProvider { + + func nowTs() -> TimeInterval { + return Date.now.timeIntervalSince1970 + } + +} + + +@objc +class DecryptionFailureTracker: NSObject { + + let GRACE_PERIOD: TimeInterval = 4 + // Call `checkFailures` every `CHECK_INTERVAL` + let CHECK_INTERVAL: TimeInterval = 2 + + @objc weak var delegate: E2EAnalytics? + + // Reported failures + var reportedFailures = [String /* eventId */: DecryptionFailure]() + + // Event ids of failures that were tracked previously + var trackedEvents = Set() + + var checkFailuresTimer: Timer? + + @objc static let sharedInstance = DecryptionFailureTracker() + + var timeProvider: TimeProvider = DefaultTimeProvider() + + override init() { + super.init() + + NotificationCenter.default.addObserver(self, + selector: #selector(eventDidDecrypt(_:)), + name: .mxEventDidDecrypt, + object: nil) + + Timer.scheduledTimer(withTimeInterval: CHECK_INTERVAL, repeats: true) { [weak self] _ in + self?.checkFailures() + } + } + + @objc + func reportUnableToDecryptError(forEvent event: MXEvent, withRoomState roomState: MXRoomState, myUser userId: String) { + if reportedFailures[event.eventId] != nil || trackedEvents.contains(event.eventId) { + return + } + + // Filter out "expected" UTDs + // We cannot decrypt messages sent before the user joined the room + guard let myUser = roomState.members.member(withUserId: userId) else { return } + if myUser.membership != MXMembership.join { + return + } + + guard let failedEventId = event.eventId else { return } + + guard let error = event.decryptionError as? NSError else { return } + + var reason = DecryptionFailureReason.unspecified + + if error.code == MXDecryptingErrorUnknownInboundSessionIdCode.rawValue { + reason = DecryptionFailureReason.olmKeysNotSent + } else if error.code == MXDecryptingErrorOlmCode.rawValue { + reason = DecryptionFailureReason.olmIndexError + } + + let context = String(format: "code: %ld, description: %@", error.code, event.decryptionError.localizedDescription) + + reportedFailures[failedEventId] = DecryptionFailure(failedEventId: failedEventId, reason: reason, context: context, ts: self.timeProvider.nowTs()) + } + + @objc + func dispatch() { + self.checkFailures() + } + + @objc + func eventDidDecrypt(_ notification: Notification) { + guard let event = notification.object as? MXEvent else { return } + + // Could be an event in the reportedFailures, remove it + reportedFailures.removeValue(forKey: event.eventId) + } + + /** + Mark reported failures that occured before tsNow - GRACE_PERIOD as failures that should be + tracked. + */ + @objc + func checkFailures() { + guard let delegate = self.delegate else {return} + + + let tsNow = self.timeProvider.nowTs() + var failuresToCheck = [DecryptionFailure]() + + for reportedFailure in self.reportedFailures.values { + let ellapsed = tsNow - reportedFailure.ts + if ellapsed > GRACE_PERIOD { + failuresToCheck.append(reportedFailure) + reportedFailures.removeValue(forKey: reportedFailure.failedEventId) + trackedEvents.insert(reportedFailure.failedEventId) + } + } + + for failure in failuresToCheck { + delegate.trackE2EEError(failure.reason, context: failure.context) + } + + } + +} diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index ab17eeac5c..79d263cef1 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -33,7 +33,6 @@ #import "ContactDetailsViewController.h" #import "BugReportViewController.h" -#import "DecryptionFailureTracker.h" #import "Tools.h" #import "WidgetManager.h" diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index d25655a226..4494bdbb2d 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -23,7 +23,6 @@ #import "WidgetManager.h" #import "MXDecryptionResult.h" -#import "DecryptionFailureTracker.h" #import diff --git a/RiotTests/DecryptionFailureTrackerTests.swift b/RiotTests/DecryptionFailureTrackerTests.swift new file mode 100644 index 0000000000..9b5fe94ea4 --- /dev/null +++ b/RiotTests/DecryptionFailureTrackerTests.swift @@ -0,0 +1,196 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +import XCTest +@testable import Element + + +class DecryptionFailureTrackerTests: XCTestCase { + + class TimeShifter: TimeProvider { + + var timestamp = TimeInterval(0) + + func nowTs() -> TimeInterval { + return timestamp + } + } + + class AnalyticsDelegate : E2EAnalytics { + var reportedFailure: Element.DecryptionFailureReason?; + + func trackE2EEError(_ reason: Element.DecryptionFailureReason, context: String) { + print("Error Tracked: ", reason) + reportedFailure = reason + } + + } + + let timeShifter = TimeShifter() + + func test_grace_period() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + timeShifter.timestamp = TimeInterval(2) + + decryptionFailureTracker.checkFailures(); + + XCTAssertNil(testDelegate.reportedFailure); + + // Pass the grace period + timeShifter.timestamp = TimeInterval(5) + + decryptionFailureTracker.checkFailures(); + + XCTAssertEqual(testDelegate.reportedFailure, DecryptionFailureReason.olmKeysNotSent); + } + + func test_do_not_double_report() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Pass the grace period + timeShifter.timestamp = TimeInterval(5) + + decryptionFailureTracker.checkFailures(); + + XCTAssertEqual(testDelegate.reportedFailure, DecryptionFailureReason.olmKeysNotSent); + + // Try to report again the same event + testDelegate.reportedFailure = nil + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + // Pass the grace period + timeShifter.timestamp = TimeInterval(10) + + decryptionFailureTracker.checkFailures(); + + XCTAssertNil(testDelegate.reportedFailure); + } + + + func test_ignore_not_member() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + let fakeMembers = FakeRoomMembers() + fakeMembers.mockMembers[myUser] = MXMembership.ban + fakeRoomState.mockMembers = fakeMembers + + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Pass the grace period + timeShifter.timestamp = TimeInterval(5) + + decryptionFailureTracker.checkFailures(); + + XCTAssertNil(testDelegate.reportedFailure); + } + + + + func test_notification_center() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Shift time below GRACE_PERIOD + timeShifter.timestamp = TimeInterval(2) + + // Simulate event gets decrypted + NotificationCenter.default.post(name: .mxEventDidDecrypt, object: fakeEvent) + + + // Shift time after GRACE_PERIOD + timeShifter.timestamp = TimeInterval(6) + + + decryptionFailureTracker.checkFailures(); + + // Event should have been graced + XCTAssertNil(testDelegate.reportedFailure); + } + +} + diff --git a/RiotTests/FakeUtils.swift b/RiotTests/FakeUtils.swift new file mode 100644 index 0000000000..7bd350e4bc --- /dev/null +++ b/RiotTests/FakeUtils.swift @@ -0,0 +1,109 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + + +class FakeEvent: MXEvent { + + var mockEventId: String; + var mockSender: String!; + var mockDecryptionError: Error? + + init(id: String) { + mockEventId = id + super.init() + } + + required init?(coder: NSCoder) { + fatalError() + } + + override var sender: String! { + get { return mockSender } + set { mockSender = newValue } + } + + override var eventId: String! { + get { return mockEventId } + set { mockEventId = newValue } + } + + override var decryptionError: Error? { + get { return mockDecryptionError } + set { mockDecryptionError = newValue } + } + +} + + +class FakeRoomState: MXRoomState { + + var mockMembers: MXRoomMembers? + + override var members: MXRoomMembers? { + get { return mockMembers } + set { mockMembers = newValue } + } + +} + +class FakeRoomMember: MXRoomMember { + var mockMembership: MXMembership = MXMembership.join + var mockUserId: String! + var mockMembers: MXRoomMembers? = FakeRoomMembers() + + init(mockUserId: String!) { + self.mockUserId = mockUserId + super.init() + } + + override var membership: MXMembership { + get { return mockMembership } + set { mockMembership = newValue } + } + + override var userId: String!{ + get { return mockUserId } + set { mockUserId = newValue } + } + +} + + +class FakeRoomMembers: MXRoomMembers { + + var mockMembers = [String : MXMembership]() + + init(joined: [String] = [String]()) { + for userId in joined { + self.mockMembers[userId] = MXMembership.join + } + super.init() + } + + override func member(withUserId userId: String!) -> MXRoomMember? { + let membership = mockMembers[userId] + if membership != nil { + let mockMember = FakeRoomMember(mockUserId: userId) + mockMember.mockMembership = membership! + return mockMember + } else { + return nil + } + } + +} From 0a6528703d987efe993ffec945fb18ec9348f24a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 29 Mar 2024 18:14:15 +0100 Subject: [PATCH 65/91] DecryptionTracker: Permanent vs Temporary UTD --- Riot/Modules/Analytics/Analytics.swift | 19 +-- .../DecryptionFailure+Analytics.swift | 44 ++++++ .../Modules/Analytics/DecryptionFailure.swift | 3 + .../Analytics/DecryptionFailureTracker.swift | 52 +++++- RiotTests/DecryptionFailureTrackerTests.swift | 148 +++++++++++++++++- 5 files changed, 235 insertions(+), 31 deletions(-) create mode 100644 Riot/Modules/Analytics/DecryptionFailure+Analytics.swift diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 849efd0b87..d9d68e2f85 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -215,7 +215,7 @@ import AnalyticsEvents @objc protocol E2EAnalytics { - func trackE2EEError(_ reason: DecryptionFailureReason, context: String) + func trackE2EEError(_ failure: DecryptionFailure) } @@ -225,21 +225,8 @@ protocol E2EAnalytics { /// - Parameters: /// - reason: The error that occurred. /// - context: Additional context of the error that occured - func trackE2EEError(_ reason: DecryptionFailureReason, context: String) { - let event = AnalyticsEvent.Error( - context: context, - cryptoModule: .Rust, - cryptoSDK: AnalyticsEvent.Error.CryptoSDK.Rust, - domain: .E2EE, - // XXX not yet supported. - eventLocalAgeMillis: nil, - isFederated: nil, - isMatrixDotOrg: nil, - name: reason.errorName, - timeToDecryptMillis: nil, - userTrustsOwnIdentity: nil, - wasVisibleToUser: nil - ) + func trackE2EEError(_ failure: DecryptionFailure) { + let event = failure.toAnalyticsEvent() capture(event: event) } diff --git a/Riot/Modules/Analytics/DecryptionFailure+Analytics.swift b/Riot/Modules/Analytics/DecryptionFailure+Analytics.swift new file mode 100644 index 0000000000..cd129aee35 --- /dev/null +++ b/Riot/Modules/Analytics/DecryptionFailure+Analytics.swift @@ -0,0 +1,44 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import AnalyticsEvents + +extension DecryptionFailure { + + public func toAnalyticsEvent() -> AnalyticsEvent.Error { + + let timeToDecryptMillis: Int = if self.timeToDecrypt != nil { + Int(self.timeToDecrypt! * 1000) + } else { + -1 + } + return AnalyticsEvent.Error( + context: self.context, + cryptoModule: .Rust, + cryptoSDK: .Rust, + domain: .E2EE, + + eventLocalAgeMillis: nil, + isFederated: nil, + isMatrixDotOrg: nil, + name: self.reason.errorName, + timeToDecryptMillis: timeToDecryptMillis, + userTrustsOwnIdentity: nil, + wasVisibleToUser: nil + ) + } +} diff --git a/Riot/Modules/Analytics/DecryptionFailure.swift b/Riot/Modules/Analytics/DecryptionFailure.swift index b5804d258a..9e0ca57858 100644 --- a/Riot/Modules/Analytics/DecryptionFailure.swift +++ b/Riot/Modules/Analytics/DecryptionFailure.swift @@ -44,6 +44,9 @@ import AnalyticsEvents /// Additional context of failure let context: String + /// UTDs can be permanent or temporary. If temporary, this field will contain the time it took to decrypt the message in milliseconds. If permanent should be nil + var timeToDecrypt: TimeInterval? + init(failedEventId: String, reason: DecryptionFailureReason, context: String, ts: TimeInterval) { self.failedEventId = failedEventId self.reason = reason diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.swift b/Riot/Modules/Analytics/DecryptionFailureTracker.swift index f33f2b7c52..19b8afb19c 100644 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.swift +++ b/Riot/Modules/Analytics/DecryptionFailureTracker.swift @@ -36,7 +36,10 @@ class DecryptionFailureTracker: NSObject { let GRACE_PERIOD: TimeInterval = 4 // Call `checkFailures` every `CHECK_INTERVAL` - let CHECK_INTERVAL: TimeInterval = 2 + let CHECK_INTERVAL: TimeInterval = 15 + + // The maximum time to wait for a late decryption before reporting as permanent UTD + let MAX_WAIT_FOR_LATE_DECRYPTION: TimeInterval = 60 @objc weak var delegate: E2EAnalytics? @@ -60,9 +63,6 @@ class DecryptionFailureTracker: NSObject { name: .mxEventDidDecrypt, object: nil) - Timer.scheduledTimer(withTimeInterval: CHECK_INTERVAL, repeats: true) { [weak self] _ in - self?.checkFailures() - } } @objc @@ -93,6 +93,14 @@ class DecryptionFailureTracker: NSObject { let context = String(format: "code: %ld, description: %@", error.code, event.decryptionError.localizedDescription) reportedFailures[failedEventId] = DecryptionFailure(failedEventId: failedEventId, reason: reason, context: context, ts: self.timeProvider.nowTs()) + + // Start the ticker if needed. There is no need to have a ticker if no failures are tracked + if checkFailuresTimer == nil { + self.checkFailuresTimer = Timer.scheduledTimer(withTimeInterval: CHECK_INTERVAL, repeats: true) { [weak self] _ in + self?.checkFailures() + } + } + } @objc @@ -104,8 +112,30 @@ class DecryptionFailureTracker: NSObject { func eventDidDecrypt(_ notification: Notification) { guard let event = notification.object as? MXEvent else { return } - // Could be an event in the reportedFailures, remove it + guard let reportedFailure = self.reportedFailures[event.eventId] else { return } + + let now = self.timeProvider.nowTs() + let ellapsedTime = now - reportedFailure.ts + + if ellapsedTime < 4 { + // event is graced + reportedFailures.removeValue(forKey: event.eventId) + } else { + // It's a late decrypt must be reported as a late decrypt + reportedFailure.timeToDecrypt = ellapsedTime + self.delegate?.trackE2EEError(reportedFailure) + } + // Remove from reported failures + self.trackedEvents.insert(event.eventId) reportedFailures.removeValue(forKey: event.eventId) + + // Check if we still need the ticker timer + if reportedFailures.isEmpty { + // Invalidate the current timer, nothing to check for + self.checkFailuresTimer?.invalidate() + self.checkFailuresTimer = nil + } + } /** @@ -116,23 +146,29 @@ class DecryptionFailureTracker: NSObject { func checkFailures() { guard let delegate = self.delegate else {return} - let tsNow = self.timeProvider.nowTs() var failuresToCheck = [DecryptionFailure]() for reportedFailure in self.reportedFailures.values { let ellapsed = tsNow - reportedFailure.ts - if ellapsed > GRACE_PERIOD { + if ellapsed > MAX_WAIT_FOR_LATE_DECRYPTION { failuresToCheck.append(reportedFailure) + reportedFailure.timeToDecrypt = nil reportedFailures.removeValue(forKey: reportedFailure.failedEventId) trackedEvents.insert(reportedFailure.failedEventId) } } for failure in failuresToCheck { - delegate.trackE2EEError(failure.reason, context: failure.context) + delegate.trackE2EEError(failure) } + // Check if we still need the ticker timer + if reportedFailures.isEmpty { + // Invalidate the current timer, nothing to check for + self.checkFailuresTimer?.invalidate() + self.checkFailuresTimer = nil + } } } diff --git a/RiotTests/DecryptionFailureTrackerTests.swift b/RiotTests/DecryptionFailureTrackerTests.swift index 9b5fe94ea4..3175ef19e4 100644 --- a/RiotTests/DecryptionFailureTrackerTests.swift +++ b/RiotTests/DecryptionFailureTrackerTests.swift @@ -32,10 +32,9 @@ class DecryptionFailureTrackerTests: XCTestCase { } class AnalyticsDelegate : E2EAnalytics { - var reportedFailure: Element.DecryptionFailureReason?; + var reportedFailure: Element.DecryptionFailure?; - func trackE2EEError(_ reason: Element.DecryptionFailureReason, context: String) { - print("Error Tracked: ", reason) + func trackE2EEError(_ reason: Element.DecryptionFailure) { reportedFailure = reason } @@ -66,6 +65,9 @@ class DecryptionFailureTrackerTests: XCTestCase { timeShifter.timestamp = TimeInterval(2) + // simulate decrypted in the grace period + NotificationCenter.default.post(name: .mxEventDidDecrypt, object: fakeEvent) + decryptionFailureTracker.checkFailures(); XCTAssertNil(testDelegate.reportedFailure); @@ -73,11 +75,71 @@ class DecryptionFailureTrackerTests: XCTestCase { // Pass the grace period timeShifter.timestamp = TimeInterval(5) + decryptionFailureTracker.checkFailures(); + XCTAssertNil(testDelegate.reportedFailure); + + } + + func test_report_ratcheted_key_utd() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorOlmCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Pass the max period + timeShifter.timestamp = TimeInterval(70) + + decryptionFailureTracker.checkFailures(); + + XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmIndexError); + } + + func test_report_unspecified_error() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorBadRoomCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Pass the max period + timeShifter.timestamp = TimeInterval(70) + decryptionFailureTracker.checkFailures(); - XCTAssertEqual(testDelegate.reportedFailure, DecryptionFailureReason.olmKeysNotSent); + XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.unspecified); } + + func test_do_not_double_report() { let myUser = "test@example.com"; @@ -100,12 +162,12 @@ class DecryptionFailureTrackerTests: XCTestCase { decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); - // Pass the grace period - timeShifter.timestamp = TimeInterval(5) + // Pass the max period + timeShifter.timestamp = TimeInterval(70) decryptionFailureTracker.checkFailures(); - XCTAssertEqual(testDelegate.reportedFailure, DecryptionFailureReason.olmKeysNotSent); + XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmKeysNotSent); // Try to report again the same event testDelegate.reportedFailure = nil @@ -192,5 +254,77 @@ class DecryptionFailureTrackerTests: XCTestCase { XCTAssertNil(testDelegate.reportedFailure); } + + func test_should_report_late_decrypt() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Simulate succesful decryption after grace period but before max wait + timeShifter.timestamp = TimeInterval(20) + + // Simulate event gets decrypted + NotificationCenter.default.post(name: .mxEventDidDecrypt, object: fakeEvent) + + + decryptionFailureTracker.checkFailures(); + + // Event should have been reported as a late decrypt + XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmKeysNotSent); + XCTAssertEqual(testDelegate.reportedFailure?.timeToDecrypt, TimeInterval(20)); + + } + + + + func test_should_report_permanent_decryption_error() { + + let myUser = "test@example.com"; + + let decryptionFailureTracker = DecryptionFailureTracker(); + decryptionFailureTracker.timeProvider = timeShifter; + + let testDelegate = AnalyticsDelegate(); + + decryptionFailureTracker.delegate = testDelegate; + + timeShifter.timestamp = TimeInterval(0) + + let fakeEvent = FakeEvent(id: "$0000"); + fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue)) + + + let fakeRoomState = FakeRoomState(); + fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser]) + + decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, myUser: myUser); + + // Simulate succesful decryption after max wait + timeShifter.timestamp = TimeInterval(70) + + decryptionFailureTracker.checkFailures(); + + // Event should have been reported as a late decrypt + XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmKeysNotSent); + XCTAssertNil(testDelegate.reportedFailure?.timeToDecrypt); + + } } From 1d633e8fa5dcdf20ff113502661dcf4dafa115f6 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 29 Mar 2024 18:21:56 +0100 Subject: [PATCH 66/91] Add more test for convertion to analytics error --- RiotTests/DecryptionFailureTrackerTests.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RiotTests/DecryptionFailureTrackerTests.swift b/RiotTests/DecryptionFailureTrackerTests.swift index 3175ef19e4..7cd9bf480f 100644 --- a/RiotTests/DecryptionFailureTrackerTests.swift +++ b/RiotTests/DecryptionFailureTrackerTests.swift @@ -290,6 +290,11 @@ class DecryptionFailureTrackerTests: XCTestCase { XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmKeysNotSent); XCTAssertEqual(testDelegate.reportedFailure?.timeToDecrypt, TimeInterval(20)); + // Assert that it's converted to millis for reporting + let analyticsError = testDelegate.reportedFailure!.toAnalyticsEvent() + + XCTAssertEqual(analyticsError.timeToDecryptMillis, 20000) + } @@ -325,6 +330,12 @@ class DecryptionFailureTrackerTests: XCTestCase { XCTAssertEqual(testDelegate.reportedFailure?.reason, DecryptionFailureReason.olmKeysNotSent); XCTAssertNil(testDelegate.reportedFailure?.timeToDecrypt); + + // Assert that it's converted to -1 for reporting + let analyticsError = testDelegate.reportedFailure!.toAnalyticsEvent() + + XCTAssertEqual(analyticsError.timeToDecryptMillis, -1) + } } From 56e66539d87f3a6cef6cc0343ce9e6021d166692 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 2 Apr 2024 11:13:10 +0200 Subject: [PATCH 67/91] post merge fix --- .../Analytics/DecryptionFailureTracker.m | 174 ------------------ 1 file changed, 174 deletions(-) delete mode 100644 Riot/Modules/Analytics/DecryptionFailureTracker.m diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.m b/Riot/Modules/Analytics/DecryptionFailureTracker.m deleted file mode 100644 index 86b847f221..0000000000 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.m +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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 "DecryptionFailureTracker.h" -#import "GeneratedInterface-Swift.h" - - -// Call `checkFailures` every `CHECK_INTERVAL` -#define CHECK_INTERVAL 10 - -// Give events a chance to be decrypted by waiting `GRACE_PERIOD` before counting -// and reporting them as failures -#define GRACE_PERIOD 30 - -// E2E failures analytics category. -NSString *const kDecryptionFailureTrackerAnalyticsCategory = @"e2e.failure"; - -@interface DecryptionFailureTracker() -{ - // Reported failures - // Every `CHECK_INTERVAL`, this list is checked for failures that happened - // more than`GRACE_PERIOD` ago. Those that did are reported to the delegate. - NSMutableDictionary *reportedFailures; - - // Event ids of failures that were tracked previously - NSMutableSet *trackedEvents; - - // Timer for periodic check - NSTimer *checkFailuresTimer; -} -@end - -@implementation DecryptionFailureTracker - -+ (instancetype)sharedInstance -{ - static DecryptionFailureTracker *sharedInstance = nil; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - sharedInstance = [[DecryptionFailureTracker alloc] init]; - }); - - return sharedInstance; -} - -- (instancetype)init -{ - self = [super init]; - if (self) - { - reportedFailures = [NSMutableDictionary dictionary]; - trackedEvents = [NSMutableSet set]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eventDidDecrypt:) name:kMXEventDidDecryptNotification object:nil]; - - checkFailuresTimer = [NSTimer scheduledTimerWithTimeInterval:CHECK_INTERVAL - target:self - selector:@selector(checkFailures) - userInfo:nil - repeats:YES]; - } - return self; -} - -- (void)reportUnableToDecryptErrorForEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState myUser:(NSString *)userId -{ - if (reportedFailures[event.eventId] || [trackedEvents containsObject:event.eventId]) - { - return; - } - - // Filter out "expected" UTDs - // We cannot decrypt messages sent before the user joined the room - MXRoomMember *myUser = [roomState.members memberWithUserId:userId]; - if (!myUser || myUser.membership != MXMembershipJoin) - { - return; - } - - NSString *failedEventId = event.eventId; - DecryptionFailureReason reason; - - // Categorise the error - switch (event.decryptionError.code) - { - case MXDecryptingErrorUnknownInboundSessionIdCode: - reason = DecryptionFailureReasonOlmKeysNotSent; - break; - - case MXDecryptingErrorOlmCode: - reason = DecryptionFailureReasonOlmIndexError; - break; - - default: - // All other error codes will be tracked as `OlmUnspecifiedError` and will include `context` containing - // the actual error code and localized description - reason = DecryptionFailureReasonUnspecified; - break; - } - - NSString *context = [NSString stringWithFormat:@"code: %ld, description: %@", event.decryptionError.code, event.decryptionError.localizedDescription]; - reportedFailures[event.eventId] = [[DecryptionFailure alloc] initWithFailedEventId:failedEventId - reason:reason - context:context]; -} - -- (void)dispatch -{ - [self checkFailures]; -} - -#pragma mark - Private methods - -/** - Mark reported failures that occured before tsNow - GRACE_PERIOD as failures that should be - tracked. - */ -- (void)checkFailures -{ - if (!_delegate) - { - return; - } - - NSTimeInterval tsNow = [NSDate date].timeIntervalSince1970; - - NSMutableArray *failuresToTrack = [NSMutableArray array]; - - for (DecryptionFailure *reportedFailure in reportedFailures.allValues) - { - if (reportedFailure.ts < tsNow - GRACE_PERIOD) - { - [failuresToTrack addObject:reportedFailure]; - [reportedFailures removeObjectForKey:reportedFailure.failedEventId]; - [trackedEvents addObject:reportedFailure.failedEventId]; - } - } - - if (failuresToTrack.count) - { - // Sort failures by error reason - NSMutableDictionary *failuresCounts = [NSMutableDictionary dictionary]; - for (DecryptionFailure *failure in failuresToTrack) - { - failuresCounts[@(failure.reason)] = @(failuresCounts[@(failure.reason)].unsignedIntegerValue + 1); - [self.delegate trackE2EEError:failure.reason context:failure.context]; - } - - MXLogDebug(@"[DecryptionFailureTracker] trackFailures: %@", failuresCounts); - } -} - -- (void)eventDidDecrypt:(NSNotification *)notif -{ - // Could be an event in the reportedFailures, remove it - MXEvent *event = notif.object; - [reportedFailures removeObjectForKey:event.eventId]; -} - -@end From cc068abe56f69518aba37bbd248a6e841de73781 Mon Sep 17 00:00:00 2001 From: Maksim Kliazovich Date: Tue, 26 Mar 2024 00:51:32 +0000 Subject: [PATCH 68/91] Translated using Weblate (Belarusian) Currently translated at 0.2% (5 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/be/ --- Riot/Assets/be.lproj/Vector.strings | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Riot/Assets/be.lproj/Vector.strings b/Riot/Assets/be.lproj/Vector.strings index 8b13789179..64295bad49 100644 --- a/Riot/Assets/be.lproj/Vector.strings +++ b/Riot/Assets/be.lproj/Vector.strings @@ -1 +1,9 @@ + + +// Titles +"title_home" = "Галоўная"; +"people_empty_view_title" = "Удзельнікі"; +"group_details_home" = "Галоўная"; +"spaces_home_space_title" = "Галоўная"; +"title_people" = "Удзельнікі"; From a92c842df287d1d3a37d880fa5997519d7a9b370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 1 Apr 2024 06:33:55 +0000 Subject: [PATCH 69/91] Translated using Weblate (Estonian) Currently translated at 100.0% (2416 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ --- Riot/Assets/et.lproj/Vector.strings | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings index 3df4d23b9b..22e9f34192 100644 --- a/Riot/Assets/et.lproj/Vector.strings +++ b/Riot/Assets/et.lproj/Vector.strings @@ -1889,8 +1889,8 @@ "notice_conference_call_started" = "VoIP rühmakõne algas"; "notice_conference_call_finished" = "VoIP rühmakõne lõppes"; // Notice Events with "You" -"notice_room_invite_by_you" = "Sina kutsusid kasutajat %@"; -"notice_room_invite_you" = "%@ kutsus sind"; +"notice_room_invite_by_you" = "Sina saatsid kutse kasutajale %@"; +"notice_room_invite_you" = "%@ saatis sulle kutse"; "notice_room_third_party_invite_by_you" = "Sina saatsid kasutajale %@ kutse jututoaga liitumiseks"; "notice_room_third_party_registered_invite_by_you" = "Sina võtsid vastu kutse %@ nimel"; "notice_room_third_party_revoked_invite_by_you" = "Sina võtsid tagasi jututoaga liitumise kutse kasutajalt %@"; @@ -2025,7 +2025,7 @@ "notice_room_third_party_invite_for_dm" = "%@ saatis kutse kasutajale %@"; "notice_room_third_party_revoked_invite_for_dm" = "%@ võttis tagasi kasutaja %@ kutse"; "notice_room_name_changed_for_dm" = "%@ muutis jututoa uueks nimeks %@."; -"notice_room_third_party_invite_by_you_for_dm" = "Sina kutsusid kasutajat %@"; +"notice_room_third_party_invite_by_you_for_dm" = "Sina saatsid kutse kasutajale %@"; "notice_room_third_party_revoked_invite_by_you_for_dm" = "Sina võtsid tagasi kasutaja %@ kutse"; "notice_room_name_changed_by_you_for_dm" = "Sa muutsid jututoa uueks nimeks %@."; "notice_room_name_removed_by_you_for_dm" = "Sa eemaldasid jututoa nime"; From 487a4f7bdaa5ee7fdd1146f47255b977b43d56e2 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 2 Apr 2024 11:58:49 +0200 Subject: [PATCH 70/91] version++ --- CHANGES.md | 7 +++++++ changelog.d/pr-7768.misc | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) delete mode 100644 changelog.d/pr-7768.misc diff --git a/CHANGES.md b/CHANGES.md index 174be9ac8a..0856778379 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +## Changes in 1.11.9 (2024-04-02) + +Others + +- Update matrix-analytics-events to version 0.15.0 ([#7768](https://github.com/element-hq/element-ios/pull/7768)) + + ## Changes in 1.11.8 (2024-03-05) 🙌 Improvements diff --git a/changelog.d/pr-7768.misc b/changelog.d/pr-7768.misc deleted file mode 100644 index 053b12b375..0000000000 --- a/changelog.d/pr-7768.misc +++ /dev/null @@ -1 +0,0 @@ -Update matrix-analytics-events to version 0.15.0 From c2b17a0ef99fbfc79f29487b7aadcdd5fc232dcb Mon Sep 17 00:00:00 2001 From: Mauro <34335419+Velin92@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:02:12 +0200 Subject: [PATCH 71/91] Update CHANGES.md --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 0856778379..eb5267b66d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,8 @@ Others - Update matrix-analytics-events to version 0.15.0 ([#7768](https://github.com/element-hq/element-ios/pull/7768)) +- Upgrade to build with Xcode 15.2 +- Add a privacy manifest ## Changes in 1.11.8 (2024-03-05) From 24f1fb59bfec67029ed3c7216dad851578fba991 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 2 Apr 2024 15:06:22 +0200 Subject: [PATCH 72/91] finish version++ --- Podfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 8ca318a662..07f1fb4d9f 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -25,7 +25,7 @@ PODS: - GBDeviceInfo (7.1.0): - GBDeviceInfo/Core (= 7.1.0) - GBDeviceInfo/Core (7.1.0) - - GZIP (1.3.1) + - GZIP (1.3.2) - Introspect (0.11.0) - JitsiMeetSDKLite (8.1.2-lite): - JitsiWebRTC (~> 111.0) @@ -176,7 +176,7 @@ SPEC CHECKSUMS: FLEX: e51461dd6f0bfb00643c262acdfea5d5d12c596b FlowCommoniOS: ca92071ab526dc89905495a37844fd7e78d1a7f2 GBDeviceInfo: 5d62fa85bdcce3ed288d83c28789adf1173e4376 - GZIP: e6922ed5bdd1d77d84589d50821ac34ea0c38d4b + GZIP: 3c0abf794bfce8c7cb34ea05a1837752416c8868 Introspect: 4cc1e4c34dd016540c8d86a591c231c09dafbee3 JitsiMeetSDKLite: 895213158cf62342069a10634a41d2f1c00057f7 JitsiWebRTC: 80f62908fcf2a1160e0d14b584323fb6e6be630b @@ -210,4 +210,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: c87b532985dd755b373732f841e3bcfe616f4e4f -COCOAPODS: 1.15.2 +COCOAPODS: 1.14.3 From ac2c3e86265e480276614a1924471aadd7739c86 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 2 Apr 2024 17:15:30 +0200 Subject: [PATCH 73/91] Ajout d'un "Privacy Manifest" dans le projet Xcode --- PrivacyInfo.xcprivacy | 41 +++++++++++++++++++++++++++++++++++++++++ changelog.d/1002.change | 1 + 2 files changed, 42 insertions(+) create mode 100644 PrivacyInfo.xcprivacy create mode 100644 changelog.d/1002.change diff --git a/PrivacyInfo.xcprivacy b/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..05faaf0e22 --- /dev/null +++ b/PrivacyInfo.xcprivacy @@ -0,0 +1,41 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + E174.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + E174.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + + diff --git a/changelog.d/1002.change b/changelog.d/1002.change new file mode 100644 index 0000000000..99144a92cc --- /dev/null +++ b/changelog.d/1002.change @@ -0,0 +1 @@ +Ajout d'un "Privacy Manifest" dans le projet Xcode (obligatoire à partir du 1er mai 2024) \ No newline at end of file From 7f64ecb274774c9f93a98dd0f4bd2c7ded9e9f43 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 2 Apr 2024 17:26:56 +0200 Subject: [PATCH 74/91] execute Twoncrier --- TCHAP_CHANGES.md | 16 ++++++++++++++++ changelog.d/664.change | 1 - changelog.d/887.change | 1 - changelog.d/970.change | 1 - changelog.d/974.change | 1 - changelog.d/975.change | 1 - changelog.d/976.change | 1 - changelog.d/982.change | 1 - changelog.d/986.change | 1 - changelog.d/995.change | 1 - changelog.d/998.change | 1 - 11 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 changelog.d/664.change delete mode 100644 changelog.d/887.change delete mode 100644 changelog.d/970.change delete mode 100644 changelog.d/974.change delete mode 100644 changelog.d/975.change delete mode 100644 changelog.d/976.change delete mode 100644 changelog.d/982.change delete mode 100644 changelog.d/986.change delete mode 100644 changelog.d/995.change delete mode 100644 changelog.d/998.change diff --git a/TCHAP_CHANGES.md b/TCHAP_CHANGES.md index 1fb7fedd31..34a49f547b 100644 --- a/TCHAP_CHANGES.md +++ b/TCHAP_CHANGES.md @@ -1,3 +1,19 @@ +## Changes in 2.7.3 (2024-04-02) + +🙌 Improvements + +- Rename RiotNSE extension product name to TchapNSE. It will change user-agent of requests in backend logs. ([#664](https://github.com/tchapgouv/tchap-ios/issues/664)) +- Réactivation de l'antivirus ([#887](https://github.com/tchapgouv/tchap-ios/issues/887)) +- Activation du partage de géolocalisation ([#970](https://github.com/tchapgouv/tchap-ios/issues/970)) +- Mettre une icône plus adaptée sur le bouton "Signaler un problème" lors d'un appel VoIP ([#974](https://github.com/tchapgouv/tchap-ios/issues/974)) +- Changement de la formulation du bouton des réglages pour autoriser les notifications sur l'appareil. Ajout d'un texte explicatif. ([#975](https://github.com/tchapgouv/tchap-ios/issues/975)) +- Changer le message d'erreur affiché en cas de problème de déchiffrement ([#976](https://github.com/tchapgouv/tchap-ios/issues/976)) +- Modifier l'intitulé de désactivation de compte ([#982](https://github.com/tchapgouv/tchap-ios/issues/982)) +- Utiliser le bouton de validation Tchap en édition de message. ([#986](https://github.com/tchapgouv/tchap-ios/issues/986)) +- La "notification par email" est rendue disponible à tout le monde. ([#995](https://github.com/tchapgouv/tchap-ios/issues/995)) +- Ajout des textes d'alerte d'activation de la géolocalisation dans les targets Btchap et DevTchap ([#998](https://github.com/tchapgouv/tchap-ios/issues/998)) + + ## Changes in 2.7.2 (2024-02-26) 🙌 Improvements diff --git a/changelog.d/664.change b/changelog.d/664.change deleted file mode 100644 index 8f88ad983e..0000000000 --- a/changelog.d/664.change +++ /dev/null @@ -1 +0,0 @@ -Rename RiotNSE extension product name to TchapNSE. It will change user-agent of requests in backend logs. \ No newline at end of file diff --git a/changelog.d/887.change b/changelog.d/887.change deleted file mode 100644 index 39f48c2176..0000000000 --- a/changelog.d/887.change +++ /dev/null @@ -1 +0,0 @@ -Réactivation de l'antivirus \ No newline at end of file diff --git a/changelog.d/970.change b/changelog.d/970.change deleted file mode 100644 index 03d602ea1d..0000000000 --- a/changelog.d/970.change +++ /dev/null @@ -1 +0,0 @@ -Activation du partage de géolocalisation \ No newline at end of file diff --git a/changelog.d/974.change b/changelog.d/974.change deleted file mode 100644 index 335b2cdcb4..0000000000 --- a/changelog.d/974.change +++ /dev/null @@ -1 +0,0 @@ -Mettre une icône plus adaptée sur le bouton "Signaler un problème" lors d'un appel VoIP \ No newline at end of file diff --git a/changelog.d/975.change b/changelog.d/975.change deleted file mode 100644 index fe7becb748..0000000000 --- a/changelog.d/975.change +++ /dev/null @@ -1 +0,0 @@ -Changement de la formulation du bouton des réglages pour autoriser les notifications sur l'appareil. Ajout d'un texte explicatif. \ No newline at end of file diff --git a/changelog.d/976.change b/changelog.d/976.change deleted file mode 100644 index 4096bfa5f9..0000000000 --- a/changelog.d/976.change +++ /dev/null @@ -1 +0,0 @@ -Changer le message d'erreur affiché en cas de problème de déchiffrement \ No newline at end of file diff --git a/changelog.d/982.change b/changelog.d/982.change deleted file mode 100644 index c08f1a0a0a..0000000000 --- a/changelog.d/982.change +++ /dev/null @@ -1 +0,0 @@ -Modifier l'intitulé de désactivation de compte \ No newline at end of file diff --git a/changelog.d/986.change b/changelog.d/986.change deleted file mode 100644 index 02643d852a..0000000000 --- a/changelog.d/986.change +++ /dev/null @@ -1 +0,0 @@ -Utiliser le bouton de validation Tchap en édition de message. \ No newline at end of file diff --git a/changelog.d/995.change b/changelog.d/995.change deleted file mode 100644 index 61281cbc49..0000000000 --- a/changelog.d/995.change +++ /dev/null @@ -1 +0,0 @@ -La "notification par email" est rendue disponible à tout le monde. \ No newline at end of file diff --git a/changelog.d/998.change b/changelog.d/998.change deleted file mode 100644 index c6978091c7..0000000000 --- a/changelog.d/998.change +++ /dev/null @@ -1 +0,0 @@ -Ajout des textes d'alerte d'activation de la géolocalisation dans les targets Btchap et DevTchap \ No newline at end of file From 67400b5e95599a64608000f18c7976a53dde9f0e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 2 Apr 2024 17:27:38 +0200 Subject: [PATCH 75/91] Update version to 2.7.4 --- Config/AppVersion.xcconfig | 2 +- towncrier.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index a07aa00f82..5170dc03f5 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 2.7.3 +MARKETING_VERSION = 2.7.4 CURRENT_PROJECT_VERSION = 1 diff --git a/towncrier.toml b/towncrier.toml index 371e14b76d..c81f8685ed 100644 --- a/towncrier.toml +++ b/towncrier.toml @@ -1,6 +1,6 @@ [tool.towncrier] name = "Changes in" -version = "2.7.3" +version = "2.7.4" filename = "TCHAP_CHANGES.md" directory = "changelog.d" template = "changelog.d/_template.md.jinja" From 2da83e68791bcc451020b8e6d270a2dd25da5630 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 2 Apr 2024 18:03:12 +0200 Subject: [PATCH 76/91] =?UTF-8?q?Mise=20en=20conformit=C3=A9=20avec=20la?= =?UTF-8?q?=20fa=C3=A7on=20configuration=20de=20Element?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SupportingFiles/PrivacyInfo.xcprivacy | 41 +++++++++++++++++++ Riot/SupportingFiles/PrivacyInfo.xcprivacy | 41 +++++++++++++++++++ RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy | 41 +++++++++++++++++++ .../SupportingFiles/PrivacyInfo.xcprivacy | 41 +++++++++++++++++++ .../SupportingFiles/PrivacyInfo.xcprivacy | 14 +++---- 5 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy create mode 100644 Riot/SupportingFiles/PrivacyInfo.xcprivacy create mode 100644 RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy create mode 100644 RiotShareExtension/SupportingFiles/PrivacyInfo.xcprivacy rename PrivacyInfo.xcprivacy => Tchap/SupportingFiles/PrivacyInfo.xcprivacy (89%) diff --git a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..c3b45f6413 --- /dev/null +++ b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,41 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + + + + \ No newline at end of file diff --git a/Riot/SupportingFiles/PrivacyInfo.xcprivacy b/Riot/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..c3b45f6413 --- /dev/null +++ b/Riot/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,41 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + + + + \ No newline at end of file diff --git a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..c3b45f6413 --- /dev/null +++ b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,41 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + + + + \ No newline at end of file diff --git a/RiotShareExtension/SupportingFiles/PrivacyInfo.xcprivacy b/RiotShareExtension/SupportingFiles/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..c3b45f6413 --- /dev/null +++ b/RiotShareExtension/SupportingFiles/PrivacyInfo.xcprivacy @@ -0,0 +1,41 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + 7D9E.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 3D61.1 + + + + + \ No newline at end of file diff --git a/PrivacyInfo.xcprivacy b/Tchap/SupportingFiles/PrivacyInfo.xcprivacy similarity index 89% rename from PrivacyInfo.xcprivacy rename to Tchap/SupportingFiles/PrivacyInfo.xcprivacy index 05faaf0e22..500ae9affe 100644 --- a/PrivacyInfo.xcprivacy +++ b/Tchap/SupportingFiles/PrivacyInfo.xcprivacy @@ -6,26 +6,26 @@ NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons - E174.1 + 1C8F.1 NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPICategoryFileTimestamp NSPrivacyAccessedAPITypeReasons - E174.1 + C617.1 NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPICategoryDiskSpace NSPrivacyAccessedAPITypeReasons - 35F9.1 + 7D9E.1 @@ -33,7 +33,7 @@ NSPrivacyAccessedAPICategorySystemBootTime NSPrivacyAccessedAPITypeReasons - 35F9.1 + 3D61.1 From f14c57dee8395549489ef20ad56419a2d432afcc Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 4 Apr 2024 15:16:46 +0200 Subject: [PATCH 77/91] Ne pas filtrer les events "serverNotice" du fetcher "allChats" --- .../Recents/Service/MatrixSDK/RecentsListService.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index bd8f52ae77..1401abe6c4 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -717,7 +717,12 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } private func updateConversationFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) { - var notDataTypes: MXRoomSummaryDataTypes = mode == .allChats ? [.hidden, .conferenceUser, .invited, .lowPriority, .serverNotice, .space] : [.hidden, .conferenceUser, .direct, .invited, .lowPriority, .serverNotice, .space] + // Tchap: + // don't exclude serverNotice channels from "all chats" group fetcher + // to get server Notices (aka "Tchap Annonces") in the main room list + // to be displayed as classic rooms +// var notDataTypes: MXRoomSummaryDataTypes = mode == .allChats ? [.hidden, .conferenceUser, .invited, .lowPriority, .serverNotice, .space] : [.hidden, .conferenceUser, .direct, .invited, .lowPriority, .serverNotice, .space] + var notDataTypes: MXRoomSummaryDataTypes = mode == .allChats ? [.hidden, .conferenceUser, .invited, .lowPriority, /*.serverNotice,*/ .space] : [.hidden, .conferenceUser, .direct, .invited, .lowPriority, /*.serverNotice,*/ .space] switch mode { case .home: From 8651599ed0778ea620c7ab13b9221c5da56ba5f2 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 4 Apr 2024 15:17:18 +0200 Subject: [PATCH 78/91] =?UTF-8?q?Ne=20pas=20afficher=20la=20section=20"Ser?= =?UTF-8?q?verNotice"=20en=20bas=20d'affichage=20(ils=20sont=20affich?= =?UTF-8?q?=C3=A9s=20parmi=20"allChats")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Recents/DataSources/RecentsDataSource.m | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 96d0025cec..48add73d5f 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -255,10 +255,13 @@ - (RecentsDataSourceSections *)makeDataSourceSections [types addObject:@(RecentsDataSourceSectionTypeLowPriority)]; } - if (self.serverNoticeCellDataArray.count > 0) - { - [types addObject:@(RecentsDataSourceSectionTypeServerNotice)]; - } + // Tchap: don't display server notices as separate section. + // Server notices are displayed in the main section "all chats" + // (see modification in `updateConversationFetcher` in `RecentListService` +// if (self.serverNoticeCellDataArray.count > 0) +// { +// [types addObject:@(RecentsDataSourceSectionTypeServerNotice)]; +// } return [[RecentsDataSourceSections alloc] initWithSectionTypes:types.copy]; } From 0950a772bd5ee1d206e7745e627c686cadf754f3 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 4 Apr 2024 15:20:36 +0200 Subject: [PATCH 79/91] Ajout de changelog --- changelog.d/1000.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1000.change diff --git a/changelog.d/1000.change b/changelog.d/1000.change new file mode 100644 index 0000000000..83cb7789ff --- /dev/null +++ b/changelog.d/1000.change @@ -0,0 +1 @@ +Afficher le salon "Tchap Annonces" dans le flux normal des salons \ No newline at end of file From ab53add3efcd01ff4a4491d72617d85f2da9a90e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 4 Apr 2024 17:12:31 +0200 Subject: [PATCH 80/91] Resolve conflicts on Rebase/Element-v1.11.9 into Tchap --- .../SupportingFiles/PrivacyInfo.xcprivacy | 4 ---- Btchap/Generated/InfoPlist.swift | 2 ++ Config/AppVersion.xcconfig | 5 ----- DevTchap/Generated/InfoPlist.swift | 2 ++ Riot/SupportingFiles/PrivacyInfo.xcprivacy | 4 ---- RiotNSE/BuildSettings.swift | 9 +++++++-- RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy | 4 ---- RiotShareExtension/BuildSettings.swift | 9 +++++++-- Tchap/Generated/InfoPlist.swift | 2 ++ Tchap/Generated/Strings.swift | 20 +++++++++++++++++-- 10 files changed, 38 insertions(+), 23 deletions(-) diff --git a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy index bf81383afb..500ae9affe 100644 --- a/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy +++ b/BroadcastUploadExtension/SupportingFiles/PrivacyInfo.xcprivacy @@ -38,8 +38,4 @@ -<<<<<<< HEAD -======= - ->>>>>>> v1.11.9 diff --git a/Btchap/Generated/InfoPlist.swift b/Btchap/Generated/InfoPlist.swift index d65235e8cb..fd4913b7ce 100644 --- a/Btchap/Generated/InfoPlist.swift +++ b/Btchap/Generated/InfoPlist.swift @@ -30,6 +30,8 @@ internal enum InfoPlist { internal static let nsCameraUsageDescription: String = _document["NSCameraUsageDescription"] internal static let nsContactsUsageDescription: String = _document["NSContactsUsageDescription"] internal static let nsFaceIDUsageDescription: String = _document["NSFaceIDUsageDescription"] + internal static let nsLocationAlwaysAndWhenInUseUsageDescription: String = _document["NSLocationAlwaysAndWhenInUseUsageDescription"] + internal static let nsLocationWhenInUseUsageDescription: String = _document["NSLocationWhenInUseUsageDescription"] internal static let nsMicrophoneUsageDescription: String = _document["NSMicrophoneUsageDescription"] internal static let nsPhotoLibraryUsageDescription: String = _document["NSPhotoLibraryUsageDescription"] internal static let uiBackgroundModes: [String] = _document["UIBackgroundModes"] diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 0206c99f1c..5170dc03f5 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,10 +15,5 @@ // // Version -<<<<<<< HEAD MARKETING_VERSION = 2.7.4 CURRENT_PROJECT_VERSION = 1 -======= -MARKETING_VERSION = 1.11.9 -CURRENT_PROJECT_VERSION = 1.11.9 ->>>>>>> v1.11.9 diff --git a/DevTchap/Generated/InfoPlist.swift b/DevTchap/Generated/InfoPlist.swift index c2b39bfa29..2306b5b8c2 100644 --- a/DevTchap/Generated/InfoPlist.swift +++ b/DevTchap/Generated/InfoPlist.swift @@ -29,6 +29,8 @@ internal enum InfoPlist { internal static let nsCameraUsageDescription: String = _document["NSCameraUsageDescription"] internal static let nsContactsUsageDescription: String = _document["NSContactsUsageDescription"] internal static let nsFaceIDUsageDescription: String = _document["NSFaceIDUsageDescription"] + internal static let nsLocationAlwaysAndWhenInUseUsageDescription: String = _document["NSLocationAlwaysAndWhenInUseUsageDescription"] + internal static let nsLocationWhenInUseUsageDescription: String = _document["NSLocationWhenInUseUsageDescription"] internal static let nsMicrophoneUsageDescription: String = _document["NSMicrophoneUsageDescription"] internal static let nsPhotoLibraryUsageDescription: String = _document["NSPhotoLibraryUsageDescription"] internal static let uiBackgroundModes: [String] = _document["UIBackgroundModes"] diff --git a/Riot/SupportingFiles/PrivacyInfo.xcprivacy b/Riot/SupportingFiles/PrivacyInfo.xcprivacy index bf81383afb..500ae9affe 100644 --- a/Riot/SupportingFiles/PrivacyInfo.xcprivacy +++ b/Riot/SupportingFiles/PrivacyInfo.xcprivacy @@ -38,8 +38,4 @@ -<<<<<<< HEAD -======= - ->>>>>>> v1.11.9 diff --git a/RiotNSE/BuildSettings.swift b/RiotNSE/BuildSettings.swift index 0c5d9ff411..ce637a7d40 100644 --- a/RiotNSE/BuildSettings.swift +++ b/RiotNSE/BuildSettings.swift @@ -270,7 +270,7 @@ final class BuildSettings: NSObject { static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ - "agent.dinum.tchap.gouv.fr" + tchapFeatureAnyHomeServer ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" @@ -456,7 +456,12 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! static let locationSharingEnabled = true diff --git a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy index bf81383afb..500ae9affe 100644 --- a/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy +++ b/RiotNSE/SupportingFiles/PrivacyInfo.xcprivacy @@ -38,8 +38,4 @@ -<<<<<<< HEAD -======= - ->>>>>>> v1.11.9 diff --git a/RiotShareExtension/BuildSettings.swift b/RiotShareExtension/BuildSettings.swift index 0c5d9ff411..ce637a7d40 100644 --- a/RiotShareExtension/BuildSettings.swift +++ b/RiotShareExtension/BuildSettings.swift @@ -270,7 +270,7 @@ final class BuildSettings: NSObject { static let tchapFeatureGeolocationSharing = "tchapFeatureGeolocationSharing" // linked to `locationSharingEnabled` property (see above) static var tchapFeaturesAllowedHomeServersForFeature: [String: [String]] = [ tchapFeatureNotificationByEmail: [ - "agent.dinum.tchap.gouv.fr" + tchapFeatureAnyHomeServer ], tchapFeatureVoiceOverIP: [ "agent.dinum.tchap.gouv.fr" @@ -456,7 +456,12 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing /// Overwritten by the home server's .well-known configuration (if any exists) - static let defaultTileServerMapStyleURL = URL(string: "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json")! + // Tchap: handle different map providers. + private enum TchapMapProvider: String { + case geoDataGouv = "https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" + case ign = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json" + } + static let defaultTileServerMapStyleURL = URL(string: TchapMapProvider.geoDataGouv.rawValue)! static let locationSharingEnabled = true diff --git a/Tchap/Generated/InfoPlist.swift b/Tchap/Generated/InfoPlist.swift index d65235e8cb..fd4913b7ce 100644 --- a/Tchap/Generated/InfoPlist.swift +++ b/Tchap/Generated/InfoPlist.swift @@ -30,6 +30,8 @@ internal enum InfoPlist { internal static let nsCameraUsageDescription: String = _document["NSCameraUsageDescription"] internal static let nsContactsUsageDescription: String = _document["NSContactsUsageDescription"] internal static let nsFaceIDUsageDescription: String = _document["NSFaceIDUsageDescription"] + internal static let nsLocationAlwaysAndWhenInUseUsageDescription: String = _document["NSLocationAlwaysAndWhenInUseUsageDescription"] + internal static let nsLocationWhenInUseUsageDescription: String = _document["NSLocationWhenInUseUsageDescription"] internal static let nsMicrophoneUsageDescription: String = _document["NSMicrophoneUsageDescription"] internal static let nsPhotoLibraryUsageDescription: String = _document["NSPhotoLibraryUsageDescription"] internal static let uiBackgroundModes: [String] = _document["UIBackgroundModes"] diff --git a/Tchap/Generated/Strings.swift b/Tchap/Generated/Strings.swift index dd83433c6e..9f27d360de 100644 --- a/Tchap/Generated/Strings.swift +++ b/Tchap/Generated/Strings.swift @@ -271,6 +271,10 @@ public class TchapL10n: NSObject { public static var errorTitleDefault: String { return TchapL10n.tr("Tchap", "error_title_default") } + /// Signaler un problème + public static var eventFormatterReportIncident: String { + return TchapL10n.tr("Tchap", "event_formatter_report_incident") + } /// La durée de validité de votre compte a expiré. Un email vous a été envoyé pour la renouveler. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous. public static var expiredAccountAlertMessage: String { return TchapL10n.tr("Tchap", "expired_account_alert_message") @@ -563,7 +567,7 @@ public class TchapL10n: NSObject { public static var roomCreationTitle: String { return TchapL10n.tr("Tchap", "room_creation_title") } - /// Sinon, consulter cet article de FAQ. + /// En savoir plus. public static var roomDecryptionErrorFaqLinkMessage: String { return TchapL10n.tr("Tchap", "room_decryption_error_faq_link_message") } @@ -743,7 +747,7 @@ public class TchapL10n: NSObject { public static var securityCrossSigningResetMessage: String { return TchapL10n.tr("Tchap", "security_cross_signing_reset_message") } - /// Êtes-vous sur ? + /// Êtes-vous sûr ? public static var securityCrossSigningResetTitle: String { return TchapL10n.tr("Tchap", "security_cross_signing_reset_title") } @@ -791,6 +795,10 @@ public class TchapL10n: NSObject { public static var settingsCryptoImportInvalidFile: String { return TchapL10n.tr("Tchap", "settings_crypto_import_invalid_file") } + /// Sans cette autorisation, les appels entrants ne seront pas notifiés. + public static var settingsEnablePushNotifText: String { + return TchapL10n.tr("Tchap", "settings_enable_push_notif_text") + } /// Les autres utilisateurs ne pourront pas découvrir mon compte lors de leurs recherches public static var settingsHideFromUsersDirectorySummary: String { return TchapL10n.tr("Tchap", "settings_hide_from_users_directory_summary") @@ -855,6 +863,14 @@ public class TchapL10n: NSObject { public static var tchapRoomInvalidLink: String { return TchapL10n.tr("Tchap", "tchap_room_invalid_link") } + /// Vous avez rencontré un souci durant votre appel VoIP. Dites-nous ce qui s'est passé : + public static var voidReportIncidentDescription: String { + return TchapL10n.tr("Tchap", "void_report_incident_description") + } + /// Signaler un problème VoIP + public static var voidReportIncidentTitle: String { + return TchapL10n.tr("Tchap", "void_report_incident_title") + } /// Attention public static var warningTitle: String { return TchapL10n.tr("Tchap", "warning_title") From 9ba1763948a0fb3df2914c4bbaefe28743c0d721 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 8 Apr 2024 09:54:34 +0200 Subject: [PATCH 81/91] =?UTF-8?q?L'affichage=20de=20g=C3=A9olocalisation?= =?UTF-8?q?=20plante=20quand=20l'affichage=20en=20bulle=20est=20d=C3=A9sac?= =?UTF-8?q?tiv=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Styles/Plain/PlainRoomTimelineCellProvider.m | 6 +++--- changelog.d/1009.change | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/1009.change diff --git a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m index b53aa3a9ba..f5b493a32a 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -268,9 +268,9 @@ - (void)registerPollCellsForTableView:(UITableView*)tableView - (void)registerLocationCellsForTableView:(UITableView*)tableView { -// [tableView registerClass:LocationCell.class forCellReuseIdentifier:LocationCell.defaultReuseIdentifier]; -// [tableView registerClass:LocationWithoutSenderInfoCell.class forCellReuseIdentifier:LocationWithoutSenderInfoCell.defaultReuseIdentifier]; -// [tableView registerClass:LocationWithPaginationTitleCell.class forCellReuseIdentifier:LocationWithPaginationTitleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationPlainCell.class forCellReuseIdentifier:LocationPlainCell.defaultReuseIdentifier]; + [tableView registerClass:LocationWithoutSenderInfoPlainCell.class forCellReuseIdentifier:LocationWithoutSenderInfoPlainCell.defaultReuseIdentifier]; + [tableView registerClass:LocationWithPaginationTitlePlainCell.class forCellReuseIdentifier:LocationWithPaginationTitlePlainCell.defaultReuseIdentifier]; } - (void)registerAntivirusCellsForTableView:(UITableView*)tableView diff --git a/changelog.d/1009.change b/changelog.d/1009.change new file mode 100644 index 0000000000..d09358cb85 --- /dev/null +++ b/changelog.d/1009.change @@ -0,0 +1 @@ +L'affichage de géolocalisation plante quand l'affichage en bulle est désactivé \ No newline at end of file From db8f72073b72a23ec095c15c2125f2db0e33e876 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 9 Apr 2024 17:04:19 +0200 Subject: [PATCH 82/91] =?UTF-8?q?Limiter=20la=20longueur=20du=20message=20?= =?UTF-8?q?d'origine=20=C3=A0=20l'affichage=20d'une=20r=C3=A9ponse=20avec?= =?UTF-8?q?=20citation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Utils/EventFormatter/MXKEventFormatter.m | 39 +++++++++++++++++++ changelog.d/832.change | 1 + 2 files changed, 40 insertions(+) create mode 100644 changelog.d/832.change diff --git a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m index d6a3b5cfd3..1fd543a036 100644 --- a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m +++ b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m @@ -2029,6 +2029,9 @@ - (NSString*)renderReplyTo:(NSString*)htmlString withRoomState:(MXRoomState*)roo } } + // Tchap: truncate quoted reply if necessary. + html = [self tchapTruncatedQuotedReplyFrom:html]; + // Replace
In reply to // By
['In reply to' from resources] // To localize the "In reply to" string @@ -2042,6 +2045,42 @@ - (NSString*)renderReplyTo:(NSString*)htmlString withRoomState:(MXRoomState*)roo return html; } +// Tchap: truncate long quoted reply +- (NSString *)tchapTruncatedQuotedReplyFrom:(NSString *)fullQuotedReply { + static NSRegularExpression *htmlQuotedTextRegex; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + htmlQuotedTextRegex = [NSRegularExpression regularExpressionWithPattern:kRepliedTextPattern + options:NSRegularExpressionCaseInsensitive + error:nil]; + }); + + NSTextCheckingResult * regexResults = [htmlQuotedTextRegex firstMatchInString:fullQuotedReply + options:0 + range:NSMakeRange(0, fullQuotedReply.length)]; + + // Check if a quoted text is present. + if( regexResults.numberOfRanges < 1 ) + { + // No reply found. + return fullQuotedReply; + } + + NSRange quotedTextRange = [regexResults rangeAtIndex:1]; + + NSUInteger quotedTextMaxLength = 60; // Max length of quoted text + + if( quotedTextRange.location != NSNotFound && quotedTextRange.length > quotedTextMaxLength ) + { + NSRange truncatedRange = NSMakeRange(quotedTextRange.location + quotedTextMaxLength, quotedTextRange.length - quotedTextMaxLength); + return [fullQuotedReply stringByReplacingCharactersInRange:truncatedRange withString:@"…"]; + } + + // The quoted reply is not found or already short. Return it as is. + return fullQuotedReply; +} + - (NSString*)renderPollEndedReplyTo:(NSString*)htmlString repliedEvent:(MXEvent*)repliedEvent { static NSRegularExpression *endedPollRegex; static dispatch_once_t onceToken; diff --git a/changelog.d/832.change b/changelog.d/832.change new file mode 100644 index 0000000000..72cdd7a085 --- /dev/null +++ b/changelog.d/832.change @@ -0,0 +1 @@ +Limiter la longueur du message d'origine à l'affichage d'une réponse avec citation. \ No newline at end of file From c617548e544326c42e2dbcb2fce4424fbc0f65ed Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 17 Apr 2024 19:38:34 +0200 Subject: [PATCH 83/91] =?UTF-8?q?Afficher=20un=20message=20d'alerte=20avan?= =?UTF-8?q?t=20envoi=20d'une=20pi=C3=A8ce=20jointe=20trop=20lourde?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Room/RoomViewController.m | 9 +++++++++ Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 5 +++++ changelog.d/1015.change | 1 + 3 files changed, 15 insertions(+) create mode 100644 changelog.d/1015.change diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 653d5899ba..b93c1e4ac9 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -7770,6 +7770,15 @@ - (void)documentPickerPresenter:(MXKDocumentPickerPresenter *)presenter didPickD { self.documentPickerPresenter = nil; + // Tchap: check maxUploadSize accepted by the home server before trying to upload. + NSUInteger maxUploadFileSize = self.roomDataSource.mxSession.maxUploadSize; + NSDictionary *fileAttributes = [NSFileManager.defaultManager attributesOfItemAtPath:url.path error:nil]; + if (fileAttributes && fileAttributes.fileSize > maxUploadFileSize) { + [self showAlertWithTitle:TchapL10n.roomSendFileTooBigTitle + message:[TchapL10n roomSendFileTooBigMessage:maxUploadFileSize/(1024*1024) :fileAttributes.fileSize/(1024*1024)]]; + return; + } + MXKUTI *fileUTI = [[MXKUTI alloc] initWithLocalFileURL:url]; NSString *mimeType = fileUTI.mimeType; diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 5b952e4bc7..14ca736756 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -330,6 +330,11 @@ "security_cross_signing_reset_message" = "Faites cette opération seulement si vous avez perdu tous vos autres appareils vérifiés."; "security_cross_signing_reset_action_title" = "Réinitialiser"; +//////////////////////////////////////////////////////////////////////////////// +// MARK: Room send file +"room_send_file_too_big_title" = "Erreur d'envoi"; +"room_send_file_too_big_message" = "Le fichier est trop lourd pour être envoyé. La taille limite est de %ldMo, mais la taille de votre fichier est de %ldMo."; + //////////////////////////////////////////////////////////////////////////////// // MARK: VoIP "event_formatter_report_incident" = "Signaler un problème"; diff --git a/changelog.d/1015.change b/changelog.d/1015.change new file mode 100644 index 0000000000..9dd68d1fa8 --- /dev/null +++ b/changelog.d/1015.change @@ -0,0 +1 @@ +Afficher un message d'alerte avant envoi d'une pièce jointe trop lourde. \ No newline at end of file From f24f2810b1fc096ddb1054f6237e1b0f3b9ecc1f Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 18 Apr 2024 10:11:21 +0200 Subject: [PATCH 84/91] =?UTF-8?q?Ajout=20de=20la=20g=C3=A9olocalisation=20?= =?UTF-8?q?en=20background=20sur=20Dev=20et=20Pre-prod?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Btchap/SupportingFiles/Info.plist | 1 + DevTchap/SupportingFiles/Info.plist | 1 + changelog.d/1017.change | 1 + 3 files changed, 3 insertions(+) create mode 100644 changelog.d/1017.change diff --git a/Btchap/SupportingFiles/Info.plist b/Btchap/SupportingFiles/Info.plist index c4cf1f06d9..5e06e305b9 100644 --- a/Btchap/SupportingFiles/Info.plist +++ b/Btchap/SupportingFiles/Info.plist @@ -63,6 +63,7 @@ This allows you to select pictures or videos from the photo library, and send them in your conversations. You can also use one of these pictures to set your profile picture. UIBackgroundModes + location remote-notification voip diff --git a/DevTchap/SupportingFiles/Info.plist b/DevTchap/SupportingFiles/Info.plist index d819fc0835..4303301c18 100644 --- a/DevTchap/SupportingFiles/Info.plist +++ b/DevTchap/SupportingFiles/Info.plist @@ -61,6 +61,7 @@ This allows you to select pictures or videos from the photo library, and send them in your conversations. You can also use one of these pictures to set your profile picture. UIBackgroundModes + location remote-notification voip diff --git a/changelog.d/1017.change b/changelog.d/1017.change new file mode 100644 index 0000000000..bb319aecfb --- /dev/null +++ b/changelog.d/1017.change @@ -0,0 +1 @@ +Ajout de la géolocalisation en background sur les targets Dev et Pre-prod \ No newline at end of file From 7bb6e9e8d9417b1426bb26e49d458ad10093f440 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 18 Apr 2024 10:21:37 +0200 Subject: [PATCH 85/91] =?UTF-8?q?Mauvais=20libell=C3=A9=20de=20fermeture?= =?UTF-8?q?=20de=20compte=20en=20anglais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Assets/en.lproj/Vector.strings | 2 +- changelog.d/1019.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1019.change diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 24297b0c71..06cc580561 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -860,7 +860,7 @@ Tap the + to start adding people."; "settings_crypto_export" = "Export keys"; "settings_crypto_blacklist_unverified_devices" = "Encrypt to verified sessions only"; -"settings_deactivate_my_account" = "Close account permanently"; // Tchap +"settings_deactivate_my_account" = "Close account"; // Tchap "settings_key_backup_info" = "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages."; "settings_key_backup_info_checking" = "Checking…"; diff --git a/changelog.d/1019.change b/changelog.d/1019.change new file mode 100644 index 0000000000..d26acdd760 --- /dev/null +++ b/changelog.d/1019.change @@ -0,0 +1 @@ +Mauvais libellé de fermeture de compte en anglais. \ No newline at end of file From 2fa07f91691145f2e4c48ee1fe53a21928caf7cf Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 22 Apr 2024 15:26:08 +0200 Subject: [PATCH 86/91] =?UTF-8?q?Mauvais=20message=20d'erreur=20quand=20on?= =?UTF-8?q?=20invite=20un=20utilisateur=20d=C3=A9j=C3=A0=20pr=C3=A9sent=20?= =?UTF-8?q?dans=20un=20salon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 2 +- changelog.d/1022.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1022.change diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 5b952e4bc7..28402c126e 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -320,7 +320,7 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Room Invite -"room_invite_error_action_forbidden" = "Cet utilisateur n'est pas autorisé à rejoindre ce salon."; +"room_invite_error_action_forbidden" = "Cet utilisateur est déjà présent dans ce salon ou bien n'est pas autorisé à le rejoindre."; "room_invite_search_consign" = "Veuillez saisir le nom d'un correspondant pour le rechercher dans l'annuaire"; //////////////////////////////////////////////////////////////////////////////// diff --git a/changelog.d/1022.change b/changelog.d/1022.change new file mode 100644 index 0000000000..56a47497b4 --- /dev/null +++ b/changelog.d/1022.change @@ -0,0 +1 @@ +Mauvais message d'erreur quand on invite un utilisateur déjà présent dans un salon \ No newline at end of file From 419b26dd6deadf57ba3ea732e289f1fcce3e4ea4 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 22 Apr 2024 16:45:08 +0200 Subject: [PATCH 87/91] Simplification du message --- Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 28402c126e..a3e1acfd46 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -320,7 +320,7 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Room Invite -"room_invite_error_action_forbidden" = "Cet utilisateur est déjà présent dans ce salon ou bien n'est pas autorisé à le rejoindre."; +"room_invite_error_action_forbidden" = "Cet utilisateur est déjà membre du salon ou n'est pas autorisé à le rejoindre."; "room_invite_search_consign" = "Veuillez saisir le nom d'un correspondant pour le rechercher dans l'annuaire"; //////////////////////////////////////////////////////////////////////////////// From 9b023b2c2abda3980ef9d94131d9aadd52712a8e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 24 Apr 2024 18:56:21 +0200 Subject: [PATCH 88/91] =?UTF-8?q?Am=C3=A9liorer=20les=20textes=20du=20parc?= =?UTF-8?q?ours=20de=20renouvellement=20de=20compte.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Riot/Modules/Application/AppCoordinator.swift | 10 +++++++--- Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 11 +++++++---- changelog.d/1021.change | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 changelog.d/1021.change diff --git a/Riot/Modules/Application/AppCoordinator.swift b/Riot/Modules/Application/AppCoordinator.swift index 2993942d42..e55874016c 100755 --- a/Riot/Modules/Application/AppCoordinator.swift +++ b/Riot/Modules/Application/AppCoordinator.swift @@ -442,14 +442,17 @@ final class AppCoordinator: NSObject, AppCoordinatorType { self.expiredAccountAlertController?.dismiss(animated: false) - let alert = UIAlertController(title: TchapL10n.warningTitle, message: TchapL10n.expiredAccountAlertMessage, preferredStyle: .alert) + // Tchap: customize wording + let alert = UIAlertController(title: TchapL10n.expiredAccountAlertTitle, message: TchapL10n.expiredAccountAlertMessage, preferredStyle: .alert) + // Tchap: customize wording let resumeTitle = TchapL10n.expiredAccountResumeButton let resumeAction = UIAlertAction(title: resumeTitle, style: .default, handler: { action in // Relaunch the session self.reloadSession(clearCache: false) }) alert.addAction(resumeAction) + // Tchap: customize wording let sendEmailTitle = TchapL10n.expiredAccountRequestRenewalEmailButton let sendEmailAction = UIAlertAction(title: sendEmailTitle, style: .default, handler: { action in // Request a new email for the main account @@ -484,9 +487,10 @@ final class AppCoordinator: NSObject, AppCoordinatorType { self.expiredAccountAlertController?.dismiss(animated: false) - let alert = UIAlertController(title: TchapL10n.infoTitle, message: TchapL10n.expiredAccountOnNewSentEmailMsg, preferredStyle: .alert) + // Tchap: customize wording + let alert = UIAlertController(title: TchapL10n.expiredAccountOnNewSentEmailTitle, message: TchapL10n.expiredAccountOnNewSentEmailMessage, preferredStyle: .alert) - let resumeTitle = TchapL10n.expiredAccountResumeButton + let resumeTitle = TchapL10n.expiredAccountOnNewSentEmailButton let resumeAction = UIAlertAction(title: resumeTitle, style: .default, handler: { action in // Relaunch the session self.reloadSession(clearCache: false) diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 5b952e4bc7..655f7e7932 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -247,10 +247,13 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Expired Account -"expired_account_alert_message" = "La durée de validité de votre compte a expiré. Un email vous a été envoyé pour la renouveler. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; -"expired_account_resume_button" = "J’ai renouvelé mon compte"; -"expired_account_request_renewal_email_button" = "Demander l’envoi d’un nouvel email"; -"expired_account_on_new_sent_email_msg" = "Un nouvel email vous a été envoyé pour renouveler la validité de votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; +"expired_account_alert_title" = "Votre compte a expiré"; +"expired_account_alert_message" = " Un email vous a été envoyé pour \"Renouveler votre compte\". Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; +"expired_account_resume_button" = "Continuer"; +"expired_account_request_renewal_email_button" = "Emvoyer un nouvel email"; +"expired_account_on_new_sent_email_title" = "Email envoyé"; +"expired_account_on_new_sent_email_message" = "Un nouvel email vous a été envoyé pour \"Renouveler votre compte\". Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; +"expired_account_on_new_sent_email_button" = "Continuer"; //////////////////////////////////////////////////////////////////////////////// // MARK: Change password diff --git a/changelog.d/1021.change b/changelog.d/1021.change new file mode 100644 index 0000000000..f56b6a6b2f --- /dev/null +++ b/changelog.d/1021.change @@ -0,0 +1 @@ +Améliorer les textes du parcours de renouvellement de compte. \ No newline at end of file From fc26556cf0811a02e4ade4f03f9dc12773de4e67 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 25 Apr 2024 15:50:00 +0200 Subject: [PATCH 89/91] =?UTF-8?q?Am=C3=A9liorer=20les=20textes=20du=20parc?= =?UTF-8?q?ours=20de=20renouvellement=20de=20compte.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tchap/Assets/Localizations/fr.lproj/Tchap.strings | 4 ++-- changelog.d/1027.change | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/1027.change diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 35c6440a43..831dc93331 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -248,11 +248,11 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Expired Account "expired_account_alert_title" = "Votre compte a expiré"; -"expired_account_alert_message" = " Un email vous a été envoyé pour \"Renouveler votre compte\". Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; +"expired_account_alert_message" = "Un email vous a été envoyé pour renouveler votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; "expired_account_resume_button" = "Continuer"; "expired_account_request_renewal_email_button" = "Emvoyer un nouvel email"; "expired_account_on_new_sent_email_title" = "Email envoyé"; -"expired_account_on_new_sent_email_message" = "Un nouvel email vous a été envoyé pour \"Renouveler votre compte\". Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; +"expired_account_on_new_sent_email_message" = "Un nouvel email vous a été envoyé pour renouveler votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous."; "expired_account_on_new_sent_email_button" = "Continuer"; //////////////////////////////////////////////////////////////////////////////// diff --git a/changelog.d/1027.change b/changelog.d/1027.change new file mode 100644 index 0000000000..f56b6a6b2f --- /dev/null +++ b/changelog.d/1027.change @@ -0,0 +1 @@ +Améliorer les textes du parcours de renouvellement de compte. \ No newline at end of file From cd199ec4c23b659a17e459a0ec21c341ab12b25e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 30 Apr 2024 17:31:08 +0200 Subject: [PATCH 90/91] =?UTF-8?q?Am=C3=A9liorer=20la=20compr=C3=A9hension?= =?UTF-8?q?=20du=20fonctionnement=20des=20notifications=20par=20email?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modules/Settings/SettingsViewController.m | 39 ++++++++++++++++++- .../Localizations/fr.lproj/Tchap.strings | 2 + changelog.d/1029.change | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1029.change diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 0bef04c922..50c8c04514 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -2241,7 +2241,34 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; - labelAndSwitchCell.mxkLabel.text = TchapL10n.settingsNotificationEmail; + + + // Tchap: add explanation to "enable notiofications by email" +// labelAndSwitchCell.mxkLabel.text = TchapL10n.settingsNotificationEmail; + + NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString: TchapL10n.settingsNotificationEmail + attributes:@{NSForegroundColorAttributeName : ThemeService.shared.theme.textPrimaryColor, + NSFontAttributeName: [UIFont systemFontOfSize:17.0]}]; + [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n" attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:4]}]]; + [attributedText appendAttributedString:[[NSMutableAttributedString alloc] initWithString: TchapL10n.settingsEnableEmailNotifText + attributes:@{NSForegroundColorAttributeName : ThemeService.shared.theme.textSecondaryColor, + NSFontAttributeName: [UIFont systemFontOfSize:14.0]}]]; + + [attributedText appendString:@" "]; + + [attributedText appendAttributedString: + [[NSAttributedString alloc] initWithString:TchapL10n.settingsEnableEmailNotifLink + attributes:@{ + NSForegroundColorAttributeName: ThemeService.shared.theme.textSecondaryColor, + NSFontAttributeName: [UIFont systemFontOfSize:14.0], + NSUnderlineStyleAttributeName: [NSNumber numberWithInt:NSUnderlineStyleSingle] + }]]; + + labelAndSwitchCell.mxkLabel.attributedText = attributedText; + + [labelAndSwitchCell.mxkLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(displayEmailNotificationFaq)]]; + labelAndSwitchCell.mxkLabel.userInteractionEnabled = YES; + labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; labelAndSwitchCell.mxkSwitch.enabled = YES; [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleNotificationsByEmail:) forControlEvents:UIControlEventTouchUpInside]; @@ -5127,4 +5154,14 @@ - (void)showUserSessionsFlow // MXLogWarning(@"Unexpected callback after OIDC account management.") //} +// Tchap: display email notification faq +- (void)displayEmailNotificationFaq { + NSLog(@"activateHyperlinkURL"); + + NSString *targetUrlString = @"https://aide.tchap.beta.gouv.fr/fr/article/notification-par-email-draft-6k7k89/"; + + WebSheetViewController *webCtrl = [[WebSheetViewController alloc] initWithTargetUrl:[NSURL URLWithString:targetUrlString]]; + [self presentViewController:webCtrl animated:YES completion:nil]; +} + @end diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 505abdbcde..faf42d7c05 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -347,3 +347,5 @@ //////////////////////////////////////////////////////////////////////////////// // MARK: Settings "settings_enable_push_notif_text" = "Sans cette autorisation, les appels entrants ne seront pas notifiés."; +"settings_enable_email_notif_text" = "Recevez un e-mail si au moins un message récent non lu pendant 72h."; +"settings_enable_email_notif_link" = "En savoir plus."; diff --git a/changelog.d/1029.change b/changelog.d/1029.change new file mode 100644 index 0000000000..59871594a9 --- /dev/null +++ b/changelog.d/1029.change @@ -0,0 +1 @@ +Améliorer la compréhension du fonctionnement des notifications par email. \ No newline at end of file From 7dfc6f220726291257df83799a3073a2152c99f2 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 30 Apr 2024 17:39:18 +0200 Subject: [PATCH 91/91] Remove useless NSLog --- Riot/Modules/Settings/SettingsViewController.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 50c8c04514..23151dbe15 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -5156,8 +5156,6 @@ - (void)showUserSessionsFlow // Tchap: display email notification faq - (void)displayEmailNotificationFaq { - NSLog(@"activateHyperlinkURL"); - NSString *targetUrlString = @"https://aide.tchap.beta.gouv.fr/fr/article/notification-par-email-draft-6k7k89/"; WebSheetViewController *webCtrl = [[WebSheetViewController alloc] initWithTargetUrl:[NSURL URLWithString:targetUrlString]];