Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) V3 #25

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
dbf6e37
dump pusher
maddox Jul 12, 2013
8e67923
generate stream url internally
maddox Jul 12, 2013
c28bdcd
hit now playing to attempt some auth
maddox Jul 12, 2013
a72f45a
when updating now playing, just use the top item off the queue
maddox Jul 12, 2013
2e4f452
new attrs and endpoints and all that jazz for the v3 api for Track
maddox Jul 12, 2013
d727740
abstract the updating of now playing
maddox Jul 16, 2013
b8d1d9b
listen for metada change notification to update now playing
maddox Jul 16, 2013
cc54ac0
put these back
maddox Jul 16, 2013
5ed2896
add airplay button
maddox Jul 16, 2013
5641f02
update directly from here
maddox Jul 16, 2013
9e4df2d
don't fetch now playing, just let PLAController handle this
maddox Jul 16, 2013
f3ebbcf
add stop button for iOS
maddox Jul 16, 2013
080e7ba
update play button
maddox Jul 16, 2013
3347f53
re-org player view
maddox Jul 16, 2013
e2ef9ba
fixed width
maddox Jul 16, 2013
7b2c80e
remove background colors and add in album name
maddox Jul 16, 2013
7dd18c0
move airplay button to the bottom
maddox Jul 16, 2013
60e2f8b
starred -> liked
maddox Aug 7, 2013
32464c1
Compiling ++
boidanny Aug 8, 2013
dd5527a
Fix like and unlike URLs.
boidanny Aug 8, 2013
9a2ed4c
don't log this
maddox Aug 19, 2013
6f45ce0
fix download path
maddox Aug 19, 2013
60919f7
just force and update
maddox Aug 19, 2013
04c76b9
update when song changes
maddox Aug 19, 2013
b1145ea
add a poller to update the queue every 20 seconds
maddox Aug 19, 2013
57d1026
on log in just start polling
maddox Aug 19, 2013
d26ec7f
proper stream url that will handle redirection if needed
maddox Aug 19, 2013
c3016ad
Merge pull request #26 from play/v3-playitem
maddox Aug 19, 2013
8ba42f1
doh
maddox Aug 19, 2013
c2485bf
Merge branch 'v3' of github.com:play/play-cocoa into v3
maddox Aug 19, 2013
4e06d4a
fuck a color token input, just log in automatically using magic
maddox Aug 19, 2013
720e972
derp
maddox Aug 19, 2013
8e9aefc
add FontAwesome
maddox Aug 19, 2013
24e44f3
use FontAwesome play/stop icons for buttons
maddox Aug 19, 2013
801808e
don't log this stuff
maddox Aug 19, 2013
5e9c9c0
don't poll while we're playing, we get that info on our own
maddox Aug 19, 2013
b4c5bd4
be less aggressive with the polling
maddox Aug 19, 2013
0f200f4
never stop polling
maddox Aug 20, 2013
350182f
don't just return, kill the old one and start a new one
maddox Aug 20, 2013
5ee8e05
set the play url before checking on it
maddox Aug 20, 2013
60684fa
always be observing
maddox Aug 20, 2013
a1796c1
update as soon as we know we're logged in
maddox Aug 20, 2013
e6ecd5e
update when we become active
maddox Aug 20, 2013
7123aa5
update version numbers
maddox Aug 20, 2013
430194f
do this here when the size is right
maddox Aug 20, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Fonts/fontawesome-webfont.ttf
Binary file not shown.
22 changes: 7 additions & 15 deletions Play Client/PLAController.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,31 @@
//

#import <Foundation/Foundation.h>
#import "PTPusher.h"

extern NSString *const PLANowPlayingUpdated;

@class PLATrack;

@interface PLAController : NSObject <PTPusherDelegate>{
@interface PLAController : NSObject{
NSArray *queuedTracks;
PLATrack *currentlyPlayingTrack;
PTPusher *pusherClient;
NSString *pusherKey;
NSString *streamUrl;
PTPusherEventBinding *updateNowPlayingPusherChannelBinding;
NSTimer *queuePoller;
}

@property (nonatomic, retain) NSArray *queuedTracks;
@property (nonatomic, retain) PLATrack *currentlyPlayingTrack;
@property (nonatomic, retain) PTPusher *pusherClient;
@property (nonatomic, retain) PTPusherEventBinding *updateNowPlayingPusherChannelBinding;
@property (nonatomic, retain) NSString *streamUrl;
@property (nonatomic, retain) NSString *pusherKey;
@property (nonatomic, retain) NSTimer *queuePoller;

+ (PLAController *)sharedController;

- (void)logInWithBlock:(void(^)(BOOL succeeded))block;
- (PTPusherChannel *)nowPlayingPusherChannel;
- (void)setUpPusher;
- (void)subscribeToChannels;
- (void)setPlayUrl:(NSString *)url;
- (NSString *)playUrl;
- (NSString *)streamUrl;
- (void)setAuthToken:(NSString *)token;
- (NSString *)authToken;
- (void)updateNowPlaying:(NSDictionary *)nowPlayingDict;
- (void)channelEventPushed:(PTPusherEvent *)channelEvent;
- (void)updateNowPlaying;
- (void)startPolling;
- (void)stopPolling;

@end
149 changes: 27 additions & 122 deletions Play Client/PLAController.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#import "PLAPlayClient.h"
#import "PLATrack.h"
#import "PTPusherChannel.h"

#if TARGET_OS_EMBEDDED
#import "Reachability.h"
Expand All @@ -20,15 +19,13 @@

@implementation PLAController

@synthesize queuedTracks, currentlyPlayingTrack, pusherClient, updateNowPlayingPusherChannelBinding, streamUrl, pusherKey;
@synthesize queuedTracks, currentlyPlayingTrack, queuePoller;

- (void) dealloc{
[queuedTracks release];
[currentlyPlayingTrack release];
[pusherClient release];
[updateNowPlayingPusherChannelBinding release];
[streamUrl release];
[pusherKey release];
[queuePoller invalidate];
[queuePoller release];

[super dealloc];
}
Expand All @@ -53,12 +50,7 @@ - (id)init {
}

- (void)logInWithBlock:(void(^)(BOOL succeeded))block{
[[PLAPlayClient sharedClient] getPath:@"/streaming_info" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.streamUrl = [responseObject objectForKey:@"stream_url"];
self.pusherKey = [responseObject objectForKey:@"pusher_key"];

[self setUpPusher];
[self subscribeToChannels];
[[PLAPlayClient sharedClient] getPath:@"/api/now_playing" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

if (block != nil)
block(YES);
Expand All @@ -70,42 +62,8 @@ - (void)logInWithBlock:(void(^)(BOOL succeeded))block{

}

#pragma mark - Pusher Bootstrap

- (PTPusherChannel *)nowPlayingPusherChannel{
if (pusherClient) {
return [pusherClient subscribeToChannelNamed:@"now_playing_updates"];
}

return nil;
}

- (void)setUpPusher{
if (pusherClient) {
NSLog(@"destroying pusherClient to be ready to create a new one");
PTPusherChannel *channel = [self nowPlayingPusherChannel];
[channel removeBinding:updateNowPlayingPusherChannelBinding];
self.updateNowPlayingPusherChannelBinding = nil;

[self.pusherClient setDelegate:nil];
[self.pusherClient unsubscribeFromChannel:channel];
[self.pusherClient setReconnectAutomatically:NO];
[self.pusherClient disconnect];
[self.pusherClient retain]; //intentional leak. For some when these object die they occasionally wreak havoc with a hard-as-shit crash.
self.pusherClient = nil;
}

self.pusherClient = [PTPusher pusherWithKey:pusherKey delegate:self encrypted:NO];
[pusherClient setReconnectAutomatically:YES];
[pusherClient setReconnectDelay:30];
}

- (void)subscribeToChannels{
if (pusherClient) {
NSLog(@"subscribing to channels");
PTPusherChannel *channel = [self nowPlayingPusherChannel];
self.updateNowPlayingPusherChannelBinding = [channel bindToEventNamed:@"update_now_playing" target:self action:@selector(channelEventPushed:)];
}
- (NSString *)streamUrl{
return [NSString stringWithFormat:@"%@/api/stream?token=%@", [[PLAController sharedController] playUrl], [self authToken]];
}

#pragma mark - Settings
Expand All @@ -128,90 +86,39 @@ - (NSString *)authToken{
return [[NSUserDefaults standardUserDefaults] objectForKey:@"authToken"];
}

#pragma mark - State methods

- (void)updateNowPlaying:(NSDictionary *)nowPlayingDict{
// record current state
self.currentlyPlayingTrack = [[[PLATrack alloc] initWithAttributes:[nowPlayingDict objectForKey:@"now_playing"]] autorelease];

NSMutableArray *tracks = [NSMutableArray array];
for (NSDictionary *trackDict in [nowPlayingDict objectForKey:@"songs"]) {
PLATrack *track = [[PLATrack alloc] initWithAttributes:trackDict];
[tracks addObject:track];
[track release];
}

self.queuedTracks = [NSArray arrayWithArray:tracks];
- (void)startPolling{
[queuePoller invalidate];
self.queuePoller = nil;

[[NSNotificationCenter defaultCenter] postNotificationName:PLANowPlayingUpdated object:nil];
}

#pragma mark - Channel Event handler

- (void)channelEventPushed:(PTPusherEvent *)channelEvent{
if ([[channelEvent name] isEqualToString:@"update_now_playing"]) {
[self updateNowPlaying:(NSDictionary *)[channelEvent data]];
}
}

#pragma mark - PTPusher Delegate Methods

- (void)pusher:(PTPusher *)client connectionDidConnect:(PTPusherConnection *)connection{
NSLog(@"connectionDidConnect");
client.reconnectAutomatically = YES;
self.queuePoller = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(updateNowPlaying) userInfo:nil repeats:YES];
[queuePoller fire];
}

- (void)pusher:(PTPusher *)pusher didSubscribeToChannel:(PTPusherChannel *)channel {
NSLog(@"did subscribe to channel: %@", [channel name]);
- (void)stopPolling{
[queuePoller invalidate];
self.queuePoller = nil;
[queuePoller release];
}

- (void)pusher:(PTPusher *)pusher didFailToSubscribeToChannel:(PTPusherChannel *)channel withError:(NSError *)error{
NSLog(@"failed to subscribe: %@", error.description);
}

- (void)pusher:(PTPusher *)pusher didReceiveErrorEvent:(PTPusherErrorEvent *)errorEvent{
NSLog(@"received error event: %@", errorEvent);
}
#pragma mark - State methods

- (void)pusher:(PTPusher *)client connectionDidDisconnect:(PTPusherConnection *)connection{
NSLog(@"connectionDidDisconnect");
- (void)updateNowPlaying{
NSLog(@"Updating Now Playing");

#if TARGET_OS_EMBEDDED
Reachability *reachability = [Reachability reachabilityForInternetConnection];

if ([reachability currentReachabilityStatus] == NotReachable) {
NSLog(@"NotReachable");
client.reconnectAutomatically = NO;
[PLATrack currentQueueWithBlock:^(NSArray *tracks, NSError *err) {
NSMutableArray *foundTracks = [NSMutableArray arrayWithArray:tracks];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:reachability];
if ([foundTracks count] > 0) {
self.currentlyPlayingTrack = [foundTracks objectAtIndex:0];
[foundTracks removeObjectAtIndex:0];
}

self.queuedTracks = [NSArray arrayWithArray:foundTracks];

[reachability startNotifier];
}else{
[PLATrack currentTrackWithBlock:^(PLATrack *track, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
self.currentlyPlayingTrack = track;
[[NSNotificationCenter defaultCenter] postNotificationName:PLANowPlayingUpdated object:nil];
[self setUpPusher];
[self subscribeToChannels];
});
}];
}

#else
[PLATrack currentTrackWithBlock:^(PLATrack *track, NSError *err) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
self.currentlyPlayingTrack = track;
[[NSNotificationCenter defaultCenter] postNotificationName:PLANowPlayingUpdated object:nil];
[self setUpPusher];
[self subscribeToChannels];
});
}];

[PLATrack currentQueueWithBlock:^(NSArray *tracks, NSError *err) {
if (tracks != nil)
self.queuedTracks = tracks;
}];
#endif
}];
}

#if TARGET_OS_EMBEDDED
Expand All @@ -226,8 +133,6 @@ - (void)reachabilityChanged:(NSNotification *)note{
[PLATrack currentTrackWithBlock:^(PLATrack *track, NSError *error) {
self.currentlyPlayingTrack = track;
[[NSNotificationCenter defaultCenter] postNotificationName:PLANowPlayingUpdated object:nil];
[self setUpPusher];
[self subscribeToChannels];
}];

}
Expand Down
14 changes: 10 additions & 4 deletions Play Client/PLATrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@
#import <Foundation/Foundation.h>

@interface PLATrack : NSObject <NSCopying> {
NSString *trackId;
NSString *slug;
NSString *name;
NSString *album;
NSString *albumSlug;
NSString *artist;
BOOL starred;
NSString *artistSlug;
NSString *albumArtPath;
BOOL liked;
BOOL queued;
}

@property (nonatomic, retain) NSString *trackId;
@property (nonatomic, retain) NSString *slug;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *album;
@property (nonatomic, retain) NSString *albumSlug;
@property (nonatomic, retain) NSString *artist;
@property (nonatomic, assign) BOOL starred;
@property (nonatomic, retain) NSString *artistSlug;
@property (nonatomic, retain) NSString *albumArtPath;
@property (nonatomic, assign) BOOL liked;
@property (nonatomic, assign) BOOL queued;
@property (nonatomic, readonly) NSURL *albumArtURL;
@property (nonatomic, readonly) NSURL *downloadURL;
Expand Down
Loading