From 4c7ef5b2d6f5b12b67ad2bf4cd8552a79d798553 Mon Sep 17 00:00:00 2001 From: James Frost Date: Mon, 13 Mar 2017 11:54:35 +0000 Subject: [PATCH 1/7] MediaItemVC: Prevent image cell from reloading. --- .../Media/MediaItemViewController.swift | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index 950984b8ff8a..a38ed04ab3ae 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -315,7 +315,6 @@ struct MediaImageRow: ImmuTableRow { if let cell = cell as? ImageTableViewCell { setAspectRatioFor(cell) - addPlaceholderImageFor(cell) loadImageFor(cell) } } @@ -345,17 +344,22 @@ struct MediaImageRow: ImmuTableRow { } private func loadImageFor(_ cell: ImageTableViewCell) { - cell.isLoading = true - media.image(with: .zero, - completionHandler: { image, error in - DispatchQueue.main.async { - if let error = error, image == nil { - self.show(error) - } else if let image = image { - self.animateImageChange(image: image, for: cell) + if !cell.isLoading && cell.customImageView.image == nil { + addPlaceholderImageFor(cell) + + cell.isLoading = true + media.image(with: .zero, + completionHandler: { image, error in + DispatchQueue.main.async { + if let error = error, image == nil { + cell.isLoading = false + self.show(error) + } else if let image = image { + self.animateImageChange(image: image, for: cell) + } } - } - }) + }) + } } private func show(_ error: Error) { From e91719d6a2b76a3aa4cd6fc83a00c94c765eb131 Mon Sep 17 00:00:00 2001 From: James Frost Date: Mon, 13 Mar 2017 11:54:59 +0000 Subject: [PATCH 2/7] MediaItemVC: Add ability to edit image title, caption, and description. --- .../Media/MediaItemViewController.swift | 161 +++++++++++++++--- 1 file changed, 141 insertions(+), 20 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index a38ed04ab3ae..72bb513d0678 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -5,16 +5,24 @@ import WordPressShared /// Displays an image preview and metadata for a single Media asset. /// -class MediaItemViewController: UITableViewController, ImmuTablePresenter { +class MediaItemViewController: UITableViewController { let media: Media + weak var dataSource: MediaLibraryPickerDataSource? = nil - var viewModel: ImmuTable! + fileprivate var viewModel: ImmuTable! + fileprivate var mediaMetadata: MediaMetadata { + didSet { + updateNavigationItem() + } + } init(media: Media, dataSource: MediaLibraryPickerDataSource) { self.media = media self.dataSource = dataSource + self.mediaMetadata = MediaMetadata(media: media) + super.init(style: .grouped) } @@ -29,18 +37,22 @@ class MediaItemViewController: UITableViewController, ImmuTablePresenter { override func viewDidLoad() { super.viewDidLoad() - title = media.title - WPStyleGuide.configureColors(for: view, andTableView: tableView) ImmuTable.registerRows([TextRow.self, EditableTextRow.self, MediaImageRow.self], tableView: tableView) - setupViewModel() - setupNavigationItem() registerChangeObserver() + + updateViewModel() + updateNavigationItem() + updateTitle() + } + + private func updateTitle() { + title = mediaMetadata.title } - private func setupViewModel() { + private func updateViewModel() { let presenter = MediaMetadataPresenter(media: media) viewModel = ImmuTable(sections: [ @@ -49,9 +61,9 @@ class MediaItemViewController: UITableViewController, ImmuTablePresenter { self?.presentImageViewControllerForMedia() }) ]), ImmuTableSection(headerText: nil, rows: [ - EditableTextRow(title: NSLocalizedString("Title", comment: "Noun. Label for the title of a media asset (image / video)"), value: media.title, action: nil), - EditableTextRow(title: NSLocalizedString("Caption", comment: "Noun. Label for the caption for a media asset (image / video)"), value: media.caption, action: nil), - EditableTextRow(title: NSLocalizedString("Description", comment: "Label for the description for a media asset (image / video)"), value: media.desc, action: nil) + EditableTextRow(title: NSLocalizedString("Title", comment: "Noun. Label for the title of a media asset (image / video)"), value: mediaMetadata.title, action: editTitle()), + EditableTextRow(title: NSLocalizedString("Caption", comment: "Noun. Label for the caption for a media asset (image / video)"), value: mediaMetadata.caption, action: editCaption()), + EditableTextRow(title: NSLocalizedString("Description", comment: "Label for the description for a media asset (image / video)"), value: mediaMetadata.desc, action: editDescription()) ], footerText: nil), ImmuTableSection(headerText: NSLocalizedString("Metadata", comment: "Title of section containing image / video metadata such as size and file type"), rows: [ TextRow(title: NSLocalizedString("File name", comment: "Label for the file name for a media asset (image / video)"), value: media.filename), @@ -62,18 +74,29 @@ class MediaItemViewController: UITableViewController, ImmuTablePresenter { ]) } - private func setupNavigationItem() { - let shareItem = UIBarButtonItem(image: Gridicon.iconOfType(.shareIOS), - style: .plain, - target: self, - action: #selector(shareTapped(_:))) + private func reloadViewModel() { + updateViewModel() + tableView.reloadData() + } + + private func updateNavigationItem() { + if mediaMetadata.matches(media) { + navigationItem.leftBarButtonItem = nil + let shareItem = UIBarButtonItem(image: Gridicon.iconOfType(.shareIOS), + style: .plain, + target: self, + action: #selector(shareTapped(_:))) - let trashItem = UIBarButtonItem(image: Gridicon.iconOfType(.trash), - style: .plain, - target: self, - action: #selector(trashTapped(_:))) + let trashItem = UIBarButtonItem(image: Gridicon.iconOfType(.trash), + style: .plain, + target: self, + action: #selector(trashTapped(_:))) - navigationItem.rightBarButtonItems = [ shareItem, trashItem ] + navigationItem.rightBarButtonItems = [ shareItem, trashItem ] + } else { + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped)) + navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped)) + } } private func presentImageViewControllerForMedia() { @@ -148,6 +171,74 @@ class MediaItemViewController: UITableViewController, ImmuTablePresenter { SVProgressHUD.showError(withStatus: NSLocalizedString("Unable to delete media item.", comment: "Text displayed in HUD if there was an error attempting to delete a media item.")) }) } + + @objc private func cancelTapped() { + mediaMetadata = MediaMetadata(media: media) + reloadViewModel() + updateTitle() + } + + @objc private func saveTapped() { + SVProgressHUD.setDefaultMaskType(.clear) + SVProgressHUD.setMinimumDismissTimeInterval(1.0) + SVProgressHUD.show(withStatus: NSLocalizedString("Saving...", comment: "Text displayed in HUD while a media item's metadata (title, etc) is being saved.")) + + mediaMetadata.update(media) + + let service = MediaService(managedObjectContext: ContextManager.sharedInstance().mainContext) + service.update(media, success: { + SVProgressHUD.showSuccess(withStatus: NSLocalizedString("Saved!", comment: "Text displayed in HUD when a media item's metadata (title, etc) is saved successfully.")) + self.updateNavigationItem() + }, failure: { error in + SVProgressHUD.showError(withStatus: NSLocalizedString("Unable to save media item.", comment: "Text displayed in HUD when a media item's metadata (title, etc) couldn't be saved.")) + self.updateNavigationItem() + }) + } + + private func editTitle() -> ((ImmuTableRow) -> ()) { + return { row in + let editableRow = row as! EditableTextRow + self.pushSettingsController(for: editableRow, hint: NSLocalizedString("Image title", comment: "Hint for image title on image settings."), + onValueChanged: { value in + self.title = value + self.mediaMetadata.title = value + self.reloadViewModel() + }) + } + } + + private func editCaption() -> ((ImmuTableRow) -> ()) { + return { row in + let editableRow = row as! EditableTextRow + self.pushSettingsController(for: editableRow, hint: NSLocalizedString("Image Caption", comment: "Hint for image caption on image settings."), + onValueChanged: { value in + self.mediaMetadata.caption = value + self.reloadViewModel() + }) + } + } + + private func editDescription() -> ((ImmuTableRow) -> ()) { + return { row in + let editableRow = row as! EditableTextRow + self.pushSettingsController(for: editableRow, hint: NSLocalizedString("Image Description", comment: "Hint for image description on image settings."), + onValueChanged: { value in + self.mediaMetadata.desc = value + self.reloadViewModel() + }) + } + } + + private func pushSettingsController(for row: EditableTextRow, hint: String? = nil, onValueChanged: @escaping SettingsTextChanged) { + let title = row.title + let value = row.value + let controller = SettingsTextViewController(text: value, placeholder: "\(title)...", hint: hint) + + controller.title = title + controller.onValueChanged = onValueChanged + + navigationController?.pushViewController(controller, animated: true) + } } // MARK: - UITableViewDataSource @@ -396,3 +487,33 @@ private struct MediaMetadataPresenter { return (media.filename as NSString).pathExtension.uppercased() } } + +/// Used to store media metadata and provide the ability to undo changes to +/// the MediaItemViewController's media property. +private struct MediaMetadata { + var title: String + var caption: String + var desc: String + + init(media: Media) { + title = media.title ?? "" + caption = media.caption ?? "" + desc = media.desc ?? "" + } + + /// - returns: True if this metadata's fields match those + /// of the specified Media object. + func matches(_ media: Media) -> Bool { + return title == media.title + && caption == media.caption + && desc == media.desc + } + + /// Update the metadata fields of the specified Media object + /// to match this metadata's fields. + func update(_ media: Media) { + media.title = title + media.caption = caption + media.desc = desc + } +} From 8f913f2ec9880da212c43f2f3e9b76d70948ecf9 Mon Sep 17 00:00:00 2001 From: James Frost Date: Tue, 14 Mar 2017 19:47:03 +0000 Subject: [PATCH 3/7] Media: Replace all rightBarButtonItems when editing. --- .../Classes/ViewRelated/Media/MediaItemViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index 72bb513d0678..874d993ce16b 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -95,7 +95,7 @@ class MediaItemViewController: UITableViewController { navigationItem.rightBarButtonItems = [ shareItem, trashItem ] } else { navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped)) - navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped)) + navigationItem.rightBarButtonItems = [ UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped)) ] } } From 06032ee6047486ea62ebf5c26800b153543618ce Mon Sep 17 00:00:00 2001 From: James Frost Date: Wed, 15 Mar 2017 11:15:52 +0000 Subject: [PATCH 4/7] Media library: Update logic for popping detail views for deleted assets * Now all handled by the main media library VC * Can pop off multiple VCs (for example if we're editing the metadata of an image) --- .../Media/MediaItemViewController.swift | 30 ------------------- .../Media/MediaLibraryViewController.swift | 23 +++++++++++++- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index 874d993ce16b..eddede9b6d2b 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -30,10 +30,6 @@ class MediaItemViewController: UITableViewController { fatalError("init(coder:) has not been implemented") } - deinit { - unregisterChangeObserver() - } - override func viewDidLoad() { super.viewDidLoad() @@ -41,8 +37,6 @@ class MediaItemViewController: UITableViewController { ImmuTable.registerRows([TextRow.self, EditableTextRow.self, MediaImageRow.self], tableView: tableView) - registerChangeObserver() - updateViewModel() updateNavigationItem() updateTitle() @@ -108,30 +102,6 @@ class MediaItemViewController: UITableViewController { } } - // MARK: - Media Library Change Observer - - private var mediaLibraryChangeObserverKey: NSObjectProtocol? = nil - - private func registerChangeObserver() { - assert(mediaLibraryChangeObserverKey == nil) - - // Listen out for changes to the media library – if the media item we're - // displaying gets deleted, we'll pop ourselves off the stack. - if let dataSource = dataSource { - mediaLibraryChangeObserverKey = dataSource.registerChangeObserverBlock({ [weak self] _, _, _, _, _ in - if let isDeleted = self?.media.isDeleted, isDeleted == true { - _ = self?.navigationController?.popViewController(animated: true) - } - }) - } - } - - private func unregisterChangeObserver() { - if let mediaLibraryChangeObserverKey = mediaLibraryChangeObserverKey { - dataSource?.unregisterChangeObserver(mediaLibraryChangeObserverKey) - } - } - // MARK: - Actions @objc private func shareTapped(_ sender: UIBarButtonItem) { diff --git a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift index a77fd564ed9e..895f51303b75 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift @@ -12,6 +12,8 @@ class MediaLibraryViewController: UIViewController { fileprivate let pickerViewController: WPMediaPickerViewController fileprivate let pickerDataSource: MediaLibraryPickerDataSource + fileprivate var selectedAsset: Media? = nil + // MARK: - Initializers init(blog: Blog) { @@ -55,6 +57,12 @@ class MediaLibraryViewController: UIViewController { registerChangeObserver() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + selectedAsset = nil + } + private func updateNavigationItemButtonsForEditingState() { if isEditing { navigationItem.setLeftBarButton(UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(editTapped)), animated: true) @@ -140,7 +148,18 @@ class MediaLibraryViewController: UIViewController { private func registerChangeObserver() { assert(mediaLibraryChangeObserverKey == nil) mediaLibraryChangeObserverKey = pickerDataSource.registerChangeObserverBlock({ [weak self] _, _, _, _, _ in - self?.updateNavigationItemButtonsForCurrentAssetSelection() + guard let strongSelf = self else { return } + + strongSelf.updateNavigationItemButtonsForCurrentAssetSelection() + + // If we're presenting an item and it's been deleted, pop the + // detail view off the stack + if let navigationController = strongSelf.navigationController, + navigationController.topViewController != strongSelf, + let asset = strongSelf.selectedAsset, + asset.isDeleted { + _ = strongSelf.navigationController?.popToViewController(strongSelf, animated: true) + } }) } @@ -199,6 +218,8 @@ extension MediaLibraryViewController: WPMediaPickerViewControllerDelegate { return nil } + selectedAsset = asset + return MediaItemViewController(media: asset, dataSource: pickerDataSource) } } From 3b368e325501aba09c73b6aaebc9978d817e1dc5 Mon Sep 17 00:00:00 2001 From: James Frost Date: Wed, 15 Mar 2017 11:24:36 +0000 Subject: [PATCH 5/7] Media library: Update logic for popping detail views for deleted assets * Now all handled by the main media library VC * Can pop off multiple VCs (for example if we're editing the metadata of an image) --- .../Media/MediaItemViewController.swift | 30 ------------------- .../Media/MediaLibraryViewController.swift | 23 +++++++++++++- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index 874d993ce16b..eddede9b6d2b 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -30,10 +30,6 @@ class MediaItemViewController: UITableViewController { fatalError("init(coder:) has not been implemented") } - deinit { - unregisterChangeObserver() - } - override func viewDidLoad() { super.viewDidLoad() @@ -41,8 +37,6 @@ class MediaItemViewController: UITableViewController { ImmuTable.registerRows([TextRow.self, EditableTextRow.self, MediaImageRow.self], tableView: tableView) - registerChangeObserver() - updateViewModel() updateNavigationItem() updateTitle() @@ -108,30 +102,6 @@ class MediaItemViewController: UITableViewController { } } - // MARK: - Media Library Change Observer - - private var mediaLibraryChangeObserverKey: NSObjectProtocol? = nil - - private func registerChangeObserver() { - assert(mediaLibraryChangeObserverKey == nil) - - // Listen out for changes to the media library – if the media item we're - // displaying gets deleted, we'll pop ourselves off the stack. - if let dataSource = dataSource { - mediaLibraryChangeObserverKey = dataSource.registerChangeObserverBlock({ [weak self] _, _, _, _, _ in - if let isDeleted = self?.media.isDeleted, isDeleted == true { - _ = self?.navigationController?.popViewController(animated: true) - } - }) - } - } - - private func unregisterChangeObserver() { - if let mediaLibraryChangeObserverKey = mediaLibraryChangeObserverKey { - dataSource?.unregisterChangeObserver(mediaLibraryChangeObserverKey) - } - } - // MARK: - Actions @objc private func shareTapped(_ sender: UIBarButtonItem) { diff --git a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift index a77fd564ed9e..895f51303b75 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift @@ -12,6 +12,8 @@ class MediaLibraryViewController: UIViewController { fileprivate let pickerViewController: WPMediaPickerViewController fileprivate let pickerDataSource: MediaLibraryPickerDataSource + fileprivate var selectedAsset: Media? = nil + // MARK: - Initializers init(blog: Blog) { @@ -55,6 +57,12 @@ class MediaLibraryViewController: UIViewController { registerChangeObserver() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + selectedAsset = nil + } + private func updateNavigationItemButtonsForEditingState() { if isEditing { navigationItem.setLeftBarButton(UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(editTapped)), animated: true) @@ -140,7 +148,18 @@ class MediaLibraryViewController: UIViewController { private func registerChangeObserver() { assert(mediaLibraryChangeObserverKey == nil) mediaLibraryChangeObserverKey = pickerDataSource.registerChangeObserverBlock({ [weak self] _, _, _, _, _ in - self?.updateNavigationItemButtonsForCurrentAssetSelection() + guard let strongSelf = self else { return } + + strongSelf.updateNavigationItemButtonsForCurrentAssetSelection() + + // If we're presenting an item and it's been deleted, pop the + // detail view off the stack + if let navigationController = strongSelf.navigationController, + navigationController.topViewController != strongSelf, + let asset = strongSelf.selectedAsset, + asset.isDeleted { + _ = strongSelf.navigationController?.popToViewController(strongSelf, animated: true) + } }) } @@ -199,6 +218,8 @@ extension MediaLibraryViewController: WPMediaPickerViewControllerDelegate { return nil } + selectedAsset = asset + return MediaItemViewController(media: asset, dataSource: pickerDataSource) } } From cae5202ee314ef965f9b1edf7f609fd2d57b45ef Mon Sep 17 00:00:00 2001 From: James Frost Date: Wed, 15 Mar 2017 13:00:24 +0000 Subject: [PATCH 6/7] Media Library: Editing only available to dotcom sites. --- WordPress/Classes/Models/Blog.h | 4 +++- WordPress/Classes/Models/Blog.m | 2 ++ .../Media/MediaItemViewController.swift | 14 +++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/WordPress/Classes/Models/Blog.h b/WordPress/Classes/Models/Blog.h index 1db43aa207b6..f60281431495 100644 --- a/WordPress/Classes/Models/Blog.h +++ b/WordPress/Classes/Models/Blog.h @@ -49,7 +49,9 @@ typedef NS_ENUM(NSUInteger, BlogFeature) { /// Does the blog support custom domains? BlogFeatureDomains, /// Does the blog support frame-nonce to authenticate previews? - BlogFeatureNoncePreviews + BlogFeatureNoncePreviews, + /// Does the blog support editing media metadata? + BlogFeatureMediaMetadataEditing }; typedef NS_ENUM(NSInteger, SiteVisibility) { diff --git a/WordPress/Classes/Models/Blog.m b/WordPress/Classes/Models/Blog.m index 19dbe89d26f9..8e7786bec5ab 100644 --- a/WordPress/Classes/Models/Blog.m +++ b/WordPress/Classes/Models/Blog.m @@ -458,6 +458,8 @@ - (BOOL)supports:(BlogFeature)feature return [self isHostedAtWPcom] && [self supportsSiteManagementServices]; case BlogFeatureNoncePreviews: return [self supportsRestApi] && ![self isHostedAtWPcom]; + case BlogFeatureMediaMetadataEditing: + return [self isHostedAtWPcom]; } } diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index eddede9b6d2b..f2e0aa4002db 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -55,9 +55,9 @@ class MediaItemViewController: UITableViewController { self?.presentImageViewControllerForMedia() }) ]), ImmuTableSection(headerText: nil, rows: [ - EditableTextRow(title: NSLocalizedString("Title", comment: "Noun. Label for the title of a media asset (image / video)"), value: mediaMetadata.title, action: editTitle()), - EditableTextRow(title: NSLocalizedString("Caption", comment: "Noun. Label for the caption for a media asset (image / video)"), value: mediaMetadata.caption, action: editCaption()), - EditableTextRow(title: NSLocalizedString("Description", comment: "Label for the description for a media asset (image / video)"), value: mediaMetadata.desc, action: editDescription()) + editableRowIfSupported(title: NSLocalizedString("Title", comment: "Noun. Label for the title of a media asset (image / video)"), value: mediaMetadata.title, action: editTitle()), + editableRowIfSupported(title: NSLocalizedString("Caption", comment: "Noun. Label for the caption for a media asset (image / video)"), value: mediaMetadata.caption, action: editCaption()), + editableRowIfSupported(title: NSLocalizedString("Description", comment: "Label for the description for a media asset (image / video)"), value: mediaMetadata.desc, action: editDescription()) ], footerText: nil), ImmuTableSection(headerText: NSLocalizedString("Metadata", comment: "Title of section containing image / video metadata such as size and file type"), rows: [ TextRow(title: NSLocalizedString("File name", comment: "Label for the file name for a media asset (image / video)"), value: media.filename), @@ -68,6 +68,14 @@ class MediaItemViewController: UITableViewController { ]) } + private func editableRowIfSupported(title: String, value: String, action: @escaping ((ImmuTableRow) -> ())) -> ImmuTableRow { + if media.blog.supports(BlogFeature.mediaMetadataEditing) { + return EditableTextRow(title: title, value: value, action: action) + } else { + return TextRow(title: title, value: value) + } + } + private func reloadViewModel() { updateViewModel() tableView.reloadData() From 1d15e6d2317d2c7412c9cdc32c7702b16e3ce39e Mon Sep 17 00:00:00 2001 From: James Frost Date: Wed, 15 Mar 2017 17:31:02 +0000 Subject: [PATCH 7/7] Media: Update rules for blog supporting media editing, added support for deletion. --- WordPress/Classes/Models/Blog.h | 4 +++- WordPress/Classes/Models/Blog.m | 4 +++- .../Classes/ViewRelated/Media/MediaItemViewController.swift | 6 +++++- .../ViewRelated/Media/MediaLibraryViewController.swift | 6 +++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/WordPress/Classes/Models/Blog.h b/WordPress/Classes/Models/Blog.h index f60281431495..3251f29a1f26 100644 --- a/WordPress/Classes/Models/Blog.h +++ b/WordPress/Classes/Models/Blog.h @@ -51,7 +51,9 @@ typedef NS_ENUM(NSUInteger, BlogFeature) { /// Does the blog support frame-nonce to authenticate previews? BlogFeatureNoncePreviews, /// Does the blog support editing media metadata? - BlogFeatureMediaMetadataEditing + BlogFeatureMediaMetadataEditing, + /// Does the blog support deleting media? + BlogFeatureMediaDeletion }; typedef NS_ENUM(NSInteger, SiteVisibility) { diff --git a/WordPress/Classes/Models/Blog.m b/WordPress/Classes/Models/Blog.m index 8e7786bec5ab..527baeecaeaf 100644 --- a/WordPress/Classes/Models/Blog.m +++ b/WordPress/Classes/Models/Blog.m @@ -459,7 +459,9 @@ - (BOOL)supports:(BlogFeature)feature case BlogFeatureNoncePreviews: return [self supportsRestApi] && ![self isHostedAtWPcom]; case BlogFeatureMediaMetadataEditing: - return [self isHostedAtWPcom]; + return [self supportsRestApi] && [self isAdmin]; + case BlogFeatureMediaDeletion: + return [self isAdmin]; } } diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index f2e0aa4002db..00d8619fbd74 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -94,7 +94,11 @@ class MediaItemViewController: UITableViewController { target: self, action: #selector(trashTapped(_:))) - navigationItem.rightBarButtonItems = [ shareItem, trashItem ] + if media.blog.supports(.mediaDeletion) { + navigationItem.rightBarButtonItems = [ shareItem, trashItem ] + } else { + navigationItem.rightBarButtonItems = [ shareItem ] + } } else { navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped)) navigationItem.rightBarButtonItems = [ UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped)) ] diff --git a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift index 895f51303b75..99a4e73b09c3 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaLibraryViewController.swift @@ -70,7 +70,11 @@ class MediaLibraryViewController: UIViewController { navigationItem.rightBarButtonItem?.isEnabled = false } else { navigationItem.setLeftBarButton(nil, animated: true) - navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped)), animated: true) + if blog.supports(.mediaDeletion) { + navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped)), animated: true) + } else { + navigationItem.setRightBarButton(nil, animated: true) + } } }