mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-01-31 03:16:42 +01:00
Mega commit... Following, design changes, share/embed code and more.
This commit is contained in:
parent
d63ef0e65c
commit
1dff7cb36f
52 changed files with 636 additions and 154 deletions
|
@ -28,7 +28,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShow($id) {
|
public function getShow($id) {
|
||||||
$album = Album::with(['tracks' => function($query) { $query->details(); }, 'tracks.cover', 'tracks.genre', 'tracks.user', 'user', 'comments' => function($query) { $query->with('user'); }])->details()->find($id);
|
$album = Album::with([
|
||||||
|
'tracks' => function($query) { $query->userDetails(); },
|
||||||
|
'tracks.cover',
|
||||||
|
'tracks.genre',
|
||||||
|
'tracks.user',
|
||||||
|
'user',
|
||||||
|
'comments',
|
||||||
|
'comments.user'])
|
||||||
|
->userDetails()
|
||||||
|
->find($id);
|
||||||
|
|
||||||
if (!$album)
|
if (!$album)
|
||||||
App::abort(404);
|
App::abort(404);
|
||||||
|
|
||||||
|
@ -49,12 +59,12 @@
|
||||||
|
|
||||||
$query = Album::summary()
|
$query = Album::summary()
|
||||||
->with('user', 'user.avatar', 'cover')
|
->with('user', 'user.avatar', 'cover')
|
||||||
->details()
|
->userDetails()
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->where('track_count', '>', 0);
|
->where('track_count', '>', 0);
|
||||||
|
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
$perPage = 18;
|
$perPage = 40;
|
||||||
|
|
||||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||||
$albums = [];
|
$albums = [];
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
'track.user',
|
'track.user',
|
||||||
'album.cover',
|
'album.cover',
|
||||||
'album.user',
|
'album.user',
|
||||||
'track' => function($query) { $query->details(); },
|
'track' => function($query) { $query->userDetails(); },
|
||||||
'album' => function($query) { $query->details(); }])->get();
|
'album' => function($query) { $query->userDetails(); }])->get();
|
||||||
|
|
||||||
$tracks = [];
|
$tracks = [];
|
||||||
$albums = [];
|
$albums = [];
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
if (!$user)
|
if (!$user)
|
||||||
App::abort(404);
|
App::abort(404);
|
||||||
|
|
||||||
$query = Track::summary()->with('genre', 'cover', 'user')->details()->whereUserId($user->id)->whereNotNull('published_at');
|
$query = Track::summary()->with('genre', 'cover', 'user')->userDetails()->whereUserId($user->id)->whereNotNull('published_at');
|
||||||
$tracks = [];
|
$tracks = [];
|
||||||
$singles = [];
|
$singles = [];
|
||||||
|
|
||||||
|
@ -83,11 +83,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShow($slug) {
|
public function getShow($slug) {
|
||||||
$user = User::whereSlug($slug)->with(['comments' => function ($query) { $query->with('user'); }])->first();
|
$user = User::whereSlug($slug)->userDetails()->with(['comments' => function ($query) { $query->with('user'); }])->first();
|
||||||
if (!$user)
|
if (!$user)
|
||||||
App::abort(404);
|
App::abort(404);
|
||||||
|
|
||||||
$trackQuery = Track::summary()->with('genre', 'cover', 'user')->details()->whereUserId($user->id)->whereNotNull('published_at')->orderBy('created_at', 'desc')->take(20);
|
$trackQuery = Track::summary()->with('genre', 'cover', 'user')->userDetails()->whereUserId($user->id)->whereNotNull('published_at')->orderBy('created_at', 'desc')->take(20);
|
||||||
$latestTracks = [];
|
$latestTracks = [];
|
||||||
|
|
||||||
foreach ($trackQuery->get() as $track) {
|
foreach ($trackQuery->get() as $track) {
|
||||||
|
@ -99,6 +99,17 @@
|
||||||
$comments[] = Comment::mapPublic($comment);
|
$comments[] = Comment::mapPublic($comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$userData = [
|
||||||
|
'is_following' => false
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($user->users->count()) {
|
||||||
|
$userRow = $user->users[0];
|
||||||
|
$userData = [
|
||||||
|
'is_following' => $userRow->is_followed
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return Response::json([
|
return Response::json([
|
||||||
'artist' => [
|
'artist' => [
|
||||||
'id' => $user->id,
|
'id' => $user->id,
|
||||||
|
@ -112,9 +123,11 @@
|
||||||
'followers' => [],
|
'followers' => [],
|
||||||
'following' => [],
|
'following' => [],
|
||||||
'latest_tracks' => $latestTracks,
|
'latest_tracks' => $latestTracks,
|
||||||
'comments' => ['count' => count($comments), 'list' => $comments],
|
'comments' => $comments,
|
||||||
'bio' => $user->bio,
|
'bio' => $user->bio,
|
||||||
'mlpforums_username' => $user->mlpforums_name
|
'mlpforums_username' => $user->mlpforums_name,
|
||||||
|
'message_url' => $user->message_url,
|
||||||
|
'user_data' => $userData
|
||||||
]
|
]
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +141,7 @@
|
||||||
->where('track_count', '>', 0);
|
->where('track_count', '>', 0);
|
||||||
|
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
$perPage = 18;
|
$perPage = 40;
|
||||||
|
|
||||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||||
$users = [];
|
$users = [];
|
||||||
|
|
|
@ -14,18 +14,22 @@
|
||||||
|
|
||||||
class DashboardController extends \ApiControllerBase {
|
class DashboardController extends \ApiControllerBase {
|
||||||
public function getIndex() {
|
public function getIndex() {
|
||||||
$query = Track::summary()->with(['genre', 'user', 'cover'])->details()->whereNotNull('published_at')->orderBy('published_at', 'desc')->take(30);
|
$recentQuery = Track::summary()
|
||||||
if (!Auth::check() || !Auth::user()->can_see_explicit_content)
|
->with(['genre', 'user', 'cover', 'user.avatar'])
|
||||||
$query->whereIsExplicit(false);
|
->userDetails()
|
||||||
|
->explicitFilter()
|
||||||
|
->published()
|
||||||
|
->orderBy('published_at', 'desc')
|
||||||
|
->take(30);
|
||||||
|
|
||||||
$tracks = [];
|
$recentTracks = [];
|
||||||
|
|
||||||
foreach ($query->get() as $track) {
|
foreach ($recentQuery->get() as $track) {
|
||||||
$tracks[] = Track::mapPublicTrackSummary($track);
|
$recentTracks[] = Track::mapPublicTrackSummary($track);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response::json([
|
return Response::json([
|
||||||
'recent_tracks' => $tracks,
|
'recent_tracks' => $recentTracks,
|
||||||
'popular_tracks' => $tracks], 200);
|
'popular_tracks' => Track::popular(30, Auth::check() && Auth::user()->can_see_explicit_content)], 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
13
app/controllers/Api/Web/FollowController.php
Normal file
13
app/controllers/Api/Web/FollowController.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Api\Web;
|
||||||
|
|
||||||
|
use Commands\ToggleFavouriteCommand;
|
||||||
|
use Commands\ToggleFollowingCommand;
|
||||||
|
use Illuminate\Support\Facades\Input;
|
||||||
|
|
||||||
|
class FollowController extends \ApiControllerBase {
|
||||||
|
public function postToggle() {
|
||||||
|
return $this->execute(new ToggleFollowingCommand(Input::get('type'), Input::get('id')));
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,13 +40,13 @@
|
||||||
|
|
||||||
$query = Playlist::summary()
|
$query = Playlist::summary()
|
||||||
->with('user', 'user.avatar', 'tracks', 'tracks.cover')
|
->with('user', 'user.avatar', 'tracks', 'tracks.cover')
|
||||||
->details()
|
->userDetails()
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->where('track_count', '>', 0)
|
->where('track_count', '>', 0)
|
||||||
->whereIsPublic(true);
|
->whereIsPublic(true);
|
||||||
|
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
$perPage = 18;
|
$perPage = 40;
|
||||||
|
|
||||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||||
$playlists = [];
|
$playlists = [];
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShow($id) {
|
public function getShow($id) {
|
||||||
$playlist = Playlist::with(['tracks.user', 'tracks.genre', 'tracks.cover', 'tracks.album', 'tracks' => function($query) { $query->details(); }, 'comments', 'comments.user'])->details()->find($id);
|
$playlist = Playlist::with(['tracks.user', 'tracks.genre', 'tracks.cover', 'tracks.album', 'tracks' => function($query) { $query->userDetails(); }, 'comments', 'comments.user'])->userDetails()->find($id);
|
||||||
if (!$playlist || !$playlist->canView(Auth::user()))
|
if (!$playlist || !$playlist->canView(Auth::user()))
|
||||||
App::abort('404');
|
App::abort('404');
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
public function getPinned() {
|
public function getPinned() {
|
||||||
$query = Playlist
|
$query = Playlist
|
||||||
::details()
|
::userDetails()
|
||||||
->with('tracks', 'tracks.cover', 'tracks.user', 'user')
|
->with('tracks', 'tracks.cover', 'tracks.user', 'user')
|
||||||
->join('pinned_playlists', function($join) {
|
->join('pinned_playlists', function($join) {
|
||||||
$join->on('playlist_id', '=', 'playlists.id');
|
$join->on('playlist_id', '=', 'playlists.id');
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShow($id) {
|
public function getShow($id) {
|
||||||
$track = Track::details()->withComments()->find($id);
|
$track = Track::userDetails()->withComments()->find($id);
|
||||||
if (!$track || !$track->canView(Auth::user()))
|
if (!$track || !$track->canView(Auth::user()))
|
||||||
return $this->notFound('Track not found!');
|
return $this->notFound('Track not found!');
|
||||||
|
|
||||||
|
@ -43,20 +43,6 @@
|
||||||
return Response::json(['track' => Track::mapPublicTrackShow($track)], 200);
|
return Response::json(['track' => Track::mapPublicTrackShow($track)], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRecent() {
|
|
||||||
$query = Track::summary()->details()->with(['genre', 'user', 'cover'])->whereNotNull('published_at')->orderBy('published_at', 'desc')->take(30);
|
|
||||||
if (!Auth::check() || !Auth::user()->can_see_explicit_content)
|
|
||||||
$query->whereIsExplicit(false);
|
|
||||||
|
|
||||||
$tracks = [];
|
|
||||||
|
|
||||||
foreach ($query->get() as $track) {
|
|
||||||
$tracks[] = Track::mapPublicTrackSummary($track);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response::json($tracks, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIndex() {
|
public function getIndex() {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
$perPage = 45;
|
$perPage = 45;
|
||||||
|
@ -65,8 +51,9 @@
|
||||||
$page = Input::get('page');
|
$page = Input::get('page');
|
||||||
|
|
||||||
$query = Track::summary()
|
$query = Track::summary()
|
||||||
->details()
|
->userDetails()
|
||||||
->whereNotNull('published_at')
|
->explicitFilter()
|
||||||
|
->published()
|
||||||
->with('user', 'genre', 'cover', 'album', 'album.user');
|
->with('user', 'genre', 'cover', 'album', 'album.user');
|
||||||
|
|
||||||
$this->applyFilters($query);
|
$this->applyFilters($query);
|
||||||
|
|
|
@ -11,6 +11,7 @@ class CreateUserTables extends Migration {
|
||||||
$table->integer('track_id')->unsigned()->nullable()->index();
|
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||||
$table->integer('album_id')->unsigned()->nullable()->index();
|
$table->integer('album_id')->unsigned()->nullable()->index();
|
||||||
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||||
|
$table->integer('artist_id')->unsigned()->nullable()->index();
|
||||||
|
|
||||||
$table->boolean('is_followed');
|
$table->boolean('is_followed');
|
||||||
$table->boolean('is_favourited');
|
$table->boolean('is_favourited');
|
||||||
|
@ -20,12 +21,13 @@ class CreateUserTables extends Migration {
|
||||||
$table->integer('play_count');
|
$table->integer('play_count');
|
||||||
$table->integer('download_count');
|
$table->integer('download_count');
|
||||||
|
|
||||||
|
$table->foreign('artist_id')->references('id')->on('users')->on_delete('cascade');
|
||||||
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||||
$table->foreign('track_id')->references('id')->on('tracks');
|
$table->foreign('track_id')->references('id')->on('tracks')->on_delete('cascade');;
|
||||||
$table->foreign('album_id')->references('id')->on('albums');
|
$table->foreign('album_id')->references('id')->on('albums')->on_delete('cascade');;
|
||||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
$table->foreign('playlist_id')->references('id')->on('playlists')->on_delete('cascade');;
|
||||||
|
|
||||||
$table->unique(['user_id', 'track_id', 'album_id', 'playlist_id']);
|
$table->unique(['user_id', 'track_id', 'album_id', 'playlist_id', 'artist_id']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Schema::create('resource_log_items', function($table){
|
Schema::create('resource_log_items', function($table){
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateFollowers extends Migration {
|
||||||
|
public function up() {
|
||||||
|
Schema::create('followers', function($table){
|
||||||
|
$table->increments('id');
|
||||||
|
$table->integer('user_id')->unsigned()->index();
|
||||||
|
|
||||||
|
$table->integer('artist_id')->unsigned()->nullable()->index();
|
||||||
|
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||||
|
|
||||||
|
$table->timestamp('created_at');
|
||||||
|
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||||
|
$table->foreign('artist_id')->references('id')->on('users')->on_delete('cascade');
|
||||||
|
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down() {
|
||||||
|
Schema::drop('followers');
|
||||||
|
}
|
||||||
|
}
|
57
app/models/Commands/ToggleFollowingCommand.php
Normal file
57
app/models/Commands/ToggleFollowingCommand.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Commands;
|
||||||
|
|
||||||
|
use Entities\Album;
|
||||||
|
use Entities\Favourite;
|
||||||
|
use Entities\Follower;
|
||||||
|
use Entities\Playlist;
|
||||||
|
use Entities\ResourceUser;
|
||||||
|
use Entities\Track;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ToggleFollowingCommand extends CommandBase {
|
||||||
|
private $_resourceType;
|
||||||
|
private $_resourceId;
|
||||||
|
|
||||||
|
function __construct($resourceType, $resourceId) {
|
||||||
|
$this->_resourceId = $resourceId;
|
||||||
|
$this->_resourceType = $resourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() {
|
||||||
|
$user = Auth::user();
|
||||||
|
return $user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Exception
|
||||||
|
* @return CommandResponse
|
||||||
|
*/
|
||||||
|
public function execute() {
|
||||||
|
$typeId = $this->_resourceType . '_id';
|
||||||
|
$existing = Follower::where($typeId, '=', $this->_resourceId)->whereUserId(Auth::user()->id)->first();
|
||||||
|
$isFollowed = false;
|
||||||
|
|
||||||
|
if ($existing) {
|
||||||
|
$existing->delete();
|
||||||
|
} else {
|
||||||
|
$follow = new Follower();
|
||||||
|
$follow->$typeId = $this->_resourceId;
|
||||||
|
$follow->user_id = Auth::user()->id;
|
||||||
|
$follow->created_at = time();
|
||||||
|
$follow->save();
|
||||||
|
$isFollowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$resourceUser = ResourceUser::get(Auth::user()->id, $this->_resourceType, $this->_resourceId);
|
||||||
|
$resourceUser->is_followed = $isFollowed;
|
||||||
|
$resourceUser->save();
|
||||||
|
|
||||||
|
return CommandResponse::succeed(['is_followed' => $isFollowed]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'cover_id', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'cover_id', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeDetails($query) {
|
public function scopeUserDetails($query) {
|
||||||
if (Auth::check()) {
|
if (Auth::check()) {
|
||||||
$query->with(['users' => function($query) {
|
$query->with(['users' => function($query) {
|
||||||
$query->whereUserId(Auth::user()->id);
|
$query->whereUserId(Auth::user()->id);
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comments(){
|
public function comments(){
|
||||||
return $this->hasMany('Entities\Comment');
|
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function mapPublicAlbumShow($album) {
|
public static function mapPublicAlbumShow($album) {
|
||||||
|
@ -81,6 +81,11 @@
|
||||||
$data['comments'] = $comments;
|
$data['comments'] = $comments;
|
||||||
$data['formats'] = $formats;
|
$data['formats'] = $formats;
|
||||||
$data['description'] = $album->description;
|
$data['description'] = $album->description;
|
||||||
|
$data['share'] = [
|
||||||
|
'url' => URL::to('/a' . $album->id),
|
||||||
|
'tumblrUrl' => 'http://www.tumblr.com/share/link?url=' . urlencode($album->url) . '&name=' . urlencode($album->title) . '&description=' . urlencode($album->description),
|
||||||
|
'twitterUrl' => 'https://platform.twitter.com/widgets/tweet_button.html?text=' . $album->title . ' by ' . $album->user->display_name . ' on Pony.fm'
|
||||||
|
];
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
9
app/models/Entities/Follower.php
Normal file
9
app/models/Entities/Follower.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Entities;
|
||||||
|
|
||||||
|
class Follower extends \Eloquent {
|
||||||
|
protected $table = 'followers';
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'is_public', 'description', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'is_public', 'description', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeDetails($query) {
|
public function scopeUserDetails($query) {
|
||||||
if (Auth::check()) {
|
if (Auth::check()) {
|
||||||
$query->with(['users' => function($query) {
|
$query->with(['users' => function($query) {
|
||||||
$query->whereUserId(Auth::user()->id);
|
$query->whereUserId(Auth::user()->id);
|
||||||
|
@ -53,6 +53,11 @@
|
||||||
$data['tracks'] = $tracks;
|
$data['tracks'] = $tracks;
|
||||||
$data['comments'] = $comments;
|
$data['comments'] = $comments;
|
||||||
$data['formats'] = $formats;
|
$data['formats'] = $formats;
|
||||||
|
$data['share'] = [
|
||||||
|
'url' => URL::to('/p' . $playlist->id),
|
||||||
|
'tumblrUrl' => 'http://www.tumblr.com/share/link?url=' . urlencode($playlist->url) . '&name=' . urlencode($playlist->title) . '&description=' . urlencode($playlist->description),
|
||||||
|
'twitterUrl' => 'https://platform.twitter.com/widgets/tweet_button.html?text=' . $playlist->title . ' by ' . $playlist->user->display_name . ' on Pony.fm'
|
||||||
|
];
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +122,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comments(){
|
public function comments(){
|
||||||
return $this->hasMany('Entities\Comment');
|
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pins() {
|
public function pins() {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
use Helpers;
|
use Helpers;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
return self::select('id', 'title', 'user_id', 'slug', 'is_vocal', 'is_explicit', 'created_at', 'published_at', 'duration', 'is_downloadable', 'genre_id', 'track_type_id', 'cover_id', 'album_id', 'comment_count', 'download_count', 'view_count', 'play_count', 'favourite_count');
|
return self::select('id', 'title', 'user_id', 'slug', 'is_vocal', 'is_explicit', 'created_at', 'published_at', 'duration', 'is_downloadable', 'genre_id', 'track_type_id', 'cover_id', 'album_id', 'comment_count', 'download_count', 'view_count', 'play_count', 'favourite_count');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeDetails($query) {
|
public function scopeUserDetails($query) {
|
||||||
if (Auth::check()) {
|
if (Auth::check()) {
|
||||||
$query->with(['users' => function($query) {
|
$query->with(['users' => function($query) {
|
||||||
$query->whereUserId(Auth::user()->id);
|
$query->whereUserId(Auth::user()->id);
|
||||||
|
@ -41,10 +42,52 @@
|
||||||
return !$query;
|
return !$query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function scopePublished($query) {
|
||||||
|
$query->whereNotNull('published_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeExplicitFilter($query) {
|
||||||
|
if (!Auth::check() || !Auth::user()->can_see_explicit_content)
|
||||||
|
$query->whereIsExplicit(false);
|
||||||
|
}
|
||||||
|
|
||||||
public function scopeWithComments($query) {
|
public function scopeWithComments($query) {
|
||||||
$query->with(['comments' => function($query) { $query->with('user'); }]);
|
$query->with(['comments' => function($query) { $query->with('user'); }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function popular($count, $allowExplicit = false) {
|
||||||
|
$tracks = Cache::remember('popular_tracks-' . ($allowExplicit ? 'explicit' : 'safe'), 5, function() use ($allowExplicit) {
|
||||||
|
$query = static
|
||||||
|
::with(['user', 'genre', 'cover', 'user.avatar'])
|
||||||
|
->published()
|
||||||
|
->whereIsExplicit($allowExplicit)
|
||||||
|
->join(DB::raw('
|
||||||
|
( SELECT `track_id`, `created_at`
|
||||||
|
FROM `resource_log_items`
|
||||||
|
WHERE `created_at` > now() - INTERVAL 1 DAY
|
||||||
|
) AS ranged_plays'),
|
||||||
|
'tracks.id', '=', 'ranged_plays.track_id')
|
||||||
|
->groupBy('id')
|
||||||
|
->orderBy('plays', 'desc')
|
||||||
|
->take(20);
|
||||||
|
return $query->get(['*', DB::raw('count(*) as plays')]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
foreach($tracks as $track) {
|
||||||
|
if ($i < $count) {
|
||||||
|
$results[] = self::mapPublicTrackSummary($track);
|
||||||
|
$i++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
public static function mapPublicTrackShow($track) {
|
public static function mapPublicTrackShow($track) {
|
||||||
$returnValue = self::mapPublicTrackSummary($track);
|
$returnValue = self::mapPublicTrackSummary($track);
|
||||||
$returnValue['description'] = $track->description;
|
$returnValue['description'] = $track->description;
|
||||||
|
@ -76,6 +119,15 @@
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$returnValue['share'] = [
|
||||||
|
'url' => URL::to('/t' . $track->id),
|
||||||
|
'html' => '<iframe src="https://pony.fm/t' . $track->id . '/embed" width="100%" height="150" allowTransparency="true" frameborder="0" seamless allowfullscreen></iframe>',
|
||||||
|
'bbcode' => '[url=' . $track->url . '][img]' . $track->getCoverUrl() . '[/img][/url]',
|
||||||
|
'twitterUrl' => 'https://platform.twitter.com/widgets/tweet_button.html?text=' . $track->title . ' by ' . $track->user->display_name . ' on Pony.fm'
|
||||||
|
];
|
||||||
|
|
||||||
|
$returnValue['share']['tumblrUrl'] = 'http://www.tumblr.com/share/video?embed=' . urlencode($returnValue['share']['html']) . '&caption=' . urlencode($track->title);
|
||||||
|
|
||||||
$returnValue['formats'] = $formats;
|
$returnValue['formats'] = $formats;
|
||||||
|
|
||||||
return $returnValue;
|
return $returnValue;
|
||||||
|
@ -191,7 +243,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comments(){
|
public function comments(){
|
||||||
return $this->hasMany('Entities\Comment');
|
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function favourites() {
|
public function favourites() {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
use Gravatar;
|
use Gravatar;
|
||||||
use Illuminate\Auth\UserInterface;
|
use Illuminate\Auth\UserInterface;
|
||||||
use Illuminate\Auth\Reminders\RemindableInterface;
|
use Illuminate\Auth\Reminders\RemindableInterface;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Ratchet\Wamp\Exception;
|
use Ratchet\Wamp\Exception;
|
||||||
|
@ -14,18 +15,36 @@
|
||||||
protected $table = 'users';
|
protected $table = 'users';
|
||||||
protected $hidden = ['password_hash', 'password_salt', 'bio'];
|
protected $hidden = ['password_hash', 'password_salt', 'bio'];
|
||||||
|
|
||||||
|
public function scopeUserDetails($query) {
|
||||||
|
if (Auth::check()) {
|
||||||
|
$query->with(['users' => function($query) {
|
||||||
|
$query->whereUserId(Auth::user()->id);
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$query;
|
||||||
|
}
|
||||||
|
|
||||||
public function avatar() {
|
public function avatar() {
|
||||||
return $this->belongsTo('Entities\Image');
|
return $this->belongsTo('Entities\Image');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comments(){
|
public function users() {
|
||||||
return $this->hasMany('Entities\Comment', 'profile_id');
|
return $this->hasMany('Entities\ResourceUser', 'artist_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function comments() {
|
||||||
|
return $this->hasMany('Entities\Comment', 'profile_id')->orderBy('created_at', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUrlAttribute() {
|
public function getUrlAttribute() {
|
||||||
return URL::to('/' . $this->slug);
|
return URL::to('/' . $this->slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMessageUrlAttribute() {
|
||||||
|
return 'http://mlpforums.com/index.php?app=members&module=messaging§ion=send&do=form&fromMemberID='.$this->id;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAuthIdentifier() {
|
public function getAuthIdentifier() {
|
||||||
return $this->getKey();
|
return $this->getKey();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
|
|
||||||
Route::get('/playlists/show/{id}', 'Api\Web\PlaylistsController@getShow');
|
Route::get('/playlists/show/{id}', 'Api\Web\PlaylistsController@getShow');
|
||||||
|
|
||||||
Route::get('/tracks/recent', 'Api\Web\TracksController@getRecent');
|
|
||||||
Route::get('/tracks', 'Api\Web\TracksController@getIndex');
|
Route::get('/tracks', 'Api\Web\TracksController@getIndex');
|
||||||
Route::get('/tracks/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+');
|
Route::get('/tracks/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+');
|
||||||
|
|
||||||
|
@ -90,6 +89,8 @@
|
||||||
Route::post('/account/settings/save', 'Api\Web\AccountController@postSave');
|
Route::post('/account/settings/save', 'Api\Web\AccountController@postSave');
|
||||||
|
|
||||||
Route::post('/favourites/toggle', 'Api\Web\FavouritesController@postToggle');
|
Route::post('/favourites/toggle', 'Api\Web\FavouritesController@postToggle');
|
||||||
|
|
||||||
|
Route::post('/follow/toggle', 'Api\Web\FollowController@postToggle');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['before' => 'auth'], function() {
|
Route::group(['before' => 'auth'], function() {
|
||||||
|
|
|
@ -1,6 +1,28 @@
|
||||||
@extends('shared._layout')
|
@extends('shared._layout')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
|
<div id="fb-root"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.fbAsyncInit = function() {
|
||||||
|
FB.init({
|
||||||
|
appId : '186765381447538',
|
||||||
|
status: true,
|
||||||
|
cookie: true,
|
||||||
|
xfbml: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(d, s, id){
|
||||||
|
var js, fjs = d.getElementsByTagName(s)[0];
|
||||||
|
if (d.getElementById(id)) {return;}
|
||||||
|
js = d.createElement(s); js.id = id;
|
||||||
|
js.src = "//connect.facebook.net/en_US/all.js";
|
||||||
|
fjs.parentNode.insertBefore(js, fjs);
|
||||||
|
}(document, 'script', 'facebook-jssdk'));
|
||||||
|
</script>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<a href="/">Pony.fm</a>
|
<a href="/">Pony.fm</a>
|
||||||
<div class="now-playing">
|
<div class="now-playing">
|
||||||
|
@ -51,7 +73,7 @@
|
||||||
</ui-view>
|
</ui-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-include src="'templates/partials/upload-dialog.html'" />
|
<ng-include src="'templates/partials/upload-dialog.html'"></ng-include>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@ -76,4 +98,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ Assets::scriptIncludes() }}
|
{{ Assets::scriptIncludes() }}
|
||||||
|
|
||||||
|
<script src="http://platform.tumblr.com/v1/share.js"></script>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
|
@ -10,4 +10,4 @@
|
||||||
|
|
||||||
<IfModule xsendfile_module>
|
<IfModule xsendfile_module>
|
||||||
XSendFile On
|
XSendFile On
|
||||||
</IfModule>
|
</IfModule>
|
|
@ -5,13 +5,22 @@ window.pfm.preloaders['album'] = [
|
||||||
]
|
]
|
||||||
|
|
||||||
angular.module('ponyfm').controller "album", [
|
angular.module('ponyfm').controller "album", [
|
||||||
'$scope', 'albums', '$state', 'playlists', 'auth'
|
'$scope', 'albums', '$state', 'playlists', 'auth', '$dialog'
|
||||||
($scope, albums, $state, playlists, auth) ->
|
($scope, albums, $state, playlists, auth, $dialog) ->
|
||||||
|
album = null
|
||||||
|
|
||||||
albums.fetch($state.params.id).done (albumResponse) ->
|
albums.fetch($state.params.id).done (albumResponse) ->
|
||||||
$scope.album = albumResponse.album
|
$scope.album = albumResponse.album
|
||||||
|
album = albumResponse.album
|
||||||
|
|
||||||
$scope.playlists = []
|
$scope.playlists = []
|
||||||
|
|
||||||
|
$scope.share = () ->
|
||||||
|
dialog = $dialog.dialog
|
||||||
|
templateUrl: '/templates/partials/album-share-dialog.html',
|
||||||
|
controller: ['$scope', ($scope) -> $scope.album = album; $scope.close = () -> dialog.close()]
|
||||||
|
dialog.open()
|
||||||
|
|
||||||
if auth.data.isLogged
|
if auth.data.isLogged
|
||||||
playlists.refreshOwned().done (lists) ->
|
playlists.refreshOwned().done (lists) ->
|
||||||
$scope.playlists.push list for list in lists
|
$scope.playlists.push list for list in lists
|
||||||
|
|
|
@ -17,5 +17,6 @@ angular.module('ponyfm').controller "albums", [
|
||||||
$scope.$on 'albums-feteched', (e, list) -> refreshPages(list)
|
$scope.$on 'albums-feteched', (e, list) -> refreshPages(list)
|
||||||
|
|
||||||
$scope.gotoPage = (page) ->
|
$scope.gotoPage = (page) ->
|
||||||
|
return if !page
|
||||||
$state.transitionTo 'content.albums.list', {page: page}
|
$state.transitionTo 'content.albums.list', {page: page}
|
||||||
]
|
]
|
|
@ -9,5 +9,4 @@ angular.module('ponyfm').controller "artist-favourites", [
|
||||||
($scope, artists, $state) ->
|
($scope, artists, $state) ->
|
||||||
artists.fetchFavourites($state.params.slug).done (artistResponse) ->
|
artists.fetchFavourites($state.params.slug).done (artistResponse) ->
|
||||||
$scope.favourites = artistResponse
|
$scope.favourites = artistResponse
|
||||||
console.log artistResponse
|
|
||||||
]
|
]
|
|
@ -5,8 +5,12 @@ window.pfm.preloaders['artist'] = [
|
||||||
]
|
]
|
||||||
|
|
||||||
angular.module('ponyfm').controller "artist", [
|
angular.module('ponyfm').controller "artist", [
|
||||||
'$scope', 'artists', '$state'
|
'$scope', 'artists', '$state', 'follow'
|
||||||
($scope, artists, $state) ->
|
($scope, artists, $state, follow) ->
|
||||||
artists.fetch($state.params.slug).done (artistResponse) ->
|
artists.fetch($state.params.slug).done (artistResponse) ->
|
||||||
$scope.artist = artistResponse.artist
|
$scope.artist = artistResponse.artist
|
||||||
|
|
||||||
|
$scope.toggleFollow = () ->
|
||||||
|
follow.toggle('artist', $scope.artist.id).then (res) ->
|
||||||
|
$scope.artist.user_data.is_following = res.is_followed
|
||||||
]
|
]
|
|
@ -17,5 +17,6 @@ angular.module('ponyfm').controller "artists", [
|
||||||
$scope.$on 'artists-feteched', (e, list) -> refreshPages(list)
|
$scope.$on 'artists-feteched', (e, list) -> refreshPages(list)
|
||||||
|
|
||||||
$scope.gotoPage = (page) ->
|
$scope.gotoPage = (page) ->
|
||||||
|
return if !page
|
||||||
$state.transitionTo 'content.artists.list', {page: page}
|
$state.transitionTo 'content.artists.list', {page: page}
|
||||||
]
|
]
|
|
@ -5,8 +5,17 @@ window.pfm.preloaders['playlist'] = [
|
||||||
]
|
]
|
||||||
|
|
||||||
angular.module('ponyfm').controller 'playlist', [
|
angular.module('ponyfm').controller 'playlist', [
|
||||||
'$scope', '$state', 'playlists'
|
'$scope', '$state', 'playlists', '$dialog'
|
||||||
($scope, $state, playlists) ->
|
($scope, $state, playlists, $dialog) ->
|
||||||
playlists.fetch($state.params.id).done (playlist) ->
|
playlist = null
|
||||||
$scope.playlist = playlist
|
|
||||||
|
playlists.fetch($state.params.id).done (playlistResponse) ->
|
||||||
|
$scope.playlist = playlistResponse
|
||||||
|
playlist = playlistResponse
|
||||||
|
|
||||||
|
$scope.share = () ->
|
||||||
|
dialog = $dialog.dialog
|
||||||
|
templateUrl: '/templates/partials/playlist-share-dialog.html',
|
||||||
|
controller: ['$scope', ($scope) -> $scope.playlist = playlist; $scope.close = () -> dialog.close()]
|
||||||
|
dialog.open()
|
||||||
]
|
]
|
|
@ -17,5 +17,6 @@ angular.module('ponyfm').controller "playlists", [
|
||||||
$scope.$on 'playlists-feteched', (e, list) -> refreshPages(list)
|
$scope.$on 'playlists-feteched', (e, list) -> refreshPages(list)
|
||||||
|
|
||||||
$scope.gotoPage = (page) ->
|
$scope.gotoPage = (page) ->
|
||||||
|
return if !page
|
||||||
$state.transitionTo 'content.playlists.list', {page: page}
|
$state.transitionTo 'content.playlists.list', {page: page}
|
||||||
]
|
]
|
|
@ -7,8 +7,11 @@ window.pfm.preloaders['track'] = [
|
||||||
angular.module('ponyfm').controller "track", [
|
angular.module('ponyfm').controller "track", [
|
||||||
'$scope', 'tracks', '$state', 'playlists', 'auth', 'favourites', '$dialog'
|
'$scope', 'tracks', '$state', 'playlists', 'auth', 'favourites', '$dialog'
|
||||||
($scope, tracks, $state, playlists, auth, favourites, $dialog) ->
|
($scope, tracks, $state, playlists, auth, favourites, $dialog) ->
|
||||||
|
track = null
|
||||||
|
|
||||||
tracks.fetch($state.params.id).done (trackResponse) ->
|
tracks.fetch($state.params.id).done (trackResponse) ->
|
||||||
$scope.track = trackResponse.track
|
$scope.track = trackResponse.track
|
||||||
|
track = trackResponse.track
|
||||||
|
|
||||||
$scope.playlists = []
|
$scope.playlists = []
|
||||||
|
|
||||||
|
@ -24,6 +27,12 @@ angular.module('ponyfm').controller "track", [
|
||||||
track.is_favourited = res.is_favourited
|
track.is_favourited = res.is_favourited
|
||||||
$scope.favouriteWorking = false
|
$scope.favouriteWorking = false
|
||||||
|
|
||||||
|
$scope.share = () ->
|
||||||
|
dialog = $dialog.dialog
|
||||||
|
templateUrl: '/templates/partials/track-share-dialog.html',
|
||||||
|
controller: ['$scope', ($scope) -> $scope.track = track; $scope.close = () -> dialog.close()]
|
||||||
|
dialog.open()
|
||||||
|
|
||||||
$scope.addToNewPlaylist = () ->
|
$scope.addToNewPlaylist = () ->
|
||||||
dialog = $dialog.dialog
|
dialog = $dialog.dialog
|
||||||
templateUrl: '/templates/partials/playlist-dialog.html'
|
templateUrl: '/templates/partials/playlist-dialog.html'
|
||||||
|
|
6
public/scripts/app/directives/share-buttons.coffee
Normal file
6
public/scripts/app/directives/share-buttons.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
angular.module('ponyfm').directive 'pfmShareButtons', () ->
|
||||||
|
(scope, element) ->
|
||||||
|
window.setTimeout((->
|
||||||
|
Tumblr.activate_share_on_tumblr_buttons()
|
||||||
|
FB.XFBML.parse()
|
||||||
|
), 0)
|
|
@ -1,6 +1,7 @@
|
||||||
angular.module('ponyfm').directive 'pfmTracksList', () ->
|
angular.module('ponyfm').directive 'pfmTracksList', () ->
|
||||||
restrict: 'E'
|
restrict: 'E'
|
||||||
templateUrl: '/templates/directives/tracks-list.html'
|
templateUrl: '/templates/directives/tracks-list.html'
|
||||||
|
replace: true
|
||||||
scope:
|
scope:
|
||||||
tracks: '=tracks',
|
tracks: '=tracks',
|
||||||
class: '@class'
|
class: '@class'
|
||||||
|
|
|
@ -14,7 +14,7 @@ angular.module('ponyfm').filter('pfmdate', [
|
||||||
if (!value)
|
if (!value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return value.toString() == '[object Date]';
|
return Object.prototype.toString.apply(value) == '[object Date]';
|
||||||
}
|
}
|
||||||
|
|
||||||
function padNumber(num, digits, trim) {
|
function padNumber(num, digits, trim) {
|
||||||
|
@ -81,6 +81,8 @@ angular.module('ponyfm').filter('pfmdate', [
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
|
||||||
|
|
||||||
var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,
|
var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,
|
||||||
NUMBER_STRING = /^\d+$/;
|
NUMBER_STRING = /^\d+$/;
|
||||||
|
|
||||||
|
@ -190,8 +192,9 @@ angular.module('ponyfm').filter('pfmdate', [
|
||||||
date = new Date(date);
|
date = new Date(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof(date) == 'object' && date.date)
|
if (typeof(date) == 'object' && date.date) {
|
||||||
date = new Date(date.date);
|
date = new Date(date.date);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isDate(date)) {
|
if (!isDate(date)) {
|
||||||
return date;
|
return date;
|
||||||
|
|
13
public/scripts/app/services/follow.coffee
Normal file
13
public/scripts/app/services/follow.coffee
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
angular.module('ponyfm').factory('follow', [
|
||||||
|
'$rootScope', '$http'
|
||||||
|
($rootScope, $http) ->
|
||||||
|
self =
|
||||||
|
toggle: (type, id) ->
|
||||||
|
def = new $.Deferred()
|
||||||
|
$http.post('/api/web/follow/toggle', {type: type, id: id, _token: pfm.token}).success (res) ->
|
||||||
|
def.resolve res
|
||||||
|
|
||||||
|
def.promise()
|
||||||
|
|
||||||
|
self
|
||||||
|
])
|
|
@ -11,4 +11,5 @@
|
||||||
@import 'animations';
|
@import 'animations';
|
||||||
@import 'body';
|
@import 'body';
|
||||||
@import 'player';
|
@import 'player';
|
||||||
@import 'content';
|
@import 'content';
|
||||||
|
@import 'dashboard';
|
|
@ -1,6 +1,14 @@
|
||||||
@import-once 'variables';
|
@import-once 'variables';
|
||||||
@import-once 'base/bootstrap/bootstrap';
|
@import-once 'base/bootstrap/bootstrap';
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #C2889C;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.site-content{
|
.site-content{
|
||||||
.box-sizing(border-box);
|
.box-sizing(border-box);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
|
@ -327,6 +327,17 @@ html {
|
||||||
.border-radius(0px);
|
.border-radius(0px);
|
||||||
|
|
||||||
border: 2px solid @pfm-purple;
|
border: 2px solid @pfm-purple;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #C2889C;
|
||||||
|
line-height: normal;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
|
|
|
@ -6,23 +6,41 @@
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.two-columns {
|
||||||
|
li {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
.box-sizing(border-box);
|
.box-sizing(border-box);
|
||||||
float: left;
|
float: left;
|
||||||
width: 16.6666%;
|
width: 25%;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
background: #ddd;
|
background: #eee;
|
||||||
display: block;
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 67px;
|
||||||
|
height: 67px;
|
||||||
|
background: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title, .published {
|
.info {
|
||||||
|
margin-left: 72px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title, .published, .stats {
|
||||||
display: block;
|
display: block;
|
||||||
color: #444;
|
color: #444;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
@ -32,17 +50,35 @@
|
||||||
.ellipsis();
|
.ellipsis();
|
||||||
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 12pt;
|
font-size: 11pt;
|
||||||
|
padding-left: 3px;
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.published {
|
.published {
|
||||||
color: #777;
|
font-size: 8pt;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.published, .stats {
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
|
color: #777;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3px;
|
||||||
|
right: 3px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
background: #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +93,34 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.artist-details {
|
||||||
|
> header {
|
||||||
|
.tabs {
|
||||||
|
clear: left;
|
||||||
|
margin: 0px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: none;
|
||||||
|
font-size: 9pt;
|
||||||
|
|
||||||
|
li.active {
|
||||||
|
a {
|
||||||
|
border: none;
|
||||||
|
background: #C1889E;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-buttons {
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
.facebook, .twitter {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> header {
|
> header {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background: #eee;
|
background: #eee;
|
||||||
|
@ -174,15 +238,8 @@ html .single-player .play-button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracks-listing {
|
html {
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
li {
|
li {
|
||||||
.box-sizing(border-box);
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.empty {
|
&.empty {
|
||||||
.border-radius(0px);
|
.border-radius(0px);
|
||||||
background: lighten(@pfm-purple, 30%);
|
background: lighten(@pfm-purple, 30%);
|
||||||
|
@ -199,6 +256,18 @@ html .single-player .play-button {
|
||||||
background-color: lighten(@pfm-purple, 30%);
|
background-color: lighten(@pfm-purple, 30%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tracks-listing {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
list-style: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
li {
|
||||||
|
.box-sizing(border-box);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
23
public/styles/dashboard.less
Normal file
23
public/styles/dashboard.less
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
@import-once "base/bootstrap/bootstrap";
|
||||||
|
|
||||||
|
.recent-tracks {
|
||||||
|
h1 {
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
font-size: 10pt;
|
||||||
|
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard {
|
||||||
|
section {
|
||||||
|
.box-sizing(border-box);
|
||||||
|
|
||||||
|
float: left;
|
||||||
|
width: 50%;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
<li bindonce ng-repeat="format in album.formats"><a target="_blank" bo-href="format.url"><span bo-text="format.name"></span> <small bo-text="'(' + format.size + ')'"></small></a></li>
|
<li bindonce ng-repeat="format in album.formats"><a target="_blank" bo-href="format.url"><span bo-text="format.name"></span> <small bo-text="'(' + format.size + ')'"></small></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#" class="btn">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>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -23,8 +23,14 @@
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img class="cover" bo-src="album.covers.normal" />
|
<img class="cover" bo-src="album.covers.normal" />
|
||||||
|
|
||||||
|
<div class="share-buttons" pfm-share-buttons>
|
||||||
|
<a class="tumblr" bo-href="album.share.tumblrUrl" title="Share on Tumblr" style="display:inline-block; overflow:hidden; width:20px; height:20px; background:url('http://platform.tumblr.com/v1/share_4.png') top left no-repeat transparent;"></a>
|
||||||
|
<div class="facebook fb-like" data-href="{{album.url}}" data-width="450" data-layout="button_count" data-show-faces="true" data-send="false"></div>
|
||||||
|
<iframe class="twitter" allowtransparency="true" frameborder="0" scrolling="no" bo-src="album.share.twitterUrl" style="width:130px; height:20px;"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Published: <strong bo-text="album.published_at | pfmdate:'short'"></strong></li>
|
<li>Published: <strong bo-text="album.created_at | pfmdate:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="album.stats.views"></strong></li>
|
<li>Views: <strong bo-text="album.stats.views"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="album.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="album.stats.downloads"></strong></li>
|
||||||
<li>Favourites: <strong bo-text="album.stats.favourites"></strong></li>
|
<li>Favourites: <strong bo-text="album.stats.favourites"></strong></li>
|
||||||
|
|
|
@ -1,33 +1,25 @@
|
||||||
<div class="user-details">
|
<div class="resource-details artist-details" bindonce="artist">
|
||||||
<ul class="breadcrumb">
|
<ul class="dropdowns">
|
||||||
<li><a href="/artists">Artist Directory</a> <span class="divider">/</span></li>
|
<li class="dropdown">
|
||||||
<li class="active">{{artist.name}}</li>
|
<a href="#" class="btn btn-small" ng-class="{'btn-primary': !artist.user_data.is_following}" ng-show="auth.isLogged && auth.user.id != artist.id" pfm-eat-click ng-click="toggleFollow()">
|
||||||
|
<span ng-hide="artist.user_data.is_following">Follow</span>
|
||||||
|
<span ng-show="artist.user_data.is_following">Following!</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a target="_blank" bo-href="artist.message_url" class="btn btn-small">
|
||||||
|
Send a Message
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<header>
|
||||||
<div class="track-toolbar btn-group pull-right">
|
<h1 bo-text="artist.name"></h1>
|
||||||
<a href="#" class="btn btn-small" ng-show="auth.isLogged">
|
|
||||||
Follow
|
|
||||||
</a>
|
|
||||||
<a href="#" class="btn btn-small">
|
|
||||||
Send a Message
|
|
||||||
</a>
|
|
||||||
<a href="#" class="btn btn-small">
|
|
||||||
MLP Forums Profile
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="header">
|
|
||||||
<h1>
|
|
||||||
{{artist.name}}
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<ul class="tabs">
|
<ul class="tabs">
|
||||||
<li ng-class="{active: stateIncludes('artist.profile')}"><a href="{{artist.slug}}">Profile</a></li>
|
<li ng-class="{active: stateIncludes('content.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('content.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>
|
<li ng-class="{active: stateIncludes('content.artist.favourites')}"><a href="{{artist.slug}}/favourites">Favourites</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
<div class="stretch-to-bottom">
|
<div class="stretch-to-bottom">
|
||||||
<ui-view></ui-view>
|
<ui-view></ui-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<div ng-show="content.albums.length">
|
<div ng-show="content.albums.length">
|
||||||
<h2>Albums</h2>
|
<h2>Albums</h2>
|
||||||
<pfm-albums-list albums="content.albums" />
|
<pfm-albums-list albums="content.albums"></pfm-albums-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="content.singles.length">
|
<div ng-show="content.singles.length">
|
||||||
<h2>Singles</h2>
|
<h2>Singles</h2>
|
||||||
<pfm-tracks-list tracks="content.singles" class="four-column no-artist"></pfm-tracks-list>
|
<pfm-tracks-list tracks="content.singles" class="four-columns no-artist"></pfm-tracks-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="content.albumTracks.length">
|
<div ng-show="content.albumTracks.length">
|
||||||
<h2>Part of an Album</h2>
|
<h2>Part of an Album</h2>
|
||||||
<pfm-tracks-list tracks="content.albumTracks" class="four-column no-artist"></pfm-tracks-list>
|
<pfm-tracks-list tracks="content.albumTracks" class="four-columns no-artist"></pfm-tracks-list>
|
||||||
</div>
|
</div>
|
|
@ -5,6 +5,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="span6">
|
<div class="span6">
|
||||||
<h2>Albums</h2>
|
<h2>Albums</h2>
|
||||||
<pfm-albums-list albums="favourites.albums"></pfm-albums-list>
|
<pfm-albums-list albums="favourites.albums" class="two-columns"></pfm-albums-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,10 +1,12 @@
|
||||||
<ul class="artist-listing stretch-to-bottom">
|
<ul class="artist-listing stretch-to-bottom">
|
||||||
<li ng-repeat="artist in artists">
|
<li ng-repeat="artist in artists" bindonce>
|
||||||
<a href="{{artist.url}}">
|
<a href="{{artist.url}}">
|
||||||
<img class="image" ng-src="{{artist.avatars.normal}}" />
|
<img class="image" bo-src="artist.avatars.small" />
|
||||||
<span class="title">{{artist.name}}</span>
|
<span class="info">
|
||||||
<span class="published">
|
<span class="title" bo-text="artist.name"></span>
|
||||||
joined {{artist.created_at.date | momentFromNow}}
|
<span class="published">
|
||||||
|
joined <span bo-text="artist.created_at.date | momentFromNow"></span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span6">
|
<div class="span6">
|
||||||
<div ng-show="artist.bio.trim().length">
|
<div bo-show="artist.bio.trim().length">
|
||||||
<h2>Bio</h2>
|
<h2>Bio</h2>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p ng-bind-html-unsafe="artist.bio | noHTML | newlines"></p>
|
<p bo-html="artist.bio | noHTML | newlines"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Comments</h2>
|
|
||||||
<pfm-comments type="user" resource="artist"></pfm-comments>
|
<pfm-comments type="user" resource="artist"></pfm-comments>
|
||||||
</div>
|
</div>
|
||||||
<div class="span6 cover-image">
|
<div class="span6 cover-image">
|
||||||
<h2>Recent Tracks</h2>
|
<h2>Recent Tracks</h2>
|
||||||
<pfm-tracks-list tracks="artist.latest_tracks" class="two-column no-artist" />
|
<pfm-tracks-list tracks="artist.latest_tracks" class="two-columns no-artist" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,9 +1,20 @@
|
||||||
<section class="recent-tracks stretch-to-bottom">
|
<div class="dashboard">
|
||||||
<div>
|
<section class="recent-tracks stretch-to-bottom">
|
||||||
<h1>
|
<div>
|
||||||
<a href="/tracks"><i class="icon-music"></i> see more</a>
|
<h1>
|
||||||
The Newest Tunes
|
<a href="/tracks"><i class="icon-music"></i> see more</a>
|
||||||
</h1>
|
The Newest Tunes
|
||||||
<pfm-tracks-list tracks="recentTracks" class="two-columns"></pfm-tracks-list>
|
</h1>
|
||||||
</div>
|
<pfm-tracks-list tracks="recentTracks" class="two-columns"></pfm-tracks-list>
|
||||||
</section>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="popular-tracks stretch-to-bottom">
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
What's Popular Today
|
||||||
|
</h1>
|
||||||
|
<pfm-tracks-list tracks="popularTracks" class="two-columns"></pfm-tracks-list>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
|
@ -1,10 +1,17 @@
|
||||||
<ul class="albums-listing {{class}}">
|
<ul class="albums-listing {{class}}">
|
||||||
<li ng-repeat="album in albums">
|
<li ng-repeat="album in albums" bindonce>
|
||||||
<a href="{{album.url}}">
|
<a bo-href="album.url">
|
||||||
<img class="image" ng-src="{{album.covers.normal}}" />
|
<img class="image" bo-src="album.covers.small" />
|
||||||
<span class="title">{{album.title}}</span>
|
<span class="info">
|
||||||
|
<span class="title" bo-text="album.title"></span>
|
||||||
<span class="published">
|
<span class="published">
|
||||||
by {{album.user.name}}
|
by <span bo-text="album.user.name"></span>
|
||||||
|
</span>
|
||||||
|
<span class="stats">
|
||||||
|
<strong bo-text="album.stats.favourites"></strong> <i class="icon-star"></i>
|
||||||
|
<strong bo-text="album.stats.comments"></strong> <i class="icon-comment"></i>
|
||||||
|
<strong bo-text="album.stats.downloads"></strong> <i class="icon-download"></i>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<div class="comments" bindonce>
|
<div class="comments" bindonce>
|
||||||
<h2>All Comments ({{resource.comments.length}})</h2>
|
<h2>All Comments ({{resource.comments.length}})</h2>
|
||||||
<div class="alert alert-info" ng-show="resource.comments.length == 0">
|
|
||||||
There are no comments yet!
|
|
||||||
</div>
|
|
||||||
<form class="pfm-form" ng-submit="addComment()" ng-show="auth.isLogged">
|
<form class="pfm-form" ng-submit="addComment()" ng-show="auth.isLogged">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<input type="text" ng-model="content" placeholder="Write a comment..." />
|
<input type="text" ng-model="content" placeholder="Write a comment..." />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<ul ng-show="resource.comments.length > 0">
|
<ul>
|
||||||
|
<li ng-show="resource.comments.length == 0" class="empty">
|
||||||
|
There are no comments yet!
|
||||||
|
</li>
|
||||||
<li bindonce ng-repeat="comment in resource.comments">
|
<li bindonce ng-repeat="comment in resource.comments">
|
||||||
<img bo-src="comment.user.avatars.thumbnail" />
|
<img bo-src="comment.user.avatars.thumbnail" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
<ul class="playlists-listing {{class}}">
|
<ul class="playlists-listing {{class}}">
|
||||||
<li ng-repeat="playlist in playlists">
|
<li ng-repeat="playlist in playlists" bindonce>
|
||||||
<a href="{{playlist.url}}">
|
<a href="{{playlist.url}}">
|
||||||
<img class="image" ng-src="{{playlist.covers.normal}}" height="350" width="350" />
|
<img class="image" ng-src="{{playlist.covers.small}}"/>
|
||||||
<span class="title">{{playlist.title}}</span>
|
<span class="info">
|
||||||
<span class="published">
|
<span class="title">{{playlist.title}}</span>
|
||||||
by {{playlist.user.name}}
|
<span class="published">
|
||||||
|
by {{playlist.user.name}}
|
||||||
|
</span>
|
||||||
|
<span class="stats">
|
||||||
|
<strong bo-text="playlist.stats.favourites"></strong> <i class="icon-star"></i>
|
||||||
|
<strong bo-text="playlist.stats.comments"></strong> <i class="icon-comment"></i>
|
||||||
|
<strong bo-text="playlist.stats.downloads"></strong> <i class="icon-download"></i>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
13
public/templates/partials/album-share-dialog.html
Normal file
13
public/templates/partials/album-share-dialog.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>
|
||||||
|
<button type="button" class="close" ng-click="close()" ng-hide="isLoading">×</button>
|
||||||
|
{{album.title}}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h2>Shortlink</h2>
|
||||||
|
<input type="text" ng-model="album.share.url" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="btn cancel" ng-click="close()" ng-disabled="isLoading">Close</a>
|
||||||
|
</div>
|
13
public/templates/partials/playlist-share-dialog.html
Normal file
13
public/templates/partials/playlist-share-dialog.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>
|
||||||
|
<button type="button" class="close" ng-click="close()" ng-hide="isLoading">×</button>
|
||||||
|
{{playlist.title}}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h2>Shortlink</h2>
|
||||||
|
<input type="text" ng-model="playlist.share.url" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="btn cancel" ng-click="close()" ng-disabled="isLoading">Close</a>
|
||||||
|
</div>
|
19
public/templates/partials/track-share-dialog.html
Normal file
19
public/templates/partials/track-share-dialog.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>
|
||||||
|
<button type="button" class="close" ng-click="close()" ng-hide="isLoading">×</button>
|
||||||
|
{{track.title}}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h2>Shortlink</h2>
|
||||||
|
<input type="text" ng-model="track.share.url" />
|
||||||
|
|
||||||
|
<h2>HTML Embed <small>(websites, blogs)</small></h2>
|
||||||
|
<textarea type="text" ng-model="track.share.html"></textarea>
|
||||||
|
|
||||||
|
<h2>BBCode Embed <small>(forums)</small></h2>
|
||||||
|
<textarea type="text" ng-model="track.share.bbcode"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="btn cancel" ng-click="close()" ng-disabled="isLoading">Close</a>
|
||||||
|
</div>
|
|
@ -8,7 +8,7 @@
|
||||||
<li bindonce ng-repeat="format in playlist.formats"><a target="_blank" bo-href="format.url"><span bo-text="format.name"></span> <small bo-text="'(' + format.size + ')'"></small></a></li>
|
<li bindonce ng-repeat="format in playlist.formats"><a target="_blank" bo-href="format.url"><span bo-text="format.name"></span> <small bo-text="'(' + format.size + ')'"></small></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#" class="btn">Share or Embed</a></li>
|
<li><a href="#" class="btn" pfm-eat-click ng-click="share()">Share</a></li>
|
||||||
<li><pfm-favourite-button resource="playlist" type="playlist"></pfm-favourite-button></li>
|
<li><pfm-favourite-button resource="playlist" type="playlist"></pfm-favourite-button></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -19,13 +19,18 @@
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
||||||
<div class="stretch-to-bottom details-columns">
|
<div class="stretch-to-bottom details-columns">
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img class="cover" bo-src="playlist.covers.normal" />
|
<img class="cover" bo-src="playlist.covers.normal" />
|
||||||
|
|
||||||
|
<div class="share-buttons" pfm-share-buttons>
|
||||||
|
<a class="tumblr" bo-href="playlist.share.tumblrUrl" title="Share on Tumblr" style="display:inline-block; overflow:hidden; width:20px; height:20px; background:url('http://platform.tumblr.com/v1/share_4.png') top left no-repeat transparent;"></a>
|
||||||
|
<div class="facebook fb-like" data-href="{{playlist.url}}" data-width="450" data-layout="button_count" data-show-faces="true" data-send="false"></div>
|
||||||
|
<iframe class="twitter" allowtransparency="true" frameborder="0" scrolling="no" bo-src="playlist.share.twitterUrl" style="width:130px; height:20px;"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Created: <strong bo-text="playlist.created_at.date | pfmdate:'short'"></strong></li>
|
<li>Created: <strong bo-text="playlist.created_at | pfmdate:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="playlist.stats.views"></strong></li>
|
<li>Views: <strong bo-text="playlist.stats.views"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="playlist.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="playlist.stats.downloads"></strong></li>
|
||||||
<li>Favourites: <strong bo-text="playlist.stats.favourites"></strong></li>
|
<li>Favourites: <strong bo-text="playlist.stats.favourites"></strong></li>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<li><a href="#" class="add-btn" pfm-eat-click ng-click="addToNewPlaylist()">Add to New Playlist</a></li>
|
<li><a href="#" class="add-btn" pfm-eat-click ng-click="addToNewPlaylist()">Add to New Playlist</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#" class="btn">Share or Embed</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>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -42,8 +42,14 @@
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img class="cover" bo-src="track.covers.normal" />
|
<img class="cover" bo-src="track.covers.normal" />
|
||||||
|
|
||||||
|
<div class="share-buttons" pfm-share-buttons>
|
||||||
|
<a class="tumblr" bo-href="track.share.tumblrUrl" title="Share on Tumblr" style="display:inline-block; overflow:hidden; width:20px; height:20px; background:url('http://platform.tumblr.com/v1/share_4.png') top left no-repeat transparent;"></a>
|
||||||
|
<div class="facebook fb-like" data-href="{{track.url}}" data-width="450" data-layout="button_count" data-show-faces="true" data-send="false"></div>
|
||||||
|
<iframe class="twitter" allowtransparency="true" frameborder="0" scrolling="no" bo-src="track.share.twitterUrl" style="width:130px; height:20px;"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Published: <strong bo-text="track.published_at | pfmdate:'short'"></strong></li>
|
<li>Published: <strong bo-text="track.published_at | pfmdate:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="track.stats.views"></strong></li>
|
<li>Views: <strong bo-text="track.stats.views"></strong></li>
|
||||||
<li>Plays: <strong bo-text="track.stats.plays"></strong></li>
|
<li>Plays: <strong bo-text="track.stats.plays"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="track.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="track.stats.downloads"></strong></li>
|
||||||
|
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223::getLoader();
|
return ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225::getLoader();
|
||||||
|
|
7
vendor/composer/autoload_classmap.php
vendored
7
vendor/composer/autoload_classmap.php
vendored
|
@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir);
|
||||||
return array(
|
return array(
|
||||||
'AbstractOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/AbstractOutputProvider.php',
|
'AbstractOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/AbstractOutputProvider.php',
|
||||||
'AccountController' => $baseDir . '/app/controllers/AccountController.php',
|
'AccountController' => $baseDir . '/app/controllers/AccountController.php',
|
||||||
|
'AlbumDownloader' => $baseDir . '/app/models/AlbumDownloader.php',
|
||||||
'AlbumsController' => $baseDir . '/app/controllers/AlbumsController.php',
|
'AlbumsController' => $baseDir . '/app/controllers/AlbumsController.php',
|
||||||
'ApiControllerBase' => $baseDir . '/app/controllers/ApiControllerBase.php',
|
'ApiControllerBase' => $baseDir . '/app/controllers/ApiControllerBase.php',
|
||||||
'Api\\Web\\AccountController' => $baseDir . '/app/controllers/Api/Web/AccountController.php',
|
'Api\\Web\\AccountController' => $baseDir . '/app/controllers/Api/Web/AccountController.php',
|
||||||
|
@ -19,6 +20,7 @@ return array(
|
||||||
'Api\\Web\\FavouritesController' => $baseDir . '/app/controllers/Api/Web/FavouritesController.php',
|
'Api\\Web\\FavouritesController' => $baseDir . '/app/controllers/Api/Web/FavouritesController.php',
|
||||||
'Api\\Web\\ImagesController' => $baseDir . '/app/controllers/Api/Web/ImagesController.php',
|
'Api\\Web\\ImagesController' => $baseDir . '/app/controllers/Api/Web/ImagesController.php',
|
||||||
'Api\\Web\\PlaylistsController' => $baseDir . '/app/controllers/Api/Web/PlaylistsController.php',
|
'Api\\Web\\PlaylistsController' => $baseDir . '/app/controllers/Api/Web/PlaylistsController.php',
|
||||||
|
'Api\\Web\\ProfilerController' => $baseDir . '/app/controllers/Api/Web/ProfilerController.php',
|
||||||
'Api\\Web\\TaxonomiesController' => $baseDir . '/app/controllers/Api/Web/TaxonomiesController.php',
|
'Api\\Web\\TaxonomiesController' => $baseDir . '/app/controllers/Api/Web/TaxonomiesController.php',
|
||||||
'Api\\Web\\TracksController' => $baseDir . '/app/controllers/Api/Web/TracksController.php',
|
'Api\\Web\\TracksController' => $baseDir . '/app/controllers/Api/Web/TracksController.php',
|
||||||
'ArtistsController' => $baseDir . '/app/controllers/ArtistsController.php',
|
'ArtistsController' => $baseDir . '/app/controllers/ArtistsController.php',
|
||||||
|
@ -150,6 +152,7 @@ return array(
|
||||||
'CreateAlbums' => $baseDir . '/app/database/migrations/2013_07_28_060804_create_albums.php',
|
'CreateAlbums' => $baseDir . '/app/database/migrations/2013_07_28_060804_create_albums.php',
|
||||||
'CreateComments' => $baseDir . '/app/database/migrations/2013_08_01_051337_create_comments.php',
|
'CreateComments' => $baseDir . '/app/database/migrations/2013_08_01_051337_create_comments.php',
|
||||||
'CreateFavourites' => $baseDir . '/app/database/migrations/2013_08_18_045248_create_favourites.php',
|
'CreateFavourites' => $baseDir . '/app/database/migrations/2013_08_18_045248_create_favourites.php',
|
||||||
|
'CreateFollowers' => $baseDir . '/app/database/migrations/2013_08_29_025516_create_followers.php',
|
||||||
'CreateImagesTable' => $baseDir . '/app/database/migrations/2013_07_26_230827_create_images_table.php',
|
'CreateImagesTable' => $baseDir . '/app/database/migrations/2013_07_26_230827_create_images_table.php',
|
||||||
'CreatePlaylists' => $baseDir . '/app/database/migrations/2013_07_28_135136_create_playlists.php',
|
'CreatePlaylists' => $baseDir . '/app/database/migrations/2013_07_28_135136_create_playlists.php',
|
||||||
'CreateSongsTable' => $baseDir . '/app/database/migrations/2013_07_28_034328_create_songs_table.php',
|
'CreateSongsTable' => $baseDir . '/app/database/migrations/2013_07_28_034328_create_songs_table.php',
|
||||||
|
@ -430,7 +433,9 @@ return array(
|
||||||
'Entities\\License' => $baseDir . '/app/models/Entities/License.php',
|
'Entities\\License' => $baseDir . '/app/models/Entities/License.php',
|
||||||
'Entities\\PinnedPlaylist' => $baseDir . '/app/models/Entities/PinnedPlaylist.php',
|
'Entities\\PinnedPlaylist' => $baseDir . '/app/models/Entities/PinnedPlaylist.php',
|
||||||
'Entities\\Playlist' => $baseDir . '/app/models/Entities/Playlist.php',
|
'Entities\\Playlist' => $baseDir . '/app/models/Entities/Playlist.php',
|
||||||
|
'Entities\\ProfileRequest' => $baseDir . '/app/models/Entities/ProfileRequest.php',
|
||||||
'Entities\\ResourceLogItem' => $baseDir . '/app/models/Entities/ResourceLogItem.php',
|
'Entities\\ResourceLogItem' => $baseDir . '/app/models/Entities/ResourceLogItem.php',
|
||||||
|
'Entities\\ResourceUser' => $baseDir . '/app/models/Entities/ResourceUser.php',
|
||||||
'Entities\\ShowSong' => $baseDir . '/app/models/Entities/ShowSong.php',
|
'Entities\\ShowSong' => $baseDir . '/app/models/Entities/ShowSong.php',
|
||||||
'Entities\\Track' => $baseDir . '/app/models/Entities/Track.php',
|
'Entities\\Track' => $baseDir . '/app/models/Entities/Track.php',
|
||||||
'Entities\\TrackType' => $baseDir . '/app/models/Entities/TrackType.php',
|
'Entities\\TrackType' => $baseDir . '/app/models/Entities/TrackType.php',
|
||||||
|
@ -1058,6 +1063,7 @@ return array(
|
||||||
'Patchwork\\PHP\\Shim\\Xml' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Xml.php',
|
'Patchwork\\PHP\\Shim\\Xml' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Xml.php',
|
||||||
'Patchwork\\Utf8' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8.php',
|
'Patchwork\\Utf8' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8.php',
|
||||||
'Patchwork\\Utf8\\Bootup' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8/Bootup.php',
|
'Patchwork\\Utf8\\Bootup' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8/Bootup.php',
|
||||||
|
'PlaylistDownloader' => $baseDir . '/app/models/PlaylistDownloader.php',
|
||||||
'PlaylistsController' => $baseDir . '/app/controllers/PlaylistsController.php',
|
'PlaylistsController' => $baseDir . '/app/controllers/PlaylistsController.php',
|
||||||
'Predis\\Autoloader' => $vendorDir . '/predis/predis/lib/Predis/Autoloader.php',
|
'Predis\\Autoloader' => $vendorDir . '/predis/predis/lib/Predis/Autoloader.php',
|
||||||
'Predis\\BasicClientInterface' => $vendorDir . '/predis/predis/lib/Predis/BasicClientInterface.php',
|
'Predis\\BasicClientInterface' => $vendorDir . '/predis/predis/lib/Predis/BasicClientInterface.php',
|
||||||
|
@ -1393,6 +1399,7 @@ return array(
|
||||||
'React\\Stream\\Util' => $vendorDir . '/react/stream/React/Stream/Util.php',
|
'React\\Stream\\Util' => $vendorDir . '/react/stream/React/Stream/Util.php',
|
||||||
'React\\Stream\\WritableStream' => $vendorDir . '/react/stream/React/Stream/WritableStream.php',
|
'React\\Stream\\WritableStream' => $vendorDir . '/react/stream/React/Stream/WritableStream.php',
|
||||||
'React\\Stream\\WritableStreamInterface' => $vendorDir . '/react/stream/React/Stream/WritableStreamInterface.php',
|
'React\\Stream\\WritableStreamInterface' => $vendorDir . '/react/stream/React/Stream/WritableStreamInterface.php',
|
||||||
|
'RefreshCache' => $baseDir . '/app/commands/RefreshCache.php',
|
||||||
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
|
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
|
||||||
'StringOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/StringOutputProvider.php',
|
'StringOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/StringOutputProvider.php',
|
||||||
'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php',
|
'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php',
|
||||||
|
|
6
vendor/composer/autoload_real.php
vendored
6
vendor/composer/autoload_real.php
vendored
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// autoload_real.php generated by Composer
|
// autoload_real.php generated by Composer
|
||||||
|
|
||||||
class ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223
|
class ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225
|
||||||
{
|
{
|
||||||
private static $loader;
|
private static $loader;
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ class ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223
|
||||||
return self::$loader;
|
return self::$loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225', 'loadClassLoader'), true, true);
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225', 'loadClassLoader'));
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(__DIR__);
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
Loading…
Reference in a new issue