diff --git a/PlexATV/Classes/HWDetailedMovieMetadataController.m b/PlexATV/Classes/HWDetailedMovieMetadataController.m index e4a4702..d8dd456 100644 --- a/PlexATV/Classes/HWDetailedMovieMetadataController.m +++ b/PlexATV/Classes/HWDetailedMovieMetadataController.m @@ -91,7 +91,6 @@ - (id)initWithPlexMediaObject:(PlexMediaObject *)aMediaObject { if (self) { self.selectedMediaObject = aMediaObject; DLog(@"init with media object:%@", self.selectedMediaObject); - self.selectedMediaItemPreviewData = self.selectedMediaObject.previewAsset; } return self; @@ -129,21 +128,21 @@ -(void)dealloc { #endif self.assets = nil; self.selectedMediaItemPreviewData = nil; - - [listDropShadowControl release]; + + [listDropShadowControl release]; [super dealloc]; } - (void)changeMetadataViewToShowDataForIndex:(int)newIndex { - //check that it is a new one, otherwise don't refresh + //check that it is a new one, otherwise don't refresh if (currentSelectedIndex != newIndex) { - //set both focused and selected to the new index + //set both focused and selected to the new index currentSelectedIndex = newIndex; self._shelfControl.focusedIndex = newIndex; self.selectedMediaItemPreviewData = [self.assets objectAtIndex:currentSelectedIndex]; - //move the shelf if needed to show the new item - //[self._shelfControl _scrollIndexToVisible:currentSelectedIndex]; - //refresh metadata, but don't touch the shelf + //move the shelf if needed to show the new item + //[self._shelfControl _scrollIndexToVisible:currentSelectedIndex]; + //refresh metadata, but don't touch the shelf [self reload]; } } @@ -153,16 +152,16 @@ - (void)changeMetadataViewToShowDataForIndex:(int)newIndex { #pragma mark Controller Lifecycle behaviour - (void)wasPushed { #if LOCAL_DEBUG_ENABLED - DLog(); + DLog(); #endif [[MachineManager sharedMachineManager] setMachineStateMonitorPriority:NO]; [super wasPushed]; } - (void)wasPopped { - self.datasource = nil; - self.assets = nil; - self.selectedMediaItemPreviewData = nil; + self.datasource = nil; + self.assets = nil; + self.selectedMediaItemPreviewData = nil; [super wasPopped]; } @@ -191,10 +190,10 @@ -(void)controllerSwitchToPrevious:(SMFMoviePreviewController *)ctrl { [[SMFThemeInfo sharedTheme] playNavigateSound]; int newIndex; if (currentSelectedIndex - 1 < 0) { - //we have reached the beginning, loop around + //we have reached the beginning, loop around newIndex = [self.assets count] - 1; } else { - //go to previous one + //go to previous one newIndex = currentSelectedIndex - 1; } #if LOCAL_DEBUG_ENABLED @@ -216,10 +215,10 @@ -(void)controllerSwitchToNext:(SMFMoviePreviewController *)ctrl { [[SMFThemeInfo sharedTheme] playNavigateSound]; int newIndex; if (currentSelectedIndex + 1 < [self.assets count]) { - //go to next one + //go to next one newIndex = currentSelectedIndex + 1; } else { - //we have reached the end, loop around + //we have reached the end, loop around newIndex = 0; } #if LOCAL_DEBUG_ENABLED @@ -236,36 +235,41 @@ -(void)controller:(SMFMoviePreviewController *)c selectedControl:(BRControl *)ct DLog(@"controller selected %@", ctrl); #endif PlexAudioSubsController *subCtrl; - + if ([ctrl isKindOfClass:[BRButtonControl class]]) { - //one of the buttons have been pushed + //one of the buttons have been pushed BRButtonControl *buttonControl = (BRButtonControl *)ctrl; #if LOCAL_DEBUG_ENABLED DLog(@"button chosen: %@", buttonControl.identifier); #endif - + + PlexMediaObject *pmo = self.selectedMediaObject; + if (!pmo) { + pmo = self.selectedMediaItemPreviewData.pmo; + } + int buttonId = [buttonControl.identifier intValue]; switch (buttonId) { case kPlayButton: DLog(@"play movie plz kthxbye"); DLog(@"asset: %@", selectedMediaItemPreviewData.title); - [[PlexNavigationController sharedPlexNavigationController] navigateToObjectsContents:selectedMediaItemPreviewData.pmo]; + [[PlexNavigationController sharedPlexNavigationController] initiatePlaybackOfMediaObject:pmo]; break; - case kMoreButton: - [listDropShadowControl addToController:self]; //show popup for marking movie as watched/unwatched - break; - case kAudioSubsButton: - subCtrl = [[PlexAudioSubsController alloc] initWithMediaObject:self.selectedMediaItemPreviewData.pmo]; - [[[BRApplicationStackManager singleton] stack] pushController:subCtrl]; + case kMoreButton: + [listDropShadowControl addToController:self]; //show popup for marking movie as watched/unwatched + break; + case kAudioSubsButton: + subCtrl = [[PlexAudioSubsController alloc] initWithMediaObject:pmo]; + [[[BRApplicationStackManager singleton] stack] pushController:subCtrl]; default: break; } - //none of the buttons do anything, make error sound for now + //none of the buttons do anything, make error sound for now [[SMFThemeInfo sharedTheme] playErrorSound]; } else if (ctrl == self._shelfControl) { - //user has selected a media item + //user has selected a media item [[SMFThemeInfo sharedTheme] playSelectSound]; [self changeMetadataViewToShowDataForIndex:self._shelfControl.focusedIndex]; } @@ -273,21 +277,21 @@ -(void)controller:(SMFMoviePreviewController *)c selectedControl:(BRControl *)ct -(void)controller:(SMFMoviePreviewController *)c switchedFocusTo:(BRControl *)newControl { if ([newControl isKindOfClass:[BRButtonControl class]]) { - //one of the buttons is now focused + //one of the buttons is now focused DLog(@"switchedFocusTo button focused"); if (shelfIsSelected) shelfIsSelected = NO; //shelf was focused, and now one of the buttons are. } else if (newControl == self._shelfControl) { - //the shelf is now re-focused, load previous focused element + //the shelf is now re-focused, load previous focused element shelfIsSelected = YES; self._shelfControl.focusedIndex = lastFocusedIndex; } } -(void)controller:(SMFMoviePreviewController *)c shelfLastIndex:(long)index { - //check if the shelf is currently selected - //we perform this check because this delegate method is called every time - //the user focuses a new control in the view + //check if the shelf is currently selected + //we perform this check because this delegate method is called every time + //the user focuses a new control in the view if (shelfIsSelected) lastFocusedIndex = index; } @@ -306,16 +310,16 @@ -(NSString *)subtitle { #if LOCAL_DEBUG_ENABLED DLog(@"subtitle_end: %@", [self.selectedMediaItemPreviewData broadcaster]); #endif - - if ([self.selectedMediaItemPreviewData broadcaster]) - return [self.selectedMediaItemPreviewData broadcaster]; - else - return @""; + + if ([self.selectedMediaItemPreviewData broadcaster]) + return [self.selectedMediaItemPreviewData broadcaster]; + else + return @""; } -(NSString *)summary { #if LOCAL_DEBUG_ENABLED - //DLog(@"summary: %@", [self.selectedMediaItemPreviewData mediaSummary]); + //DLog(@"summary: %@", [self.selectedMediaItemPreviewData mediaSummary]); #endif return [self.selectedMediaItemPreviewData mediaSummary]; } @@ -325,10 +329,10 @@ -(NSArray *)headers { } -(NSArray *)columns { - //the table will hold all the columns + //the table will hold all the columns NSMutableArray *table = [NSMutableArray array]; - // ======= details column ====== + // ======= details column ====== NSMutableArray *details = [NSMutableArray array]; BRGenre *genre = [self.selectedMediaItemPreviewData primaryGenre]; @@ -349,25 +353,25 @@ -(NSArray *)columns { [badges addObject:[[BRThemeInfo sharedTheme] ccBadge]]; [details addObject:badges]; - if ([self.selectedMediaItemPreviewData starRatingImage]) { - BRImage *starRating = [self.selectedMediaItemPreviewData starRatingImage]; - [details addObject:starRating]; + if ([self.selectedMediaItemPreviewData starRatingImage]) { + BRImage *starRating = [self.selectedMediaItemPreviewData starRatingImage]; + [details addObject:starRating]; } - + [table addObject:details]; - // ======= actors column ====== - if ([self.selectedMediaItemPreviewData cast]) { - NSArray *actors = [self.selectedMediaItemPreviewData cast]; - [table addObject:actors]; + // ======= actors column ====== + if ([self.selectedMediaItemPreviewData cast]) { + NSArray *actors = [self.selectedMediaItemPreviewData cast]; + [table addObject:actors]; } - // ======= director column ====== + // ======= director column ====== NSMutableArray *directorAndWriters = [NSMutableArray arrayWithArray:[self.selectedMediaItemPreviewData directors]]; - if (directorAndWriters == nil) - [directorAndWriters initWithCapacity:2]; - + if (directorAndWriters == nil) + [directorAndWriters initWithCapacity:2]; + [directorAndWriters addObject:@" "]; NSAttributedString *subHeadingWriters = [[NSAttributedString alloc]initWithString:@"Writers" attributes:[SMFMoviePreviewController columnHeaderAttributes]]; [directorAndWriters addObject:subHeadingWriters]; @@ -377,13 +381,13 @@ -(NSArray *)columns { [table addObject:directorAndWriters]; - // ======= producers column ====== - if ([self.selectedMediaItemPreviewData producers]) { - NSArray *producers = [self.selectedMediaItemPreviewData producers]; - [table addObject:producers]; + // ======= producers column ====== + if ([self.selectedMediaItemPreviewData producers]) { + NSArray *producers = [self.selectedMediaItemPreviewData producers]; + [table addObject:producers]; } - // ======= done building table ====== + // ======= done building table ====== #if LOCAL_DEBUG_ENABLED DLog(@"table: %@", table); #endif @@ -409,49 +413,67 @@ -(BRImage *)coverArt { } - (NSURL *)backgroundImageUrl { - NSURL* backgroundImageUrl = nil; - PlexMediaObject *pmo = self.selectedMediaItemPreviewData.pmo; - if ([pmo.attributes valueForKey:@"art"] != nil) { - NSString *backgroundImagePath = [NSString stringWithFormat:@"%@%@",pmo.request.base, [pmo.attributes valueForKey:@"art"]]; - backgroundImageUrl = [pmo.request pathForScaledImage:backgroundImagePath ofSize:self.frame.size]; + NSURL* backgroundImageUrl = nil; + + NSString *artPath = nil; + PlexMediaObject *pmo = nil; + + if (self.selectedMediaObject) { + pmo = self.selectedMediaObject; + if ([pmo.attributes valueForKey:@"art"]) { + //movie + artPath = [pmo.attributes valueForKey:@"art"]; + } else { + //tv show + artPath = [pmo.mediaContainer.attributes valueForKey:@"art"]; + } + } else { + pmo = self.selectedMediaItemPreviewData.pmo; + artPath = [pmo.attributes valueForKey:@"art"]; + } + + if (artPath) { + NSString *backgroundImagePath = [NSString stringWithFormat:@"%@%@",pmo.request.base, artPath]; + backgroundImageUrl = [pmo.request pathForScaledImage:backgroundImagePath ofSize:self.frame.size]; } + DLog(@"=============!!!===background image with url %@", backgroundImageUrl); return backgroundImageUrl; } -(NSArray *)buttons { - // built-in images: - // deleteActionImage, menuActionUnfocusedImage, playActionImage, - // previewActionImage, queueActionImage, rateActionImage + // built-in images: + // deleteActionImage, menuActionUnfocusedImage, playActionImage, + // previewActionImage, queueActionImage, rateActionImage NSMutableArray *buttons = [NSMutableArray array]; BRButtonControl* b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]playActionImage] - subtitle:@"Play" - badge:nil]; + subtitle:@"Play" + badge:nil]; [b setIdentifier:[NSNumber numberWithInt:kPlayButton]]; [buttons addObject:b]; - /* - b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]previewActionImage] - subtitle:@"Preview" - badge:nil]; - [b setIdentifier:[NSNumber numberWithInt:kPreviewButton]]; - [buttons addObject:b]; - */ - b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]queueActionImage] - subtitle:@"Audio/subs" - badge:nil]; - [b setIdentifier:[NSNumber numberWithInt:kAudioSubsButton]]; - [buttons addObject:b]; - - - b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]rateActionImage] - subtitle:@"More" - badge:nil]; - [b setIdentifier:[NSNumber numberWithInt:kMoreButton]]; - [buttons addObject:b]; - - - return buttons; + /* + b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]previewActionImage] + subtitle:@"Preview" + badge:nil]; + [b setIdentifier:[NSNumber numberWithInt:kPreviewButton]]; + [buttons addObject:b]; + */ + b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]queueActionImage] + subtitle:@"Audio/subs" + badge:nil]; + [b setIdentifier:[NSNumber numberWithInt:kAudioSubsButton]]; + [buttons addObject:b]; + + + b = [BRButtonControl actionButtonWithImage:[[BRThemeInfo sharedTheme]rateActionImage] + subtitle:@"More" + badge:nil]; + [b setIdentifier:[NSNumber numberWithInt:kMoreButton]]; + [buttons addObject:b]; + + + return buttons; } -(BRPhotoDataStoreProvider *)providerForShelf { @@ -493,21 +515,21 @@ - (long)popupItemCount { } - (id)popupItemForRow:(long)row { - SMFMenuItem *it = [SMFMenuItem menuItem]; - switch (row) { + SMFMenuItem *it = [SMFMenuItem menuItem]; + switch (row) { case MarkAsWatchedOption: { [it setTitle:@"Mark as watched"]; break; } - case MarkAsUnwatchedOption: { + case MarkAsUnwatchedOption: { [it setTitle:@"Mark as unwatched"]; - break; - } + break; + } default: [it setTitle:@"Go back"]; break; } - return it; + return it; } - (long)popupDefaultIndex { @@ -518,17 +540,17 @@ - (void)popup:(id)p itemSelected:(long)row { [p removeFromParent]; switch (row) { case MarkAsWatchedOption: { - DLog(@"marking movie as watched"); - [selectedMediaItemPreviewData.pmo markSeen]; + DLog(@"marking movie as watched"); + [selectedMediaItemPreviewData.pmo markSeen]; break; } - case MarkAsUnwatchedOption: { - DLog(@"marking movie as un-watched"); - [selectedMediaItemPreviewData.pmo markUnseen]; - break; - } + case MarkAsUnwatchedOption: { + DLog(@"marking movie as un-watched"); + [selectedMediaItemPreviewData.pmo markUnseen]; + break; + } default: - DLog(@"going back"); + DLog(@"going back"); break; } } diff --git a/PlexATV/Classes/PlexNavigationController.h b/PlexATV/Classes/PlexNavigationController.h index 3c069e9..8e5685e 100644 --- a/PlexATV/Classes/PlexNavigationController.h +++ b/PlexATV/Classes/PlexNavigationController.h @@ -18,6 +18,7 @@ + (PlexNavigationController *)sharedPlexNavigationController; //Navigation Methods +- (void)initiatePlaybackOfMediaObject:(PlexMediaObject *)aMediaObject; - (void)navigateToObjectsContents:(PlexMediaObject *)aMediaObject; - (void)navigateToDetailedMetadataController:(NSArray *)previewAssets withSelectedIndex:(int)selectedIndex; - (void)navigateToChannelsForMachine:(Machine *)aMachine; diff --git a/PlexATV/Classes/PlexNavigationController.m b/PlexATV/Classes/PlexNavigationController.m index 39e208e..8b92326 100644 --- a/PlexATV/Classes/PlexNavigationController.m +++ b/PlexATV/Classes/PlexNavigationController.m @@ -86,6 +86,19 @@ - (void)controlWasActivated {} #pragma mark - #pragma mark Navigation Methods +- (void)initiatePlaybackOfMediaObject:(PlexMediaObject *)aMediaObject { + DLog(@"Navigating to: [Playback of %@]", aMediaObject); + self.targetController = nil; + self.targetMediaObject = nil; + self.promptText = [NSString stringWithFormat:@"Loading playback of \"%@\"...", self.targetMediaObject.name]; + + PlexPlaybackController *playbackController = [[PlexPlaybackController alloc] initWithPlexMediaObject:aMediaObject]; + self.targetController = playbackController; + [playbackController release]; + + [[[BRApplicationStackManager singleton] stack] pushController:self]; +} + - (void)navigateToObjectsContents:(PlexMediaObject *)aMediaObject { DLog(@"Navigating to: [%@]", aMediaObject); self.targetController = nil; @@ -180,7 +193,7 @@ - (BRController *)newControllerForObject:(PlexMediaObject *)aMediaObject { //play theme music if we're entering a tv show [[PlexThemeMusicPlayer sharedPlexThemeMusicPlayer] startPlayingThemeMusicIfAppropiateForMediaObject:aMediaObject]; // ========== movie, initiate movie pre-play view ============ - if (aMediaObject.hasMedia || [@"Video" isEqualToString:aMediaObject.containerType]) { + if (aMediaObject.hasMedia || [@"Video" isEqualToString:aMediaObject.containerType]) { return [[HWDetailedMovieMetadataController alloc] initWithPlexMediaObject:aMediaObject]; } // ============ sound plugin or other type of sound, initiate playback ============ diff --git a/PlexATV/Classes/PlexThemeMusicPlayer.m b/PlexATV/Classes/PlexThemeMusicPlayer.m index 5c67590..cd1b0ee 100644 --- a/PlexATV/Classes/PlexThemeMusicPlayer.m +++ b/PlexATV/Classes/PlexThemeMusicPlayer.m @@ -23,23 +23,39 @@ - (void)startPlayingThemeMusicIfAppropiateForMediaObject:(PlexMediaObject *)medi NSString *themeUrlAsString; //let's play theme music both in show view but also in season view, since we in grid mode always go to season view directly - if ([mediaObject.attributes valueForKey:@"theme"] != nil) { //show + if ([mediaObject.attributes valueForKey:@"theme"] != nil) { // episode/movie hasThemeMusic = YES; themeUrlAsString = [mediaObject.request buildAbsoluteKey: [mediaObject.attributes valueForKey:@"theme"]]; } - else if ([mediaObject.parentObject.attributes valueForKey:@"theme"] != nil) { //season - hasThemeMusic = YES; - themeUrlAsString = [mediaObject.request buildAbsoluteKey: [mediaObject.parentObject.attributes valueForKey:@"theme"]]; + + + if (!hasThemeMusic) { //check parent + PlexMediaObject *parentObject = nil; + if ([mediaObject.parentObject isKindOfClass:[PlexMediaObject class]]) { + parentObject = mediaObject.parentObject; + } - } - else if ([mediaObject.parentObject.parentObject.attributes valueForKey:@"theme"] != nil) { //episode - hasThemeMusic = YES; - themeUrlAsString = [mediaObject.request buildAbsoluteKey: [mediaObject.parentObject.parentObject.attributes valueForKey:@"theme"]]; + if ([parentObject.attributes valueForKey:@"theme"] != nil) { //season + hasThemeMusic = YES; + themeUrlAsString = [mediaObject.request buildAbsoluteKey: [parentObject.attributes valueForKey:@"theme"]]; + + } + if (!hasThemeMusic) { //check grandparent + PlexMediaObject *grandparentObject = nil; + if (parentObject && [parentObject.parentObject isKindOfClass:[PlexMediaObject class]]) { + grandparentObject = parentObject.parentObject; + } + + if (!hasThemeMusic && [grandparentObject.attributes valueForKey:@"theme"] != nil) { //episode + hasThemeMusic = YES; + themeUrlAsString = [mediaObject.request buildAbsoluteKey: [grandparentObject.attributes valueForKey:@"theme"]]; + + } + } } - else - hasThemeMusic = NO; + if (hasThemeMusic) { NSURL *themeUrl = [NSURL URLWithString:themeUrlAsString];