Show inline actions for remote local timeline + fetch remote status

This commit is contained in:
Thomas Ricouard 2023-02-13 06:48:29 +01:00
parent ef37db496c
commit 9867faa6de
3 changed files with 42 additions and 15 deletions

View file

@ -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()

View file

@ -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)
}
}

View file

@ -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
}
}
}