Skip to content

Commit aad3cd2

Browse files
authored
Merge pull request #7452 from woocommerce/issue/7440-change-navigation-ipp-orders
[Mobile Payments] Redirect Simple Payments from Order navigation to HubMenu
2 parents bcd4a8f + 88b9252 commit aad3cd2

File tree

5 files changed

+217
-1
lines changed

5 files changed

+217
-1
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Creation/FlowCoordinator/AddOrderCoordinator.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import UIKit
22
import Yosemite
33
import Combine
4+
import SwiftUI
5+
import WordPressUI
46

7+
/// Manages the different navigation flows that start from the Orders main tab
8+
///
59
final class AddOrderCoordinator: Coordinator {
610
var navigationController: UINavigationController
711

812
private let siteID: Int64
913
private let sourceBarButtonItem: UIBarButtonItem?
1014
private let sourceView: UIView?
1115

16+
/// Keeps a reference to NewSimplePaymentsLocationNoticeViewController in order to use it as child of WordPressUI's BottomSheetViewController component
17+
///
18+
private lazy var newSimplePaymentsNoticeViewController: NewSimplePaymentsLocationNoticeViewController = {
19+
NewSimplePaymentsLocationNoticeViewController()
20+
}()
21+
1222
/// Assign this closure to be notified when a new order is created
1323
///
1424
var onOrderCreated: (Order) -> Void = { _ in }
@@ -55,7 +65,11 @@ private extension AddOrderCoordinator {
5565
func presentOrderCreationFlow(bottomSheetOrderType: BottomSheetOrderType) {
5666
switch bottomSheetOrderType {
5767
case .simple:
58-
presentSimplePaymentsAmountController()
68+
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.paymentsHubMenuSection) {
69+
presentBottomAnnouncement()
70+
} else {
71+
presentSimplePaymentsAmountController()
72+
}
5973
case .full:
6074
presentNewOrderController()
6175
return
@@ -68,6 +82,13 @@ private extension AddOrderCoordinator {
6882
SimplePaymentsAmountFlowOpener.openSimplePaymentsAmountFlow(from: navigationController, siteID: siteID)
6983
}
7084

85+
/// Presents `BottomAnnouncementView`UIHostingController modally.
86+
///
87+
func presentBottomAnnouncement() {
88+
let bottomSheet = BottomSheetViewController(childViewController: newSimplePaymentsNoticeViewController)
89+
bottomSheet.show(from: navigationController, sourceView: sourceView, sourceBarButtonItem: sourceBarButtonItem, arrowDirections: .any)
90+
}
91+
7192
/// Presents `OrderFormHostingController`.
7293
///
7394
func presentNewOrderController() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import UIKit
2+
import SwiftUI
3+
import WordPressUI
4+
5+
final class NewSimplePaymentsLocationNoticeViewController: UIViewController {
6+
private let viewModel: NewSimplePaymentsLocationNoticeViewModel
7+
private let simplePaymentsNoticeView: DismissableNoticeView
8+
9+
init() {
10+
viewModel = NewSimplePaymentsLocationNoticeViewModel()
11+
simplePaymentsNoticeView = DismissableNoticeView(
12+
buttonTapped: viewModel.navigateToMenuButtonWasTapped,
13+
title: viewModel.title,
14+
message: viewModel.message,
15+
confirmationButtonMessage: viewModel.confirmationButtonMessage,
16+
icon: viewModel.icon
17+
)
18+
super.init(nibName: nil, bundle: nil)
19+
}
20+
21+
required init?(coder: NSCoder) {
22+
fatalError("init(coder:) has not been implemented")
23+
}
24+
25+
override func viewDidLoad() {
26+
super.viewDidLoad()
27+
setupNewSimplePaymentsNoticeView()
28+
}
29+
30+
override func viewWillLayoutSubviews() {
31+
super.viewWillLayoutSubviews()
32+
}
33+
34+
private func setupNewSimplePaymentsNoticeView() {
35+
let hostingController = UIHostingController(rootView: simplePaymentsNoticeView)
36+
addChild(hostingController)
37+
view.addSubview(hostingController.view)
38+
hostingController.didMove(toParent: self)
39+
setupConstraints(for: hostingController)
40+
}
41+
42+
private func setupConstraints(for hostingController: UIHostingController<DismissableNoticeView>) {
43+
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
44+
hostingController.view.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
45+
hostingController.view.heightAnchor.constraint(equalToConstant: view.intrinsicContentSize.height + Layout.verticalSpace).isActive = true
46+
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
47+
}
48+
}
49+
50+
/// `BottomSheetViewController` conformance
51+
///
52+
extension NewSimplePaymentsLocationNoticeViewController: DrawerPresentable {
53+
var collapsedHeight: DrawerHeight {
54+
return .contentHeight(Layout.verticalSpace)
55+
}
56+
}
57+
58+
extension NewSimplePaymentsLocationNoticeViewController {
59+
enum Layout {
60+
static let verticalSpace: CGFloat = 200
61+
}
62+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import SwiftUI
2+
3+
final class NewSimplePaymentsLocationNoticeViewModel {
4+
let title: String
5+
let message: String
6+
let confirmationButtonMessage: String
7+
let icon: UIImage = .walletImage
8+
9+
/// Redirects to `HubMenu`tabBar
10+
///
11+
var navigateToMenuButtonWasTapped: () -> Void = {
12+
guard let mainTabBarController = AppDelegate.shared.tabBarController else {
13+
return
14+
}
15+
mainTabBarController.navigateTo(.hubMenu)
16+
}
17+
18+
init() {
19+
title = Localization.title
20+
message = Localization.message
21+
confirmationButtonMessage = Localization.confirmationButtonMessage
22+
}
23+
24+
}
25+
26+
extension NewSimplePaymentsLocationNoticeViewModel {
27+
enum Localization {
28+
static let title = NSLocalizedString("Payments from the Menu tab",
29+
comment: "Title of the bottom announcement modal when a merchant taps on Simple Payment")
30+
static let message = NSLocalizedString("Now you can quickly access In-Person Payments and other features with ease.",
31+
comment: "Message of the bottom announcement modal when a merchant taps on Simple Payment")
32+
static let confirmationButtonMessage = NSLocalizedString("Got it!",
33+
comment: "Confirmation text of the button on the bottom announcement modal" +
34+
"when a merchant taps on Simple Payment")
35+
}
36+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import SwiftUI
2+
3+
/// A generic View that shows a dismissable Notice.
4+
/// This contains a title, left-side message, right-side icon, and a button that dismisses the View when tapped.
5+
///
6+
/// - Parameters:
7+
/// - buttonTapped: The callback to dismiss the View.
8+
/// - title: Title to be displayed on the top of the View.
9+
/// - message: Left-side message to be displayed.
10+
/// - confirmationButtonMessage: The text inside the button component.
11+
/// - icon: Right-side icon to be displayed.
12+
///
13+
struct DismissableNoticeView: View {
14+
@Environment(\.presentationMode) private var presentation
15+
@ScaledMetric private var scale: CGFloat = 1.0
16+
17+
var buttonTapped: (() -> Void)?
18+
var title: String
19+
var message: String
20+
var confirmationButtonMessage: String
21+
var icon: UIImage
22+
23+
var body: some View {
24+
VStack() {
25+
Spacer()
26+
Text(title)
27+
.font(.body).bold()
28+
.padding(.top, Layout.verticalPadding*2)
29+
.frame(maxWidth: .infinity, alignment: .leading)
30+
HStack {
31+
Text(message)
32+
.font(.subheadline)
33+
.foregroundColor(.gray)
34+
.multilineTextAlignment(.leading)
35+
.fixedSize(horizontal: false, vertical: true)
36+
.frame(alignment: .leading)
37+
Spacer()
38+
ZStack {
39+
Color(UIColor(light: .listBackground,
40+
dark: .secondaryButtonBackground))
41+
Image(uiImage: icon)
42+
.resizable()
43+
.aspectRatio(contentMode: .fit)
44+
.frame(width: Layout.iconSize * scale, height: Layout.iconSize * scale)
45+
}
46+
.frame(width: Layout.imageSize, height: Layout.imageSize, alignment: .trailing)
47+
.cornerRadius(Layout.imageSize/2)
48+
}
49+
.padding(.bottom, Layout.verticalPadding)
50+
.frame(maxWidth: .infinity)
51+
Button(confirmationButtonMessage) {
52+
if let completionHandler = buttonTapped {
53+
completionHandler()
54+
}
55+
presentation.wrappedValue.dismiss()
56+
}
57+
.buttonStyle(SecondaryButtonStyle())
58+
.padding(.bottom, Layout.verticalPadding)
59+
}
60+
.padding(.leading, Layout.horizontalPadding)
61+
.padding(.trailing, Layout.horizontalPadding)
62+
.padding(.top, Layout.verticalPadding)
63+
.padding(.bottom, Layout.verticalPadding*4)
64+
}
65+
}
66+
67+
struct DismissableNoticeView_Previews: PreviewProvider {
68+
static var previews: some View {
69+
DismissableNoticeView(
70+
title: "Dismissable notice title",
71+
message: "Dismissable notice message",
72+
confirmationButtonMessage: "Ok",
73+
icon: .walletImage)
74+
}
75+
}
76+
77+
extension DismissableNoticeView {
78+
enum Layout {
79+
static let horizontalPadding: CGFloat = 16
80+
static let verticalPadding: CGFloat = 16
81+
static let cornerRadius: CGFloat = 20
82+
static let imageSize: CGFloat = 48
83+
static let iconSize: CGFloat = 32
84+
}
85+
}

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,9 @@
953953
57F2C6CD246DECC10074063B /* SummaryTableViewCellViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F2C6CC246DECC10074063B /* SummaryTableViewCellViewModelTests.swift */; };
954954
57F42E40253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F42E3F253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift */; };
955955
581D5052274AA2480089B6AD /* View+AutofocusTextModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581D5051274AA2480089B6AD /* View+AutofocusTextModifier.swift */; };
956+
6827140F28A3988300E6E3F6 /* DismissableNoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6827140E28A3988300E6E3F6 /* DismissableNoticeView.swift */; };
957+
6827141128A5410D00E6E3F6 /* NewSimplePaymentsLocationNoticeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6827141028A5410D00E6E3F6 /* NewSimplePaymentsLocationNoticeViewModel.swift */; };
958+
6827141528A671B900E6E3F6 /* NewSimplePaymentsLocationNoticeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6827141428A671B900E6E3F6 /* NewSimplePaymentsLocationNoticeViewController.swift */; };
956959
6832C7CA26DA5C4500BA4088 /* LabeledTextViewTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6832C7C926DA5C4500BA4088 /* LabeledTextViewTableViewCell.swift */; };
957960
6832C7CC26DA5FDF00BA4088 /* LabeledTextViewTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6832C7CB26DA5FDE00BA4088 /* LabeledTextViewTableViewCell.xib */; };
958961
684AB83A2870677F003DFDD1 /* CardReaderManualsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684AB8392870677F003DFDD1 /* CardReaderManualsView.swift */; };
@@ -2760,6 +2763,9 @@
27602763
57F2C6CC246DECC10074063B /* SummaryTableViewCellViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SummaryTableViewCellViewModelTests.swift; sourceTree = "<group>"; };
27612764
57F42E3F253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleAndEditableValueTableViewCellViewModelTests.swift; sourceTree = "<group>"; };
27622765
581D5051274AA2480089B6AD /* View+AutofocusTextModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+AutofocusTextModifier.swift"; sourceTree = "<group>"; };
2766+
6827140E28A3988300E6E3F6 /* DismissableNoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissableNoticeView.swift; sourceTree = "<group>"; };
2767+
6827141028A5410D00E6E3F6 /* NewSimplePaymentsLocationNoticeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewSimplePaymentsLocationNoticeViewModel.swift; sourceTree = "<group>"; };
2768+
6827141428A671B900E6E3F6 /* NewSimplePaymentsLocationNoticeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewSimplePaymentsLocationNoticeViewController.swift; sourceTree = "<group>"; };
27632769
6832C7C926DA5C4500BA4088 /* LabeledTextViewTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabeledTextViewTableViewCell.swift; sourceTree = "<group>"; };
27642770
6832C7CB26DA5FDE00BA4088 /* LabeledTextViewTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LabeledTextViewTableViewCell.xib; sourceTree = "<group>"; };
27652771
684AB8392870677F003DFDD1 /* CardReaderManualsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderManualsView.swift; sourceTree = "<group>"; };
@@ -5670,6 +5676,7 @@
56705676
DE34771227F174C8009CA300 /* StatusView.swift */,
56715677
B9E4364B287587D300883CFA /* FeatureAnnouncementCardView.swift */,
56725678
B9E4364D287589E200883CFA /* BadgeView.swift */,
5679+
6827140E28A3988300E6E3F6 /* DismissableNoticeView.swift */,
56735680
);
56745681
path = "SwiftUI Components";
56755682
sourceTree = "<group>";
@@ -6243,6 +6250,8 @@
62436250
children = (
62446251
AEA622B1274669D3002A9B57 /* AddOrderCoordinator.swift */,
62456252
AEA622B327466B78002A9B57 /* BottomSheetOrderType.swift */,
6253+
6827141028A5410D00E6E3F6 /* NewSimplePaymentsLocationNoticeViewModel.swift */,
6254+
6827141428A671B900E6E3F6 /* NewSimplePaymentsLocationNoticeViewController.swift */,
62466255
);
62476256
path = FlowCoordinator;
62486257
sourceTree = "<group>";
@@ -9075,6 +9084,7 @@
90759084
57896D6625362B0C000E8C4D /* TitleAndEditableValueTableViewCellViewModel.swift in Sources */,
90769085
0205021E27C8B6C600FB1C6B /* InboxEligibilityUseCase.swift in Sources */,
90779086
26E1BECE251CD9F80096D0A1 /* RefundItemViewModel.swift in Sources */,
9087+
6827141128A5410D00E6E3F6 /* NewSimplePaymentsLocationNoticeViewModel.swift in Sources */,
90789088
DE7B479027A153C20018742E /* CouponSearchUICommand.swift in Sources */,
90799089
02645D8827BA2E820065DC68 /* NSAttributedString+Attributes.swift in Sources */,
90809090
024DF3092372CA00006658FE /* EditorViewProperties.swift in Sources */,
@@ -9130,6 +9140,7 @@
91309140
D89FAF4E2795BDFF00D8DA66 /* InPersonPaymentsPluginConflictAdminView.swift in Sources */,
91319141
E15F163126C5117300D3059B /* InPersonPaymentsNoConnectionView.swift in Sources */,
91329142
456CB50D2444BFAC00992A05 /* ProductPurchaseNoteViewController.swift in Sources */,
9143+
6827140F28A3988300E6E3F6 /* DismissableNoticeView.swift in Sources */,
91339144
D802541F2655137A001B2CC1 /* CardPresentModalNonRetryableError.swift in Sources */,
91349145
B651474527D644FF00C9C4E6 /* CustomerNoteSection.swift in Sources */,
91359146
0375799B28227EDE0083F2E1 /* CardPresentPaymentsOnboardingPresenter.swift in Sources */,
@@ -9434,6 +9445,7 @@
94349445
027A2E162513356100DA6ACB /* AppleIDCredentialChecker.swift in Sources */,
94359446
26B98758273C5BE30090E8CA /* EditCustomerNoteViewModelProtocol.swift in Sources */,
94369447
4524CD9E242D01FD00B2F20A /* ProductStatusSettingListSelectorCommand.swift in Sources */,
9448+
6827141528A671B900E6E3F6 /* NewSimplePaymentsLocationNoticeViewController.swift in Sources */,
94379449
02F6800325807C9B00C3BAD2 /* ShippingLabelPaperSizeOptionListView.swift in Sources */,
94389450
02E8B17723E2C49000A43403 /* InProgressProductImageCollectionViewCell.swift in Sources */,
94399451
CE5F462C23AACBC4006B1A5C /* RefundDetailsResultController.swift in Sources */,

0 commit comments

Comments
 (0)