Remove @Published used for input(keyboard) binding (side effect)
This commit is contained in:
parent
3f6e91ef2e
commit
368ac68005
|
@ -10,14 +10,20 @@ import SwiftUI
|
|||
|
||||
struct ConnectToServerView: View {
|
||||
@StateObject var viewModel = ConnectToServerViewModel()
|
||||
@State
|
||||
var username = ""
|
||||
@State
|
||||
var password = ""
|
||||
@State
|
||||
var uri = ""
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if viewModel.isConnectedServer {
|
||||
if viewModel.publicUsers.isEmpty {
|
||||
Section(header: Text(viewModel.lastPublicUsers.isEmpty || viewModel.username == "" ? "Login to \(ServerEnvironment.current.server.name ?? "")": "")) {
|
||||
if viewModel.lastPublicUsers.isEmpty || viewModel.username == "" {
|
||||
TextField("Username", text: $viewModel.username)
|
||||
Section(header: Text(viewModel.lastPublicUsers.isEmpty || username == "" ? "Login to \(ServerEnvironment.current.server.name ?? "")": "")) {
|
||||
if viewModel.lastPublicUsers.isEmpty || username == "" {
|
||||
TextField("Username", text: $username)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
} else {
|
||||
|
@ -30,7 +36,7 @@ struct ConnectToServerView: View {
|
|||
}
|
||||
}
|
||||
|
||||
SecureField("Password (optional)", text: $viewModel.password)
|
||||
SecureField("Password (optional)", text: $password)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
}
|
||||
|
@ -39,7 +45,7 @@ struct ConnectToServerView: View {
|
|||
HStack {
|
||||
Button {
|
||||
if !viewModel.lastPublicUsers.isEmpty {
|
||||
viewModel.username = ""
|
||||
username = ""
|
||||
viewModel.showPublicUsers()
|
||||
} else {
|
||||
viewModel.isConnectedServer = false
|
||||
|
@ -62,7 +68,7 @@ struct ConnectToServerView: View {
|
|||
Text("Login")
|
||||
}
|
||||
Spacer()
|
||||
}.disabled(viewModel.isLoading || viewModel.username.isEmpty)
|
||||
}.disabled(viewModel.isLoading || username.isEmpty)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -74,11 +80,11 @@ struct ConnectToServerView: View {
|
|||
let user = SessionManager.current.getSavedSession(userID: publicUser.id!)
|
||||
SessionManager.current.loginWithSavedSession(user: user)
|
||||
} else {
|
||||
viewModel.username = publicUser.name ?? ""
|
||||
username = publicUser.name ?? ""
|
||||
viewModel.selectedPublicUser = publicUser
|
||||
viewModel.hidePublicUsers()
|
||||
if !(publicUser.hasPassword ?? true) {
|
||||
viewModel.password = ""
|
||||
password = ""
|
||||
viewModel.login()
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +98,7 @@ struct ConnectToServerView: View {
|
|||
Spacer()
|
||||
Button {
|
||||
viewModel.hidePublicUsers()
|
||||
viewModel.username = ""
|
||||
username = ""
|
||||
} label: {
|
||||
Text("Other User").font(.headline).fontWeight(.semibold)
|
||||
}
|
||||
|
@ -103,7 +109,7 @@ struct ConnectToServerView: View {
|
|||
} else {
|
||||
Form {
|
||||
Section(header: Text("Server Information")) {
|
||||
TextField("Jellyfin Server URL", text: $viewModel.uri)
|
||||
TextField("Jellyfin Server URL", text: $uri)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
Button {
|
||||
|
@ -117,7 +123,7 @@ struct ConnectToServerView: View {
|
|||
ProgressView()
|
||||
}
|
||||
}
|
||||
.disabled(viewModel.isLoading || viewModel.uri.isEmpty)
|
||||
.disabled(viewModel.isLoading || uri.isEmpty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +133,15 @@ struct ConnectToServerView: View {
|
|||
.alert(item: $viewModel.errorMessage) { _ in
|
||||
Alert(title: Text("Error"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("Ok")))
|
||||
}
|
||||
.onChange(of: uri) { uri in
|
||||
viewModel.uriSubject.send(uri)
|
||||
}
|
||||
.onChange(of: username) { username in
|
||||
viewModel.usernameSubject.send(username)
|
||||
}
|
||||
.onChange(of: password) { password in
|
||||
viewModel.passwordSubject.send(password)
|
||||
}
|
||||
.navigationTitle(viewModel.isConnectedServer ? "Who's watching?" : "Connect to Jellyfin")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,14 @@ import KeychainSwift
|
|||
import SwiftUI
|
||||
|
||||
struct ConnectToServerView: View {
|
||||
@StateObject var viewModel = ConnectToServerViewModel()
|
||||
@StateObject
|
||||
var viewModel = ConnectToServerViewModel()
|
||||
@State
|
||||
var username = ""
|
||||
@State
|
||||
var password = ""
|
||||
@State
|
||||
var uri = ""
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
|
@ -19,10 +26,10 @@ struct ConnectToServerView: View {
|
|||
if viewModel.isConnectedServer {
|
||||
if viewModel.publicUsers.isEmpty {
|
||||
Section(header: Text("Login to \(ServerEnvironment.current.server.name ?? "")")) {
|
||||
TextField("Username", text: $viewModel.username)
|
||||
TextField("Username", text: $username)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
SecureField("Password", text: $viewModel.password)
|
||||
SecureField("Password", text: $password)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
Button {
|
||||
|
@ -35,7 +42,7 @@ struct ConnectToServerView: View {
|
|||
ProgressView()
|
||||
}
|
||||
}
|
||||
}.disabled(viewModel.isLoading || viewModel.username.isEmpty)
|
||||
}.disabled(viewModel.isLoading || username.isEmpty)
|
||||
}
|
||||
|
||||
Section {
|
||||
|
@ -56,10 +63,10 @@ struct ConnectToServerView: View {
|
|||
ForEach(viewModel.publicUsers, id: \.id) { publicUser in
|
||||
HStack {
|
||||
Button(action: {
|
||||
viewModel.username = publicUser.name ?? ""
|
||||
username = publicUser.name ?? ""
|
||||
viewModel.publicUsers.removeAll()
|
||||
if !(publicUser.hasPassword ?? true) {
|
||||
viewModel.password = ""
|
||||
password = ""
|
||||
viewModel.login()
|
||||
}
|
||||
}) {
|
||||
|
@ -88,7 +95,7 @@ struct ConnectToServerView: View {
|
|||
Section {
|
||||
Button {
|
||||
viewModel.publicUsers.removeAll()
|
||||
viewModel.username = ""
|
||||
username = ""
|
||||
} label: {
|
||||
HStack {
|
||||
Text("Other User").font(.subheadline).fontWeight(.semibold)
|
||||
|
@ -106,7 +113,7 @@ struct ConnectToServerView: View {
|
|||
}
|
||||
} else {
|
||||
Section(header: Text("Server Information")) {
|
||||
TextField("Jellyfin Server URL", text: $viewModel.uri)
|
||||
TextField("Jellyfin Server URL", text: $uri)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
Button {
|
||||
|
@ -120,11 +127,20 @@ struct ConnectToServerView: View {
|
|||
ProgressView()
|
||||
}
|
||||
}
|
||||
.disabled(viewModel.isLoading || viewModel.uri.isEmpty)
|
||||
.disabled(viewModel.isLoading || uri.isEmpty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: uri) { uri in
|
||||
viewModel.uriSubject.send(uri)
|
||||
}
|
||||
.onChange(of: username) { username in
|
||||
viewModel.usernameSubject.send(username)
|
||||
}
|
||||
.onChange(of: password) { password in
|
||||
viewModel.passwordSubject.send(password)
|
||||
}
|
||||
.alert(item: $viewModel.errorMessage) { _ in
|
||||
Alert(title: Text("Error"), message: Text("message"), dismissButton: .default(Text("Try again")))
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import SwiftUI
|
|||
struct LibrarySearchView: View {
|
||||
@StateObject
|
||||
var viewModel: LibrarySearchViewModel
|
||||
|
||||
@State
|
||||
var searchQuery = ""
|
||||
// MARK: tracks for grid
|
||||
|
||||
@State
|
||||
|
@ -25,7 +26,7 @@ struct LibrarySearchView: View {
|
|||
var body: some View {
|
||||
VStack {
|
||||
Spacer().frame(height: 6)
|
||||
SearchBar(text: $viewModel.searchQuery)
|
||||
SearchBar(text: $searchQuery)
|
||||
ZStack {
|
||||
ScrollView(.vertical) {
|
||||
if !viewModel.items.isEmpty {
|
||||
|
@ -67,6 +68,9 @@ struct LibrarySearchView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: searchQuery) { query in
|
||||
viewModel.searchQuerySubject.send(query)
|
||||
}
|
||||
.navigationBarTitle("Search", displayMode: .inline)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,10 @@ import JellyfinAPI
|
|||
final class ConnectToServerViewModel: ViewModel {
|
||||
@Published
|
||||
var isConnectedServer = false
|
||||
@Published
|
||||
var uri = ""
|
||||
@Published
|
||||
var username = ""
|
||||
@Published
|
||||
var password = ""
|
||||
|
||||
var uriSubject = CurrentValueSubject<String, Never>("")
|
||||
var usernameSubject = CurrentValueSubject<String, Never>("")
|
||||
var passwordSubject = CurrentValueSubject<String, Never>("")
|
||||
|
||||
@Published
|
||||
var lastPublicUsers = [UserDto]()
|
||||
|
@ -57,7 +55,7 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
}
|
||||
|
||||
func connectToServer() {
|
||||
ServerEnvironment.current.create(with: uri)
|
||||
ServerEnvironment.current.create(with: uriSubject.value)
|
||||
.sink(receiveCompletion: { result in
|
||||
switch result {
|
||||
case let .failure(error):
|
||||
|
@ -72,7 +70,7 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
}
|
||||
|
||||
func login() {
|
||||
SessionManager.current.login(username: username, password: password)
|
||||
SessionManager.current.login(username: usernameSubject.value, password: passwordSubject.value)
|
||||
.sink(receiveCompletion: { completion in
|
||||
self.handleAPIRequestCompletion(completion: completion)
|
||||
}, receiveValue: { _ in
|
||||
|
|
|
@ -15,15 +15,14 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
@Published
|
||||
var items = [BaseItemDto]()
|
||||
|
||||
@Published
|
||||
var searchQuery = ""
|
||||
var searchQuerySubject = CurrentValueSubject<String, Never>("")
|
||||
var parentID: String?
|
||||
|
||||
init(parentID: String?) {
|
||||
self.parentID = parentID
|
||||
super.init()
|
||||
|
||||
$searchQuery
|
||||
searchQuerySubject
|
||||
.debounce(for: 0.25, scheduler: DispatchQueue.main)
|
||||
.sink(receiveValue: search(with:))
|
||||
.store(in: &cancellables)
|
||||
|
|
Loading…
Reference in New Issue