From 2bd5c26c6f32bb13e07c636df3852386036f4994 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Sun, 5 Feb 2023 10:07:45 +0100 Subject: [PATCH] Add inline account badge for status context favorites / boosts --- .../DesignSystem/Views/AvatarView.swift | 6 ++- .../Status/Row/StatusActionsView.swift | 39 +++++++++++++++---- .../Status/Row/StatusRowViewModel.swift | 11 ++++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift index a1abc3e2..34034706 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift @@ -7,7 +7,7 @@ public struct AvatarView: View { @EnvironmentObject private var theme: Theme public enum Size { - case account, status, embed, badge, boost + case account, status, embed, badge, list, boost public var size: CGSize { switch self { @@ -22,6 +22,8 @@ public struct AvatarView: View { return .init(width: 34, height: 34) case .badge: return .init(width: 28, height: 28) + case .list: + return .init(width: 20, height: 20) case .boost: return .init(width: 12, height: 12) } @@ -29,7 +31,7 @@ public struct AvatarView: View { var cornerRadius: CGFloat { switch self { - case .badge, .boost: + case .badge, .boost, .list: return size.width / 2 default: return 4 diff --git a/Packages/Status/Sources/Status/Row/StatusActionsView.swift b/Packages/Status/Sources/Status/Row/StatusActionsView.swift index 30a63f32..5d65452a 100644 --- a/Packages/Status/Sources/Status/Row/StatusActionsView.swift +++ b/Packages/Status/Sources/Status/Row/StatusActionsView.swift @@ -92,6 +92,9 @@ struct StatusActionsView: View { } if viewModel.isFocused { summaryView + .task { + await viewModel.fetchActionsAccounts() + } } } } @@ -137,22 +140,42 @@ struct StatusActionsView: View { if viewModel.favoritesCount > 0 { Divider() NavigationLink(value: RouterDestinations.favoritedBy(id: viewModel.status.id)) { - Text("status.summary.n-favorites \(viewModel.favoritesCount)") - .font(.scaledCallout) - Spacer() - Image(systemName: "chevron.right") + HStack { + Text("status.summary.n-favorites \(viewModel.favoritesCount)") + .font(.scaledCallout) + Spacer() + makeAccountsScrollView(accounts: viewModel.favoriters) + Image(systemName: "chevron.right") + } + .frame(height: 20) } } if viewModel.reblogsCount > 0 { Divider() NavigationLink(value: RouterDestinations.rebloggedBy(id: viewModel.status.id)) { - Text("status.summary.n-boosts \(viewModel.reblogsCount)") - .font(.scaledCallout) - Spacer() - Image(systemName: "chevron.right") + HStack { + Text("status.summary.n-boosts \(viewModel.reblogsCount)") + .font(.scaledCallout) + Spacer() + makeAccountsScrollView(accounts: viewModel.rebloggers) + Image(systemName: "chevron.right") + } + .frame(height: 20) } } } + + private func makeAccountsScrollView(accounts: [Account]) -> some View { + ScrollView(.horizontal, showsIndicators: false) { + LazyHStack(spacing: 0) { + ForEach(accounts) { account in + AvatarView(url: account.avatar, size: .list) + .padding(.leading, -4) + } + } + .padding(.leading, .layoutPadding) + } + } private func handleAction(action: Actions) { Task { diff --git a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift index 06c5c992..7155be28 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift @@ -27,6 +27,9 @@ public class StatusRowViewModel: ObservableObject { @Published var translation: String? @Published var isLoadingTranslation: Bool = false + @Published var favoriters: [Account] = [] + @Published var rebloggers: [Account] = [] + var seen = false var filter: Filtered? { @@ -250,6 +253,14 @@ public class StatusRowViewModel: ObservableObject { _ = try await client.delete(endpoint: Statuses.status(id: status.id)) } catch {} } + + func fetchActionsAccounts() async { + guard let client else { return } + do { + favoriters = try await client.get(endpoint: Statuses.favoritedBy(id: status.id, maxId: nil)) + rebloggers = try await client.get(endpoint: Statuses.rebloggedBy(id: status.id, maxId: nil)) + } catch { } + } private func updateFromStatus(status: Status) { if let reblog = status.reblog {