[tvOS] SelectServerView Change to Menu (#1363)
* Selection & Fix ServerSelectionMenu padding * ButtonStyle * Move from `FullScreenMenu` to just use `Menu` Remove usages of `FullScreenMenu` since it's no longer used anywhere else. * Remove unused `FullScreenMenu` * Remove unused `SelectServerView` since it's now in the `ServerSelectionMenu` * Selection menu fixes * Focus issues * clean up --------- Co-authored-by: Ethan Pippin <ethanpippin2343@gmail.com>
This commit is contained in:
parent
97affd198e
commit
d580e8dcfd
|
@ -12,11 +12,6 @@ import SwiftUI
|
|||
|
||||
final class SelectUserCoordinator: NavigationCoordinatable {
|
||||
|
||||
struct SelectServerParameters {
|
||||
let selection: Binding<SelectUserServerSelection>
|
||||
let viewModel: SelectUserViewModel
|
||||
}
|
||||
|
||||
let stack = NavigationStack(initial: \SelectUserCoordinator.start)
|
||||
|
||||
@Root
|
||||
|
@ -31,11 +26,6 @@ final class SelectUserCoordinator: NavigationCoordinatable {
|
|||
@Route(.modal)
|
||||
var userSignIn = makeUserSignIn
|
||||
|
||||
#if os(tvOS)
|
||||
@Route(.fullScreen)
|
||||
var selectServer = makeSelectServer
|
||||
#endif
|
||||
|
||||
func makeAdvancedSettings() -> NavigationViewCoordinator<AppSettingsCoordinator> {
|
||||
NavigationViewCoordinator(AppSettingsCoordinator())
|
||||
}
|
||||
|
@ -62,15 +52,6 @@ final class SelectUserCoordinator: NavigationCoordinatable {
|
|||
NavigationViewCoordinator(UserSignInCoordinator(server: server))
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
func makeSelectServer(parameters: SelectServerParameters) -> some View {
|
||||
SelectServerView(
|
||||
selection: parameters.selection,
|
||||
viewModel: parameters.viewModel
|
||||
)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ViewBuilder
|
||||
func makeStart() -> some View {
|
||||
SelectUserView()
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
//
|
||||
// Swiftfin is subject to the terms of the Mozilla Public
|
||||
// License, v2.0. If a copy of the MPL was not distributed with this
|
||||
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct FullScreenMenu<Content: View>: View {
|
||||
|
||||
private let content: () -> Content
|
||||
private let title: String
|
||||
|
||||
init(_ title: String, @ViewBuilder content: @escaping () -> Content) {
|
||||
self.title = title
|
||||
self.content = content
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Color.black
|
||||
.opacity(0.5)
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
VStack {
|
||||
Text(title)
|
||||
.font(.title2)
|
||||
.fontWeight(.bold)
|
||||
|
||||
ScrollView {
|
||||
VStack {
|
||||
content()
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
}
|
||||
.frame(width: 580)
|
||||
}
|
||||
.padding(.top, 20)
|
||||
.background(Material.regular, in: RoundedRectangle(cornerRadius: 30))
|
||||
.frame(width: 620)
|
||||
.padding(100)
|
||||
.shadow(radius: 50)
|
||||
}
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
//
|
||||
// Swiftfin is subject to the terms of the Mozilla Public
|
||||
// License, v2.0. If a copy of the MPL was not distributed with this
|
||||
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
||||
//
|
||||
|
||||
import CollectionVGrid
|
||||
import SwiftUI
|
||||
|
||||
struct SelectServerView: View {
|
||||
|
||||
@EnvironmentObject
|
||||
private var router: SelectUserCoordinator.Router
|
||||
|
||||
@Binding
|
||||
private var serverSelection: SelectUserServerSelection
|
||||
|
||||
@ObservedObject
|
||||
private var viewModel: SelectUserViewModel
|
||||
|
||||
private var selectedServer: ServerState? {
|
||||
if case let SelectUserServerSelection.server(id: id) = serverSelection,
|
||||
let server = viewModel.servers.keys.first(where: { server in server.id == id })
|
||||
{
|
||||
return server
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
init(
|
||||
selection: Binding<SelectUserServerSelection>,
|
||||
viewModel: SelectUserViewModel
|
||||
) {
|
||||
self._serverSelection = selection
|
||||
self.viewModel = viewModel
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
FullScreenMenu(L10n.servers) {
|
||||
Section {
|
||||
Button {
|
||||
router.popLast {
|
||||
router.route(to: \.connectToServer)
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
L10n.addServer.text
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
}
|
||||
|
||||
if let selectedServer {
|
||||
Button {
|
||||
router.popLast {
|
||||
router.route(to: \.editServer, selectedServer)
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
L10n.editServer.text
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "server.rack")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
|
||||
if viewModel.servers.keys.count > 1 {
|
||||
Button {
|
||||
serverSelection = .all
|
||||
router.popLast()
|
||||
} label: {
|
||||
HStack {
|
||||
L10n.allServers.text
|
||||
|
||||
Spacer()
|
||||
|
||||
if serverSelection == .all {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ForEach(viewModel.servers.keys.reversed()) { server in
|
||||
Button {
|
||||
serverSelection = .server(id: server.id)
|
||||
router.popLast()
|
||||
} label: {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Text(server.name)
|
||||
.font(.headline)
|
||||
.fontWeight(.semibold)
|
||||
|
||||
Text(server.currentURL.absoluteString)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
if selectedServer == server {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.card)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
} header: {
|
||||
Text(L10n.servers)
|
||||
}
|
||||
.headerProminence(.increased)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,17 +12,18 @@ extension SelectUserView {
|
|||
|
||||
struct ServerSelectionMenu: View {
|
||||
|
||||
// MARK: - Observed & Environment Objects
|
||||
|
||||
@EnvironmentObject
|
||||
private var router: SelectUserCoordinator.Router
|
||||
|
||||
@Binding
|
||||
private var serverSelection: SelectUserServerSelection
|
||||
|
||||
@ObservedObject
|
||||
private var viewModel: SelectUserViewModel
|
||||
|
||||
@State
|
||||
private var isPresentingServers: Bool = false
|
||||
// MARK: - Server Selection
|
||||
|
||||
@Binding
|
||||
private var serverSelection: SelectUserServerSelection
|
||||
|
||||
private var selectedServer: ServerState? {
|
||||
if case let SelectUserServerSelection.server(id: id) = serverSelection,
|
||||
|
@ -34,6 +35,8 @@ extension SelectUserView {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MARK: - Initializer
|
||||
|
||||
init(
|
||||
selection: Binding<SelectUserServerSelection>,
|
||||
viewModel: SelectUserViewModel
|
||||
|
@ -42,34 +45,57 @@ extension SelectUserView {
|
|||
self.viewModel = viewModel
|
||||
}
|
||||
|
||||
// MARK: - Body
|
||||
|
||||
var body: some View {
|
||||
Menu {
|
||||
Picker(L10n.servers, selection: _serverSelection) {
|
||||
ForEach(viewModel.servers.keys) { server in
|
||||
Button {
|
||||
let parameters = SelectUserCoordinator.SelectServerParameters(
|
||||
selection: _serverSelection,
|
||||
viewModel: viewModel
|
||||
)
|
||||
|
||||
router.route(to: \.selectServer, parameters)
|
||||
Text(server.name)
|
||||
Text(server.currentURL.absoluteString)
|
||||
}
|
||||
.tag(SelectUserServerSelection.server(id: server.id))
|
||||
}
|
||||
if viewModel.servers.keys.count > 1 {
|
||||
Label(L10n.allServers, systemImage: "person.2.fill")
|
||||
.tag(SelectUserServerSelection.all)
|
||||
}
|
||||
}
|
||||
Section {
|
||||
if let selectedServer {
|
||||
Button(L10n.editServer, systemImage: "server.rack") {
|
||||
router.route(to: \.editServer, selectedServer)
|
||||
}
|
||||
}
|
||||
Button(L10n.addServer, systemImage: "plus") {
|
||||
router.route(to: \.connectToServer)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
ZStack {
|
||||
|
||||
Group {
|
||||
HStack(spacing: 16) {
|
||||
switch serverSelection {
|
||||
case .all:
|
||||
Label(L10n.allServers, systemImage: "person.2.fill")
|
||||
Image(systemName: "person.2.fill")
|
||||
Text(L10n.allServers)
|
||||
case let .server(id):
|
||||
if let server = viewModel.servers.keys.first(where: { $0.id == id }) {
|
||||
Label(server.name, systemImage: "server.rack")
|
||||
Image(systemName: "server.rack")
|
||||
Text(server.name)
|
||||
}
|
||||
}
|
||||
Image(systemName: "chevron.up.chevron.down")
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.subheadline.weight(.semibold))
|
||||
}
|
||||
.font(.body.weight(.semibold))
|
||||
.foregroundStyle(Color.primary)
|
||||
}
|
||||
.frame(height: 50)
|
||||
.frame(maxWidth: 400)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
}
|
||||
.menuOrder(.fixed)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -881,7 +881,6 @@
|
|||
E193D5432719407E00900D82 /* tvOSMainCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D5422719407E00900D82 /* tvOSMainCoordinator.swift */; };
|
||||
E193D547271941C500900D82 /* SelectUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D546271941C500900D82 /* SelectUserView.swift */; };
|
||||
E193D549271941CC00900D82 /* UserSignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D548271941CC00900D82 /* UserSignInView.swift */; };
|
||||
E193D54B271941D300900D82 /* SelectServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D54A271941D300900D82 /* SelectServerView.swift */; };
|
||||
E193D5502719430400900D82 /* ServerDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D54F2719430400900D82 /* ServerDetailView.swift */; };
|
||||
E193D5512719432400900D82 /* ServerConnectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E173DA5326D050F500CC4EB7 /* ServerConnectionViewModel.swift */; };
|
||||
E193D553271943D500900D82 /* tvOSMainTabCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D552271943D500900D82 /* tvOSMainTabCoordinator.swift */; };
|
||||
|
@ -1774,7 +1773,6 @@
|
|||
E193D5422719407E00900D82 /* tvOSMainCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tvOSMainCoordinator.swift; sourceTree = "<group>"; };
|
||||
E193D546271941C500900D82 /* SelectUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectUserView.swift; sourceTree = "<group>"; };
|
||||
E193D548271941CC00900D82 /* UserSignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSignInView.swift; sourceTree = "<group>"; };
|
||||
E193D54A271941D300900D82 /* SelectServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectServerView.swift; sourceTree = "<group>"; };
|
||||
E193D54F2719430400900D82 /* ServerDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerDetailView.swift; sourceTree = "<group>"; };
|
||||
E193D552271943D500900D82 /* tvOSMainTabCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tvOSMainTabCoordinator.swift; sourceTree = "<group>"; };
|
||||
E19D41A62BEEDC450082B8B2 /* UserLocalSecurityViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserLocalSecurityViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -2980,7 +2978,6 @@
|
|||
E1A42E4928CA6CCD00A14DCB /* CinematicItemSelector.swift */,
|
||||
E1C92618288756BD002A7A66 /* DotHStack.swift */,
|
||||
E12E30F4296392EC0022FAC9 /* EnumPickerView.swift */,
|
||||
E1763A652BF3CA83004DF6AB /* FullScreenMenu.swift */,
|
||||
E1549677296CB22B00C4EF88 /* InlineEnumToggle.swift */,
|
||||
E1A42E5028CBE44500A14DCB /* LandscapePosterProgressBar.swift */,
|
||||
E1763A632BF3C9AA004DF6AB /* ListRowButton.swift */,
|
||||
|
@ -3737,7 +3734,6 @@
|
|||
E10B1E8C2BD7708900A92EAF /* QuickConnectView.swift */,
|
||||
E1E1643928BAC2EF00323B0A /* SearchView.swift */,
|
||||
4EF18B232CB9932F00343666 /* PagingLibraryView */,
|
||||
E193D54A271941D300900D82 /* SelectServerView.swift */,
|
||||
E164A8122BE4995200A54B18 /* SelectUserView */,
|
||||
E193D54F2719430400900D82 /* ServerDetailView.swift */,
|
||||
E1E5D54D2783E66600692DFE /* SettingsView */,
|
||||
|
@ -5234,7 +5230,6 @@
|
|||
4ECF5D8B2D0A57EF00F066B1 /* DynamicDayOfWeek.swift in Sources */,
|
||||
62E632ED267D410B0063E547 /* SeriesItemViewModel.swift in Sources */,
|
||||
5398514526B64DA100101B49 /* SettingsView.swift in Sources */,
|
||||
E193D54B271941D300900D82 /* SelectServerView.swift in Sources */,
|
||||
E1575E91293E7B1E001665B1 /* URL.swift in Sources */,
|
||||
53ABFDE6267974EF00886593 /* SettingsViewModel.swift in Sources */,
|
||||
E10B1EC22BD9AD6100A92EAF /* V1UserModel.swift in Sources */,
|
||||
|
@ -5485,7 +5480,6 @@
|
|||
E193D553271943D500900D82 /* tvOSMainTabCoordinator.swift in Sources */,
|
||||
4E8B34EB2AB91B6E0018F305 /* ItemFilter.swift in Sources */,
|
||||
E174121029AE9D94003EF3B5 /* NavigationCoordinatable.swift in Sources */,
|
||||
E1763A662BF3CA83004DF6AB /* FullScreenMenu.swift in Sources */,
|
||||
E14EDECD2B8FB709000F00A4 /* ItemYear.swift in Sources */,
|
||||
E154965F296CA2EF00C4EF88 /* DownloadTask.swift in Sources */,
|
||||
E154967E296CCB6C00C4EF88 /* BasicNavigationCoordinator.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue