From 5c1f113c54467df38627a252562a5b58f6d856d7 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Tue, 9 Jan 2024 16:17:34 +0100 Subject: [PATCH] Add a progress indicator when posting a new post --- .../Sources/StatusKit/Editor/MainView.swift | 3 ++ .../StatusKit/Editor/ToolbarItems.swift | 1 - .../Sources/StatusKit/Editor/ViewModel.swift | 37 +++++++++++++++---- .../StatusKit/Row/StatusRowViewModel.swift | 2 +- .../Subviews/StatusRowMediaPreviewView.swift | 7 +++- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Packages/StatusKit/Sources/StatusKit/Editor/MainView.swift b/Packages/StatusKit/Sources/StatusKit/Editor/MainView.swift index 6aae8b70..052a73c6 100644 --- a/Packages/StatusKit/Sources/StatusKit/Editor/MainView.swift +++ b/Packages/StatusKit/Sources/StatusKit/Editor/MainView.swift @@ -44,6 +44,9 @@ extension StatusEditor { NavigationStack { ScrollView { VStackLayout(spacing: 0) { + if mainSEVM.isPosting { + ProgressView(value: mainSEVM.postingProgress, total: 100.0) + } EditorView( viewModel: mainSEVM, followUpSEVMs: $followUpSEVMs, diff --git a/Packages/StatusKit/Sources/StatusKit/Editor/ToolbarItems.swift b/Packages/StatusKit/Sources/StatusKit/Editor/ToolbarItems.swift index 92da1ed1..6632d31f 100644 --- a/Packages/StatusKit/Sources/StatusKit/Editor/ToolbarItems.swift +++ b/Packages/StatusKit/Sources/StatusKit/Editor/ToolbarItems.swift @@ -105,7 +105,6 @@ extension StatusEditor { @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) diff --git a/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift b/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift index 76f42230..3203c1d1 100644 --- a/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift +++ b/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift @@ -87,7 +87,10 @@ extension StatusEditor { var spoilerOn: Bool = false var spoilerText: String = "" + var postingProgress: Double = 0.0 + var postingTimer: Timer? var isPosting: Bool = false + var mediaPickers: [PhotosPickerItem] = [] { didSet { if mediaPickers.count > 4 { @@ -185,6 +188,19 @@ extension StatusEditor { func postStatus() async -> Status? { guard let client else { return nil } do { + if postingTimer == nil { + Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { timer in + Task { @MainActor in + if self.postingProgress < 100 { + self.postingProgress += 0.5 + } + if self.postingProgress >= 100 { + self.postingTimer?.invalidate() + self.postingTimer = nil + } + } + } + } isPosting = true let postStatus: Status? var pollData: StatusData.PollData? @@ -204,20 +220,27 @@ extension StatusEditor { switch mode { case .new, .replyTo, .quote, .mention, .shareExtension: postStatus = try await client.post(endpoint: Statuses.postStatus(json: data)) - if let postStatus { - StreamWatcher.shared.emmitPostEvent(for: postStatus) - } case let .edit(status): postStatus = try await client.put(endpoint: Statuses.editStatus(id: status.id, json: data)) - if let postStatus { - StreamWatcher.shared.emmitEditEvent(for: postStatus) - } } - HapticManager.shared.fireHaptic(.notification(.success)) + + postingTimer?.invalidate() + postingTimer = nil + + if let postStatus { + StreamWatcher.shared.emmitEditEvent(for: postStatus) + HapticManager.shared.fireHaptic(.notification(.success)) + withAnimation { + postingProgress = 99.0 + } + try await Task.sleep(for: .seconds(0.5)) + } + if hasExplicitlySelectedLanguage, let selectedLanguage { preferences?.markLanguageAsSelected(isoCode: selectedLanguage) } isPosting = false + return postStatus } catch { if let error = error as? Models.ServerError { diff --git a/Packages/StatusKit/Sources/StatusKit/Row/StatusRowViewModel.swift b/Packages/StatusKit/Sources/StatusKit/Row/StatusRowViewModel.swift index cba5c623..32e91b1b 100644 --- a/Packages/StatusKit/Sources/StatusKit/Row/StatusRowViewModel.swift +++ b/Packages/StatusKit/Sources/StatusKit/Row/StatusRowViewModel.swift @@ -280,8 +280,8 @@ import SwiftUI func delete() async { do { - _ = try await client.delete(endpoint: Statuses.status(id: status.id)) StreamWatcher.shared.emmitDeleteEvent(for: status.id) + _ = try await client.delete(endpoint: Statuses.status(id: status.id)) } catch {} } diff --git a/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowMediaPreviewView.swift index dcf54311..d4eea8cd 100644 --- a/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowMediaPreviewView.swift +++ b/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowMediaPreviewView.swift @@ -8,6 +8,7 @@ import SwiftUI @MainActor public struct StatusRowMediaPreviewView: View { + @Environment(\.isPresented) private var isPresented @Environment(\.openWindow) private var openWindow @Environment(\.extraLeadingInset) private var extraLeadingInset: CGFloat @Environment(\.isCompact) private var isCompact: Bool @@ -31,7 +32,11 @@ public struct StatusRowMediaPreviewView: View { { return sceneDelegate.windowWidth * 0.80 } - return sceneDelegate.windowWidth + if isPresented && UIDevice.current.userInterfaceIdiom == .pad { + return sceneDelegate.windowWidth * 0.50 + } else { + return sceneDelegate.windowWidth + } #endif }