mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-25 14:37:59 +01:00
Image things
This commit is contained in:
parent
c56568b6f5
commit
3b291f3b8f
12 changed files with 210 additions and 22 deletions
29
app/controllers/Api/Web/ImagesController.php
Normal file
29
app/controllers/Api/Web/ImagesController.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Api\Web;
|
||||||
|
|
||||||
|
use Commands\DeleteTrackCommand;
|
||||||
|
use Commands\EditTrackCommand;
|
||||||
|
use Commands\UploadTrackCommand;
|
||||||
|
use Cover;
|
||||||
|
use Entities\Image;
|
||||||
|
use Entities\Track;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Input;
|
||||||
|
use Illuminate\Support\Facades\Response;
|
||||||
|
|
||||||
|
class ImagesController extends \ApiControllerBase {
|
||||||
|
public function getOwned() {
|
||||||
|
$query = Image::where('uploaded_by', \Auth::user()->id);
|
||||||
|
$images = [];
|
||||||
|
foreach ($query->get() as $image) {
|
||||||
|
$images[] = [
|
||||||
|
'id' => $image->id,
|
||||||
|
'url' => $image->getUrl(Image::SMALL),
|
||||||
|
'filename' => $image->filename
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::json($images, 200);
|
||||||
|
}
|
||||||
|
}
|
|
@ -92,7 +92,8 @@
|
||||||
'description' => $track->description,
|
'description' => $track->description,
|
||||||
'lyrics' => $track->lyrics,
|
'lyrics' => $track->lyrics,
|
||||||
'released_at' => $track->released_at,
|
'released_at' => $track->released_at,
|
||||||
'cover_url' => $track->hasCover() ? $track->getCoverUrl(Image::NORMAL) : null
|
'cover_url' => $track->hasCover() ? $track->getCoverUrl(Image::NORMAL) : null,
|
||||||
|
'real_cover_url' => $track->getCoverUrl(Image::NORMAL)
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,17 @@
|
||||||
if (!$image)
|
if (!$image)
|
||||||
App::abort(404);
|
App::abort(404);
|
||||||
|
|
||||||
return File::inline($image->getFile($coverType['id']), $image->mime, $image->filename);
|
$filename = $image->getFile($coverType['id']);
|
||||||
|
$lastModified = filemtime($filename);
|
||||||
|
|
||||||
|
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $lastModified == $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
|
||||||
|
header('HTTP/1.0 304 Not Modified');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Last-Modified: ' . $lastModified);
|
||||||
|
header('Cache-Control: max-age=' . (60 * 60 * 24 * 7));
|
||||||
|
|
||||||
|
return File::inline($filename, $image->mime, $image->filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -42,7 +42,8 @@
|
||||||
'genre_id' => 'required|exists:genres,id',
|
'genre_id' => 'required|exists:genres,id',
|
||||||
'cover' => 'image|mimes:png|min_width:350|min_height:350',
|
'cover' => 'image|mimes:png|min_width:350|min_height:350',
|
||||||
'track_type_id' => 'required|exists:track_types,id',
|
'track_type_id' => 'required|exists:track_types,id',
|
||||||
'songs' => 'required_when:track_type,2|exists:songs,id'
|
'songs' => 'required_when:track_type,2|exists:songs,id',
|
||||||
|
'cover_id' => 'exists:images,id'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails())
|
if ($validator->fails())
|
||||||
|
@ -64,10 +65,13 @@
|
||||||
$track->published_at = new \DateTime();
|
$track->published_at = new \DateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->_input['cover'])) {
|
if (isset($this->_input['cover_id'])) {
|
||||||
|
$track->cover_id = $this->_input['cover_id'];
|
||||||
|
}
|
||||||
|
else if (isset($this->_input['cover'])) {
|
||||||
$cover = $this->_input['cover'];
|
$cover = $this->_input['cover'];
|
||||||
$track->cover_id = Image::Upload($cover, Auth::user())->id;
|
$track->cover_id = Image::Upload($cover, Auth::user())->id;
|
||||||
} else
|
} else if ($this->_input['remove_cover'] == 'true')
|
||||||
$track->cover_id = null;
|
$track->cover_id = null;
|
||||||
|
|
||||||
$track->save();
|
$track->save();
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['before' => 'auth'], function() {
|
Route::group(['before' => 'auth'], function() {
|
||||||
|
Route::get('/images/owned', 'Api\Web\ImagesController@getOwned');
|
||||||
Route::get('/tracks/owned', 'Api\Web\TracksController@getOwned');
|
Route::get('/tracks/owned', 'Api\Web\TracksController@getOwned');
|
||||||
Route::get('/tracks/edit/{id}', 'Api\Web\TracksController@getEdit');
|
Route::get('/tracks/edit/{id}', 'Api\Web\TracksController@getEdit');
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
$scope.isCoverLoaded = false
|
$scope.isCoverLoaded = false
|
||||||
$scope.selectedTrack = null
|
$scope.selectedTrack = null
|
||||||
$scope.isDirty = false
|
$scope.isDirty = false
|
||||||
|
$scope.isSaving = false
|
||||||
$scope.taxonomies =
|
$scope.taxonomies =
|
||||||
trackTypes: taxonomies.trackTypes
|
trackTypes: taxonomies.trackTypes
|
||||||
licenses: taxonomies.licenses
|
licenses: taxonomies.licenses
|
||||||
|
@ -18,11 +19,22 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
|
|
||||||
$scope.previewCover = () ->
|
$scope.previewCover = () ->
|
||||||
return if !$scope.edit.cover
|
return if !$scope.edit.cover
|
||||||
|
if typeof($scope.edit.cover) == 'object'
|
||||||
lightbox.openDataUrl $('#coverPreview').attr 'src'
|
lightbox.openDataUrl $('#coverPreview').attr 'src'
|
||||||
|
else
|
||||||
|
lightbox.openImageUrl $scope.edit.cover
|
||||||
|
|
||||||
|
$scope.selectGalleryImage = (image) ->
|
||||||
|
$('#coverPreview').attr 'src', image.url
|
||||||
|
$scope.edit.cover_id = image.id
|
||||||
|
$scope.edit.remove_cover = false
|
||||||
|
$scope.edit.cover = null
|
||||||
|
$scope.isDirty = true
|
||||||
|
|
||||||
$scope.updateTrack = (track) ->
|
$scope.updateTrack = (track) ->
|
||||||
xhr = new XMLHttpRequest()
|
xhr = new XMLHttpRequest()
|
||||||
xhr.onload = -> $scope.$apply ->
|
xhr.onload = -> $scope.$apply ->
|
||||||
|
$scope.isSaving = false
|
||||||
if xhr.status != 200
|
if xhr.status != 200
|
||||||
errors =
|
errors =
|
||||||
if xhr.getResponseHeader('content-type') == 'application/json'
|
if xhr.getResponseHeader('content-type') == 'application/json'
|
||||||
|
@ -40,12 +52,15 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
formData = new FormData();
|
formData = new FormData();
|
||||||
_.each $scope.edit, (value, name) ->
|
_.each $scope.edit, (value, name) ->
|
||||||
if name == 'cover'
|
if name == 'cover'
|
||||||
|
return if value == null
|
||||||
|
if typeof(value) == 'object'
|
||||||
formData.append name, value, value.name
|
formData.append name, value, value.name
|
||||||
else
|
else
|
||||||
formData.append name, value
|
formData.append name, value
|
||||||
|
|
||||||
xhr.open 'POST', '/api/web/tracks/edit/' + $scope.edit.id, true
|
xhr.open 'POST', '/api/web/tracks/edit/' + $scope.edit.id, true
|
||||||
xhr.setRequestHeader 'X-Token', pfm.token
|
xhr.setRequestHeader 'X-Token', pfm.token
|
||||||
|
$scope.isSaving = true
|
||||||
xhr.send formData
|
xhr.send formData
|
||||||
|
|
||||||
$scope.uploadTrackCover = () ->
|
$scope.uploadTrackCover = () ->
|
||||||
|
@ -53,6 +68,7 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
|
|
||||||
$scope.setCoverImage = (input) ->
|
$scope.setCoverImage = (input) ->
|
||||||
$scope.$apply ->
|
$scope.$apply ->
|
||||||
|
delete $scope.edit.cover_id
|
||||||
previewElement = $('#coverPreview')[0]
|
previewElement = $('#coverPreview')[0]
|
||||||
file = input.files[0]
|
file = input.files[0]
|
||||||
|
|
||||||
|
@ -71,6 +87,9 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
|
|
||||||
$scope.clearTrackCover = () ->
|
$scope.clearTrackCover = () ->
|
||||||
$scope.isCoverLoaded = false
|
$scope.isCoverLoaded = false
|
||||||
|
$scope.isDirty = true
|
||||||
|
$scope.edit.remove_cover = true
|
||||||
|
delete $scope.edit.cover_id
|
||||||
delete $scope.edit.cover
|
delete $scope.edit.cover
|
||||||
|
|
||||||
$scope.filters =
|
$scope.filters =
|
||||||
|
@ -162,6 +181,20 @@ angular.module('ponyfm').controller "account-content-tracks", [
|
||||||
genre_id: track.genre_id
|
genre_id: track.genre_id
|
||||||
track_type_id: track.track_type_id
|
track_type_id: track.track_type_id
|
||||||
released_at: if track.released_at then track.released_at.date else ''
|
released_at: if track.released_at then track.released_at.date else ''
|
||||||
|
remove_cover: false
|
||||||
|
cover: track.cover_url
|
||||||
|
|
||||||
|
trackDbItem = tracksDb[t.id]
|
||||||
|
trackDbItem.title = track.title
|
||||||
|
trackDbItem.is_explicit = track.is_explicit
|
||||||
|
trackDbItem.is_vocal = track.is_vocal
|
||||||
|
trackDbItem.genre_id = track.genre_id
|
||||||
|
trackDbItem.is_published = track.is_published
|
||||||
|
trackDbItem.cover_url = track.real_cover_url
|
||||||
|
|
||||||
|
if track.cover_url
|
||||||
|
$('#coverPreview').attr 'src', track.cover_url
|
||||||
|
$scope.isCoverLoaded = true
|
||||||
|
|
||||||
$scope.touchModel = -> $scope.isDirty = true
|
$scope.touchModel = -> $scope.isDirty = true
|
||||||
|
|
||||||
|
|
10
public/scripts/app/controllers/account-image-select.coffee
Normal file
10
public/scripts/app/controllers/account-image-select.coffee
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
angular.module('ponyfm').controller "account-image-select", [
|
||||||
|
'$scope'
|
||||||
|
($scope) ->
|
||||||
|
$scope.images = []
|
||||||
|
$scope.isLoading = true
|
||||||
|
|
||||||
|
$.getJSON('/api/web/images/owned').done (images) -> $scope.$apply ->
|
||||||
|
$scope.images = images
|
||||||
|
$scope.isLoading = false
|
||||||
|
]
|
36
public/scripts/app/directives/popup.coffee
Normal file
36
public/scripts/app/directives/popup.coffee
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
angular.module('ponyfm').directive 'pfmPopup', () ->
|
||||||
|
(scope, element, attrs) ->
|
||||||
|
$popup = $ '#' + attrs.pfmPopup
|
||||||
|
$element = $ element
|
||||||
|
$popup.remove()
|
||||||
|
open = false
|
||||||
|
|
||||||
|
documentClickHandler = () ->
|
||||||
|
return if !open
|
||||||
|
$popup.removeClass 'open'
|
||||||
|
open = false
|
||||||
|
|
||||||
|
$(document.body).bind 'click', documentClickHandler
|
||||||
|
|
||||||
|
$(document.body).append $popup
|
||||||
|
|
||||||
|
$(element).click (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
if open
|
||||||
|
open = false
|
||||||
|
$popup.removeClass 'open'
|
||||||
|
return
|
||||||
|
|
||||||
|
position = $element.offset()
|
||||||
|
$popup.addClass 'open'
|
||||||
|
$popup.css
|
||||||
|
top: position.top + $element.height() + 10
|
||||||
|
left: position.left
|
||||||
|
|
||||||
|
open = true
|
||||||
|
|
||||||
|
scope.$on '$destroy', () ->
|
||||||
|
$(document.body).unbind 'click', documentClickHandler
|
||||||
|
$popup.remove()
|
|
@ -4,5 +4,10 @@ angular.module('ponyfm').factory('lightbox', [
|
||||||
$.colorbox
|
$.colorbox
|
||||||
html: '<img src="' + src + '" />'
|
html: '<img src="' + src + '" />'
|
||||||
transition: 'none'
|
transition: 'none'
|
||||||
|
|
||||||
|
openImageUrl: (src) ->
|
||||||
|
$.colorbox
|
||||||
|
href: src
|
||||||
|
transition: 'none'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-selector {
|
||||||
|
width: 500px;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0px;
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
.transition(all 400ms);
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
img {
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.account-tracks-listing {
|
.account-tracks-listing {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
|
|
@ -81,3 +81,15 @@ html body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pfm-popup {
|
||||||
|
.box-shadow(0 5px 10px rgba(0, 0, 0, 0.2));
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,42 +58,48 @@
|
||||||
<form novalidate ng-submit="updateTrack(edit)">
|
<form novalidate ng-submit="updateTrack(edit)">
|
||||||
<ul class="toolbar">
|
<ul class="toolbar">
|
||||||
<li>
|
<li>
|
||||||
<button type="submit" class="btn" ng-class="{disabled: selectedTrack.is_published && !isDirty, 'btn-primary': !selectedTrack.is_published || isDirty}">
|
<button type="submit" class="btn" ng-class="{disabled: (selectedTrack.is_published && !isDirty) || isSaving, 'btn-primary': !selectedTrack.is_published || isDirty}">
|
||||||
<span ng-show="selectedTrack.is_published">Save Changes</span>
|
<span ng-show="selectedTrack.is_published">
|
||||||
<span ng-hide="selectedTrack.is_published">Publish Track</span>
|
Save Changes
|
||||||
|
<i ng-show="isSaving" class="icon-cog icon-spin icon-large"></i>
|
||||||
|
</span>
|
||||||
|
<span ng-hide="selectedTrack.is_published">
|
||||||
|
Publish Track
|
||||||
|
<i ng-show="isSaving" class="icon-cog icon-spin icon-large"></i>
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="delete"><a class="btn btn-danger" href="#" ng-click="deleteTrack(selectedTrack)" pfm-eat-click>Delete Track</a></li>
|
<li class="delete"><a ng-class="{disabled: isSaving}" class="btn btn-danger" href="#" ng-click="deleteTrack(selectedTrack)" pfm-eat-click>Delete Track</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="strech-to-bottom">
|
<div class="strech-to-bottom">
|
||||||
<div class="form-row" ng-class="{'has-error': errors.title != null}">
|
<div class="form-row" ng-class="{'has-error': errors.title != null}">
|
||||||
<label for="title" class="strong">Title:</label>
|
<label for="title" class="strong">Title:</label>
|
||||||
<input required ng-change="touchModel()" placeholder="Track Title" type="text" id="title" ng-model="edit.title" />
|
<input ng-disabled="isSaving" ng-change="touchModel()" placeholder="Track Title" type="text" id="title" ng-model="edit.title" />
|
||||||
<div class="error">{{errors.title}}</div>
|
<div class="error">{{errors.title}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span6 form-row" ng-class="{'has-error': errors.description != null}">
|
<div class="span6 form-row" ng-class="{'has-error': errors.description != null}">
|
||||||
<label for="description" class="strong">Description:</label>
|
<label for="description" class="strong">Description:</label>
|
||||||
<textarea ng-change="touchModel()" placeholder="Description (optional)" id="description" ng-model="edit.description"></textarea>
|
<textarea ng-disabled="isSaving" ng-change="touchModel()" placeholder="Description (optional)" id="description" ng-model="edit.description"></textarea>
|
||||||
<div class="error">{{errors.description}}</div>
|
<div class="error">{{errors.description}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="span6 form-row" ng-class="{'has-error': errors.lyrics != null}">
|
<div class="span6 form-row" ng-class="{'has-error': errors.lyrics != null}">
|
||||||
<label for="is_vocal" class="strong"><input ng-change="touchModel(); updateIsVocal()" id="is_vocal" type="checkbox" ng-model="edit.is_vocal" /> Is Vocal</label>
|
<label for="is_vocal" class="strong"><input ng-disabled="isSaving" ng-change="touchModel(); updateIsVocal()" id="is_vocal" type="checkbox" ng-model="edit.is_vocal" /> Is Vocal</label>
|
||||||
<textarea ng-change="touchModel()" ng-show="edit.is_vocal" ng-animate="'fade'" placeholder="Lyrics (required)" id="lyrics" ng-model="edit.lyrics"></textarea>
|
<textarea ng-disabled="isSaving" ng-change="touchModel()" ng-show="edit.is_vocal" ng-animate="'fade'" placeholder="Lyrics (required)" id="lyrics" ng-model="edit.lyrics"></textarea>
|
||||||
<div class="error">{{errors.lyrics}}</div>
|
<div class="error">{{errors.lyrics}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.track_type_id != null}">
|
<div class="form-row span6" ng-class="{'has-error': errors.track_type_id != null}">
|
||||||
<label for="track_type" class="strong">This track is...</label>
|
<label for="track_type" class="strong">This track is...</label>
|
||||||
<select required id="track_type" ng-change="touchModel()" ng-model="edit.track_type_id" ng-options="type.id as type.editor_title for type in taxonomies.trackTypes">
|
<select ng-disabled="isSaving" id="track_type" ng-change="touchModel()" ng-model="edit.track_type_id" ng-options="type.id as type.editor_title for type in taxonomies.trackTypes">
|
||||||
<option value="">Please select a type...</option>
|
<option value="">Please select a type...</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="error">{{errors.track_type_id}}</div>
|
<div class="error">{{errors.track_type_id}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.genre_id != null}">
|
<div class="form-row span6" ng-class="{'has-error': errors.genre_id != null}">
|
||||||
<label for="genre" class="strong">Genre:</label>
|
<label for="genre" class="strong">Genre:</label>
|
||||||
<select required id="genre" ng-change="touchModel()" ng-model="edit.genre_id" ng-options="genre.id as genre.name for genre in taxonomies.genres">
|
<select ng-disabled="isSaving" id="genre" ng-change="touchModel()" ng-model="edit.genre_id" ng-options="genre.id as genre.name for genre in taxonomies.genres">
|
||||||
<option value="">Please select a genre...</option>
|
<option value="">Please select a genre...</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="error">{{errors.genre_id}}</div>
|
<div class="error">{{errors.genre_id}}</div>
|
||||||
|
@ -109,24 +115,32 @@
|
||||||
<input type="file" id="coverImage" onchange="angular.element(this).scope().setCoverImage(this)" />
|
<input type="file" id="coverImage" onchange="angular.element(this).scope().setCoverImage(this)" />
|
||||||
</p>
|
</p>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
<a href="#" pfm-popup="image-selector" class="btn btn-small"><i class="icon-picture"></i> Gallery</a>
|
||||||
<a href="#" pfm-eat-click ng-click="uploadTrackCover()" class="btn btn-info btn-small"><i class="icon-upload"></i> Upload</a>
|
<a href="#" pfm-eat-click ng-click="uploadTrackCover()" class="btn btn-info btn-small"><i class="icon-upload"></i> Upload</a>
|
||||||
<a href="#" pfm-eat-click ng-click="clearTrackCover()" class="btn btn-danger btn-small" ng-show="edit.cover"><i class="icon-remove"></i></a>
|
<a href="#" pfm-eat-click ng-click="clearTrackCover()" class="btn btn-danger btn-small" ng-show="edit.cover || edit.cover_id"><i class="icon-remove"></i></a>
|
||||||
|
</div>
|
||||||
|
<div id="image-selector" class="pfm-popup image-selector" ng-controller="account-image-select">
|
||||||
|
<ul>
|
||||||
|
<li ng-repeat="image in images" ng-click="selectGalleryImage(image)">
|
||||||
|
<img src="{{image.url}}" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="error">{{errors.cover}}</div>
|
<div class="error">{{errors.cover}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row span6" ng-class="{'has-error': errors.released_at != null}">
|
<div class="form-row span6" ng-class="{'has-error': errors.released_at != null}">
|
||||||
<label for="released_at" class="strong">Release Date:</label>
|
<label for="released_at" class="strong">Release Date:</label>
|
||||||
<input type="text" id="released_at" ui-date ng-model="edit.released_at" ng-change="touchModel()" ui-date-format="yy-mm-dd" />
|
<input ng-disabled="isSaving" type="text" id="released_at" ui-date ng-model="edit.released_at" ng-change="touchModel()" ui-date-format="yy-mm-dd" />
|
||||||
<div class="error">{{errors.released_at}}</div>
|
<div class="error">{{errors.released_at}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span6 form-row">
|
<div class="span6 form-row">
|
||||||
<label for="is_explicit"><input ng-change="touchModel()" id="is_explicit" type="checkbox" ng-model="edit.is_explicit" /> Contains Explicit Content</label>
|
<label for="is_explicit"><input ng-disabled="isSaving" ng-change="touchModel()" id="is_explicit" type="checkbox" ng-model="edit.is_explicit" /> Contains Explicit Content</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="span6 form-row">
|
<div class="span6 form-row">
|
||||||
<label for="is_downloadable"><input ng-change="touchModel()" id="is_downloadable" type="checkbox" ng-model="edit.is_downloadable" /> Is Downloadable</label>
|
<label for="is_downloadable"><input ng-disabled="isSaving" ng-change="touchModel()" id="is_downloadable" type="checkbox" ng-model="edit.is_downloadable" /> Is Downloadable</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
@ -136,7 +150,7 @@
|
||||||
<div ng-click="edit.license_id = license.id; touchModel()">
|
<div ng-click="edit.license_id = license.id; touchModel()">
|
||||||
<strong>{{license.title}}</strong>
|
<strong>{{license.title}}</strong>
|
||||||
<p>{{license.description}}</p>
|
<p>{{license.description}}</p>
|
||||||
<a href="#" pfm-eat-click class="btn" ng-class="{'btn-primary': edit.license_id == license.id}">
|
<a href="#" pfm-eat-click class="btn" ng-class="{'btn-primary': edit.license_id == license.id, 'disabled': isSaving}">
|
||||||
<span ng-hide="edit.license_id == license.id">Select</span>
|
<span ng-hide="edit.license_id == license.id">Select</span>
|
||||||
<span ng-show="edit.license_id == license.id">Selected</span>
|
<span ng-show="edit.license_id == license.id">Selected</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
Loading…
Reference in a new issue