Skip to content

Commit

Permalink
Add a way to cancel uploads from the Media Uploads view
Browse files Browse the repository at this point in the history
  • Loading branch information
kean committed Apr 26, 2024
1 parent fb43b93 commit c684f29
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 20 deletions.
3 changes: 0 additions & 3 deletions WordPress/Classes/Models/Blog+Quota.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ extension Blog {

/// Returns the maximum upload byte size supported for a media file on the site.
@objc var maxUploadSize: NSNumber? {
#warning("TEMP")
return NSNumber(value: 1024 * 1024)

guard let maxUploadSize = getOptionValue("max_upload_size") as? NSNumber else {
return nil
}
Expand Down
7 changes: 7 additions & 0 deletions WordPress/Classes/Services/MediaCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ class MediaCoordinator: NSObject {
func cancelUploadAndDeleteMedia(_ media: Media) {
cancelUpload(of: media)
delete(media: [media])
if RemoteFeatureFlag.syncPublishing.enabled() {
notifyObserversForMedia(media, ofStateChange: .cancelled)
}
}

/// Cancels any ongoing upload for the media object
Expand Down Expand Up @@ -588,6 +591,8 @@ class MediaCoordinator: NSObject {
case ended
case failed(error: NSError)
case progress(value: Double)
/// The upload was cancelled by the user.
case cancelled

var debugDescription: String {
switch self {
Expand All @@ -603,6 +608,8 @@ class MediaCoordinator: NSObject {
return "Failed: \(error)"
case .progress(let value):
return "Progress: \(value)"
case .cancelled:
return "Cancelled"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,8 @@ extension AztecPostViewController {
handleError(error, onAttachment: attachment)
case .progress(let value):
handleProgress(value, forMedia: media, onAttachment: attachment)
case .cancelled:
richTextView.remove(attachmentID: attachment.identifier)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ class GutenbergMediaInserterHelper: NSObject {
}
case .progress(let value):
gutenberg.mediaUploadUpdate(id: mediaUploadID, state: .uploading, progress: Float(value), url: nil, serverID: nil)
case .cancelled:
gutenberg.mediaUploadUpdate(id: mediaUploadID, state: .reset, progress: 0, url: nil, serverID: nil)
}
}

Expand Down
55 changes: 39 additions & 16 deletions WordPress/Classes/ViewRelated/Post/PostMediaUploadsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ private struct PostMediaUploadItemView: View {
@ObservedObject var viewModel: PostMediaUploadItemViewModel

var body: some View {
HStack(alignment: .center, spacing: 16) {
HStack(alignment: .center, spacing: 0) {
MediaThubmnailImageView(image: viewModel.thumbnail)
.aspectRatio(viewModel.thumbnailAspectRatio, contentMode: .fit)
.frame(maxHeight: viewModel.thumbnailMaxHeight)
.clipped()
.frame(width: 40, height: 40)
.padding(.trailing, 16)

VStack(alignment: .leading) {
Text(viewModel.title)
Expand All @@ -59,17 +60,22 @@ private struct PostMediaUploadItemView: View {
.lineLimit(3)
}

Spacer()
Spacer(minLength: 8)

switch viewModel.state {
case .uploading:
MediaUploadProgressView(progress: viewModel.fractionCompleted)
case .failed:
Image(systemName: "exclamationmark.circle.fill")
.foregroundStyle(.red)
case .uploaded:
Image(systemName: "checkmark.circle.fill")
.foregroundStyle(.secondary.opacity(0.33))
HStack(alignment: .center, spacing: 8) {
switch viewModel.state {
case .uploading:
MediaUploadProgressView(progress: viewModel.fractionCompleted)
.padding(.trailing, 4) // To align with the exlamation mark
makeMenu(for: viewModel)
case .failed:
Image(systemName: "exclamationmark.circle.fill")
.foregroundStyle(.red)
makeMenu(for: viewModel)
case .uploaded:
Image(systemName: "checkmark.circle.fill")
.foregroundStyle(.secondary.opacity(0.33))
}
}
}
.task {
Expand All @@ -78,19 +84,34 @@ private struct PostMediaUploadItemView: View {
}
}

@ViewBuilder
private func makeMenu(for viewModel: PostMediaUploadItemViewModel) -> some View {
Menu {
if viewModel.error != nil {
Button(action: viewModel.buttonRetryTapped) {
Label(Strings.retryUpload, systemImage: "arrow.clockwise")
}
}
Button(role: .destructive, action: viewModel.buttonCancelTapped) {
Label(Strings.cancelUpload, systemImage: "trash")
}
} label: {
Image(systemName: "ellipsis")
.font(.subheadline)
.tint(.secondary)
}
}

struct MediaUploadProgressView: View {
let progress: Double

var body: some View {
ZStack {
Circle()
.stroke(
Color.secondary.opacity(0.25),
lineWidth: 3
)
.stroke(Color.secondary.opacity(0.25), lineWidth: 2)
Circle()
.trim(from: 0, to: progress)
.stroke(Color(uiColor: .brand), style: StrokeStyle(lineWidth: 3, lineCap: .round))
.stroke(Color(uiColor: .brand), style: StrokeStyle(lineWidth: 2, lineCap: .round))
.rotationEffect(.degrees(-90))
.animation(.easeOut, value: progress)
}
Expand Down Expand Up @@ -119,5 +140,7 @@ private enum Strings {
static let title = NSLocalizedString("postMediaUploadStatusView.title", value: "Media Uploads", comment: "Title for post media upload status view")
static let empty = NSLocalizedString("postMediaUploadStatusView.noPendingUploads", value: "No pending uploads", comment: "Placeholder text in postMediaUploadStatusView when no uploads remain")
static let close = NSLocalizedString("postMediaUploadStatusView.close", value: "Close", comment: "Close button in postMediaUploadStatusView")
static let retryUpload = NSLocalizedString("postMediaUploadStatusView.retryUpload", value: "Retry Upload", comment: "Retry (single) upload button in postMediaUploadStatusView")
static let cancelUpload = NSLocalizedString("postMediaUploadStatusView.cancelUpload", value: "Cancel Upload", comment: "Cancel (single) upload button in postMediaUploadStatusView")
static let retryUploads = NSLocalizedString("postMediaUploadStatusView.retryUploads", value: "Retry Uploads", comment: "Retry upload button in postMediaUploadStatusView")
}
10 changes: 10 additions & 0 deletions WordPress/Classes/ViewRelated/Post/PostMediaUploadsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ final class PostMediaUploadItemViewModel: ObservableObject, Identifiable {
// Continue showing placeholder
}
}

// MARK: - Actions

func buttonRetryTapped() {
retry()
}

func buttonCancelTapped() {
coordinator.cancelUploadAndDeleteMedia(media)
}
}

private extension Media {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ extension PostSettingsViewController {
// The Media coordinator shows its own notice about a failed upload. We have a better, more explanatory message for users here
// so we want to supress the one coming from the coordinator and show ours.
ActionDispatcher.dispatch(NoticeAction.post(notice))
case .progress:
case .progress, .cancelled:
break
}
}
Expand Down

0 comments on commit c684f29

Please sign in to comment.