-
Notifications
You must be signed in to change notification settings - Fork 121
Product Preview: Add "Preview" button to product details #7960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
ca41149
d239cb3
0e48db9
7fb78a3
0b7e974
223297d
386cfe2
c289b55
a525828
edf3702
b6ea899
c1e812f
9867928
6281f5b
9401ad1
ac52d2d
d69489c
dad2691
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -199,6 +199,34 @@ final class ProductFormViewController<ViewModel: ProductFormViewModelProtocol>: | |
| saveProduct(status: .draft) | ||
| } | ||
|
|
||
| // MARK: Product preview action handling | ||
|
|
||
| @objc private func saveDraftAndDisplayProductPreview() { | ||
| guard viewModel.canSaveAsDraft() || viewModel.hasUnsavedChanges() else { | ||
| displayProductPreview() | ||
| return | ||
| } | ||
|
|
||
| saveProduct(status: .draft) { [weak self] result in | ||
| if result.isSuccess { | ||
| self?.displayProductPreview() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private func displayProductPreview() { | ||
| var permalink = URLComponents(string: product.permalink) | ||
| var updatedQueryItems = permalink?.queryItems ?? [] | ||
| updatedQueryItems.append(.init(name: "preview", value: "true")) | ||
| permalink?.queryItems = updatedQueryItems | ||
| guard let url = permalink?.url else { | ||
| return | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this fail? if it can, should we show some kind of toast?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The source string, |
||
| } | ||
|
|
||
| // TODO: Show authenticated WebView | ||
| WebviewHelper.launch(url, with: self) | ||
| } | ||
|
|
||
| // MARK: Navigation actions | ||
|
|
||
| @objc func closeNavigationBarButtonTapped() { | ||
|
|
@@ -716,14 +744,14 @@ private extension ProductFormViewController { | |
| // MARK: Navigation actions | ||
| // | ||
| private extension ProductFormViewController { | ||
| func saveProduct(status: ProductStatus? = nil) { | ||
| func saveProduct(status: ProductStatus? = nil, onCompletion: @escaping (Result<Void, ProductUpdateError>) -> Void = { _ in }) { | ||
| let productStatus = status ?? product.status | ||
| let messageType = viewModel.saveMessageType(for: productStatus) | ||
| showSavingProgress(messageType) | ||
| saveProductRemotely(status: status) | ||
| saveProductRemotely(status: status, onCompletion: onCompletion) | ||
| } | ||
|
|
||
| func saveProductRemotely(status: ProductStatus?) { | ||
| func saveProductRemotely(status: ProductStatus?, onCompletion: @escaping (Result<Void, ProductUpdateError>) -> Void = { _ in }) { | ||
| viewModel.saveProductRemotely(status: status) { [weak self] result in | ||
| switch result { | ||
| case .failure(let error): | ||
|
|
@@ -732,6 +760,7 @@ private extension ProductFormViewController { | |
| // Dismisses the in-progress UI then presents the error alert. | ||
| self?.navigationController?.dismiss(animated: true) { | ||
| self?.displayError(error: error) | ||
| onCompletion(.failure(error)) | ||
| } | ||
| case .success: | ||
| // Dismisses the in-progress UI, then presents the confirmation alert. | ||
|
|
@@ -741,6 +770,7 @@ private extension ProductFormViewController { | |
| // Show linked products promo banner after product save | ||
| (self?.viewModel as? ProductFormViewModel)?.isLinkedProductsPromoEnabled = true | ||
| self?.reloadLinkedPromoCellAnimated() | ||
| onCompletion(.success(())) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -908,6 +938,8 @@ private extension ProductFormViewController { | |
| // Create action buttons based on view model | ||
| let rightBarButtonItems: [UIBarButtonItem] = viewModel.actionButtons.reversed().map { buttonType in | ||
| switch buttonType { | ||
| case .preview: | ||
| return createPreviewBarButtonItem() | ||
| case .publish: | ||
| return createPublishBarButtonItem() | ||
| case .save: | ||
|
|
@@ -934,6 +966,10 @@ private extension ProductFormViewController { | |
| return UIBarButtonItem(title: Localization.saveTitle, style: .done, target: self, action: #selector(saveProductAndLogEvent)) | ||
| } | ||
|
|
||
| func createPreviewBarButtonItem() -> UIBarButtonItem { | ||
| return UIBarButtonItem(title: Localization.previewTitle, style: .done, target: self, action: #selector(saveDraftAndDisplayProductPreview)) | ||
| } | ||
|
|
||
| func createMoreOptionsBarButtonItem() -> UIBarButtonItem { | ||
| let moreButton = UIBarButtonItem(image: .moreImage, | ||
| style: .plain, | ||
|
|
@@ -1535,6 +1571,7 @@ private extension ProductFormViewController { | |
| private enum Localization { | ||
| static let publishTitle = NSLocalizedString("Publish", comment: "Action for creating a new product remotely with a published status") | ||
| static let saveTitle = NSLocalizedString("Save", comment: "Action for saving a Product remotely") | ||
| static let previewTitle = NSLocalizedString("Preview", comment: "Action for previewing draft Product changes in the webview") | ||
| static let groupedProductsViewTitle = NSLocalizedString("Grouped Products", | ||
| comment: "Navigation bar title for editing linked products for a grouped product") | ||
| static let unnamedProduct = NSLocalizedString("Unnamed product", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,6 +151,12 @@ final class ProductFormViewModel: ProductFormViewModelProtocol { | |
| } | ||
| }() | ||
|
|
||
| // Preview existing drafts or new products, that can be saved as a draft | ||
| if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.productsPreview), | ||
| (canSaveAsDraft() || productModel.status == .draft) { | ||
| buttons.insert(.preview, at: 0) | ||
| } | ||
|
||
|
|
||
| // Add more button if needed | ||
| if shouldShowMoreOptionsMenu() { | ||
| buttons.append(.more) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could use the same
.productsOnboardingfeature flag right?When the other deliverables are done, we can just take them out of the feature flag check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, updated in edf3702