Yattee v2 rewrite

This commit is contained in:
Arkadiusz Fal
2026-02-08 18:31:16 +01:00
parent 20d0cfc0c7
commit 05f921d605
1043 changed files with 163875 additions and 68430 deletions

View File

@@ -0,0 +1,115 @@
//
// ChapterRow.swift
// Yattee
//
// Row view for displaying a video chapter.
//
import SwiftUI
struct ChapterRow: View {
let chapter: VideoChapter
let isActive: Bool
let storyboard: Storyboard?
let onTap: () -> Void
@State private var thumbnail: PlatformImage?
var body: some View {
Button(action: onTap) {
HStack(spacing: 12) {
// Thumbnail from storyboard
Group {
if let thumbnail {
#if os(macOS)
Image(nsImage: thumbnail)
.resizable()
.aspectRatio(contentMode: .fill)
#else
Image(uiImage: thumbnail)
.resizable()
.aspectRatio(contentMode: .fill)
#endif
} else {
Rectangle()
.fill(.quaternary)
.overlay {
Image(systemName: "film")
.foregroundStyle(.secondary)
}
}
}
.frame(width: 80, height: 45)
.clipShape(RoundedRectangle(cornerRadius: 4))
// Info
VStack(alignment: .leading, spacing: 4) {
Text(chapter.title)
.font(.subheadline)
.fontWeight(isActive ? .semibold : .regular)
.lineLimit(2)
Text(chapter.formattedStartTime)
.font(.caption)
.foregroundStyle(.secondary)
.monospacedDigit()
}
Spacer()
// Active indicator
if isActive {
Image(systemName: "play.fill")
.font(.caption)
.foregroundStyle(Color.accentColor)
}
}
.padding(.vertical, 4)
}
.buttonStyle(.plain)
.listRowBackground(isActive ? Color.accentColor.opacity(0.1) : nil)
.task {
await loadThumbnail()
}
}
private func loadThumbnail() async {
guard let storyboard else { return }
let service = StoryboardService.shared
// Try cached first
if let cached = await service.thumbnail(for: chapter.startTime, from: storyboard) {
thumbnail = cached
return
}
// Load the sheet
await service.preloadNearbySheets(around: chapter.startTime, from: storyboard)
// Try again after loading
if let loaded = await service.thumbnail(for: chapter.startTime, from: storyboard) {
thumbnail = loaded
}
}
}
// MARK: - Preview
#Preview {
List {
ChapterRow(
chapter: VideoChapter(title: "Introduction", startTime: 0),
isActive: true,
storyboard: nil,
onTap: {}
)
ChapterRow(
chapter: VideoChapter(title: "Main Content", startTime: 60),
isActive: false,
storyboard: nil,
onTap: {}
)
}
.listStyle(.plain)
}