2023-02-18 06:26:48 +00:00
|
|
|
import DesignSystem
|
2023-02-17 12:30:56 +00:00
|
|
|
import Env
|
|
|
|
import Models
|
2023-02-18 06:26:48 +00:00
|
|
|
import SwiftUI
|
2023-02-17 12:30:56 +00:00
|
|
|
|
2023-09-19 07:18:20 +00:00
|
|
|
@MainActor
|
2023-02-17 12:30:56 +00:00
|
|
|
struct StatusRowSwipeView: View {
|
2023-09-18 19:03:52 +00:00
|
|
|
@Environment(Theme.self) private var theme
|
2023-09-19 07:18:20 +00:00
|
|
|
@Environment(UserPreferences.self) private var preferences
|
2023-09-18 05:01:23 +00:00
|
|
|
@Environment(CurrentAccount.self) private var currentAccount
|
|
|
|
@Environment(StatusDataController.self) private var statusDataController
|
2023-02-18 06:26:48 +00:00
|
|
|
|
2023-02-17 12:30:56 +00:00
|
|
|
enum Mode {
|
|
|
|
case leading, trailing
|
|
|
|
}
|
2023-02-22 18:09:39 +00:00
|
|
|
|
2023-02-22 11:49:36 +00:00
|
|
|
func privateBoost() -> Bool {
|
2023-09-16 12:15:03 +00:00
|
|
|
viewModel.status.visibility == .priv && viewModel.status.account.id == currentAccount.account?.id
|
2023-02-22 11:49:36 +00:00
|
|
|
}
|
2023-02-18 06:26:48 +00:00
|
|
|
|
2023-09-18 05:01:23 +00:00
|
|
|
var viewModel: StatusRowViewModel
|
2023-02-17 12:30:56 +00:00
|
|
|
let mode: Mode
|
2023-02-18 06:26:48 +00:00
|
|
|
|
2023-02-17 12:30:56 +00:00
|
|
|
var body: some View {
|
|
|
|
switch mode {
|
|
|
|
case .leading:
|
|
|
|
leadingSwipeActions
|
|
|
|
case .trailing:
|
|
|
|
trailingSwipeActions
|
|
|
|
}
|
|
|
|
}
|
2023-02-18 06:26:48 +00:00
|
|
|
|
2023-02-17 12:30:56 +00:00
|
|
|
@ViewBuilder
|
|
|
|
private var trailingSwipeActions: some View {
|
|
|
|
if preferences.swipeActionsStatusTrailingRight != StatusAction.none, !viewModel.isRemote {
|
|
|
|
makeSwipeButton(action: preferences.swipeActionsStatusTrailingRight)
|
|
|
|
.tint(preferences.swipeActionsStatusTrailingRight.color(themeTintColor: theme.tintColor, useThemeColor: preferences.swipeActionsUseThemeColor, outside: true))
|
|
|
|
}
|
|
|
|
if preferences.swipeActionsStatusTrailingLeft != StatusAction.none, !viewModel.isRemote {
|
|
|
|
makeSwipeButton(action: preferences.swipeActionsStatusTrailingLeft)
|
|
|
|
.tint(preferences.swipeActionsStatusTrailingLeft.color(themeTintColor: theme.tintColor, useThemeColor: preferences.swipeActionsUseThemeColor, outside: false))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ViewBuilder
|
|
|
|
private var leadingSwipeActions: some View {
|
|
|
|
if preferences.swipeActionsStatusLeadingLeft != StatusAction.none, !viewModel.isRemote {
|
|
|
|
makeSwipeButton(action: preferences.swipeActionsStatusLeadingLeft)
|
|
|
|
.tint(preferences.swipeActionsStatusLeadingLeft.color(themeTintColor: theme.tintColor, useThemeColor: preferences.swipeActionsUseThemeColor, outside: true))
|
|
|
|
}
|
|
|
|
if preferences.swipeActionsStatusLeadingRight != StatusAction.none, !viewModel.isRemote {
|
|
|
|
makeSwipeButton(action: preferences.swipeActionsStatusLeadingRight)
|
|
|
|
.tint(preferences.swipeActionsStatusLeadingRight.color(themeTintColor: theme.tintColor, useThemeColor: preferences.swipeActionsUseThemeColor, outside: false))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ViewBuilder
|
|
|
|
private func makeSwipeButton(action: StatusAction) -> some View {
|
|
|
|
switch action {
|
|
|
|
case .reply:
|
|
|
|
makeSwipeButtonForRouterPath(action: action, destination: .replyToStatusEditor(status: viewModel.status))
|
|
|
|
case .quote:
|
|
|
|
makeSwipeButtonForRouterPath(action: action, destination: .quoteStatusEditor(status: viewModel.status))
|
2023-09-16 12:15:03 +00:00
|
|
|
.disabled(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv)
|
2023-02-17 12:30:56 +00:00
|
|
|
case .favorite:
|
|
|
|
makeSwipeButtonForTask(action: action) {
|
2023-03-01 06:28:46 +00:00
|
|
|
await statusDataController.toggleFavorite(remoteStatus: nil)
|
2023-02-17 12:30:56 +00:00
|
|
|
}
|
|
|
|
case .boost:
|
2023-02-22 11:49:36 +00:00
|
|
|
makeSwipeButtonForTask(action: action, privateBoost: privateBoost()) {
|
2023-03-01 06:28:46 +00:00
|
|
|
await statusDataController.toggleReblog(remoteStatus: nil)
|
2023-02-17 12:30:56 +00:00
|
|
|
}
|
2023-02-22 11:49:36 +00:00
|
|
|
.disabled(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv && viewModel.status.account.id != currentAccount.account?.id)
|
2023-02-17 12:30:56 +00:00
|
|
|
case .bookmark:
|
|
|
|
makeSwipeButtonForTask(action: action) {
|
2023-03-01 06:28:46 +00:00
|
|
|
await statusDataController.toggleBookmark(remoteStatus: nil)
|
2023-02-17 12:30:56 +00:00
|
|
|
}
|
|
|
|
case .none:
|
|
|
|
EmptyView()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ViewBuilder
|
2023-02-21 17:52:30 +00:00
|
|
|
private func makeSwipeButtonForRouterPath(action: StatusAction, destination: SheetDestination) -> some View {
|
2023-02-17 12:30:56 +00:00
|
|
|
Button {
|
|
|
|
HapticManager.shared.fireHaptic(of: .notification(.success))
|
|
|
|
viewModel.routerPath.presentedSheet = destination
|
|
|
|
} label: {
|
|
|
|
makeSwipeLabel(action: action, style: preferences.swipeActionsIconStyle)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ViewBuilder
|
2023-02-22 11:49:36 +00:00
|
|
|
private func makeSwipeButtonForTask(action: StatusAction, privateBoost: Bool = false, task: @escaping () async -> Void) -> some View {
|
2023-02-17 12:30:56 +00:00
|
|
|
Button {
|
|
|
|
Task {
|
|
|
|
HapticManager.shared.fireHaptic(of: .notification(.success))
|
|
|
|
await task()
|
|
|
|
}
|
|
|
|
} label: {
|
2023-02-22 11:49:36 +00:00
|
|
|
makeSwipeLabel(action: action, style: preferences.swipeActionsIconStyle, privateBoost: privateBoost)
|
2023-02-17 12:30:56 +00:00
|
|
|
}
|
|
|
|
}
|
2023-02-18 06:26:48 +00:00
|
|
|
|
2023-02-17 12:30:56 +00:00
|
|
|
@ViewBuilder
|
2023-02-22 11:49:36 +00:00
|
|
|
private func makeSwipeLabel(action: StatusAction, style: UserPreferences.SwipeActionsIconStyle, privateBoost: Bool = false) -> some View {
|
2023-02-18 06:26:48 +00:00
|
|
|
switch style {
|
2023-02-17 12:30:56 +00:00
|
|
|
case .iconOnly:
|
2023-02-28 05:58:52 +00:00
|
|
|
Label(action.displayName(isReblogged: statusDataController.isReblogged,
|
|
|
|
isFavorited: statusDataController.isFavorited,
|
|
|
|
isBookmarked: statusDataController.isBookmarked,
|
|
|
|
privateBoost: privateBoost),
|
2023-02-28 13:53:31 +00:00
|
|
|
imageNamed: action.iconName(isReblogged: statusDataController.isReblogged,
|
2023-03-13 12:38:28 +00:00
|
|
|
isFavorited: statusDataController.isFavorited,
|
|
|
|
isBookmarked: statusDataController.isBookmarked,
|
|
|
|
privateBoost: privateBoost))
|
2023-02-17 12:30:56 +00:00
|
|
|
.labelStyle(.iconOnly)
|
|
|
|
.environment(\.symbolVariants, .none)
|
|
|
|
case .iconWithText:
|
2023-02-28 05:58:52 +00:00
|
|
|
Label(action.displayName(isReblogged: statusDataController.isReblogged,
|
|
|
|
isFavorited: statusDataController.isFavorited,
|
|
|
|
isBookmarked: statusDataController.isBookmarked,
|
|
|
|
privateBoost: privateBoost),
|
2023-02-28 13:53:31 +00:00
|
|
|
imageNamed: action.iconName(isReblogged: statusDataController.isReblogged,
|
2023-03-13 12:38:28 +00:00
|
|
|
isFavorited: statusDataController.isFavorited,
|
|
|
|
isBookmarked: statusDataController.isBookmarked,
|
|
|
|
privateBoost: privateBoost))
|
2023-02-17 12:30:56 +00:00
|
|
|
.labelStyle(.titleAndIcon)
|
|
|
|
.environment(\.symbolVariants, .none)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|