diff --git a/sass b/sass index 2d8eb12..9ed3ed9 100755 --- a/sass +++ b/sass @@ -1 +1 @@ -sass src/scss/style.scss build/style.css +sass --style=compressed src/scss/style.scss build/style.css diff --git a/spotify/templates/app.html b/spotify/templates/app.html index 32db709..dad2198 100644 --- a/spotify/templates/app.html +++ b/spotify/templates/app.html @@ -33,5 +33,6 @@
+
toast
\ No newline at end of file diff --git a/src/js/Admin/Functions.js b/src/js/Admin/Functions.js index 701a733..3af096f 100644 --- a/src/js/Admin/Functions.js +++ b/src/js/Admin/Functions.js @@ -1,6 +1,8 @@ import React, { Component } from "react"; const axios = require('axios'); +import showMessage from "../Toast.js" + class Functions extends Component { constructor(props){ @@ -12,7 +14,7 @@ class Functions extends Component { runAllUsers(event){ axios.get('/api/playlist/run/users') .catch((error) => { - console.log(error); + showMessage(`error running all users (${error.response.status})`); }); } diff --git a/src/js/Admin/Lock.js b/src/js/Admin/Lock.js index 794d8ef..f2a5a94 100644 --- a/src/js/Admin/Lock.js +++ b/src/js/Admin/Lock.js @@ -1,6 +1,8 @@ import React, { Component } from "react"; const axios = require('axios'); +import showMessage from "../Toast.js" + class Lock extends Component { constructor(props){ @@ -22,6 +24,9 @@ class Lock extends Component { accounts: response.data.accounts, isLoading: false }) + }) + .catch((error) => { + showMessage(`error getting users info (${error.response.status})`); }); } @@ -30,7 +35,8 @@ class Lock extends Component { username: username, locked: to_state }).catch((error) => { - console.log(error); + var lockMessage = to_state ? 'locking' : 'unlocking'; + showMessage(`error ${lockMessage} ${username} (${error.response.status})`); }).finally(() => { this.getUserInfo(); }); diff --git a/src/js/Index/Index.js b/src/js/Index/Index.js index 52041fc..4613e4e 100644 --- a/src/js/Index/Index.js +++ b/src/js/Index/Index.js @@ -6,19 +6,6 @@ class Index extends Component{ constructor(props){ super(props); this.state = {} - // this.pingPlaylists(); - } - - pingPlaylists(){ - var self = this; - axios.get('/api/playlists') - .then((response) => { - console.log(response) - }); - axios.get('/api/user') - .then((response) => { - console.log(response) - }); } render(){ diff --git a/src/js/Playlist/NewPlaylist.js b/src/js/Playlist/NewPlaylist.js index 8e83441..0ee2ada 100644 --- a/src/js/Playlist/NewPlaylist.js +++ b/src/js/Playlist/NewPlaylist.js @@ -2,15 +2,15 @@ import React, { Component } from "react"; import { BrowserRouter as Redirect } from "react-router-dom"; const axios = require('axios'); +import showMessage from "../Toast.js" + class NewPlaylist extends Component { constructor(props) { super(props); this.state = { name: '', - type: 'normal', - error: false, - errorText: null + type: 'normal' } this.handleInputChange = this.handleInputChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); @@ -25,25 +25,25 @@ class NewPlaylist extends Component { handleSubmit(event){ axios.get('/api/playlists') .then((response) => { - var sameName = response.data.playlists.filter((i) => {i.name == this.state.name ? true : false}); - if(sameName.length == 0){ + var sameName = response.data.playlists.includes(this.state.name); + if(sameName.length == false){ axios.put('/api/playlist', { name: this.state.name, parts: [], playlist_references: [], shuffle: false, type: this.state.type, + }).then((response) => { + showMessage(`${this.state.name} created`); }).catch((error) => { - console.log(error); - }).finally(() => { - window.location.href = "/app/playlists"; + showMessage(`error creating playlist (${error.response.status})`); }); }else{ - this.setState({ - error: true, - errorText: 'name already exists' - }); + showMessage('named playlist already exists'); } + }) + .catch((error) => { + showMessage(`error getting playlists (${error.response.status})`); }); } @@ -80,12 +80,6 @@ class NewPlaylist extends Component { - { this.state.error && - - -

{this.state.errorText}

- - } ); diff --git a/src/js/Playlist/PlaylistView.js b/src/js/Playlist/PlaylistView.js index ecd6ed4..71a0a0f 100644 --- a/src/js/Playlist/PlaylistView.js +++ b/src/js/Playlist/PlaylistView.js @@ -1,6 +1,8 @@ import React, { Component } from "react"; const axios = require('axios'); +import showMessage from "../Toast.js" + class PlaylistView extends Component{ constructor(props){ @@ -11,8 +13,6 @@ class PlaylistView extends Component{ playlists: [], playlist_references: [], type: null, - error: false, - error_text: null, day_boundary: '', recommendation_sample: '', @@ -37,14 +37,24 @@ class PlaylistView extends Component{ componentDidMount(){ axios.all([this.getPlaylistInfo(), this.getPlaylists()]) .then(axios.spread((info, playlists) => { + + info.data.parts.sort(function(a, b){ + if(a < b) { return -1; } + if(a > b) { return 1; } + return 0; + }); + + info.data.playlist_references.sort(function(a, b){ + if(a < b) { return -1; } + if(a > b) { return 1; } + return 0; + }); + this.setState(info.data); this.setState({playlists: playlists.data.playlists}); })) .catch((error) => { - this.setState({ - error: true, - error_text: "error pulling playlist info" - }); + showMessage(`error getting playlist info (${error.response.status})`); }); } @@ -57,7 +67,6 @@ class PlaylistView extends Component{ } handleInputChange(event){ - console.log(event.target.name + event.target.value); this.setState({ [event.target.name]: event.target.value }); @@ -75,7 +84,7 @@ class PlaylistView extends Component{ name: this.state.name, day_boundary: parseInt(boundary) }).catch((error) => { - console.log(error); + showMessage(`error updating boundary value (${error.response.status})`); }); } @@ -84,7 +93,7 @@ class PlaylistView extends Component{ name: this.state.name, recommendation_sample: parseInt(sample) }).catch((error) => { - console.log(error); + showMessage(`error updating rec. sample value (${error.response.status})`); }); } @@ -96,7 +105,7 @@ class PlaylistView extends Component{ name: this.state.name, shuffle: event.target.checked }).catch((error) => { - console.log(error); + showMessage(`error updating shuffle value (${error.response.status})`); }); } @@ -108,7 +117,7 @@ class PlaylistView extends Component{ name: this.state.name, include_recommendations: event.target.checked }).catch((error) => { - console.log(error); + showMessage(`error updating rec. value (${error.response.status})`); }); } @@ -136,7 +145,7 @@ class PlaylistView extends Component{ name: this.state.name, parts: parts }).catch((error) => { - console.log(error); + showMessage(`error adding part (${error.response.status})`); }); } } @@ -165,7 +174,7 @@ class PlaylistView extends Component{ name: this.state.name, playlist_references: playlist_references }).catch((error) => { - console.log(error); + showMessage(`error adding reference (${error.response.status})`); }); } } @@ -185,7 +194,7 @@ class PlaylistView extends Component{ name: this.state.name, parts: parts }).catch((error) => { - console.log(error); + showMessage(`error removing part (${error.response.status})`); }); } @@ -204,14 +213,17 @@ class PlaylistView extends Component{ name: this.state.name, playlist_references: playlist_references }).catch((error) => { - console.log(error); + showMessage(`error removing reference (${error.response.status})`); }); } handleRun(event){ axios.get('/api/playlist/run', {params: {name: this.state.name}}) + .then((reponse) => { + showMessage(`${this.state.name} ran`); + }) .catch((error) => { - console.log(error); + showMessage(`error running ${this.state.name} (${error.response.status})`); }); } diff --git a/src/js/Playlist/PlaylistsView.js b/src/js/Playlist/PlaylistsView.js index 5d1abda..024340f 100644 --- a/src/js/Playlist/PlaylistsView.js +++ b/src/js/Playlist/PlaylistsView.js @@ -2,6 +2,8 @@ import React, { Component } from "react"; import { BrowserRouter as Router, Route, Link } from "react-router-dom"; const axios = require('axios'); +import showMessage from "../Toast.js" + class PlaylistsView extends Component { constructor(props){ @@ -32,29 +34,39 @@ class PlaylistsView extends Component { playlists: playlists, isLoading: false }); + }) + .catch((error) => { + showMessage(`error getting playlists (${error.response.status})`); }); } handleRunPlaylist(name, event){ axios.get('/api/playlist/run', {params: {name: name}}) - .catch((error) => {this - console.log(error); + .then((response) => { + showMessage(`${name} ran`); + }) + .catch((error) => { + showMessage(`error running ${name} (${error.response.status})`); }); } handleDeletePlaylist(name, event){ axios.delete('/api/playlist', { params: { name: name } }) .then((response) => { + showMessage(`${name} deleted`); this.getPlaylists(); }).catch((error) => { - console.log(error); + showMessage(`error deleting ${name} (${error.response.status})`); }); } handleRunAll(event){ axios.get('/api/playlist/run/user') + .then((response) => { + showMessage("all playlists ran"); + }) .catch((error) => { - console.log(error); + showMessage(`error running all (${error.response.status})`); }); } diff --git a/src/js/PlaylistManager.js b/src/js/PlaylistManager.js index c01f595..00ff54b 100644 --- a/src/js/PlaylistManager.js +++ b/src/js/PlaylistManager.js @@ -9,6 +9,8 @@ import Admin from "./Admin/Admin.js"; import NotFound from "./Error/NotFound.js"; +import showMessage from "./Toast.js" + const axios = require('axios'); class PlaylistManager extends Component { @@ -41,6 +43,9 @@ class PlaylistManager extends Component { type: response.data.type, spotify_linked: response.data.spotify_linked }) + }) + .catch((error) => { + showMessage(`error getting user info (${error.response.status})`); }); } diff --git a/src/js/Settings/SpotifyLink.js b/src/js/Settings/SpotifyLink.js index d099fa3..5abe107 100644 --- a/src/js/Settings/SpotifyLink.js +++ b/src/js/Settings/SpotifyLink.js @@ -1,6 +1,8 @@ import React, { Component } from "react"; const axios = require('axios'); +import showMessage from "../Toast.js" + class SpotifyLink extends Component { constructor(props){ @@ -19,6 +21,9 @@ class SpotifyLink extends Component { spotify_linked: response.data.spotify_linked, isLoading: false }) + }) + .catch((error) => { + showMessage(`error getting user info (${error.response.status})`); }); } diff --git a/src/js/Toast.js b/src/js/Toast.js new file mode 100644 index 0000000..526f62c --- /dev/null +++ b/src/js/Toast.js @@ -0,0 +1,9 @@ + +function showToast(message) { + var x = document.getElementById("snackbar"); + x.innerHTML = message; + x.className = "show"; + setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000); +} + +export default showToast; \ No newline at end of file diff --git a/src/scss/style.scss b/src/scss/style.scss index addfe50..05d0c93 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -3,6 +3,7 @@ $background-colour: #202124; $ui-colour: #131313; $light-ui: #575757; $text-colour: white; +$ui-element: #505050; $pad-px: 20px; @@ -48,7 +49,7 @@ p { } .button { - background-color: #505050; + background-color: $ui-element; color: $text-colour; display: inline-block; @@ -63,17 +64,11 @@ p { cursor: pointer; box-shadow: 0 9px #383838; - /*-webkit-transition-duration: 0.4s; - transition-duration: 0.4s;*/ text: { align: center; decoration: none; } - - // &:hover { - // box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19); - // } &:active { box-shadow: 0 5px #383838; @@ -83,7 +78,7 @@ p { input[type=text], input[type=password], input[type=number], select { padding: 10px; - background-color: #505050; + background-color: $ui-element; border: black; border-radius: 4px; color: white; @@ -237,12 +232,8 @@ ul.navbar { padding-bottom: 10px; tr { - // float: left; - // position: -webkit-sticky; - // position: sticky; top: 0; cursor: pointer; - // padding: 10px; td { @@ -252,18 +243,9 @@ ul.navbar { border-radius: 5px; - // margin-top: 10px; - // margin-bottom: 10px; - // margin: auto; - a { - // display: block; color: $text-colour; - // text-align: center; - // vertical-align: center; - // margin: 25px; - // padding: 14px 16px; - // border-radius: 5px; + height: 100%; width: 100%; display: inline-block; @@ -324,6 +306,48 @@ footer { } } +#snackbar { + visibility: hidden; + min-width: 250px; + margin-left: -125px; + background-color: white; + color: black; + text-align: center; + border-radius: 2px; + padding: 16px; + position: fixed; + z-index: 1; + left: 50%; + bottom: 30px; + font-size: 17px; + } + + #snackbar.show { + visibility: visible; + -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; + animation: fadein 0.5s, fadeout 0.5s 2.5s; + } + + @-webkit-keyframes fadein { + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} + } + + @keyframes fadein { + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} + } + + @-webkit-keyframes fadeout { + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} + } + + @keyframes fadeout { + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} + } + @media only screen and (max-width: 768px) { ul.navbar li.right, ul.navbar li {float: none;} diff --git a/watchsass b/watchsass index 729f219..c080fd3 100755 --- a/watchsass +++ b/watchsass @@ -1 +1 @@ -sass --watch src/scss/style.scss build/style.css +sass --style=compressed --watch src/scss/style.scss build/style.css