another.im-ios/ConversationsClassic/View/Screens/Contacts/ContactsScreen.swift

173 lines
6.1 KiB
Swift
Raw Normal View History

2024-06-19 15:15:27 +00:00
import SwiftUI
struct ContactsScreen: View {
@EnvironmentObject var store: AppStore
@State private var addPanelPresented = false
@State private var isErrorAlertPresented = false
@State private var errorAlertMessage = ""
@State private var isShowingLoader = false
var body: some View {
ZStack {
// Background color
2024-07-04 08:21:12 +00:00
Color.Material.Background.light
2024-06-19 15:15:27 +00:00
.ignoresSafeArea()
// Content
VStack(spacing: 0) {
// Header
2024-08-07 09:19:53 +00:00
SharedNavigationBar(
centerText: .init(text: L10n.Contacts.title),
rightButton: .init(
image: Image(systemName: "plus"),
action: {
addPanelPresented = true
}
)
)
2024-06-19 15:15:27 +00:00
// Contacts list
let rosters = store.state.rostersState.rosters.filter { !$0.locallyDeleted }
if !rosters.isEmpty {
List {
ForEach(rosters) { roster in
ContactsScreenRow(
roster: roster,
isErrorAlertPresented: $isErrorAlertPresented,
errorAlertMessage: $errorAlertMessage,
isShowingLoader: $isShowingLoader
)
}
}
.listStyle(.plain)
2024-07-04 08:21:12 +00:00
.background(Color.Material.Background.light)
2024-06-19 15:15:27 +00:00
} else {
Spacer()
}
// Tab bar
SharedTabBar()
}
}
.loadingIndicator(isShowingLoader)
.fullScreenCover(isPresented: $addPanelPresented) {
AddContactOrChannelScreen(isPresented: $addPanelPresented)
}
.alert(isPresented: $isErrorAlertPresented) {
Alert(
title: Text(L10n.Global.Error.title),
message: Text(errorAlertMessage),
dismissButton: .default(Text(L10n.Global.ok))
)
}
}
}
private struct ContactsScreenRow: View {
@EnvironmentObject var store: AppStore
var roster: Roster
@State private var isShowingMenu = false
@State private var isDeleteAlertPresented = false
@Binding var isErrorAlertPresented: Bool
@Binding var errorAlertMessage: String
@Binding var isShowingLoader: Bool
var body: some View {
2024-08-07 19:07:39 +00:00
SharedListRow(
iconType: .charCircle(roster.name?.firstLetter ?? roster.contactBareJid.firstLetter),
text: roster.contactBareJid
)
// VStack(spacing: 0) {
// HStack(spacing: 8) {
// ZStack {
// Circle()
// .frame(width: 44, height: 44)
// .foregroundColor(.red)
// Text(roster.name?.firstLetter ?? roster.contactBareJid.firstLetter)
// .foregroundColor(.white)
// .font(.body1)
// }
// Text(roster.contactBareJid)
// .foregroundColor(Color.Material.Text.main)
// .font(.body2)
// Spacer()
// }
// .padding(.horizontal, 16)
// .padding(.vertical, 4)
// Rectangle()
// .frame(maxWidth: .infinity)
// .frame(height: 1)
// .foregroundColor(.Material.Background.dark)
// }
// .sharedListRow()
2024-06-19 15:15:27 +00:00
.onTapGesture {
2024-06-20 05:27:13 +00:00
store.dispatch(.chatsAction(.startChat(accountJid: roster.bareJid, participantJid: roster.contactBareJid)))
2024-06-19 15:15:27 +00:00
}
.onLongPressGesture {
isShowingMenu.toggle()
}
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button {
isDeleteAlertPresented = true
} label: {
Label(L10n.Contacts.sendMessage, systemImage: "trash")
}
.tint(Color.red)
}
.contextMenu {
Button(L10n.Contacts.sendMessage, systemImage: "message") {
2024-06-20 05:27:13 +00:00
store.dispatch(.chatsAction(.startChat(accountJid: roster.bareJid, participantJid: roster.contactBareJid)))
2024-06-19 15:15:27 +00:00
}
Divider()
Button(L10n.Contacts.editContact) {
print("Edit contact")
}
Button(L10n.Contacts.selectContact) {
print("Select contact")
}
Divider()
Button(L10n.Contacts.deleteContact, systemImage: "trash", role: .destructive) {
isDeleteAlertPresented = true
}
}
.actionSheet(isPresented: $isDeleteAlertPresented) {
ActionSheet(
title: Text(L10n.Contacts.Delete.title),
message: Text(L10n.Contacts.Delete.message),
buttons: [
.destructive(Text(L10n.Contacts.Delete.deleteFromDevice)) {
store.dispatch(.rostersAction(.markRosterAsLocallyDeleted(ownerJID: roster.bareJid, contactJID: roster.contactBareJid)))
},
.destructive(Text(L10n.Contacts.Delete.deleteCompletely)) {
isShowingLoader = true
store.dispatch(.rostersAction(.deleteRoster(ownerJID: roster.bareJid, contactJID: roster.contactBareJid)))
},
.cancel(Text(L10n.Global.cancel))
]
)
}
.onChange(of: store.state.rostersState.rosters) { _ in
endOfDeleting()
}
.onChange(of: store.state.rostersState.deleteRosterError) { _ in
endOfDeleting()
}
}
private func endOfDeleting() {
if isShowingLoader {
isShowingLoader = false
if let error = store.state.rostersState.deleteRosterError {
errorAlertMessage = error
isErrorAlertPresented = true
}
}
}
}