diff --git a/app/controllers/Api/Web/AlbumsController.php b/app/controllers/Api/Web/AlbumsController.php index 1ec18c06..5f11f995 100644 --- a/app/controllers/Api/Web/AlbumsController.php +++ b/app/controllers/Api/Web/AlbumsController.php @@ -93,23 +93,7 @@ $albums = []; foreach ($query->get() as $album) { - $albums[] = [ - 'id' => $album->id, - 'track_count' => $album->tracks->count(), - 'title' => $album->title, - 'slug' => $album->slug, - 'created_at' => $album->created_at, - 'covers' => [ - 'small' => $album->getCoverUrl(Image::SMALL), - 'normal' => $album->getCoverUrl(Image::NORMAL) - ], - 'url' => $album->url, - 'user' => [ - 'id' => $album->user->id, - 'name' => $album->user->display_name, - 'url' => $album->user->url, - ] - ]; + $albums[] = Album::mapPublicAlbumSummary($album); } return Response::json(["albums" => $albums, "current_page" => $page, "total_pages" => ceil($count / $perPage)], 200); diff --git a/app/controllers/Api/Web/ArtistsController.php b/app/controllers/Api/Web/ArtistsController.php index a71def8a..cae659ad 100644 --- a/app/controllers/Api/Web/ArtistsController.php +++ b/app/controllers/Api/Web/ArtistsController.php @@ -17,11 +17,49 @@ use Illuminate\Support\Facades\Response; class ArtistsController extends \ApiControllerBase { + public function getContent($slug) { + $user = User::whereSlug($slug)->first(); + if (!$user) + App::abort(404); + + $query = Track::summary()->whereUserId($user->id)->whereNotNull('published_at'); + $tracks = []; + $singles = []; + + foreach ($query->get() as $track) { + if ($track->album_id != null) + $tracks[] = Track::mapPublicTrackSummary($track); + else + $singles[] = Track::mapPublicTrackSummary($track); + } + + $query = Album::summary() + ->with('tracks', 'user') + ->orderBy('created_at', 'desc') + ->whereRaw('(SELECT COUNT(id) FROM tracks WHERE tracks.album_id = albums.id) > 0') + ->whereUserId($user->id); + + $albums = []; + + foreach ($query->get() as $album) { + $albums[] = Album::mapPublicAlbumSummary($album); + } + + return Response::json(['singles' => $singles, 'albumTracks' => $tracks, 'albums' => $albums], 200); + } + public function getShow($slug) { $user = User::whereSlug($slug)->first(); if (!$user) App::abort(404); + $trackQuery = Track::summary()->whereUserId($user->id)->whereNotNull('published_at')->orderBy('created_at', 'desc')->take(10); + $latestTracks = []; + + foreach ($trackQuery->get() as $track) { + $latestTracks[] = Track::mapPublicTrackSummary($track); + } + return Response::json([ 'artist' => [ 'id' => $user->id, @@ -31,7 +69,13 @@ 'small' => $user->getAvatarUrl(Image::SMALL), 'normal' => $user->getAvatarUrl(Image::NORMAL) ], - 'created_at' => $user->created_at + 'created_at' => $user->created_at, + 'followers' => [], + 'following' => [], + 'latest_tracks' => $latestTracks, + 'comments' => ['count' => 0, 'list' => []], + 'bio' => $user->bio, + 'mlpforums_username' => $user->mlpforums_name ] ], 200); } diff --git a/app/models/Entities/Album.php b/app/models/Entities/Album.php index a43801a9..b62c8b7b 100644 --- a/app/models/Entities/Album.php +++ b/app/models/Entities/Album.php @@ -30,6 +30,26 @@ return $this->hasMany('Entities\Track')->orderBy('track_number', 'asc'); } + public static function mapPublicAlbumSummary($album) { + return [ + 'id' => $album->id, + 'track_count' => $album->tracks->count(), + 'title' => $album->title, + 'slug' => $album->slug, + 'created_at' => $album->created_at, + 'covers' => [ + 'small' => $album->getCoverUrl(Image::SMALL), + 'normal' => $album->getCoverUrl(Image::NORMAL) + ], + 'url' => $album->url, + 'user' => [ + 'id' => $album->user->id, + 'name' => $album->user->display_name, + 'url' => $album->user->url, + ] + ]; + } + public function hasCover() { return $this->cover_id != null; } diff --git a/app/routes.php b/app/routes.php index ab32f4f6..1c812470 100644 --- a/app/routes.php +++ b/app/routes.php @@ -53,7 +53,9 @@ Route::get('/albums/{id}', 'Api\Web\AlbumsController@getShow')->where('id', '\d+'); Route::get('/artists', 'Api\Web\ArtistsController@getIndex'); - Route::get('/artists/{slug}', 'Api\Web\ArtistsController@getShow')->where('id', '[-\w]'); + Route::get('/artists/{slug}', 'Api\Web\ArtistsController@getShow'); + Route::get('/artists/{slug}/content', 'Api\Web\ArtistsController@getContent'); + Route::get('/artists/{slug}/favourites', 'Api\Web\ArtistsController@getFavourites'); Route::get('/dashboard', 'Api\Web\DashboardController@getIndex'); @@ -113,6 +115,8 @@ Route::get('u{id}', 'ArtistsController@getShortlink')->where('id', '\d+'); Route::get('users/{id}-{slug}', 'ArtistsController@getShortlink')->where('id', '\d+'); - Route::get('{slug}', 'ArtistsController@getProfile')->where('id', '[-\w]'); + Route::get('{slug}', 'ArtistsController@getProfile'); + Route::get('{slug}/content', 'ArtistsController@getProfile'); + Route::get('{slug}/favourites', 'ArtistsController@getProfile'); Route::get('/', 'HomeController@getIndex'); \ No newline at end of file diff --git a/public/scripts/app/app.coffee b/public/scripts/app/app.coffee index d749faa6..f74b9d93 100644 --- a/public/scripts/app/app.coffee +++ b/public/scripts/app/app.coffee @@ -174,9 +174,25 @@ angular.module 'ponyfm', ['ui.bootstrap', 'ui.state', 'ui.date', 'ui.sortable'], # Final catch-all for aritsts state.state 'artist', url: '^/:slug' - templateUrl: '/templates/artists/show.html' + templateUrl: '/templates/artists/_show_layout.html' + abstract: true controller: 'artist' + state.state 'artist.profile', + url: '' + templateUrl: '/templates/artists/profile.html' + controller: 'artist-profile' + + state.state 'artist.content', + url: '/content' + templateUrl: '/templates/artists/content.html' + controller: 'artist-content' + + state.state 'artist.favourites', + url: '/favourites' + templateUrl: '/templates/artists/favourites.html' + controller: 'artist-favourites' + route.otherwise '/' location.html5Mode(true); diff --git a/public/scripts/app/controllers/artist-content.coffee b/public/scripts/app/controllers/artist-content.coffee new file mode 100644 index 00000000..4583ec3f --- /dev/null +++ b/public/scripts/app/controllers/artist-content.coffee @@ -0,0 +1,12 @@ +window.pfm.preloaders['artist-content'] = [ + 'artists', '$state' + (artists, $state) -> + $.when.all [artists.fetch($state.params.slug, true), artists.fetchContent($state.params.slug, true)] +] + +angular.module('ponyfm').controller "artist-content", [ + '$scope', 'artists', '$state' + ($scope, artists, $state) -> + artists.fetchContent($state.params.slug).done (artistResponse) -> + $scope.content = artistResponse +] \ No newline at end of file diff --git a/public/scripts/app/controllers/artist-favourites.coffee b/public/scripts/app/controllers/artist-favourites.coffee new file mode 100644 index 00000000..f2b1792a --- /dev/null +++ b/public/scripts/app/controllers/artist-favourites.coffee @@ -0,0 +1,12 @@ +window.pfm.preloaders['artist-favourites'] = [ + 'artists', '$state' + (artists, $state) -> + artists.fetch $state.params.slug, true +] + +angular.module('ponyfm').controller "artist-favourites", [ + '$scope', 'artists', '$state' + ($scope, artists, $state) -> + artists.fetch($state.params.slug).done (artistResponse) -> + $scope.artist = artistResponse.artist +] \ No newline at end of file diff --git a/public/scripts/app/controllers/artist-profile.coffee b/public/scripts/app/controllers/artist-profile.coffee new file mode 100644 index 00000000..1b72a20a --- /dev/null +++ b/public/scripts/app/controllers/artist-profile.coffee @@ -0,0 +1,10 @@ +window.pfm.preloaders['artist-profile'] = [ + 'artists', '$state' + (artists, $state) -> + artists.fetch $state.params.slug, true +] + +angular.module('ponyfm').controller "artist-profile", [ + '$scope', 'artists', '$state' + ($scope, artists, $state) -> +] \ No newline at end of file diff --git a/public/scripts/app/controllers/artist.coffee b/public/scripts/app/controllers/artist.coffee index a6261f95..08f84b4f 100644 --- a/public/scripts/app/controllers/artist.coffee +++ b/public/scripts/app/controllers/artist.coffee @@ -1,7 +1,7 @@ window.pfm.preloaders['artist'] = [ 'artists', '$state' (artists, $state) -> - artists.fetch $state.params.slug + artists.fetch $state.params.slug, true ] angular.module('ponyfm').controller "artist", [ diff --git a/public/scripts/app/directives/albums-list.coffee b/public/scripts/app/directives/albums-list.coffee new file mode 100644 index 00000000..360b06f4 --- /dev/null +++ b/public/scripts/app/directives/albums-list.coffee @@ -0,0 +1,11 @@ +angular.module('ponyfm').directive 'pfmAlbumsList', () -> + restrict: 'E' + templateUrl: '/templates/directives/albums-list.html' + scope: + albums: '=albums', + class: '@class' + + controller: [ + '$scope' + ($scope) -> + ] \ No newline at end of file diff --git a/public/scripts/app/directives/tracks-list.coffee b/public/scripts/app/directives/tracks-list.coffee new file mode 100644 index 00000000..4a43a57d --- /dev/null +++ b/public/scripts/app/directives/tracks-list.coffee @@ -0,0 +1,11 @@ +angular.module('ponyfm').directive 'pfmTracksList', () -> + restrict: 'E' + templateUrl: '/templates/directives/tracks-list.html' + scope: + tracks: '=tracks', + class: '@class' + + controller: [ + '$scope' + ($scope) -> + ] \ No newline at end of file diff --git a/public/scripts/app/services/artists.coffee b/public/scripts/app/services/artists.coffee index a080cb5e..fc80e7c8 100644 --- a/public/scripts/app/services/artists.coffee +++ b/public/scripts/app/services/artists.coffee @@ -3,6 +3,7 @@ angular.module('ponyfm').factory('artists', [ ($rootScope, $http) -> artistPage = [] artists = {} + artistContent = {} self = filters: {} @@ -28,5 +29,15 @@ angular.module('ponyfm').factory('artists', [ artists[slug] = artistsDef.promise() + fetchContent: (slug, force) -> + force = force || false + slug = 1 if !slug + return artistContent[slug] if !force && artistContent[slug] + artistsDef = new $.Deferred() + $http.get('/api/web/artists/' + slug + '/content').success (albums) -> + artistsDef.resolve albums + + artistContent[slug] = artistsDef.promise() + self ]) \ No newline at end of file diff --git a/public/styles/layout.less b/public/styles/layout.less index 36b734d4..63a91593 100644 --- a/public/styles/layout.less +++ b/public/styles/layout.less @@ -442,8 +442,10 @@ header { border-bottom: 2px solid #ddd; margin-bottom: 2px; } +} - > div > .tabs { +html { + .tabs { .clearfix(); list-style: none; border-bottom: 4px solid #ddd; diff --git a/public/styles/tracks.less b/public/styles/tracks.less index 5380e4bc..f8adfe64 100644 --- a/public/styles/tracks.less +++ b/public/styles/tracks.less @@ -24,6 +24,16 @@ padding: 0px; list-style: none; + &.no-artist { + li { + .info { + .artist { + display: none; + } + } + } + } + &.two-column { li { .box-sizing(border-box); @@ -35,6 +45,17 @@ } } + &.four-column { + li { + .box-sizing(border-box); + + width: 25%; + float: left; + margin: 0px; + padding: 5px; + } + } + li { overflow: hidden; margin: 10px 0px; @@ -127,13 +148,25 @@ } } -.track-details, .album-details { - h1 { +.user-details { + .header { .box-shadow(0px 2px 3px rgba(0, 0, 0, .3)); background: #eee; - padding: 5px; - } + h1 { + padding: 5px; + } + + .tabs { + background: #f0f0f0; + margin: 0px; + border: none; + border-top: 1px solid #ddd; + } + } +} + +.user-details, .track-details, .album-details { .comments { .alert { .border-radius(0px); @@ -177,6 +210,14 @@ } } } +} + +.track-details, .album-details { + h1 { + .box-shadow(0px 2px 3px rgba(0, 0, 0, .3)); + background: #eee; + padding: 5px; + } .lyrics { font-size: 10pt; diff --git a/public/templates/albums/list.html b/public/templates/albums/list.html index f9c93056..76f13c39 100644 --- a/public/templates/albums/list.html +++ b/public/templates/albums/list.html @@ -1,14 +1,3 @@ -
+- Artist Directory /
+ - {{artist.name}}
+
+ ++ {{artist.name}} +
+ ++- Profile
+ - Content
+ - Favourites
+
+Albums
+Singles
+Part of an Album
+Bio
+Comments
+Recent Tracks
+-- Artist Directory /
- - {{artist.name}}
-
- -{{artist.name}}
---
-
-
-
-
-
-
-
-
-
- {{track.title}}
-
- by: {{track.user.name}} /
- {{track.genre.name}} /
- {{track.published_at.date | momentFromNow}}
-
-
-
-
+