This commit is contained in:
fmodf 2024-10-15 19:47:51 +02:00
parent bec095e8de
commit c153985bf0
4 changed files with 64 additions and 42 deletions

View file

@ -2,6 +2,12 @@ import Combine
import Foundation
import GRDB
enum ClientsListState {
case empty
case allDisabled
case haveSomeEnabled
}
@MainActor
final class ClientsStore: ObservableObject {
static let shared = ClientsStore()
@ -10,6 +16,7 @@ final class ClientsStore: ObservableObject {
@Published private(set) var clients: [Client] = []
@Published private(set) var actualRosters: [Roster] = []
@Published private(set) var actualChats: [Chat] = []
@Published private(set) var listState: ClientsListState = .empty
private var credentialsCancellable: AnyCancellable?
private var rostersCancellable: AnyCancellable?
@ -41,13 +48,29 @@ final class ClientsStore: ObservableObject {
updatedClients.append(contentsOf: newClients)
clients = updatedClients
// for creds in credentials {
// if let client = client(for: creds) {
// client.credentials = creds
// }
// }
if !ready {
ready = true
}
resubscribeRosters()
resubscribeChats()
reconnectAll()
reconnectNeeded()
if credentials.isEmpty {
listState = .empty
} else if credentials.allSatisfy({ !$0.isActive }) {
listState = .allDisabled
} else {
listState = .haveSomeEnabled
}
objectWillChange.send()
}
private func client(for credentials: Credentials) -> Client? {
@ -67,21 +90,20 @@ extension ClientsStore {
try? await client.credentials.save()
}
private func reconnectAll() {
private func reconnectNeeded() {
Task {
await withTaskGroup(of: Void.self) { taskGroup in
for client in clients {
if client.credentials.isActive && client.state != .enabled(.connected) {
taskGroup.addTask {
await client.connect()
}
}
if !client.credentials.isActive && client.state == .enabled(.connected) {
taskGroup.addTask {
client.disconnect()
}
}
if client.credentials.isActive && client.state != .enabled(.connected) {
taskGroup.addTask {
await client.connect()
}
}
}
}
}

View file

@ -10,22 +10,22 @@ struct WelcomeScreen: View {
Color.Material.Background.light
.ignoresSafeArea()
// if !clientsStore.clients.isEmpty && clientsStore.clients.allSatisfy({ $0.state != .enabled(.connected) }) {
// VStack {
// HStack {
// Spacer()
// Image(systemName: "gear")
// .foregroundColor(.Material.Elements.active)
// .tappablePadding(.symmetric(10)) {
// router.showScreen(.push) { _ in
// SettingsScreen()
// }
// }
// }
// .padding()
// Spacer()
// }
// }
if clientsStore.listState == .allDisabled {
VStack {
HStack {
Spacer()
Image(systemName: "gear")
.foregroundColor(.Material.Elements.active)
.tappablePadding(.symmetric(10)) {
router.showScreen(.push) { _ in
SettingsScreen()
}
}
}
.padding()
Spacer()
}
}
// content
VStack(spacing: 32) {

View file

@ -22,23 +22,23 @@ struct SettingsScreen: View {
// Accounts section
SharedSectionTitle(text: L10n.Settings.Section.Accounts.title)
// ForEach(settingsStore.credentials) { creds in
// SharedListRow(
// iconType: .charCircle(creds.bareJid),
// text: creds.bareJid,
// controlType: .switcher(isOn: Binding(
// get: { creds.isActive },
// set: { new in
// Task {
// try? await creds.setActive(flag: new)
// }
// }
// ))
// )
// .onTapGesture {
// print("Tapped account \(creds.bareJid)")
// }
// }
ForEach(clientsStore.clients) { client in
SharedListRow(
iconType: .charCircle(client.credentials.bareJid),
text: client.credentials.bareJid,
controlType: .switcher(isOn: Binding(
get: { client.credentials.isActive },
set: { new in
Task {
try? await client.credentials.setActive(flag: new)
}
}
))
)
.onTapGesture {
print("Tapped account \(client.credentials.bareJid)")
}
}
SharedListRow(
iconType: .image(Image(systemName: "plus"), .Material.Elements.active),

View file

@ -7,7 +7,7 @@ struct RootView: View {
var body: some View {
Group {
if clientsStore.ready {
if clientsStore.clients.isEmpty {
if clientsStore.listState != .haveSomeEnabled {
RouterView { _ in
WelcomeScreen()
}