Unify forms, add to/remove from playlist on all platforms, UI improvements

This commit is contained in:
Arkadiusz Fal
2021-09-28 20:06:05 +02:00
parent 17291b47e0
commit 7446c945b5
29 changed files with 644 additions and 448 deletions

View File

@@ -0,0 +1,47 @@
import Defaults
import Foundation
import SwiftUI
struct AccountSelectionView: View {
@EnvironmentObject<InstancesModel> private var instancesModel
@EnvironmentObject<InvidiousAPI> private var api
@Default(.accounts) private var accounts
@Default(.instances) private var instances
var body: some View {
Section(header: Text("Current Account")) {
Button(api.account?.name ?? "Not selected") {
if let account = nextAccount {
api.setAccount(account)
}
}
.disabled(nextAccount == nil)
.contextMenu {
ForEach(instances) { instance in
Button(accountButtonTitle(instance: instance, account: instance.anonymousAccount)) {
api.setAccount(instance.anonymousAccount)
}
ForEach(instancesModel.accounts(instance.id)) { account in
Button(accountButtonTitle(instance: instance, account: account)) {
api.setAccount(account)
}
}
}
}
}
}
private var nextAccount: Instance.Account? {
guard api.account != nil else {
return accounts.first
}
return accounts.next(after: api.account!)
}
func accountButtonTitle(instance: Instance, account: Instance.Account) -> String {
instances.count > 1 ? "\(account.description)\(instance.shortDescription)" : account.description
}
}

View File

@@ -1,99 +0,0 @@
import Defaults
import Siesta
import SwiftUI
struct AddToPlaylistView: View {
@StateObject private var store = Store<[Playlist]>()
@State private var selectedPlaylist: Playlist?
@Default(.videoIDToAddToPlaylist) private var videoID
@Environment(\.dismiss) private var dismiss
@EnvironmentObject<InvidiousAPI> private var api
var resource: Resource {
api.playlists
}
init() {
resource.addObserver(store)
}
var body: some View {
HStack {
Spacer()
VStack {
Spacer()
if !resource.isLoading && store.collection.isEmpty {
CoverSectionView("You have no Playlists", inline: true) {
Text("Open \"Playlists\" tab to create new one")
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
}
Button("Go back") {
dismiss()
}
.padding()
} else if !store.collection.isEmpty {
CoverSectionView("Add to Playlist", inline: true) { selectPlaylistButton }
CoverSectionRowView {
Button("Add", action: addToPlaylist)
.disabled(currentPlaylist.isNil)
}
}
Spacer()
}
.frame(maxWidth: 1200)
Spacer()
}
.background(.thinMaterial)
.onAppear {
resource.loadIfNeeded()?.onSuccess { _ in
selectedPlaylist = store.collection.first
}
}
}
var selectPlaylistButton: some View {
Button(currentPlaylist?.title ?? "Select playlist") {
guard currentPlaylist != nil else {
return
}
self.selectedPlaylist = store.collection.next(after: currentPlaylist!)
}
.contextMenu {
ForEach(store.collection) { playlist in
Button(playlist.title) {
self.selectedPlaylist = playlist
}
}
}
}
var currentPlaylist: Playlist? {
selectedPlaylist ?? store.collection.first
}
func addToPlaylist() {
guard currentPlaylist != nil else {
return
}
let resource = api.playlistVideos(currentPlaylist!.id)
let body = ["videoId": videoID]
resource.request(.post, json: body).onSuccess { _ in
Defaults.reset(.videoIDToAddToPlaylist)
api.playlists.load()
dismiss()
}
}
}

View File

@@ -1,46 +0,0 @@
import Defaults
import SwiftUI
struct OptionsView: View {
@EnvironmentObject<NavigationModel> private var navigation
@Environment(\.dismiss) private var dismiss
var body: some View {
HStack {
VStack {
HStack {
Spacer()
VStack(alignment: .leading) {
Spacer()
CoverSectionView("View Options") {
// CoverSectionRowView("Show videos as") { nextLayoutButton }
}
CoverSectionView(divider: false) {
CoverSectionRowView("Close View Options") { Button("Close") { dismiss() } }
}
Spacer()
SettingsView()
}
.frame(maxWidth: 800)
Spacer()
}
Spacer()
}
}
.background(.thinMaterial)
}
}
struct OptionsView_Previews: PreviewProvider {
static var previews: some View {
OptionsView()
}
}

View File

@@ -7,10 +7,6 @@ struct TVNavigationView: View {
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
@State private var showingOptions = false
@Default(.showingAddToPlaylist) var showingAddToPlaylist
var body: some View {
TabView(selection: $navigation.tabSelection) {
WatchNowView()
@@ -37,8 +33,12 @@ struct TVNavigationView: View {
.tabItem { Image(systemName: "magnifyingglass") }
.tag(TabSelection.search)
}
.fullScreenCover(isPresented: $showingOptions) { OptionsView() }
.fullScreenCover(isPresented: $showingAddToPlaylist) { AddToPlaylistView() }
.fullScreenCover(isPresented: $navigation.presentingSettings) { SettingsView() }
.fullScreenCover(isPresented: $navigation.presentingAddToPlaylist) {
if let video = navigation.videoToAddToPlaylist {
AddToPlaylistView(video: video)
}
}
.fullScreenCover(isPresented: $navigation.showingVideo) {
if let video = navigation.video {
VideoPlayerView(video)
@@ -48,15 +48,19 @@ struct TVNavigationView: View {
.fullScreenCover(isPresented: $navigation.isChannelOpen) {
if let channel = recents.presentedChannel {
ChannelVideosView(channel: channel)
.background(.thickMaterial)
}
}
.onPlayPauseCommand { showingOptions.toggle() }
.onPlayPauseCommand { navigation.presentingSettings.toggle() }
}
}
struct TVNavigationView_Previews: PreviewProvider {
static var previews: some View {
TVNavigationView()
.environmentObject(InvidiousAPI())
.environmentObject(NavigationModel())
.environmentObject(SearchModel())
.environmentObject(InstancesModel())
.environmentObject(SubscriptionsModel())
}
}