123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /*****************************************************************************
- * VLCOpenNetworkStreamViewController.m
- * VLC for iOS
- *****************************************************************************
- * Copyright (c) 2013 VideoLAN. All rights reserved.
- * $Id$
- *
- * Authors: Felix Paul Kühne <fkuehne # videolan.org>
- * Gleb Pinigin <gpinigin # gmail.com>
- * Pierre Sagaspe <pierre.sagaspe # me.com>
- *
- * Refer to the COPYING file of the official project for license.
- *****************************************************************************/
- #import "VLCOpenNetworkStreamViewController.h"
- #import "VLCPlaybackController.h"
- #import "VLCLibraryViewController.h"
- #import "VLCMenuTableViewController.h"
- #import "UIDevice+VLC.h"
- @interface VLCOpenNetworkStreamViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
- {
- NSMutableArray *_recentURLs;
- }
- @end
- @implementation VLCOpenNetworkStreamViewController
- + (void)initialize
- {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSDictionary *appDefaults = @{kVLCRecentURLs : @[], kVLCPrivateWebStreaming : @(NO)};
- [defaults registerDefaults:appDefaults];
- }
- - (void)applicationDidBecomeActive:(NSNotification *)notification
- {
- [self updatePasteboardTextInURLField];
- }
- - (void)dealloc
- {
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:UIApplicationDidBecomeActiveNotification
- object:[UIApplication sharedApplication]];
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- /*
- * Observe changes to the pasteboard so we can automatically paste it into the URL field.
- * Do not use UIPasteboardChangedNotification because we have copy actions that will trigger it on this screen.
- * Instead when the user comes back to the application from the background (or the inactive state by pulling down notification center), update the URL field.
- * Using the 'active' rather than 'foreground' notification for future proofing if iOS ever allows running multiple apps on the same screen (which would allow the pasteboard to be changed without truly backgrounding the app).
- */
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationDidBecomeActive:)
- name:UIApplicationDidBecomeActiveNotification
- object:[UIApplication sharedApplication]];
- [self.openButton setTitle:NSLocalizedString(@"OPEN_NETWORK", nil) forState:UIControlStateNormal];
- [self.privateModeLabel setText:NSLocalizedString(@"PRIVATE_PLAYBACK_TOGGLE", nil)];
- [self.ScanSubModeLabel setText:NSLocalizedString(@"SCAN_SUBTITLE_TOGGLE", nil)];
- [self.ScanSubModeLabel setAdjustsFontSizeToFitWidth:YES];
- [self.ScanSubModeLabel setNumberOfLines:0];
- self.title = NSLocalizedString(@"OPEN_NETWORK", nil);
- self.navigationItem.leftBarButtonItem = [UIBarButtonItem themedRevealMenuButtonWithTarget:self andSelector:@selector(goBack:)];
- [self.whatToOpenHelpLabel setText:NSLocalizedString(@"OPEN_NETWORK_HELP", nil)];
- self.urlField.delegate = self;
- self.urlField.keyboardType = UIKeyboardTypeURL;
- self.historyTableView.backgroundColor = [UIColor VLCDarkBackgroundColor];
- NSAttributedString *coloredAttributedPlaceholder = [[NSAttributedString alloc] initWithString:@"http://myserver.com/file.mkv" attributes:@{NSForegroundColorAttributeName: [UIColor VLCLightTextColor]}];
- self.urlField.attributedPlaceholder = coloredAttributedPlaceholder;
- self.edgesForExtendedLayout = UIRectEdgeNone;
- // This will be called every time this VC is opened by the side menu controller
- [self updatePasteboardTextInURLField];
- }
- - (void)updatePasteboardTextInURLField
- {
- UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
- if ([pasteboard containsPasteboardTypes:@[@"public.url"]])
- self.urlField.text = [[pasteboard valueForPasteboardType:@"public.url"] absoluteString];
- }
- - (void)viewWillAppear:(BOOL)animated
- {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- _recentURLs = [NSMutableArray arrayWithArray:[defaults objectForKey:kVLCRecentURLs]];
- self.privateToggleSwitch.on = [defaults boolForKey:kVLCPrivateWebStreaming];
- self.ScanSubToggleSwitch.on = [defaults boolForKey:kVLChttpScanSubtitle];
- [super viewWillAppear:animated];
- }
- - (void)viewWillDisappear:(BOOL)animated
- {
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:UIApplicationDidBecomeActiveNotification
- object:[UIApplication sharedApplication]];
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:[NSArray arrayWithArray:_recentURLs] forKey:kVLCRecentURLs];
- [defaults setBool:self.privateToggleSwitch.on forKey:kVLCPrivateWebStreaming];
- [defaults setBool:self.ScanSubToggleSwitch.on forKey:kVLChttpScanSubtitle];
- [defaults synchronize];
- [super viewWillDisappear:animated];
- }
- - (CGSize)contentSizeForViewInPopover {
- return [self.view sizeThatFits:CGSizeMake(320, 800)];
- }
- #pragma mark - UI interaction
- - (BOOL)shouldAutorotate
- {
- UIInterfaceOrientation toInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
- return NO;
- return YES;
- }
- - (IBAction)goBack:(id)sender
- {
- [self.view endEditing:YES];
- [[VLCSidebarController sharedInstance] toggleSidebar];
- }
- - (IBAction)openButtonAction:(id)sender
- {
- if ([self.urlField.text length] > 0) {
- if (!self.privateToggleSwitch.on) {
- if ([_recentURLs indexOfObject:self.urlField.text] != NSNotFound)
- [_recentURLs removeObject:self.urlField.text];
- if (_recentURLs.count >= 100)
- [_recentURLs removeLastObject];
- [_recentURLs addObject:self.urlField.text];
- [self.historyTableView reloadData];
- }
- [self _openURLStringAndDismiss:self.urlField.text];
- }
- }
- #pragma mark - table view data source
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- {
- return 1;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- {
- return _recentURLs.count;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"StreamingHistoryCell";
- UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
- cell.textLabel.textColor = [UIColor whiteColor];
- cell.textLabel.highlightedTextColor = [UIColor blackColor];
- cell.detailTextLabel.textColor = [UIColor VLCLightTextColor];
- cell.detailTextLabel.highlightedTextColor = [UIColor blackColor];
- }
- NSInteger row = indexPath.row;
- cell.textLabel.text = [_recentURLs[row] lastPathComponent];
- cell.detailTextLabel.text = _recentURLs[row];
- return cell;
- }
- #pragma mark - table view delegate
- - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
- {
- cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor VLCDarkBackgroundColor];
- }
- - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
- {
- return YES;
- }
- - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
- {
- if (editingStyle == UITableViewCellEditingStyleDelete) {
- [_recentURLs removeObjectAtIndex:indexPath.row];
- [tableView reloadData];
- }
- }
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- {
- [self _openURLStringAndDismiss:_recentURLs[indexPath.row]];
- [self.historyTableView deselectRowAtIndexPath:indexPath animated:NO];
- }
- - (void)tableView:(UITableView *)tableView
- performAction:(SEL)action
- forRowAtIndexPath:(NSIndexPath *)indexPath
- withSender:(id)sender
- {
- NSString *actionText = NSStringFromSelector(action);
- if ([actionText isEqualToString:@"copy:"])
- {
- [UIPasteboard generalPasteboard].string = _recentURLs[indexPath.row];
- }
- }
- - (BOOL)tableView:(UITableView *)tableView
- canPerformAction:(SEL)action
- forRowAtIndexPath:(NSIndexPath *)indexPath
- withSender:(id)sender
- {
- NSString *actionText = NSStringFromSelector(action);
- if ([actionText isEqualToString:@"copy:"])
- {
- return YES;
- }
- return NO;
- }
- - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- return YES;
- }
- #pragma mark - internals
- - (void)_openURLStringAndDismiss:(NSString *)url
- {
- NSURL *URLscheme = [NSURL URLWithString:url];
- NSString *URLofSubtitle = nil;
- if ([URLscheme.scheme isEqualToString:@"http"])
- if (self.ScanSubToggleSwitch.on)
- URLofSubtitle = [self _checkURLofSubtitle:url];
- VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
- [vpc playURL:[NSURL URLWithString:url] subtitlesFilePath:URLofSubtitle];
- }
- - (NSString *)_checkURLofSubtitle:(NSString *)url
- {
- NSString *subtitleFileExtensions = kSupportedSubtitleFileExtensions;
- NSCharacterSet *characterFilter = [NSCharacterSet characterSetWithCharactersInString:@"\\.():$"];
- subtitleFileExtensions = [[subtitleFileExtensions componentsSeparatedByCharactersInSet:characterFilter] componentsJoinedByString:@""];
- NSArray *arraySubtitleFileExtensions = [subtitleFileExtensions componentsSeparatedByString:@"|"];
- NSString *urlTemp = [[url stringByDeletingPathExtension] stringByAppendingString:@"."];
- for (int cnt = 0; cnt < arraySubtitleFileExtensions.count; cnt++) {
- NSString *checkAddress = [urlTemp stringByAppendingString:arraySubtitleFileExtensions[cnt]];
- NSURL *checkURL = [NSURL URLWithString:checkAddress];
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:checkURL];
- request.HTTPMethod = @"HEAD";
- NSURLResponse *response = nil;
- [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
- NSInteger httpStatus = [(NSHTTPURLResponse *)response statusCode];
- if (httpStatus == 200) {
- NSString *fileSubtitlePath = [self _getFileSubtitleFromServer:checkURL];
- return fileSubtitlePath;
- }
- }
- return nil;
- }
- - (NSString *)_getFileSubtitleFromServer:(NSURL *)url
- {
- NSString *FileSubtitlePath = nil;
- NSString *fileName = [[url path] lastPathComponent];
- NSData *receivedSub = [NSData dataWithContentsOfURL:url];
- if (receivedSub.length < [[UIDevice currentDevice] freeDiskspace].longLongValue) {
- NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
- NSString *directoryPath = [searchPaths objectAtIndex:0];
- FileSubtitlePath = [directoryPath stringByAppendingPathComponent:fileName];
- NSFileManager *fileManager = [NSFileManager defaultManager];
- if (![fileManager fileExistsAtPath:FileSubtitlePath]) {
- [fileManager createFileAtPath:FileSubtitlePath contents:nil attributes:nil];
- if (![fileManager fileExistsAtPath:FileSubtitlePath])
- APLog(@"file creation failed, no data was saved");
- }
- [receivedSub writeToFile:FileSubtitlePath atomically:YES];
- } else {
- VLCAlertView *alert = [[VLCAlertView alloc] initWithTitle:NSLocalizedString(@"DISK_FULL", nil)
- message:[NSString stringWithFormat:NSLocalizedString(@"DISK_FULL_FORMAT", nil), fileName, [[UIDevice currentDevice] model]]
- delegate:self
- cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
- otherButtonTitles:nil];
- [alert show];
- }
- return FileSubtitlePath;
- }
- #pragma mark - text view delegate
- - (BOOL)textFieldShouldReturn:(UITextField *)textField
- {
- [self.urlField resignFirstResponder];
- return NO;
- }
- @end
|