Skip to content

Commit 896f26f

Browse files
Avoid publishing the same post twice due to accidental double tap of publish button
1 parent a5e5384 commit 896f26f

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

Mastodon/Scene/Compose/ComposeViewController.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,11 @@ extension ComposeViewController {
361361
}
362362

363363
private func enqueuePublishStatus() {
364+
guard !composeContentViewModel.isPublishing else { return }
364365
do {
365366
let statusPublisher = try composeContentViewModel.statusPublisher()
366367
cancelBarButtonItem.isEnabled = false
367-
publishButton.isEnabled = false
368+
composeContentViewModel.beginPublish()
368369
statusPublisher.state
369370
.receive(on: DispatchQueue.main)
370371
.sink { [weak self] result in
@@ -374,13 +375,15 @@ extension ComposeViewController {
374375
case .success:
375376
self?.publishProgressView.progress = 100
376377
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
377-
self?.dismiss(animated: true, completion: { self?.viewModel.postPublishCompletion?(true) })
378+
self?.dismiss(animated: true, completion: { self?.viewModel.postPublishCompletion?(true)
379+
self?.composeContentViewModel.donePublishing()
380+
})
378381
}
379382
case .failure(let error):
380383
UIView.animate(withDuration: 0.25) {
381384
self?.publishProgressView.alpha = 0
382385
}
383-
self?.publishButton.isEnabled = true
386+
self?.composeContentViewModel.donePublishing()
384387
let alertController = UIAlertController.standardAlert(of: error)
385388
self?.present(alertController, animated: true)
386389
// HomeTimelineViewController is also listening and will post the alert if this view has been dismissed
@@ -395,6 +398,7 @@ extension ComposeViewController {
395398
authenticationBox: viewModel.authenticationBox
396399
)
397400
} catch {
401+
composeContentViewModel.donePublishing()
398402
let alertController = UIAlertController.standardAlert(of: error)
399403
present(alertController, animated: true)
400404
return
@@ -435,10 +439,11 @@ extension ComposeViewController {
435439
}
436440

437441
private func enqueuePublishStatusEdit() {
442+
guard !composeContentViewModel.isPublishing else { return }
438443
do {
439444
guard let editStatusPublisher = try composeContentViewModel.statusEditPublisher() else { return }
440445
cancelBarButtonItem.isEnabled = false
441-
saveButton.isEnabled = false
446+
composeContentViewModel.beginPublish()
442447
editStatusPublisher.state
443448
.receive(on: DispatchQueue.main)
444449
.sink { [weak self] result in
@@ -448,13 +453,15 @@ extension ComposeViewController {
448453
case .success:
449454
self?.editPublishProgressView.progress = 100
450455
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
451-
self?.dismiss(animated: true, completion: { self?.viewModel.postPublishCompletion?(true) })
456+
self?.dismiss(animated: true, completion: { self?.viewModel.postPublishCompletion?(true)
457+
self?.composeContentViewModel.donePublishing()
458+
})
452459
}
453460
case .failure(let error):
454461
UIView.animate(withDuration: 0.25) {
455462
self?.editPublishProgressView.alpha = 0
456463
}
457-
self?.saveButton.isEnabled = true
464+
self?.composeContentViewModel.donePublishing()
458465
let alertController = UIAlertController.standardAlert(of: error)
459466
self?.present(alertController, animated: true)
460467
// HomeTimelineViewController is also listening and will post the alert if this view has been dismissed
@@ -468,6 +475,7 @@ extension ComposeViewController {
468475
authenticationBox: viewModel.authenticationBox
469476
)
470477
} catch {
478+
composeContentViewModel.donePublishing()
471479
let alertController = UIAlertController.standardAlert(of: error)
472480
present(alertController, animated: true)
473481
return

MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public protocol ComposeContentViewModelDelegate: AnyObject {
2121

2222
@MainActor
2323
public final class ComposeContentViewModel: NSObject, ObservableObject {
24+
25+
public private(set) var isPublishing: Bool = false
2426

2527
public enum ComposeContext {
2628
case composeStatus(quoting: (Mastodon.Entity.Status, ()->(AnyView))?)
@@ -338,6 +340,14 @@ public final class ComposeContentViewModel: NSObject, ObservableObject {
338340

339341

340342
extension ComposeContentViewModel {
343+
public func beginPublish() {
344+
isPublishing = true
345+
}
346+
347+
public func donePublishing() {
348+
isPublishing = false
349+
}
350+
341351
private func bind() {
342352
// bind instance configuration updates
343353
AuthenticationServiceProvider.shared.instanceConfigurationUpdates

0 commit comments

Comments
 (0)