From bc2a09891a644ec6f14a7b7898993792f191f1f7 Mon Sep 17 00:00:00 2001 From: Max von Webel Date: Mon, 11 Mar 2024 08:57:35 +0100 Subject: [PATCH] Added a "Moved To" Button to accounts that moved to other instances (#2001) * added moved information to Account model * Added "Moved To" button to account details for accounts that have moved --- .../Localization/Localizable.xcstrings | 19 ++++++++++++++++++- .../Account/AccountDetailHeaderView.swift | 12 ++++++++++++ Packages/Models/Sources/Models/Account.swift | 7 ++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/IceCubesApp/Resources/Localization/Localizable.xcstrings b/IceCubesApp/Resources/Localization/Localizable.xcstrings index cd84e0f3..16aa35cd 100644 --- a/IceCubesApp/Resources/Localization/Localizable.xcstrings +++ b/IceCubesApp/Resources/Localization/Localizable.xcstrings @@ -17067,6 +17067,23 @@ } } }, + "account.movedto.redirect-%@" : { + "extractionState" : "manual", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Umgezogen nach %@" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Moved To %@" + } + } + } + }, "account.post.pinned" : { "extractionState" : "manual", "localizations" : { @@ -79155,4 +79172,4 @@ } }, "version" : "1.0" -} +} \ No newline at end of file diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index 1c636e51..33a851c5 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -207,6 +207,7 @@ struct AccountDetailHeaderView: View { .foregroundStyle(.secondary) .textSelection(.enabled) .accessibilityRespondsToUserInteraction(false) + movedToView joinedAtView } .accessibilityElement(children: .contain) @@ -311,6 +312,17 @@ struct AccountDetailHeaderView: View { } } + @ViewBuilder + private var movedToView: some View { + if let movedTo = viewModel.account?.moved { + Button("account.movedto.redirect-\("@\(movedTo.acct)")") { + routerPath.navigate(to: .accountDetailWithAccount(account: movedTo)) + } + .font(.scaledCallout) + .foregroundColor(.accentColor) + } + } + @ViewBuilder private func makeNoteView(_ note: String) -> some View { VStack(alignment: .leading, spacing: 4) { diff --git a/Packages/Models/Sources/Models/Account.swift b/Packages/Models/Sources/Models/Account.swift index b222f79a..7ac4c9c3 100644 --- a/Packages/Models/Sources/Models/Account.swift +++ b/Packages/Models/Sources/Models/Account.swift @@ -61,6 +61,7 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable public let source: Source? public let bot: Bool public let discoverable: Bool? + public let moved: Account? public var haveAvatar: Bool { avatar.lastPathComponent != "missing.png" @@ -70,7 +71,7 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable header.lastPathComponent != "missing.png" } - public init(id: String, username: String, displayName: String?, avatar: URL, header: URL, acct: String, note: HTMLString, createdAt: ServerDate, followersCount: Int, followingCount: Int, statusesCount: Int, lastStatusAt: String? = nil, fields: [Account.Field], locked: Bool, emojis: [Emoji], url: URL? = nil, source: Account.Source? = nil, bot: Bool, discoverable: Bool? = nil) { + public init(id: String, username: String, displayName: String?, avatar: URL, header: URL, acct: String, note: HTMLString, createdAt: ServerDate, followersCount: Int, followingCount: Int, statusesCount: Int, lastStatusAt: String? = nil, fields: [Account.Field], locked: Bool, emojis: [Emoji], url: URL? = nil, source: Account.Source? = nil, bot: Bool, discoverable: Bool? = nil, moved: Account? = nil) { self.id = id self.username = username self.displayName = displayName @@ -90,6 +91,7 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable self.source = source self.bot = bot self.discoverable = discoverable + self.moved = moved if let displayName, !displayName.isEmpty { cachedDisplayName = .init(stringValue: displayName) @@ -118,6 +120,7 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable case source case bot case discoverable + case moved } public init(from decoder: Decoder) throws { @@ -141,6 +144,8 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable source = try container.decodeIfPresent(Account.Source.self, forKey: .source) bot = try container.decode(Bool.self, forKey: .bot) discoverable = try container.decodeIfPresent(Bool.self, forKey: .discoverable) + moved = try container.decodeIfPresent(Account.self, forKey: .moved) + if let displayName, !displayName.isEmpty { cachedDisplayName = .init(stringValue: displayName) } else {