From 54ee5603b5983d15869a9f2c644eec977e256293 Mon Sep 17 00:00:00 2001 From: shannon Date: Fri, 13 Dec 2024 16:41:52 -0500 Subject: [PATCH] Add indication of publishing progress to the publish button. Contributes to #846 Toot lost in poor network conditions --- .../Scene/Compose/ComposeViewController.swift | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift index 6b484ec2b..91e79c645 100644 --- a/Mastodon/Scene/Compose/ComposeViewController.swift +++ b/Mastodon/Scene/Compose/ComposeViewController.swift @@ -19,6 +19,11 @@ import MastodonSDK final class ComposeViewController: UIViewController { static let minAutoCompleteVisibleHeight: CGFloat = 100 + lazy var publishProgressView: UIProgressView = { + let progressView = UIProgressView(progressViewStyle: .bar) + progressView.alpha = 0 + return progressView + }() var disposeBag = Set() var viewModel: ComposeViewModel @@ -26,9 +31,39 @@ final class ComposeViewController: UIViewController { init(viewModel: ComposeViewModel) { self.viewModel = viewModel super.init(nibName: nil, bundle: nil) + self.setUpPublishingIndicator() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + func setUpPublishingIndicator() { + publishProgressView.translatesAutoresizingMaskIntoConstraints = false + publishProgressView.tintColor = .systemIndigo + publishProgressView.trackTintColor = .systemGray + publishButton.addSubview(publishProgressView) + let constraints = [ + publishProgressView.leadingAnchor.constraint(equalTo: publishButton.leadingAnchor), + publishProgressView.trailingAnchor.constraint(equalTo: publishButton.trailingAnchor), + publishProgressView.topAnchor.constraint(equalTo: publishButton.topAnchor), + publishProgressView.bottomAnchor.constraint(equalTo: publishButton.bottomAnchor), + publishProgressView.heightAnchor.constraint(greaterThanOrEqualToConstant: 35) + ] + NSLayoutConstraint.activate(constraints) + + PublisherService.shared.$currentPublishProgress + .receive(on: DispatchQueue.main) + .sink { [weak self] progress in + guard let self = self else { return } + let progress = Float(progress) + if progress > 0 { + UIView.animate(withDuration: 0.25) { + self.publishProgressView.alpha = 1 + } + self.publishProgressView.setProgress(progress, animated: true) + } + } + .store(in: &disposeBag) + } lazy var composeContentViewModel: ComposeContentViewModel = { @@ -241,13 +276,24 @@ extension ComposeViewController { private func enqueuePublishStatus() { do { let statusPublisher = try composeContentViewModel.statusPublisher() + cancelBarButtonItem.isEnabled = false + publishButton.isEnabled = false statusPublisher.state .receive(on: DispatchQueue.main) .sink { [weak self] result in + self?.cancelBarButtonItem.isEnabled = true + switch result { case .success: - self?.dismiss(animated: true, completion: nil) + self?.publishProgressView.progress = 100 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { + self?.dismiss(animated: true, completion: nil) + } case .failure(let error): + UIView.animate(withDuration: 0.25) { + self?.publishProgressView.alpha = 0 + } + self?.publishButton.isEnabled = true let alertController = UIAlertController.standardAlert(of: error) self?.present(alertController, animated: true) // HomeTimelineViewController is also listening and will post the alert if this view has been dismissed