Commit 498fc2c0 authored by Felix Paul Kühne's avatar Felix Paul Kühne

playlist: implement album listing and playback (phone form factor only for now)

parent 6b3a9a43
......@@ -62,7 +62,10 @@
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
_sectionHeaderTexts = @[@"SECTION_HEADER_LIBRARY", @"SECTION_HEADER_NETWORK", @"Settings"];
_menuItemsSectionOne = @[@"LIBRARY_ALL_FILES"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
_menuItemsSectionOne = @[@"LIBRARY_ALL_FILES", @"LIBRARY_MUSIC"];
else
_menuItemsSectionOne = @[@"LIBRARY_ALL_FILES"];
_menuItemsSectionTwo = @[@"LOCAL_NETWORK", @"OPEN_NETWORK", @"DOWNLOAD_FROM_HTTP", @"WiFi Upload", @"Dropbox"];
_menuItemsSectionThree = @[@"Settings", @"ABOUT_APP"];
......@@ -134,11 +137,11 @@
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) // media
return 1;
return _menuItemsSectionOne.count;
else if (section == 1) // network
return 5;
return _menuItemsSectionTwo.count;
else if (section == 2) // settings & co
return 2;
return _menuItemsSectionThree.count;
else
return 0;
}
......@@ -280,8 +283,10 @@
viewController = self.settingsController.viewController;
} else if (itemIndex == 1)
viewController = [[VLCAboutViewController alloc] init];
} else
} else {
viewController = self.appDelegate.playlistViewController;
[self.appDelegate.playlistViewController setLibraryMode:itemIndex];
}
if (!viewController)
return;
......
......@@ -21,7 +21,7 @@
@property (nonatomic, strong) IBOutlet UILabel *artistNameLabel;
@property (nonatomic, strong) IBOutlet UILabel *albumNameLabel;
@property (nonatomic, retain) MLFile *mediaObject;
@property (nonatomic, retain) NSManagedObject *mediaObject;
+ (VLCPlaylistTableViewCell *)cellWithReuseIdentifier:(NSString *)ident;
+ (CGFloat)heightOfCell;
......
......@@ -9,6 +9,7 @@
//
#import "VLCPlaylistTableViewCell.h"
#import <MediaLibraryKit/MLAlbum.h>
#define MAX_CACHE_SIZE 21 // three times the number of items shown on iPhone 5
......@@ -39,7 +40,12 @@
[_mediaObject removeObserver:self forKeyPath:@"title"];
[_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
[_mediaObject didHide];
[_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
[_mediaObject removeObserver:self forKeyPath:@"album"];
[_mediaObject removeObserver:self forKeyPath:@"artist"];
[_mediaObject removeObserver:self forKeyPath:@"genre"];
if ([_mediaObject respondsToSelector:@selector(didHide)])
[(MLFile*)_mediaObject didHide];
_mediaObject = mediaObject;
......@@ -50,7 +56,13 @@
[_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
[_mediaObject willDisplay];
[_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
if ([_mediaObject respondsToSelector:@selector(willDisplay)])
[(MLFile*)_mediaObject willDisplay];
}
[self _updatedDisplayedInformationForKeyPath:NULL];
......@@ -64,59 +76,90 @@
- (void)_updatedDisplayedInformationForKeyPath:(NSString *)keyPath
{
MLFile *mediaObject = self.mediaObject;
self.albumNameLabel.text = self.artistNameLabel.text = @"";
if (mediaObject.isAlbumTrack) {
self.artistNameLabel.text = mediaObject.albumTrack.artist;
self.albumNameLabel.text = mediaObject.albumTrack.album.name;
self.titleLabel.text = (mediaObject.albumTrack.title.length > 1) ? mediaObject.albumTrack.title : mediaObject.title;
} else
self.titleLabel.text = mediaObject.title;
if (self.isEditing)
self.subtitleLabel.text = [NSString stringWithFormat:@"%@ — %i MB", [VLCTime timeWithNumber:[mediaObject duration]], (int)([mediaObject fileSizeInBytes] / 1e6)];
else {
self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[mediaObject duration]]];
if (mediaObject.videoTrack) {
NSString *width = [[mediaObject videoTrack] valueForKey:@"width"];
NSString *height = [[mediaObject videoTrack] valueForKey:@"height"];
if (width.intValue > 0 && height.intValue > 0)
self.subtitleLabel.text = [self.subtitleLabel.text stringByAppendingFormat:@" — %@x%@", width, height];
if ([self.mediaObject isKindOfClass:[MLFile class]]) {
MLFile *mediaObject = (MLFile*)self.mediaObject;
self.albumNameLabel.text = self.artistNameLabel.text = @"";
if (mediaObject.isAlbumTrack) {
self.artistNameLabel.text = mediaObject.albumTrack.artist;
self.albumNameLabel.text = mediaObject.albumTrack.album.name;
self.titleLabel.text = (mediaObject.albumTrack.title.length > 1) ? mediaObject.albumTrack.title : mediaObject.title;
} else
self.titleLabel.text = mediaObject.title;
if (self.isEditing)
self.subtitleLabel.text = [NSString stringWithFormat:@"%@ — %i MB", [VLCTime timeWithNumber:[mediaObject duration]], (int)([mediaObject fileSizeInBytes] / 1e6)];
else {
self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[mediaObject duration]]];
if (mediaObject.videoTrack) {
NSString *width = [[mediaObject videoTrack] valueForKey:@"width"];
NSString *height = [[mediaObject videoTrack] valueForKey:@"height"];
if (width.intValue > 0 && height.intValue > 0)
self.subtitleLabel.text = [self.subtitleLabel.text stringByAppendingFormat:@" — %@x%@", width, height];
}
}
}
if ([keyPath isEqualToString:@"computedThumbnail"] || !keyPath) {
static NSMutableArray *_thumbnailCacheIndex;
static NSMutableDictionary *_thumbnailCache;
if (!_thumbnailCache)
_thumbnailCache = [[NSMutableDictionary alloc] initWithCapacity:MAX_CACHE_SIZE];
if (!_thumbnailCacheIndex)
_thumbnailCacheIndex = [[NSMutableArray alloc] initWithCapacity:MAX_CACHE_SIZE];
NSManagedObjectID *objID = mediaObject.objectID;
UIImage *displayedImage;
if ([_thumbnailCacheIndex containsObject:objID]) {
[_thumbnailCacheIndex removeObject:objID];
[_thumbnailCacheIndex insertObject:objID atIndex:0];
displayedImage = [_thumbnailCache objectForKey:objID];
} else {
if (_thumbnailCacheIndex.count >= MAX_CACHE_SIZE) {
[_thumbnailCache removeObjectForKey:[_thumbnailCacheIndex lastObject]];
[_thumbnailCacheIndex removeLastObject];
if ([keyPath isEqualToString:@"computedThumbnail"] || !keyPath) {
static NSMutableArray *_thumbnailCacheIndex;
static NSMutableDictionary *_thumbnailCache;
if (!_thumbnailCache)
_thumbnailCache = [[NSMutableDictionary alloc] initWithCapacity:MAX_CACHE_SIZE];
if (!_thumbnailCacheIndex)
_thumbnailCacheIndex = [[NSMutableArray alloc] initWithCapacity:MAX_CACHE_SIZE];
NSManagedObjectID *objID = mediaObject.objectID;
UIImage *displayedImage;
if ([_thumbnailCacheIndex containsObject:objID]) {
[_thumbnailCacheIndex removeObject:objID];
[_thumbnailCacheIndex insertObject:objID atIndex:0];
displayedImage = [_thumbnailCache objectForKey:objID];
} else {
if (_thumbnailCacheIndex.count >= MAX_CACHE_SIZE) {
[_thumbnailCache removeObjectForKey:[_thumbnailCacheIndex lastObject]];
[_thumbnailCacheIndex removeLastObject];
}
displayedImage = mediaObject.computedThumbnail;
if (displayedImage)
[_thumbnailCache setObject:displayedImage forKey:objID];
[_thumbnailCacheIndex insertObject:objID atIndex:0];
}
displayedImage = mediaObject.computedThumbnail;
if (displayedImage)
[_thumbnailCache setObject:displayedImage forKey:objID];
[_thumbnailCacheIndex insertObject:objID atIndex:0];
self.thumbnailView.image = displayedImage;
}
self.thumbnailView.image = displayedImage;
CGFloat position = mediaObject.lastPosition.floatValue;
self.progressIndicator.progress = position;
self.progressIndicator.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
[self.progressIndicator setNeedsDisplay];
self.mediaIsUnreadView.hidden = !mediaObject.unread.intValue;
} else if ([self.mediaObject isKindOfClass:[MLAlbum class]]) {
MLAlbum *mediaObject = (MLAlbum *)self.mediaObject;
self.titleLabel.text = mediaObject.name;
MLAlbumTrack *anyTrack = [mediaObject.tracks anyObject];
if (anyTrack)
self.artistNameLabel.text = anyTrack.artist;
else
self.artistNameLabel.text = @"";
self.albumNameLabel.text = mediaObject.releaseYear;
self.thumbnailView.image = nil;
NSUInteger count = mediaObject.tracks.count;
self.subtitleLabel.text = [NSString stringWithFormat:(count > 1) ? @"%i Tracks" : @"%i Track", count];
self.mediaIsUnreadView.hidden = YES;
self.progressIndicator.hidden = YES;
} else if ([self.mediaObject isKindOfClass:[MLAlbumTrack class]]) {
MLAlbumTrack *mediaObject = (MLAlbumTrack *)self.mediaObject;
self.artistNameLabel.text = mediaObject.artist;
self.albumNameLabel.text = mediaObject.album.name;
self.titleLabel.text = mediaObject.title;
self.thumbnailView.image = nil;
MLFile *anyFileFromTrack = mediaObject.files.anyObject;
self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[anyFileFromTrack duration]]];
CGFloat position = anyFileFromTrack.lastPosition.floatValue;
self.progressIndicator.progress = position;
self.progressIndicator.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
[self.progressIndicator setNeedsDisplay];
self.mediaIsUnreadView.hidden = !anyFileFromTrack.unread.intValue;
}
CGFloat position = mediaObject.lastPosition.floatValue;
self.progressIndicator.progress = position;
self.progressIndicator.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
[self.progressIndicator setNeedsDisplay];
self.mediaIsUnreadView.hidden = !mediaObject.unread.intValue;
[self setNeedsDisplay];
}
......
......@@ -11,6 +11,12 @@
#import <UIKit/UIKit.h>
#import "AQGridView.h"
#define EXPERIMENTAL_LIBRARY 1
#define kVLCLibraryModeAllFiles 0
#define kVLCLibraryModeAllAlbums 1
#define kVLCLibraryModeAllSeries 2
@class VLCMovieViewController;
@class EmptyLibraryView;
......@@ -25,13 +31,14 @@
@property (nonatomic, strong) EmptyLibraryView *emptyLibraryView;
- (IBAction)leftButtonAction:(id)sender;
- (void)updateViewContents;
- (void)openMovieFromURL:(NSURL *)url;
- (void)removeMediaObject:(MLFile *)mediaObject;
- (void)setLibraryMode:(NSUInteger)mode;
@end
@interface EmptyLibraryView: UIView
......
......@@ -21,9 +21,9 @@
@implementation EmptyLibraryView
@end
@interface VLCPlaylistViewController () <AQGridViewDataSource, AQGridViewDelegate,
UITableViewDataSource, UITableViewDelegate> {
@interface VLCPlaylistViewController () <AQGridViewDataSource, AQGridViewDelegate, UITableViewDataSource, UITableViewDelegate> {
NSMutableArray *_foundMedia;
NSUInteger _libraryMode;
}
@end
......@@ -44,6 +44,8 @@
self.view = _gridView;
}
_libraryMode = kVLCLibraryModeAllFiles;
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.emptyLibraryView = [[[NSBundle mainBundle] loadNibNamed:@"VLCEmptyLibraryView" owner:self options:nil] lastObject];
}
......@@ -99,7 +101,7 @@
- (void)viewDidAppear:(BOOL)animated
{
[self performSelector:@selector(updateViewContents) withObject:nil afterDelay:.0];
[self performSelector:@selector(reloadContents) withObject:nil afterDelay:.0];
[[MLMediaLibrary sharedMediaLibrary] performSelector:@selector(libraryDidAppear) withObject:nil afterDelay:1.];
[super viewDidAppear:animated];
......@@ -142,7 +144,7 @@
}
[fileManager removeItemAtPath:[[NSURL URLWithString:mediaObject.url] path] error:nil];
[[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
[self updateViewContents];
[self reloadContents];
}
- (void)_displayEmptyLibraryViewIfNeeded
......@@ -164,10 +166,28 @@
}
}
- (void)updateViewContents
- (void)reloadContents
{
_foundMedia = [NSMutableArray arrayWithArray:[MLFile allFiles]];
if (_libraryMode == kVLCLibraryModeAllAlbums) {
NSArray *rawAlbums = [MLAlbum allAlbums];
_foundMedia = [[NSMutableArray alloc] init];
NSUInteger count = rawAlbums.count;
MLAlbum *album;
for (NSUInteger x = 0; x < count; x++) {
album = rawAlbums[x];
if (album.name.length > 0 && album.tracks.count > 0)
[_foundMedia addObject:album];
}
rawAlbums = nil;
} else
_foundMedia = [NSMutableArray arrayWithArray:[MLFile allFiles]];
[self updateViewContents];
}
- (void)updateViewContents
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
[self.tableView reloadData];
else {
......@@ -178,7 +198,6 @@
[self _displayEmptyLibraryViewIfNeeded];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
......@@ -224,12 +243,22 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MLFile *mediaObject = _foundMedia[indexPath.row];
if (!self.movieViewController)
self.movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];
NSManagedObject *currentObject = _foundMedia[indexPath.row];
if ([currentObject isKindOfClass:[MLAlbum class]]) {
_foundMedia = [NSMutableArray arrayWithArray:[[(MLAlbum *)currentObject tracks] allObjects]];
NSLog(@"current item is an album with %i kids", _foundMedia.count);
[self updateViewContents];
} else {
if (!self.movieViewController)
self.movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];
self.movieViewController.mediaItem = mediaObject;
[self.navigationController pushViewController:self.movieViewController animated:YES];
if ([currentObject isKindOfClass:[MLFile class]])
self.movieViewController.mediaItem = (MLFile *)currentObject;
else
self.movieViewController.mediaItem = [(MLAlbumTrack*)currentObject files].anyObject;
[self.navigationController pushViewController:self.movieViewController animated:YES];
}
}
#pragma mark - AQGridView
......@@ -340,4 +369,10 @@
self.movieViewController.url = url;
}
- (void)setLibraryMode:(NSUInteger)mode
{
_libraryMode = mode;
[self reloadContents];
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment