IceCubesApp/Packages/Status/Sources/Status/Row/Subviews/StatusRowSwipeView.swift
Thomas Ricouard 6c307aba63 SwiftFormat
2023-03-13 13:38:28 +01:00

131 lines
5.6 KiB
Swift

import DesignSystem
import Env
import Models
import SwiftUI
struct StatusRowSwipeView: View {
@EnvironmentObject private var theme: Theme
@EnvironmentObject private var preferences: UserPreferences
@EnvironmentObject private var currentAccount: CurrentAccount
@EnvironmentObject private var statusDataController: StatusDataController
enum Mode {
case leading, trailing
}
func privateBoost() -> Bool {
return viewModel.status.visibility == .priv && viewModel.status.account.id == currentAccount.account?.id
}
@ObservedObject var viewModel: StatusRowViewModel
let mode: Mode
var body: some View {
switch mode {
case .leading:
leadingSwipeActions
case .trailing:
trailingSwipeActions
}
}
@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))
case .favorite:
makeSwipeButtonForTask(action: action) {
await statusDataController.toggleFavorite(remoteStatus: nil)
}
case .boost:
makeSwipeButtonForTask(action: action, privateBoost: privateBoost()) {
await statusDataController.toggleReblog(remoteStatus: nil)
}
.disabled(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv && viewModel.status.account.id != currentAccount.account?.id)
case .bookmark:
makeSwipeButtonForTask(action: action) {
await statusDataController.toggleBookmark(remoteStatus: nil)
}
case .none:
EmptyView()
}
}
@ViewBuilder
private func makeSwipeButtonForRouterPath(action: StatusAction, destination: SheetDestination) -> some View {
Button {
HapticManager.shared.fireHaptic(of: .notification(.success))
viewModel.routerPath.presentedSheet = destination
} label: {
makeSwipeLabel(action: action, style: preferences.swipeActionsIconStyle)
}
}
@ViewBuilder
private func makeSwipeButtonForTask(action: StatusAction, privateBoost: Bool = false, task: @escaping () async -> Void) -> some View {
Button {
Task {
HapticManager.shared.fireHaptic(of: .notification(.success))
await task()
}
} label: {
makeSwipeLabel(action: action, style: preferences.swipeActionsIconStyle, privateBoost: privateBoost)
}
}
@ViewBuilder
private func makeSwipeLabel(action: StatusAction, style: UserPreferences.SwipeActionsIconStyle, privateBoost: Bool = false) -> some View {
switch style {
case .iconOnly:
Label(action.displayName(isReblogged: statusDataController.isReblogged,
isFavorited: statusDataController.isFavorited,
isBookmarked: statusDataController.isBookmarked,
privateBoost: privateBoost),
imageNamed: action.iconName(isReblogged: statusDataController.isReblogged,
isFavorited: statusDataController.isFavorited,
isBookmarked: statusDataController.isBookmarked,
privateBoost: privateBoost))
.labelStyle(.iconOnly)
.environment(\.symbolVariants, .none)
case .iconWithText:
Label(action.displayName(isReblogged: statusDataController.isReblogged,
isFavorited: statusDataController.isFavorited,
isBookmarked: statusDataController.isBookmarked,
privateBoost: privateBoost),
imageNamed: action.iconName(isReblogged: statusDataController.isReblogged,
isFavorited: statusDataController.isFavorited,
isBookmarked: statusDataController.isBookmarked,
privateBoost: privateBoost))
.labelStyle(.titleAndIcon)
.environment(\.symbolVariants, .none)
}
}
}