mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-02-16 18:14:23 +01:00
Logout
Volume Slider Track Uploader Fav list A bunch of other things And stuff.
This commit is contained in:
parent
1dff7cb36f
commit
18e41d2af4
58 changed files with 1013 additions and 359 deletions
|
@ -3,10 +3,96 @@
|
||||||
namespace Api\Web;
|
namespace Api\Web;
|
||||||
|
|
||||||
use Commands\ToggleFavouriteCommand;
|
use Commands\ToggleFavouriteCommand;
|
||||||
|
use Entities\Album;
|
||||||
|
use Entities\Favourite;
|
||||||
|
use Entities\Playlist;
|
||||||
|
use Entities\Track;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Input;
|
use Illuminate\Support\Facades\Input;
|
||||||
|
use Illuminate\Support\Facades\Response;
|
||||||
|
|
||||||
class FavouritesController extends \ApiControllerBase {
|
class FavouritesController extends \ApiControllerBase {
|
||||||
public function postToggle() {
|
public function postToggle() {
|
||||||
return $this->execute(new ToggleFavouriteCommand(Input::get('type'), Input::get('id')));
|
return $this->execute(new ToggleFavouriteCommand(Input::get('type'), Input::get('id')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTracks() {
|
||||||
|
$query = Favourite
|
||||||
|
::whereUserId(Auth::user()->id)
|
||||||
|
->whereNotNull('track_id')
|
||||||
|
->with([
|
||||||
|
'track' => function($query) {
|
||||||
|
$query
|
||||||
|
->userDetails()
|
||||||
|
->published();
|
||||||
|
},
|
||||||
|
'track.user',
|
||||||
|
'track.genre',
|
||||||
|
'track.cover',
|
||||||
|
'track.album',
|
||||||
|
'track.album.user'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tracks = [];
|
||||||
|
|
||||||
|
foreach ($query->get() as $fav) {
|
||||||
|
if ($fav->track == null) // deleted track
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$tracks[] = Track::mapPublicTrackSummary($fav->track);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::json(["tracks" => $tracks], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAlbums() {
|
||||||
|
$query = Favourite
|
||||||
|
::whereUserId(Auth::user()->id)
|
||||||
|
->whereNotNull('album_id')
|
||||||
|
->with([
|
||||||
|
'album' => function($query) {
|
||||||
|
$query->userDetails();
|
||||||
|
},
|
||||||
|
'album.user',
|
||||||
|
'album.user.avatar',
|
||||||
|
'album.cover'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$albums = [];
|
||||||
|
|
||||||
|
foreach ($query->get() as $fav) {
|
||||||
|
if ($fav->album == null) // deleted album
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$albums[] = Album::mapPublicAlbumSummary($fav->album);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::json(["albums" => $albums], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlaylists() {
|
||||||
|
$query = Favourite
|
||||||
|
::whereUserId(Auth::user()->id)
|
||||||
|
->whereNotNull('playlist_id')
|
||||||
|
->with([
|
||||||
|
'playlist' => function($query) {
|
||||||
|
$query->userDetails();
|
||||||
|
},
|
||||||
|
'playlist.user',
|
||||||
|
'playlist.user.avatar',
|
||||||
|
'playlist.tracks',
|
||||||
|
'playlist.tracks.cover'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$playlists = [];
|
||||||
|
|
||||||
|
foreach ($query->get() as $fav) {
|
||||||
|
if ($fav->playlist == null) // deleted playlist
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$playlists[] = Playlist::mapPublicPlaylistSummary($fav->playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::json(["playlists" => $playlists], 200);
|
||||||
|
}
|
||||||
}
|
}
|
7
app/controllers/UploaderController.php
Normal file
7
app/controllers/UploaderController.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class UploaderController extends Controller {
|
||||||
|
public function getIndex() {
|
||||||
|
return View::make('shared.null');
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,12 +35,11 @@
|
||||||
* @return CommandResponse
|
* @return CommandResponse
|
||||||
*/
|
*/
|
||||||
public function execute() {
|
public function execute() {
|
||||||
$isVocal = isset($this->_input['is_vocal']) && $this->_input['is_vocal'] == 'true' ? true : false;
|
$isVocal = (isset($this->_input['is_vocal']) && $this->_input['is_vocal'] == 'true') ? true : false;
|
||||||
|
|
||||||
$rules = [
|
$rules = [
|
||||||
'title' => 'required|min:3|max:80',
|
'title' => 'required|min:3|max:80',
|
||||||
'released_at' => 'before:today' . ($this->_input['released_at'] != "" ? '|date' : ''),
|
'released_at' => 'before:today' . ($this->_input['released_at'] != "" ? '|date' : ''),
|
||||||
'lyrics' => $isVocal ? 'required' : '',
|
|
||||||
'license_id' => 'required|exists:licenses,id',
|
'license_id' => 'required|exists:licenses,id',
|
||||||
'genre_id' => 'required|exists:genres,id',
|
'genre_id' => 'required|exists:genres,id',
|
||||||
'cover' => 'image|mimes:png|min_width:350|min_height:350',
|
'cover' => 'image|mimes:png|min_width:350|min_height:350',
|
||||||
|
@ -50,6 +49,9 @@
|
||||||
'album_id' => 'exists:albums,id'
|
'album_id' => 'exists:albums,id'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($isVocal)
|
||||||
|
$rules['lyrics'] = 'required';
|
||||||
|
|
||||||
if ($this->_input['track_type_id'] == 2)
|
if ($this->_input['track_type_id'] == 2)
|
||||||
$rules['show_song_ids'] = 'required|exists:show_songs,id';
|
$rules['show_song_ids'] = 'required|exists:show_songs,id';
|
||||||
|
|
||||||
|
@ -80,7 +82,7 @@
|
||||||
$track->album_id = $this->_input['album_id'];
|
$track->album_id = $this->_input['album_id'];
|
||||||
|
|
||||||
Album::whereId($album->id)->update([
|
Album::whereId($album->id)->update([
|
||||||
'track_count' => DB::raw('SELECT COUNT(id) FROM tracks WHERE album_id = ' . $album->id)
|
'track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE album_id = ' . $album->id . ')')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -132,7 +132,11 @@
|
||||||
'name' => $album->user->display_name,
|
'name' => $album->user->display_name,
|
||||||
'url' => $album->user->url,
|
'url' => $album->user->url,
|
||||||
],
|
],
|
||||||
'user_data' => $userData
|
'user_data' => $userData,
|
||||||
|
'permissions' => [
|
||||||
|
'delete' => Auth::check() && Auth::user()->id == $album->user_id,
|
||||||
|
'edit' => Auth::check() && Auth::user()->id == $album->user_id
|
||||||
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,11 @@
|
||||||
'name' => $playlist->user->display_name,
|
'name' => $playlist->user->display_name,
|
||||||
'url' => $playlist->user->url,
|
'url' => $playlist->user->url,
|
||||||
],
|
],
|
||||||
'user_data' => $userData
|
'user_data' => $userData,
|
||||||
|
'permissions' => [
|
||||||
|
'delete' => Auth::check() && Auth::user()->id == $playlist->user_id,
|
||||||
|
'edit' => Auth::check() && Auth::user()->id == $playlist->user_id
|
||||||
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
$query->whereUserId(Auth::user()->id);
|
$query->whereUserId(Auth::user()->id);
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !$query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopePublished($query) {
|
public function scopePublished($query) {
|
||||||
|
@ -194,7 +192,11 @@
|
||||||
'streams' => [
|
'streams' => [
|
||||||
'mp3' => $track->getStreamUrl('MP3')
|
'mp3' => $track->getStreamUrl('MP3')
|
||||||
],
|
],
|
||||||
'user_data' => $userData
|
'user_data' => $userData,
|
||||||
|
'permissions' => [
|
||||||
|
'delete' => Auth::check() && Auth::user()->id == $track->user_id,
|
||||||
|
'edit' => Auth::check() && Auth::user()->id == $track->user_id
|
||||||
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,10 @@
|
||||||
|
|
||||||
Route::get('/playlists/owned', 'Api\Web\PlaylistsController@getOwned');
|
Route::get('/playlists/owned', 'Api\Web\PlaylistsController@getOwned');
|
||||||
Route::get('/playlists/pinned', 'Api\Web\PlaylistsController@getPinned');
|
Route::get('/playlists/pinned', 'Api\Web\PlaylistsController@getPinned');
|
||||||
|
|
||||||
|
Route::get('/favourites/tracks', 'Api\Web\FavouritesController@getTracks');
|
||||||
|
Route::get('/favourites/albums', 'Api\Web\FavouritesController@getAlbums');
|
||||||
|
Route::get('/favourites/playlists', 'Api\Web\FavouritesController@getPlaylists');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['before' => 'csrf'], function(){
|
Route::group(['before' => 'csrf'], function(){
|
||||||
|
@ -127,6 +131,8 @@
|
||||||
Route::get('/albums/create', 'ContentController@getAlbums');
|
Route::get('/albums/create', 'ContentController@getAlbums');
|
||||||
Route::get('/playlists', 'ContentController@getPlaylists');
|
Route::get('/playlists', 'ContentController@getPlaylists');
|
||||||
|
|
||||||
|
Route::get('/uploader', 'UploaderController@getIndex');
|
||||||
|
|
||||||
Route::get('/', 'AccountController@getIndex');
|
Route::get('/', 'AccountController@getIndex');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,6 +26,18 @@
|
||||||
<header>
|
<header>
|
||||||
<a href="/">Pony.fm</a>
|
<a href="/">Pony.fm</a>
|
||||||
<div class="now-playing">
|
<div class="now-playing">
|
||||||
|
@if (Auth::check())
|
||||||
|
<div class="user-details dropdown">
|
||||||
|
<a class="avatar dropdown-toggle" href="#">
|
||||||
|
<img src="{{Auth::user()->getAvatarUrl(\Entities\Image::THUMBNAIL)}}" />
|
||||||
|
<span><i class="icon-chevron-down"></i></span>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="{{Auth::user()->url}}">Your Profile</a></li>
|
||||||
|
<li><a href="#" pfm-eat-click ng-click="logout()">Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<pfm-player></pfm-player>
|
<pfm-player></pfm-player>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -42,29 +54,25 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@if (Auth::check())
|
@if (Auth::check())
|
||||||
<li ng-class="{selected: stateIncludes('account-content') || isActive('/account')}"><a href="/account/tracks">Account <i class="icon-user"></i></a></li>
|
<li ng-class="{selected: stateIncludes('account')}"><a href="/account/tracks">Account <i class="icon-user"></i></a></li>
|
||||||
|
<li ng-class="{selected: stateIncludes('favourites')}"><a href="/account/favourites/tracks">Favourites <i class="icon-star"></i></a></li>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<li ng-class="{selected: isActive('/about')}"><a href="/about">Meta <i class="icon-info"></i></a></li>
|
<li ng-class="{selected: isActive('/about')}"><a href="/about">About <i class="icon-info"></i></a></li>
|
||||||
|
|
||||||
@if (Auth::check())
|
@if (Auth::check())
|
||||||
|
<li class="uploader" ng-class="{selected: stateIncludes('uploader')}">
|
||||||
|
<a href="/account/uploader">Upload Music <i class="icon-upload-alt"></i></a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
<a href="#" ng-click="createPlaylist()" pfm-eat-click title="Create Playlist"><i class="icon-plus"></i></a>
|
<a href="#" ng-click="createPlaylist()" pfm-eat-click title="Create Playlist"><i class="icon-plus"></i></a>
|
||||||
<a href="/account/playlists" ng-class="{selected: $state.is('account-content-playlists')}" title="View Playlists" class="view-all"><i class="icon-list"></i></a>
|
|
||||||
Playlists
|
Playlists
|
||||||
</h3>
|
</h3>
|
||||||
</li>
|
</li>
|
||||||
<li class="none" ng-show="!playlists.length"><span>no pinned playlists</span></li>
|
<li class="none" ng-show="!playlists.length"><span>no pinned playlists</span></li>
|
||||||
<li class="dropdown" ng-repeat="playlist in playlists" ng-cloak ng-class="{selected: stateIncludes('content.playlist') && $state.params.id == playlist.id}">
|
<li class="dropdown" ng-repeat="playlist in playlists" ng-cloak ng-class="{selected: stateIncludes('content.playlist') && $state.params.id == playlist.id}">
|
||||||
<a class="menu dropdown-toggle" pfm-eat-click href="#"><i class="icon-ellipsis-vertical"></i></a>
|
|
||||||
<a href="{{Helpers::angular('playlist.url')}}" ng-bind="playlist.title"></a>
|
<a href="{{Helpers::angular('playlist.url')}}" ng-bind="playlist.title"></a>
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="#" pfm-eat-click ng-click="editPlaylist(playlist)">Edit</a></li>
|
|
||||||
<li><a href="#" pfm-eat-click ng-click="unpinPlaylist(playlist)">Unpin</a></li>
|
|
||||||
<li><a href="#" pfm-eat-click ng-click="deletePlaylist(playlist)" ng-show="playlist.user_id == auth.user_id">Delete</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -73,8 +81,6 @@
|
||||||
</ui-view>
|
</ui-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-include src="'templates/partials/upload-dialog.html'"></ng-include>
|
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('styles')
|
@section('styles')
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
@yield('styles')
|
@yield('styles')
|
||||||
</head>
|
</head>
|
||||||
<body ng-app="ponyfm" ng-controller="application" uploader>
|
<body ng-app="ponyfm" ng-controller="application">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
@yield('scripts')
|
@yield('scripts')
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -6,64 +6,74 @@ module.config [
|
||||||
'$locationProvider', '$stateProvider', '$dialogProvider'
|
'$locationProvider', '$stateProvider', '$dialogProvider'
|
||||||
(location, state, $dialogProvider) ->
|
(location, state, $dialogProvider) ->
|
||||||
|
|
||||||
|
# Upload
|
||||||
|
|
||||||
|
state.state 'uploader',
|
||||||
|
url: '/account/uploader'
|
||||||
|
templateUrl: '/templates/uploader/index.html'
|
||||||
|
controller: 'uploader'
|
||||||
|
|
||||||
# Account
|
# Account
|
||||||
|
|
||||||
state.state 'account',
|
state.state 'account',
|
||||||
url: '/account'
|
url: '/account'
|
||||||
|
abstract: true
|
||||||
|
templateUrl: '/templates/account/_layout.html'
|
||||||
|
|
||||||
|
state.state 'account.settings',
|
||||||
|
url: ''
|
||||||
templateUrl: '/templates/account/settings.html'
|
templateUrl: '/templates/account/settings.html'
|
||||||
controller: 'account-settings'
|
controller: 'account-settings'
|
||||||
|
|
||||||
state.state 'account-content',
|
state.state 'account.tracks',
|
||||||
url: '/account'
|
|
||||||
abstract: true
|
|
||||||
templateUrl: '/templates/account/content/_layout.html'
|
|
||||||
|
|
||||||
state.state 'account-content.tracks',
|
|
||||||
url: '/tracks'
|
url: '/tracks'
|
||||||
templateUrl: '/templates/account/content/tracks.html'
|
templateUrl: '/templates/account/tracks.html'
|
||||||
controller: 'account-tracks'
|
controller: 'account-tracks'
|
||||||
|
|
||||||
state.state 'account-content.tracks.edit',
|
state.state 'account.tracks.edit',
|
||||||
url: '/edit/:track_id'
|
url: '/edit/:track_id'
|
||||||
templateUrl: '/templates/account/content/track.html'
|
templateUrl: '/templates/account/track.html'
|
||||||
controller: 'account-tracks-edit'
|
controller: 'account-track'
|
||||||
|
|
||||||
state.state 'account-content.albums',
|
state.state 'account.albums',
|
||||||
url: '/albums'
|
url: '/albums'
|
||||||
templateUrl: '/templates/account/content/albums.html'
|
templateUrl: '/templates/account/albums.html'
|
||||||
controller: 'account-albums'
|
controller: 'account-albums'
|
||||||
|
|
||||||
state.state 'account-content.albums.create',
|
state.state 'account.albums.create',
|
||||||
url: '/create'
|
url: '/create'
|
||||||
templateUrl: '/templates/account/content/album.html'
|
templateUrl: '/templates/account/album.html'
|
||||||
controller: 'account-albums-edit'
|
controller: 'account-albums-edit'
|
||||||
|
|
||||||
state.state 'account-content.albums.edit',
|
state.state 'account.albums.edit',
|
||||||
url: '/edit/:album_id'
|
url: '/edit/:album_id'
|
||||||
templateUrl: '/templates/account/content/album.html'
|
templateUrl: '/templates/account/album.html'
|
||||||
controller: 'account-albums-edit'
|
controller: 'account-albums-edit'
|
||||||
|
|
||||||
state.state 'account-content-playlists',
|
state.state 'account.playlists',
|
||||||
url: '/account/playlists'
|
url: '/playlists'
|
||||||
templateUrl: '/templates/account/content/playlists.html'
|
templateUrl: '/templates/account/playlists.html'
|
||||||
controller: 'account-playlists'
|
controller: 'account-playlists'
|
||||||
|
|
||||||
state.state 'account-favourites',
|
state.state 'favourites',
|
||||||
url: '/account/favourites'
|
url: '/account/favourites'
|
||||||
abstract: true
|
abstract: true
|
||||||
templateUrl: '/templates/account/favourites/_layout.html'
|
templateUrl: '/templates/favourites/_layout.html'
|
||||||
|
|
||||||
state.state 'account-favourites.tracks',
|
state.state 'favourites.tracks',
|
||||||
url: ''
|
url: '/tracks'
|
||||||
templateUrl: '/templates/account/favourites/tracks.html'
|
templateUrl: '/templates/favourites/tracks.html'
|
||||||
|
controller: 'favourites-tracks'
|
||||||
|
|
||||||
state.state 'account-favourites.playlists',
|
state.state 'favourites.playlists',
|
||||||
url: '/playlists'
|
url: '/playlists'
|
||||||
templateUrl: '/templates/account/favourites/playlists.html'
|
templateUrl: '/templates/favourites/playlists.html'
|
||||||
|
controller: 'favourites-playlists'
|
||||||
|
|
||||||
state.state 'account-favourites.albums',
|
state.state 'favourites.albums',
|
||||||
url: '/albums'
|
url: '/albums'
|
||||||
templateUrl: '/templates/account/favourites/albums.html'
|
templateUrl: '/templates/favourites/albums.html'
|
||||||
|
controller: 'favourites-albums'
|
||||||
|
|
||||||
# Tracks
|
# Tracks
|
||||||
|
|
||||||
|
@ -72,14 +82,14 @@ module.config [
|
||||||
templateUrl: '/templates/content/_layout.html'
|
templateUrl: '/templates/content/_layout.html'
|
||||||
|
|
||||||
state.state 'content.tracks',
|
state.state 'content.tracks',
|
||||||
templateUrl: '/templates/tracks/search.html'
|
templateUrl: '/templates/tracks/index.html'
|
||||||
controller: 'tracks'
|
controller: 'tracks'
|
||||||
url: '/tracks'
|
url: '/tracks'
|
||||||
abstract: true
|
abstract: true
|
||||||
|
|
||||||
state.state 'content.tracks.list',
|
state.state 'content.tracks.list',
|
||||||
url: '^/tracks?filter&page'
|
url: '^/tracks?filter&page'
|
||||||
templateUrl: '/templates/tracks/search-list.html'
|
templateUrl: '/templates/tracks/list.html'
|
||||||
controller: 'tracks-list'
|
controller: 'tracks-list'
|
||||||
|
|
||||||
state.state 'content.track',
|
state.state 'content.track',
|
||||||
|
|
|
@ -73,7 +73,7 @@ angular.module('ponyfm').controller "account-albums-edit", [
|
||||||
if $scope.isNew
|
if $scope.isNew
|
||||||
$scope.isDirty = false
|
$scope.isDirty = false
|
||||||
$scope.$emit 'album-created'
|
$scope.$emit 'album-created'
|
||||||
$state.transitionTo 'account-content.albums.edit', {album_id: response.id}
|
$state.transitionTo 'account.albums.edit', {album_id: response.id}
|
||||||
else
|
else
|
||||||
$scope.isDirty = false
|
$scope.isDirty = false
|
||||||
$scope.data.selectedAlbum.title = $scope.album.title
|
$scope.data.selectedAlbum.title = $scope.album.title
|
||||||
|
@ -104,7 +104,7 @@ angular.module('ponyfm').controller "account-albums-edit", [
|
||||||
$.post('/api/web/albums/delete/' + $scope.album.id, {_token: window.pfm.token})
|
$.post('/api/web/albums/delete/' + $scope.album.id, {_token: window.pfm.token})
|
||||||
.then -> $scope.$apply ->
|
.then -> $scope.$apply ->
|
||||||
$scope.$emit 'album-deleted'
|
$scope.$emit 'album-deleted'
|
||||||
$state.transitionTo 'account-content.albums'
|
$state.transitionTo 'account.albums'
|
||||||
|
|
||||||
$scope.setCover = (image, type) ->
|
$scope.setCover = (image, type) ->
|
||||||
delete $scope.album.cover_id
|
delete $scope.album.cover_id
|
||||||
|
|
|
@ -13,6 +13,8 @@ angular.module('ponyfm').controller "account-albums", [
|
||||||
selectedAlbum: null
|
selectedAlbum: null
|
||||||
tracksDb: []
|
tracksDb: []
|
||||||
|
|
||||||
|
selectAlbum = (album) -> $scope.data.selectedAlbum = album
|
||||||
|
|
||||||
updateTracks = (tracks) ->
|
updateTracks = (tracks) ->
|
||||||
$scope.data.tracksDb.push track for track in tracks
|
$scope.data.tracksDb.push track for track in tracks
|
||||||
|
|
||||||
|
@ -32,8 +34,6 @@ angular.module('ponyfm').controller "account-albums", [
|
||||||
|
|
||||||
albums.refresh().done updateAlbums
|
albums.refresh().done updateAlbums
|
||||||
|
|
||||||
selectAlbum = (album) -> $scope.data.selectedAlbum = album
|
|
||||||
|
|
||||||
$scope.$on '$stateChangeSuccess', () ->
|
$scope.$on '$stateChangeSuccess', () ->
|
||||||
if $state.params.album_id
|
if $state.params.album_id
|
||||||
selectAlbum albumsDb[$state.params.album_id]
|
selectAlbum albumsDb[$state.params.album_id]
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
window.pfm.preloaders['account-tracks-edit'] = [
|
window.pfm.preloaders['account-track'] = [
|
||||||
'account-tracks', 'account-albums', 'taxonomies', '$state'
|
'account-tracks', 'account-albums', 'taxonomies', '$state'
|
||||||
(tracks, albums, taxonomies, state) ->
|
(tracks, albums, taxonomies, state) ->
|
||||||
$.when.all [albums.refresh(), taxonomies.refresh(), tracks.getEdit(state.params.track_id, true)]
|
$.when.all [albums.refresh(), taxonomies.refresh(), tracks.getEdit(state.params.track_id, true)]
|
||||||
]
|
]
|
||||||
|
|
||||||
angular.module('ponyfm').controller "account-tracks-edit", [
|
angular.module('ponyfm').controller "account-track", [
|
||||||
'$scope', '$state', 'taxonomies', '$dialog', 'account-albums', 'account-tracks'
|
'$scope', '$state', 'taxonomies', '$dialog', 'account-albums', 'account-tracks', 'images'
|
||||||
($scope, $state, taxonomies, $dialog, albums, tracks) ->
|
($scope, $state, taxonomies, $dialog, albums, tracks, images) ->
|
||||||
$scope.isDirty = false
|
$scope.isDirty = false
|
||||||
$scope.isSaving = false
|
$scope.isSaving = false
|
||||||
$scope.taxonomies = taxonomies
|
$scope.taxonomies = taxonomies
|
||||||
|
@ -85,6 +85,7 @@ angular.module('ponyfm').controller "account-tracks-edit", [
|
||||||
trackDbItem.cover_url = track.real_cover_url
|
trackDbItem.cover_url = track.real_cover_url
|
||||||
$scope.isDirty = false
|
$scope.isDirty = false
|
||||||
$scope.errors = {}
|
$scope.errors = {}
|
||||||
|
images.refresh true
|
||||||
|
|
||||||
formData = new FormData();
|
formData = new FormData();
|
||||||
_.each $scope.edit, (value, name) ->
|
_.each $scope.edit, (value, name) ->
|
||||||
|
@ -136,7 +137,7 @@ angular.module('ponyfm').controller "account-tracks-edit", [
|
||||||
$.post('/api/web/tracks/delete/' + track.id, {_token: window.pfm.token})
|
$.post('/api/web/tracks/delete/' + track.id, {_token: window.pfm.token})
|
||||||
.then -> $scope.$apply ->
|
.then -> $scope.$apply ->
|
||||||
$scope.$emit 'track-deleted'
|
$scope.$emit 'track-deleted'
|
||||||
$state.transitionTo 'account-content.tracks'
|
$state.transitionTo 'account.tracks'
|
||||||
|
|
||||||
$scope.$on '$locationChangeStart', (e) ->
|
$scope.$on '$locationChangeStart', (e) ->
|
||||||
return if !$scope.isDirty
|
return if !$scope.isDirty
|
|
@ -26,67 +26,8 @@ angular.module('ponyfm').controller "account-tracks", [
|
||||||
|
|
||||||
tracks.refresh().done setTracks
|
tracks.refresh().done setTracks
|
||||||
|
|
||||||
$scope.filters =
|
|
||||||
published: [
|
|
||||||
{title: 'Either', query: ''},
|
|
||||||
{title: 'Yes', query: 'published=1'},
|
|
||||||
{title: 'No', query: 'published=0'}]
|
|
||||||
|
|
||||||
sort: [
|
|
||||||
{title: 'Newest to Oldest', query: 'order=created_at,desc'},
|
|
||||||
{title: 'Oldest to Newest', query: 'order=created_at,asc'}]
|
|
||||||
|
|
||||||
genres: {}
|
|
||||||
trackTypes: {}
|
|
||||||
|
|
||||||
$scope.filter =
|
|
||||||
published: $scope.filters.published[0]
|
|
||||||
sort: $scope.filters.sort[0]
|
|
||||||
genres: {}
|
|
||||||
trackTypes: {}
|
|
||||||
|
|
||||||
$scope.titles =
|
|
||||||
genres: 'All'
|
|
||||||
trackTypes: 'All'
|
|
||||||
|
|
||||||
for genre in taxonomies.genres
|
|
||||||
$scope.filters.genres[genre.id] =
|
|
||||||
id: genre.id
|
|
||||||
title: genre.name
|
|
||||||
query: 'genres[]=' + genre.id
|
|
||||||
|
|
||||||
for type in taxonomies.trackTypes
|
|
||||||
$scope.filters.trackTypes[type.id] =
|
|
||||||
id: type.id
|
|
||||||
title: type.title
|
|
||||||
query: 'types[]=' + type.id
|
|
||||||
|
|
||||||
$scope.updateFilter = (type, filter) ->
|
|
||||||
$scope.filter[type] = filter
|
|
||||||
$scope.refreshList()
|
|
||||||
|
|
||||||
$scope.toggleFilter = (type, id) ->
|
|
||||||
if !$scope.filter[type][id]
|
|
||||||
$scope.filter[type][id] = $scope.filters[type][id]
|
|
||||||
else
|
|
||||||
delete $scope.filter[type][id]
|
|
||||||
|
|
||||||
length = _.keys($scope.filter[type]).length
|
|
||||||
if length == 1
|
|
||||||
$scope.titles[type] = _.map($scope.filter[type], (f) -> f.title).join ', '
|
|
||||||
else if length > 1
|
|
||||||
$scope.titles[type] = length + ' selected'
|
|
||||||
else
|
|
||||||
$scope.titles[type] = 'All'
|
|
||||||
|
|
||||||
$scope.refreshList()
|
|
||||||
|
|
||||||
$scope.refreshList = () ->
|
$scope.refreshList = () ->
|
||||||
parts = [$scope.filter.sort.query, $scope.filter.published.query]
|
tracks.refresh().done setTracks
|
||||||
_.each $scope.filter.genres, (g) -> parts.push g.query
|
|
||||||
_.each $scope.filter.trackTypes, (g) -> parts.push g.query
|
|
||||||
query = parts.join '&'
|
|
||||||
tracks.refresh(query).done setTracks
|
|
||||||
|
|
||||||
$scope.selectTrack = (track) ->
|
$scope.selectTrack = (track) ->
|
||||||
$scope.data.selectedTrack = track
|
$scope.data.selectedTrack = track
|
||||||
|
|
12
public/scripts/app/controllers/favourites-albums.coffee
Normal file
12
public/scripts/app/controllers/favourites-albums.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
window.pfm.preloaders['favourites-albums'] = [
|
||||||
|
'favourites'
|
||||||
|
(favourites) ->
|
||||||
|
favourites.fetchAlbums(true)
|
||||||
|
]
|
||||||
|
|
||||||
|
angular.module('ponyfm').controller "favourites-albums", [
|
||||||
|
'$scope', 'favourites'
|
||||||
|
($scope, favourites) ->
|
||||||
|
favourites.fetchAlbums().done (res) ->
|
||||||
|
$scope.albums = res.albums
|
||||||
|
]
|
12
public/scripts/app/controllers/favourites-playlists.coffee
Normal file
12
public/scripts/app/controllers/favourites-playlists.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
window.pfm.preloaders['favourites-playlists'] = [
|
||||||
|
'favourites'
|
||||||
|
(favourites) ->
|
||||||
|
favourites.fetchPlaylists(true)
|
||||||
|
]
|
||||||
|
|
||||||
|
angular.module('ponyfm').controller "favourites-playlists", [
|
||||||
|
'$scope', 'favourites'
|
||||||
|
($scope, favourites) ->
|
||||||
|
favourites.fetchPlaylists().done (res) ->
|
||||||
|
$scope.playlists = res.playlists
|
||||||
|
]
|
12
public/scripts/app/controllers/favourites-tracks.coffee
Normal file
12
public/scripts/app/controllers/favourites-tracks.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
window.pfm.preloaders['favourites-tracks'] = [
|
||||||
|
'favourites'
|
||||||
|
(favourites) ->
|
||||||
|
favourites.fetchTracks(true)
|
||||||
|
]
|
||||||
|
|
||||||
|
angular.module('ponyfm').controller "favourites-tracks", [
|
||||||
|
'$scope', 'favourites'
|
||||||
|
($scope, favourites) ->
|
||||||
|
favourites.fetchTracks().done (res) ->
|
||||||
|
$scope.tracks = res.tracks
|
||||||
|
]
|
|
@ -1,32 +0,0 @@
|
||||||
angular.module('ponyfm').controller "upload", [
|
|
||||||
'$scope', 'auth', 'upload', '$state'
|
|
||||||
($scope, auth, upload, $state) ->
|
|
||||||
$scope.$on 'upload-queue-started', () ->
|
|
||||||
$scope.state = 'uploading'
|
|
||||||
$scope.uploadDialogOpen = true
|
|
||||||
$scope.uploads = {}
|
|
||||||
$scope.progress = 0
|
|
||||||
$scope.uploadedFiles = 0
|
|
||||||
$scope.totalFiles = 0
|
|
||||||
|
|
||||||
$scope.$on 'upload-added', (e, upload) ->
|
|
||||||
$scope.uploads[upload.index] = upload
|
|
||||||
$scope.totalFiles++
|
|
||||||
|
|
||||||
$scope.$on 'upload-queue-ended', () ->
|
|
||||||
$scope.state = 'finished'
|
|
||||||
$scope.uploadDialogOpen = false if _.each upload.queue, (u) -> u.error == null
|
|
||||||
$state.transitionTo 'account-content.tracks'
|
|
||||||
$scope.uploadDialogOpen = false if !(_.size $scope.uploads)
|
|
||||||
|
|
||||||
$scope.$on 'upload-finished', (e, upload) ->
|
|
||||||
$scope.uploadedFiles++
|
|
||||||
delete $scope.uploads[upload.index] if upload.success
|
|
||||||
|
|
||||||
$scope.$on 'upload-progress', () ->
|
|
||||||
$scope.progress = upload.totalBytesUploaded / upload.totalBytes * 100
|
|
||||||
$scope.state = 'processing' if $scope.progress >= 100
|
|
||||||
|
|
||||||
$scope.close = () ->
|
|
||||||
$scope.uploadDialogOpen = false
|
|
||||||
]
|
|
8
public/scripts/app/controllers/uploader.coffee
Normal file
8
public/scripts/app/controllers/uploader.coffee
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
angular.module('ponyfm').controller "uploader", [
|
||||||
|
'$scope', 'auth', 'upload', '$state'
|
||||||
|
($scope, auth, upload, $state) ->
|
||||||
|
|
||||||
|
$scope.data = upload
|
||||||
|
|
||||||
|
$scope.$on 'upload-finished', (e, upload) ->
|
||||||
|
]
|
|
@ -41,7 +41,7 @@ angular.module('ponyfm').directive 'pfmPlayer', () ->
|
||||||
|
|
||||||
moveVolumeSlider = (absoluteY) ->
|
moveVolumeSlider = (absoluteY) ->
|
||||||
newY = absoluteY - $bar.offset().top;
|
newY = absoluteY - $bar.offset().top;
|
||||||
maxY = $bar.height() - ($knob.height() / 2)
|
maxY = $bar.height() - ($knob.height() / 2) - 8
|
||||||
|
|
||||||
newY = 0 if newY < 0
|
newY = 0 if newY < 0
|
||||||
newY = maxY if newY > maxY
|
newY = maxY if newY > maxY
|
||||||
|
@ -54,11 +54,11 @@ angular.module('ponyfm').directive 'pfmPlayer', () ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
$slider.click (e) -> $scope.$apply -> moveVolumeSlider(e.pageY)
|
$slider.click (e) -> $scope.$apply -> moveVolumeSlider(e.pageY - 8)
|
||||||
|
|
||||||
$(document).mousemove (e) ->
|
$(document).mousemove (e) ->
|
||||||
return if !isSliding
|
return if !isSliding
|
||||||
moveVolumeSlider(e.pageY)
|
moveVolumeSlider(e.pageY - 8)
|
||||||
|
|
||||||
$knob.mousedown (e) ->
|
$knob.mousedown (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
|
@ -43,7 +43,7 @@ angular.module('ponyfm').directive 'pfmPopup', () ->
|
||||||
height = windowHeight - top;
|
height = windowHeight - top;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left: left - parentPosition.left - 5
|
left: left - parentPosition.left
|
||||||
top: top - parentPosition.top,
|
top: top - parentPosition.top,
|
||||||
height: height - 15}
|
height: height - 15}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
angular.module('ponyfm').directive 'uploader', [
|
angular.module('ponyfm').directive 'uploader', [
|
||||||
'upload'
|
'upload'
|
||||||
(upload) -> (scope) ->
|
(upload) -> (scope, element) ->
|
||||||
$body = $ 'body'
|
$dropzone = $(element)
|
||||||
$notice = $("<div class='file-over-notice'><p>Drop the files anywhere to begin your upload!</p></div>").appendTo($body)
|
|
||||||
notice = $notice[0]
|
|
||||||
|
|
||||||
window.addEventListener 'dragover', (e) ->
|
$dropzone[0].addEventListener 'dragover', (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
$body.addClass 'file-over'
|
$dropzone.addClass 'file-over'
|
||||||
|
|
||||||
notice.addEventListener 'dragleave', (e) ->
|
$dropzone[0].addEventListener 'dragleave', (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
$body.removeClass 'file-over'
|
$dropzone.removeClass 'file-over'
|
||||||
|
|
||||||
notice.addEventListener 'drop', (e) ->
|
$dropzone[0].addEventListener 'drop', (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
$body.removeClass 'file-over'
|
$dropzone.removeClass 'file-over'
|
||||||
|
|
||||||
files = e.target.files || e.dataTransfer.files
|
files = e.target.files || e.dataTransfer.files
|
||||||
scope.$apply -> upload.upload files
|
scope.$apply -> upload.upload files
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
angular.module('ponyfm').factory('favourites', [
|
angular.module('ponyfm').factory('favourites', [
|
||||||
'$rootScope', '$http'
|
'$rootScope', '$http'
|
||||||
($rootScope, $http) ->
|
($rootScope, $http) ->
|
||||||
|
tracksDef = null
|
||||||
|
playlistsDef = null
|
||||||
|
albumsDef = null
|
||||||
|
|
||||||
self =
|
self =
|
||||||
toggle: (type, id) ->
|
toggle: (type, id) ->
|
||||||
def = new $.Deferred()
|
def = new $.Deferred()
|
||||||
|
@ -9,5 +13,29 @@ angular.module('ponyfm').factory('favourites', [
|
||||||
|
|
||||||
def.promise()
|
def.promise()
|
||||||
|
|
||||||
|
fetchTracks: (force) ->
|
||||||
|
return tracksDef if !force && tracksDef
|
||||||
|
tracksDef = new $.Deferred()
|
||||||
|
$http.get('/api/web/favourites/tracks').success (res) ->
|
||||||
|
tracksDef.resolve res
|
||||||
|
|
||||||
|
tracksDef
|
||||||
|
|
||||||
|
fetchAlbums: (force) ->
|
||||||
|
return albumsDef if !force && albumsDef
|
||||||
|
albumsDef = new $.Deferred()
|
||||||
|
$http.get('/api/web/favourites/albums').success (res) ->
|
||||||
|
albumsDef.resolve res
|
||||||
|
|
||||||
|
albumsDef
|
||||||
|
|
||||||
|
fetchPlaylists: (force) ->
|
||||||
|
return playlistsDef if !force && playlistsDef
|
||||||
|
playlistsDef = new $.Deferred()
|
||||||
|
$http.get('/api/web/favourites/playlists').success (res) ->
|
||||||
|
playlistsDef.resolve res
|
||||||
|
|
||||||
|
playlistsDef
|
||||||
|
|
||||||
self
|
self
|
||||||
])
|
])
|
|
@ -5,8 +5,8 @@ angular.module('ponyfm').factory('images', [
|
||||||
self =
|
self =
|
||||||
images: []
|
images: []
|
||||||
isLoading: true
|
isLoading: true
|
||||||
refresh: () ->
|
refresh: (force) ->
|
||||||
return def if def
|
return def if !force && def
|
||||||
def = new $.Deferred()
|
def = new $.Deferred()
|
||||||
|
|
||||||
self.images = []
|
self.images = []
|
||||||
|
|
|
@ -3,12 +3,8 @@ angular.module('ponyfm').factory('upload', [
|
||||||
($rootScope) ->
|
($rootScope) ->
|
||||||
self =
|
self =
|
||||||
queue: []
|
queue: []
|
||||||
totalBytes: 0
|
|
||||||
totalBytesUploaded: 0
|
|
||||||
|
|
||||||
upload: (files) ->
|
upload: (files) ->
|
||||||
$rootScope.$broadcast 'upload-queue-started' if self.queue.length == 0
|
|
||||||
|
|
||||||
_.each files, (file) ->
|
_.each files, (file) ->
|
||||||
upload =
|
upload =
|
||||||
name: file.name
|
name: file.name
|
||||||
|
@ -21,7 +17,6 @@ angular.module('ponyfm').factory('upload', [
|
||||||
error: null
|
error: null
|
||||||
|
|
||||||
self.queue.push upload
|
self.queue.push upload
|
||||||
self.totalBytes += file.size
|
|
||||||
$rootScope.$broadcast 'upload-added', upload
|
$rootScope.$broadcast 'upload-added', upload
|
||||||
|
|
||||||
xhr = new XMLHttpRequest()
|
xhr = new XMLHttpRequest()
|
||||||
|
@ -29,7 +24,6 @@ angular.module('ponyfm').factory('upload', [
|
||||||
$rootScope.$apply ->
|
$rootScope.$apply ->
|
||||||
upload.uploadedSize = e.loaded
|
upload.uploadedSize = e.loaded
|
||||||
upload.progress = e.loaded / upload.size * 100
|
upload.progress = e.loaded / upload.size * 100
|
||||||
self.totalBytesUploaded = _.reduce self.queue, ((i, u) -> i + u.uploadedSize), 0
|
|
||||||
$rootScope.$broadcast 'upload-progress', upload
|
$rootScope.$broadcast 'upload-progress', upload
|
||||||
|
|
||||||
xhr.onload = -> $rootScope.$apply ->
|
xhr.onload = -> $rootScope.$apply ->
|
||||||
|
@ -45,15 +39,9 @@ angular.module('ponyfm').factory('upload', [
|
||||||
$rootScope.$broadcast 'upload-error', [upload, error]
|
$rootScope.$broadcast 'upload-error', [upload, error]
|
||||||
else
|
else
|
||||||
upload.success = true
|
upload.success = true
|
||||||
|
upload.trackId = $.parseJSON(xhr.responseText).id
|
||||||
|
|
||||||
$rootScope.$broadcast 'upload-finished', upload
|
$rootScope.$broadcast 'upload-finished', upload
|
||||||
|
|
||||||
if (_.every self.queue, (u) -> !u.isUploading)
|
|
||||||
self.queue = []
|
|
||||||
self.totalBytes = 0
|
|
||||||
self.totalBytesUploaded = 0
|
|
||||||
$rootScope.$broadcast 'upload-queue-ended'
|
|
||||||
|
|
||||||
formData = new FormData();
|
formData = new FormData();
|
||||||
formData.append('track', file);
|
formData.append('track', file);
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,418 @@
|
||||||
@import-once 'base/bootstrap/bootstrap';
|
@import-once 'base/bootstrap/bootstrap';
|
||||||
@import-once 'mixins';
|
@import-once 'mixins';
|
||||||
|
|
||||||
|
ul.playlists {
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0px 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
height: 40px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
padding: 0px;
|
||||||
|
display: block;
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
float: right;
|
||||||
|
display: block;
|
||||||
|
margin-top: 7px;
|
||||||
|
margin-right: 7px;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
.border-radius(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.main {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #444;
|
||||||
|
|
||||||
|
.is-public {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
.ellipsis();
|
||||||
|
margin-left: 50px;
|
||||||
|
line-height: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-selector {
|
||||||
|
width: 500px;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0px;
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
.transition(all 400ms);
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
img {
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
.two-pane-view.closed {
|
||||||
|
.account-albums-listing {
|
||||||
|
li {
|
||||||
|
.box-sizing(border-box);
|
||||||
|
width: 20%;
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
.image {
|
||||||
|
.img-polaroid();
|
||||||
|
position: relative;
|
||||||
|
left: -5px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0px;
|
||||||
|
font-size: 12pt;
|
||||||
|
padding: 0px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.published {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-tracks-listing, .account-albums-listing {
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
.box-sizing(border-box);
|
||||||
|
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
line-height: normal;
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
.alert();
|
||||||
|
float: none !important;
|
||||||
|
width: auto !important;
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-not-published a {
|
||||||
|
background: fadeout(@yellow, 90%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected, &.selected:hover {
|
||||||
|
a {
|
||||||
|
background: @pfm-purple;
|
||||||
|
cursor: default;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.published {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
.transition(350px ease-out all);
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 9pt;
|
||||||
|
font-weight: normal;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.image {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
float: left;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
.ellipsis();
|
||||||
|
display: block;
|
||||||
|
margin-left: 37px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.published {
|
||||||
|
display: block;
|
||||||
|
color: #777;
|
||||||
|
margin-left: 37px;
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #ddd;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.two-pane-view {
|
||||||
|
.list {
|
||||||
|
.dropdowns {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.album-track-listing {
|
||||||
|
padding: 0px;
|
||||||
|
clear: both;
|
||||||
|
margin: 0px;
|
||||||
|
margin-top: 10px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: normal;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
font-size: 8pt;
|
||||||
|
border-bottom: 1px dashed #ddd;
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
line-height: normal;
|
||||||
|
padding: 2px 5px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ui-sortable-helper {
|
||||||
|
#gradient>.vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%));
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ui-sortable-placeholder {
|
||||||
|
background: @yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-songs, .album {
|
||||||
|
.btn {
|
||||||
|
display: block;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-songs, .album, .track-selector {
|
||||||
|
.btn {
|
||||||
|
.border-radius(0px);
|
||||||
|
padding: 3px 10px;
|
||||||
|
font-size: 8pt;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfm-popup {
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
.ellipsis();
|
||||||
|
display: block;
|
||||||
|
padding: 3px 10px;
|
||||||
|
font-size: 8pt;
|
||||||
|
color: #333333;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
#gradient>.vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%));
|
||||||
|
text-decoration: none;
|
||||||
|
color: @dropdownLinkColorHover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
a {
|
||||||
|
#gradient>.vertical(@green, darken(@green, 5%));
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
#gradient>.vertical(fadeout(@green, 20%), fadeout(darken(@green, 5%), 20%));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.closed {
|
||||||
|
.account-tracks-listing, .account-albums-listing {
|
||||||
|
.clearfix();
|
||||||
|
|
||||||
|
li {
|
||||||
|
float: left;
|
||||||
|
width: 25%;
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
.list {
|
||||||
|
border-right: 2px solid #ddd;
|
||||||
|
|
||||||
|
width: 250px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
margin-left: 260px;
|
||||||
|
margin-right: 10px;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.stretch-to-bottom {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.license-grid {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
float: left;
|
||||||
|
width: 25%;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
margin: 0px 5px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-size: 9pt;
|
||||||
|
display: block;
|
||||||
|
margin: 0px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
padding: 0px;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
min-height: 120px;
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
.border-radius(0px);
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
> div {
|
||||||
|
cursor: default;
|
||||||
|
border-color: @blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover > div {
|
||||||
|
border: 1px solid #3366CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child > div {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child > div {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,3 +13,4 @@
|
||||||
@import 'player';
|
@import 'player';
|
||||||
@import 'content';
|
@import 'content';
|
||||||
@import 'dashboard';
|
@import 'dashboard';
|
||||||
|
@import 'uploader';
|
|
@ -33,6 +33,50 @@ header {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-details {
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 9px;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
.img-polaroid();
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
padding: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0px 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
left: auto;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
float: left;
|
||||||
|
height: 44px;
|
||||||
|
line-height: 44px;
|
||||||
|
padding-right: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.now-playing {
|
.now-playing {
|
||||||
|
@ -52,6 +96,7 @@ header {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
@ -128,6 +173,11 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li.uploader {
|
||||||
|
a {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-content {
|
.site-content {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@import-once 'mixins';
|
@import-once 'mixins';
|
||||||
|
|
||||||
.track-player {
|
.track-player {
|
||||||
overflow: hidden;
|
margin-right: 75px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
|
@ -106,6 +106,47 @@
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.volume {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.volume-slider {
|
||||||
|
display: none;
|
||||||
|
z-index: 1000;
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 33px;
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
background: #ddd;
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
background: @pfm-purple;
|
||||||
|
width: 10px;
|
||||||
|
margin: auto;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knob {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: -3px;
|
||||||
|
|
||||||
|
background: darken(@pfm-purple, 20%);
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &.keep-open {
|
||||||
|
.volume-slider {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ html {
|
||||||
border-left: 3px solid #111;
|
border-left: 3px solid #111;
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
padding: 5px;
|
||||||
background: #222;
|
background: #222;
|
||||||
|
|
||||||
.clear-button {
|
.clear-button {
|
||||||
|
@ -18,6 +19,10 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
.open-button {
|
.open-button {
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 2px 10px;
|
||||||
|
text-indent: 0px;
|
||||||
|
|
||||||
i:before {
|
i:before {
|
||||||
content: "\f077";
|
content: "\f077";
|
||||||
}
|
}
|
||||||
|
@ -42,7 +47,6 @@ html {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
padding: 5px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
|
@ -60,6 +64,13 @@ html {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.open-button {
|
||||||
|
font-size: 1pt;
|
||||||
|
padding: 2px;
|
||||||
|
text-indent: -1000px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|
82
public/styles/uploader.less
Normal file
82
public/styles/uploader.less
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
@import-once 'variables';
|
||||||
|
|
||||||
|
.uploader {
|
||||||
|
h1 {
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone {
|
||||||
|
border: 2px dotted @pfm-purple;
|
||||||
|
background: lighten(@pfm-purple, 25%);
|
||||||
|
padding: 10px;
|
||||||
|
color: darken(@pfm-purple, 25%);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.file-over {
|
||||||
|
background: lighten(@pfm-purple, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
.border-radius(0px);
|
||||||
|
width: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploads {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
background: #eee;
|
||||||
|
font-size: 9pt;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
color: #444;
|
||||||
|
border: 2px solid #aaa;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 5px;
|
||||||
|
padding: 0px;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-error {
|
||||||
|
border-color: @red;
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-processing {
|
||||||
|
border-color: @blue;
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
public/templates/account/_layout.html
Normal file
8
public/templates/account/_layout.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<ul class="tabs">
|
||||||
|
<li ng-class="{active: stateIncludes('account.tracks')}"><a href="/account/tracks">Tracks</a></li>
|
||||||
|
<li ng-class="{active: stateIncludes('account.albums')}"><a href="/account/albums">Albums</a></li>
|
||||||
|
<li ng-class="{active: stateIncludes('account.playlists')}"><a href="/account/playlists">Playlists</a></li>
|
||||||
|
<li ng-class="{active: stateIncludes('account.settings')}"><a href="/account">Settings</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ui-view></ui-view>
|
|
@ -1,8 +0,0 @@
|
||||||
<div>
|
|
||||||
<ul class="tabs">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<div>
|
|
||||||
<h1>Your Playlists</h1>
|
|
||||||
<ul class="playlists stretch-to-bottom">
|
|
||||||
<li ng-repeat="playlist in playlists">
|
|
||||||
<div class="btn-group">
|
|
||||||
<a href="#" pfm-eat-click class="btn btn-small" ng-click="togglePlaylistPin(playlist)" ng-class="{active: playlist.is_pinned, 'btn-primary': playlist.is_pinned}">
|
|
||||||
<i class="icon-pushpin"></i>
|
|
||||||
</a>
|
|
||||||
<a href="#" pfm-eat-click class="btn btn-small" ng-click="editPlaylist(playlist)">Edit</a>
|
|
||||||
<a href="#" pfm-eat-click class="btn btn-small btn-danger" ng-click="deletePlaylist(playlist)">Delete</a>
|
|
||||||
</div>
|
|
||||||
<a href="{{playlist.url}}" class="main">
|
|
||||||
<span class="is-public">
|
|
||||||
<span ng-show="playlist.is_public">Is Public</span>
|
|
||||||
<span ng-hide="playlist.is_public">Is Private</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<img ng-src="{{playlist.covers.small}}" />
|
|
||||||
<span class="title">
|
|
||||||
{{playlist.title}}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<div>
|
|
||||||
<ul class="dropdowns">
|
|
||||||
<li class="dropdown">
|
|
||||||
<a class="dropdown-toggle btn">
|
|
||||||
Published: <strong>{{filter.published.title}}</strong>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li ng-repeat="filter in filters.published">
|
|
||||||
<a pfm-eat-click href="#" ng-click="updateFilter('published', filter)">{{filter.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a class="dropdown-toggle btn">
|
|
||||||
Sort: <strong>{{filter.sort.title}}</strong>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li ng-repeat="filter in filters.sort">
|
|
||||||
<a pfm-eat-click href="#" ng-click="updateFilter('sort', filter)">{{filter.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a class="dropdown-toggle btn">
|
|
||||||
Type: <strong>{{titles.trackTypes}}</strong>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li ng-repeat="type in filters.trackTypes" ng-class="{selected: filter.trackTypes[type.id]}">
|
|
||||||
<a pfm-eat-click href="#" ng-click="toggleFilter('trackTypes', type.id); $event.stopPropagation();">{{type.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a class="dropdown-toggle btn">
|
|
||||||
Genera: <strong>{{titles.genres}}</strong>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li ng-repeat="genre in filters.genres" ng-class="{selected: filter.genres[genre.id]}">
|
|
||||||
<a pfm-eat-click href="#" ng-click="toggleFilter('genres', genre.id); $event.stopPropagation();">{{genre.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="two-pane-view" ng-class="{open: data.selectedTrack != null, closed: data.selectedTrack == null}">
|
|
||||||
<div class="list">
|
|
||||||
<ul class="account-tracks-listing stretch-to-bottom">
|
|
||||||
<li ng-repeat="track in tracks" ng-class="{selected: track.id == data.selectedTrack.id, 'is-not-published': !track.is_published}">
|
|
||||||
<a href="/account/tracks/edit/{{track.id}}" ng-click="selectTrack(track)">
|
|
||||||
<img class="image" ng-src="{{track.cover_url}}" />
|
|
||||||
<span class="title">{{track.title}}</span>
|
|
||||||
<span class="published">{{track.created_at | pfmdate:'MM/dd/yyyy'}}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ui-view class="editor"></ui-view>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<div>
|
|
||||||
<ul class="tabs">
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$state = {{$state.current.name}}
|
|
||||||
$stateParams = {{$stateParams}}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
<h2>Favourite Albums</h2>
|
|
|
@ -1 +0,0 @@
|
||||||
<h2>Favourite Playlists</h2>
|
|
|
@ -1 +0,0 @@
|
||||||
<h2>Favourite tracks</h2>
|
|
22
public/templates/account/playlists.html
Normal file
22
public/templates/account/playlists.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<ul class="playlists stretch-to-bottom">
|
||||||
|
<li ng-repeat="playlist in playlists">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="#" pfm-eat-click class="btn btn-small" ng-click="togglePlaylistPin(playlist)" ng-class="{active: playlist.is_pinned, 'btn-primary': playlist.is_pinned}">
|
||||||
|
<i class="icon-pushpin"></i>
|
||||||
|
</a>
|
||||||
|
<a href="#" pfm-eat-click class="btn btn-small" ng-click="editPlaylist(playlist)">Edit</a>
|
||||||
|
<a href="#" pfm-eat-click class="btn btn-small btn-danger" ng-click="deletePlaylist(playlist)">Delete</a>
|
||||||
|
</div>
|
||||||
|
<a href="{{playlist.url}}" class="main">
|
||||||
|
<span class="is-public">
|
||||||
|
<span ng-show="playlist.is_public">Is Public</span>
|
||||||
|
<span ng-hide="playlist.is_public">Is Private</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<img ng-src="{{playlist.covers.small}}" />
|
||||||
|
<span class="title">
|
||||||
|
{{playlist.title}}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
|
@ -1,6 +1,4 @@
|
||||||
<div>
|
<form ng-submit="updateAccount()" class="pfm-form account-settings-form">
|
||||||
<h1>Account Settings</h1>
|
|
||||||
<form ng-submit="updateAccount()" class="pfm-form account-settings-form">
|
|
||||||
<ul class="toolbar">
|
<ul class="toolbar">
|
||||||
<li>
|
<li>
|
||||||
<button type="submit" class="btn" ng-class="{disabled: !isDirty || isSaving, 'btn-primary': isDirty}">
|
<button type="submit" class="btn" ng-class="{disabled: !isDirty || isSaving, 'btn-primary': isDirty}">
|
||||||
|
@ -10,25 +8,22 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="stretch-to-bottom">
|
<div class="stretch-to-bottom">
|
||||||
<div class="row-fluid">
|
<div class="form-row" ng-class="{'has-error': errors.display_name != null}">
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.display_name != null}">
|
|
||||||
<label for="sync_names" class="strong"><input ng-disabled="isSaving" ng-change="touchModel();" id="sync_names" type="checkbox" ng-model="settings.sync_names" /> Sync my MLP Forums display name with Pony.fm</label>
|
<label for="sync_names" class="strong"><input ng-disabled="isSaving" ng-change="touchModel();" id="sync_names" type="checkbox" ng-model="settings.sync_names" /> Sync my MLP Forums display name with Pony.fm</label>
|
||||||
<input type="text" ng-disabled="isSaving" ng-change="touchModel()" ng-show="!settings.sync_names" placeholder="Display Name" id="display_name" ng-model="settings.display_name" />
|
<input type="text" ng-disabled="isSaving" ng-change="touchModel()" ng-show="!settings.sync_names" placeholder="Display Name" id="display_name" ng-model="settings.display_name" />
|
||||||
<div ng-show="settings.sync_names" class="alert alert-info">Your current MLP Forums display name is <strong>{{settings.mlpforums_name}}</strong></div>
|
<div ng-show="settings.sync_names" class="alert alert-info">Your current MLP Forums display name is <strong>{{settings.mlpforums_name}}</strong></div>
|
||||||
<div class="error">{{errors.display_name}}</div>
|
<div class="error">{{errors.display_name}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row span6">
|
<div class="form-row">
|
||||||
<label for="can_see_explicit_content"><input ng-change="touchModel()" ng-disabled="isLoading" id="can_see_explicit_content" type="checkbox" ng-model="settings.can_see_explicit_content" /> Can See Explicit Content</label>
|
<label for="can_see_explicit_content" class="strong"><input ng-change="touchModel()" ng-disabled="isLoading" id="can_see_explicit_content" type="checkbox" ng-model="settings.can_see_explicit_content" /> Can See Explicit Content</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-row" ng-class="{'has-error': errors.bio != null}">
|
||||||
<div class="row-fluid">
|
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.bio != null}">
|
|
||||||
<label class="strong" for="bio">Bio</label>
|
<label class="strong" for="bio">Bio</label>
|
||||||
<textarea id="bio" placeholder="bio (optional)" ng-model="settings.bio" ng-disabled="isLoading" ng-change="touchModel()"></textarea>
|
<textarea id="bio" placeholder="bio (optional)" ng-model="settings.bio" ng-disabled="isLoading" ng-change="touchModel()"></textarea>
|
||||||
<div class="error">{{errors.description}}</div>
|
<div class="error">{{errors.description}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.avatar != null || errors.gravatar != null}">
|
<div class="form-row" ng-class="{'has-error': errors.avatar != null || errors.gravatar != null}">
|
||||||
<label for="uses_gravatar">
|
<label for="uses_gravatar" class="strong">
|
||||||
<input ng-change="touchModel()" ng-disabled="isLoading" id="uses_gravatar" type="checkbox" ng-model="settings.uses_gravatar" /> Use Gravatar
|
<input ng-change="touchModel()" ng-disabled="isLoading" id="uses_gravatar" type="checkbox" ng-model="settings.uses_gravatar" /> Use Gravatar
|
||||||
</label>
|
</label>
|
||||||
<div ng-show="!settings.uses_gravatar">
|
<div ng-show="!settings.uses_gravatar">
|
||||||
|
@ -38,7 +33,4 @@
|
||||||
<div class="error" ng-show="errors.avatar != null">{{errors.avatar}}</div>
|
<div class="error" ng-show="errors.avatar != null">{{errors.avatar}}</div>
|
||||||
<div class="error" ng-show="errors.gravatar != null">{{errors.gravatar}}</div>
|
<div class="error" ng-show="errors.gravatar != null">{{errors.gravatar}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
15
public/templates/account/tracks.html
Normal file
15
public/templates/account/tracks.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="two-pane-view" ng-class="{open: data.selectedTrack != null, closed: data.selectedTrack == null}">
|
||||||
|
<div class="list">
|
||||||
|
<ul class="account-tracks-listing stretch-to-bottom">
|
||||||
|
<li ng-repeat="track in tracks" ng-class="{selected: track.id == data.selectedTrack.id, 'is-not-published': !track.is_published}">
|
||||||
|
<a href="/account/tracks/edit/{{track.id}}" ng-click="selectTrack(track)">
|
||||||
|
<img class="image" ng-src="{{track.cover_url}}" />
|
||||||
|
<span class="title">{{track.title}}</span>
|
||||||
|
<span class="published">{{track.created_at | pfmdate:'MM/dd/yyyy'}}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ui-view class="editor"></ui-view>
|
||||||
|
</div>
|
|
@ -1,3 +1,3 @@
|
||||||
<div class="stretch-to-bottom">
|
<div class="stretch-to-bottom">
|
||||||
<pfm-albums-list albums="albums" />
|
<pfm-albums-list albums="albums"></pfm-albums-list>
|
||||||
</div>
|
</div>
|
|
@ -10,6 +10,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#" class="btn" pfm-eat-click ng-click="share()">Share or Embed</a></li>
|
<li><a href="#" class="btn" pfm-eat-click ng-click="share()">Share or Embed</a></li>
|
||||||
<li><pfm-favourite-button resource="album" type="album"></pfm-favourite-button></li>
|
<li><pfm-favourite-button resource="album" type="album"></pfm-favourite-button></li>
|
||||||
|
<li bo-show="album.permissions.edit"><a class="btn btn-small" bo-href="'/account/albums/edit/' + album.id">Edit</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a pfm-eat-click ng-click="playNext()" class="next" href="#"><i class="icon-fast-forward"></i></a></li>
|
<li><a pfm-eat-click ng-click="playNext()" class="next" href="#"><i class="icon-fast-forward"></i></a></li>
|
||||||
<li>
|
<li class="volume">
|
||||||
<a pfm-eat-click ng-click="" class="volume" href="#">
|
<a pfm-eat-click ng-click="" class="volume" href="#">
|
||||||
<i class="icon-volume-up"></i>
|
<i class="icon-volume-up"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
14
public/templates/favourites/_layout.html
Normal file
14
public/templates/favourites/_layout.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<div>
|
||||||
|
<ul class="tabs">
|
||||||
|
<li ng-class="{active: stateIncludes('favourites.tracks')}"><a href="/account/favourites/tracks">Tracks</a></li>
|
||||||
|
<li ng-class="{active: stateIncludes('favourites.albums')}"><a href="/account/favourites/albums">Albums</a></li>
|
||||||
|
<li ng-class="{active: stateIncludes('favourites.playlists')}"><a href="/account/favourites/playlists">Playlists</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ui-view></ui-view>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$state = {{$state.current.name}}
|
||||||
|
$stateParams = {{$stateParams}}
|
||||||
|
</pre>
|
||||||
|
</div>
|
3
public/templates/favourites/albums.html
Normal file
3
public/templates/favourites/albums.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="stretch-to-bottom">
|
||||||
|
<pfm-albums-list albums="albums" />
|
||||||
|
</div>
|
3
public/templates/favourites/playlists.html
Normal file
3
public/templates/favourites/playlists.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="stretch-to-bottom">
|
||||||
|
<pfm-playlists-list playlists="playlists"></pfm-playlists-list>
|
||||||
|
</div>
|
|
@ -1,19 +0,0 @@
|
||||||
<div class="overlay upload-dialog" ng-controller="upload" ng-show="uploadDialogOpen">
|
|
||||||
<div class="inner">
|
|
||||||
<h2 ng-show="state == 'uploading'">
|
|
||||||
<span>{{uploadedFiles}} of {{totalFiles}}</span>
|
|
||||||
Uploading Tracks...
|
|
||||||
</h2>
|
|
||||||
<h2 ng-show="state == 'processing'">Processing...</h2>
|
|
||||||
|
|
||||||
<a href="#" pfm-eat-click class="btn btn-primary close-button" ng-click="close()" ng-show="state == 'finished'">Close <i class="icon-remove"></i></a>
|
|
||||||
|
|
||||||
<ul class="uploads">
|
|
||||||
<li ng-repeat="upload in uploads" ng-class="{'has-error': upload.error != null, 'is-processing': upload.isUploading && upload.error == null && upload.progress >= 100}" ng-animate="'upload-queue'">
|
|
||||||
<p><strong>{{upload.name}}</strong></p>
|
|
||||||
<p ng-show="upload.error != null">{{upload.error}}</p>
|
|
||||||
<div class="bar" pfm-progress-bar="upload.progress"></div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,3 +1,3 @@
|
||||||
<div class="stretch-to-bottom">
|
<div class="stretch-to-bottom">
|
||||||
<pfm-playlists-list playlists="playlists" />
|
<pfm-playlists-list playlists="playlists"></pfm-playlists-list>
|
||||||
</div>
|
</div>
|
3
public/templates/tracks/list.html
Normal file
3
public/templates/tracks/list.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="stretch-to-bottom">
|
||||||
|
<pfm-tracks-list tracks="tracks" class="three-columns"></pfm-tracks-list>
|
||||||
|
</div>
|
|
@ -24,6 +24,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#" class="btn" pfm-eat-click ng-click="share()">Share</a></li>
|
<li><a href="#" class="btn" pfm-eat-click ng-click="share()">Share</a></li>
|
||||||
<li><pfm-favourite-button resource="track" type="track"></pfm-favourite-button></li>
|
<li><pfm-favourite-button resource="track" type="track"></pfm-favourite-button></li>
|
||||||
|
<li bo-show="track.permissions.edit"><a class="btn btn-small" bo-href="'/account/tracks/edit/' + track.id">Edit</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
|
25
public/templates/uploader/index.html
Normal file
25
public/templates/uploader/index.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<div class="uploader">
|
||||||
|
<div class="dropzone" uploader>
|
||||||
|
<p>Drop files here to begin your upload!</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="uploads">
|
||||||
|
<li ng-repeat="upload in data.queue" ng-class="{'has-error': upload.error != null, 'is-processing': upload.isUploading && upload.error == null && upload.progress >= 100}" ng-animate="'upload-queue'">
|
||||||
|
<p>
|
||||||
|
<span ng-show="!upload.success">
|
||||||
|
<strong ng-show="upload.isUploading && upload.error == null && upload.progress >= 100">Processing</strong>
|
||||||
|
<strong ng-hide="upload.isUploading && upload.error == null && upload.progress >= 100">Uploading</strong>
|
||||||
|
{{upload.name}}
|
||||||
|
</span>
|
||||||
|
<span ng-show="upload.success">
|
||||||
|
<a href="/account/tracks/edit/{{upload.trackId}}" class="btn btn-small btn-primary">
|
||||||
|
Publish
|
||||||
|
</a>
|
||||||
|
{{upload.name}}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p ng-show="upload.error != null">{{upload.error}}</p>
|
||||||
|
<div class="bar" pfm-progress-bar="upload.progress"></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
Loading…
Reference in a new issue