conversations-classic-ios/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift

132 lines
5.3 KiB
Swift
Raw Normal View History

2024-07-10 17:49:36 +00:00
import AVFoundation
2024-07-10 14:13:47 +00:00
import Combine
import Foundation
2024-07-10 17:49:36 +00:00
import Photos
import UIKit
2024-07-10 14:13:47 +00:00
final class SharingMiddleware {
static let shared = SharingMiddleware()
2024-07-14 10:48:04 +00:00
func middleware(state: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
2024-07-10 14:13:47 +00:00
switch action {
2024-07-14 13:00:14 +00:00
// MARK: - Camera and Gallery Access
2024-07-10 17:49:36 +00:00
case .sharingAction(.checkCameraAccess):
2024-08-07 12:49:47 +00:00
return Deferred {
Future<AppAction, Never> { promise in
let status = AVCaptureDevice.authorizationStatus(for: .video)
switch status {
case .authorized:
promise(.success(.sharingAction(.setCameraAccess(true))))
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { granted in
promise(.success(.sharingAction(.setCameraAccess(granted))))
}
case .denied, .restricted:
promise(.success(.sharingAction(.setCameraAccess(false))))
@unknown default:
promise(.success(.sharingAction(.setCameraAccess(false))))
2024-07-10 17:49:36 +00:00
}
}
}
.eraseToAnyPublisher()
case .sharingAction(.checkGalleryAccess):
2024-08-07 12:49:47 +00:00
return Deferred {
Future<AppAction, Never> { promise in
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized, .limited:
promise(.success(.sharingAction(.setGalleryAccess(true))))
case .notDetermined:
PHPhotoLibrary.requestAuthorization { status in
promise(.success(.sharingAction(.setGalleryAccess(status == .authorized))))
}
case .denied, .restricted:
promise(.success(.sharingAction(.setGalleryAccess(false))))
@unknown default:
promise(.success(.sharingAction(.setGalleryAccess(false))))
2024-07-10 17:49:36 +00:00
}
}
}
.eraseToAnyPublisher()
2024-07-14 13:42:51 +00:00
case .fileAction(.itemsFromGalleryFetched(let items)):
return Just(.sharingAction(.galleryItemsUpdated(items: items)))
.eraseToAnyPublisher()
2024-07-10 17:49:36 +00:00
2024-07-14 13:00:14 +00:00
// MARK: - Sharing
case .sharingAction(.shareMedia(let ids)):
2024-08-07 12:49:47 +00:00
return Deferred {
Future { promise in
let items = state.sharingState.galleryItems.filter { ids.contains($0.id) }
promise(.success(.fileAction(.copyGalleryItemsForUploading(items: items))))
}
2024-07-14 13:00:14 +00:00
}
.eraseToAnyPublisher()
2024-07-16 11:48:50 +00:00
case .fileAction(.itemsCopiedForUploading(let newMessageIds, let localNames)):
2024-07-14 17:08:43 +00:00
if let chat = state.conversationsState.currentChat {
return Just(.conversationAction(.sendMediaMessages(
from: chat.account,
to: chat.participant,
messagesIds: newMessageIds,
localFilesNames: localNames
)))
.eraseToAnyPublisher()
} else {
return Empty().eraseToAnyPublisher()
}
2024-07-16 11:48:50 +00:00
case .sharingAction(.cameraCaptured(let media, let type)):
2024-08-07 12:49:47 +00:00
return Deferred {
Future { promise in
if let (id, localName) = FileProcessing.shared.copyCameraCapturedForUploading(media: media, type: type) {
promise(.success(.fileAction(.itemsCopiedForUploading(newMessageIds: [id], localNames: [localName])))
)
} else {
promise(.success(.info("SharingMiddleware: camera's captured file didn't copied")))
}
2024-07-16 11:48:50 +00:00
}
}
.eraseToAnyPublisher()
2024-07-14 10:48:04 +00:00
case .sharingAction(.shareLocation(let lat, let lon)):
if let chat = state.conversationsState.currentChat {
let msg = "geo:\(lat),\(lon)"
return Just(.conversationAction(.sendMessage(from: chat.account, to: chat.participant, body: msg)))
.eraseToAnyPublisher()
} else {
return Empty().eraseToAnyPublisher()
}
2024-07-16 18:05:15 +00:00
case .sharingAction(.shareDocuments(let data, let extensions)):
2024-08-07 12:49:47 +00:00
return Deferred {
Future { promise in
let ids = FileProcessing.shared.copyDocumentsForUploading(data: data, extensions: extensions)
promise(.success(.fileAction(.itemsCopiedForUploading(newMessageIds: ids.map { $0.0 }, localNames: ids.map { $0.1 })))
)
}
2024-07-16 18:05:15 +00:00
}
.eraseToAnyPublisher()
2024-07-14 13:00:14 +00:00
case .sharingAction(.shareContact(let jid)):
if let chat = state.conversationsState.currentChat {
let msg = "contact:\(jid)"
return Just(.conversationAction(.sendMessage(from: chat.account, to: chat.participant, body: msg)))
.eraseToAnyPublisher()
} else {
return Empty().eraseToAnyPublisher()
}
2024-07-10 14:13:47 +00:00
default:
return Empty().eraseToAnyPublisher()
}
}
}