OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
6 #error "This file requires ARC support." | |
7 #endif | |
8 | |
9 #import "remoting/client/ios/app/remoting_view_controller.h" | |
10 | |
11 #import "base/mac/bind_objc_block.h" | |
12 #import "ios/third_party/material_components_ios/src/components/AnimationTiming/
src/MaterialAnimationTiming.h" | |
13 #import "ios/third_party/material_components_ios/src/components/AppBar/src/Mater
ialAppBar.h" | |
14 #import "ios/third_party/material_components_ios/src/components/Dialogs/src/Mate
rialDialogs.h" | |
15 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/Mat
erialSnackbar.h" | |
16 #import "remoting/client/ios/app/client_connection_view_controller.h" | |
17 #import "remoting/client/ios/app/host_collection_view_controller.h" | |
18 #import "remoting/client/ios/app/host_view_controller.h" | |
19 #import "remoting/client/ios/app/remoting_settings_view_controller.h" | |
20 #import "remoting/client/ios/domain/client_session_details.h" | |
21 #import "remoting/client/ios/facade/remoting_authentication.h" | |
22 #import "remoting/client/ios/facade/remoting_service.h" | |
23 #import "remoting/client/ios/session/remoting_client.h" | |
24 | |
25 #include "base/strings/sys_string_conversions.h" | |
26 #include "remoting/base/oauth_token_getter.h" | |
27 #include "remoting/client/connect_to_host_info.h" | |
28 | |
29 static CGFloat kHostInset = 5.f; | |
30 | |
31 @interface RemotingViewController ()<HostCollectionViewControllerDelegate, | |
32 ClientConnectionViewControllerDelegate, | |
33 UIViewControllerAnimatedTransitioning, | |
34 UIViewControllerTransitioningDelegate> { | |
35 bool _isAuthenticated; | |
36 MDCDialogTransitionController* _dialogTransitionController; | |
37 MDCAppBar* _appBar; | |
38 HostCollectionViewController* _collectionViewController; | |
39 RemotingService* _remotingService; | |
40 RemotingClient* _client; | |
41 } | |
42 @end | |
43 | |
44 // TODO(nicholss): Localize this file. | |
45 // TODO(nicholss): This file is not finished with integration, the app flow is | |
46 // still pending development. | |
47 | |
48 @implementation RemotingViewController | |
49 | |
50 - (instancetype)init { | |
51 _isAuthenticated = NO; | |
52 UICollectionViewFlowLayout* layout = | |
53 [[UICollectionViewFlowLayout alloc] init]; | |
54 layout.minimumInteritemSpacing = 0; | |
55 CGFloat sectionInset = kHostInset * 2.f; | |
56 [layout setSectionInset:UIEdgeInsetsMake(sectionInset, sectionInset, | |
57 sectionInset, sectionInset)]; | |
58 HostCollectionViewController* collectionVC = [ | |
59 [HostCollectionViewController alloc] initWithCollectionViewLayout:layout]; | |
60 self = [super initWithContentViewController:collectionVC]; | |
61 if (self) { | |
62 _remotingService = [RemotingService SharedInstance]; | |
63 | |
64 _collectionViewController = collectionVC; | |
65 _collectionViewController.flexHeaderContainerViewController = self; | |
66 _collectionViewController.delegate = self; | |
67 | |
68 _appBar = [[MDCAppBar alloc] init]; | |
69 [self addChildViewController:_appBar.headerViewController]; | |
70 | |
71 _appBar.headerViewController.headerView.backgroundColor = | |
72 [UIColor clearColor]; | |
73 _appBar.navigationBar.tintColor = [UIColor whiteColor]; | |
74 | |
75 UIBarButtonItem* menuButton = | |
76 [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Settings"] | |
77 style:UIBarButtonItemStyleDone | |
78 target:self | |
79 action:@selector(didSelectSettings)]; | |
80 self.navigationItem.leftBarButtonItem = menuButton; | |
81 | |
82 UIBarButtonItem* refreshButton = | |
83 [[UIBarButtonItem alloc] initWithTitle:@"Refresh" | |
84 style:UIBarButtonItemStyleDone | |
85 target:self | |
86 action:@selector(didSelectRefresh)]; | |
87 self.navigationItem.rightBarButtonItem = refreshButton; | |
88 | |
89 [[NSNotificationCenter defaultCenter] | |
90 addObserver:self | |
91 selector:@selector(hostSessionStatusChanged:) | |
92 name:kHostSessionStatusChanged | |
93 object:nil]; | |
94 } | |
95 return self; | |
96 } | |
97 | |
98 #pragma mark - UIViewController | |
99 | |
100 - (void)viewDidLoad { | |
101 [super viewDidLoad]; | |
102 [_appBar addSubviewsToParent]; | |
103 | |
104 [[NSNotificationCenter defaultCenter] | |
105 addObserver:self | |
106 selector:@selector(hostsDidUpdateNotification:) | |
107 name:kHostsDidUpdate | |
108 object:nil]; | |
109 [[NSNotificationCenter defaultCenter] | |
110 addObserver:self | |
111 selector:@selector(userDidUpdateNotification:) | |
112 name:kUserDidUpdate | |
113 object:nil]; | |
114 } | |
115 | |
116 - (void)viewWillAppear:(BOOL)animated { | |
117 [super viewWillAppear:animated]; | |
118 | |
119 [self nowAuthenticated:_remotingService.authentication.user.isAuthenticated]; | |
120 [self presentStatus]; | |
121 } | |
122 | |
123 - (void)viewDidAppear:(BOOL)animated { | |
124 [super viewDidAppear:animated]; | |
125 if (!_isAuthenticated) { | |
126 // TODO(nicholss): This is used as a demo of the app functionality for the | |
127 // moment but the real app will force the login flow if unauthenticated. | |
128 [self didSelectSettings]; | |
129 // [self didSelectRefresh]; | |
130 MDCSnackbarMessage* message = [[MDCSnackbarMessage alloc] init]; | |
131 message.text = @"Please login."; | |
132 [MDCSnackbarManager showMessage:message]; | |
133 } else { | |
134 [_remotingService requestHostListFetch]; | |
135 } | |
136 } | |
137 | |
138 - (void)viewDidLayoutSubviews { | |
139 [super viewDidLayoutSubviews]; | |
140 | |
141 // Adjust the collection view's position and size so that it doesn't get | |
142 // overlayed by the navigation bar. | |
143 CGFloat collectionOffsetY = | |
144 _appBar.headerViewController.headerView.frame.size.height; | |
145 CGFloat collectionHeight = self.view.bounds.size.height - collectionOffsetY; | |
146 CGRect oldFrame = _collectionViewController.collectionView.frame; | |
147 _collectionViewController.collectionView.frame = | |
148 CGRectMake(oldFrame.origin.x, collectionOffsetY, oldFrame.size.width, | |
149 collectionHeight); | |
150 } | |
151 | |
152 #pragma mark - Remoting Service Notifications | |
153 | |
154 - (void)hostsDidUpdateNotification:(NSNotification*)notification { | |
155 [_collectionViewController.collectionView reloadData]; | |
156 } | |
157 | |
158 - (void)userDidUpdateNotification:(NSNotification*)notification { | |
159 [self nowAuthenticated:_remotingService.authentication.user.isAuthenticated]; | |
160 } | |
161 | |
162 #pragma mark - RemotingAuthenticationDelegate | |
163 | |
164 - (void)nowAuthenticated:(BOOL)authenticated { | |
165 if (authenticated) { | |
166 MDCSnackbarMessage* message = [[MDCSnackbarMessage alloc] init]; | |
167 message.text = @"Logged In!"; | |
168 [MDCSnackbarManager showMessage:message]; | |
169 } else { | |
170 MDCSnackbarMessage* message = [[MDCSnackbarMessage alloc] init]; | |
171 message.text = @"Not logged in."; | |
172 [MDCSnackbarManager showMessage:message]; | |
173 } | |
174 _isAuthenticated = authenticated; | |
175 [_collectionViewController.collectionView reloadData]; | |
176 } | |
177 | |
178 #pragma mark - RemotingHostListDelegate | |
179 | |
180 // TODO(nicholss): these need to be a stats change like "none, loading, | |
181 // updated"... | |
182 - (void)hostListUpdated { | |
183 [_collectionViewController.collectionView reloadData]; | |
184 } | |
185 | |
186 #pragma mark - ClientConnectionViewControllerDelegate | |
187 | |
188 - (void)clientConnected { | |
189 HostViewController* hostViewController = | |
190 [[HostViewController alloc] initWithClient:_client]; | |
191 [self presentViewController:hostViewController animated:YES completion:nil]; | |
192 } | |
193 | |
194 - (NSString*)getConnectingHostName { | |
195 if (_client) { | |
196 return _client.hostInfo.hostName; | |
197 } | |
198 return nil; | |
199 } | |
200 | |
201 #pragma mark - HostCollectionViewControllerDelegate | |
202 | |
203 - (void)didSelectCell:(HostCollectionViewCell*)cell | |
204 completion:(void (^)())completionBlock { | |
205 _client = [[RemotingClient alloc] init]; | |
206 | |
207 [_remotingService.authentication | |
208 callbackWithAccessToken:base::BindBlockArc(^( | |
209 remoting::OAuthTokenGetter::Status status, | |
210 const std::string& user_email, | |
211 const std::string& access_token) { | |
212 // TODO(nicholss): Check status. | |
213 HostInfo* hostInfo = cell.hostInfo; | |
214 [_client connectToHost:hostInfo | |
215 username:base::SysUTF8ToNSString(user_email) | |
216 accessToken:base::SysUTF8ToNSString(access_token)]; | |
217 })]; | |
218 | |
219 ClientConnectionViewController* clientConnectionViewController = | |
220 [[ClientConnectionViewController alloc] init]; | |
221 clientConnectionViewController.delegate = self; | |
222 [self presentViewController:clientConnectionViewController | |
223 animated:YES | |
224 completion:nil]; | |
225 completionBlock(); | |
226 } | |
227 | |
228 - (NSInteger)getHostCount { | |
229 return _remotingService.hosts.count; | |
230 } | |
231 | |
232 - (HostInfo*)getHostAtIndexPath:(NSIndexPath*)path { | |
233 return _remotingService.hosts[path.row]; | |
234 } | |
235 | |
236 #pragma mark - UIViewControllerTransitioningDelegate | |
237 | |
238 - (nullable id<UIViewControllerAnimatedTransitioning>) | |
239 animationControllerForPresentedController:(UIViewController*)presented | |
240 presentingController:(UIViewController*)presenting | |
241 sourceController:(UIViewController*)source { | |
242 // TODO(nicholss): Not implemented yet. | |
243 return nil; | |
244 } | |
245 | |
246 - (nullable id<UIViewControllerAnimatedTransitioning>) | |
247 animationControllerForDismissedController:(UIViewController*)dismissed { | |
248 return self; | |
249 } | |
250 | |
251 #pragma mark - UIViewControllerAnimatedTransitioning | |
252 | |
253 - (void)animateTransition: | |
254 (id<UIViewControllerContextTransitioning>)transitionContext { | |
255 } | |
256 | |
257 - (NSTimeInterval)transitionDuration: | |
258 (id<UIViewControllerContextTransitioning>)transitionContext { | |
259 return 0.2; | |
260 } | |
261 | |
262 #pragma mark - Private | |
263 | |
264 - (void)hostSessionStatusChanged:(NSNotification*)notification { | |
265 NSLog(@"hostSessionStatusChanged: %@", [notification userInfo]); | |
266 } | |
267 | |
268 - (void)closeViewController { | |
269 [self dismissViewControllerAnimated:true completion:nil]; | |
270 } | |
271 | |
272 - (void)didSelectRefresh { | |
273 // TODO(nicholss): Might want to rate limit this. Maybe remoting service | |
274 // controls that. | |
275 [_remotingService requestHostListFetch]; | |
276 } | |
277 | |
278 - (void)didSelectSettings { | |
279 RemotingSettingsViewController* settingsViewController = | |
280 [[RemotingSettingsViewController alloc] init]; | |
281 [self presentViewController:settingsViewController | |
282 animated:YES | |
283 completion:nil]; | |
284 } | |
285 | |
286 - (void)presentStatus { | |
287 MDCSnackbarMessage* message = [[MDCSnackbarMessage alloc] init]; | |
288 if (_isAuthenticated) { | |
289 message.text = [NSString | |
290 stringWithFormat:@"Currently signed in as %@.", | |
291 _remotingService.authentication.user.userEmail]; | |
292 [MDCSnackbarManager showMessage:message]; | |
293 } | |
294 } | |
295 | |
296 @end | |
OLD | NEW |