This commit is contained in:
fmodf 2024-08-17 14:11:11 +02:00
parent bf040bda25
commit 1676ab63e9
8 changed files with 57 additions and 32 deletions

View file

@ -141,7 +141,7 @@ extension ClientsStore {
} }
extension ClientsStore { extension ClientsStore {
func conversationStore(for roster: Roster) async throws -> ConversationStore { func getStores(for roster: Roster) async throws -> (ConversationStore, FileStore) {
while !ready { while !ready {
await Task.yield() await Task.yield()
} }
@ -150,10 +150,13 @@ extension ClientsStore {
throw ClientStoreError.clientNotFound throw ClientStoreError.clientNotFound
} }
return ConversationStore(roster: roster, client: client) let conversation = ConversationStore(roster: roster, client: client)
let fileStore = FileStore(roster: roster, client: client)
return (conversation, fileStore)
} }
func conversationStore(for chat: Chat) async throws -> ConversationStore { func getStores(for chat: Chat) async throws -> (ConversationStore, FileStore) {
while !ready { while !ready {
await Task.yield() await Task.yield()
} }
@ -163,6 +166,9 @@ extension ClientsStore {
} }
let roster = try await chat.fetchRoster() let roster = try await chat.fetchRoster()
return ConversationStore(roster: roster, client: client) let conversation = ConversationStore(roster: roster, client: client)
let fileStore = FileStore(roster: roster, client: client)
return (conversation, fileStore)
} }
} }

View file

@ -8,8 +8,6 @@ import Photos
final class ConversationStore: ObservableObject { final class ConversationStore: ObservableObject {
@Published private(set) var messages: [Message] = [] @Published private(set) var messages: [Message] = []
@Published var replyText = "" @Published var replyText = ""
@Published var cameraAccessGranted = false
@Published var galleryAccessGranted = false
private(set) var roster: Roster private(set) var roster: Roster
private let client: Client private let client: Client
@ -53,27 +51,6 @@ extension ConversationStore {
} }
} }
extension ConversationStore {
func checkCameraAuthorization() async {
let status = AVCaptureDevice.authorizationStatus(for: .video)
var isAuthorized = status == .authorized
if status == .notDetermined {
isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
}
cameraAccessGranted = isAuthorized
}
func checkGalleryAuthorization() async {
let status = PHPhotoLibrary.authorizationStatus()
var isAuthorized = status == .authorized
if status == .notDetermined {
let req = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
isAuthorized = (req == .authorized) || (req == .limited)
}
galleryAccessGranted = isAuthorized
}
}
private extension ConversationStore { private extension ConversationStore {
func subscribe() { func subscribe() {
messagesCancellable = ValueObservation.tracking(Message messagesCancellable = ValueObservation.tracking(Message

View file

@ -0,0 +1,38 @@
import Combine
import Foundation
import Photos
@MainActor
final class FileStore: ObservableObject {
@Published var cameraAccessGranted = false
@Published var galleryAccessGranted = false
private let client: Client
private let roster: Roster
init(roster: Roster, client: Client) {
self.client = client
self.roster = roster
}
}
extension FileStore {
func checkCameraAuthorization() async {
let status = AVCaptureDevice.authorizationStatus(for: .video)
var isAuthorized = status == .authorized
if status == .notDetermined {
isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
}
cameraAccessGranted = isAuthorized
}
func checkGalleryAuthorization() async {
let status = PHPhotoLibrary.authorizationStatus()
var isAuthorized = status == .authorized
if status == .notDetermined {
let req = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
isAuthorized = (req == .authorized) || (req == .limited)
}
galleryAccessGranted = isAuthorized
}
}

View file

@ -60,9 +60,9 @@ private struct ChatsRow: View {
} }
do { do {
let conversation = try await clientsStore.conversationStore(for: chat) let (conversation, fileStore) = try await clientsStore.getStores(for: chat)
router.showScreen(.push) { _ in router.showScreen(.push) { _ in
ConversationScreen(conversation: conversation) ConversationScreen(conversation: conversation, fileStore: fileStore)
.navigationBarHidden(true) .navigationBarHidden(true)
} }
} catch { } catch {

View file

@ -158,9 +158,9 @@ private struct ContactsScreenRow: View {
} }
do { do {
let conversation = try await clientsStore.conversationStore(for: roster) let (conversation, fileStore) = try await clientsStore.getStores(for: roster)
router.showScreen(.push) { _ in router.showScreen(.push) { _ in
ConversationScreen(conversation: conversation) ConversationScreen(conversation: conversation, fileStore: fileStore)
.navigationBarHidden(true) .navigationBarHidden(true)
} }
} catch { } catch {

View file

@ -3,7 +3,7 @@ import SwiftUI
struct CameraCellPreview: View { struct CameraCellPreview: View {
@Environment(\.router) var router @Environment(\.router) var router
@EnvironmentObject var store: ConversationStore @EnvironmentObject var store: FileStore
var body: some View { var body: some View {
Group { Group {

View file

@ -6,6 +6,7 @@ import SwiftUI
struct ConversationScreen: View { struct ConversationScreen: View {
@Environment(\.router) var router @Environment(\.router) var router
@StateObject var conversation: ConversationStore @StateObject var conversation: ConversationStore
@StateObject var fileStore: FileStore
@State private var autoScroll = true @State private var autoScroll = true
@State private var firstIsVisible = true @State private var firstIsVisible = true
@ -101,6 +102,7 @@ struct ConversationScreen: View {
.safeAreaInset(edge: .bottom, spacing: 0) { .safeAreaInset(edge: .bottom, spacing: 0) {
ConversationTextInput(autoScroll: $autoScroll) ConversationTextInput(autoScroll: $autoScroll)
.environmentObject(conversation) .environmentObject(conversation)
.environmentObject(fileStore)
} }
} }
} }

View file

@ -4,6 +4,7 @@ import UIKit
struct ConversationTextInput: View { struct ConversationTextInput: View {
@Environment(\.router) var router @Environment(\.router) var router
@EnvironmentObject var conversation: ConversationStore @EnvironmentObject var conversation: ConversationStore
@EnvironmentObject var fileStore: FileStore
@State private var messageStr = "" @State private var messageStr = ""
@FocusState private var isFocused: Bool @FocusState private var isFocused: Bool
@ -53,6 +54,7 @@ struct ConversationTextInput: View {
router.showScreen(.fullScreenCover) { _ in router.showScreen(.fullScreenCover) { _ in
AttachmentPickerScreen() AttachmentPickerScreen()
.environmentObject(conversation) .environmentObject(conversation)
.environmentObject(fileStore)
} }
} }
TextField("", text: $messageStr, prompt: Text(L10n.Chat.textfieldPrompt).foregroundColor(.Material.Shape.separator)) TextField("", text: $messageStr, prompt: Text(L10n.Chat.textfieldPrompt).foregroundColor(.Material.Shape.separator))