mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-27 15:27:58 +01:00
290 lines
12 KiB
CoffeeScript
290 lines
12 KiB
CoffeeScript
# Pony.fm - A community for pony fan music.
|
|
# Copyright (C) 2015 Peter Deltchev
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
module.exports = angular.module('ponyfm').factory('playlists', [
|
|
'$rootScope', '$state', '$http', 'auth'
|
|
($rootScope, $state, $http, auth) ->
|
|
playlistDef = null
|
|
filterDef = null
|
|
playlists = {}
|
|
playlistPages = []
|
|
|
|
class Query
|
|
cacheDef: null
|
|
page: 1
|
|
listeners: []
|
|
|
|
constructor: (@availableFilters) ->
|
|
@filters = {}
|
|
@hasLoadedFilters = false
|
|
@resetFilters()
|
|
|
|
resetFilters: ->
|
|
_.each @availableFilters, (filter, name) =>
|
|
if filter.type == 'single'
|
|
@filters[name] = _.find filter.values, (f) -> f.isDefault
|
|
else
|
|
@filters[name] = {title: 'Any', selectedArray: [], selectedObject: {}}
|
|
|
|
clearFilter: (type) ->
|
|
@cachedDef = null
|
|
@page = 1
|
|
filter = @availableFilters[type]
|
|
|
|
if filter.type == 'single'
|
|
@filters[type] = _.find filter.values, (f) -> f.isDefault
|
|
else
|
|
currentFilter = @filters[type]
|
|
currentFilter.selectedArray = []
|
|
currentFilter.selectedObject = {}
|
|
currentFilter.title = 'Any'
|
|
|
|
setPage: (page) ->
|
|
@page = page
|
|
@cachedDef = null
|
|
|
|
setFilter: (type, value) ->
|
|
@cachedDef = null
|
|
@page = 1
|
|
@filters[type] = value
|
|
|
|
toFilterString: ->
|
|
parts = []
|
|
_.each @availableFilters, (filter, name) =>
|
|
filterName = filter.name
|
|
if filter.type == 'single'
|
|
return if @filters[name].query == ''
|
|
parts.push(filterName + '-' + @filters[name].query)
|
|
else
|
|
return if @filters[name].selectedArray.length == 0
|
|
parts.push(filterName + '-' + _.map(@filters[name].selectedArray, (f) -> f.id).join '-')
|
|
|
|
return parts.join '!'
|
|
|
|
fromFilterString: (str) ->
|
|
@hasLoadedFilters = true
|
|
@cachedDef = null
|
|
@resetFilters()
|
|
|
|
filters = (str || "").split '!'
|
|
for queryFilter in filters
|
|
parts = queryFilter.split '-'
|
|
queryName = parts[0]
|
|
|
|
filterName = null
|
|
filter = null
|
|
|
|
for name,f of @availableFilters
|
|
continue if f.name != queryName
|
|
filterName = name
|
|
filter = f
|
|
|
|
return if !filter
|
|
|
|
if filter.type == 'single'
|
|
filterToSet = _.find filter.values, (f) -> f.query == parts[1]
|
|
filterToSet = (_.find filter.values, (f) -> f.isDefault) if filterToSet == null
|
|
@setFilter filterName, filterToSet
|
|
else
|
|
@toggleListFilter filterName, id for id in _.rest parts, 1
|
|
|
|
listen: (listener) ->
|
|
@listeners.push listener
|
|
@cachedDef.done listener if @cachedDef
|
|
|
|
fetch: () ->
|
|
return @cachedDef if @cachedDef
|
|
@cachedDef = new $.Deferred()
|
|
playlistDef = @cachedDef
|
|
|
|
query = '/api/web/playlists?'
|
|
|
|
parts = ['page=' + @page]
|
|
_.each @availableFilters, (filter, name) =>
|
|
if filter.type == 'single'
|
|
parts.push @filters[name].filter
|
|
else
|
|
queryName = filter.filterName
|
|
for item in @filters[name].selectedArray
|
|
parts.push queryName + "[]=" + item.id
|
|
|
|
query += parts.join '&'
|
|
$http.get(query).success (playlists) =>
|
|
@playlists = playlists
|
|
for listener in @listeners
|
|
listener playlists
|
|
|
|
playlistDef.resolve playlists
|
|
|
|
playlistDef.promise()
|
|
|
|
|
|
self =
|
|
pinnedPlaylists: []
|
|
filters: {}
|
|
|
|
createQuery: -> new Query self.filters
|
|
|
|
loadFilters: ->
|
|
return filterDef if filterDef
|
|
|
|
filterDef = new $.Deferred()
|
|
self.filters.sort =
|
|
type: 'single'
|
|
name: 'sort'
|
|
values: [
|
|
{title: 'Most Favourited', query: 'favourites', isDefault: true, filter: 'order=favourite_count,desc'}
|
|
{title: 'Most Viewed', query: 'plays', isDefault: false, filter: 'order=view_count,desc'},
|
|
{title: 'Most Downloaded', query: 'downloads', isDefault: false, filter: 'order=download_count,desc'},
|
|
{title: 'Alphabetical', query: 'alphabetical', isDefault: false, filter: 'order=title,asc'},
|
|
{title: 'Latest', query: 'latest', isDefault: false, filter: 'order=created_at,desc'},
|
|
{title: 'Track count', query: 'tracks', isDefault: false, filter: 'order=track_count,desc'},
|
|
]
|
|
|
|
self.mainQuery = self.createQuery()
|
|
filterDef.resolve self
|
|
|
|
filterDef.promise()
|
|
|
|
fetchList: (page, force) ->
|
|
force = force || false
|
|
page = 1 if !page
|
|
return playlistPages[page] if !force && playlistPages[page]
|
|
playlistDef = new $.Deferred()
|
|
$http.get('/api/web/playlists?page=' + page).success (playlists) ->
|
|
playlistDef.resolve playlists
|
|
$rootScope.$broadcast 'playlists-feteched', playlists
|
|
|
|
playlistPages[page] = playlistDef.promise()
|
|
|
|
fetch: (id, force) ->
|
|
force = force || false
|
|
return playlists[id] if !force && playlists[id]
|
|
def = new $.Deferred()
|
|
$http.get('/api/web/playlists/' + id + '?log=true').success (playlist) ->
|
|
def.resolve playlist
|
|
|
|
playlists[id] = def.promise()
|
|
|
|
isPlaylistPinned: (id) ->
|
|
_.find(self.pinnedPlaylists, (p) -> `p.id == id`) != undefined
|
|
|
|
refreshOwned: (force) ->
|
|
force = force || false
|
|
return playlistDef if !force && playlistDef
|
|
|
|
playlistDef = new $.Deferred()
|
|
|
|
if auth.data.isLogged
|
|
$http.get('/api/web/playlists/owned').success (playlists) ->
|
|
playlistDef.resolve playlists
|
|
else
|
|
playlistDef.resolve []
|
|
|
|
playlistDef
|
|
|
|
addTrackToPlaylist: (playlistId, trackId) ->
|
|
def = new $.Deferred()
|
|
$http.post('/api/web/playlists/' + playlistId + '/add-track', {track_id: trackId}).success (res) ->
|
|
def.resolve(res)
|
|
|
|
def
|
|
|
|
removeTrackFromPlaylist: (playlistId, trackId) ->
|
|
def = new $.Deferred()
|
|
$http.post('/api/web/playlists/' + playlistId + '/remove-track', {track_id: trackId}).success (res) ->
|
|
def.resolve(res)
|
|
|
|
def
|
|
|
|
refresh: () ->
|
|
if auth.data.isLogged
|
|
$.getJSON('/api/web/playlists/pinned')
|
|
.done (playlists) -> $rootScope.$apply ->
|
|
self.pinnedPlaylists.length = 0
|
|
self.pinnedPlaylists.push playlist for playlist in playlists
|
|
|
|
deletePlaylist: (playlist) ->
|
|
def = new $.Deferred()
|
|
$.post('/api/web/playlists/delete/' + playlist.id)
|
|
.then -> $rootScope.$apply ->
|
|
if _.some(self.pinnedPlaylists, (p) -> p.id == playlist.id)
|
|
currentIndex = _.indexOf(self.pinnedPlaylists, (t) -> t.id == playlist.id)
|
|
self.pinnedPlaylists.splice currentIndex, 1
|
|
|
|
if $state.is('playlist') && $state.params.id == playlist.id
|
|
$state.transitionTo 'home'
|
|
|
|
def.resolve()
|
|
|
|
def
|
|
|
|
editPlaylist: (playlist) ->
|
|
def = new $.Deferred()
|
|
$.post('/api/web/playlists/edit/' + playlist.id, playlist)
|
|
.done (res) ->
|
|
$rootScope.$apply ->
|
|
currentIndex = _.indexOf(self.pinnedPlaylists, (t) -> t.id == playlist.id)
|
|
isPinned = _.some(self.pinnedPlaylists, (p) -> p.id == playlist.id)
|
|
|
|
if res.is_pinned && !isPinned
|
|
self.pinnedPlaylists.push res
|
|
self.pinnedPlaylists.sort (left, right) -> left.title.localeCompare right.title
|
|
currentIndex = _.indexOf(self.pinnedPlaylists, (t) -> t.id == playlist.id)
|
|
else if !res.is_pinned && isPinned
|
|
self.pinnedPlaylists.splice currentIndex, 1
|
|
currentIndex = _.indexOf(self.pinnedPlaylists, (t) -> t.id == playlist.id)
|
|
|
|
if res.is_pinned
|
|
current = self.pinnedPlaylists[currentIndex]
|
|
_.forEach res, (value, name) -> current[name] = value
|
|
self.pinnedPlaylists.sort (left, right) -> left.title.localeCompare right.title
|
|
|
|
def.resolve res
|
|
$rootScope.$broadcast 'playlist-updated', res
|
|
|
|
.fail (res)->
|
|
$rootScope.$apply ->
|
|
errors = {}
|
|
_.each res.responseJSON.errors, (value, key) -> errors[key] = value.join ', '
|
|
def.reject errors
|
|
|
|
def
|
|
|
|
createPlaylist: (playlist) ->
|
|
def = new $.Deferred()
|
|
$.post('/api/web/playlists/create', playlist)
|
|
.done (res) ->
|
|
$rootScope.$apply ->
|
|
if res.is_pinned
|
|
self.pinnedPlaylists.push res
|
|
self.pinnedPlaylists.sort (left, right) -> left.title.localeCompare right.title
|
|
|
|
def.resolve res
|
|
|
|
.fail (res)->
|
|
$rootScope.$apply ->
|
|
errors = {}
|
|
_.each res.responseJSON.errors, (value, key) -> errors[key] = value.join ', '
|
|
def.reject errors
|
|
|
|
def
|
|
|
|
|
|
self.refresh()
|
|
self
|
|
])
|
|
|