From 9867faa6de54c3fd329ba5ad91c2c206486589e2 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Mon, 13 Feb 2023 06:48:29 +0100 Subject: [PATCH] Show inline actions for remote local timeline + fetch remote status --- .../Status/Row/StatusActionsView.swift | 9 ++++- .../Sources/Status/Row/StatusRowView.swift | 10 ++--- .../Status/Row/StatusRowViewModel.swift | 38 +++++++++++++++---- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Packages/Status/Sources/Status/Row/StatusActionsView.swift b/Packages/Status/Sources/Status/Row/StatusActionsView.swift index 64a92ebd..f11ab090 100644 --- a/Packages/Status/Sources/Status/Row/StatusActionsView.swift +++ b/Packages/Status/Sources/Status/Row/StatusActionsView.swift @@ -76,7 +76,7 @@ struct StatusActionsView: View { HStack(spacing: 2) { Image(systemName: action.iconName(viewModel: viewModel)) .foregroundColor(action.tintColor(viewModel: viewModel, theme: theme)) - if let count = action.count(viewModel: viewModel, theme: theme) { + if let count = action.count(viewModel: viewModel, theme: theme), !viewModel.isRemote { Text("\(count)") .font(.scaledFootnote) } @@ -97,10 +97,15 @@ struct StatusActionsView: View { private func handleAction(action: Actions) { Task { + if viewModel.isRemote, viewModel.localStatusId == nil || viewModel.localStatus == nil { + guard await viewModel.fetchRemoteStatus() else { + return + } + } HapticManager.shared.fireHaptic(of: .notification(.success)) switch action { case .respond: - routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.status) + routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.localStatus ?? viewModel.status) case .favorite: if viewModel.isFavorited { await viewModel.unFavorite() diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index 1a0d9498..a55655c2 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -53,7 +53,7 @@ public struct StatusRowView: View { replyView } statusView - if viewModel.showActions && !viewModel.isRemote, theme.statusActionsDisplay != .none { + if viewModel.showActions, theme.statusActionsDisplay != .none { StatusActionsView(viewModel: viewModel) .padding(.top, 8) .tint(viewModel.isFocused ? theme.tintColor : .gray) @@ -465,20 +465,20 @@ public struct StatusRowView: View { @ViewBuilder private var trailingSwipeActions: some View { - if preferences.swipeActionsStatusTrailingRight != StatusAction.none { + if preferences.swipeActionsStatusTrailingRight != StatusAction.none, !viewModel.isRemote { makeSwipeButton(action: preferences.swipeActionsStatusTrailingRight) } - if preferences.swipeActionsStatusTrailingLeft != StatusAction.none { + if preferences.swipeActionsStatusTrailingLeft != StatusAction.none, !viewModel.isRemote { makeSwipeButton(action: preferences.swipeActionsStatusTrailingLeft) } } @ViewBuilder private var leadingSwipeActions: some View { - if preferences.swipeActionsStatusLeadingLeft != StatusAction.none { + if preferences.swipeActionsStatusLeadingLeft != StatusAction.none, !viewModel.isRemote { makeSwipeButton(action: preferences.swipeActionsStatusLeadingLeft) } - if preferences.swipeActionsStatusLeadingRight != StatusAction.none { + if preferences.swipeActionsStatusLeadingRight != StatusAction.none, !viewModel.isRemote { makeSwipeButton(action: preferences.swipeActionsStatusLeadingRight) } } diff --git a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift index dc39c3ce..04429706 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift @@ -13,7 +13,7 @@ public class StatusRowViewModel: ObservableObject { let isFocused: Bool let isRemote: Bool let showActions: Bool - + @Published var favoritesCount: Int @Published var isFavorited: Bool @Published var isReblogged: Bool @@ -25,7 +25,6 @@ public class StatusRowViewModel: ObservableObject { @Published var displaySpoiler: Bool = false @Published var isEmbedLoading: Bool = false @Published var isFiltered: Bool = false - @Published var isLoadingRemoteContent: Bool = false @Published var translation: StatusTranslation? @Published var isLoadingTranslation: Bool = false @@ -33,6 +32,10 @@ public class StatusRowViewModel: ObservableObject { @Published var favoriters: [Account] = [] @Published var rebloggers: [Account] = [] + + @Published var isLoadingRemoteContent: Bool = false + @Published var localStatusId: String? + @Published var localStatus: Status? private let theme = Theme.shared @@ -168,7 +171,7 @@ public class StatusRowViewModel: ObservableObject { isFavorited = true favoritesCount += 1 do { - let status: Status = try await client.post(endpoint: Statuses.favorite(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.favorite(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isFavorited = false @@ -181,7 +184,7 @@ public class StatusRowViewModel: ObservableObject { isFavorited = false favoritesCount -= 1 do { - let status: Status = try await client.post(endpoint: Statuses.unfavorite(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.unfavorite(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isFavorited = true @@ -194,7 +197,7 @@ public class StatusRowViewModel: ObservableObject { isReblogged = true reblogsCount += 1 do { - let status: Status = try await client.post(endpoint: Statuses.reblog(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.reblog(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isReblogged = false @@ -207,7 +210,7 @@ public class StatusRowViewModel: ObservableObject { isReblogged = false reblogsCount -= 1 do { - let status: Status = try await client.post(endpoint: Statuses.unreblog(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.unreblog(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isReblogged = true @@ -241,7 +244,7 @@ public class StatusRowViewModel: ObservableObject { guard let client, client.isAuth else { return } isBookmarked = true do { - let status: Status = try await client.post(endpoint: Statuses.bookmark(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.bookmark(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isBookmarked = false @@ -252,7 +255,7 @@ public class StatusRowViewModel: ObservableObject { guard let client, client.isAuth else { return } isBookmarked = false do { - let status: Status = try await client.post(endpoint: Statuses.unbookmark(id: status.reblog?.id ?? status.id)) + let status: Status = try await client.post(endpoint: Statuses.unbookmark(id: localStatusId ?? status.reblog?.id ?? status.id)) updateFromStatus(status: status) } catch { isBookmarked = true @@ -324,4 +327,23 @@ public class StatusRowViewModel: ObservableObject { } } } + + func fetchRemoteStatus() async -> Bool { + guard isRemote, let client, let remoteStatusURL = URL(string: status.reblog?.url ?? status.url ?? "") else { return false } + isLoadingRemoteContent = true + let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString, + type: "statuses", + offset: nil, + following: nil), + forceVersion: .v2) + if let status = results?.statuses.first { + self.localStatusId = status.id + self.localStatus = status + isLoadingRemoteContent = false + return true + } else { + isLoadingRemoteContent = false + return false + } + } }