OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/browser/payments/shipping_option_selection_coordinator.h" | 5 #import "ios/chrome/browser/payments/shipping_option_selection_coordinator.h" |
6 | 6 |
| 7 #include "base/logging.h" |
7 #include "base/strings/sys_string_conversions.h" | 8 #include "base/strings/sys_string_conversions.h" |
| 9 #include "components/payments/core/strings_util.h" |
8 #include "ios/chrome/browser/payments/payment_request.h" | 10 #include "ios/chrome/browser/payments/payment_request.h" |
9 #import "ios/chrome/browser/payments/payment_request_util.h" | 11 #import "ios/chrome/browser/payments/payment_request_util.h" |
| 12 #include "ios/chrome/browser/payments/shipping_option_selection_mediator.h" |
10 #include "ios/web/public/payments/payment_request.h" | 13 #include "ios/web/public/payments/payment_request.h" |
11 | 14 |
12 #if !defined(__has_feature) || !__has_feature(objc_arc) | 15 #if !defined(__has_feature) || !__has_feature(objc_arc) |
13 #error "This file requires ARC support." | 16 #error "This file requires ARC support." |
14 #endif | 17 #endif |
15 | 18 |
16 namespace { | 19 namespace { |
17 using ::payment_request_util::GetShippingOptionSelectorErrorMessage; | 20 using ::payment_request_util::GetShippingOptionSelectorErrorMessage; |
| 21 using ::payments::GetShippingOptionSectionString; |
| 22 |
| 23 // The delay in nano seconds before notifying the delegate of the selection. |
| 24 const int64_t kDelegateNotificationDelayInNanoSeconds = 0.2 * NSEC_PER_SEC; |
18 } // namespace | 25 } // namespace |
19 | 26 |
20 @interface ShippingOptionSelectionCoordinator () | 27 @interface ShippingOptionSelectionCoordinator () |
21 | 28 |
22 @property(nonatomic, strong) | 29 @property(nonatomic, strong) |
23 ShippingOptionSelectionViewController* viewController; | 30 PaymentRequestSelectorViewController* viewController; |
| 31 |
| 32 @property(nonatomic, strong) ShippingOptionSelectionMediator* mediator; |
24 | 33 |
25 // Called when the user selects a shipping option. The cell is checked, the | 34 // Called when the user selects a shipping option. The cell is checked, the |
26 // UI is locked so that the user can't interact with it, then the delegate is | 35 // UI is locked so that the user can't interact with it, then the delegate is |
27 // notified. The delay is here to let the user get a visual feedback of the | 36 // notified. The delay is here to let the user get a visual feedback of the |
28 // selection before this view disappears. | 37 // selection before this view disappears. |
29 - (void)delayedNotifyDelegateOfSelection: | 38 - (void)delayedNotifyDelegateOfSelection: |
30 (web::PaymentShippingOption*)shippingOption; | 39 (web::PaymentShippingOption*)shippingOption; |
31 | 40 |
32 @end | 41 @end |
33 | 42 |
34 @implementation ShippingOptionSelectionCoordinator | 43 @implementation ShippingOptionSelectionCoordinator |
35 | 44 |
36 @synthesize paymentRequest = _paymentRequest; | 45 @synthesize paymentRequest = _paymentRequest; |
37 @synthesize delegate = _delegate; | 46 @synthesize delegate = _delegate; |
38 @synthesize viewController = _viewController; | 47 @synthesize viewController = _viewController; |
| 48 @synthesize mediator = _mediator; |
39 | 49 |
40 - (void)start { | 50 - (void)start { |
41 _viewController = [[ShippingOptionSelectionViewController alloc] | 51 self.mediator = [[ShippingOptionSelectionMediator alloc] |
42 initWithPaymentRequest:_paymentRequest]; | 52 initWithPaymentRequest:self.paymentRequest]; |
43 [_viewController setDelegate:self]; | 53 |
44 [_viewController loadModel]; | 54 self.viewController = [[PaymentRequestSelectorViewController alloc] init]; |
| 55 self.viewController.title = base::SysUTF16ToNSString( |
| 56 GetShippingOptionSectionString(self.paymentRequest->shipping_type())); |
| 57 self.viewController.delegate = self; |
| 58 self.viewController.dataSource = self.mediator; |
| 59 [self.viewController loadModel]; |
45 | 60 |
46 DCHECK(self.baseViewController.navigationController); | 61 DCHECK(self.baseViewController.navigationController); |
47 [self.baseViewController.navigationController | 62 [self.baseViewController.navigationController |
48 pushViewController:_viewController | 63 pushViewController:self.viewController |
49 animated:YES]; | 64 animated:YES]; |
50 } | 65 } |
51 | 66 |
52 - (void)stop { | 67 - (void)stop { |
53 [self.baseViewController.navigationController popViewControllerAnimated:YES]; | 68 [self.baseViewController.navigationController popViewControllerAnimated:YES]; |
54 _viewController = nil; | 69 self.viewController = nil; |
| 70 self.mediator = nil; |
55 } | 71 } |
56 | 72 |
57 - (void)stopSpinnerAndDisplayError { | 73 - (void)stopSpinnerAndDisplayError { |
58 // Re-enable user interactions that were disabled earlier in | 74 // Re-enable user interactions that were disabled earlier in |
59 // delayedNotifyDelegateOfSelection. | 75 // delayedNotifyDelegateOfSelection. |
60 _viewController.view.userInteractionEnabled = YES; | 76 self.viewController.view.userInteractionEnabled = YES; |
61 | 77 |
62 [_viewController setPending:NO]; | 78 DCHECK(self.paymentRequest); |
63 DCHECK(_paymentRequest); | 79 self.mediator.headerText = |
64 [_viewController | 80 GetShippingOptionSelectorErrorMessage(*self.paymentRequest); |
65 setErrorMessage:GetShippingOptionSelectorErrorMessage(*_paymentRequest)]; | 81 self.mediator.state = PaymentRequestSelectorStateError; |
66 [_viewController loadModel]; | 82 [self.viewController loadModel]; |
67 [[_viewController collectionView] reloadData]; | 83 [self.viewController.collectionView reloadData]; |
68 } | 84 } |
69 | 85 |
70 #pragma mark - ShippingOptionSelectionViewControllerDelegate | 86 #pragma mark - PaymentRequestSelectorViewControllerDelegate |
71 | 87 |
72 - (void)shippingOptionSelectionViewController: | 88 - (void)paymentRequestSelectorViewController: |
73 (ShippingOptionSelectionViewController*)controller | 89 (PaymentRequestSelectorViewController*)controller |
74 didSelectShippingOption: | 90 didSelectItemAtIndex:(NSUInteger)index { |
75 (web::PaymentShippingOption*)shippingOption { | 91 // Update the data source with the selection. |
76 [self delayedNotifyDelegateOfSelection:shippingOption]; | 92 self.mediator.selectedItemIndex = index; |
| 93 |
| 94 DCHECK(index < self.paymentRequest->shipping_options().size()); |
| 95 [self delayedNotifyDelegateOfSelection:self.paymentRequest |
| 96 ->shipping_options()[index]]; |
77 } | 97 } |
78 | 98 |
79 - (void)shippingOptionSelectionViewControllerDidReturn: | 99 - (void)paymentRequestSelectorViewControllerDidFinish: |
80 (ShippingOptionSelectionViewController*)controller { | 100 (PaymentRequestSelectorViewController*)controller { |
81 [_delegate shippingOptionSelectionCoordinatorDidReturn:self]; | 101 [self.delegate shippingOptionSelectionCoordinatorDidReturn:self]; |
82 } | 102 } |
83 | 103 |
| 104 #pragma mark - Helper methods |
| 105 |
84 - (void)delayedNotifyDelegateOfSelection: | 106 - (void)delayedNotifyDelegateOfSelection: |
85 (web::PaymentShippingOption*)shippingOption { | 107 (web::PaymentShippingOption*)shippingOption { |
86 _viewController.view.userInteractionEnabled = NO; | 108 self.viewController.view.userInteractionEnabled = NO; |
87 __weak ShippingOptionSelectionCoordinator* weakSelf = self; | 109 __weak ShippingOptionSelectionCoordinator* weakSelf = self; |
88 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, | 110 dispatch_after( |
89 static_cast<int64_t>(0.2 * NSEC_PER_SEC)), | 111 dispatch_time(DISPATCH_TIME_NOW, kDelegateNotificationDelayInNanoSeconds), |
90 dispatch_get_main_queue(), ^{ | 112 dispatch_get_main_queue(), ^{ |
91 ShippingOptionSelectionCoordinator* strongSelf = weakSelf; | 113 [weakSelf.mediator setState:PaymentRequestSelectorStatePending]; |
92 // Early return if the coordinator has been deallocated. | 114 [weakSelf.viewController loadModel]; |
93 if (!strongSelf) | 115 [weakSelf.viewController.collectionView reloadData]; |
94 return; | |
95 [strongSelf.viewController setPending:YES]; | |
96 [strongSelf.viewController loadModel]; | |
97 [[strongSelf.viewController collectionView] reloadData]; | |
98 | 116 |
99 [strongSelf.delegate | 117 [weakSelf.delegate shippingOptionSelectionCoordinator:weakSelf |
100 shippingOptionSelectionCoordinator:strongSelf | 118 didSelectShippingOption:shippingOption]; |
101 didSelectShippingOption:shippingOption]; | 119 }); |
102 }); | |
103 } | 120 } |
104 | 121 |
105 @end | 122 @end |
OLD | NEW |