VLCServerListTVTableViewController.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*****************************************************************************
  2. * VLC for iOS
  3. *****************************************************************************
  4. * Copyright (c) 2015 VideoLAN. All rights reserved.
  5. * $Id$
  6. *
  7. * Authors: Tobias Conradi <videolan # tobias-conradi.de>
  8. *
  9. * Refer to the COPYING file of the official project for license.
  10. *****************************************************************************/
  11. #import "VLCServerListTVTableViewController.h"
  12. #import "VLCLocalNetworkServerTVCell.h"
  13. #import "VLCServerBrowsingTVViewController.h"
  14. #import "VLCNetworkServerLoginInformation.h"
  15. #import "VLCNetworkServerBrowserPlex.h"
  16. #import "VLCLocalNetworkServiceBrowserPlex.h"
  17. #import "VLCNetworkServerBrowserVLCMedia.h"
  18. #import "VLCLocalNetworkServiceBrowserDSM.h"
  19. #import "VLCLocalNetworkServiceBrowserFTP.h"
  20. #import "VLCNetworkServerBrowserFTP.h"
  21. #import <SSKeychain/SSKeychain.h>
  22. @interface VLCServerListTVTableViewController ()
  23. {
  24. UILabel *_nothingFoundLabel;
  25. }
  26. @end
  27. @implementation VLCServerListTVTableViewController
  28. - (void)viewDidLoad {
  29. [super viewDidLoad];
  30. self.automaticallyAdjustsScrollViewInsets = NO;
  31. self.edgesForExtendedLayout = UIRectEdgeAll ^ UIRectEdgeTop;
  32. UINib *nib = [UINib nibWithNibName:@"VLCLocalNetworkServerTVCell" bundle:nil];
  33. [self.tableView registerNib:nib forCellReuseIdentifier:VLCLocalServerTVCell];
  34. self.tableView.rowHeight = 150;
  35. _nothingFoundLabel = [[UILabel alloc] init];
  36. _nothingFoundLabel.text = NSLocalizedString(@"NO_SERVER_FOUND", nil);
  37. _nothingFoundLabel.textAlignment = NSTextAlignmentCenter;
  38. _nothingFoundLabel.textColor = [UIColor VLCLightTextColor];
  39. _nothingFoundLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3];
  40. [_nothingFoundLabel sizeToFit];
  41. [_nothingFoundLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
  42. [self.view addSubview:_nothingFoundLabel];
  43. NSLayoutConstraint *yConstraint = [NSLayoutConstraint constraintWithItem:_nothingFoundLabel
  44. attribute:NSLayoutAttributeCenterY
  45. relatedBy:NSLayoutRelationEqual
  46. toItem:self.view
  47. attribute:NSLayoutAttributeCenterY
  48. multiplier:1.0
  49. constant:0.0];
  50. [self.view addConstraint:yConstraint];
  51. NSLayoutConstraint *xConstraint = [NSLayoutConstraint constraintWithItem:_nothingFoundLabel
  52. attribute:NSLayoutAttributeCenterX
  53. relatedBy:NSLayoutRelationEqual
  54. toItem:self.view
  55. attribute:NSLayoutAttributeCenterX
  56. multiplier:1.0
  57. constant:0.0];
  58. [self.view addConstraint:xConstraint];
  59. }
  60. - (void)viewDidAppear:(BOOL)animated
  61. {
  62. [super viewDidAppear:animated];
  63. [self.discoveryController startDiscovery];
  64. }
  65. - (void)viewDidDisappear:(BOOL)animated
  66. {
  67. [super viewDidDisappear:animated];
  68. [self.discoveryController stopDiscovery];
  69. }
  70. #pragma mark - Table view data source
  71. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  72. return self.discoveryController.numberOfSections;
  73. }
  74. - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
  75. VLCLocalServerDiscoveryController *discoverer = self.discoveryController;
  76. if (discoverer.numberOfSections > 1 && [discoverer numberOfItemsInSection:section] > 0) {
  77. return [self.discoveryController titleForSection:section];
  78. }
  79. return nil;
  80. }
  81. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  82. return [self.discoveryController numberOfItemsInSection:section];
  83. }
  84. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  85. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:VLCLocalServerTVCell forIndexPath:indexPath];
  86. id<VLCLocalNetworkService> service = [self.discoveryController networkServiceForIndexPath:indexPath];
  87. cell.textLabel.text = service.title;
  88. cell.imageView.image = service.icon ? service.icon : [UIImage imageNamed:@"serverIcon"];
  89. return cell;
  90. }
  91. - (void)showWIP:(NSString *)todo {
  92. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Work in Progress\nFeature not (yet) implemented."
  93. message:todo
  94. preferredStyle:UIAlertControllerStyleAlert];
  95. [alertController addAction:[UIAlertAction actionWithTitle:@"Please fix this!"
  96. style:UIAlertActionStyleDefault
  97. handler:nil]];
  98. [alertController addAction:[UIAlertAction actionWithTitle:@"Nevermind"
  99. style:UIAlertActionStyleCancel
  100. handler:nil]];
  101. [self presentViewController:alertController animated:YES completion:nil];
  102. }
  103. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  104. id<VLCLocalNetworkService> service = [self.discoveryController networkServiceForIndexPath:indexPath];
  105. if ([service respondsToSelector:@selector(serverBrowser)]) {
  106. id <VLCNetworkServerBrowser> browser = [service serverBrowser];
  107. if (browser) {
  108. VLCServerBrowsingTVViewController *browsingViewController = [[VLCServerBrowsingTVViewController alloc] initWithServerBrowser:browser];
  109. [self presentViewController:[[UINavigationController alloc] initWithRootViewController:browsingViewController]
  110. animated:YES
  111. completion:nil];
  112. return;
  113. }
  114. }
  115. if ([service respondsToSelector:@selector(loginInformation)]) {
  116. VLCNetworkServerLoginInformation *login = service.loginInformation;
  117. if (!login) return;
  118. [self showLoginAlertWithLogin:login];
  119. return;
  120. }
  121. if ([service respondsToSelector:@selector(directPlaybackURL)]) {
  122. NSURL *url = service.directPlaybackURL;
  123. if (!url) return;
  124. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  125. [vpc playURL:url subtitlesFilePath:nil];
  126. [self presentViewController:[VLCFullscreenMovieTVViewController fullscreenMovieTVViewController]
  127. animated:YES
  128. completion:nil];
  129. return;
  130. }
  131. }
  132. - (void)showLoginAlertWithLogin:(nonnull VLCNetworkServerLoginInformation *)login
  133. {
  134. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"CONNECT_TO_SERVER", nil)
  135. message:login.address preferredStyle:UIAlertControllerStyleAlert];
  136. NSURLComponents *components = [[NSURLComponents alloc] init];
  137. components.scheme = login.protocolIdentifier;
  138. components.host = login.address;
  139. components.port = login.port;
  140. NSString *serviceIdentifier = components.URL.absoluteString;
  141. NSString *accountName = [SSKeychain accountsForService:serviceIdentifier].firstObject[kSSKeychainAccountKey];
  142. NSString *password = [SSKeychain passwordForService:serviceIdentifier account:accountName];
  143. __block UITextField *usernameField = nil;
  144. __block UITextField *passwordField = nil;
  145. [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  146. textField.placeholder = NSLocalizedString(@"USER_LABEL", nil);
  147. textField.text = accountName;
  148. usernameField = textField;
  149. }];
  150. [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  151. textField.secureTextEntry = YES;
  152. textField.placeholder = NSLocalizedString(@"PASSWORD_LABEL", nil);
  153. textField.text = password;
  154. passwordField = textField;
  155. }];
  156. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"LOGIN", nil)
  157. style:UIAlertActionStyleDefault
  158. handler:^(UIAlertAction * _Nonnull action) {
  159. login.username = usernameField.text;
  160. login.password = passwordField.text;
  161. [self showBrowserWithLogin:login];
  162. }]];
  163. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_SAVE", nil)
  164. style:UIAlertActionStyleDefault
  165. handler:^(UIAlertAction * _Nonnull action) {
  166. NSString *accountName = usernameField.text;
  167. NSString *password = passwordField.text;
  168. [SSKeychain setPassword:password forService:serviceIdentifier account:accountName];
  169. login.username = accountName;
  170. login.password = password;
  171. [self showBrowserWithLogin:login];
  172. }]];
  173. if (accountName.length && password.length) {
  174. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_DELETE", nil)
  175. style:UIAlertActionStyleDestructive
  176. handler:^(UIAlertAction * _Nonnull action) {
  177. [SSKeychain deletePasswordForService:serviceIdentifier account:accountName];
  178. }]];
  179. }
  180. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)
  181. style:UIAlertActionStyleCancel
  182. handler:nil]];
  183. [self presentViewController:alertController animated:YES completion:nil];
  184. }
  185. - (void)showBrowserWithLogin:(nonnull VLCNetworkServerLoginInformation *)login
  186. {
  187. id<VLCNetworkServerBrowser> serverBrowser = nil;
  188. NSString *identifier = login.protocolIdentifier;
  189. if ([identifier isEqualToString:VLCNetworkServerProtocolIdentifierFTP]) {
  190. serverBrowser = [[VLCNetworkServerBrowserFTP alloc] initWithLogin:login];
  191. } else if ([identifier isEqualToString:VLCNetworkServerProtocolIdentifierPlex]) {
  192. serverBrowser = [[VLCNetworkServerBrowserPlex alloc] initWithLogin:login];
  193. } else if ([identifier isEqualToString:VLCNetworkServerProtocolIdentifierSMB]) {
  194. serverBrowser = [VLCNetworkServerBrowserVLCMedia SMBNetworkServerBrowserWithLogin:login];
  195. }
  196. if (serverBrowser) {
  197. VLCServerBrowsingTVViewController *targetViewController = [[VLCServerBrowsingTVViewController alloc] initWithServerBrowser:serverBrowser];
  198. [self presentViewController:[[UINavigationController alloc] initWithRootViewController:targetViewController]
  199. animated:YES
  200. completion:nil];
  201. }
  202. }
  203. #pragma mark - VLCLocalServerDiscoveryController
  204. - (void)discoveryFoundSomethingNew
  205. {
  206. [self.tableView reloadData];
  207. _nothingFoundLabel.hidden = self.discoveryController.foundAnythingAtAll;
  208. }
  209. @end