This commit is contained in:
fmodf 2024-10-15 13:39:23 +02:00
parent c426847700
commit acf2807056
10 changed files with 77 additions and 22 deletions

View file

@ -100,12 +100,6 @@ extension Client {
_ = try await connection.module(.roster).removeItem(jid: JID(roster.contactBareJid))
}
func setActive(_ active: Bool) {
Task {
try? await credentials.setActive(flag: active)
}
}
func connect() async {
guard credentials.isActive, state == .enabled(.disconnected) else {
return

View file

@ -5,7 +5,7 @@ import Photos
import SwiftUI
@MainActor
final class SettingsStore: ObservableObject {
final class ChatSettingsStore: ObservableObject {
@Published var chat: Chat?
private let client: Client
@ -21,7 +21,7 @@ final class SettingsStore: ObservableObject {
}
}
extension SettingsStore {
extension ChatSettingsStore {
func setSecured(_ secured: Bool) {
Task {
try? await chat?.setEncrypted(secured)
@ -30,7 +30,7 @@ extension SettingsStore {
}
// MARK: - Processing attachments
private extension SettingsStore {
private extension ChatSettingsStore {
func subscribe() {
chatCancellable = ValueObservation.tracking(Chat
.filter(Column("account") == roster.bareJid && Column("participant") == roster.contactBareJid)

View file

@ -131,7 +131,7 @@ extension ClientsStore {
// MARK: - Produce stores for conversation
extension ClientsStore {
// swiftlint:disable:next large_tuple
func conversationStores(for roster: Roster) async throws -> (MessagesStore, AttachmentsStore, SettingsStore) {
func conversationStores(for roster: Roster) async throws -> (MessagesStore, AttachmentsStore, ChatSettingsStore) {
while !ready {
await Task.yield()
}
@ -142,12 +142,12 @@ extension ClientsStore {
let conversationStore = MessagesStore(roster: roster, client: client)
let attachmentsStore = AttachmentsStore(roster: roster, client: client)
let settingsStore = SettingsStore(roster: roster, client: client)
let settingsStore = ChatSettingsStore(roster: roster, client: client)
return (conversationStore, attachmentsStore, settingsStore)
}
// swiftlint:disable:next large_tuple
func conversationStores(for chat: Chat) async throws -> (MessagesStore, AttachmentsStore, SettingsStore) {
func conversationStores(for chat: Chat) async throws -> (MessagesStore, AttachmentsStore, ChatSettingsStore) {
while !ready {
await Task.yield()
}
@ -159,7 +159,7 @@ extension ClientsStore {
let roster = try await chat.fetchRoster()
let conversationStore = MessagesStore(roster: roster, client: client)
let attachmentsStore = AttachmentsStore(roster: roster, client: client)
let settingsStore = SettingsStore(roster: roster, client: client)
let settingsStore = ChatSettingsStore(roster: roster, client: client)
return (conversationStore, attachmentsStore, settingsStore)
}
}

View file

@ -0,0 +1,32 @@
import Combine
import Foundation
import GRDB
import Photos
import SwiftUI
@MainActor
final class GlobalSettingsStore: ObservableObject {
static let shared = GlobalSettingsStore()
@Published var credentials: [Credentials] = []
private var credentialsCancellable: AnyCancellable?
init() {
subscribe()
}
}
private extension GlobalSettingsStore {
func subscribe() {
credentialsCancellable = ValueObservation.tracking(Credentials
.fetchAll
)
.publisher(in: Database.shared.dbQueue, scheduling: .immediate)
.receive(on: DispatchQueue.main)
.sink { _ in
} receiveValue: { [weak self] credentials in
self?.credentials = credentials
}
}
}

View file

@ -5,6 +5,7 @@ import SwiftUI
@MainActor
struct ConversationsClassic: App {
private let clientsStore = ClientsStore.shared
private let globalSettingsStore = GlobalSettingsStore.shared
init() {
// There's a bug on iOS 17 where sheet may not load with large title, even if modifiers are set, which causes some tests to fail
@ -16,6 +17,7 @@ struct ConversationsClassic: App {
WindowGroup {
RootView()
.environmentObject(clientsStore)
.environmentObject(globalSettingsStore)
}
}
}

View file

@ -1,6 +1,7 @@
import SwiftUI
struct WelcomeScreen: View {
@EnvironmentObject var globalSettingsStore: GlobalSettingsStore
@Environment(\.router) var router
var body: some View {
@ -9,6 +10,23 @@ struct WelcomeScreen: View {
Color.Material.Background.light
.ignoresSafeArea()
if !globalSettingsStore.credentials.isEmpty && globalSettingsStore.credentials.allSatisfy({ !$0.isActive }) {
VStack {
HStack {
Spacer()
Image(systemName: "gear")
.foregroundColor(.Material.Elements.active)
.tappablePadding(.symmetric(10)) {
router.showScreen(.push) { _ in
SettingsScreen()
}
}
}
.padding()
Spacer()
}
}
// content
VStack(spacing: 32) {
// icon

View file

@ -7,7 +7,7 @@ struct ConversationScreen: View {
@Environment(\.router) var router
@StateObject var messagesStore: MessagesStore
@StateObject var attachments: AttachmentsStore
@StateObject var settings: SettingsStore
@StateObject var settings: ChatSettingsStore
@State private var autoScroll = true
@State private var firstIsVisible = true

View file

@ -5,7 +5,7 @@ import SwiftUI
struct ConversationSettingsScreen: View {
@Environment(\.router) var router
@EnvironmentObject var settingsStore: SettingsStore
@EnvironmentObject var settingsStore: ChatSettingsStore
var body: some View {
ZStack {

View file

@ -2,6 +2,7 @@ import SwiftUI
struct SettingsScreen: View {
@EnvironmentObject var clientsStore: ClientsStore
@EnvironmentObject var settingsStore: GlobalSettingsStore
@Environment(\.router) var router
var body: some View {
@ -22,19 +23,21 @@ struct SettingsScreen: View {
// Accounts section
SharedSectionTitle(text: L10n.Settings.Section.Accounts.title)
ForEach(clientsStore.clients) { client in
ForEach(settingsStore.credentials) { creds in
SharedListRow(
iconType: .charCircle(client.credentials.bareJid),
text: client.credentials.bareJid,
iconType: .charCircle(creds.bareJid),
text: creds.bareJid,
controlType: .switcher(isOn: Binding(
get: { client.credentials.isActive },
get: { creds.isActive },
set: { new in
client.setActive(new)
Task {
try? await creds.setActive(flag: new)
}
}
))
)
.onTapGesture {
print("Tapped account \(client.credentials.bareJid)")
print("Tapped account \(creds.bareJid)")
}
}
@ -83,6 +86,11 @@ struct SettingsScreen: View {
Spacer()
}
}
// .onDisappear {
// if settingsStore.credentials.isEmpty || settingsStore.credentials.allSatisfy({ !$0.isActive }) {
// router.dismissScreenStack()
// }
// }
}
@ViewBuilder private var addAccountSelector: some View {

View file

@ -3,11 +3,12 @@ import SwiftUI
struct RootView: View {
@EnvironmentObject var clientsStore: ClientsStore
@EnvironmentObject var globalSettingsStore: GlobalSettingsStore
var body: some View {
Group {
if clientsStore.ready {
if clientsStore.clients.isEmpty || clientsStore.clients.allSatisfy({ !$0.credentials.isActive }) {
if clientsStore.clients.isEmpty || globalSettingsStore.credentials.allSatisfy({ !$0.isActive }) {
RouterView { _ in
WelcomeScreen()
}