2013-07-31 13:47:16 +02:00
|
|
|
angular.module('ponyfm').factory('tracks', [
|
|
|
|
'$rootScope', '$http', 'taxonomies'
|
|
|
|
($rootScope, $http, taxonomies) ->
|
2013-08-01 01:04:04 +02:00
|
|
|
filterDef = null
|
|
|
|
trackCache = {}
|
2013-07-31 13:47:16 +02:00
|
|
|
|
|
|
|
class Query
|
|
|
|
cachedDef: null
|
|
|
|
page: 1
|
|
|
|
listeners: []
|
|
|
|
|
|
|
|
constructor: (@availableFilters) ->
|
|
|
|
@filters = {}
|
|
|
|
@hasLoadedFilters = false
|
2013-08-16 01:49:20 +02:00
|
|
|
@resetFilters()
|
2013-07-31 13:47:16 +02:00
|
|
|
|
2013-08-16 01:49:20 +02:00
|
|
|
resetFilters: ->
|
2013-07-31 13:47:16 +02:00
|
|
|
_.each @availableFilters, (filter, name) =>
|
|
|
|
if filter.type == 'single'
|
|
|
|
@filters[name] = _.find filter.values, (f) -> f.isDefault
|
|
|
|
else
|
|
|
|
@filters[name] = {title: 'Any', selectedArray: [], selectedObject: {}}
|
|
|
|
|
|
|
|
isIdSelected: (type, id) ->
|
|
|
|
@filters[type].selectedObject[id] != undefined
|
|
|
|
|
|
|
|
listen: (listener) ->
|
|
|
|
@listeners.push listener
|
|
|
|
@cachedDef.done listener if @cachedDef
|
|
|
|
|
|
|
|
setListFilter: (type, id) ->
|
|
|
|
@cachedDef = null
|
|
|
|
@page = 1
|
|
|
|
filterToAdd = _.find @availableFilters[type].values, (f) -> `f.id == id`
|
|
|
|
return if !filterToAdd
|
|
|
|
|
|
|
|
filter = @filters[type]
|
|
|
|
filter.selectedArray = [filterToAdd]
|
|
|
|
filter.selectedObject = {}
|
|
|
|
filter.selectedObject[id] = filterToAdd
|
|
|
|
filter.title = filterToAdd.title
|
|
|
|
|
2013-08-16 01:49:20 +02:00
|
|
|
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'
|
|
|
|
|
2013-07-31 13:47:16 +02:00
|
|
|
toggleListFilter: (type, id) ->
|
|
|
|
@cachedDef = null
|
|
|
|
@page = 1
|
|
|
|
filter = @filters[type]
|
|
|
|
|
|
|
|
if filter.selectedObject[id]
|
|
|
|
delete filter.selectedObject[id]
|
|
|
|
filter.selectedArray.splice _.indexOf(filter.selectedArray, (f) -> f.id == id), 1
|
|
|
|
else
|
|
|
|
filterToAdd = _.find @availableFilters[type].values, (f) -> `f.id == id`
|
|
|
|
return if !filterToAdd
|
|
|
|
filter.selectedObject[id] = filterToAdd
|
|
|
|
filter.selectedArray.push filterToAdd
|
|
|
|
|
|
|
|
if filter.selectedArray.length == 0
|
|
|
|
filter.title = 'Any'
|
|
|
|
else if filter.selectedArray.length == 1
|
|
|
|
filter.title = filter.selectedArray[0].title
|
|
|
|
else
|
|
|
|
filter.title = filter.selectedArray.length + ' selected'
|
|
|
|
|
|
|
|
setPage: (page) ->
|
|
|
|
@page = page
|
|
|
|
@cachedDef = null
|
|
|
|
|
|
|
|
setFilter: (type, value) ->
|
|
|
|
@cachedDef = null
|
|
|
|
@page = 1
|
|
|
|
@filters[type] = value
|
|
|
|
|
|
|
|
toFilterString: ->
|
|
|
|
parts = []
|
|
|
|
_.each @availableFilters, (filter, name) =>
|
|
|
|
if filter.type == 'single'
|
|
|
|
return if @filters[name].query == ''
|
|
|
|
parts.push(name + '-' + @filters[name].query)
|
|
|
|
else
|
|
|
|
return if @filters[name].selectedArray.length == 0
|
|
|
|
parts.push(name + '-' + _.map(@filters[name].selectedArray, (f) -> f.id).join '-')
|
|
|
|
|
|
|
|
return parts.join '!'
|
|
|
|
|
|
|
|
fromFilterString: (str) ->
|
|
|
|
@hasLoadedFilters = true
|
2013-08-16 01:49:20 +02:00
|
|
|
@cachedDef = null
|
|
|
|
@resetFilters()
|
|
|
|
|
|
|
|
filters = (str || "").split '!'
|
2013-07-31 13:47:16 +02:00
|
|
|
for filter in filters
|
|
|
|
parts = filter.split '-'
|
|
|
|
name = parts[0]
|
|
|
|
return if !@availableFilters[name]
|
|
|
|
|
|
|
|
if @availableFilters[name].type == 'single'
|
|
|
|
filterToSet = _.find @availableFilters[name].values, (f) -> f.query == parts[1]
|
2013-08-16 01:49:20 +02:00
|
|
|
filterToSet = (_.find @availableFilters[name].values, (f) -> f.isDefault) if filterToSet == null
|
|
|
|
@setFilter name, filterToSet
|
2013-07-31 13:47:16 +02:00
|
|
|
else
|
|
|
|
@toggleListFilter name, id for id in _.rest parts, 1
|
|
|
|
|
|
|
|
fetch: () ->
|
|
|
|
return @cachedDef if @cachedDef
|
|
|
|
@cachedDef = new $.Deferred()
|
2013-08-01 01:04:04 +02:00
|
|
|
trackDef = @cachedDef
|
2013-07-31 13:47:16 +02:00
|
|
|
|
|
|
|
query = '/api/web/tracks?'
|
|
|
|
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 (tracks) =>
|
|
|
|
@tracks = tracks
|
|
|
|
for listener in @listeners
|
|
|
|
listener tracks
|
|
|
|
|
2013-08-16 01:49:20 +02:00
|
|
|
|
2013-08-01 01:04:04 +02:00
|
|
|
trackDef.resolve tracks
|
2013-07-31 13:47:16 +02:00
|
|
|
|
2013-08-01 01:04:04 +02:00
|
|
|
trackDef.promise()
|
2013-07-31 13:47:16 +02:00
|
|
|
|
|
|
|
self =
|
|
|
|
filters: {}
|
|
|
|
|
2013-08-01 01:04:04 +02:00
|
|
|
fetch: (id, force) ->
|
|
|
|
force = force || false
|
|
|
|
return trackCache[id] if !force && trackCache[id]
|
|
|
|
trackDef = new $.Deferred()
|
2013-08-19 05:39:29 +02:00
|
|
|
$http.get('/api/web/tracks/' + id + '?log=true').success (track) ->
|
2013-08-01 01:04:04 +02:00
|
|
|
trackDef.resolve track
|
|
|
|
|
|
|
|
trackCache[id] = trackDef.promise()
|
|
|
|
|
2013-07-31 13:47:16 +02:00
|
|
|
createQuery: -> new Query self.filters
|
2013-08-01 01:04:04 +02:00
|
|
|
|
2013-07-31 13:47:16 +02:00
|
|
|
loadFilters: ->
|
2013-08-01 01:04:04 +02:00
|
|
|
return filterDef if filterDef
|
2013-07-31 13:47:16 +02:00
|
|
|
|
2013-08-01 01:04:04 +02:00
|
|
|
filterDef = new $.Deferred()
|
2013-07-31 13:47:16 +02:00
|
|
|
self.filters.isVocal =
|
|
|
|
type: 'single'
|
|
|
|
values: [
|
|
|
|
{title: 'Either', query: '', isDefault: true, filter: ''},
|
|
|
|
{title: 'Yes', query: 'yes', isDefault: false, filter: 'is_vocal=true'},
|
|
|
|
{title: 'No', query: 'no', isDefault: false, filter: 'is_vocal=false'}
|
|
|
|
]
|
|
|
|
|
|
|
|
self.filters.sort =
|
|
|
|
type: 'single'
|
|
|
|
values: [
|
2013-08-19 05:39:29 +02:00
|
|
|
{title: 'Latest', query: '', isDefault: true, filter: 'order=created_at,desc'},
|
|
|
|
{title: 'Most Played', query: 'play_count', isDefault: false, filter: 'order=play_count,desc'},
|
|
|
|
{title: 'Most Downloaded', query: 'download_count', isDefault: false, filter: 'order=download_count,desc'},
|
|
|
|
{title: 'Most Favourited', query: 'favourite_count', isDefault: false, filter: 'order=favourite_count,desc'}
|
2013-07-31 13:47:16 +02:00
|
|
|
]
|
|
|
|
|
|
|
|
self.filters.genres =
|
|
|
|
type: 'list'
|
|
|
|
values: []
|
|
|
|
filterName: 'genres'
|
|
|
|
|
|
|
|
self.filters.trackTypes =
|
|
|
|
type: 'list'
|
|
|
|
values: []
|
|
|
|
filterName: 'types'
|
|
|
|
|
|
|
|
self.filters.showSongs =
|
|
|
|
type: 'list'
|
|
|
|
values: []
|
|
|
|
filterName: 'songs'
|
|
|
|
|
|
|
|
taxonomies.refresh().done (taxes) ->
|
|
|
|
for genre in taxes.genresWithTracks
|
|
|
|
self.filters.genres.values.push
|
|
|
|
title: genre.name
|
|
|
|
id: genre.id
|
|
|
|
|
|
|
|
for type in taxes.trackTypesWithTracks
|
|
|
|
self.filters.trackTypes.values.push
|
|
|
|
title: type.title
|
|
|
|
id: type.id
|
|
|
|
|
|
|
|
for song in taxes.showSongsWithTracks
|
|
|
|
self.filters.showSongs.values.push
|
|
|
|
title: song.title
|
|
|
|
id: song.id
|
|
|
|
|
|
|
|
self.mainQuery = self.createQuery()
|
2013-08-01 01:04:04 +02:00
|
|
|
filterDef.resolve self
|
2013-07-31 13:47:16 +02:00
|
|
|
|
2013-08-01 01:04:04 +02:00
|
|
|
filterDef.promise()
|
2013-07-31 13:47:16 +02:00
|
|
|
|
|
|
|
self
|
|
|
|
])
|