Add settings view + fix signin flow
This commit is contained in:
parent
3994a6f408
commit
2e3c12fed3
@ -11,6 +11,7 @@
|
|||||||
3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DA2B27F5D300F5C29A /* Model.xcdatamodeld */; };
|
3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DA2B27F5D300F5C29A /* Model.xcdatamodeld */; };
|
||||||
3D1015DE2B27F79900F5C29A /* DatamodelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DD2B27F79900F5C29A /* DatamodelController.swift */; };
|
3D1015DE2B27F79900F5C29A /* DatamodelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DD2B27F79900F5C29A /* DatamodelController.swift */; };
|
||||||
3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015E32B28000E00F5C29A /* AuthStateController.swift */; };
|
3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015E32B28000E00F5C29A /* AuthStateController.swift */; };
|
||||||
|
3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */; };
|
||||||
3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; };
|
3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; };
|
||||||
3D77093B2B29139700199889 /* PulseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D77093A2B29139700199889 /* PulseUI */; };
|
3D77093B2B29139700199889 /* PulseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D77093A2B29139700199889 /* PulseUI */; };
|
||||||
3D77093D2B29350700199889 /* ConsoleSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D77093C2B29350700199889 /* ConsoleSheetView.swift */; };
|
3D77093D2B29350700199889 /* ConsoleSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D77093C2B29350700199889 /* ConsoleSheetView.swift */; };
|
||||||
@ -25,6 +26,9 @@
|
|||||||
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDC82B28C62800919017 /* SignInView.swift */; };
|
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDC82B28C62800919017 /* SignInView.swift */; };
|
||||||
3D91FDCB2B28CA2500919017 /* SignInToServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDCA2B28CA2500919017 /* SignInToServerView.swift */; };
|
3D91FDCB2B28CA2500919017 /* SignInToServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDCA2B28CA2500919017 /* SignInToServerView.swift */; };
|
||||||
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */; };
|
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */; };
|
||||||
|
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; };
|
||||||
|
3DDD67932B293BC40026781E /* DashBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashBoardView.swift */; };
|
||||||
|
3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; };
|
||||||
3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */; };
|
3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -64,6 +68,7 @@
|
|||||||
3D1015DB2B27F5D300F5C29A /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
|
3D1015DB2B27F5D300F5C29A /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
|
||||||
3D1015DD2B27F79900F5C29A /* DatamodelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatamodelController.swift; sourceTree = "<group>"; };
|
3D1015DD2B27F79900F5C29A /* DatamodelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatamodelController.swift; sourceTree = "<group>"; };
|
||||||
3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; };
|
3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; };
|
||||||
|
3D41D1F42B2C962500E58234 /* AppearancePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearancePicker.swift; sourceTree = "<group>"; };
|
||||||
3D77093C2B29350700199889 /* ConsoleSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleSheetView.swift; sourceTree = "<group>"; };
|
3D77093C2B29350700199889 /* ConsoleSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleSheetView.swift; sourceTree = "<group>"; };
|
||||||
3D9063C72B279A310063DD2A /* Jel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jel.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
3D9063C72B279A310063DD2A /* Jel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jel.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
3D9063CA2B279A310063DD2A /* JelApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JelApp.swift; sourceTree = "<group>"; };
|
3D9063CA2B279A310063DD2A /* JelApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JelApp.swift; sourceTree = "<group>"; };
|
||||||
@ -80,6 +85,9 @@
|
|||||||
3D91FDCA2B28CA2500919017 /* SignInToServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInToServerView.swift; sourceTree = "<group>"; };
|
3D91FDCA2B28CA2500919017 /* SignInToServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInToServerView.swift; sourceTree = "<group>"; };
|
||||||
3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinDateFormatter.swift; sourceTree = "<group>"; };
|
3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinDateFormatter.swift; sourceTree = "<group>"; };
|
||||||
3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
|
||||||
|
3DDD67922B293BC40026781E /* DashBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashBoardView.swift; sourceTree = "<group>"; };
|
||||||
|
3DDD67952B29E28B0026781E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||||
3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinClientController.swift; sourceTree = "<group>"; };
|
3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinClientController.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@ -115,8 +123,10 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
3D9063CC2B279A310063DD2A /* ContentView.swift */,
|
3D9063CC2B279A310063DD2A /* ContentView.swift */,
|
||||||
|
3DDD67902B293B780026781E /* Dashboard */,
|
||||||
|
3DDD67942B29E27A0026781E /* Settings */,
|
||||||
3D91FDC52B28C28900919017 /* SignIn */,
|
3D91FDC52B28C28900919017 /* SignIn */,
|
||||||
3D77093C2B29350700199889 /* ConsoleSheetView.swift */,
|
3DDD67912B293B9E0026781E /* Utility */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -127,6 +137,7 @@
|
|||||||
3D1015DD2B27F79900F5C29A /* DatamodelController.swift */,
|
3D1015DD2B27F79900F5C29A /* DatamodelController.swift */,
|
||||||
3D1015E32B28000E00F5C29A /* AuthStateController.swift */,
|
3D1015E32B28000E00F5C29A /* AuthStateController.swift */,
|
||||||
3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */,
|
3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */,
|
||||||
|
3DC6BA2C2B2A422300416B9F /* SettingsController.swift */,
|
||||||
);
|
);
|
||||||
path = Controllers;
|
path = Controllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -211,6 +222,31 @@
|
|||||||
path = SignIn;
|
path = SignIn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
3DDD67902B293B780026781E /* Dashboard */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3DDD67922B293BC40026781E /* DashBoardView.swift */,
|
||||||
|
);
|
||||||
|
path = Dashboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3DDD67912B293B9E0026781E /* Utility */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3D77093C2B29350700199889 /* ConsoleSheetView.swift */,
|
||||||
|
);
|
||||||
|
path = Utility;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3DDD67942B29E27A0026781E /* Settings */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3DDD67952B29E28B0026781E /* SettingsView.swift */,
|
||||||
|
3D41D1F42B2C962500E58234 /* AppearancePicker.swift */,
|
||||||
|
);
|
||||||
|
path = Settings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@ -359,8 +395,12 @@
|
|||||||
3D77093D2B29350700199889 /* ConsoleSheetView.swift in Sources */,
|
3D77093D2B29350700199889 /* ConsoleSheetView.swift in Sources */,
|
||||||
3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */,
|
3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */,
|
||||||
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,
|
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,
|
||||||
|
3DDD67932B293BC40026781E /* DashBoardView.swift in Sources */,
|
||||||
|
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */,
|
||||||
3D91FDCB2B28CA2500919017 /* SignInToServerView.swift in Sources */,
|
3D91FDCB2B28CA2500919017 /* SignInToServerView.swift in Sources */,
|
||||||
3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */,
|
3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */,
|
||||||
|
3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */,
|
||||||
|
3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -546,7 +586,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = icu.trinket.apps.Jel;
|
PRODUCT_BUNDLE_IDENTIFIER = icu.trinket.apps.Jel;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@ -586,7 +626,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = icu.trinket.apps.Jel;
|
PRODUCT_BUNDLE_IDENTIFIER = icu.trinket.apps.Jel;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
@ -62,24 +62,27 @@ class JellyfinClientController: ObservableObject {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func isJellyfinServer() async -> Bool {
|
func getPublicServerInfo() async -> PublicSystemInfo? {
|
||||||
let request = Paths.getPublicSystemInfo
|
let request = Paths.getPublicSystemInfo
|
||||||
do {
|
do {
|
||||||
let res = try await api.send(request)
|
let res = try await api.send(request)
|
||||||
if res.statusCode != 200 {
|
if res.statusCode != 200 {
|
||||||
throw JellyfinClientError.badResponseCode
|
throw JellyfinClientError.badResponseCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res.value
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func signIn(username: String, pw: String) async throws {
|
func signIn(username: String, pw: String) async throws {
|
||||||
let request = Paths.authenticateUserByName(AuthenticateUserByName(pw: pw, username: username))
|
let request = Paths.authenticateUserByName(AuthenticateUserByName(pw: pw, username: username))
|
||||||
let res = try await self.api.send(request)
|
let res = try await self.api.send(request)
|
||||||
|
DispatchQueue.main.async {
|
||||||
self.authState.loggedIn = true
|
self.authState.loggedIn = true
|
||||||
self.authState.authToken = res.value.accessToken
|
self.authState.authToken = res.value.accessToken
|
||||||
self.authState.save()
|
self.authState.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
44
Jel/Controllers/SettingsController.swift
Normal file
44
Jel/Controllers/SettingsController.swift
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// SettingsController.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/13/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum AppearanceState: Int, CaseIterable, Identifiable, CustomStringConvertible {
|
||||||
|
case automatic
|
||||||
|
case light
|
||||||
|
case dark
|
||||||
|
|
||||||
|
var id: Self { self }
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .light:
|
||||||
|
return "Light"
|
||||||
|
case .dark:
|
||||||
|
return "Dark"
|
||||||
|
case .automatic:
|
||||||
|
return "Automatic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsController: ObservableObject {
|
||||||
|
static let shared: SettingsController = SettingsController()
|
||||||
|
|
||||||
|
@Published var appearance: AppearanceState = .automatic
|
||||||
|
|
||||||
|
private let defaults = UserDefaults.standard
|
||||||
|
|
||||||
|
func save() {
|
||||||
|
defaults.set(self.appearance.rawValue, forKey: "Settings_appearance")
|
||||||
|
}
|
||||||
|
|
||||||
|
func load() {
|
||||||
|
let oldAppearance = defaults.integer(forKey: "Settings_appearance")
|
||||||
|
self.appearance = AppearanceState(rawValue: oldAppearance) ?? .automatic
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,6 @@ import SwiftUI
|
|||||||
@main
|
@main
|
||||||
struct JelApp: App {
|
struct JelApp: App {
|
||||||
let datamodelController = DatamodelController.shared
|
let datamodelController = DatamodelController.shared
|
||||||
let authStateController = AuthStateController.shared
|
|
||||||
|
|
||||||
let jellyfinClientController = JellyfinClientController(authHeaders: AuthHeaders(
|
let jellyfinClientController = JellyfinClientController(authHeaders: AuthHeaders(
|
||||||
Client: "Jel",
|
Client: "Jel",
|
||||||
Device: UIDevice.current.systemName,
|
Device: UIDevice.current.systemName,
|
||||||
@ -21,15 +19,13 @@ struct JelApp: App {
|
|||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
ContentView(authState: authStateController)
|
ContentView()
|
||||||
.environment(\.managedObjectContext,
|
.environment(\.managedObjectContext,
|
||||||
datamodelController.container.viewContext)
|
datamodelController.container.viewContext)
|
||||||
.environmentObject(jellyfinClientController)
|
.environmentObject(jellyfinClientController)
|
||||||
.task {
|
.task {
|
||||||
authStateController.load()
|
AuthStateController.shared.load()
|
||||||
if authStateController.serverUrl != nil {
|
SettingsController.shared.load()
|
||||||
jellyfinClientController.setUrl(url: authStateController.serverUrl!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
//
|
|
||||||
// ConsoleSheetView.swift
|
|
||||||
// Jel
|
|
||||||
//
|
|
||||||
// Created by zerocool on 12/12/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import PulseUI
|
|
||||||
|
|
||||||
struct ConsoleSheetView: View {
|
|
||||||
@Binding var showingConsoleSheet: Bool
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
NavigationStack {
|
|
||||||
List {
|
|
||||||
NavigationLink {
|
|
||||||
ConsoleView(mode: .network)
|
|
||||||
.closeButtonHidden()
|
|
||||||
} label: {
|
|
||||||
Text("Network Console")
|
|
||||||
}
|
|
||||||
NavigationLink {
|
|
||||||
ConsoleView(mode: .logs)
|
|
||||||
.closeButtonHidden()
|
|
||||||
} label: {
|
|
||||||
Text("Logs Console")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toolbar {
|
|
||||||
Button {
|
|
||||||
showingConsoleSheet.toggle()
|
|
||||||
} label: {
|
|
||||||
Text("Done")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Preview {
|
|
||||||
ConsoleSheetView(showingConsoleSheet: .constant(true))
|
|
||||||
}
|
|
@ -9,34 +9,36 @@ import SwiftUI
|
|||||||
import PulseUI
|
import PulseUI
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@ObservedObject var authState: AuthStateController
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
||||||
|
|
||||||
|
@StateObject var settingsController: SettingsController = SettingsController.shared
|
||||||
|
|
||||||
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
||||||
@State var showingConsoleSheet: Bool = false
|
@State var showingConsoleSheet: Bool = false
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
Button {
|
|
||||||
showingConsoleSheet.toggle()
|
|
||||||
} label: {
|
|
||||||
Label("Console", systemImage: "network")
|
|
||||||
}
|
|
||||||
.sheet(isPresented: $showingConsoleSheet) {
|
|
||||||
ConsoleSheetView(showingConsoleSheet: $showingConsoleSheet)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !authState.loggedIn {
|
if !authState.loggedIn {
|
||||||
SignInView(authState: authState)
|
SignInView()
|
||||||
} else {
|
} else {
|
||||||
Text("Logged in")
|
NavigationStack {
|
||||||
Button("Log out") {
|
DashBoardView()
|
||||||
authState.loggedIn = false
|
|
||||||
authState.save()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
|
.preferredColorScheme({
|
||||||
|
switch settingsController.appearance {
|
||||||
|
case .dark:
|
||||||
|
return ColorScheme.dark
|
||||||
|
case .light:
|
||||||
|
return ColorScheme.light
|
||||||
|
case .automatic:
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
ContentView(authState: AuthStateController())
|
ContentView()
|
||||||
}
|
}
|
||||||
|
36
Jel/Views/Dashboard/DashBoardView.swift
Normal file
36
Jel/Views/Dashboard/DashBoardView.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// DashBoardView.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/12/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct DashBoardView: View {
|
||||||
|
@State var showingSettingsSheet: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack {
|
||||||
|
VStack {
|
||||||
|
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button {
|
||||||
|
showingSettingsSheet.toggle()
|
||||||
|
} label: {
|
||||||
|
Label("Settings", systemImage: "gear")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $showingSettingsSheet) {
|
||||||
|
SettingsView(showingSettingsView: $showingSettingsSheet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
DashBoardView()
|
||||||
|
}
|
25
Jel/Views/Settings/AppearancePicker.swift
Normal file
25
Jel/Views/Settings/AppearancePicker.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// AppearancePicker.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/15/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AppearancePicker: View {
|
||||||
|
@ObservedObject var settingsController: SettingsController = SettingsController.shared
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Picker("Appearance", selection: $settingsController.appearance) {
|
||||||
|
ForEach(AppearanceState.allCases) { option in
|
||||||
|
Text(String(describing: option))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pickerStyle(.menu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
AppearancePicker()
|
||||||
|
}
|
68
Jel/Views/Settings/SettingsView.swift
Normal file
68
Jel/Views/Settings/SettingsView.swift
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// SettingsView.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/13/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import PulseUI
|
||||||
|
|
||||||
|
struct SettingsView: View {
|
||||||
|
@Binding var showingSettingsView: Bool
|
||||||
|
|
||||||
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
||||||
|
|
||||||
|
@ObservedObject var settingsController: SettingsController = SettingsController.shared
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack {
|
||||||
|
Form {
|
||||||
|
Section {
|
||||||
|
AppearancePicker()
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
NavigationLink {
|
||||||
|
ConsoleView()
|
||||||
|
.closeButtonHidden()
|
||||||
|
} label: {
|
||||||
|
Text("Logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(role: .destructive) {
|
||||||
|
authState.loggedIn = false
|
||||||
|
authState.save()
|
||||||
|
} label: {
|
||||||
|
Text("Sign out")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle("Settings")
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button {
|
||||||
|
showingSettingsView.toggle()
|
||||||
|
settingsController.save()
|
||||||
|
} label: {
|
||||||
|
Text("Done")
|
||||||
|
.bold()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.preferredColorScheme({
|
||||||
|
switch settingsController.appearance {
|
||||||
|
case .dark:
|
||||||
|
return ColorScheme.dark
|
||||||
|
case .light:
|
||||||
|
return ColorScheme.light
|
||||||
|
case .automatic:
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
SettingsView(showingSettingsView: .constant(true))
|
||||||
|
}
|
@ -9,7 +9,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct AddServerView: View {
|
struct AddServerView: View {
|
||||||
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
||||||
@ObservedObject var authState: AuthStateController
|
@ObservedObject var authState: AuthStateController = AuthStateController.shared
|
||||||
@Binding var serverUrlIsValid: Bool
|
@Binding var serverUrlIsValid: Bool
|
||||||
|
|
||||||
@State var serverUrlString: String = "http://"
|
@State var serverUrlString: String = "http://"
|
||||||
@ -73,7 +73,7 @@ struct AddServerView: View {
|
|||||||
if isValidUrl(data: serverUrlString) {
|
if isValidUrl(data: serverUrlString) {
|
||||||
let url = URL(string: serverUrlString)!
|
let url = URL(string: serverUrlString)!
|
||||||
jellyfinClient.setUrl(url: url)
|
jellyfinClient.setUrl(url: url)
|
||||||
if await jellyfinClient.isJellyfinServer() {
|
if await jellyfinClient.getPublicServerInfo() != nil {
|
||||||
authState.serverUrl = url
|
authState.serverUrl = url
|
||||||
authState.save()
|
authState.save()
|
||||||
urlHasError = false
|
urlHasError = false
|
||||||
@ -103,6 +103,6 @@ struct AddServerView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
AddServerView(authState: AuthStateController(), serverUrlIsValid: .constant(false))
|
AddServerView(serverUrlIsValid: .constant(false))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,19 @@ import SwiftUI
|
|||||||
|
|
||||||
struct SignInToServerView: View {
|
struct SignInToServerView: View {
|
||||||
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
||||||
@ObservedObject var authState: AuthStateController
|
|
||||||
|
|
||||||
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
||||||
@State var username: String = ""
|
@State var username: String = ""
|
||||||
@State var password: String = ""
|
@State var password: String = ""
|
||||||
|
|
||||||
@State var isLoading: Bool = false
|
@State var isLoading: Bool = false
|
||||||
@State var hasError: Bool = false
|
@State var hasError: Bool = false
|
||||||
|
|
||||||
|
@State var serverName: String = ""
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
Text("Sign in")
|
Text("Sign in to \(serverName)")
|
||||||
.font(.title)
|
.font(.title)
|
||||||
TextField(text: $username) {
|
TextField(text: $username) {
|
||||||
Text("Username")
|
Text("Username")
|
||||||
@ -60,6 +62,13 @@ struct SignInToServerView: View {
|
|||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
.textInputAutocapitalization(.never)
|
.textInputAutocapitalization(.never)
|
||||||
.disabled(isLoading)
|
.disabled(isLoading)
|
||||||
|
.onAppear {
|
||||||
|
Task {
|
||||||
|
if let serverInfo = await jellyfinClient.getPublicServerInfo() {
|
||||||
|
serverName = serverInfo.serverName ?? "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func logInToServer() async {
|
func logInToServer() async {
|
||||||
@ -74,6 +83,7 @@ struct SignInToServerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
// FIXME: Preview broken for this view
|
||||||
SignInToServerView(authState: AuthStateController())
|
//#Preview {
|
||||||
}
|
// SignInToServerView()
|
||||||
|
//}
|
||||||
|
@ -6,17 +6,20 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import PulseUI
|
||||||
|
|
||||||
struct SignInView: View {
|
struct SignInView: View {
|
||||||
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
||||||
@ObservedObject var authState: AuthStateController
|
|
||||||
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
||||||
@State var serverUrlIsValid: Bool = false
|
@State var serverUrlIsValid: Bool = false
|
||||||
|
@State var showingConsoleSheet: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
AddServerView(authState: authState, serverUrlIsValid: $serverUrlIsValid)
|
AddServerView(serverUrlIsValid: $serverUrlIsValid)
|
||||||
.navigationDestination(isPresented: $serverUrlIsValid) {
|
.navigationDestination(isPresented: $serverUrlIsValid) {
|
||||||
SignInToServerView(authState: authState)
|
SignInToServerView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
@ -31,12 +34,12 @@ struct SignInView: View {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if await jellyfinClient.isJellyfinServer() {
|
if await jellyfinClient.getPublicServerInfo() != nil {
|
||||||
serverUrlIsValid = true
|
serverUrlIsValid = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
SignInView(authState: AuthStateController())
|
SignInView()
|
||||||
}
|
}
|
||||||
|
35
Jel/Views/Utility/ConsoleSheetView.swift
Normal file
35
Jel/Views/Utility/ConsoleSheetView.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// ConsoleSheetView.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/12/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import PulseUI
|
||||||
|
|
||||||
|
struct ConsoleSheetView: View {
|
||||||
|
@Binding var showingConsoleSheet: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack {
|
||||||
|
ConsoleView()
|
||||||
|
.closeButtonHidden()
|
||||||
|
.navigationTitle("Debug consoles")
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button {
|
||||||
|
showingConsoleSheet.toggle()
|
||||||
|
} label: {
|
||||||
|
Text("Done")
|
||||||
|
.bold()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
ConsoleSheetView(showingConsoleSheet: .constant(true))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user