mirror of
https://github.com/ProtonMail/ios-mail.git
synced 2026-05-15 09:50:39 +00:00
135 lines
4.3 KiB
Swift
135 lines
4.3 KiB
Swift
// Copyright (c) 2024 Proton Technologies AG
|
|
//
|
|
// This file is part of Proton Mail.
|
|
//
|
|
// Proton Mail is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Proton Mail is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
|
|
|
import InboxCore
|
|
import InboxCoreUI
|
|
import InboxDesignSystem
|
|
import ProtonUIFoundations
|
|
import SwiftUI
|
|
import proton_app_uniffi
|
|
|
|
public struct ComposerScreen: View {
|
|
@Environment(\.dismissTestable) var dismiss: Dismissable
|
|
@EnvironmentObject var toastStateStore: ToastStateStore
|
|
@StateObject private var model: ComposerScreenModel
|
|
private let messageLastScheduledTime: UInt64?
|
|
private let isAddingAttachmentsEnabled: Bool
|
|
private let onDismiss: (ComposerDismissReason) -> Void
|
|
private let dependencies: Dependencies
|
|
|
|
public init(
|
|
messageId: ID,
|
|
messageLastScheduledTime: UInt64? = nil,
|
|
dependencies: Dependencies,
|
|
onDismiss: @escaping (ComposerDismissReason) -> Void
|
|
) {
|
|
self.messageLastScheduledTime = messageLastScheduledTime
|
|
self.dependencies = dependencies
|
|
isAddingAttachmentsEnabled = true
|
|
self.onDismiss = onDismiss
|
|
self._model = StateObject(
|
|
wrappedValue:
|
|
ComposerScreenModel(
|
|
messageId: messageId,
|
|
userSession: dependencies.userSession
|
|
)
|
|
)
|
|
}
|
|
|
|
public init(
|
|
draft: AppDraftProtocol,
|
|
draftOrigin: DraftOrigin,
|
|
dependencies: Dependencies,
|
|
isAddingAttachmentsEnabled: Bool = true,
|
|
onDismiss: @escaping (ComposerDismissReason) -> Void
|
|
) {
|
|
self.messageLastScheduledTime = nil
|
|
self.dependencies = dependencies
|
|
self.isAddingAttachmentsEnabled = isAddingAttachmentsEnabled
|
|
self.onDismiss = onDismiss
|
|
self._model = StateObject(
|
|
wrappedValue: ComposerScreenModel(
|
|
draft: draft,
|
|
draftOrigin: draftOrigin
|
|
)
|
|
)
|
|
}
|
|
|
|
public var body: some View {
|
|
switch model.state {
|
|
case .loadingDraft:
|
|
ComposerLoadingView(dismissAction: {
|
|
model.cancel()
|
|
dismiss()
|
|
})
|
|
.onChange(of: model.draftError) { _, newValue in
|
|
guard let newValue else { return }
|
|
toastStateStore.present(toast: .error(message: newValue.localizedDescription))
|
|
dismiss()
|
|
}
|
|
case .draftLoaded(let draft, let draftOrigin):
|
|
ComposerView(
|
|
draft: draft,
|
|
draftOrigin: draftOrigin,
|
|
draftLastScheduledTime: messageLastScheduledTime,
|
|
contactProvider: dependencies.contactProvider,
|
|
isAddingAttachmentsEnabled: isAddingAttachmentsEnabled,
|
|
onDismiss: onDismiss
|
|
)
|
|
.interactiveDismissDisabled()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ComposerScreen {
|
|
public struct Dependencies {
|
|
let contactProvider: ComposerContactProvider
|
|
let userSession: MailUserSession
|
|
|
|
public init(contactProvider: ComposerContactProvider, userSession: MailUserSession) {
|
|
self.contactProvider = contactProvider
|
|
self.userSession = userSession
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ComposerLoadingView: View {
|
|
var dismissAction: (() -> Void)?
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
ComposerTopBar(isSendEnabled: false, dismissAction: dismissAction)
|
|
Spacer()
|
|
ProtonSpinner()
|
|
Spacer()
|
|
}
|
|
.background(DS.Color.Background.norm)
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
let toastStateStore = ToastStateStore(initialState: .initial)
|
|
|
|
ComposerScreen(
|
|
draft: .emptyMock,
|
|
draftOrigin: .new,
|
|
dependencies: .init(contactProvider: .mockInstance, userSession: .init(noPointer: .init())),
|
|
onDismiss: { _ in }
|
|
)
|
|
.environmentObject(toastStateStore)
|
|
}
|