mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-01-31 03:16:42 +01:00
Things
This commit is contained in:
parent
a80de5ea8f
commit
d349fa1e6e
23 changed files with 274 additions and 88 deletions
|
@ -51,6 +51,7 @@
|
|||
|
||||
public function getIndex() {
|
||||
$page = 1;
|
||||
$perPage = 60;
|
||||
|
||||
if (Input::has('page'))
|
||||
$page = Input::get('page');
|
||||
|
@ -63,7 +64,7 @@
|
|||
$this->applyFilters($query);
|
||||
|
||||
$totalCount = $query->count();
|
||||
$query->take(30)->skip(30 * ($page - 1));
|
||||
$query->take($perPage)->skip(30 * ($page - 1));
|
||||
|
||||
$tracks = [];
|
||||
$ids = [];
|
||||
|
@ -73,7 +74,7 @@
|
|||
$ids[] = $track->id;
|
||||
}
|
||||
|
||||
return Response::json(["tracks" => $tracks, "current_page" => $page, "total_pages" => ceil($totalCount / 30)], 200);
|
||||
return Response::json(["tracks" => $tracks, "current_page" => $page, "total_pages" => ceil($totalCount / $perPage)], 200);
|
||||
}
|
||||
|
||||
public function getOwned() {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
new FileAsset('scripts/base/jquery-ui.js'),
|
||||
new FileAsset('scripts/base/jquery.cookie.js'),
|
||||
new FileAsset('scripts/base/jquery.colorbox.js'),
|
||||
new FileAsset('scripts/base/jquery.viewport.js'),
|
||||
new FileAsset('scripts/base/underscore.js'),
|
||||
new FileAsset('scripts/base/moment.js'),
|
||||
new FileAsset('scripts/base/soundmanager2-nodebug.js'),
|
||||
|
|
|
@ -11,16 +11,16 @@
|
|||
<div class="site-body">
|
||||
<ul class="sidebar" ng-controller="sidebar">
|
||||
@if (Auth::check())
|
||||
<li ng-class="{selected: $state.includes('home')}"><a href="/">Dashboard <i class="icon-home"></i></a></li>
|
||||
<li ng-class="{selected: stateIncludes('home')}"><a href="/">Dashboard <i class="icon-home"></i></a></li>
|
||||
@else
|
||||
<li ng-class="{selected: $state.includes('home')}"><a href="/">Home <i class="icon-home"></i></a></li>
|
||||
<li ng-class="{selected: stateIncludes('home')}"><a href="/">Home <i class="icon-home"></i></a></li>
|
||||
@endif
|
||||
<li ng-class="{selected: $state.includes('content')}">
|
||||
<li ng-class="{selected: stateIncludes('content')}">
|
||||
<a href="/tracks">Discover <i class="icon-music"></i></a>
|
||||
</li>
|
||||
|
||||
@if (Auth::check())
|
||||
<li ng-class="{selected: $state.includes('account-content') || isActive('/account')}"><a href="/account/tracks">Account <i class="icon-user"></i></a></li>
|
||||
<li ng-class="{selected: stateIncludes('account-content') || isActive('/account')}"><a href="/account/tracks">Account <i class="icon-user"></i></a></li>
|
||||
@endif
|
||||
|
||||
<li ng-class="{selected: isActive('/about')}"><a href="/about">Meta <i class="icon-info"></i></a></li>
|
||||
|
|
|
@ -5,6 +5,7 @@ angular.module('ponyfm').controller "application", [
|
|||
$scope.$state = $state
|
||||
$scope.$stateParams = $stateParams
|
||||
$loadingElement = null
|
||||
loadingStateName = null
|
||||
|
||||
$rootScope.safeApply = (fn) ->
|
||||
phase = $rootScope.$$phase
|
||||
|
@ -25,8 +26,20 @@ angular.module('ponyfm').controller "application", [
|
|||
$loadingElement.removeClass 'loading'
|
||||
$loadingElement = null
|
||||
|
||||
$scope.stateIncludes = (state) ->
|
||||
if $loadingElement
|
||||
newParts = state.split '.'
|
||||
oldParts = loadingStateName.split '.'
|
||||
for i in [0..newParts.length]
|
||||
continue if !newParts[i]
|
||||
return false if newParts[i] != oldParts[i]
|
||||
|
||||
return true
|
||||
else
|
||||
$state.includes(state)
|
||||
|
||||
statesPreloaded = {}
|
||||
$scope.$on '$stateChangeStart', (e, newState, newParams, oldState) ->
|
||||
$scope.$on '$stateChangeStart', (e, newState, newParams, oldState, oldParams) ->
|
||||
return if !oldState || !newState.controller
|
||||
|
||||
preloader = window.pfm.preloaders[newState.controller]
|
||||
|
@ -37,6 +50,7 @@ angular.module('ponyfm').controller "application", [
|
|||
return
|
||||
|
||||
e.preventDefault()
|
||||
loadingStateName = newState.name
|
||||
|
||||
selector = ''
|
||||
newParts = newState.name.split '.'
|
||||
|
|
|
@ -9,7 +9,6 @@ angular.module('ponyfm').controller "track", [
|
|||
($scope, tracks, $state, playlists, auth, favourites, $dialog) ->
|
||||
tracks.fetch($state.params.id).done (trackResponse) ->
|
||||
$scope.track = trackResponse.track
|
||||
$scope.trackArray = [$scope.track]
|
||||
|
||||
$scope.playlists = []
|
||||
|
||||
|
|
|
@ -2,10 +2,8 @@ window.pfm.preloaders['tracks-list'] = [
|
|||
'tracks', '$state'
|
||||
(tracks, $state) ->
|
||||
tracks.loadFilters().then(->
|
||||
if !tracks.mainQuery.hasLoadedFilters
|
||||
tracks.mainQuery.fromFilterString($state.params.filter)
|
||||
if $state.params.page
|
||||
tracks.mainQuery.setPage $state.params.page
|
||||
tracks.mainQuery.fromFilterString($state.params.filter)
|
||||
tracks.mainQuery.setPage $state.params.page || 1
|
||||
|
||||
tracks.mainQuery.fetch()
|
||||
)
|
||||
|
|
|
@ -23,6 +23,10 @@ angular.module('ponyfm').controller "tracks", [
|
|||
$scope.query.setListFilter filter, id
|
||||
$state.transitionTo 'content.tracks.list', {filter: $scope.query.toFilterString()}
|
||||
|
||||
$scope.clearFilter = (filter) ->
|
||||
$scope.query.clearFilter filter
|
||||
$state.transitionTo 'content.tracks.list', {filter: $scope.query.toFilterString()}
|
||||
|
||||
tracks.mainQuery.listen (searchResults) ->
|
||||
$scope.tracks = searchResults.tracks
|
||||
$scope.currentPage = parseInt(searchResults.current_page)
|
||||
|
|
|
@ -4,6 +4,7 @@ angular.module('ponyfm').directive 'pfmPlayer', () ->
|
|||
restrict: 'E'
|
||||
templateUrl: '/templates/directives/player.html'
|
||||
scope: {}
|
||||
replace: true
|
||||
|
||||
compile: (element) ->
|
||||
$element = element
|
||||
|
|
28
public/scripts/app/directives/scroll-recorder.coffee
Normal file
28
public/scripts/app/directives/scroll-recorder.coffee
Normal file
|
@ -0,0 +1,28 @@
|
|||
angular.module('ponyfm').directive 'pfmScrollRecorder', () ->
|
||||
(scope, element, attrs) ->
|
||||
timeout = null
|
||||
onScroll = null
|
||||
lastInView = null
|
||||
|
||||
element.scroll (e) ->
|
||||
(window.clearTimeout timeout) if timeout
|
||||
timeout = window.setTimeout (-> onScroll e), 500
|
||||
|
||||
onScroll = (e) -> scope.safeApply ->
|
||||
items = element.find 'li:not(.empty)'
|
||||
itemHeight = (items.eq 0).height()
|
||||
itemsArray = items.get()
|
||||
|
||||
elementViewTop = element.offset().top
|
||||
elementViewBottom = elementViewTop + element.height()
|
||||
|
||||
for i in [itemsArray.length - 1..0]
|
||||
listItem = $ itemsArray[i]
|
||||
|
||||
listItemTop = listItem.offset().top + itemHeight
|
||||
isInView = listItemTop > elementViewTop && listItemTop < elementViewBottom
|
||||
if isInView
|
||||
lastInView = listItem
|
||||
break
|
||||
|
||||
scope.$emit 'element-in-view', angular.element(lastInView).scope()
|
13
public/scripts/app/directives/track-player.coffee
Normal file
13
public/scripts/app/directives/track-player.coffee
Normal file
|
@ -0,0 +1,13 @@
|
|||
angular.module('ponyfm').directive 'pfmTrackPlayer', () ->
|
||||
restrict: 'E'
|
||||
templateUrl: '/templates/directives/track-player.html'
|
||||
scope:
|
||||
track: '=track',
|
||||
class: '@class'
|
||||
|
||||
controller: [
|
||||
'$scope', 'player'
|
||||
($scope, player) ->
|
||||
$scope.play = () ->
|
||||
player.playTracks [$scope.track], 0
|
||||
]
|
|
@ -12,7 +12,9 @@ angular.module('ponyfm').factory('tracks', [
|
|||
constructor: (@availableFilters) ->
|
||||
@filters = {}
|
||||
@hasLoadedFilters = false
|
||||
@resetFilters()
|
||||
|
||||
resetFilters: ->
|
||||
_.each @availableFilters, (filter, name) =>
|
||||
if filter.type == 'single'
|
||||
@filters[name] = _.find filter.values, (f) -> f.isDefault
|
||||
|
@ -38,6 +40,19 @@ angular.module('ponyfm').factory('tracks', [
|
|||
filter.selectedObject[id] = filterToAdd
|
||||
filter.title = filterToAdd.title
|
||||
|
||||
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'
|
||||
|
||||
toggleListFilter: (type, id) ->
|
||||
@cachedDef = null
|
||||
@page = 1
|
||||
|
@ -82,8 +97,10 @@ angular.module('ponyfm').factory('tracks', [
|
|||
|
||||
fromFilterString: (str) ->
|
||||
@hasLoadedFilters = true
|
||||
return if !str
|
||||
filters = str.split '!'
|
||||
@cachedDef = null
|
||||
@resetFilters()
|
||||
|
||||
filters = (str || "").split '!'
|
||||
for filter in filters
|
||||
parts = filter.split '-'
|
||||
name = parts[0]
|
||||
|
@ -91,7 +108,8 @@ angular.module('ponyfm').factory('tracks', [
|
|||
|
||||
if @availableFilters[name].type == 'single'
|
||||
filterToSet = _.find @availableFilters[name].values, (f) -> f.query == parts[1]
|
||||
filterToSet = _.find @availableFilters[name].values, (f) -> f.isDefault if filterToSet == null
|
||||
filterToSet = (_.find @availableFilters[name].values, (f) -> f.isDefault) if filterToSet == null
|
||||
@setFilter name, filterToSet
|
||||
else
|
||||
@toggleListFilter name, id for id in _.rest parts, 1
|
||||
|
||||
|
@ -116,6 +134,7 @@ angular.module('ponyfm').factory('tracks', [
|
|||
for listener in @listeners
|
||||
listener tracks
|
||||
|
||||
|
||||
trackDef.resolve tracks
|
||||
|
||||
trackDef.promise()
|
||||
|
@ -150,7 +169,7 @@ angular.module('ponyfm').factory('tracks', [
|
|||
type: 'single'
|
||||
values: [
|
||||
{title: 'Newest to Oldest', query: '', isDefault: true, filter: 'order=created_at,desc'},
|
||||
{title: 'Oldest to Newest', query: 'created_at,asc', isDefault: true, filter: 'order=created_at,asc'}
|
||||
{title: 'Oldest to Newest', query: 'created_at,asc', isDefault: false, filter: 'order=created_at,asc'}
|
||||
]
|
||||
|
||||
self.filters.genres =
|
||||
|
|
58
public/scripts/base/jquery.viewport.js
Normal file
58
public/scripts/base/jquery.viewport.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Viewport - jQuery selectors for finding elements in viewport
|
||||
*
|
||||
* Copyright (c) 2008-2009 Mika Tuupola
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/viewport
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.belowthefold = function(element, settings) {
|
||||
var fold = $(window).height() + $(window).scrollTop();
|
||||
return fold <= $(element).offset().top - settings.threshold;
|
||||
};
|
||||
|
||||
$.abovethetop = function(element, settings) {
|
||||
var top = $(window).scrollTop();
|
||||
return top >= $(element).offset().top + $(element).height() - settings.threshold;
|
||||
};
|
||||
|
||||
$.rightofscreen = function(element, settings) {
|
||||
var fold = $(window).width() + $(window).scrollLeft();
|
||||
return fold <= $(element).offset().left - settings.threshold;
|
||||
};
|
||||
|
||||
$.leftofscreen = function(element, settings) {
|
||||
var left = $(window).scrollLeft();
|
||||
return left >= $(element).offset().left + $(element).width() - settings.threshold;
|
||||
};
|
||||
|
||||
$.inviewport = function(element, settings) {
|
||||
return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
|
||||
};
|
||||
|
||||
$.extend($.expr[':'], {
|
||||
"below-the-fold": function(a, i, m) {
|
||||
return $.belowthefold(a, {threshold : 0});
|
||||
},
|
||||
"above-the-top": function(a, i, m) {
|
||||
return $.abovethetop(a, {threshold : 0});
|
||||
},
|
||||
"left-of-screen": function(a, i, m) {
|
||||
return $.leftofscreen(a, {threshold : 0});
|
||||
},
|
||||
"right-of-screen": function(a, i, m) {
|
||||
return $.rightofscreen(a, {threshold : 0});
|
||||
},
|
||||
"in-viewport": function(a, i, m) {
|
||||
return $.inviewport(a, {threshold : 0});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
})(jQuery);
|
|
@ -20,6 +20,34 @@
|
|||
margin-right: 10px;
|
||||
line-height: normal;
|
||||
|
||||
> .btn {
|
||||
float: left;
|
||||
display: block;
|
||||
}
|
||||
|
||||
> .btn + .btn {
|
||||
.transition(background 300ms ease-out);
|
||||
|
||||
display: none;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
&.has-filter {
|
||||
> .btn {
|
||||
background: @pfm-purple;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
> .btn + .btn {
|
||||
display: block;
|
||||
background: darken(@pfm-purple, 20%);
|
||||
|
||||
&:hover {
|
||||
background: darken(@pfm-purple, 40%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
> .btn {
|
||||
background: @pfm-purple;
|
||||
|
@ -320,7 +348,7 @@ html {
|
|||
|
||||
li.active a {
|
||||
background: @pfm-purple;
|
||||
color: #ddd;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,12 @@ html, body {
|
|||
|
||||
html body {
|
||||
height: 100%;
|
||||
background: @pfm-dark-grey;
|
||||
background: #444;
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
}
|
||||
|
||||
header, .site-body {
|
||||
.box-shadow(0 0 7px rgba(0, 0, 0, .3));
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
.box-shadow(0 0 7px rgba(0, 0, 0, .6));
|
||||
}
|
||||
|
||||
header {
|
||||
|
@ -50,9 +48,9 @@ header {
|
|||
}
|
||||
|
||||
.sidebar {
|
||||
background: @pfm-light-grey;
|
||||
width: @pfm-sidebar-size;
|
||||
height: 100%;
|
||||
background: @pfm-light-grey;
|
||||
float: left;
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
|
@ -68,6 +66,7 @@ header {
|
|||
background: #fff;
|
||||
|
||||
> a {
|
||||
cursor: default;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
@import-once 'mixins';
|
||||
@import-once 'variables';
|
||||
|
||||
@icon-size: 42px;
|
||||
|
||||
.tracks-listing.four-columns {
|
||||
li {
|
||||
float: left;
|
||||
|
@ -23,9 +25,40 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tracks-listing {
|
||||
@icon-size: 42px;
|
||||
.single-player, .tracks-listing li .image {
|
||||
float: left;
|
||||
width: @icon-size;
|
||||
height: @icon-size;
|
||||
position: relative;
|
||||
|
||||
.play-button {
|
||||
.transition(background 250ms ease-out);
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
font-size: 12pt;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
display: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .8);
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.tracks-listing {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
|
@ -34,44 +67,28 @@
|
|||
.clearfix();
|
||||
.box-sizing(border-box);
|
||||
|
||||
&.empty {
|
||||
.border-radius(0px);
|
||||
background: lighten(@pfm-purple, 30%);
|
||||
border: 1px solid lighten(@pfm-purple, 10%);
|
||||
color: lighten(@pfm-purple, 3%);
|
||||
float: none !important;
|
||||
width: auto !important;
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
font-size: 9pt;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(@pfm-purple, 30%);
|
||||
}
|
||||
}
|
||||
|
||||
line-height: normal;
|
||||
margin: 5px 0px;
|
||||
padding: 0px;
|
||||
padding-right: 10px;
|
||||
|
||||
.image {
|
||||
float: left;
|
||||
width: @icon-size;
|
||||
height: @icon-size;
|
||||
position: relative;
|
||||
|
||||
.play-button {
|
||||
.transition(background 250ms ease-out);
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
font-size: 12pt;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
display: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .8);
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.icons {
|
||||
float: right;
|
||||
display: block;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div>
|
||||
<ul class="tabs">
|
||||
<li ng-class="{active: $state.includes('account-content.tracks')}"><a href="/account/tracks">Tracks</a></li>
|
||||
<li ng-class="{active: $state.includes('account-content.albums')}"><a href="/account/albums">Albums</a></li>
|
||||
<li ng-class="{active: stateIncludes('account-content.tracks')}"><a href="/account/tracks">Tracks</a></li>
|
||||
<li ng-class="{active: stateIncludes('account-content.albums')}"><a href="/account/albums">Albums</a></li>
|
||||
</ul>
|
||||
|
||||
<ui-view></ui-view>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div>
|
||||
<ul class="tabs">
|
||||
<li ng-class="{active: $state.includes('account-favourites.tracks')}"><a href="/account/favourites">Tracks</a></li>
|
||||
<li ng-class="{active: $state.includes('account-favourites.albums')}"><a href="/account/favourites/albums">Albums</a></li>
|
||||
<li ng-class="{active: $state.includes('account-favourites.playlists')}"><a href="/account/favourites/playlists">Playlists</a></li>
|
||||
<li ng-class="{active: stateIncludes('account-favourites.tracks')}"><a href="/account/favourites">Tracks</a></li>
|
||||
<li ng-class="{active: stateIncludes('account-favourites.albums')}"><a href="/account/favourites/albums">Albums</a></li>
|
||||
<li ng-class="{active: stateIncludes('account-favourites.playlists')}"><a href="/account/favourites/playlists">Playlists</a></li>
|
||||
</ul>
|
||||
|
||||
<ui-view></ui-view>
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
</h1>
|
||||
|
||||
<ul class="tabs">
|
||||
<li ng-class="{active: $state.includes('artist.profile')}"><a href="{{artist.slug}}">Profile</a></li>
|
||||
<li ng-class="{active: $state.includes('artist.content')}"><a href="{{artist.slug}}/content">Content</a></li>
|
||||
<li ng-class="{active: $state.includes('artist.favourites')}"><a href="{{artist.slug}}/favourites">Favourites</a></li>
|
||||
<li ng-class="{active: stateIncludes('artist.profile')}"><a href="{{artist.slug}}">Profile</a></li>
|
||||
<li ng-class="{active: stateIncludes('artist.content')}"><a href="{{artist.slug}}/content">Content</a></li>
|
||||
<li ng-class="{active: stateIncludes('artist.favourites')}"><a href="{{artist.slug}}/favourites">Favourites</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<ul class="tabs">
|
||||
<li ng-class="{active: $state.includes('content.tracks') || $state.includes('content.track')}"><a href="/tracks">Tracks</a></li>
|
||||
<li ng-class="{active: $state.includes('content.artists') || $state.includes('content.artist')}"><a href="/artists">Artists</a></li>
|
||||
<li ng-class="{active: $state.includes('content.albums') || $state.includes('content.album')}"><a href="/albums">Albums</a></li>
|
||||
<li ng-class="{active: $state.includes('content.playlists') || $state.includes('content.playlist')}"><a href="/playlists">Playlists</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.tracks') || stateIncludes('content.track')}"><a href="/tracks">Tracks</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.artists') || stateIncludes('content.artist')}"><a href="/artists">Artists</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.albums') || stateIncludes('content.album')}"><a href="/albums">Albums</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.playlists') || stateIncludes('content.playlist')}"><a href="/playlists">Playlists</a></li>
|
||||
</ul>
|
||||
|
||||
<ui-view></ui-view>
|
7
public/templates/directives/track-player.html
Normal file
7
public/templates/directives/track-player.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div class="single-player">
|
||||
<a href="#" class="play-button" pfm-eat-click ng-click="play()">
|
||||
<i class="icon-play" ng-show="!track.isPlaying"></i>
|
||||
<i class="icon-pause" ng-hide="!track.isPlaying"></i>
|
||||
</a>
|
||||
<img ng-src="{{track.covers.thumbnail}}" />
|
||||
</div>
|
|
@ -1,3 +1,3 @@
|
|||
<div class="stretch-to-bottom">
|
||||
<pfm-tracks-list tracks="tracks" class="two-columns"></pfm-tracks-list>
|
||||
<pfm-tracks-list tracks="tracks" class="three-columns"></pfm-tracks-list>
|
||||
</div>
|
|
@ -1,8 +1,9 @@
|
|||
<ul class="dropdowns">
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle btn" ng-class="{'btn-info': query.filters.trackTypes.selectedArray.length}">
|
||||
Type: <strong class="ng-cloak">{{query.filters.trackTypes.title}}</strong>
|
||||
<li class="dropdown" ng-class="{'has-filter': query.filters.trackTypes.selectedArray.length}">
|
||||
<a class="dropdown-toggle btn">
|
||||
Type: <strong>{{query.filters.trackTypes.title}}</strong>
|
||||
</a>
|
||||
<a class="btn" pfm-eat-click ng-click="clearFilter('trackTypes')"><i class="icon-remove"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="type in filters.trackTypes.values" ng-class="{selected: query.isIdSelected('trackTypes', type.id)}">
|
||||
<a class="dont-close" pfm-eat-click href="#" ng-click="toggleListFilter('trackTypes', type.id); $event.stopPropagation();"><i class="icon-plus"></i></a>
|
||||
|
@ -10,10 +11,11 @@
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle btn" ng-class="{'btn-info': query.filters.showSongs.selectedArray.length}">
|
||||
<li class="dropdown" ng-class="{'has-filter': query.filters.showSongs.selectedArray.length}">
|
||||
<a class="dropdown-toggle btn">
|
||||
Show Songs: <strong>{{query.filters.showSongs.title}}</strong>
|
||||
</a>
|
||||
<a class="btn" pfm-eat-click ng-click="clearFilter('showSongs')"><i class="icon-remove"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="song in filters.showSongs.values" ng-class="{selected: query.isIdSelected('showSongs', song.id)}">
|
||||
<a class="dont-close" pfm-eat-click href="#" ng-click="toggleListFilter('showSongs', song.id); $event.stopPropagation();"><i class="icon-plus"></i></a>
|
||||
|
@ -21,10 +23,11 @@
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle btn" ng-class="{'btn-info': query.filters.genres.selectedArray.length}">
|
||||
<li class="dropdown" ng-class="{'has-filter': query.filters.genres.selectedArray.length}">
|
||||
<a class="dropdown-toggle btn">
|
||||
Genre: <strong>{{query.filters.genres.title}}</strong>
|
||||
</a>
|
||||
<a class="btn" pfm-eat-click ng-click="clearFilter('genres')"><i class="icon-remove"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="genre in filters.genres.values" ng-class="{selected: query.isIdSelected('genres', genre.id)}">
|
||||
<a class="dont-close" pfm-eat-click href="#" ng-click="toggleListFilter('genres', genre.id); $event.stopPropagation();"><i class="icon-plus"></i></a>
|
||||
|
@ -32,20 +35,22 @@
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle btn" ng-class="{'btn-info': !query.filters.isVocal.isDefault}">
|
||||
<li class="dropdown" ng-class="{'has-filter': !query.filters.isVocal.isDefault}">
|
||||
<a class="dropdown-toggle btn">
|
||||
Is Vocal: <strong>{{query.filters.isVocal.title}}</strong>
|
||||
</a>
|
||||
<a class="btn" pfm-eat-click ng-click="clearFilter('isVocal')"><i class="icon-remove"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="item in filters.isVocal.values" ng-class="{selected: item == query.filters.isVocal}">
|
||||
<a pfm-eat-click href="#" ng-click="setFilter('isVocal', item);">{{item.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle btn" ng-class="{'btn-info': !query.filters.sort.isDefault}">
|
||||
<li class="dropdown" ng-class="{'has-filter': !query.filters.sort.isDefault}">
|
||||
<a class="dropdown-toggle btn">
|
||||
Order: <strong>{{query.filters.sort.title}}</strong>
|
||||
</a>
|
||||
<a class="btn" pfm-eat-click ng-click="clearFilter('sort')"><i class="icon-remove"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="filter in filters.sort.values" ng-class="{selected: filter == query.filters.sort}">
|
||||
<a pfm-eat-click href="#" ng-click="setFilter('sort', filter)">{{filter.title}}</a>
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
<div class="track-details" xmlns="http://www.w3.org/1999/html">
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/tracks">Tracks</a> <span class="divider">/</span></li>
|
||||
<li><a href="/tracks?filter=genres-{{track.genre.id}}">{{track.genre.name}}</a> <span class="divider">/</span></li>
|
||||
<li class="active">{{track.title}}</li>
|
||||
</ul>
|
||||
|
||||
<div class="track-toolbar btn-group pull-right">
|
||||
<pfm-favourite-button resource="track" type="track"></pfm-favourite-button>
|
||||
<div class="dropdown">
|
||||
|
@ -31,7 +25,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<pfm-tracks-list tracks="trackArray"></pfm-tracks-list>
|
||||
<pfm-track-player track="track"></pfm-track-player>
|
||||
<h1>
|
||||
{{track.title}}
|
||||
<span class="subtitle">
|
||||
|
|
Loading…
Reference in a new issue