Skip to content

Commit bbd24b3

Browse files
dgatteyweblancaster
authored andcommitted
User favorite status synced across app (fixes #659) (#731)
* Heart updates based on saved value when song changes * Broadcasting favorites and unfavorites to sync them (stream & player) * All songs now update themselves when broadcasted to
1 parent eb71c04 commit bbd24b3

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

app/public/js/common/favoriteSongDirective.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ app.directive('favoriteSong', function(
2727
notificationFactory.warn("Song removed from likes!");
2828
$scope.favorite = false;
2929
$scope.count -= 1;
30+
$rootScope.$broadcast("track::unfavorited", songId);
3031
}
3132
}, function() {
3233
notificationFactory.error("Something went wrong!");
@@ -38,6 +39,7 @@ app.directive('favoriteSong', function(
3839
notificationFactory.success("Song added to likes!");
3940
$scope.favorite = true;
4041
$scope.count += 1;
42+
$rootScope.$broadcast("track::favorited", songId);
4143
}
4244
}, function(status) {
4345
notificationFactory.error("Something went wrong!");

app/public/js/common/playerService.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ app.factory('playerService', function(
6161
player.elPlayerProgress = document.getElementById('player-progress');
6262
player.elPlayerDuration = document.getElementById('player-duration');
6363
player.elPlayerTimeCurrent = document.getElementById('player-timecurrent');
64+
player.elPlayerFavorite = angular.element( document.querySelector('.player_favorite') );
6465
player.elThumb = document.getElementById('playerThumb');
6566
player.elTitle = document.getElementById('playerTitle');
6667
player.elUser = document.getElementById('playerUser');
@@ -165,6 +166,15 @@ app.factory('playerService', function(
165166
};
166167
}
167168

169+
// Make sure the favorite heart is active if user liked it
170+
var fav = this.elPlayerFavorite;
171+
utilsService.updateTracksLikes([trackObj], true) // use cache to start
172+
.then(function() {
173+
if ( trackObj.user_favorite ) {
174+
fav.addClass('active');
175+
}
176+
});
177+
168178
$rootScope.isSongPlaying = true;
169179
$rootScope.$broadcast('activateQueue');
170180

@@ -173,6 +183,14 @@ app.factory('playerService', function(
173183
document.querySelector('.player_favorite').classList.remove('active');
174184
};
175185

186+
// Updates cache when liking or unliking a song, so future checks will be correct
187+
$rootScope.$on('track::favorited', function(event, trackId) {
188+
utilsService.addCachedFavorite(trackId);
189+
});
190+
$rootScope.$on('track::unfavorited', function(event, trackId) {
191+
utilsService.removeCachedFavorite(trackId);
192+
});
193+
176194
/**
177195
* Responsible to play song
178196
* @method playSong

app/public/js/common/queueCtrl.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ app.controller('QueueCtrl', function(
8383
if ( typeof status == "object" ) {
8484
notificationFactory.success("Song added to likes!");
8585
utilsService.markTrackAsFavorite(songId);
86+
$rootScope.$broadcast("track::favorited", songId);
8687
}
8788
}, function(status) {
8889
notificationFactory.error("Something went wrong!");

app/public/js/common/songDirective.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ app.directive('song', function ($rootScope, $window, playerService) {
1414
});
1515
});
1616

17+
// Updating favorites when they get sent from other scope like the queue, stream, and player
18+
$scope.$on('track::favorited', function(event, trackId) {
19+
if ($scope.data.id == parseInt(trackId)) {
20+
$scope.data.user_favorite = true;
21+
}
22+
});
23+
$scope.$on('track::unfavorited', function(event, trackId) {
24+
if ($scope.data.id == parseInt(trackId)) {
25+
$scope.data.user_favorite = false;
26+
}
27+
});
28+
1729
}
1830
}
1931
});

app/public/js/common/utilsService.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,42 @@ app.factory('utilsService', function(
125125
}
126126
collection.forEach(function (item) {
127127
var track = item.track || item;
128+
var id = track.id || track.songId;
128129
// modify each track by reference
129-
track.user_favorite = Utils.likesIds.indexOf(track.id) > -1;
130+
track.user_favorite = Utils.likesIds.indexOf(id) > -1;
130131
});
131132
return collection;
132133
});
133134
};
134135

136+
/**
137+
* When manipulating likes after a page is loaded, it's necessary to
138+
* manipulate the likesIds cache when you modify user_favorite like
139+
* above. Used to sync the likes between player and everything else
140+
* @param {number or string} id - the song id to add to likes
141+
*/
142+
Utils.addCachedFavorite = function(id) {
143+
id = parseInt(id);
144+
var index = Utils.likesIds.indexOf(id);
145+
if (index == -1) {
146+
Utils.likesIds.push(id);
147+
}
148+
}
149+
150+
/**
151+
* When manipulating likes after a page is loaded, it's necessary to
152+
* manipulate the likesIds cache when you modify user_favorite like
153+
* above. Used to sync the likes between player and everything else
154+
* @param {number or string} id - the song id to remove from likes
155+
*/
156+
Utils.removeCachedFavorite = function(id) {
157+
id = parseInt(id);
158+
var index = Utils.likesIds.indexOf(id);
159+
if (index > -1) {
160+
Utils.likesIds.splice(index, 1);
161+
}
162+
}
163+
135164
/**
136165
* Fetch ids of reposted tracks and apply them to existing collection
137166
* @param {array} collection - stream collection or tracks array

app/public/js/player/playerCtrl.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ app.controller('PlayerCtrl', function (
112112
if ( typeof status == "object" ) {
113113
notificationFactory.warn("Song removed from likes!");
114114
$event.currentTarget.classList.remove('active');
115+
$rootScope.$broadcast("track::unfavorited", track.songId);
115116
}
116117
}, function() {
117118
notificationFactory.error("Something went wrong!");
@@ -122,13 +123,30 @@ app.controller('PlayerCtrl', function (
122123
if ( typeof status == "object" ) {
123124
notificationFactory.success("Song added to likes!");
124125
$event.currentTarget.classList.add('active');
126+
$rootScope.$broadcast("track::favorited", track.songId);
125127
}
126128
}, function(status) {
127129
notificationFactory.error("Something went wrong!");
128130
});
129131
}
130132
};
131133

134+
// Listen for updates from other scopes about favorites and unfavorites
135+
$scope.$on('track::favorited', function(event, trackId) {
136+
var track = queueService.getTrack();
137+
if ( track && trackId == track.songId ) {
138+
var elFavorite = document.querySelector('.player_favorite');
139+
elFavorite.classList.add('active');
140+
}
141+
});
142+
$scope.$on('track::unfavorited', function(event, trackId) {
143+
var track = queueService.getTrack();
144+
if ( track && trackId == track.songId ) {
145+
var elFavorite = document.querySelector('.player_favorite');
146+
elFavorite.classList.remove('active');
147+
}
148+
});
149+
132150

133151
/*
134152
* Add native media shortcuts

0 commit comments

Comments
 (0)