Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions WordPress/Classes/Services/SiteManagementService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ open class SiteManagementService: NSObject {
guard let remote = siteManagementServiceRemoteForBlog(blog) else {
return
}
remote.deleteSite(blog.dotComID!,
remote.deleteSite(
blog.dotComID!,
success: {
let blogService = BlogService(coreDataStack: self.coreDataStack)
blogService.remove(blog)
Expand All @@ -41,7 +42,8 @@ open class SiteManagementService: NSObject {
},
failure: { error in
failure?(error)
})
}
)
}

/// Triggers content export of the specified WordPress.com site.
Expand All @@ -57,13 +59,15 @@ open class SiteManagementService: NSObject {
guard let remote = siteManagementServiceRemoteForBlog(blog) else {
return
}
remote.exportContent(blog.dotComID!,
remote.exportContent(
blog.dotComID!,
success: {
success?()
},
failure: { error in
failure?(error)
})
}
)
}

/// Gets the list of active purchases of the specified WordPress.com site.
Expand All @@ -73,17 +77,23 @@ open class SiteManagementService: NSObject {
/// - success: Optional success block with array of purchases (if any)
/// - failure: Optional failure block with NSError
///
@objc open func getActivePurchasesForBlog(_ blog: Blog, success: (([SitePurchase]) -> Void)?, failure: ((NSError) -> Void)?) {
@objc open func getActivePurchasesForBlog(
_ blog: Blog,
success: (([SitePurchase]) -> Void)?,
failure: ((NSError) -> Void)?
) {
guard let remote = siteManagementServiceRemoteForBlog(blog) else {
return
}
remote.getActivePurchases(blog.dotComID!,
remote.getActivePurchases(
blog.dotComID!,
success: { purchases in
success?(purchases)
},
failure: { error in
failure?(error)
})
}
)
}

/// Creates a remote service for site management
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ open class JetpackConnectionViewController: UITableViewController {
fileprivate var blog: Blog!
fileprivate var service: BlogJetpackSettingsService!
fileprivate lazy var handler: ImmuTableViewHandler = {
return ImmuTableViewHandler(takeOver: self)
ImmuTableViewHandler(takeOver: self)
}()

// MARK: - Public Properties
Expand Down Expand Up @@ -66,37 +66,53 @@ open class JetpackConnectionViewController: UITableViewController {
}

func tableViewModel() -> ImmuTable {
let disconnectRow = DestructiveButtonRow(title: NSLocalizedString("Disconnect from WordPress.com",
comment: "Disconnect from WordPress.com button"),
action: self.disconnectJetpackTapped(),
accessibilityIdentifier: "disconnectFromWordPress.comButton")
let disconnectRow = DestructiveButtonRow(
title: NSLocalizedString(
"Disconnect from WordPress.com",
comment: "Disconnect from WordPress.com button"
),
action: self.disconnectJetpackTapped(),
accessibilityIdentifier: "disconnectFromWordPress.comButton"
)
return ImmuTable(sections: [
ImmuTableSection(
headerText: "",
rows: [disconnectRow],
footerText: NSLocalizedString("Your site will no longer send data to WordPress.com and Jetpack features will stop working. You will lose access to the site on the app and you will have to re-add it with the site credentials.",
comment: "Explanatory text bellow the Disconnect from WordPress.com button")
footerText: NSLocalizedString(
"Your site will no longer send data to WordPress.com and Jetpack features will stop working. You will lose access to the site on the app and you will have to re-add it with the site credentials.",
comment: "Explanatory text bellow the Disconnect from WordPress.com button"
)
)
])
}

// MARK: - Row Handler

func disconnectJetpackTapped() -> ImmuTableAction {
return { [unowned self] _ in
{ [unowned self] _ in
self.tableView.deselectSelectedRowWithAnimation(true)
let message = NSLocalizedString("Are you sure you want to disconnect Jetpack from the site?",
comment: "Message prompting the user to confirm that they want to disconnect Jetpack from the site.")

let alertController = UIAlertController(title: nil,
message: message,
preferredStyle: .alert)
alertController.addCancelActionWithTitle(NSLocalizedString("Cancel", comment: "Verb. A button title. Tapping cancels an action."))
alertController.addDestructiveActionWithTitle(NSLocalizedString("Disconnect",
comment: "Title for button that disconnects Jetpack from the site"),
handler: { _ in
self.disconnectJetpack()
})
let message = NSLocalizedString(
"Are you sure you want to disconnect Jetpack from the site?",
comment: "Message prompting the user to confirm that they want to disconnect Jetpack from the site."
)

let alertController = UIAlertController(
title: nil,
message: message,
preferredStyle: .alert
)
alertController.addCancelActionWithTitle(
NSLocalizedString("Cancel", comment: "Verb. A button title. Tapping cancels an action.")
)
alertController.addDestructiveActionWithTitle(
NSLocalizedString(
"Disconnect",
comment: "Title for button that disconnects Jetpack from the site"
),
handler: { _ in
self.disconnectJetpack()
}
)
WPAnalytics.trackEvent(.jetpackDisconnectTapped)
self.present(alertController, animated: true)
}
Expand All @@ -105,26 +121,32 @@ open class JetpackConnectionViewController: UITableViewController {
@objc func disconnectJetpack() {
WPAnalytics.trackEvent(.jetpackDisconnectRequested)
startLoading()
self.service.disconnectJetpackFromBlog(self.blog,
success: { [weak self] in
self?.stopLoading()
if let blog = self?.blog {
let service = BlogService(coreDataStack: ContextManager.shared)
service.remove(blog)
self?.delegate?.jetpackDisconnectedForBlog(blog)
} else {
self?.dismiss()
}
},
failure: { [weak self] error in
self?.stopLoading()
let errorTitle = NSLocalizedString("Error disconnecting Jetpack",
comment: "Title of error dialog when disconnecting jetpack fails.")
let errorMessage = NSLocalizedString("Please contact support for assistance.",
comment: "Message displayed on an error alert to prompt the user to contact support")
WPError.showAlert(withTitle: errorTitle, message: errorMessage, withSupportButton: true)
DDLogError("Error disconnecting Jetpack: \(String(describing: error))")
})
self.service.disconnectJetpackFromBlog(
self.blog,
success: { [weak self] in
self?.stopLoading()
if let blog = self?.blog {
let service = BlogService(coreDataStack: ContextManager.shared)
service.remove(blog)
self?.delegate?.jetpackDisconnectedForBlog(blog)
} else {
self?.dismiss()
}
},
failure: { [weak self] error in
self?.stopLoading()
let errorTitle = NSLocalizedString(
"Error disconnecting Jetpack",
comment: "Title of error dialog when disconnecting jetpack fails."
)
let errorMessage = NSLocalizedString(
"Please contact support for assistance.",
comment: "Message displayed on an error alert to prompt the user to contact support"
)
WPError.showAlert(withTitle: errorTitle, message: errorMessage, withSupportButton: true)
DDLogError("Error disconnecting Jetpack: \(String(describing: error))")
}
)
}

@objc func dismiss() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@ import WordPressShared

protocol ExternalMediaPickerViewDelegate: AnyObject {
/// If the user cancels the flow, the selection is empty.
func externalMediaPickerViewController(_ viewController: ExternalMediaPickerViewController, didFinishWithSelection selection: [ExternalMediaAsset])
func externalMediaPickerViewController(
_ viewController: ExternalMediaPickerViewController,
didFinishWithSelection selection: [ExternalMediaAsset]
)
}

final class ExternalMediaPickerViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UISearchResultsUpdating, MediaPreviewControllerDataSource {
final class ExternalMediaPickerViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate,
UISearchResultsUpdating, MediaPreviewControllerDataSource
{ // swiftlint:disable:this opening_brace
private lazy var collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
private lazy var flowLayout = UICollectionViewFlowLayout()
private var collectionViewDataSource: UICollectionViewDiffableDataSource<Int, String>!
private let searchController = UISearchController()
private let activityIndicator = UIActivityIndicatorView()
private let toolbarItemTitle = ExternalMediaSelectionTitleView()
private lazy var buttonDone = UIBarButtonItem(title: Strings.add, style: .done, target: self, action: #selector(buttonDoneTapped))
private lazy var buttonDone = UIBarButtonItem(
title: Strings.add,
style: .done,
target: self,
action: #selector(buttonDoneTapped)
)

private let dataSource: ExternalMediaDataSource
private var assets: [String: ExternalMediaAsset] = [:]
Expand All @@ -32,9 +42,11 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie

private static let cellReuseID = "ExternalMediaPickerCollectionCell"

init(dataSource: ExternalMediaDataSource,
source: MediaSource,
allowsMultipleSelection: Bool = false) {
init(
dataSource: ExternalMediaDataSource,
source: MediaSource,
allowsMultipleSelection: Bool = false
) {
self.dataSource = dataSource
self.source = source
self.allowsMultipleSelection = allowsMultipleSelection
Expand Down Expand Up @@ -133,9 +145,12 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie
}

private func configureNavigationItems() {
let buttonCancel = UIBarButtonItem(systemItem: .cancel, primaryAction: UIAction { [weak self] _ in
self?.buttonCancelTapped()
})
let buttonCancel = UIBarButtonItem(
systemItem: .cancel,
primaryAction: UIAction { [weak self] _ in
self?.buttonCancelTapped()
}
)
navigationItem.leftBarButtonItem = buttonCancel
if allowsMultipleSelection {
navigationItem.rightBarButtonItems = [buttonDone]
Expand All @@ -152,7 +167,11 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie
toolbarItems.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil))
self.toolbarItems = toolbarItems

toolbarItemTitle.buttonViewSelected.addTarget(self, action: #selector(buttonPreviewSelectionTapped), for: .touchUpInside)
toolbarItemTitle.buttonViewSelected.addTarget(
self,
action: #selector(buttonPreviewSelectionTapped),
for: .touchUpInside
)
}

private func didUpdateAssets() {
Expand Down Expand Up @@ -234,8 +253,11 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie
dataSource.assets.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Self.cellReuseID, for: indexPath) as! ExternalMediaPickerCollectionCell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{ // swiftlint:disable:this opening_brace
let cell =
collectionView.dequeueReusableCell(withReuseIdentifier: Self.cellReuseID, for: indexPath)
as! ExternalMediaPickerCollectionCell
let item = dataSource.assets[indexPath.item]
cell.configure(imageURL: item.thumbnailURL, size: ImageSize(scaling: flowLayout.itemSize, in: self.view))
return cell
Expand Down Expand Up @@ -277,13 +299,18 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie

func previewController(_ controller: MediaPreviewController, previewItemAt index: Int) -> MediaPreviewItem? {
guard let id = selection.object(at: index) as? String,
let asset = assets[id] else {
let asset = assets[id]
else {
return nil
}
return MediaPreviewItem(url: asset.largeURL)
}
}

private enum Strings {
static let add = NSLocalizedString("externalMediaPicker.add", value: "Add", comment: "Title for confirmation navigation bar button item")
static let add = NSLocalizedString(
"externalMediaPicker.add",
value: "Add",
comment: "Title for confirmation navigation bar button item"
)
}