mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-29 10:30:32 +00:00
175 lines
5.7 KiB
Swift
175 lines
5.7 KiB
Swift
import Env
|
|
import Models
|
|
import StoreKit
|
|
import SwiftUI
|
|
import DesignSystem
|
|
|
|
extension StatusEditor {
|
|
@MainActor
|
|
struct ToolbarItems: ToolbarContent {
|
|
@State private var isLanguageConfirmPresented = false
|
|
@State private var isDismissAlertPresented: Bool = false
|
|
@State private var isDraftsSheetDisplayed: Bool = false
|
|
|
|
let mainSEVM: ViewModel
|
|
let focusedSEVM: ViewModel
|
|
let followUpSEVMs: [ViewModel]
|
|
|
|
@Environment(\.modelContext) private var context
|
|
@Environment(UserPreferences.self) private var preferences
|
|
@Environment(Theme.self) private var theme
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
@Environment(\.dismissWindow) private var dismissWindow
|
|
#else
|
|
@Environment(\.dismiss) private var dismiss
|
|
#endif
|
|
|
|
var body: some ToolbarContent {
|
|
if !mainSEVM.mode.isInShareExtension {
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
Button {
|
|
isDraftsSheetDisplayed = true
|
|
} label: {
|
|
Image(systemName: "pencil.and.list.clipboard")
|
|
}
|
|
.accessibilityLabel("accessibility.editor.button.drafts")
|
|
.popover(isPresented: $isDraftsSheetDisplayed) {
|
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
|
draftsListView
|
|
.presentationDetents([.medium])
|
|
} else {
|
|
draftsListView
|
|
.frame(width: 400, height: 500)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
Button {
|
|
Task {
|
|
mainSEVM.evaluateLanguages()
|
|
if preferences.autoDetectPostLanguage, let _ = mainSEVM.languageConfirmationDialogLanguages {
|
|
isLanguageConfirmPresented = true
|
|
} else {
|
|
await postAllStatus()
|
|
}
|
|
}
|
|
} label: {
|
|
Image(systemName: "paperplane.fill")
|
|
.bold()
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
.disabled(!mainSEVM.canPost || mainSEVM.isPosting)
|
|
.keyboardShortcut(.return, modifiers: .command)
|
|
.confirmationDialog("", isPresented: $isLanguageConfirmPresented, actions: {
|
|
languageConfirmationDialog
|
|
})
|
|
}
|
|
|
|
ToolbarItem(placement: .navigationBarLeading) {
|
|
Button {
|
|
if mainSEVM.shouldDisplayDismissWarning {
|
|
isDismissAlertPresented = true
|
|
} else {
|
|
close()
|
|
NotificationCenter.default.post(name: .shareSheetClose,
|
|
object: nil)
|
|
}
|
|
} label: {
|
|
Image(systemName: "xmark")
|
|
}
|
|
.keyboardShortcut(.cancelAction)
|
|
.confirmationDialog(
|
|
"",
|
|
isPresented: $isDismissAlertPresented,
|
|
actions: {
|
|
Button("status.draft.delete", role: .destructive) {
|
|
close()
|
|
NotificationCenter.default.post(name: .shareSheetClose,
|
|
object: nil)
|
|
}
|
|
Button("status.draft.save") {
|
|
context.insert(Draft(content: mainSEVM.statusText.string))
|
|
close()
|
|
NotificationCenter.default.post(name: .shareSheetClose,
|
|
object: nil)
|
|
}
|
|
Button("action.cancel", role: .cancel) {}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
@discardableResult
|
|
private func postStatus(with model: ViewModel, isMainPost: Bool) async -> Status? {
|
|
let status = await model.postStatus()
|
|
if status != nil, isMainPost {
|
|
close()
|
|
SoundEffectManager.shared.playSound(.tootSent)
|
|
NotificationCenter.default.post(name: .shareSheetClose, object: nil)
|
|
#if !targetEnvironment(macCatalyst)
|
|
if !mainSEVM.mode.isInShareExtension, !preferences.requestedReview {
|
|
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
|
|
SKStoreReviewController.requestReview(in: scene)
|
|
}
|
|
preferences.requestedReview = true
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return status
|
|
}
|
|
|
|
private func postAllStatus() async {
|
|
guard var latestPost = await postStatus(with: mainSEVM, isMainPost: true) else { return }
|
|
for p in followUpSEVMs {
|
|
p.mode = .replyTo(status: latestPost)
|
|
guard let post = await postStatus(with: p, isMainPost: false) else {
|
|
break
|
|
}
|
|
latestPost = post
|
|
}
|
|
}
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
private func close() { dismissWindow() }
|
|
#else
|
|
private func close() { dismiss() }
|
|
#endif
|
|
|
|
@ViewBuilder
|
|
private var languageConfirmationDialog: some View {
|
|
if let (detected: detected, selected: selected) = mainSEVM.languageConfirmationDialogLanguages,
|
|
let detectedLong = Locale.current.localizedString(forLanguageCode: detected),
|
|
let selectedLong = Locale.current.localizedString(forLanguageCode: selected)
|
|
{
|
|
Button("status.editor.language-select.confirmation.detected-\(detectedLong)") {
|
|
mainSEVM.selectedLanguage = detected
|
|
Task { await postAllStatus() }
|
|
}
|
|
Button("status.editor.language-select.confirmation.selected-\(selectedLong)") {
|
|
mainSEVM.selectedLanguage = selected
|
|
Task { await postAllStatus() }
|
|
}
|
|
Button("action.cancel", role: .cancel) {
|
|
mainSEVM.languageConfirmationDialogLanguages = nil
|
|
}
|
|
} else {
|
|
EmptyView()
|
|
}
|
|
}
|
|
|
|
private var draftsListView: some View {
|
|
DraftsListView(selectedDraft: .init(get: {
|
|
nil
|
|
}, set: { draft in
|
|
if let draft {
|
|
focusedSEVM.insertStatusText(text: draft.content)
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
}
|