From abcd4cc32190e01a11d72aeb55df41e84ac41934 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Thu, 2 May 2024 08:43:58 +0200 Subject: [PATCH] Add muted and blocked accounts list --- IceCubesApp/App/AppRegistry.swift | 4 + .../Localization/Localizable.xcstrings | 480 +++++++++++++----- .../Sources/Account/AccountDetailView.swift | 15 + .../AccountsList/AccountsListView.swift | 3 + .../AccountsList/AccountsListViewModel.swift | 18 + Packages/Env/Sources/Env/Router.swift | 2 + .../Sources/Lists/Create/ListCreateView.swift | 1 + .../Sources/Network/Endpoint/Accounts.swift | 6 + 8 files changed, 408 insertions(+), 121 deletions(-) diff --git a/IceCubesApp/App/AppRegistry.swift b/IceCubesApp/App/AppRegistry.swift index 766e5045..8edfec18 100644 --- a/IceCubesApp/App/AppRegistry.swift +++ b/IceCubesApp/App/AppRegistry.swift @@ -70,6 +70,10 @@ extension View { NotificationsListView(lockedType: nil , lockedAccountId: accountId, scrollToTopSignal: .constant(0)) + case .blockedAccounts: + AccountsListView(mode: .blocked) + case .mutedAccounts: + AccountsListView(mode: .muted) } } } diff --git a/IceCubesApp/Resources/Localization/Localizable.xcstrings b/IceCubesApp/Resources/Localization/Localizable.xcstrings index c48639b3..452d1540 100644 --- a/IceCubesApp/Resources/Localization/Localizable.xcstrings +++ b/IceCubesApp/Resources/Localization/Localizable.xcstrings @@ -1,126 +1,6 @@ { "sourceLanguage" : "en", "strings" : { - "action.cancel" : { - "comment" : "MARK: Common strings", - "extractionState" : "stale", - "localizations" : { - "be" : { - "stringUnit" : { - "state" : "translated", - "value" : "Скасаваць" - } - }, - "ca" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancel·la" - } - }, - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Abbrechen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancel" - } - }, - "en-GB" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancel" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancelar" - } - }, - "eu" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utzi" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Annuler" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Annulla" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "キャンセル" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "취소" - } - }, - "nb" : { - "stringUnit" : { - "state" : "translated", - "value" : "Avbryt" - } - }, - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Annuleer" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Anuluj" - } - }, - "pt-BR" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancelar" - } - }, - "tr" : { - "stringUnit" : { - "state" : "translated", - "value" : "İptal Et" - } - }, - "uk" : { - "stringUnit" : { - "state" : "translated", - "value" : "Відміна" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "取消" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "取消" - } - } - } - }, "" : { "localizations" : { "be" : { @@ -11587,6 +11467,125 @@ } } }, + "account.blocked" : { + "extractionState" : "manual", + "localizations" : { + "be" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "ca" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "de" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blocked accounts" + } + }, + "en-GB" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blocked accounts" + } + }, + "es" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "" + } + }, + "eu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blocked accounts" + } + }, + "fr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blocked accounts" + } + }, + "ja" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "ko" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "nb" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "nl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "pt-BR" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "tr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blocked accounts" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Blocked accounts" + } + } + } + }, "account.boosted-by" : { "extractionState" : "manual", "localizations" : { @@ -17312,6 +17311,125 @@ } } }, + "account.muted" : { + "extractionState" : "manual", + "localizations" : { + "be" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "ca" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "de" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Muted accounts" + } + }, + "en-GB" : { + "stringUnit" : { + "state" : "translated", + "value" : "Muted accounts" + } + }, + "es" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "eu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Muted accounts" + } + }, + "fr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "it" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "" + } + }, + "ja" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "ko" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "nb" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "nl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "pt-BR" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "tr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "uk" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Muted accounts" + } + } + } + }, "account.post.pinned" : { "extractionState" : "manual", "localizations" : { @@ -18264,6 +18382,126 @@ } } }, + "action.cancel" : { + "comment" : "MARK: Common strings", + "extractionState" : "stale", + "localizations" : { + "be" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скасаваць" + } + }, + "ca" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancel·la" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abbrechen" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancel" + } + }, + "en-GB" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancel" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancelar" + } + }, + "eu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utzi" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annulla" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャンセル" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "취소" + } + }, + "nb" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avbryt" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuleer" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anuluj" + } + }, + "pt-BR" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancelar" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "İptal Et" + } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Відміна" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "取消" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "取消" + } + } + } + }, "action.delete" : { "extractionState" : "manual", "localizations" : { @@ -80231,4 +80469,4 @@ } }, "version" : "1.0" -} +} \ No newline at end of file diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index 573952a0..b202f4c4 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -326,6 +326,21 @@ public struct AccountDetailView: View { if let account = viewModel.account { Divider() + + Button { + routerPath.navigate(to: .blockedAccounts) + } label: { + Label("account.blocked", systemImage: "person.crop.circle.badge.xmark") + } + + + Button { + routerPath.navigate(to: .mutedAccounts) + } label: { + Label("account.muted", systemImage: "person.crop.circle.badge.moon") + } + + Divider() Button { if let url = URL(string: "https://mastometrics.com/auth/login?username=\(account.acct)@\(client.server)&instance=\(client.server)&auto=true") { diff --git a/Packages/Account/Sources/Account/AccountsList/AccountsListView.swift b/Packages/Account/Sources/Account/AccountsList/AccountsListView.swift index e1673ea3..ed916294 100644 --- a/Packages/Account/Sources/Account/AccountsList/AccountsListView.swift +++ b/Packages/Account/Sources/Account/AccountsList/AccountsListView.swift @@ -52,6 +52,9 @@ public struct AccountsListView: View { searchableList } else { standardList + .refreshable { + await viewModel.fetch() + } } } diff --git a/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift b/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift index b6db3470..72d0537c 100644 --- a/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift +++ b/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift @@ -8,6 +8,7 @@ public enum AccountsListMode { case following(accountId: String), followers(accountId: String) case favoritedBy(statusId: String), rebloggedBy(statusId: String) case accountsList(accounts: [Account]) + case blocked, muted var title: LocalizedStringKey { switch self { @@ -21,6 +22,10 @@ public enum AccountsListMode { "account.boosted-by" case .accountsList: "" + case .blocked: + "account.blocked" + case .muted: + "account.muted" } } } @@ -84,6 +89,12 @@ public enum AccountsListMode { case let .accountsList(accounts): self.accounts = accounts link = nil + + case .blocked: + (accounts, link) = try await client.getWithLink(endpoint: Accounts.blockList) + + case .muted: + (accounts, link) = try await client.getWithLink(endpoint: Accounts.muteList) } nextPageId = link?.maxId relationships = try await client.get(endpoint: @@ -114,7 +125,14 @@ public enum AccountsListMode { case .accountsList: newAccounts = [] link = nil + + case .blocked: + (newAccounts, link) = try await client.getWithLink(endpoint: Accounts.blockList) + + case .muted: + (newAccounts, link) = try await client.getWithLink(endpoint: Accounts.muteList) } + accounts.append(contentsOf: newAccounts) let newRelationships: [Relationship] = try await client.get(endpoint: Accounts.relationships(ids: newAccounts.map(\.id))) diff --git a/Packages/Env/Sources/Env/Router.swift b/Packages/Env/Sources/Env/Router.swift index 7daf81ef..0a6fc5e3 100644 --- a/Packages/Env/Sources/Env/Router.swift +++ b/Packages/Env/Sources/Env/Router.swift @@ -25,6 +25,8 @@ public enum RouterDestination: Hashable { case tagsList(tags: [Tag]) case notificationsRequests case notificationForAccount(accountId: String) + case blockedAccounts + case mutedAccounts } public enum WindowDestinationEditor: Hashable, Codable { diff --git a/Packages/Lists/Sources/Lists/Create/ListCreateView.swift b/Packages/Lists/Sources/Lists/Create/ListCreateView.swift index f94bc3ed..344263da 100644 --- a/Packages/Lists/Sources/Lists/Create/ListCreateView.swift +++ b/Packages/Lists/Sources/Lists/Create/ListCreateView.swift @@ -39,6 +39,7 @@ public struct ListCreateView: View { .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) .toolbar { + CancelToolbarItem() ToolbarItem { Button { Task { diff --git a/Packages/Network/Sources/Network/Endpoint/Accounts.swift b/Packages/Network/Sources/Network/Endpoint/Accounts.swift index 80f66b41..536c928a 100644 --- a/Packages/Network/Sources/Network/Endpoint/Accounts.swift +++ b/Packages/Network/Sources/Network/Endpoint/Accounts.swift @@ -32,6 +32,8 @@ public enum Accounts: Endpoint { case mute(id: String, json: MuteData) case unmute(id: String) case relationshipNote(id: String, json: RelationshipNoteData) + case blockList + case muteList public func path() -> String { switch self { @@ -81,6 +83,10 @@ public enum Accounts: Endpoint { "accounts/\(id)/unmute" case let .relationshipNote(id, _): "accounts/\(id)/note" + case .blockList: + "blocks" + case .muteList: + "mutes" } }