2023-01-17 17:47:37 +00:00
|
|
|
//
|
|
|
|
// Created by Avently on 17.01.2023.
|
|
|
|
// Copyright (c) 2023 SimpleX Chat. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
import SimpleXChat
|
|
|
|
|
|
|
|
struct UserProfilesView: View {
|
|
|
|
@EnvironmentObject private var m: ChatModel
|
|
|
|
@Environment(\.editMode) private var editMode
|
2023-01-24 19:00:30 +00:00
|
|
|
@State private var showDeleteConfirmation = false
|
|
|
|
@State private var userToDelete: Int?
|
2023-01-20 12:38:38 +00:00
|
|
|
@State private var alert: UserProfilesAlert?
|
2023-02-08 13:39:41 +03:00
|
|
|
@State var authorized = !UserDefaults.standard.bool(forKey: DEFAULT_PERFORM_LA)
|
2023-01-20 12:38:38 +00:00
|
|
|
|
|
|
|
private enum UserProfilesAlert: Identifiable {
|
2023-01-24 19:00:30 +00:00
|
|
|
case deleteUser(index: Int, delSMPQueues: Bool)
|
2023-01-31 15:55:41 +00:00
|
|
|
case activateUserError(error: String)
|
2023-01-20 12:38:38 +00:00
|
|
|
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
|
|
|
|
|
|
|
var id: String {
|
|
|
|
switch self {
|
2023-01-24 19:00:30 +00:00
|
|
|
case let .deleteUser(index, delSMPQueues): return "deleteUser \(index) \(delSMPQueues)"
|
2023-01-31 15:55:41 +00:00
|
|
|
case let .activateUserError(err): return "activateUserError \(err)"
|
2023-01-20 12:38:38 +00:00
|
|
|
case let .error(title, _): return "error \(title)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-01-17 17:47:37 +00:00
|
|
|
|
|
|
|
var body: some View {
|
2023-02-08 13:39:41 +03:00
|
|
|
if authorized {
|
|
|
|
userProfilesView()
|
|
|
|
} else {
|
|
|
|
Button(action: runAuth) { Label("Unlock", systemImage: "lock") }
|
|
|
|
.onAppear(perform: runAuth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func runAuth() { authorize(NSLocalizedString("Open user profiles", comment: "authentication reason"), $authorized) }
|
|
|
|
|
|
|
|
private func userProfilesView() -> some View {
|
2023-01-17 17:47:37 +00:00
|
|
|
List {
|
2023-01-20 12:38:38 +00:00
|
|
|
Section {
|
|
|
|
ForEach(m.users) { u in
|
|
|
|
userView(u.user)
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
|
|
|
.onDelete { indexSet in
|
2023-01-20 12:38:38 +00:00
|
|
|
if let i = indexSet.first {
|
2023-01-24 19:00:30 +00:00
|
|
|
showDeleteConfirmation = true
|
|
|
|
userToDelete = i
|
2023-01-20 12:38:38 +00:00
|
|
|
}
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
2023-01-20 12:38:38 +00:00
|
|
|
|
|
|
|
NavigationLink {
|
|
|
|
CreateProfile()
|
|
|
|
} label: {
|
|
|
|
Label("Add profile", systemImage: "plus")
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
2023-01-20 12:38:38 +00:00
|
|
|
.frame(height: 44)
|
|
|
|
.padding(.vertical, 4)
|
|
|
|
} footer: {
|
|
|
|
Text("Your chat profiles are stored locally, only on your device.")
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
.toolbar { EditButton() }
|
2023-02-08 13:39:41 +03:00
|
|
|
.navigationTitle("Your chat profiles")
|
2023-01-24 19:00:30 +00:00
|
|
|
.confirmationDialog("Delete chat profile?", isPresented: $showDeleteConfirmation, titleVisibility: .visible) {
|
|
|
|
deleteModeButton("Profile and server connections", true)
|
|
|
|
deleteModeButton("Local profile data only", false)
|
|
|
|
}
|
2023-01-20 12:38:38 +00:00
|
|
|
.alert(item: $alert) { alert in
|
|
|
|
switch alert {
|
2023-01-24 19:00:30 +00:00
|
|
|
case let .deleteUser(index, delSMPQueues):
|
2023-01-20 12:38:38 +00:00
|
|
|
return Alert(
|
|
|
|
title: Text("Delete user profile?"),
|
|
|
|
message: Text("All chats and messages will be deleted - this cannot be undone!"),
|
|
|
|
primaryButton: .destructive(Text("Delete")) {
|
2023-01-24 19:00:30 +00:00
|
|
|
removeUser(index, delSMPQueues)
|
2023-01-20 12:38:38 +00:00
|
|
|
},
|
|
|
|
secondaryButton: .cancel()
|
|
|
|
)
|
2023-01-31 15:55:41 +00:00
|
|
|
case let .activateUserError(error: err):
|
|
|
|
return Alert(
|
|
|
|
title: Text("Error switching profile!"),
|
|
|
|
message: Text(err)
|
|
|
|
)
|
2023-01-20 12:38:38 +00:00
|
|
|
case let .error(title, error):
|
|
|
|
return Alert(title: Text(title), message: Text(error))
|
|
|
|
}
|
|
|
|
}
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
|
|
|
|
2023-01-24 19:00:30 +00:00
|
|
|
private func deleteModeButton(_ title: LocalizedStringKey, _ delSMPQueues: Bool) -> some View {
|
|
|
|
Button(title, role: .destructive) {
|
|
|
|
if let i = userToDelete {
|
|
|
|
alert = .deleteUser(index: i, delSMPQueues: delSMPQueues)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func removeUser(_ index: Int, _ delSMPQueues: Bool) {
|
|
|
|
if index >= m.users.count { return }
|
2023-01-19 16:22:56 +00:00
|
|
|
do {
|
2023-01-24 19:00:30 +00:00
|
|
|
let u = m.users[index].user
|
|
|
|
if u.activeUser {
|
|
|
|
if let newActive = m.users.first(where: { !$0.user.activeUser }) {
|
|
|
|
try changeActiveUser_(newActive.user.userId)
|
|
|
|
try deleteUser(u.userId)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
try deleteUser(u.userId)
|
|
|
|
}
|
2023-01-20 12:38:38 +00:00
|
|
|
} catch let error {
|
|
|
|
let a = getErrorAlert(error, "Error deleting user profile")
|
|
|
|
alert = .error(title: a.title, error: a.message)
|
2023-01-19 16:22:56 +00:00
|
|
|
}
|
2023-01-24 19:00:30 +00:00
|
|
|
|
|
|
|
func deleteUser(_ userId: Int64) throws {
|
|
|
|
try apiDeleteUser(userId, delSMPQueues)
|
|
|
|
m.users.remove(at: index)
|
|
|
|
}
|
2023-01-19 16:22:56 +00:00
|
|
|
}
|
2023-01-20 12:38:38 +00:00
|
|
|
|
2023-01-27 12:54:42 +00:00
|
|
|
private func userView(_ user: User) -> some View {
|
2023-01-20 12:38:38 +00:00
|
|
|
Button {
|
2023-01-31 15:55:41 +00:00
|
|
|
do {
|
|
|
|
try changeActiveUser_(user.userId)
|
|
|
|
} catch {
|
|
|
|
alert = .activateUserError(error: responseError(error))
|
|
|
|
}
|
2023-01-17 17:47:37 +00:00
|
|
|
} label: {
|
2023-01-20 12:38:38 +00:00
|
|
|
HStack {
|
2023-01-24 19:00:30 +00:00
|
|
|
ProfileImage(imageStr: user.image, color: Color(uiColor: .tertiarySystemFill))
|
2023-01-20 12:38:38 +00:00
|
|
|
.frame(width: 44, height: 44)
|
|
|
|
.padding(.vertical, 4)
|
|
|
|
.padding(.trailing, 12)
|
|
|
|
Text(user.chatViewName)
|
|
|
|
Spacer()
|
|
|
|
Image(systemName: "checkmark")
|
|
|
|
.foregroundColor(user.activeUser ? .primary : .clear)
|
|
|
|
}
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
2023-01-24 19:00:30 +00:00
|
|
|
.disabled(user.activeUser)
|
2023-01-20 12:38:38 +00:00
|
|
|
.foregroundColor(.primary)
|
2023-01-24 19:00:30 +00:00
|
|
|
.deleteDisabled(m.users.count <= 1)
|
2023-01-17 17:47:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct UserProfilesView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
|
|
|
UserProfilesView()
|
|
|
|
}
|
|
|
|
}
|