Implement suggestions

This commit is contained in:
David Ullmer 2022-07-12 19:51:47 +02:00
parent 3f56aea9e2
commit 46cbd4f7d1
No known key found for this signature in database
GPG Key ID: 4AEABE3359D5883C
11 changed files with 123 additions and 54 deletions

View File

@ -28,6 +28,8 @@ final class SettingsCoordinator: NavigationCoordinatable {
var missingSettings = makeMissingSettings
@Route(.push)
var about = makeAbout
@Route(.push)
var quickConnect = makeQuickConnectSettings
@ViewBuilder
func makeServerDetail() -> some View {
@ -60,6 +62,12 @@ final class SettingsCoordinator: NavigationCoordinatable {
AboutView()
}
@ViewBuilder
func makeQuickConnectSettings() -> some View {
let viewModel = QuickConnectSettingsViewModel()
QuickConnectSettingsView(viewModel: viewModel)
}
@ViewBuilder
func makeStart() -> some View {
let viewModel = SettingsViewModel(server: SessionManager.main.currentLogin.server, user: SessionManager.main.currentLogin.user)

View File

@ -91,7 +91,7 @@ enum NetworkError: Error {
default:
errorMessage = ErrorMessage(code: code,
title: L10n.error,
message: L10n.unknownError)
message: displayMessage ?? L10n.unknownError)
}
}

View File

@ -34,6 +34,8 @@ internal enum L10n {
internal static var audioAndCaptions: String { return L10n.tr("Localizable", "audioAndCaptions") }
/// Audio Track
internal static var audioTrack: String { return L10n.tr("Localizable", "audioTrack") }
/// Authorize
internal static var authorize: String { return L10n.tr("Localizable", "authorize") }
/// Auto Play
internal static var autoPlay: String { return L10n.tr("Localizable", "autoPlay") }
/// Back
@ -264,10 +266,12 @@ internal enum L10n {
internal static var publicUsers: String { return L10n.tr("Localizable", "publicUsers") }
/// Quick Connect
internal static var quickConnect: String { return L10n.tr("Localizable", "quickConnect") }
/// Authorize
internal static var quickConnectAuthorize: String { return L10n.tr("Localizable", "quickConnectAuthorize") }
/// Quick Connect code
internal static var quickConnectCode: String { return L10n.tr("Localizable", "quickConnectCode") }
/// Invalid Quick Connect code
internal static var quickConnectInvalidError: String { return L10n.tr("Localizable", "quickConnectInvalidError") }
/// Authorizing Quick Connect successful. Please continue on your other device.
internal static var quickConnectSuccessMessage: String { return L10n.tr("Localizable", "quickConnectSuccessMessage") }
/// Rated
internal static var rated: String { return L10n.tr("Localizable", "rated") }
/// Recently Added

View File

@ -0,0 +1,46 @@
//
// 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) 2022 Jellyfin & Jellyfin Contributors
//
import Foundation
import JellyfinAPI
final class QuickConnectSettingsViewModel: ViewModel {
@Published
var quickConnectCode = ""
@Published
var showSuccessMessage = false
var alertTitle: String {
var message: String = ""
if errorMessage?.code != ErrorMessage.noShowErrorCode {
message.append(contentsOf: "\(errorMessage?.code ?? ErrorMessage.noShowErrorCode)\n")
}
message.append(contentsOf: "\(errorMessage?.title ?? L10n.unknownError)")
return message
}
func sendQuickConnect() {
QuickConnectAPI.authorize(code: self.quickConnectCode)
.trackActivity(loading)
.sink(receiveCompletion: { completion in
self.handleAPIRequestError(displayMessage: L10n.quickConnectInvalidError, completion: completion)
switch completion {
case .failure:
LogManager.log.debug("Invalid Quick Connect code entered")
default:
break
}
}, receiveValue: { _ in
// receiving a successful HTTP response indicates a valid code
LogManager.log.debug("Valid Quick connect code entered")
self.showSuccessMessage = true
})
.store(in: &cancellables)
}
}

View File

@ -14,21 +14,12 @@ import SwiftUI
final class SettingsViewModel: ViewModel {
@RouterObject
var router: SettingsCoordinator.Router?
var bitrates: [Bitrates] = []
var langs: [TrackLanguage] = []
let server: SwiftfinStore.State.Server
let user: SwiftfinStore.State.User
@Published
var quickConnectCode = ""
@Published
var validQuickConnect = true
init(server: SwiftfinStore.State.Server, user: SwiftfinStore.State.User) {
self.server = server
@ -55,26 +46,4 @@ final class SettingsViewModel: ViewModel {
}.sorted(by: { $0.name < $1.name })
self.langs.insert(.auto, at: 0)
}
func sendQuickConnect() {
QuickConnectAPI.authorize(code: self.quickConnectCode)
.sink(receiveCompletion: { completion in
switch completion {
case .failure:
LogManager.log.debug("Invalid Quick Connect code entered")
self.validQuickConnect = false
default:
self.handleAPIRequestError(displayMessage: "Error", completion: completion)
}
}, receiveValue: { value in
if !value {
LogManager.log.debug("Invalid Quick Connect code entered")
self.validQuickConnect = false
} else {
LogManager.log.debug("Valid Quick connect code entered")
self.router?.dismissCoordinator()
}
})
.store(in: &cancellables)
}
}

View File

@ -17,9 +17,6 @@ final class UserSignInViewModel: ViewModel {
var router: UserSignInCoordinator.Router?
let server: SwiftfinStore.State.Server
@Published
var isLoadingUsers = false
@Published
var publicUsers: [UserDto] = []
@ -32,7 +29,7 @@ final class UserSignInViewModel: ViewModel {
if errorMessage?.code != ErrorMessage.noShowErrorCode {
message.append(contentsOf: "\(errorMessage?.code ?? ErrorMessage.noShowErrorCode)\n")
}
message.append(contentsOf: "\(errorMessage?.title ?? "Unkown Error")")
message.append(contentsOf: "\(errorMessage?.title ?? L10n.unknownError)")
return message
}
@ -57,14 +54,13 @@ final class UserSignInViewModel: ViewModel {
}
func loadUsers() {
self.isLoadingUsers = true
JellyfinAPIAPI.basePath = server.currentURI
UserAPI.getPublicUsers()
.trackActivity(loading)
.sink(receiveCompletion: { completion in
self.handleAPIRequestError(displayMessage: L10n.unableToConnectServer, completion: completion)
}, receiveValue: { response in
self.publicUsers = response
self.isLoadingUsers = false
})
.store(in: &cancellables)
}

View File

@ -248,6 +248,8 @@
62EC353426766B03000E9F2D /* DeviceRotationViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */; };
62ECA01826FA685A00E8EBB7 /* DeepLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62ECA01726FA685A00E8EBB7 /* DeepLink.swift */; };
631759CF2879DB6A00A621AD /* PublicUserSignInCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631759CE2879DB6A00A621AD /* PublicUserSignInCellView.swift */; };
6334175B287DDFB9000603CE /* QuickConnectSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6334175A287DDFB9000603CE /* QuickConnectSettingsView.swift */; };
6334175D287DE0D0000603CE /* QuickConnectSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6334175C287DE0D0000603CE /* QuickConnectSettingsViewModel.swift */; };
637FCAF4287B5B2600C0A353 /* UDPBroadcast.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 637FCAF3287B5B2600C0A353 /* UDPBroadcast.xcframework */; };
637FCAF5287B5B2600C0A353 /* UDPBroadcast.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 637FCAF3287B5B2600C0A353 /* UDPBroadcast.xcframework */; };
AE8C3159265D6F90008AA076 /* bitrates.json in Resources */ = {isa = PBXBuildFile; fileRef = AE8C3158265D6F90008AA076 /* bitrates.json */; };
@ -744,6 +746,8 @@
62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = "<group>"; };
62ECA01726FA685A00E8EBB7 /* DeepLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLink.swift; sourceTree = "<group>"; };
631759CE2879DB6A00A621AD /* PublicUserSignInCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicUserSignInCellView.swift; sourceTree = "<group>"; };
6334175A287DDFB9000603CE /* QuickConnectSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickConnectSettingsView.swift; sourceTree = "<group>"; };
6334175C287DE0D0000603CE /* QuickConnectSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickConnectSettingsViewModel.swift; sourceTree = "<group>"; };
637FCAF3287B5B2600C0A353 /* UDPBroadcast.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = UDPBroadcast.xcframework; path = Carthage/Build/UDPBroadcast.xcframework; sourceTree = "<group>"; };
AE8C3158265D6F90008AA076 /* bitrates.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bitrates.json; sourceTree = "<group>"; };
C400DB6927FE894F007B65FE /* LiveTVChannelsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveTVChannelsView.swift; sourceTree = "<group>"; };
@ -1058,6 +1062,7 @@
09389CC626819B4500AE350E /* VideoPlayerModel.swift */,
E126F73F278A655300A522BF /* VideoPlayerViewModel */,
625CB57B2678CE1000530A6E /* ViewModel.swift */,
6334175C287DE0D0000603CE /* QuickConnectSettingsViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
@ -1882,6 +1887,7 @@
E176DE6F278E369F001EFD8D /* MissingItemsSettingsView.swift */,
E1E5D5472783CCF900692DFE /* OverlaySettingsView.swift */,
539B2DA4263BA5B8007FF1A4 /* SettingsView.swift */,
6334175A287DDFB9000603CE /* QuickConnectSettingsView.swift */,
);
path = SettingsView;
sourceTree = "<group>";
@ -2474,12 +2480,14 @@
E1C812CE277AE43100918266 /* VideoPlayerViewModel.swift in Sources */,
E10D87DA2784E4F100BD264C /* ItemViewDetailsView.swift in Sources */,
E1C812C3277A8E5D00918266 /* VLCPlayerOverlayView.swift in Sources */,
6334175B287DDFB9000603CE /* QuickConnectSettingsView.swift in Sources */,
E1002B642793CEE800E47059 /* ChapterInfoExtensions.swift in Sources */,
E188460026DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift in Sources */,
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */,
E13DD3F5271793BB009D4DAF /* UserSignInView.swift in Sources */,
5D1603FC278A3D5800D22B99 /* SubtitleSize.swift in Sources */,
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
6334175D287DE0D0000603CE /* QuickConnectSettingsViewModel.swift in Sources */,
53649AB1269CFB1900A2D8B7 /* LogManager.swift in Sources */,
E13DD3E127176BD3009D4DAF /* ServerListViewModel.swift in Sources */,
62E632E9267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */,

View File

@ -0,0 +1,44 @@
//
// 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) 2022 Jellyfin & Jellyfin Contributors
//
import Foundation
import SwiftUI
struct QuickConnectSettingsView: View {
@ObservedObject
var viewModel: QuickConnectSettingsViewModel
var body: some View {
Form {
Section(header: L10n.quickConnect.text) {
TextField(L10n.quickConnectCode, text: $viewModel.quickConnectCode)
.keyboardType(.numberPad)
.disabled(viewModel.isLoading)
Button {
viewModel.sendQuickConnect()
} label: {
L10n.authorize.text
.font(.callout)
.disabled((viewModel.quickConnectCode.count != 6) || viewModel.isLoading)
}
}
.alert(isPresented: $viewModel.showSuccessMessage) {
Alert(title: L10n.quickConnect.text,
message: L10n.quickConnectSuccessMessage.text,
dismissButton: .default(L10n.ok.text))
}
}
.alert(item: $viewModel.errorMessage) { _ in
Alert(title: Text(viewModel.alertTitle),
message: Text(viewModel.errorMessage?.message ?? L10n.unknownError),
dismissButton: .cancel())
}
}
}

View File

@ -81,22 +81,16 @@ struct SettingsView: View {
L10n.switchUser.text
.font(.callout)
}
}
Section(header: L10n.quickConnect.text) {
TextField(L10n.quickConnectCode, text: $viewModel.quickConnectCode)
.keyboardType(.numberPad)
.onChange(of: viewModel.quickConnectCode, perform: { _ in
viewModel.validQuickConnect = true
})
.foregroundColor(viewModel.validQuickConnect ? .none : Color.red)
Button {
viewModel.sendQuickConnect()
settingsRouter.route(to: \.quickConnect)
} label: {
L10n.quickConnectAuthorize.text
.font(.callout)
.disabled(viewModel.quickConnectCode.isEmpty)
HStack {
L10n.quickConnect.text
.foregroundColor(.primary)
Spacer()
Image(systemName: "chevron.right")
}
}
}

View File

@ -71,7 +71,7 @@ struct UserSignInView: View {
} label: {
Image(systemName: "arrow.clockwise.circle.fill")
}
.disabled(viewModel.isLoadingUsers || viewModel.isLoading)
.disabled(viewModel.isLoading)
}
}
.headerProminence(.increased)