Browse Source

remote playback: split item deletion code into separate parent class

Felix Paul Kühne 9 years ago
parent
commit
5a3acda92e

+ 21 - 0
Apple-TV/VLCDeletionCapableViewController.h

@@ -0,0 +1,21 @@
+/*****************************************************************************
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Tobias Conradi <videolan # tobias-conradi.de>
+ *          Felix Paul Kühne <fkuehne # videolan.org>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+@interface VLCDeletionCapableViewController : UIViewController
+
+@property (nonatomic, weak) IBOutlet UIView *deleteHintView;
+@property (nonatomic, readonly, nullable) NSIndexPath *indexPathToDelete;
+@property (nonatomic, readonly, nullable) NSString *itemToDelete;
+
+@end

+ 143 - 0
Apple-TV/VLCDeletionCapableViewController.m

@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Tobias Conradi <videolan # tobias-conradi.de>
+ *          Felix Paul Kühne <fkuehne # videolan.org>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+#import "VLCDeletionCapableViewController.h"
+
+@interface VLCDeletionCapableViewController ()
+@property (nonatomic) UITapGestureRecognizer *playPausePressRecognizer;
+@property (nonatomic) UITapGestureRecognizer *cancelRecognizer;
+@property (nonatomic) NSIndexPath *currentlyFocusedIndexPath;
+@property (nonatomic) NSTimer *hintTimer;
+
+@end
+
+@implementation VLCDeletionCapableViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+
+    UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(startEditMode)];
+    recognizer.allowedPressTypes = @[@(UIPressTypeSelect)];
+    recognizer.minimumPressDuration = 1.0;
+    [self.view addGestureRecognizer:recognizer];
+
+    UITapGestureRecognizer *cancelRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(endEditMode)];
+    cancelRecognizer.allowedPressTypes = @[@(UIPressTypeSelect),@(UIPressTypeMenu)];
+    self.cancelRecognizer = cancelRecognizer;
+    [self.view addGestureRecognizer:cancelRecognizer];
+
+    UITapGestureRecognizer *playPauseRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handlePlayPausePress)];
+    playPauseRecognizer.allowedPressTypes = @[@(UIPressTypePlayPause)];
+    self.playPausePressRecognizer = playPauseRecognizer;
+    [self.view addGestureRecognizer:playPauseRecognizer];
+}
+
+- (void)handlePlayPausePress
+{
+    NSString *fileToDelete = self.itemToDelete;
+    if (fileToDelete == nil)
+        return;
+    NSIndexPath *indexPathToDelete = self.indexPathToDelete;
+
+    NSString *title = fileToDelete.lastPathComponent;
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
+                                                                             message:nil
+                                                                      preferredStyle:UIAlertControllerStyleAlert];
+    UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_DELETE", nil)
+                                                           style:UIAlertActionStyleDestructive
+                                                         handler:^(UIAlertAction * _Nonnull action) {
+                                                             [self deleteFileAtIndex:indexPathToDelete];
+                                                         }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)
+                                                           style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+                                                               self.editing = NO;
+                                                           }];
+
+    [alertController addAction:deleteAction];
+    [alertController addAction:cancelAction];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)deleteFileAtIndex:(NSIndexPath *)indexPathToDelete
+{
+    // NO-OP, implemented by subclass
+}
+
+- (void)animateDeletHintToVisibility:(BOOL)visible
+{
+    const NSTimeInterval duration = 0.5;
+
+    UIView *hintView = self.deleteHintView;
+
+    if (hintView.hidden) {
+        hintView.alpha = 0.0;
+    }
+
+    if (hintView.alpha == 0.0) {
+        hintView.hidden = NO;
+    }
+
+    const CGFloat targetAlpha = visible ? 1.0 : 0.0;
+    [UIView animateWithDuration:duration
+                          delay:0
+                        options:UIViewAnimationOptionBeginFromCurrentState
+                     animations:^{
+                         hintView.alpha = targetAlpha;
+                     }
+                     completion:^(BOOL finished) {
+                         if (hintView.alpha == 0.0) {
+                             hintView.hidden = YES;
+                         }
+                     }];
+}
+
+- (void)hintTimerFired:(NSTimer *)timer
+{
+    const NSTimeInterval waitUntilHideInterval = 5.0;
+
+    NSNumber *userInfo = [timer userInfo];
+    BOOL shouldShow = [userInfo isKindOfClass:[NSNumber class]] && [userInfo boolValue];
+    [self animateDeletHintToVisibility:shouldShow];
+    if (shouldShow) {
+        [self.hintTimer invalidate];
+        self.hintTimer = [NSTimer scheduledTimerWithTimeInterval:waitUntilHideInterval target:self selector:@selector(hintTimerFired:) userInfo:@(NO) repeats:NO];
+    }
+}
+
+- (void)startEditMode
+{
+    self.editing = YES;
+}
+- (void)endEditMode
+{
+    self.editing = NO;
+}
+
+- (void)setEditing:(BOOL)editing
+{
+    [super setEditing:editing];
+
+    if (editing) {
+        [self.hintTimer invalidate];
+        self.hintTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(hintTimerFired:) userInfo:@(YES) repeats:NO];
+    } else {
+        [self.hintTimer invalidate];
+        self.hintTimer = nil;
+        [self animateDeletHintToVisibility:NO];
+    }
+
+    self.cancelRecognizer.enabled = editing;
+    self.playPausePressRecognizer.enabled = editing;
+}
+
+@end

+ 2 - 3
Apple-TV/VLCRemotePlaybackViewController.h

@@ -10,9 +10,9 @@
  *****************************************************************************/
 
 #import <UIKit/UIKit.h>
-#import "VLCRemoteBrowsingCollectionViewController.h"
+#import "VLCDeletionCapableViewController.h"
 
-@interface VLCRemotePlaybackViewController : UIViewController
+@interface VLCRemotePlaybackViewController : VLCDeletionCapableViewController
 
 @property (readwrite, nonatomic, weak) IBOutlet UILabel *httpServerLabel;
 @property (readwrite, nonatomic, weak) IBOutlet UIButton *toggleHTTPServerButton;
@@ -20,7 +20,6 @@
 @property (readwrite, nonatomic, weak) IBOutlet UILabel *cachedMediaLabel;
 @property (readwrite, nonatomic, weak) IBOutlet UILabel *cachedMediaLongLabel;
 @property (readwrite, nonatomic, weak) IBOutlet UICollectionView *cachedMediaCollectionView;
-@property (nonatomic, weak) IBOutlet UIView *deleteHintView;
 
 - (IBAction)toggleHTTPServer:(id)sender;
 

+ 53 - 142
Apple-TV/VLCRemotePlaybackViewController.m

@@ -27,10 +27,7 @@ static NSString *const VLCWiggleAnimationKey = @"VLCWiggleAnimation";
     Reachability *_reachability;
     NSMutableArray<NSString *> *_discoveredFiles;
 }
-@property (nonatomic) UITapGestureRecognizer *playPausePressRecognizer;
-@property (nonatomic) UITapGestureRecognizer *cancelRecognizer;
 @property (nonatomic) NSIndexPath *currentlyFocusedIndexPath;
-@property (nonatomic) NSTimer *hintTimer;
 
 @end
 
@@ -72,21 +69,6 @@ static NSString *const VLCWiggleAnimationKey = @"VLCWiggleAnimation";
     [discoverer addObserver:self];
     [discoverer startDiscovering];
 
-    UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(startEditMode)];
-    recognizer.allowedPressTypes = @[@(UIPressTypeSelect)];
-    recognizer.minimumPressDuration = 1.0;
-    [self.view addGestureRecognizer:recognizer];
-
-    UITapGestureRecognizer *cancelRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(endEditMode)];
-    cancelRecognizer.allowedPressTypes = @[@(UIPressTypeSelect),@(UIPressTypeMenu)];
-    self.cancelRecognizer = cancelRecognizer;
-    [self.view addGestureRecognizer:cancelRecognizer];
-
-    UITapGestureRecognizer *playPauseRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handlePlayPausePress)];
-    playPauseRecognizer.allowedPressTypes = @[@(UIPressTypePlayPause)];
-    self.playPausePressRecognizer = playPauseRecognizer;
-    [self.view addGestureRecognizer:playPauseRecognizer];
-
     self.cachedMediaLabel.text = NSLocalizedString(@"CACHED_MEDIA", nil);
     self.cachedMediaLongLabel.text = NSLocalizedString(@"CACHED_MEDIA_LONG", nil);
 }
@@ -159,130 +141,6 @@ static NSString *const VLCWiggleAnimationKey = @"VLCWiggleAnimation";
     [[NSUserDefaults standardUserDefaults] synchronize];
 }
 
-#pragma mark - editing
-
-- (void)handlePlayPausePress
-{
-    NSIndexPath *indexPathToDelete = self.currentlyFocusedIndexPath;
-    if (!indexPathToDelete) {
-        return;
-    }
-    NSString *fileToDelete = nil;
-    @synchronized(_discoveredFiles) {
-        fileToDelete = _discoveredFiles[indexPathToDelete.item];
-    }
-
-    NSString *title = fileToDelete.lastPathComponent;
-    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
-                                                                             message:nil
-                                                                      preferredStyle:UIAlertControllerStyleAlert];
-    UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_DELETE", nil)
-                                                           style:UIAlertActionStyleDestructive
-                                                         handler:^(UIAlertAction * _Nonnull action) {
-                                                             [self deleteFileAtIndex:indexPathToDelete];
-                                                         }];
-    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)
-                                                           style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
-                                                               self.editing = NO;
-                                                           }];
-
-    [alertController addAction:deleteAction];
-    [alertController addAction:cancelAction];
-    [self presentViewController:alertController animated:YES completion:nil];
-}
-
-- (void)deleteFileAtIndex:(NSIndexPath *)indexPathToDelete
-{
-    if (!indexPathToDelete) {
-        return;
-    }
-    __block NSString *fileToDelete = nil;
-    [self.cachedMediaCollectionView performBatchUpdates:^{
-        @synchronized(_discoveredFiles) {
-            fileToDelete = _discoveredFiles[indexPathToDelete.item];
-            [_discoveredFiles removeObject:fileToDelete];
-        }
-        [self.cachedMediaCollectionView deleteItemsAtIndexPaths:@[indexPathToDelete]];
-
-    } completion:^(BOOL finished) {
-        [[NSFileManager defaultManager] removeItemAtPath:fileToDelete error:nil];
-        self.editing = NO;
-    }];
-
-}
-
-- (void)animateDeletHintToVisibility:(BOOL)visible
-{
-    const NSTimeInterval duration = 0.5;
-
-    UIView *hintView = self.deleteHintView;
-
-    if (hintView.hidden) {
-        hintView.alpha = 0.0;
-    }
-
-    if (hintView.alpha == 0.0) {
-        hintView.hidden = NO;
-    }
-
-    const CGFloat targetAlpha = visible ? 1.0 : 0.0;
-    [UIView animateWithDuration:duration
-                          delay:0
-                        options:UIViewAnimationOptionBeginFromCurrentState
-                     animations:^{
-                         hintView.alpha = targetAlpha;
-                     }
-                     completion:^(BOOL finished) {
-                         if (hintView.alpha == 0.0) {
-                             hintView.hidden = YES;
-                         }
-                     }];
-}
-
-- (void)hintTimerFired:(NSTimer *)timer
-{
-    const NSTimeInterval waitUntilHideInterval = 5.0;
-
-    NSNumber *userInfo = [timer userInfo];
-    BOOL shouldShow = [userInfo isKindOfClass:[NSNumber class]] && [userInfo boolValue];
-    [self animateDeletHintToVisibility:shouldShow];
-    if (shouldShow) {
-        [self.hintTimer invalidate];
-        self.hintTimer = [NSTimer scheduledTimerWithTimeInterval:waitUntilHideInterval target:self selector:@selector(hintTimerFired:) userInfo:@(NO) repeats:NO];
-    }
-}
-
-- (void)startEditMode
-{
-    self.editing = YES;
-}
-- (void)endEditMode
-{
-    self.editing = NO;
-}
-
-- (void)setEditing:(BOOL)editing
-{
-    [super setEditing:editing];
-
-    UICollectionViewCell *focusedCell = [self.cachedMediaCollectionView cellForItemAtIndexPath:self.currentlyFocusedIndexPath];
-
-    if (editing) {
-        [focusedCell.layer addAnimation:[CAAnimation vlc_wiggleAnimation]
-                                 forKey:VLCWiggleAnimationKey];
-        [self.hintTimer invalidate];
-        self.hintTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(hintTimerFired:) userInfo:@(YES) repeats:NO];
-    } else {
-        [focusedCell.layer removeAnimationForKey:VLCWiggleAnimationKey];
-        [self.hintTimer invalidate];
-        self.hintTimer = nil;
-        [self animateDeletHintToVisibility:NO];
-    }
-
-    self.cancelRecognizer.enabled = editing;
-    self.playPausePressRecognizer.enabled = editing;
-}
-
 #pragma mark - collection view data source
 
 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
@@ -339,6 +197,59 @@ static NSString *const VLCWiggleAnimationKey = @"VLCWiggleAnimation";
     self.currentlyFocusedIndexPath = nextPath;
 }
 
+#pragma mark - editing
+
+- (NSIndexPath *)indexPathToDelete
+{
+    NSIndexPath *indexPathToDelete = self.currentlyFocusedIndexPath;
+    return indexPathToDelete;
+}
+
+- (NSString *)itemToDelete
+{
+    NSIndexPath *indexPathToDelete = self.indexPathToDelete;
+    if (!indexPathToDelete) {
+        return nil;
+    }
+
+    NSString *ret;
+    @synchronized(_discoveredFiles) {
+        ret = _discoveredFiles[indexPathToDelete.item];
+    }
+    return ret;
+}
+
+- (void)setEditing:(BOOL)editing
+{
+    [super setEditing:editing];
+
+    UICollectionViewCell *focusedCell = [self.cachedMediaCollectionView cellForItemAtIndexPath:self.currentlyFocusedIndexPath];
+    if (editing) {
+        [focusedCell.layer addAnimation:[CAAnimation vlc_wiggleAnimation]
+                                 forKey:VLCWiggleAnimationKey];
+    } else {
+        [focusedCell.layer removeAnimationForKey:VLCWiggleAnimationKey];
+    }
+}
+
+- (void)deleteFileAtIndex:(NSIndexPath *)indexPathToDelete
+{
+    if (!indexPathToDelete) {
+        return;
+    }
+    __block NSString *fileToDelete = nil;
+    [self.cachedMediaCollectionView performBatchUpdates:^{
+        @synchronized(_discoveredFiles) {
+            fileToDelete = _discoveredFiles[indexPathToDelete.item];
+            [_discoveredFiles removeObject:fileToDelete];
+        }
+        [self.cachedMediaCollectionView deleteItemsAtIndexPaths:@[indexPathToDelete]];
+    } completion:^(BOOL finished) {
+        [[NSFileManager defaultManager] removeItemAtPath:fileToDelete error:nil];
+        self.editing = NO;
+    }];
+}
+
 #pragma mark - collection view delegate
 
 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

+ 6 - 0
VLC for iOS.xcodeproj/project.pbxproj

@@ -161,6 +161,7 @@
 		7D5CAA8C1A4AD8E5003F2CBC /* VLCTrackSelectorHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D5CAA8B1A4AD8E5003F2CBC /* VLCTrackSelectorHeaderView.m */; };
 		7D5DD5C717590ABF001421E3 /* About Contents.html in Resources */ = {isa = PBXBuildFile; fileRef = 7D5DD5C617590ABF001421E3 /* About Contents.html */; };
 		7D6069691BD92E6900AB765C /* libSDropboxSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D5278CD1BD7DE3D00D0CA0E /* libSDropboxSDK.a */; };
+		7D62621A1C18AECD00F7CB24 /* VLCDeletionCapableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D6262191C18AECD00F7CB24 /* VLCDeletionCapableViewController.m */; };
 		7D63C19018774B1700BD5256 /* VLCFirstStepsSecondPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D63C18E18774B1700BD5256 /* VLCFirstStepsSecondPageViewController.m */; };
 		7D63C19518774E0100BD5256 /* VLCFirstStepsThirdPageViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D63C19418774E0100BD5256 /* VLCFirstStepsThirdPageViewController~ipad.xib */; };
 		7D63C19718774F1000BD5256 /* VLCFirstStepsFourthPageViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D63C19618774F1000BD5256 /* VLCFirstStepsFourthPageViewController~ipad.xib */; };
@@ -1046,6 +1047,8 @@
 		7D5CAA8A1A4AD8E5003F2CBC /* VLCTrackSelectorHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCTrackSelectorHeaderView.h; path = Sources/VLCTrackSelectorHeaderView.h; sourceTree = SOURCE_ROOT; };
 		7D5CAA8B1A4AD8E5003F2CBC /* VLCTrackSelectorHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCTrackSelectorHeaderView.m; path = Sources/VLCTrackSelectorHeaderView.m; sourceTree = SOURCE_ROOT; };
 		7D5DD5C617590ABF001421E3 /* About Contents.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "About Contents.html"; sourceTree = "<group>"; };
+		7D6262181C18AECD00F7CB24 /* VLCDeletionCapableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCDeletionCapableViewController.h; sourceTree = "<group>"; };
+		7D6262191C18AECD00F7CB24 /* VLCDeletionCapableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCDeletionCapableViewController.m; sourceTree = "<group>"; };
 		7D62C8A51C08B512007A6EF3 /* HockeySDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HockeySDK.framework; path = "ImportedSources/HockeySDK-tvOS/Support/build/Debug-appletvos/HockeySDK.framework"; sourceTree = "<group>"; };
 		7D62C8AB1C08B874007A6EF3 /* libHockeySDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libHockeySDK.a; path = "ImportedSources/HockeySDK-tvOS/Support/build/Debug-appletvos/libHockeySDK.a"; sourceTree = "<group>"; };
 		7D62C9271C08B9C7007A6EF3 /* CrashReporter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CrashReporter.framework; path = "ImportedSources/HockeySDK-tvOS/Vendor/CrashReporter.framework"; sourceTree = "<group>"; };
@@ -2332,6 +2335,8 @@
 				7D1A2DB01BF66335002E0962 /* VLCMDFBrowsingArtworkProvider.m */,
 				DD9D8F5D1C00C73F00B4060F /* VLCDeleteHintTVView.h */,
 				DD9D8F5E1C00C73F00B4060F /* VLCDeleteHintTVView.m */,
+				7D6262181C18AECD00F7CB24 /* VLCDeletionCapableViewController.h */,
+				7D6262191C18AECD00F7CB24 /* VLCDeletionCapableViewController.m */,
 			);
 			name = "Common Code";
 			sourceTree = "<group>";
@@ -3411,6 +3416,7 @@
 				7D1334801BE132F10012E919 /* VLCNetworkServerBrowserUPnP.m in Sources */,
 				DD4089FA1BF659030022745E /* VLCPlaybackInfoTVCollectionSectionTitleView.m in Sources */,
 				7DF383D01BF24BB100D71A5C /* VLCBoxCollectionViewController.m in Sources */,
+				7D62621A1C18AECD00F7CB24 /* VLCDeletionCapableViewController.m in Sources */,
 				DDEAECC71BDEC79D00756C83 /* VLCLocalNetworkServiceBrowserSAP.m in Sources */,
 				7D1329441BA1F10100BE647E /* AppleTVAppDelegate.m in Sources */,
 				7D1329411BA1F10100BE647E /* main.m in Sources */,