mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Flescio/add room image (#961)
* image media upload for room creation * fix remove duplicate logic * use Async Image, add Focusable Fields in create room * remove alert message which doesn't have a copy * add remove duplicates on crete room image * add button style for preventing undesired touches * add changelog, add error case for file too large * Fix iPad sheet presentation * add error media preprocess * dismissing focus on image picker
This commit is contained in:
@@ -20,7 +20,7 @@ import SwiftUI
|
||||
struct StartChatScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
weak var userIndicatorController: UserIndicatorControllerProtocol?
|
||||
let navigationStackCoordinator: NavigationStackCoordinator?
|
||||
let navigationStackCoordinator: NavigationStackCoordinator
|
||||
let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||
}
|
||||
|
||||
@@ -45,6 +45,14 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
||||
selectedUsers.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private var navigationStackCoordinator: NavigationStackCoordinator {
|
||||
parameters.navigationStackCoordinator
|
||||
}
|
||||
|
||||
private var userIndicatorController: UserIndicatorControllerProtocol? {
|
||||
parameters.userIndicatorController
|
||||
}
|
||||
|
||||
var actions: AnyPublisher<StartChatScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
@@ -60,12 +68,12 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .close:
|
||||
self.actionsSubject.send(.close)
|
||||
actionsSubject.send(.close)
|
||||
case .createRoom:
|
||||
// before creating a room we select the users we would like to invite in that room
|
||||
self.presentInviteUsersScreen()
|
||||
presentInviteUsersScreen()
|
||||
case .openRoom(let identifier):
|
||||
self.actionsSubject.send(.openRoom(withIdentifier: identifier))
|
||||
actionsSubject.send(.openRoom(withIdentifier: identifier))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -99,7 +107,7 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
parameters.navigationStackCoordinator?.push(coordinator) { [weak self] in
|
||||
navigationStackCoordinator.push(coordinator) { [weak self] in
|
||||
self?.createRoomParameters.send(.init())
|
||||
self?.selectedUsers.send([])
|
||||
}
|
||||
@@ -107,27 +115,71 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
private func openCreateRoomScreen() {
|
||||
let createParameters = CreateRoomCoordinatorParameters(userSession: parameters.userSession,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
userIndicatorController: userIndicatorController,
|
||||
createRoomParameters: createRoomParametersPublisher,
|
||||
selectedUsers: selectedUsersPublisher)
|
||||
let coordinator = CreateRoomCoordinator(parameters: createParameters)
|
||||
coordinator.actions.sink { [weak self] result in
|
||||
guard let self else { return }
|
||||
switch result {
|
||||
case .deselectUser(let user):
|
||||
self?.toggleUser(user)
|
||||
self.toggleUser(user)
|
||||
case .updateDetails(let details):
|
||||
self?.createRoomParameters.send(details)
|
||||
self.createRoomParameters.send(details)
|
||||
case .openRoom(let identifier):
|
||||
self?.actionsSubject.send(.openRoom(withIdentifier: identifier))
|
||||
self.actionsSubject.send(.openRoom(withIdentifier: identifier))
|
||||
case .displayMediaPickerWithSource(let source):
|
||||
self.displayMediaPickerWithSource(source)
|
||||
case .removeImage:
|
||||
var parameters = self.createRoomParameters.value
|
||||
parameters.avatarImageMedia = nil
|
||||
self.createRoomParameters.send(parameters)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
parameters.navigationStackCoordinator?.push(coordinator)
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
let mediaUploadingPreprocessor = MediaUploadingPreprocessor()
|
||||
private func displayMediaPickerWithSource(_ source: MediaPickerScreenSource) {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
let userIndicatorController = UserIndicatorController(rootCoordinator: stackCoordinator)
|
||||
|
||||
let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController, source: source) { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .cancel:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .selectMediaAtURL(let url):
|
||||
processAvatar(from: url)
|
||||
}
|
||||
}
|
||||
|
||||
stackCoordinator.setRootCoordinator(mediaPickerCoordinator)
|
||||
|
||||
navigationStackCoordinator.setSheetCoordinator(userIndicatorController)
|
||||
}
|
||||
|
||||
private func processAvatar(from url: URL) {
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
showLoadingIndicator()
|
||||
Task { [weak self] in
|
||||
guard let self else { return }
|
||||
do {
|
||||
let media = try await mediaUploadingPreprocessor.processMedia(at: url).get()
|
||||
var parameters = createRoomParameters.value
|
||||
parameters.avatarImageMedia = media
|
||||
createRoomParameters.send(parameters)
|
||||
} catch {
|
||||
userIndicatorController?.alertInfo = AlertInfo(id: .init(), title: L10n.commonError, message: L10n.errorUnknown)
|
||||
}
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleUser(_ user: UserProfileProxy) {
|
||||
var selectedUsers = selectedUsers.value
|
||||
if let index = selectedUsers.firstIndex(where: { $0.userID == user.userID }) {
|
||||
@@ -137,4 +189,19 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
self.selectedUsers.send(selectedUsers)
|
||||
}
|
||||
|
||||
// MARK: Loading indicator
|
||||
|
||||
private static let loadingIndicatorIdentifier = "StartChatCoordinatorLoading"
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
private func hideLoadingIndicator() {
|
||||
userIndicatorController?.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user