mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 01:39:46 +00:00
Yattee v2 rewrite
This commit is contained in:
136
Yattee/Views/Home/PlaylistsListView.swift
Normal file
136
Yattee/Views/Home/PlaylistsListView.swift
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// PlaylistsListView.swift
|
||||
// Yattee
|
||||
//
|
||||
// Full page view for listing all playlists.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct PlaylistsListView: View {
|
||||
@Environment(\.appEnvironment) private var appEnvironment
|
||||
@State private var playlists: [LocalPlaylist] = []
|
||||
@State private var showingNewPlaylist = false
|
||||
@State private var playlistToEdit: LocalPlaylist?
|
||||
|
||||
private var dataManager: DataManager? { appEnvironment?.dataManager }
|
||||
|
||||
/// List style from centralized settings.
|
||||
private var listStyle: VideoListStyle {
|
||||
appEnvironment?.settingsManager.listStyle ?? .inset
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if playlists.isEmpty {
|
||||
emptyView
|
||||
} else {
|
||||
listContent
|
||||
}
|
||||
}
|
||||
.navigationTitle(String(localized: "home.playlists.title"))
|
||||
#if !os(tvOS)
|
||||
.toolbarTitleDisplayMode(.inlineLarge)
|
||||
#endif
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Button {
|
||||
showingNewPlaylist = true
|
||||
} label: {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showingNewPlaylist) {
|
||||
PlaylistFormSheet(mode: .create) { title, description in
|
||||
_ = dataManager?.createPlaylist(title: title, description: description)
|
||||
loadPlaylists()
|
||||
}
|
||||
}
|
||||
.sheet(item: $playlistToEdit) { playlist in
|
||||
PlaylistFormSheet(mode: .edit(playlist)) { newTitle, newDescription in
|
||||
dataManager?.updatePlaylist(playlist, title: newTitle, description: newDescription)
|
||||
loadPlaylists()
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
loadPlaylists()
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .playlistsDidChange)) { _ in
|
||||
loadPlaylists()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Empty View
|
||||
|
||||
private var emptyView: some View {
|
||||
ContentUnavailableView {
|
||||
Label(String(localized: "home.playlists.title"), systemImage: "list.bullet.rectangle")
|
||||
} description: {
|
||||
Text(String(localized: "home.empty.description"))
|
||||
} actions: {
|
||||
Button {
|
||||
showingNewPlaylist = true
|
||||
} label: {
|
||||
Label(String(localized: "home.playlists.new"), systemImage: "plus")
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - List Content
|
||||
|
||||
private var listContent: some View {
|
||||
VideoListContainer(listStyle: listStyle, rowStyle: .regular) {
|
||||
Spacer()
|
||||
.frame(height: 16)
|
||||
} content: {
|
||||
ForEach(Array(playlists.enumerated()), id: \.element.id) { index, playlist in
|
||||
VideoListRow(
|
||||
isLast: index == playlists.count - 1,
|
||||
rowStyle: .regular,
|
||||
listStyle: listStyle,
|
||||
contentWidth: 80 // PlaylistRowView thumbnail width
|
||||
) {
|
||||
playlistRow(playlist: playlist)
|
||||
}
|
||||
.swipeActions {
|
||||
SwipeAction(
|
||||
symbolImage: "pencil",
|
||||
tint: .white,
|
||||
background: .orange
|
||||
) { reset in
|
||||
playlistToEdit = playlist
|
||||
reset()
|
||||
}
|
||||
SwipeAction(
|
||||
symbolImage: "trash.fill",
|
||||
tint: .white,
|
||||
background: .red
|
||||
) { reset in
|
||||
dataManager?.deletePlaylist(playlist)
|
||||
loadPlaylists()
|
||||
reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helper Views
|
||||
|
||||
@ViewBuilder
|
||||
private func playlistRow(playlist: LocalPlaylist) -> some View {
|
||||
PlaylistRowView(playlist: playlist)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
appEnvironment?.navigationCoordinator.navigate(to: .playlist(.local(playlist.id, title: playlist.title)))
|
||||
}
|
||||
.zoomTransitionSource(id: playlist.id)
|
||||
}
|
||||
|
||||
private func loadPlaylists() {
|
||||
playlists = (dataManager?.playlists() ?? []).sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == .orderedAscending }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user