Refactor views

This commit is contained in:
Arkadiusz Fal
2026-02-09 01:13:02 +01:00
parent 8464464199
commit 612dce6b9f
43 changed files with 143 additions and 125 deletions

View File

@@ -10,13 +10,13 @@ import SwiftUI
/// A bookmark card for grid/horizontal scroll layouts.
/// Displays video content via VideoCardView with additional tags/notes.
struct BookmarkCardView: View {
@Environment(\.appEnvironment) private var appEnvironment
let bookmark: Bookmark
var watchProgress: Double? = nil
/// Use compact styling for dense grids (3+ columns).
var isCompact: Bool = false
@Environment(\.appEnvironment) private var appEnvironment
private var accentColor: Color {
appEnvironment?.settingsManager.accentColor.color ?? .accentColor
}

View File

@@ -12,6 +12,8 @@ import SwiftUI
/// Automatically handles DeArrow integration.
/// Supports optional queue context for auto-play functionality.
struct BookmarkRowView: View {
@Environment(\.appEnvironment) private var appEnvironment
let bookmark: Bookmark
var style: VideoRowStyle = .regular
var watchProgress: Double? = nil
@@ -24,8 +26,6 @@ struct BookmarkRowView: View {
var videoIndex: Int? = nil
var loadMoreVideos: LoadMoreVideosCallback? = nil
@Environment(\.appEnvironment) private var appEnvironment
private var accentColor: Color {
appEnvironment?.settingsManager.accentColor.color ?? .accentColor
}

View File

@@ -9,11 +9,11 @@ import SwiftUI
/// Read-only display of bookmark tags with optional overflow indicator.
struct BookmarkTagsView: View {
@Environment(\.appEnvironment) private var appEnvironment
let tags: [String]
var maxVisible: Int = 3
@Environment(\.appEnvironment) private var appEnvironment
private var accentColor: Color {
appEnvironment?.settingsManager.accentColor.color ?? .accentColor
}

View File

@@ -9,12 +9,13 @@ import SwiftUI
import NukeUI
struct CommentView: View {
@Environment(\.appEnvironment) private var appEnvironment
let comment: Comment
let videoID: String?
let source: ContentSource?
let isReply: Bool
@Environment(\.appEnvironment) private var appEnvironment
@State private var replies: [Comment] = []
@State private var isLoadingReplies = false
@State private var showReplies = false

View File

@@ -19,6 +19,8 @@ import SwiftUI
/// tracks dictionary access per-key, so this view only re-renders when THIS video's
/// progress changes - not when any other download progresses.
struct DeArrowVideoThumbnail: View {
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
var cornerRadius: CGFloat = 8
@@ -26,7 +28,6 @@ struct DeArrowVideoThumbnail: View {
var duration: String? = nil
var durationAlignment: Alignment = .bottomLeading
@Environment(\.appEnvironment) private var appEnvironment
@State private var isWatched = false
private var deArrowProvider: DeArrowBrandingProvider? {

View File

@@ -8,12 +8,12 @@
import SwiftUI
struct ExpandableText: View {
let text: String
var lineLimit: Int = 2
@Binding var isExpanded: Bool
@Environment(\.font) private var font
let text: String
var lineLimit: Int = 2
@Binding var isExpanded: Bool
@State private var fullHeight: CGFloat = 0
@State private var truncatedHeight: CGFloat = 0

View File

@@ -8,6 +8,8 @@
import SwiftUI
struct ExpandedCommentsView: View {
@Environment(\.appEnvironment) private var appEnvironment
let videoID: String
let onClose: () -> Void
var onDismissOffsetChanged: ((CGFloat) -> Void)? = nil
@@ -18,8 +20,6 @@ struct ExpandedCommentsView: View {
var onDragChanged: ((CGFloat) -> Void)? = nil
var onDragEnded: ((CGFloat, CGFloat) -> Void)? = nil
@Environment(\.appEnvironment) private var appEnvironment
@State private var showScrollButton = false
@State private var scrollToTopTrigger: Int = 0
@State private var scrollBounceOffset: CGFloat = 0

View File

@@ -9,12 +9,12 @@ import SwiftUI
/// A sheet that appears when tapping a video, offering options to play or add to queue.
struct QueueActionSheet: View {
let video: Video
var queueSource: QueueSource?
@Environment(\.dismiss) private var dismiss
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
var queueSource: QueueSource?
var body: some View {
VStack(spacing: 0) {
// Drag indicator

View File

@@ -9,13 +9,13 @@ import SwiftUI
/// A sheet that appears when playing a partially watched video, offering options to resume or start over.
struct ResumeActionSheet: View {
@Environment(\.dismiss) private var dismiss
let video: Video
let resumeTime: TimeInterval
let onContinue: () -> Void
let onStartOver: () -> Void
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack(spacing: 0) {
// Drag indicator

View File

@@ -9,9 +9,10 @@ import SwiftUI
/// Shows source badge only when user has multiple sources configured.
struct SourceBadge: View {
let source: ContentSource
@Environment(\.appEnvironment) private var appEnvironment
let source: ContentSource
var body: some View {
if shouldShowBadge {
HStack(spacing: 2) {

View File

@@ -8,11 +8,11 @@
import SwiftUI
struct TagInputView: View {
@Environment(\.appEnvironment) private var appEnvironment
@Binding var tags: [String]
var isFocused: Bool = false
@Environment(\.appEnvironment) private var appEnvironment
@State private var inputText: String = ""
@State private var showMaxTagsWarning = false
@State private var showMaxLengthWarning = false

View File

@@ -18,6 +18,8 @@ struct ResumeSheetData: Identifiable {
/// When queue is enabled and not empty, shows a sheet with queue options.
/// When queue is empty or disabled, plays the video directly and queues subsequent videos.
struct TappableVideoModifier: ViewModifier {
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
var startTime: Double? = nil
var customActions: [VideoContextAction] = []
@@ -31,16 +33,15 @@ struct TappableVideoModifier: ViewModifier {
var videoList: [Video]? = nil
/// Index of this video in the list
var videoIndex: Int? = nil
/// Callback to load more videos via continuation
nonisolated(unsafe) var loadMoreVideos: LoadMoreVideosCallback? = nil
@Environment(\.appEnvironment) private var appEnvironment
@State private var showingQueueSheet = false
// Resume action sheet state - using item-based sheet to ensure data is available when presented
@State private var resumeSheetData: ResumeSheetData? = nil
// Password alert state (for WebDAV sources)
@State private var showingPasswordAlert = false
@State private var sourceNeedingPassword: MediaSource?

View File

@@ -13,6 +13,9 @@ import SwiftUI
/// Download status is automatically shown from the download manager.
/// On iOS/macOS, supports configurable tap zones for thumbnail and text area.
struct VideoCardView: View {
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var videoQueueContext
let video: Video
var watchProgress: Double? = nil
/// Use compact styling for dense grids (3+ columns).
@@ -22,9 +25,6 @@ struct VideoCardView: View {
/// Custom duration text to show on thumbnail (e.g., remaining time). If nil, uses video.formattedDuration.
var customDuration: String? = nil
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var videoQueueContext
// Platform-specific fonts
#if os(tvOS)
private var titleFont: Font { isCompact ? .subheadline : .body }

View File

@@ -41,13 +41,14 @@ enum VideoContextMenuContext {
/// View modifier that attaches VideoContextMenu and its required sheets.
struct VideoContextMenuModifier: ViewModifier {
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
var customActions: [VideoContextAction] = []
var context: VideoContextMenuContext = .default
var startTime: Double? = nil
var watchProgress: Double? = nil
@Environment(\.appEnvironment) private var appEnvironment
@State private var showingPlaylistSheet = false
@State private var showingDownloadSheet = false
@State private var showingDeleteDownloadConfirmation = false
@@ -128,6 +129,8 @@ struct VideoContextMenuModifier: ViewModifier {
/// The actual menu content (uses bindings from parent for sheet presentation).
/// All observable values are snapshotted at init time to prevent redraws during playback.
struct VideoContextMenuContent: View {
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
var customActions: [VideoContextAction] = []
var context: VideoContextMenuContext = .default
@@ -137,8 +140,6 @@ struct VideoContextMenuContent: View {
@Binding var showingDeleteDownloadConfirmation: Bool
@Binding var downloadToDelete: Download?
@Environment(\.appEnvironment) private var appEnvironment
// MARK: - Snapshotted Values (captured at init to prevent observation)
/// Snapshotted remote control enabled state.
@@ -592,13 +593,14 @@ extension View {
/// A dropdown menu view for videos, showing context menu actions.
/// Used in player views where the video is already playing.
struct VideoContextMenuView: View {
@Environment(\.appEnvironment) private var appEnvironment
let video: Video
let accentColor: Color
var buttonSize: CGFloat = 32
var buttonBackgroundStyle: ButtonBackgroundStyle = .none
var theme: ControlsTheme = .dark
@Environment(\.appEnvironment) private var appEnvironment
@State private var showingPlaylistSheet = false
@State private var showingDownloadSheet = false
@State private var showingDeleteDownloadConfirmation = false

View File

@@ -13,6 +13,9 @@ import SwiftUI
/// Download status is automatically shown from the download manager.
/// On iOS/macOS, supports configurable tap zones for thumbnail and text area.
struct VideoRowView: View {
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var videoQueueContext
let video: Video
var style: VideoRowStyle = .regular
var watchProgress: Double? = nil
@@ -24,9 +27,6 @@ struct VideoRowView: View {
/// When true, disables internal tap handling so parent view can handle all taps.
var disableInternalTapHandling: Bool = false
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var videoQueueContext
// Platform-specific fonts
#if os(tvOS)
private var titleFont: Font {

View File

@@ -10,11 +10,12 @@ import SwiftUI
#if !os(tvOS)
/// View modifier that applies user-configurable swipe actions plus fixed context-specific actions.
struct VideoSwipeActionsModifier: ViewModifier {
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var queueContext
let video: Video
var fixedActions: [SwipeAction] = []
@Environment(\.appEnvironment) private var appEnvironment
@Environment(\.videoQueueContext) private var queueContext
@State private var showingPlaylistSheet = false
@State private var showingDownloadSheet = false