mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-25 06:27:59 +01:00
Finished show songs
This commit is contained in:
parent
c3744e2931
commit
f2b1bc82cf
10 changed files with 186 additions and 41 deletions
|
@ -20,6 +20,7 @@
|
|||
$images[] = [
|
||||
'id' => $image->id,
|
||||
'url' => $image->getUrl(Image::SMALL),
|
||||
'url_normal' => $image->getUrl(Image::NORMAL),
|
||||
'filename' => $image->filename
|
||||
];
|
||||
}
|
||||
|
|
|
@ -67,13 +67,18 @@
|
|||
}
|
||||
|
||||
public function getEdit($id) {
|
||||
$track = Track::find($id);
|
||||
$track = Track::with('showSongs')->find($id);
|
||||
if (!$track)
|
||||
return $this->notFound('Track ' . $id . ' not found!');
|
||||
|
||||
if ($track->user_id != Auth::user()->id)
|
||||
return $this->notAuthorized();
|
||||
|
||||
$showSongs = [];
|
||||
foreach ($track->showSongs as $showSong) {
|
||||
$showSongs[] = ['id' => $showSong->id, 'title' => $showSong->title];
|
||||
}
|
||||
|
||||
return Response::json([
|
||||
'id' => $track->id,
|
||||
'title' => $track->title,
|
||||
|
@ -93,7 +98,8 @@
|
|||
'lyrics' => $track->lyrics,
|
||||
'released_at' => $track->released_at,
|
||||
'cover_url' => $track->hasCover() ? $track->getCoverUrl(Image::NORMAL) : null,
|
||||
'real_cover_url' => $track->getCoverUrl(Image::NORMAL)
|
||||
'real_cover_url' => $track->getCoverUrl(Image::NORMAL),
|
||||
'show_songs' => $showSongs
|
||||
], 200);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ class CreateSongsTable extends Migration {
|
|||
$table->string('slug', 200)->indexed();
|
||||
});
|
||||
|
||||
Schema::create('track_show_songs', function($table) {
|
||||
Schema::create('show_song_track', function($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('track_id')->unsigned();
|
||||
$table->integer('show_song_id')->unsigned();
|
||||
|
@ -2039,12 +2039,12 @@ Twilight Sparkle: Yes! Everything’s going to be just fine!",
|
|||
}
|
||||
|
||||
public function down() {
|
||||
Schema::table('track_show_songs', function($table){
|
||||
$table->drop_foreign('track_show_songs_track_id_foreign');
|
||||
$table->drop_foreign('track_show_songs_show_song_id_foreign');
|
||||
Schema::table('show_song_track', function($table){
|
||||
$table->drop_foreign('show_song_track_track_id_foreign');
|
||||
$table->drop_foreign('show_song_track_show_song_id_foreign');
|
||||
});
|
||||
|
||||
Schema::drop('track_show_songs');
|
||||
Schema::drop('show_song_track');
|
||||
Schema::drop('show_songs');
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@
|
|||
public function execute() {
|
||||
$isVocal = isset($this->_input['is_vocal']) && $this->_input['is_vocal'] == 'true' ? true : false;
|
||||
|
||||
$validator = \Validator::make($this->_input, [
|
||||
$rules = [
|
||||
'title' => 'required|min:3|max:80',
|
||||
'released_at' => 'before:today' . ($this->_input['released_at'] != "" ? '|date' : ''),
|
||||
'lyrics' => $isVocal ? 'required' : '',
|
||||
|
@ -43,8 +43,13 @@
|
|||
'cover' => 'image|mimes:png|min_width:350|min_height:350',
|
||||
'track_type_id' => 'required|exists:track_types,id',
|
||||
'songs' => 'required_when:track_type,2|exists:songs,id',
|
||||
'cover_id' => 'exists:images,id'
|
||||
]);
|
||||
'cover_id' => 'exists:images,id',
|
||||
];
|
||||
|
||||
if ($this->_input['track_type_id'] == 2)
|
||||
$rules['show_song_ids'] = 'required|exists:show_songs,id';
|
||||
|
||||
$validator = \Validator::make($this->_input, $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
return CommandResponse::fail($validator);
|
||||
|
@ -61,6 +66,11 @@
|
|||
$track->is_downloadable = $this->_input['is_downloadable'] == 'true';
|
||||
$track->is_vocal = $isVocal;
|
||||
|
||||
if ($track->track_type_id == 2) {
|
||||
$track->showSongs()->sync(explode(',', $this->_input['show_song_ids']));
|
||||
} else
|
||||
$track->showSongs()->sync([]);
|
||||
|
||||
if ($track->published_at == null) {
|
||||
$track->published_at = new \DateTime();
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
return $this->belongsTo('Entities\Image');
|
||||
}
|
||||
|
||||
public function showSongs() {
|
||||
return $this->belongsToMany('Entities\ShowSong');
|
||||
}
|
||||
|
||||
public function isPublished() {
|
||||
return $this->published_at != null && $this->deleted_at == null;
|
||||
}
|
||||
|
|
|
@ -9,16 +9,34 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
|||
$scope.selectedTrack = null
|
||||
$scope.isDirty = false
|
||||
$scope.isSaving = false
|
||||
$scope.taxonomies =
|
||||
trackTypes: taxonomies.trackTypes
|
||||
licenses: taxonomies.licenses
|
||||
genres: taxonomies.genres
|
||||
$scope.taxonomies = taxonomies
|
||||
$scope.selectedSongsTitle = 'None'
|
||||
$scope.selectedSongs = {}
|
||||
|
||||
updateSongDisplay = () ->
|
||||
if _.size $scope.selectedSongs
|
||||
$scope.selectedSongsTitle = (_.map _.values($scope.selectedSongs), (s) -> s.title).join(', ')
|
||||
else
|
||||
$scope.selectedSongsTitle = 'None'
|
||||
|
||||
$scope.toggleSong = (song) ->
|
||||
$scope.isDirty = true
|
||||
if $scope.selectedSongs[song.id]
|
||||
delete $scope.selectedSongs[song.id]
|
||||
else
|
||||
$scope.selectedSongs[song.id] = song
|
||||
|
||||
updateSongDisplay()
|
||||
|
||||
$scope.updateIsVocal = () ->
|
||||
delete $scope.errors.lyrics if !$scope.edit.is_vocal
|
||||
|
||||
$scope.previewCover = () ->
|
||||
return if !$scope.edit.cover
|
||||
return if !$scope.edit.cover && !$scope.edit.cover_id
|
||||
|
||||
if $scope.edit.cover_id
|
||||
lightbox.openImageUrl $scope.cover_url
|
||||
else
|
||||
if typeof($scope.edit.cover) == 'object'
|
||||
lightbox.openDataUrl $('#coverPreview').attr 'src'
|
||||
else
|
||||
|
@ -27,6 +45,7 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
|||
$scope.selectGalleryImage = (image) ->
|
||||
$('#coverPreview').attr 'src', image.url
|
||||
$scope.edit.cover_id = image.id
|
||||
$scope.cover_url = image.url_normal
|
||||
$scope.edit.remove_cover = false
|
||||
$scope.edit.cover = null
|
||||
$scope.isDirty = true
|
||||
|
@ -58,6 +77,9 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
|||
else
|
||||
formData.append name, value
|
||||
|
||||
if $scope.edit.track_type_id == 2
|
||||
formData.append 'show_song_ids', _.map(_.values($scope.selectedSongs), (s) -> s.id).join()
|
||||
|
||||
xhr.open 'POST', '/api/web/tracks/edit/' + $scope.edit.id, true
|
||||
xhr.setRequestHeader 'X-Token', pfm.token
|
||||
$scope.isSaving = true
|
||||
|
@ -196,6 +218,10 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
|||
$('#coverPreview').attr 'src', track.cover_url
|
||||
$scope.isCoverLoaded = true
|
||||
|
||||
$scope.selectedSongs = {}
|
||||
$scope.selectedSongs[song.id] = song for song in track.show_songs
|
||||
updateSongDisplay()
|
||||
|
||||
$scope.touchModel = -> $scope.isDirty = true
|
||||
|
||||
$.getJSON('/api/web/tracks/owned?order=created_at,desc').done (tracks) -> $scope.$apply ->
|
||||
|
|
|
@ -2,17 +2,51 @@ angular.module('ponyfm').directive 'pfmPopup', () ->
|
|||
(scope, element, attrs) ->
|
||||
$popup = $ '#' + attrs.pfmPopup
|
||||
$element = $ element
|
||||
$popup.remove()
|
||||
$positionParent = null
|
||||
open = false
|
||||
|
||||
$popup.parents().each () ->
|
||||
$this = $ this
|
||||
$positionParent = $this if $positionParent == null && ($this.css('position') == 'relative' || $this.is 'body')
|
||||
|
||||
documentClickHandler = () ->
|
||||
return if !open
|
||||
$popup.removeClass 'open'
|
||||
open = false
|
||||
|
||||
$(document.body).bind 'click', documentClickHandler
|
||||
calculatePosition = ->
|
||||
position = $element.offset()
|
||||
parentPosition = $positionParent.offset()
|
||||
|
||||
$(document.body).append $popup
|
||||
left = position.left
|
||||
right = left + $popup.width()
|
||||
windowWidth = $(window).width() - 15
|
||||
if right > windowWidth
|
||||
left -= right - windowWidth
|
||||
|
||||
height = 'auto'
|
||||
top = position.top + $element.height() + 10
|
||||
bottom = top + $popup.height()
|
||||
windowHeight = $(window).height()
|
||||
if bottom > windowHeight
|
||||
height = windowHeight - top;
|
||||
|
||||
return {
|
||||
left: left - parentPosition.left - 2
|
||||
top: top - parentPosition.top,
|
||||
height: height}
|
||||
|
||||
windowResizeHandler = () ->
|
||||
return if !open
|
||||
$popup.css 'height', 'auto'
|
||||
position = calculatePosition()
|
||||
$popup.css
|
||||
left: position.left
|
||||
top: position.top
|
||||
height: position.height
|
||||
|
||||
$(document.body).bind 'click', documentClickHandler
|
||||
$(window).bind 'resize', windowResizeHandler
|
||||
|
||||
$(element).click (e) ->
|
||||
e.preventDefault()
|
||||
|
@ -25,19 +59,15 @@ angular.module('ponyfm').directive 'pfmPopup', () ->
|
|||
|
||||
$popup.addClass 'open'
|
||||
|
||||
position = $element.offset()
|
||||
left = position.left
|
||||
right = left + $popup.width()
|
||||
windowWidth = $(window).width() - 15
|
||||
if right > windowWidth
|
||||
left -= right - windowWidth
|
||||
|
||||
$popup.css 'height', 'auto'
|
||||
position = calculatePosition()
|
||||
$popup.css
|
||||
top: position.top + $element.height() + 10
|
||||
left: left
|
||||
left: position.left
|
||||
top: position.top
|
||||
height: position.height
|
||||
|
||||
open = true
|
||||
|
||||
scope.$on '$destroy', () ->
|
||||
$(document.body).unbind 'click', documentClickHandler
|
||||
$popup.remove()
|
||||
$(window).unbind 'click', windowResizeHandler
|
||||
|
|
|
@ -125,6 +125,62 @@
|
|||
.editor {
|
||||
display: none;
|
||||
|
||||
.show-songs {
|
||||
.btn {
|
||||
.border-radius(0px);
|
||||
display: block;
|
||||
float: none;
|
||||
padding: 3px 10px;
|
||||
font-size: 8pt;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.error {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.pfm-popup {
|
||||
width: 300px;
|
||||
|
||||
ul {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
a {
|
||||
.ellipsis();
|
||||
display: block;
|
||||
padding: 3px 10px;
|
||||
font-size: 8pt;
|
||||
color: #333333;
|
||||
|
||||
&:hover {
|
||||
#gradient>.vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%));
|
||||
text-decoration: none;
|
||||
color: @dropdownLinkColorHover;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
a {
|
||||
#gradient>.vertical(@green, darken(@green, 5%));
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
#gradient>.vertical(fadeout(@green, 20%), fadeout(darken(@green, 5%), 20%));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 10px;
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ html body {
|
|||
|
||||
.pfm-popup {
|
||||
.box-shadow(0 5px 10px rgba(0, 0, 0, 0.2));
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
display: none;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
background: #fff;
|
||||
overflow-y: auto;
|
||||
|
||||
&.open {
|
||||
display: block;
|
||||
|
|
|
@ -105,8 +105,18 @@
|
|||
<div class="error">{{errors.genre_id}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row" ng-show="edit.track_type_id == 2">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="form-row show-songs span6" ng-show="edit.track_type_id == 2" ng-class="{'has-error': errors.show_song_ids != null}">
|
||||
<a pfm-popup="song-selector" href="#" class="btn btn-small">Show Songs: <strong>{{selectedSongsTitle}}</strong></a>
|
||||
<div id="song-selector" class="pfm-popup">
|
||||
<ul>
|
||||
<li ng-repeat="song in taxonomies.showSongs" ng-class="{selected: selectedSongs[song.id]}">
|
||||
<a pfm-eat-click href="#" ng-click="toggleSong(song); $event.stopPropagation();">{{song.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="error">{{errors.show_song_ids}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="form-row span6" ng-class="{'has-error': errors.cover != null}">
|
||||
|
|
Loading…
Reference in a new issue