Merge pull request #473 from daullmer/known-users
iOS - Add known public users to login screen
This commit is contained in:
commit
be66d1008e
|
@ -198,6 +198,8 @@ internal enum L10n {
|
|||
internal static var `none`: String { return L10n.tr("Localizable", "none") }
|
||||
/// No overview available
|
||||
internal static var noOverviewAvailable: String { return L10n.tr("Localizable", "noOverviewAvailable") }
|
||||
/// No public Users
|
||||
internal static var noPublicUsers: String { return L10n.tr("Localizable", "noPublicUsers") }
|
||||
/// No results.
|
||||
internal static var noResults: String { return L10n.tr("Localizable", "noResults") }
|
||||
/// Normal
|
||||
|
@ -258,6 +260,8 @@ internal enum L10n {
|
|||
internal static var previousItem: String { return L10n.tr("Localizable", "previousItem") }
|
||||
/// Programs
|
||||
internal static var programs: String { return L10n.tr("Localizable", "programs") }
|
||||
/// Public Users
|
||||
internal static var publicUsers: String { return L10n.tr("Localizable", "publicUsers") }
|
||||
/// Rated
|
||||
internal static var rated: String { return L10n.tr("Localizable", "rated") }
|
||||
/// Recently Added
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import CoreStore
|
||||
import Foundation
|
||||
import JellyfinAPI
|
||||
import Stinsen
|
||||
|
||||
final class UserSignInViewModel: ViewModel {
|
||||
|
@ -16,6 +17,12 @@ final class UserSignInViewModel: ViewModel {
|
|||
var router: UserSignInCoordinator.Router?
|
||||
let server: SwiftfinStore.State.Server
|
||||
|
||||
@Published
|
||||
var isLoadingUsers = false
|
||||
|
||||
@Published
|
||||
var publicUsers: [UserDto] = []
|
||||
|
||||
init(server: SwiftfinStore.State.Server) {
|
||||
self.server = server
|
||||
}
|
||||
|
@ -48,4 +55,25 @@ final class UserSignInViewModel: ViewModel {
|
|||
|
||||
self.isLoading = false
|
||||
}
|
||||
|
||||
func loadUsers() {
|
||||
self.isLoadingUsers = true
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
UserAPI.getPublicUsers()
|
||||
.sink(receiveCompletion: { completion in
|
||||
self.handleAPIRequestError(displayMessage: L10n.unableToConnectServer, completion: completion)
|
||||
}, receiveValue: { response in
|
||||
self.publicUsers = response
|
||||
self.isLoadingUsers = false
|
||||
})
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func getProfileImageUrl(user: UserDto) -> URL? {
|
||||
let urlString = ImageAPI.getUserImageWithRequestBuilder(userId: user.id ?? "--",
|
||||
imageType: .primary,
|
||||
width: 200,
|
||||
quality: 90).URLString
|
||||
return URL(string: urlString)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,6 +247,7 @@
|
|||
62EC353226766849000E9F2D /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352E267666A5000E9F2D /* SessionManager.swift */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
|
@ -742,6 +743,7 @@
|
|||
62EC352E267666A5000E9F2D /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1667,6 +1669,7 @@
|
|||
E1E5D54A2783E26100692DFE /* SettingsView */,
|
||||
E13DD3FB2717EAE8009D4DAF /* UserListView.swift */,
|
||||
E13DD3F4271793BB009D4DAF /* UserSignInView.swift */,
|
||||
631759CE2879DB6A00A621AD /* PublicUserSignInCellView.swift */,
|
||||
E193D5452719418B00900D82 /* VideoPlayer */,
|
||||
);
|
||||
path = Views;
|
||||
|
@ -2485,6 +2488,7 @@
|
|||
6220D0CC26D640C400B8E046 /* AppURLHandler.swift in Sources */,
|
||||
53DE4BD2267098F300739748 /* SearchBarView.swift in Sources */,
|
||||
E1E48CC9271E6D410021A2F9 /* RefreshHelper.swift in Sources */,
|
||||
631759CF2879DB6A00A621AD /* PublicUserSignInCellView.swift in Sources */,
|
||||
E1AA33222782648000F6439C /* OverlaySliderColor.swift in Sources */,
|
||||
E1D4BF842719D25A00A11E64 /* TrackLanguage.swift in Sources */,
|
||||
E14F7D0726DB36EF007C3AE6 /* ItemPortraitMainView.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// 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 JellyfinAPI
|
||||
import SwiftUI
|
||||
|
||||
struct UserLoginCellView: View {
|
||||
|
||||
@ObservedObject
|
||||
var viewModel: UserSignInViewModel
|
||||
|
||||
@State
|
||||
private var enteredPassword: String = ""
|
||||
|
||||
var user: UserDto
|
||||
|
||||
var body: some View {
|
||||
DisclosureGroup {
|
||||
SecureField(L10n.password, text: $enteredPassword)
|
||||
Button {
|
||||
viewModel.login(username: user.name ?? "--", password: enteredPassword)
|
||||
} label: {
|
||||
L10n.signIn.text
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
ImageView(viewModel.getProfileImageUrl(user: user)) {
|
||||
Image(systemName: "person.circle")
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
}
|
||||
.frame(width: 50, height: 50)
|
||||
.clipShape(Circle())
|
||||
|
||||
Text(user.name ?? "--")
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,8 +19,7 @@ struct UserSignInView: View {
|
|||
private var password: String = ""
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
List {
|
||||
Section {
|
||||
TextField(L10n.username, text: $username)
|
||||
.disableAutocorrection(true)
|
||||
|
@ -47,6 +46,35 @@ struct UserSignInView: View {
|
|||
} header: {
|
||||
L10n.signInToServer(viewModel.server.name).text
|
||||
}
|
||||
|
||||
Section {
|
||||
if !viewModel.publicUsers.isEmpty {
|
||||
ForEach(viewModel.publicUsers, id: \.id) { user in
|
||||
UserLoginCellView(viewModel: viewModel, user: user)
|
||||
.disabled(viewModel.isLoading)
|
||||
}
|
||||
} else {
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
L10n.noPublicUsers.text
|
||||
.font(.callout)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
HStack {
|
||||
L10n.publicUsers.text
|
||||
Spacer()
|
||||
Button {
|
||||
viewModel.loadUsers()
|
||||
} label: {
|
||||
Image(systemName: "arrow.clockwise.circle.fill")
|
||||
}
|
||||
.disabled(viewModel.isLoadingUsers || viewModel.isLoading)
|
||||
}
|
||||
}
|
||||
.headerProminence(.increased)
|
||||
}
|
||||
.alert(item: $viewModel.errorMessage) { _ in
|
||||
Alert(title: Text(viewModel.alertTitle),
|
||||
|
@ -55,5 +83,6 @@ struct UserSignInView: View {
|
|||
}
|
||||
.navigationTitle(L10n.signIn)
|
||||
.navigationBarBackButtonHidden(viewModel.isLoading)
|
||||
.onAppear(perform: viewModel.loadUsers)
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue