Implement BasicAppSettingsView, purge, and fix iOS discovering servers
This commit is contained in:
parent
f3a6cee8ca
commit
30bf12bea2
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
/*
|
||||
* 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 2021 Aiden Vigue & Jellyfin Contributors
|
||||
*/
|
||||
|
||||
import Defaults
|
||||
import Stinsen
|
||||
import SwiftUI
|
||||
|
||||
struct BasicAppSettingsView: View {
|
||||
|
||||
@EnvironmentObject var basicAppSettingsRouter: BasicAppSettingsCoordinator.Router
|
||||
@ObservedObject var viewModel: BasicAppSettingsViewModel
|
||||
@State var resetTapped: Bool = false
|
||||
|
||||
@Default(.appAppearance) var appAppearance
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section {
|
||||
Picker(NSLocalizedString("Appearance", comment: ""), selection: $appAppearance) {
|
||||
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
||||
Text(appearance.localizedName).tag(appearance.rawValue)
|
||||
}
|
||||
}.onChange(of: appAppearance, perform: { _ in
|
||||
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appAppearance.style
|
||||
})
|
||||
} header: {
|
||||
Text("Accessibility")
|
||||
}
|
||||
|
||||
Button {
|
||||
resetTapped = true
|
||||
} label: {
|
||||
Text("Reset")
|
||||
}
|
||||
}
|
||||
.alert("Reset", isPresented: $resetTapped, actions: {
|
||||
Button(role: .destructive) {
|
||||
viewModel.reset()
|
||||
basicAppSettingsRouter.dismissCoordinator()
|
||||
} label: {
|
||||
Text("Reset")
|
||||
}
|
||||
})
|
||||
.navigationTitle("Settings")
|
||||
}
|
||||
}
|
|
@ -91,7 +91,7 @@ struct ServerListView: View {
|
|||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var toolbarContent: some View {
|
||||
private var trailingToolbarContent: some View {
|
||||
if viewModel.servers.isEmpty {
|
||||
EmptyView()
|
||||
} else {
|
||||
|
@ -100,6 +100,13 @@ struct ServerListView: View {
|
|||
} label: {
|
||||
Image(systemName: "plus.circle.fill")
|
||||
}
|
||||
.contextMenu {
|
||||
Button {
|
||||
serverListRouter.route(to: \.basicAppSettings)
|
||||
} label: {
|
||||
Text("Settings")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +115,7 @@ struct ServerListView: View {
|
|||
.navigationTitle("Servers")
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||
toolbarContent
|
||||
trailingToolbarContent
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
|
|
|
@ -206,8 +206,6 @@
|
|||
62C29EA326D1030F00C1D2E7 /* ConnectToServerCoodinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */; };
|
||||
62C29EA626D1036A00C1D2E7 /* HomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */; };
|
||||
62C29EA826D103D500C1D2E7 /* LibraryListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */; };
|
||||
62CB3F4B2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; };
|
||||
62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; };
|
||||
62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */; };
|
||||
62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
|
||||
62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
|
||||
|
@ -329,6 +327,9 @@
|
|||
E1D4BF882719D27100A11E64 /* Bitrates.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF862719D27100A11E64 /* Bitrates.swift */; };
|
||||
E1D4BF8A2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF892719D3D000A11E64 /* BasicAppSettingsCoordinator.swift */; };
|
||||
E1D4BF8B2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF892719D3D000A11E64 /* BasicAppSettingsCoordinator.swift */; };
|
||||
E1D4BF8C2719F39F00A11E64 /* AppAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF802719D22800A11E64 /* AppAppearance.swift */; };
|
||||
E1D4BF8D2719F3A300A11E64 /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
|
||||
E1D4BF8F271A079A00A11E64 /* BasicAppSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF8E271A079A00A11E64 /* BasicAppSettingsView.swift */; };
|
||||
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
|
||||
E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
|
||||
E1FCD08826C35A0D007C8DCF /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD08726C35A0D007C8DCF /* NetworkError.swift */; };
|
||||
|
@ -515,7 +516,6 @@
|
|||
62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerCoodinator.swift; sourceTree = "<group>"; };
|
||||
62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCoordinator.swift; sourceTree = "<group>"; };
|
||||
62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryListCoordinator.swift; sourceTree = "<group>"; };
|
||||
62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultsExtension.swift; sourceTree = "<group>"; };
|
||||
62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMediaViewModel.swift; sourceTree = "<group>"; };
|
||||
62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySearchViewModel.swift; sourceTree = "<group>"; };
|
||||
62E632DF267D30CA0063E547 /* LibraryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -582,6 +582,7 @@
|
|||
E1D4BF832719D25A00A11E64 /* TrackLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackLanguage.swift; sourceTree = "<group>"; };
|
||||
E1D4BF862719D27100A11E64 /* Bitrates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bitrates.swift; sourceTree = "<group>"; };
|
||||
E1D4BF892719D3D000A11E64 /* BasicAppSettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicAppSettingsCoordinator.swift; sourceTree = "<group>"; };
|
||||
E1D4BF8E271A079A00A11E64 /* BasicAppSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicAppSettingsView.swift; sourceTree = "<group>"; };
|
||||
E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerJumpLength.swift; sourceTree = "<group>"; };
|
||||
E1FCD08726C35A0D007C8DCF /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = "<group>"; };
|
||||
E1FCD09526C47118007C8DCF /* ErrorMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMessage.swift; sourceTree = "<group>"; };
|
||||
|
@ -1026,7 +1027,6 @@
|
|||
5389277B263CC3DB0035E14B /* BlurHashDecode.swift */,
|
||||
6267B3D526710B8900A7371D /* CollectionExtensions.swift */,
|
||||
E173DA5126D04AAF00CC4EB7 /* ColorExtension.swift */,
|
||||
62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */,
|
||||
6267B3D92671138200A7371D /* ImageExtensions.swift */,
|
||||
E1AD105226D96D5F003E4A08 /* JellyfinAPIExtensions */,
|
||||
621338922660107500A81A2A /* StringExtensions.swift */,
|
||||
|
@ -1119,6 +1119,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
53ABFDEA2679753200886593 /* ConnectToServerView.swift */,
|
||||
E1D4BF8E271A079A00A11E64 /* BasicAppSettingsView.swift */,
|
||||
531690EB267ABF46005D8AB9 /* ContinueWatchingView.swift */,
|
||||
531690E6267ABD79005D8AB9 /* HomeView.swift */,
|
||||
E193D54E271942C000900D82 /* ItemView */,
|
||||
|
@ -1714,7 +1715,6 @@
|
|||
53ABFDE7267974EF00886593 /* ConnectToServerViewModel.swift in Sources */,
|
||||
5398514626B64DBB00101B49 /* SearchablePickerView.swift in Sources */,
|
||||
53ABFDEE26799DCD00886593 /* ImageView.swift in Sources */,
|
||||
62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */,
|
||||
62E632E4267D3BA60063E547 /* MovieItemViewModel.swift in Sources */,
|
||||
53649AB2269D019100A2D8B7 /* LogManager.swift in Sources */,
|
||||
E13DD3D6271693CD009D4DAF /* SwiftfinStoreDefaults.swift in Sources */,
|
||||
|
@ -1741,6 +1741,7 @@
|
|||
E193D53B27193F9200900D82 /* SettingsCoordinator.swift in Sources */,
|
||||
536D3D74267BA8170004248C /* BackgroundManager.swift in Sources */,
|
||||
535870632669D21600D05A09 /* JellyfinPlayer_tvOSApp.swift in Sources */,
|
||||
E1D4BF8F271A079A00A11E64 /* BasicAppSettingsView.swift in Sources */,
|
||||
E193D547271941C500900D82 /* UserListView.swift in Sources */,
|
||||
E1D4BF7F2719D1DD00A11E64 /* BasicAppSettingsViewModel.swift in Sources */,
|
||||
E193D53227193F7B00900D82 /* ConnectToServerCoodinator.swift in Sources */,
|
||||
|
@ -1783,7 +1784,6 @@
|
|||
E13DD3EC27178A54009D4DAF /* UserSignInViewModel.swift in Sources */,
|
||||
625CB5772678C34300530A6E /* ConnectToServerViewModel.swift in Sources */,
|
||||
536D3D78267BD5C30004248C /* ViewModel.swift in Sources */,
|
||||
62CB3F4B2685BB77003D0A6F /* DefaultsExtension.swift in Sources */,
|
||||
E1FCD08826C35A0D007C8DCF /* NetworkError.swift in Sources */,
|
||||
E13DD3E527177D15009D4DAF /* ServerListView.swift in Sources */,
|
||||
E18845F826DEA9C900B0C5B7 /* ItemViewBody.swift in Sources */,
|
||||
|
@ -1891,6 +1891,7 @@
|
|||
E1FCD09A26C4F35A007C8DCF /* ErrorMessage.swift in Sources */,
|
||||
628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */,
|
||||
E13DD3F72717E87D009D4DAF /* SwiftfinNotificationCenter.swift in Sources */,
|
||||
E1D4BF8D2719F3A300A11E64 /* VideoPlayerJumpLength.swift in Sources */,
|
||||
6220D0AF26D5EABE00B8E046 /* ViewExtensions.swift in Sources */,
|
||||
E13DD3D7271693CD009D4DAF /* SwiftfinStoreDefaults.swift in Sources */,
|
||||
E1FCD09926C4F358007C8DCF /* NetworkError.swift in Sources */,
|
||||
|
@ -1898,6 +1899,7 @@
|
|||
E13DD3CA27164B80009D4DAF /* SwiftfinStore.swift in Sources */,
|
||||
62EC353226766849000E9F2D /* SessionManager.swift in Sources */,
|
||||
536D3D79267BD5D00004248C /* ViewModel.swift in Sources */,
|
||||
E1D4BF8C2719F39F00A11E64 /* AppAppearance.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -44,8 +44,10 @@ struct ConnectToServerView: View {
|
|||
if viewModel.searching {
|
||||
HStack(alignment: .center, spacing: 5) {
|
||||
Spacer()
|
||||
ProgressView()
|
||||
Text("Searching")
|
||||
// Oct. 15, 2021
|
||||
// There is a bug where ProgressView() won't appear sometimes when searching,
|
||||
// dots were used instead but ProgressView() is preferred
|
||||
Text("Searching...")
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
}
|
||||
|
@ -61,6 +63,7 @@ struct ConnectToServerView: View {
|
|||
} else {
|
||||
ForEach(viewModel.discoveredServers.sorted(by: { $0.name < $1.name }), id: \.id) { discoveredServer in
|
||||
Button {
|
||||
uri = discoveredServer.url.absoluteString
|
||||
viewModel.connectToServer(uri: discoveredServer.url.absoluteString)
|
||||
} label: {
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
|
|
|
@ -1,22 +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 2021 Aiden Vigue & Jellyfin Contributors
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Defaults
|
||||
|
||||
extension Defaults.Keys {
|
||||
static let inNetworkBandwidth = Key<Int>("InNetworkBandwidth", default: 40_000_000)
|
||||
static let outOfNetworkBandwidth = Key<Int>("OutOfNetworkBandwidth", default: 40_000_000)
|
||||
static let isAutoSelectSubtitles = Key<Bool>("isAutoSelectSubtitles", default: false)
|
||||
static let autoSelectSubtitlesLangCode = Key<String>("AutoSelectSubtitlesLangCode", default: "Auto")
|
||||
static let autoSelectAudioLangCode = Key<String>("AutoSelectAudioLangCode", default: "Auto")
|
||||
static let appAppearance = Key<AppAppearance>("appAppearance", default: .system)
|
||||
static let videoPlayerJumpForward = Key<VideoPlayerJumpLength>("videoPlayerJumpForward", default: .thirty)
|
||||
static let videoPlayerJumpBackward = Key<VideoPlayerJumpLength>("videoPlayerJumpBackward", default: .thirty)
|
||||
}
|
|
@ -179,12 +179,16 @@ final class SessionManager {
|
|||
}
|
||||
|
||||
func purge() {
|
||||
// Delete all servers
|
||||
let servers = fetchServers()
|
||||
|
||||
for server in servers {
|
||||
delete(server: server)
|
||||
}
|
||||
|
||||
// Delete UserDefaults
|
||||
SwiftfinStore.Defaults.suite.removeAll()
|
||||
|
||||
SwiftfinNotificationCenter.main.post(name: SwiftfinNotificationCenter.Keys.didPurge, object: nil)
|
||||
}
|
||||
|
||||
|
@ -224,7 +228,7 @@ final class SessionManager {
|
|||
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
|
||||
var deviceName = UIDevice.current.name
|
||||
deviceName = deviceName.folding(options: .diacriticInsensitive, locale: .current)
|
||||
deviceName = String(deviceName.unicodeScalars.filter {CharacterSet.urlQueryAllowed.contains($0) })
|
||||
deviceName = String(deviceName.unicodeScalars.filter { CharacterSet.urlQueryAllowed.contains($0) })
|
||||
|
||||
let platform: String
|
||||
#if os(tvOS)
|
||||
|
|
|
@ -156,6 +156,7 @@ enum SwiftfinStore {
|
|||
}()
|
||||
}
|
||||
|
||||
// MARK: LocalizedError
|
||||
extension SwiftfinStore.Errors: LocalizedError {
|
||||
|
||||
var title: String {
|
||||
|
|
|
@ -22,4 +22,13 @@ extension SwiftfinStore {
|
|||
|
||||
extension Defaults.Keys {
|
||||
static let lastServerUserID = Defaults.Key<String?>("lastServerUserID", suite: SwiftfinStore.Defaults.suite)
|
||||
|
||||
static let inNetworkBandwidth = Key<Int>("InNetworkBandwidth", default: 40_000_000, suite: SwiftfinStore.Defaults.suite)
|
||||
static let outOfNetworkBandwidth = Key<Int>("OutOfNetworkBandwidth", default: 40_000_000, suite: SwiftfinStore.Defaults.suite)
|
||||
static let isAutoSelectSubtitles = Key<Bool>("isAutoSelectSubtitles", default: false, suite: SwiftfinStore.Defaults.suite)
|
||||
static let autoSelectSubtitlesLangCode = Key<String>("AutoSelectSubtitlesLangCode", default: "Auto", suite: SwiftfinStore.Defaults.suite)
|
||||
static let autoSelectAudioLangCode = Key<String>("AutoSelectAudioLangCode", default: "Auto", suite: SwiftfinStore.Defaults.suite)
|
||||
static let appAppearance = Key<AppAppearance>("appAppearance", default: .system, suite: SwiftfinStore.Defaults.suite)
|
||||
static let videoPlayerJumpForward = Key<VideoPlayerJumpLength>("videoPlayerJumpForward", default: .thirty, suite: SwiftfinStore.Defaults.suite)
|
||||
static let videoPlayerJumpBackward = Key<VideoPlayerJumpLength>("videoPlayerJumpBackward", default: .thirty, suite: SwiftfinStore.Defaults.suite)
|
||||
}
|
||||
|
|
|
@ -50,10 +50,11 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
}
|
||||
|
||||
func discoverServers() {
|
||||
discoveredServers.removeAll()
|
||||
searching = true
|
||||
|
||||
// Timeout after 5 seconds
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||||
self.searching = false
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,6 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
if let server = server {
|
||||
discoveredServers.insert(server)
|
||||
}
|
||||
searching = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue