mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-01-30 19:06:44 +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) {
|
||||
$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)
|
||||
App::abort(404);
|
||||
|
||||
|
@ -49,12 +59,12 @@
|
|||
|
||||
$query = Album::summary()
|
||||
->with('user', 'user.avatar', 'cover')
|
||||
->details()
|
||||
->userDetails()
|
||||
->orderBy('created_at', 'desc')
|
||||
->where('track_count', '>', 0);
|
||||
|
||||
$count = $query->count();
|
||||
$perPage = 18;
|
||||
$perPage = 40;
|
||||
|
||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||
$albums = [];
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
'track.user',
|
||||
'album.cover',
|
||||
'album.user',
|
||||
'track' => function($query) { $query->details(); },
|
||||
'album' => function($query) { $query->details(); }])->get();
|
||||
'track' => function($query) { $query->userDetails(); },
|
||||
'album' => function($query) { $query->userDetails(); }])->get();
|
||||
|
||||
$tracks = [];
|
||||
$albums = [];
|
||||
|
@ -56,7 +56,7 @@
|
|||
if (!$user)
|
||||
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 = [];
|
||||
$singles = [];
|
||||
|
||||
|
@ -83,11 +83,11 @@
|
|||
}
|
||||
|
||||
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)
|
||||
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 = [];
|
||||
|
||||
foreach ($trackQuery->get() as $track) {
|
||||
|
@ -99,6 +99,17 @@
|
|||
$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([
|
||||
'artist' => [
|
||||
'id' => $user->id,
|
||||
|
@ -112,9 +123,11 @@
|
|||
'followers' => [],
|
||||
'following' => [],
|
||||
'latest_tracks' => $latestTracks,
|
||||
'comments' => ['count' => count($comments), 'list' => $comments],
|
||||
'comments' => $comments,
|
||||
'bio' => $user->bio,
|
||||
'mlpforums_username' => $user->mlpforums_name
|
||||
'mlpforums_username' => $user->mlpforums_name,
|
||||
'message_url' => $user->message_url,
|
||||
'user_data' => $userData
|
||||
]
|
||||
], 200);
|
||||
}
|
||||
|
@ -128,7 +141,7 @@
|
|||
->where('track_count', '>', 0);
|
||||
|
||||
$count = $query->count();
|
||||
$perPage = 18;
|
||||
$perPage = 40;
|
||||
|
||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||
$users = [];
|
||||
|
|
|
@ -14,18 +14,22 @@
|
|||
|
||||
class DashboardController extends \ApiControllerBase {
|
||||
public function getIndex() {
|
||||
$query = Track::summary()->with(['genre', 'user', 'cover'])->details()->whereNotNull('published_at')->orderBy('published_at', 'desc')->take(30);
|
||||
if (!Auth::check() || !Auth::user()->can_see_explicit_content)
|
||||
$query->whereIsExplicit(false);
|
||||
$recentQuery = Track::summary()
|
||||
->with(['genre', 'user', 'cover', 'user.avatar'])
|
||||
->userDetails()
|
||||
->explicitFilter()
|
||||
->published()
|
||||
->orderBy('published_at', 'desc')
|
||||
->take(30);
|
||||
|
||||
$tracks = [];
|
||||
$recentTracks = [];
|
||||
|
||||
foreach ($query->get() as $track) {
|
||||
$tracks[] = Track::mapPublicTrackSummary($track);
|
||||
foreach ($recentQuery->get() as $track) {
|
||||
$recentTracks[] = Track::mapPublicTrackSummary($track);
|
||||
}
|
||||
|
||||
return Response::json([
|
||||
'recent_tracks' => $tracks,
|
||||
'popular_tracks' => $tracks], 200);
|
||||
'recent_tracks' => $recentTracks,
|
||||
'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()
|
||||
->with('user', 'user.avatar', 'tracks', 'tracks.cover')
|
||||
->details()
|
||||
->userDetails()
|
||||
->orderBy('created_at', 'desc')
|
||||
->where('track_count', '>', 0)
|
||||
->whereIsPublic(true);
|
||||
|
||||
$count = $query->count();
|
||||
$perPage = 18;
|
||||
$perPage = 40;
|
||||
|
||||
$query->skip(($page - 1) * $perPage)->take($perPage);
|
||||
$playlists = [];
|
||||
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
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()))
|
||||
App::abort('404');
|
||||
|
||||
|
@ -73,7 +73,7 @@
|
|||
|
||||
public function getPinned() {
|
||||
$query = Playlist
|
||||
::details()
|
||||
::userDetails()
|
||||
->with('tracks', 'tracks.cover', 'tracks.user', 'user')
|
||||
->join('pinned_playlists', function($join) {
|
||||
$join->on('playlist_id', '=', 'playlists.id');
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
|
||||
public function getShow($id) {
|
||||
$track = Track::details()->withComments()->find($id);
|
||||
$track = Track::userDetails()->withComments()->find($id);
|
||||
if (!$track || !$track->canView(Auth::user()))
|
||||
return $this->notFound('Track not found!');
|
||||
|
||||
|
@ -43,20 +43,6 @@
|
|||
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() {
|
||||
$page = 1;
|
||||
$perPage = 45;
|
||||
|
@ -65,8 +51,9 @@
|
|||
$page = Input::get('page');
|
||||
|
||||
$query = Track::summary()
|
||||
->details()
|
||||
->whereNotNull('published_at')
|
||||
->userDetails()
|
||||
->explicitFilter()
|
||||
->published()
|
||||
->with('user', 'genre', 'cover', 'album', 'album.user');
|
||||
|
||||
$this->applyFilters($query);
|
||||
|
|
|
@ -11,6 +11,7 @@ class CreateUserTables extends Migration {
|
|||
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||
$table->integer('album_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_favourited');
|
||||
|
@ -20,12 +21,13 @@ class CreateUserTables extends Migration {
|
|||
$table->integer('play_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('track_id')->references('id')->on('tracks');
|
||||
$table->foreign('album_id')->references('id')->on('albums');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||
$table->foreign('track_id')->references('id')->on('tracks')->on_delete('cascade');;
|
||||
$table->foreign('album_id')->references('id')->on('albums')->on_delete('cascade');;
|
||||
$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){
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
public function scopeDetails($query) {
|
||||
public function scopeUserDetails($query) {
|
||||
if (Auth::check()) {
|
||||
$query->with(['users' => function($query) {
|
||||
$query->whereUserId(Auth::user()->id);
|
||||
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
|
||||
public function comments(){
|
||||
return $this->hasMany('Entities\Comment');
|
||||
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public static function mapPublicAlbumShow($album) {
|
||||
|
@ -81,6 +81,11 @@
|
|||
$data['comments'] = $comments;
|
||||
$data['formats'] = $formats;
|
||||
$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;
|
||||
}
|
||||
|
|
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');
|
||||
}
|
||||
|
||||
public function scopeDetails($query) {
|
||||
public function scopeUserDetails($query) {
|
||||
if (Auth::check()) {
|
||||
$query->with(['users' => function($query) {
|
||||
$query->whereUserId(Auth::user()->id);
|
||||
|
@ -53,6 +53,11 @@
|
|||
$data['tracks'] = $tracks;
|
||||
$data['comments'] = $comments;
|
||||
$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;
|
||||
}
|
||||
|
@ -117,7 +122,7 @@
|
|||
}
|
||||
|
||||
public function comments(){
|
||||
return $this->hasMany('Entities\Comment');
|
||||
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function pins() {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
use Helpers;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
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');
|
||||
}
|
||||
|
||||
public function scopeDetails($query) {
|
||||
public function scopeUserDetails($query) {
|
||||
if (Auth::check()) {
|
||||
$query->with(['users' => function($query) {
|
||||
$query->whereUserId(Auth::user()->id);
|
||||
|
@ -41,10 +42,52 @@
|
|||
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) {
|
||||
$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) {
|
||||
$returnValue = self::mapPublicTrackSummary($track);
|
||||
$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;
|
||||
|
||||
return $returnValue;
|
||||
|
@ -191,7 +243,7 @@
|
|||
}
|
||||
|
||||
public function comments(){
|
||||
return $this->hasMany('Entities\Comment');
|
||||
return $this->hasMany('Entities\Comment')->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function favourites() {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
use Gravatar;
|
||||
use Illuminate\Auth\UserInterface;
|
||||
use Illuminate\Auth\Reminders\RemindableInterface;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Str;
|
||||
use Ratchet\Wamp\Exception;
|
||||
|
@ -14,18 +15,36 @@
|
|||
protected $table = 'users';
|
||||
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() {
|
||||
return $this->belongsTo('Entities\Image');
|
||||
}
|
||||
|
||||
public function comments(){
|
||||
return $this->hasMany('Entities\Comment', 'profile_id');
|
||||
public function users() {
|
||||
return $this->hasMany('Entities\ResourceUser', 'artist_id');
|
||||
}
|
||||
|
||||
public function comments() {
|
||||
return $this->hasMany('Entities\Comment', 'profile_id')->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function getUrlAttribute() {
|
||||
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() {
|
||||
return $this->getKey();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
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/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+');
|
||||
|
||||
|
@ -90,6 +89,8 @@
|
|||
Route::post('/account/settings/save', 'Api\Web\AccountController@postSave');
|
||||
|
||||
Route::post('/favourites/toggle', 'Api\Web\FavouritesController@postToggle');
|
||||
|
||||
Route::post('/follow/toggle', 'Api\Web\FollowController@postToggle');
|
||||
});
|
||||
|
||||
Route::group(['before' => 'auth'], function() {
|
||||
|
|
|
@ -1,6 +1,28 @@
|
|||
@extends('shared._layout')
|
||||
|
||||
@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>
|
||||
<a href="/">Pony.fm</a>
|
||||
<div class="now-playing">
|
||||
|
@ -51,7 +73,7 @@
|
|||
</ui-view>
|
||||
</div>
|
||||
|
||||
<ng-include src="'templates/partials/upload-dialog.html'" />
|
||||
<ng-include src="'templates/partials/upload-dialog.html'"></ng-include>
|
||||
|
||||
@endsection
|
||||
|
||||
|
@ -76,4 +98,7 @@
|
|||
</script>
|
||||
|
||||
{{ Assets::scriptIncludes() }}
|
||||
|
||||
<script src="http://platform.tumblr.com/v1/share.js"></script>
|
||||
|
||||
@endsection
|
|
@ -10,4 +10,4 @@
|
|||
|
||||
<IfModule xsendfile_module>
|
||||
XSendFile On
|
||||
</IfModule>
|
||||
</IfModule>
|
|
@ -5,13 +5,22 @@ window.pfm.preloaders['album'] = [
|
|||
]
|
||||
|
||||
angular.module('ponyfm').controller "album", [
|
||||
'$scope', 'albums', '$state', 'playlists', 'auth'
|
||||
($scope, albums, $state, playlists, auth) ->
|
||||
'$scope', 'albums', '$state', 'playlists', 'auth', '$dialog'
|
||||
($scope, albums, $state, playlists, auth, $dialog) ->
|
||||
album = null
|
||||
|
||||
albums.fetch($state.params.id).done (albumResponse) ->
|
||||
$scope.album = albumResponse.album
|
||||
album = albumResponse.album
|
||||
|
||||
$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
|
||||
playlists.refreshOwned().done (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.gotoPage = (page) ->
|
||||
return if !page
|
||||
$state.transitionTo 'content.albums.list', {page: page}
|
||||
]
|
|
@ -9,5 +9,4 @@ angular.module('ponyfm').controller "artist-favourites", [
|
|||
($scope, artists, $state) ->
|
||||
artists.fetchFavourites($state.params.slug).done (artistResponse) ->
|
||||
$scope.favourites = artistResponse
|
||||
console.log artistResponse
|
||||
]
|
|
@ -5,8 +5,12 @@ window.pfm.preloaders['artist'] = [
|
|||
]
|
||||
|
||||
angular.module('ponyfm').controller "artist", [
|
||||
'$scope', 'artists', '$state'
|
||||
($scope, artists, $state) ->
|
||||
'$scope', 'artists', '$state', 'follow'
|
||||
($scope, artists, $state, follow) ->
|
||||
artists.fetch($state.params.slug).done (artistResponse) ->
|
||||
$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.gotoPage = (page) ->
|
||||
return if !page
|
||||
$state.transitionTo 'content.artists.list', {page: page}
|
||||
]
|
|
@ -5,8 +5,17 @@ window.pfm.preloaders['playlist'] = [
|
|||
]
|
||||
|
||||
angular.module('ponyfm').controller 'playlist', [
|
||||
'$scope', '$state', 'playlists'
|
||||
($scope, $state, playlists) ->
|
||||
playlists.fetch($state.params.id).done (playlist) ->
|
||||
$scope.playlist = playlist
|
||||
'$scope', '$state', 'playlists', '$dialog'
|
||||
($scope, $state, playlists, $dialog) ->
|
||||
playlist = null
|
||||
|
||||
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.gotoPage = (page) ->
|
||||
return if !page
|
||||
$state.transitionTo 'content.playlists.list', {page: page}
|
||||
]
|
|
@ -7,8 +7,11 @@ window.pfm.preloaders['track'] = [
|
|||
angular.module('ponyfm').controller "track", [
|
||||
'$scope', 'tracks', '$state', 'playlists', 'auth', 'favourites', '$dialog'
|
||||
($scope, tracks, $state, playlists, auth, favourites, $dialog) ->
|
||||
track = null
|
||||
|
||||
tracks.fetch($state.params.id).done (trackResponse) ->
|
||||
$scope.track = trackResponse.track
|
||||
track = trackResponse.track
|
||||
|
||||
$scope.playlists = []
|
||||
|
||||
|
@ -24,6 +27,12 @@ angular.module('ponyfm').controller "track", [
|
|||
track.is_favourited = res.is_favourited
|
||||
$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 = () ->
|
||||
dialog = $dialog.dialog
|
||||
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', () ->
|
||||
restrict: 'E'
|
||||
templateUrl: '/templates/directives/tracks-list.html'
|
||||
replace: true
|
||||
scope:
|
||||
tracks: '=tracks',
|
||||
class: '@class'
|
||||
|
|
|
@ -14,7 +14,7 @@ angular.module('ponyfm').filter('pfmdate', [
|
|||
if (!value)
|
||||
return false;
|
||||
|
||||
return value.toString() == '[object Date]';
|
||||
return Object.prototype.toString.apply(value) == '[object Date]';
|
||||
}
|
||||
|
||||
function padNumber(num, digits, trim) {
|
||||
|
@ -81,6 +81,8 @@ angular.module('ponyfm').filter('pfmdate', [
|
|||
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))(.*)/,
|
||||
NUMBER_STRING = /^\d+$/;
|
||||
|
||||
|
@ -190,8 +192,9 @@ angular.module('ponyfm').filter('pfmdate', [
|
|||
date = new Date(date);
|
||||
}
|
||||
|
||||
if (typeof(date) == 'object' && date.date)
|
||||
if (typeof(date) == 'object' && date.date) {
|
||||
date = new Date(date.date);
|
||||
}
|
||||
|
||||
if (!isDate(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 'body';
|
||||
@import 'player';
|
||||
@import 'content';
|
||||
@import 'content';
|
||||
@import 'dashboard';
|
|
@ -1,6 +1,14 @@
|
|||
@import-once 'variables';
|
||||
@import-once 'base/bootstrap/bootstrap';
|
||||
|
||||
a {
|
||||
color: #C2889C;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.site-content{
|
||||
.box-sizing(border-box);
|
||||
padding: 10px;
|
||||
|
|
|
@ -327,6 +327,17 @@ html {
|
|||
.border-radius(0px);
|
||||
|
||||
border: 2px solid @pfm-purple;
|
||||
|
||||
h2 {
|
||||
font-size: 12pt;
|
||||
color: #C2889C;
|
||||
line-height: normal;
|
||||
margin-bottom: 5px;
|
||||
|
||||
small {
|
||||
font-size: 10pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
|
|
|
@ -6,23 +6,41 @@
|
|||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
|
||||
&.two-columns {
|
||||
li {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
.box-sizing(border-box);
|
||||
float: left;
|
||||
width: 16.6666%;
|
||||
width: 25%;
|
||||
padding: 5px;
|
||||
line-height: normal;
|
||||
|
||||
a {
|
||||
background: #ddd;
|
||||
background: #eee;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 67px;
|
||||
height: 67px;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.title, .published {
|
||||
.info {
|
||||
margin-left: 72px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.title, .published, .stats {
|
||||
display: block;
|
||||
color: #444;
|
||||
padding: 5px;
|
||||
|
@ -32,17 +50,35 @@
|
|||
.ellipsis();
|
||||
|
||||
font-weight: bold;
|
||||
font-size: 12pt;
|
||||
font-size: 11pt;
|
||||
padding-left: 3px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.published {
|
||||
color: #777;
|
||||
font-size: 8pt;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.published, .stats {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
font-size: 10pt;
|
||||
color: #777;
|
||||
position: absolute;
|
||||
bottom: 3px;
|
||||
right: 3px;
|
||||
|
||||
strong {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
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 {
|
||||
padding: 5px;
|
||||
background: #eee;
|
||||
|
@ -174,15 +238,8 @@ html .single-player .play-button {
|
|||
}
|
||||
}
|
||||
|
||||
.tracks-listing {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
|
||||
html {
|
||||
li {
|
||||
.box-sizing(border-box);
|
||||
overflow: hidden;
|
||||
|
||||
&.empty {
|
||||
.border-radius(0px);
|
||||
background: lighten(@pfm-purple, 30%);
|
||||
|
@ -199,6 +256,18 @@ html .single-player .play-button {
|
|||
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;
|
||||
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>
|
||||
</ul>
|
||||
</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>
|
||||
</ul>
|
||||
|
||||
|
@ -23,8 +23,14 @@
|
|||
<div class="right">
|
||||
<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">
|
||||
<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>Downloads: <strong bo-text="album.stats.downloads"></strong></li>
|
||||
<li>Favourites: <strong bo-text="album.stats.favourites"></strong></li>
|
||||
|
|
|
@ -1,33 +1,25 @@
|
|||
<div class="user-details">
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/artists">Artist Directory</a> <span class="divider">/</span></li>
|
||||
<li class="active">{{artist.name}}</li>
|
||||
<div class="resource-details artist-details" bindonce="artist">
|
||||
<ul class="dropdowns">
|
||||
<li class="dropdown">
|
||||
<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>
|
||||
|
||||
<div class="track-toolbar btn-group pull-right">
|
||||
<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>
|
||||
|
||||
<header>
|
||||
<h1 bo-text="artist.name"></h1>
|
||||
<ul class="tabs">
|
||||
<li ng-class="{active: stateIncludes('artist.profile')}"><a href="{{artist.slug}}">Profile</a></li>
|
||||
<li ng-class="{active: stateIncludes('artist.content')}"><a href="{{artist.slug}}/content">Content</a></li>
|
||||
<li ng-class="{active: stateIncludes('artist.favourites')}"><a href="{{artist.slug}}/favourites">Favourites</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.artist.profile')}"><a href="{{artist.slug}}">Profile</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.artist.content')}"><a href="{{artist.slug}}/content">Content</a></li>
|
||||
<li ng-class="{active: stateIncludes('content.artist.favourites')}"><a href="{{artist.slug}}/favourites">Favourites</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<div class="stretch-to-bottom">
|
||||
<ui-view></ui-view>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<div ng-show="content.albums.length">
|
||||
<h2>Albums</h2>
|
||||
<pfm-albums-list albums="content.albums" />
|
||||
<pfm-albums-list albums="content.albums"></pfm-albums-list>
|
||||
</div>
|
||||
|
||||
<div ng-show="content.singles.length">
|
||||
<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 ng-show="content.albumTracks.length">
|
||||
<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>
|
|
@ -5,6 +5,6 @@
|
|||
</div>
|
||||
<div class="span6">
|
||||
<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>
|
|
@ -1,10 +1,12 @@
|
|||
<ul class="artist-listing stretch-to-bottom">
|
||||
<li ng-repeat="artist in artists">
|
||||
<li ng-repeat="artist in artists" bindonce>
|
||||
<a href="{{artist.url}}">
|
||||
<img class="image" ng-src="{{artist.avatars.normal}}" />
|
||||
<span class="title">{{artist.name}}</span>
|
||||
<span class="published">
|
||||
joined {{artist.created_at.date | momentFromNow}}
|
||||
<img class="image" bo-src="artist.avatars.small" />
|
||||
<span class="info">
|
||||
<span class="title" bo-text="artist.name"></span>
|
||||
<span class="published">
|
||||
joined <span bo-text="artist.created_at.date | momentFromNow"></span>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
<div class="row-fluid">
|
||||
<div class="span6">
|
||||
<div ng-show="artist.bio.trim().length">
|
||||
<div bo-show="artist.bio.trim().length">
|
||||
<h2>Bio</h2>
|
||||
<div class="description">
|
||||
<p ng-bind-html-unsafe="artist.bio | noHTML | newlines"></p>
|
||||
<p bo-html="artist.bio | noHTML | newlines"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Comments</h2>
|
||||
<pfm-comments type="user" resource="artist"></pfm-comments>
|
||||
</div>
|
||||
<div class="span6 cover-image">
|
||||
<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>
|
|
@ -1,9 +1,20 @@
|
|||
<section class="recent-tracks stretch-to-bottom">
|
||||
<div>
|
||||
<h1>
|
||||
<a href="/tracks"><i class="icon-music"></i> see more</a>
|
||||
The Newest Tunes
|
||||
</h1>
|
||||
<pfm-tracks-list tracks="recentTracks" class="two-columns"></pfm-tracks-list>
|
||||
</div>
|
||||
</section>
|
||||
<div class="dashboard">
|
||||
<section class="recent-tracks stretch-to-bottom">
|
||||
<div>
|
||||
<h1>
|
||||
<a href="/tracks"><i class="icon-music"></i> see more</a>
|
||||
The Newest Tunes
|
||||
</h1>
|
||||
<pfm-tracks-list tracks="recentTracks" class="two-columns"></pfm-tracks-list>
|
||||
</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}}">
|
||||
<li ng-repeat="album in albums">
|
||||
<a href="{{album.url}}">
|
||||
<img class="image" ng-src="{{album.covers.normal}}" />
|
||||
<span class="title">{{album.title}}</span>
|
||||
<li ng-repeat="album in albums" bindonce>
|
||||
<a bo-href="album.url">
|
||||
<img class="image" bo-src="album.covers.small" />
|
||||
<span class="info">
|
||||
<span class="title" bo-text="album.title"></span>
|
||||
<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>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<div class="comments" bindonce>
|
||||
<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">
|
||||
<div class="form-row">
|
||||
<input type="text" ng-model="content" placeholder="Write a comment..." />
|
||||
</div>
|
||||
</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">
|
||||
<img bo-src="comment.user.avatars.thumbnail" />
|
||||
<div class="content">
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
<ul class="playlists-listing {{class}}">
|
||||
<li ng-repeat="playlist in playlists">
|
||||
<li ng-repeat="playlist in playlists" bindonce>
|
||||
<a href="{{playlist.url}}">
|
||||
<img class="image" ng-src="{{playlist.covers.normal}}" height="350" width="350" />
|
||||
<span class="title">{{playlist.title}}</span>
|
||||
<span class="published">
|
||||
by {{playlist.user.name}}
|
||||
<img class="image" ng-src="{{playlist.covers.small}}"/>
|
||||
<span class="info">
|
||||
<span class="title">{{playlist.title}}</span>
|
||||
<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>
|
||||
</a>
|
||||
</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>
|
||||
</ul>
|
||||
</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>
|
||||
</ul>
|
||||
|
||||
|
@ -19,13 +19,18 @@
|
|||
</h2>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="stretch-to-bottom details-columns">
|
||||
<div class="right">
|
||||
<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">
|
||||
<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>Downloads: <strong bo-text="playlist.stats.downloads"></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>
|
||||
</ul>
|
||||
</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>
|
||||
</ul>
|
||||
|
||||
|
@ -42,8 +42,14 @@
|
|||
<div class="right">
|
||||
<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">
|
||||
<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>Plays: <strong bo-text="track.stats.plays"></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';
|
||||
|
||||
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(
|
||||
'AbstractOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/AbstractOutputProvider.php',
|
||||
'AccountController' => $baseDir . '/app/controllers/AccountController.php',
|
||||
'AlbumDownloader' => $baseDir . '/app/models/AlbumDownloader.php',
|
||||
'AlbumsController' => $baseDir . '/app/controllers/AlbumsController.php',
|
||||
'ApiControllerBase' => $baseDir . '/app/controllers/ApiControllerBase.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\\ImagesController' => $baseDir . '/app/controllers/Api/Web/ImagesController.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\\TracksController' => $baseDir . '/app/controllers/Api/Web/TracksController.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',
|
||||
'CreateComments' => $baseDir . '/app/database/migrations/2013_08_01_051337_create_comments.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',
|
||||
'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',
|
||||
|
@ -430,7 +433,9 @@ return array(
|
|||
'Entities\\License' => $baseDir . '/app/models/Entities/License.php',
|
||||
'Entities\\PinnedPlaylist' => $baseDir . '/app/models/Entities/PinnedPlaylist.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\\ResourceUser' => $baseDir . '/app/models/Entities/ResourceUser.php',
|
||||
'Entities\\ShowSong' => $baseDir . '/app/models/Entities/ShowSong.php',
|
||||
'Entities\\Track' => $baseDir . '/app/models/Entities/Track.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\\Utf8' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8.php',
|
||||
'Patchwork\\Utf8\\Bootup' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8/Bootup.php',
|
||||
'PlaylistDownloader' => $baseDir . '/app/models/PlaylistDownloader.php',
|
||||
'PlaylistsController' => $baseDir . '/app/controllers/PlaylistsController.php',
|
||||
'Predis\\Autoloader' => $vendorDir . '/predis/predis/lib/Predis/Autoloader.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\\WritableStream' => $vendorDir . '/react/stream/React/Stream/WritableStream.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',
|
||||
'StringOutputProvider' => $vendorDir . '/codescale/ffmpeg-php/provider/StringOutputProvider.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
|
||||
|
||||
class ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223
|
||||
class ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -19,9 +19,9 @@ class ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223
|
|||
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();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitf5e8b08f8d3ef98cfbf31c8bbf4b6225', 'loadClassLoader'));
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
|
Loading…
Reference in a new issue