VLCMenuTableViewController.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*****************************************************************************
  2. * VLCMenuTableViewController.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2013-2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Felix Paul Kühne <fkuehne # videolan.org>
  9. * Gleb Pinigin <gpinigin # gmail.com>
  10. * Jean-Romain Prévost <jr # 3on.fr>
  11. * Carola Nitz <nitz.carola # googlemail.com>
  12. * Tamas Timar <ttimar.vlc # gmail.com>
  13. * Pierre Sagaspe <pierre.sagaspe # me.com>
  14. *
  15. * Refer to the COPYING file of the official project for license.
  16. *****************************************************************************/
  17. #import "VLCMenuTableViewController.h"
  18. #import "VLCSidebarViewCell.h"
  19. #import "Reachability.h"
  20. #import <QuartzCore/QuartzCore.h>
  21. #import "VLCWiFiUploadTableViewCell.h"
  22. #import "VLCHTTPUploaderController.h"
  23. #import "VLCAppDelegate.h"
  24. #import "HTTPServer.h"
  25. #import "IASKAppSettingsViewController.h"
  26. #import "VLCServerListViewController.h"
  27. #import "VLCOpenNetworkStreamViewController.h"
  28. #import "VLCSettingsController.h"
  29. #import "VLCAboutViewController.h"
  30. #import "VLCPlaylistViewController.h"
  31. #import "VLCBugreporter.h"
  32. #import "VLCCloudServicesTableViewController.h"
  33. #import "VLCNavigationController.h"
  34. #import "GHRevealViewController.h"
  35. @interface VLCMenuTableViewController () <UITableViewDataSource, UITableViewDelegate>
  36. {
  37. NSArray *_sectionHeaderTexts;
  38. NSArray *_menuItemsSectionOne;
  39. NSArray *_menuItemsSectionTwo;
  40. NSArray *_menuItemsSectionThree;
  41. NSMutableSet *_hiddenSettingKeys;
  42. UILabel *_uploadLocationLabel;
  43. UIButton *_uploadButton;
  44. Reachability *_reachability;
  45. }
  46. @end
  47. @implementation VLCMenuTableViewController
  48. - (void)dealloc
  49. {
  50. [_reachability stopNotifier];
  51. [[NSNotificationCenter defaultCenter] removeObserver:self];
  52. }
  53. - (void)viewDidLoad
  54. {
  55. [super viewDidLoad];
  56. self.view.frame = CGRectMake(0.0f, 0.0f, kGHRevealSidebarWidth, CGRectGetHeight(self.view.bounds));
  57. self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  58. _sectionHeaderTexts = @[@"SECTION_HEADER_LIBRARY", @"SECTION_HEADER_NETWORK", @"Settings"];
  59. _menuItemsSectionOne = @[@"LIBRARY_ALL_FILES", @"LIBRARY_MUSIC", @"LIBRARY_SERIES"];
  60. _menuItemsSectionTwo = @[@"LOCAL_NETWORK", @"OPEN_NETWORK", @"DOWNLOAD_FROM_HTTP", @"WEBINTF_TITLE", @"CLOUD_SERVICES"];
  61. _menuItemsSectionThree = @[@"Settings", @"ABOUT_APP"];
  62. _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, 44.0f + 20.0f, kGHRevealSidebarWidth, CGRectGetHeight(self.view.bounds) - (44.0f + 20.0f)) style:UITableViewStylePlain];
  63. _tableView.delegate = self;
  64. _tableView.dataSource = self;
  65. _tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  66. _tableView.backgroundColor = [UIColor colorWithRed:(43.0f/255.0f) green:(43.0f/255.0f) blue:(43.0f/255.0f) alpha:1.0f];
  67. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  68. _tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
  69. _tableView.rowHeight = [VLCWiFiUploadTableViewCell heightOfCell];
  70. _tableView.scrollsToTop = NO;
  71. self.view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, kGHRevealSidebarWidth, CGRectGetHeight(self.view.bounds))];
  72. self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  73. [self.view addSubview:_tableView];
  74. UIView *brandingBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, kGHRevealSidebarWidth, 64.0f)];
  75. brandingBackgroundView.backgroundColor = [UIColor colorWithRed:0.1608 green:0.1608 blue:0.1608 alpha:1.0000];
  76. [self.view addSubview:brandingBackgroundView];
  77. UIImageView *brandingImageView;
  78. brandingImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, kGHRevealSidebarWidth, 44.0f + 40.0f)];
  79. brandingImageView.contentMode = UIViewContentModeCenter;
  80. brandingImageView.image = [UIImage imageNamed:@"title"];
  81. [self.view addSubview:brandingImageView];
  82. [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionTop];
  83. _reachability = [Reachability reachabilityForLocalWiFi];
  84. [_reachability startNotifier];
  85. [self netReachabilityChanged:nil];
  86. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(netReachabilityChanged:) name:kReachabilityChangedNotification object:nil];
  87. BOOL isHTTPServerOn = [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingSaveHTTPUploadServerStatus];
  88. [[VLCHTTPUploaderController sharedInstance] changeHTTPServerState:isHTTPServerOn];
  89. [self updateHTTPServerAddress];
  90. }
  91. - (void)viewWillAppear:(BOOL)animated
  92. {
  93. [super viewWillAppear:animated];
  94. self.view.frame = CGRectMake(0.0f, 0.0f,kGHRevealSidebarWidth, CGRectGetHeight(self.view.bounds));
  95. [self netReachabilityChanged:nil];
  96. }
  97. - (void)netReachabilityChanged:(NSNotification *)notification
  98. {
  99. if (_reachability.currentReachabilityStatus == ReachableViaWiFi) {
  100. _uploadButton.enabled = YES;
  101. [self updateHTTPServerAddress];
  102. } else {
  103. [_uploadButton setImage:[UIImage imageNamed:@"WifiUp"] forState:UIControlStateNormal];
  104. _uploadButton.enabled = NO;
  105. [_uploadButton setImage:[UIImage imageNamed:@"WiFiUp"] forState:UIControlStateDisabled];
  106. _uploadLocationLabel.text = NSLocalizedString(@"HTTP_UPLOAD_NO_CONNECTIVITY", nil);
  107. [[VLCHTTPUploaderController sharedInstance] changeHTTPServerState:NO];
  108. }
  109. }
  110. - (BOOL)shouldAutorotate
  111. {
  112. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  113. return (orientation == UIInterfaceOrientationPortraitUpsideDown) ? (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) : YES;
  114. }
  115. - (BOOL)canBecomeFirstResponder
  116. {
  117. return YES;
  118. }
  119. #pragma mark - table view data source
  120. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  121. {
  122. return 3;
  123. }
  124. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  125. {
  126. if (section == 0) // media
  127. return _menuItemsSectionOne.count;
  128. else if (section == 1) // network
  129. return _menuItemsSectionTwo.count;
  130. else if (section == 2) // settings & co
  131. return _menuItemsSectionThree.count;
  132. else
  133. return 0;
  134. }
  135. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  136. {
  137. static NSString *CellIdentifier = @"VLCMenuCell";
  138. static NSString *WiFiCellIdentifier = @"VLCMenuWiFiCell";
  139. NSString *rawTitle;
  140. NSUInteger section = indexPath.section;
  141. if (section == 0)
  142. rawTitle = _menuItemsSectionOne[indexPath.row];
  143. else if(section == 1)
  144. rawTitle = _menuItemsSectionTwo[indexPath.row];
  145. else if(section == 2)
  146. rawTitle = _menuItemsSectionThree[indexPath.row];
  147. UITableViewCell *cell;
  148. if ([rawTitle isEqualToString:@"WEBINTF_TITLE"]) {
  149. cell = (VLCWiFiUploadTableViewCell *)[tableView dequeueReusableCellWithIdentifier:WiFiCellIdentifier];
  150. if (cell == nil)
  151. cell = [VLCWiFiUploadTableViewCell cellWithReuseIdentifier:WiFiCellIdentifier];
  152. } else {
  153. cell = (VLCSidebarViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  154. if (cell == nil)
  155. cell = [[VLCSidebarViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  156. }
  157. if (section == 0) {
  158. if ([rawTitle isEqualToString:@"LIBRARY_ALL_FILES"])
  159. cell.imageView.image = [UIImage imageNamed:@"AllFiles"];
  160. else if ([rawTitle isEqualToString:@"LIBRARY_MUSIC"])
  161. cell.imageView.image = [UIImage imageNamed:@"MusicAlbums"];
  162. else if ([rawTitle isEqualToString:@"LIBRARY_SERIES"])
  163. cell.imageView.image = [UIImage imageNamed:@"TVShowsIcon"];
  164. } else if (section == 1) {
  165. if ([rawTitle isEqualToString:@"LOCAL_NETWORK"])
  166. cell.imageView.image = [UIImage imageNamed:@"Local"];
  167. else if ([rawTitle isEqualToString:@"OPEN_NETWORK"])
  168. cell.imageView.image = [UIImage imageNamed:@"OpenNetStream"];
  169. else if ([rawTitle isEqualToString:@"DOWNLOAD_FROM_HTTP"])
  170. cell.imageView.image = [UIImage imageNamed:@"Downloads"];
  171. else if ([rawTitle isEqualToString:@"WEBINTF_TITLE"]) {
  172. _uploadLocationLabel = [(VLCWiFiUploadTableViewCell*)cell uploadAddressLabel];
  173. _uploadButton = [(VLCWiFiUploadTableViewCell*)cell serverOnButton];
  174. [_uploadButton addTarget:self action:@selector(toggleHTTPServer:) forControlEvents:UIControlEventTouchUpInside];
  175. } else if ([rawTitle isEqualToString:@"CLOUD_SERVICES"])
  176. cell.imageView.image = [UIImage imageNamed:@"iCloudIcon"];
  177. } else if (section == 2) {
  178. if ([rawTitle isEqualToString:@"Settings"])
  179. cell.imageView.image = [UIImage imageNamed:@"Settings"];
  180. else
  181. cell.imageView.image = [UIImage imageNamed:@"menuCone"];
  182. }
  183. if (![rawTitle isEqualToString:@"WEBINTF_TITLE"])
  184. cell.textLabel.text = NSLocalizedString(rawTitle, nil);
  185. return cell;
  186. }
  187. #pragma mark - table view delegation
  188. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
  189. {
  190. if (section < 3)
  191. return 21.f;
  192. return 0.;
  193. }
  194. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
  195. {
  196. NSObject *headerText = NSLocalizedString(_sectionHeaderTexts[section], nil);
  197. UIView *headerView = nil;
  198. if (headerText != [NSNull null]) {
  199. headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [UIScreen mainScreen].bounds.size.height, 21.0f)];
  200. headerView.backgroundColor = [UIColor VLCDarkBackgroundColor];
  201. UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectInset(headerView.bounds, 12.0f, 5.0f)];
  202. textLabel.text = (NSString *) headerText;
  203. textLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:([UIFont systemFontSize] * 0.8f)];
  204. textLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
  205. textLabel.shadowColor = [UIColor VLCDarkTextShadowColor];
  206. textLabel.textColor = [UIColor colorWithRed:(118.0f/255.0f) green:(118.0f/255.0f) blue:(118.0f/255.0f) alpha:1.0f];
  207. textLabel.backgroundColor = [UIColor clearColor];
  208. [headerView addSubview:textLabel];
  209. UIView *topLine = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [UIScreen mainScreen].bounds.size.height, 1.0f)];
  210. topLine.backgroundColor = [UIColor colorWithRed:(95.0f/255.0f) green:(95.0f/255.0f) blue:(95.0f/255.0f) alpha:1.0f];
  211. [headerView addSubview:topLine];
  212. UIView *bottomLine = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 21.0f, [UIScreen mainScreen].bounds.size.height, 1.0f)];
  213. bottomLine.backgroundColor = [UIColor colorWithRed:(16.0f/255.0f) green:(16.0f/255.0f) blue:(16.0f/255.0f) alpha:1.0f];
  214. [headerView addSubview:bottomLine];
  215. }
  216. return headerView;
  217. }
  218. #pragma mark - menu implementation
  219. - (void)updateHTTPServerAddress
  220. {
  221. VLCHTTPUploaderController *uploadController = [VLCHTTPUploaderController sharedInstance];
  222. HTTPServer *server = uploadController.httpServer;
  223. if (server.isRunning) {
  224. _uploadLocationLabel.numberOfLines = 0;
  225. if (server.listeningPort != 80)
  226. _uploadLocationLabel.text = [NSString stringWithFormat:@"http://%@:%i\nhttp://%@:%i", [uploadController currentIPAddress], server.listeningPort, [uploadController hostname], server.listeningPort];
  227. else
  228. _uploadLocationLabel.text = [NSString stringWithFormat:@"http://%@\nhttp://%@", [uploadController currentIPAddress], [uploadController hostname]];
  229. [_uploadButton setImage:[UIImage imageNamed:@"WifiUpOn"] forState:UIControlStateNormal];
  230. } else {
  231. _uploadLocationLabel.text = NSLocalizedString(@"HTTP_UPLOAD_SERVER_OFF", nil);
  232. [_uploadButton setImage:[UIImage imageNamed:@"WifiUp"] forState:UIControlStateNormal];
  233. }
  234. }
  235. - (IBAction)toggleHTTPServer:(UIButton *)sender
  236. {
  237. if (_uploadButton.enabled) {
  238. VLCHTTPUploaderController *uploadController = [VLCHTTPUploaderController sharedInstance];
  239. BOOL futureHTTPServerState = !uploadController.httpServer.isRunning;
  240. [[NSUserDefaults standardUserDefaults] setBool:futureHTTPServerState forKey:kVLCSettingSaveHTTPUploadServerStatus];
  241. [uploadController changeHTTPServerState:futureHTTPServerState];
  242. [self updateHTTPServerAddress];
  243. [[NSUserDefaults standardUserDefaults] synchronize];
  244. }
  245. }
  246. - (void)_revealItem:(NSUInteger)itemIndex inSection:(NSUInteger)sectionNumber
  247. {
  248. UIViewController *viewController;
  249. VLCAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
  250. if (sectionNumber == 1) {
  251. if (itemIndex == 0)
  252. viewController = [[VLCServerListViewController alloc] init];
  253. else if (itemIndex == 1) {
  254. viewController = [[VLCOpenNetworkStreamViewController alloc] initWithNibName:@"VLCOpenNetworkStreamViewController" bundle:nil];
  255. } else if (itemIndex == 2)
  256. viewController = [VLCDownloadViewController sharedInstance];
  257. else if (itemIndex == 3)
  258. [self toggleHTTPServer:nil];
  259. else if (itemIndex == 4)
  260. viewController = [[VLCCloudServicesTableViewController alloc] initWithNibName:@"VLCCloudServicesTableViewController" bundle:nil];
  261. } else if (sectionNumber == 2) {
  262. if (itemIndex == 0) {
  263. if (!self.settingsController)
  264. self.settingsController = [[VLCSettingsController alloc] init];
  265. VLCSettingsController *settingsController = self.settingsController;
  266. if (!self.settingsViewController) {
  267. self.settingsViewController = [[IASKAppSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
  268. settingsController.viewController = self.settingsViewController;
  269. self.settingsViewController.navigationItem.leftBarButtonItem = [UIBarButtonItem themedRevealMenuButtonWithTarget:self.settingsController.viewController andSelector:@selector(dismiss:)];
  270. }
  271. _hiddenSettingKeys = [[NSMutableSet alloc] init];
  272. IASKAppSettingsViewController *settingsVC = self.settingsViewController;
  273. settingsVC.modalPresentationStyle = UIModalPresentationFormSheet;
  274. settingsVC.delegate = self.settingsController;
  275. settingsVC.showDoneButton = NO;
  276. settingsVC.showCreditsFooter = NO;
  277. if (![[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingPlaybackGestures] boolValue])
  278. [_hiddenSettingKeys addObject:@"EnableVariableJumpDuration"];
  279. [self.settingsController.viewController setHiddenKeys:_hiddenSettingKeys];
  280. viewController = settingsVC;
  281. } else if (itemIndex == 1)
  282. viewController = [[VLCAboutViewController alloc] init];
  283. } else {
  284. viewController = appDelegate.playlistViewController;
  285. [(VLCPlaylistViewController *)viewController setLibraryMode:(int)itemIndex];
  286. }
  287. if (!viewController)
  288. return;
  289. VLCSidebarController *sidebarController = [VLCSidebarController sharedInstance];
  290. if ([sidebarController.contentViewController isKindOfClass:[UINavigationController class]]) {
  291. UINavigationController *navCon = (UINavigationController*)sidebarController.contentViewController;
  292. navCon.viewControllers = @[viewController];
  293. } else
  294. sidebarController.contentViewController = [[VLCNavigationController alloc] initWithRootViewController:viewController];
  295. [sidebarController hideSidebar];
  296. }
  297. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  298. {
  299. [self _revealItem:indexPath.row inSection:indexPath.section];
  300. }
  301. #pragma mark Public Methods
  302. - (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition
  303. {
  304. UITableView *tableView = self.tableView;
  305. [tableView selectRowAtIndexPath:indexPath animated:animated scrollPosition:scrollPosition];
  306. if (scrollPosition == UITableViewScrollPositionNone)
  307. [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
  308. [self _revealItem:indexPath.row inSection:indexPath.section];
  309. }
  310. #pragma mark - shake for support
  311. - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
  312. {
  313. if (motion == UIEventSubtypeMotionShake)
  314. [[VLCBugreporter sharedInstance] handleBugreportRequest];
  315. }
  316. @end