Merge branch 'feature/playlist-image-upload' into develop
This commit is contained in:
@ -2920,6 +2920,7 @@ input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="date"],
|
||||
input[type="file"],
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
@ -2939,6 +2940,8 @@ select {
|
||||
input[type="email"]:active,
|
||||
input[type="date"]:focus,
|
||||
input[type="date"]:active,
|
||||
input[type="file"]:focus,
|
||||
input[type="file"]:active,
|
||||
select:focus,
|
||||
select:active {
|
||||
background: rgba(255, 255, 255, 0.2); }
|
||||
@ -2948,6 +2951,7 @@ select {
|
||||
input[type="number"]:disabled,
|
||||
input[type="email"]:disabled,
|
||||
input[type="date"]:disabled,
|
||||
input[type="file"]:disabled,
|
||||
select:disabled {
|
||||
opacity: 0.5; }
|
||||
textarea.tiny,
|
||||
@ -2956,6 +2960,7 @@ select {
|
||||
input[type="number"].tiny,
|
||||
input[type="email"].tiny,
|
||||
input[type="date"].tiny,
|
||||
input[type="file"].tiny,
|
||||
select.tiny {
|
||||
width: 50px;
|
||||
padding-left: 4px;
|
||||
@ -3301,7 +3306,9 @@ input[type="submit"] {
|
||||
color: #cf2d2d;
|
||||
display: inline-block;
|
||||
opacity: 1; }
|
||||
.field.radio input, .field.checkbox input {
|
||||
.field.radio input[type="radio"],
|
||||
.field.radio input[type="checkbox"], .field.checkbox input[type="radio"],
|
||||
.field.checkbox input[type="checkbox"] {
|
||||
display: none; }
|
||||
.field.radio .input, .field.checkbox .input {
|
||||
padding-top: 4px; }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -26,9 +26,6 @@
|
||||
<link rel="apple-touch-icon" sizes="512x512" href="/iris/assets/logo-app-512.png" />
|
||||
<link rel="mask-icon" href="/iris/assets/icon_coloured.svg" color="#08d58f" />
|
||||
|
||||
<!-- Raven Sentry -->
|
||||
<script src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Loading screen -->
|
||||
<style>
|
||||
html {
|
||||
@ -77,7 +74,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1530743614";
|
||||
var build = "1530996335";
|
||||
var version = "3.22.0";
|
||||
|
||||
// Construct the script tag
|
||||
@ -114,5 +111,8 @@
|
||||
|
||||
</script>
|
||||
|
||||
<!-- Raven Sentry -->
|
||||
<script src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@ -26,9 +26,6 @@
|
||||
<link rel="apple-touch-icon" sizes="512x512" href="/iris/assets/logo-app-512.png" />
|
||||
<link rel="mask-icon" href="/iris/assets/icon_coloured.svg" color="#08d58f" />
|
||||
|
||||
<!-- Raven Sentry -->
|
||||
<script src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Loading screen -->
|
||||
<style>
|
||||
html {
|
||||
@ -114,5 +111,8 @@
|
||||
|
||||
</script>
|
||||
|
||||
<!-- Raven Sentry -->
|
||||
<script src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@ class OutputControl extends React.Component{
|
||||
} else {
|
||||
|
||||
// No customisable outputs
|
||||
if (!this.props.http_streaming_enabled && !this.props.snacast_enabled){
|
||||
if (!this.props.http_streaming_enabled && !this.props.snapcast_enabled){
|
||||
return (
|
||||
<span className="output-control disabled">
|
||||
<a className="control speakers"><Icon name="speaker" /></a>
|
||||
@ -133,7 +133,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
http_streaming_enabled: state.core.http_streaming_enabled,
|
||||
http_streaming_volume: state.core.http_streaming_volume,
|
||||
http_streaming_mute: state.core.http_streaming_mute,
|
||||
snapcast_enabled: state.pusher.config.snapcast_enabled,
|
||||
snapcast_enabled: (state.pusher.config ? state.pusher.config.snapcast_enabled : null),
|
||||
pusher_connected: state.pusher.connected,
|
||||
snapcast_clients: state.pusher.snapcast_clients
|
||||
}
|
||||
|
||||
@ -13,23 +13,40 @@ export default class EditPlaylistModal extends React.Component{
|
||||
name: this.props.data.name,
|
||||
description: (this.props.data.description ? this.props.data.description : ''),
|
||||
public: this.props.data.public,
|
||||
image: null,
|
||||
collaborative: this.props.data.collaborative
|
||||
}
|
||||
}
|
||||
|
||||
savePlaylist(e){
|
||||
savePlaylist(e){
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.state.name || this.state.name == ''){
|
||||
this.setState({error: 'Name is required'})
|
||||
return false
|
||||
} else {
|
||||
this.props.coreActions.savePlaylist(this.props.data.uri, this.state.name, this.state.description, this.state.public, this.state.collaborative)
|
||||
this.props.uiActions.closeModal()
|
||||
return false
|
||||
this.props.coreActions.savePlaylist(this.props.data.uri, this.state.name, this.state.description, this.state.public, this.state.collaborative, this.state.image);
|
||||
this.props.uiActions.closeModal();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
setImage(e){
|
||||
var self = this;
|
||||
|
||||
// Create a file-reader to import the selected image as a base64 string
|
||||
var file_reader = new FileReader();
|
||||
|
||||
// Once the image is loaded, convert the result
|
||||
file_reader.addEventListener("load", function(e){
|
||||
var image_base64 = e.target.result.replace('data:image/jpeg;base64,','');
|
||||
self.setState({image: image_base64});
|
||||
});
|
||||
|
||||
// This calls the filereader to load the file
|
||||
file_reader.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
|
||||
renderFields(){
|
||||
switch (helpers.uriSource(this.props.data.uri)){
|
||||
|
||||
@ -42,7 +59,8 @@ export default class EditPlaylistModal extends React.Component{
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ name: e.target.value })}
|
||||
value={ this.state.name } />
|
||||
value={ this.state.name }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field text">
|
||||
@ -51,7 +69,21 @@ export default class EditPlaylistModal extends React.Component{
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ description: e.target.value })}
|
||||
value={ this.state.description } />
|
||||
value={ this.state.description }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field file">
|
||||
<div className="name">Cover image</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="file"
|
||||
placeholder="Leave empty to keep existing image"
|
||||
onChange={e => this.setImage(e)}
|
||||
/>
|
||||
<div className="description">
|
||||
JPEG only, 256kB max. Leave empty to keep cover image unchanged.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field checkbox white">
|
||||
|
||||
@ -831,5 +831,3 @@ export let getIndexedRecords = function(index, uris){
|
||||
export let titleCase = function(string){
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ export function reorderPlaylistTracks(uri, indexes, insert_before, snapshot_id =
|
||||
}
|
||||
}
|
||||
|
||||
export function savePlaylist(uri, name, description = '', is_public = false, is_collaborative = false){
|
||||
export function savePlaylist(uri, name, description = '', is_public = false, is_collaborative = false, image = null){
|
||||
switch (helpers.uriSource(uri)){
|
||||
|
||||
case 'spotify':
|
||||
@ -119,6 +119,7 @@ export function savePlaylist(uri, name, description = '', is_public = false, is_
|
||||
key: uri,
|
||||
name: name,
|
||||
description: (description == '' ? null : description),
|
||||
image: image,
|
||||
is_public: is_public,
|
||||
is_collaborative: is_collaborative
|
||||
}
|
||||
|
||||
@ -1488,7 +1488,7 @@ export function createPlaylist(name, description, is_public, is_collaborative){
|
||||
}
|
||||
}
|
||||
|
||||
export function savePlaylist(uri, name, description, is_public, is_collaborative){
|
||||
export function savePlaylist(uri, name, description, is_public, is_collaborative, image){
|
||||
return (dispatch, getState) => {
|
||||
|
||||
var data = {
|
||||
@ -1498,20 +1498,51 @@ export function savePlaylist(uri, name, description, is_public, is_collaborative
|
||||
collaborative: is_collaborative
|
||||
}
|
||||
|
||||
sendRequest(dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/'+ helpers.getFromUri('playlistid',uri), 'PUT', data)
|
||||
// Update the playlist fields
|
||||
sendRequest(
|
||||
dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/'+ helpers.getFromUri('playlistid',uri), 'PUT', data)
|
||||
.then(
|
||||
response => {
|
||||
dispatch({
|
||||
type: 'PLAYLIST_UPDATED',
|
||||
key: uri,
|
||||
playlist: {
|
||||
name: name,
|
||||
public: is_public,
|
||||
collaborative: is_collaborative,
|
||||
description: description
|
||||
}
|
||||
})
|
||||
dispatch(uiActions.createNotification({content: 'Saved'}));
|
||||
|
||||
// Save the image
|
||||
if (image){
|
||||
sendRequest(dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/'+ helpers.getFromUri('playlistid',uri)+'/images', 'PUT', image)
|
||||
.then(
|
||||
|
||||
response => {
|
||||
dispatch({
|
||||
type: 'PLAYLIST_UPDATED',
|
||||
key: uri,
|
||||
playlist: {
|
||||
name: name,
|
||||
public: is_public,
|
||||
collaborative: is_collaborative,
|
||||
description: description
|
||||
}
|
||||
});
|
||||
},
|
||||
error => {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not save image',
|
||||
error
|
||||
));
|
||||
}
|
||||
);
|
||||
|
||||
// No image, so we're done here
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'PLAYLIST_UPDATED',
|
||||
key: uri,
|
||||
playlist: {
|
||||
name: name,
|
||||
public: is_public,
|
||||
collaborative: is_collaborative,
|
||||
description: description
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error => {
|
||||
dispatch(coreActions.handleException(
|
||||
@ -1519,7 +1550,7 @@ export function savePlaylist(uri, name, description, is_public, is_collaborative
|
||||
error
|
||||
));
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -92,14 +92,12 @@ const SpotifyMiddleware = (function(){
|
||||
store.dispatch(spotifyActions.addTracksToPlaylist(action.key, action.tracks_uris ))
|
||||
break;
|
||||
|
||||
|
||||
case 'SPOTIFY_REORDER_PLAYLIST_TRACKS':
|
||||
store.dispatch(spotifyActions.reorderPlaylistTracks(action.key, action.range_start, action.range_length, action.insert_before, action.snapshot_id ))
|
||||
break;
|
||||
|
||||
|
||||
case 'SPOTIFY_SAVE_PLAYLIST':
|
||||
store.dispatch(spotifyActions.savePlaylist(action.key, action.name, action.description, action.is_public, action.is_collaborative ))
|
||||
store.dispatch(spotifyActions.savePlaylist(action.key, action.name, action.description, action.is_public, action.is_collaborative, action.image))
|
||||
break;
|
||||
|
||||
case 'SPOTIFY_NEW_RELEASES_LOADED':
|
||||
|
||||
@ -13,6 +13,7 @@ input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="date"],
|
||||
input[type="file"],
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
background: rgba(255,255,255,0.1);
|
||||
@ -339,7 +340,9 @@ input[type="submit"] {
|
||||
|
||||
&.radio,
|
||||
&.checkbox {
|
||||
input{
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user