Respond to main branch
This commit is contained in:
parent
3ad789fe08
commit
a16d70ab11
|
@ -23,7 +23,7 @@ final class HomeCoordinator: NavigationCoordinatable {
|
||||||
func resolveRoute(route: Route) -> Transition {
|
func resolveRoute(route: Route) -> Transition {
|
||||||
switch route {
|
switch route {
|
||||||
case .settings:
|
case .settings:
|
||||||
return .modal(SettingsCoordinator().eraseToAnyCoordinatable())
|
return .modal(NavigationViewCoordinator(SettingsCoordinator()).eraseToAnyCoordinatable())
|
||||||
case let .library(viewModel, title):
|
case let .library(viewModel, title):
|
||||||
return .push(LibraryCoordinator(viewModel: viewModel, title: title).eraseToAnyCoordinatable())
|
return .push(LibraryCoordinator(viewModel: viewModel, title: title).eraseToAnyCoordinatable())
|
||||||
case let .item(viewModel):
|
case let .item(viewModel):
|
||||||
|
|
|
@ -14,9 +14,16 @@ import SwiftUI
|
||||||
final class SettingsCoordinator: NavigationCoordinatable {
|
final class SettingsCoordinator: NavigationCoordinatable {
|
||||||
var navigationStack = NavigationStack()
|
var navigationStack = NavigationStack()
|
||||||
|
|
||||||
enum Route: NavigationRoute {}
|
enum Route: NavigationRoute {
|
||||||
|
case serverDetail
|
||||||
|
}
|
||||||
|
|
||||||
func resolveRoute(route: Route) -> Transition {}
|
func resolveRoute(route: Route) -> Transition {
|
||||||
|
switch route {
|
||||||
|
case .serverDetail:
|
||||||
|
return .push(ServerDetailView().eraseToAnyView())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func start() -> some View {
|
func start() -> some View {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Stinsen
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SettingsView: View {
|
struct SettingsView: View {
|
||||||
@EnvironmentObject var mainRouter: ViewRouter<MainCoordinator.Route>
|
@RouterObject var mainRouter: ViewRouter<MainCoordinator.Route>?
|
||||||
@EnvironmentObject var settingsRouter: NavigationRouter<SettingsCoordinator.Route>
|
@EnvironmentObject var settingsRouter: NavigationRouter<SettingsCoordinator.Route>
|
||||||
@Environment(\.managedObjectContext) private var viewContext
|
@Environment(\.managedObjectContext) private var viewContext
|
||||||
|
|
||||||
|
@ -27,125 +27,100 @@ struct SettingsView: View {
|
||||||
@Default(.videoPlayerJumpBackward) var jumpBackwardLength
|
@Default(.videoPlayerJumpBackward) var jumpBackwardLength
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
Form {
|
||||||
Form {
|
Section {
|
||||||
Section(header: EmptyView()) {
|
HStack {
|
||||||
|
Text("User")
|
||||||
|
Spacer()
|
||||||
|
Text(SessionManager.current.user.username ?? "")
|
||||||
|
.foregroundColor(.jellyfinPurple)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
settingsRouter.route(to: .serverDetail)
|
||||||
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
Text("User")
|
Text("Server")
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(SessionManager.current.user.username ?? "")
|
Text(ServerEnvironment.current.server.name ?? "")
|
||||||
.foregroundColor(.jellyfinPurple)
|
.foregroundColor(.jellyfinPurple)
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(
|
|
||||||
destination: ServerDetailView(),
|
|
||||||
label: {
|
|
||||||
HStack {
|
|
||||||
Text("Server")
|
|
||||||
Spacer()
|
|
||||||
Text(ServerEnvironment.current.server.name ?? "")
|
|
||||||
.foregroundColor(.jellyfinPurple)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Button {
|
|
||||||
close = false
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
||||||
SessionManager.current.logout()
|
|
||||||
let nc = NotificationCenter.default
|
|
||||||
nc.post(name: Notification.Name("didSignOut"), object: nil)
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
Text("Sign out")
|
|
||||||
.font(.callout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Section(header: Text("Playback")) {
|
|
||||||
Picker("Default local quality", selection: $inNetworkStreamBitrate) {
|
|
||||||
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
|
||||||
Text(bitrate.name).tag(bitrate.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Picker("Default remote quality", selection: $outOfNetworkStreamBitrate) {
|
|
||||||
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
|
||||||
Text(bitrate.name).tag(bitrate.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Picker("Jump Forward Length", selection: $jumpForwardLength) {
|
|
||||||
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
|
|
||||||
Text(length.label).tag(length.rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Picker("Jump Backward Length", selection: $jumpBackwardLength) {
|
|
||||||
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
|
|
||||||
Text(length.label).tag(length.rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: Text("Accessibility")) {
|
Button {
|
||||||
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
settingsRouter.dismiss {
|
||||||
SearchablePicker(label: "Preferred subtitle language",
|
|
||||||
options: viewModel.langs,
|
|
||||||
optionToString: { $0.name },
|
|
||||||
selected: Binding<TrackLanguage>(get: {
|
|
||||||
viewModel.langs
|
|
||||||
.first(where: { $0.isoCode == autoSelectSubtitlesLangcode
|
|
||||||
}) ??
|
|
||||||
.auto
|
|
||||||
},
|
|
||||||
set: { autoSelectSubtitlesLangcode = $0.isoCode }))
|
|
||||||
SearchablePicker(label: "Preferred audio language",
|
|
||||||
options: viewModel.langs,
|
|
||||||
optionToString: { $0.name },
|
|
||||||
selected: Binding<TrackLanguage>(get: {
|
|
||||||
viewModel.langs
|
|
||||||
.first(where: { $0.isoCode == autoSelectAudioLangcode }) ??
|
|
||||||
.auto
|
|
||||||
},
|
|
||||||
set: { autoSelectAudioLangcode = $0.isoCode }))
|
|
||||||
Picker(NSLocalizedString("Appearance", comment: ""), selection: $appAppearance) {
|
|
||||||
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
|
||||||
Text(appearance.localizedName).tag(appearance.rawValue)
|
|
||||||
}
|
|
||||||
}.onChange(of: appAppearance, perform: { value in
|
|
||||||
guard let appearance = AppAppearance(rawValue: value) else { return }
|
|
||||||
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appearance.style
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Section(header: Text(ServerEnvironment.current.server.name ?? "")) {
|
|
||||||
HStack {
|
|
||||||
Text("Signed in as \(username)").foregroundColor(.primary)
|
|
||||||
Spacer()
|
|
||||||
Button {
|
|
||||||
print("logging out")
|
|
||||||
mainRouter.route(to: .connectToServer)
|
|
||||||
settingsRouter.dismiss()
|
|
||||||
} label: {
|
|
||||||
Text("Switch user").font(.callout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
SessionManager.current.logout()
|
SessionManager.current.logout()
|
||||||
mainRouter.route(to: .connectToServer)
|
mainRouter?.route(to: .connectToServer)
|
||||||
settingsRouter.dismiss()
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Text("Sign out").font(.callout)
|
Text("Sign out")
|
||||||
|
.font(.callout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Section(header: Text("Playback")) {
|
||||||
|
Picker("Default local quality", selection: $inNetworkStreamBitrate) {
|
||||||
|
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
||||||
|
Text(bitrate.name).tag(bitrate.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Picker("Default remote quality", selection: $outOfNetworkStreamBitrate) {
|
||||||
|
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
||||||
|
Text(bitrate.name).tag(bitrate.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Picker("Jump Forward Length", selection: $jumpForwardLength) {
|
||||||
|
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
|
||||||
|
Text(length.label).tag(length.rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Picker("Jump Backward Length", selection: $jumpBackwardLength) {
|
||||||
|
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
|
||||||
|
Text(length.label).tag(length.rawValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitle("Settings", displayMode: .inline)
|
|
||||||
.toolbar {
|
Section(header: Text("Accessibility")) {
|
||||||
ToolbarItemGroup(placement: .navigationBarLeading) {
|
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
||||||
Button {
|
SearchablePicker(label: "Preferred subtitle language",
|
||||||
settingsRouter.dismiss()
|
options: viewModel.langs,
|
||||||
} label: {
|
optionToString: { $0.name },
|
||||||
Image(systemName: "xmark")
|
selected: Binding<TrackLanguage>(get: {
|
||||||
|
viewModel.langs
|
||||||
|
.first(where: { $0.isoCode == autoSelectSubtitlesLangcode
|
||||||
|
}) ??
|
||||||
|
.auto
|
||||||
|
},
|
||||||
|
set: { autoSelectSubtitlesLangcode = $0.isoCode }))
|
||||||
|
SearchablePicker(label: "Preferred audio language",
|
||||||
|
options: viewModel.langs,
|
||||||
|
optionToString: { $0.name },
|
||||||
|
selected: Binding<TrackLanguage>(get: {
|
||||||
|
viewModel.langs
|
||||||
|
.first(where: { $0.isoCode == autoSelectAudioLangcode }) ??
|
||||||
|
.auto
|
||||||
|
},
|
||||||
|
set: { autoSelectAudioLangcode = $0.isoCode }))
|
||||||
|
Picker(NSLocalizedString("Appearance", comment: ""), selection: $appAppearance) {
|
||||||
|
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
||||||
|
Text(appearance.localizedName).tag(appearance.rawValue)
|
||||||
}
|
}
|
||||||
|
}.onChange(of: appAppearance, perform: { value in
|
||||||
|
guard let appearance = AppAppearance(rawValue: value) else { return }
|
||||||
|
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appearance.style
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationBarTitle("Settings", displayMode: .inline)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItemGroup(placement: .navigationBarLeading) {
|
||||||
|
Button {
|
||||||
|
settingsRouter.dismiss()
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "xmark")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ protocol PlayerViewControllerDelegate: AnyObject {
|
||||||
|
|
||||||
class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRemoteMediaClientListener {
|
class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRemoteMediaClientListener {
|
||||||
@RouterObject
|
@RouterObject
|
||||||
var main: ViewRouter<MainCoordinator.Route>?
|
|
||||||
|
|
||||||
weak var delegate: PlayerViewControllerDelegate?
|
weak var delegate: PlayerViewControllerDelegate?
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue