Remaining modals; Error boundaries; Notification styles
This commit is contained in:
@ -3898,21 +3898,10 @@ input[type="submit"] {
|
|||||||
font-size: 30px; }
|
font-size: 30px; }
|
||||||
.modal--kiosk-mode .content .current-track .artist-sentence {
|
.modal--kiosk-mode .content .current-track .artist-sentence {
|
||||||
opacity: 0.5; }
|
opacity: 0.5; }
|
||||||
.modal--send-authorization .list {
|
.modal--share-authorization .list {
|
||||||
padding-top: 40px; }
|
padding-top: 40px; }
|
||||||
.modal--receive-authorization .user-details {
|
.modal--share-authorization .list .list-item {
|
||||||
padding: 70px 0 0 120px;
|
cursor: pointer; }
|
||||||
min-height: 100px;
|
|
||||||
position: relative; }
|
|
||||||
.modal--receive-authorization .user-details::after {
|
|
||||||
content: '';
|
|
||||||
clear: both;
|
|
||||||
display: block; }
|
|
||||||
.modal--receive-authorization .user-details .thumbnail {
|
|
||||||
max-width: 100px;
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
left: 0; }
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
.modal .content {
|
.modal .content {
|
||||||
padding: 40px 5%;
|
padding: 40px 5%;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
// Release details
|
// Release details
|
||||||
// These are automatically injected to built HTML
|
// These are automatically injected to built HTML
|
||||||
var build = "1531081129";
|
var build = "1532129909";
|
||||||
var version = "3.22.0";
|
var version = "3.22.0";
|
||||||
|
|
||||||
// Construct the script tag
|
// Construct the script tag
|
||||||
|
|||||||
27
src/js/components/ErrorBoundary.js
Executable file
27
src/js/components/ErrorBoundary.js
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default class ErrorBoundary extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { hasError: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidCatch(error, info) {
|
||||||
|
// Display fallback UI
|
||||||
|
this.setState({ hasError: true });
|
||||||
|
// You can also log the error to an error reporting service
|
||||||
|
//logErrorToMyService(error, info);
|
||||||
|
console.error(error,info);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.hasError){
|
||||||
|
// You can render any custom fallback UI
|
||||||
|
return <p className="grey-text">Failed to render</p>;
|
||||||
|
}
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
import { hashHistory } from 'react-router'
|
||||||
import { bindActionCreators } from 'redux'
|
import { bindActionCreators } from 'redux'
|
||||||
|
|
||||||
import Dropzone from './Dropzone'
|
import Dropzone from './Dropzone'
|
||||||
@ -57,7 +58,8 @@ class Dropzones extends React.Component{
|
|||||||
break
|
break
|
||||||
|
|
||||||
case 'add_to_playlist':
|
case 'add_to_playlist':
|
||||||
this.props.uiActions.openModal('add_to_playlist',{tracks_uris: uris})
|
hashHistory.push(global.baseURL+'add-to-playlist/');
|
||||||
|
//uris
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export default class Notifications extends React.Component{
|
|||||||
importSpotifyAuthorization(notification_key, user, authorization){
|
importSpotifyAuthorization(notification_key, user, authorization){
|
||||||
this.props.spotifyActions.importAuthorization(user, authorization);
|
this.props.spotifyActions.importAuthorization(user, authorization);
|
||||||
this.props.uiActions.removeNotification(notification_key, true);
|
this.props.uiActions.removeNotification(notification_key, true);
|
||||||
hashHistory.push(global.baseURL+'settings/service/spotify');
|
this.props.uiActions.createNotification({content: 'Spotify authorization imported'});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNotifications(){
|
renderNotifications(){
|
||||||
|
|||||||
@ -64,7 +64,7 @@ class Services extends React.Component{
|
|||||||
var share_authorization_button = null;
|
var share_authorization_button = null;
|
||||||
if (this.props.spotify.authorization){
|
if (this.props.spotify.authorization){
|
||||||
share_authorization_button = (
|
share_authorization_button = (
|
||||||
<Link className="button" to={global.baseURL+'settings/share-authorization/send'}>
|
<Link className="button" to={global.baseURL+'settings/share-authorization'}>
|
||||||
Share authorization
|
Share authorization
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import Dater from './Dater'
|
|||||||
import URILink from './URILink'
|
import URILink from './URILink'
|
||||||
import ContextMenuTrigger from './ContextMenuTrigger'
|
import ContextMenuTrigger from './ContextMenuTrigger'
|
||||||
import Popularity from './Popularity'
|
import Popularity from './Popularity'
|
||||||
|
import ErrorBoundary from './ErrorBoundary'
|
||||||
|
|
||||||
import * as helpers from '../helpers'
|
import * as helpers from '../helpers'
|
||||||
|
|
||||||
@ -337,6 +338,7 @@ export default class Track extends React.Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
<div
|
<div
|
||||||
className={className}
|
className={className}
|
||||||
onMouseEnter={e => this.handleMouseEnter(e)}
|
onMouseEnter={e => this.handleMouseEnter(e)}
|
||||||
@ -351,6 +353,7 @@ export default class Track extends React.Component{
|
|||||||
{track_actions}
|
{track_actions}
|
||||||
{track_columns}
|
{track_columns}
|
||||||
</div>
|
</div>
|
||||||
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ import EditRadio from './views/modals/EditRadio';
|
|||||||
import AddToQueue from './views/modals/AddToQueue';
|
import AddToQueue from './views/modals/AddToQueue';
|
||||||
import InitialSetup from './views/modals/InitialSetup';
|
import InitialSetup from './views/modals/InitialSetup';
|
||||||
import KioskMode from './views/modals/KioskMode';
|
import KioskMode from './views/modals/KioskMode';
|
||||||
import ShareAuthorization_Send from './views/modals/ShareAuthorization_Send';
|
import ShareAuthorization from './views/modals/ShareAuthorization';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Hijack console error for Raven to capture
|
// Hijack console error for Raven to capture
|
||||||
@ -69,7 +69,7 @@ ReactDOM.render(
|
|||||||
<Route path="queue/add-uri" component={AddToQueue} />
|
<Route path="queue/add-uri" component={AddToQueue} />
|
||||||
<Route path="settings/debug" component={Debug} />
|
<Route path="settings/debug" component={Debug} />
|
||||||
<Route path="settings(/service/:sub_view)" component={Settings} />
|
<Route path="settings(/service/:sub_view)" component={Settings} />
|
||||||
<Route path="settings/share-authorization/send" component={ShareAuthorization_Send} />
|
<Route path="settings/share-authorization" component={ShareAuthorization} />
|
||||||
|
|
||||||
<Route path="search(/:query)" component={Search} />
|
<Route path="search(/:query)" component={Search} />
|
||||||
<Route path="album/:uri" component={Album} />
|
<Route path="album/:uri" component={Album} />
|
||||||
|
|||||||
@ -20,8 +20,8 @@ export default class AddToPlaylistModal extends React.Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
playlistSelected(playlist_uri){
|
playlistSelected(playlist_uri){
|
||||||
this.props.coreActions.addTracksToPlaylist(playlist_uri, this.props.tracks_uris )
|
this.props.coreActions.addTracksToPlaylist(playlist_uri, this.props.tracks_uris);
|
||||||
this.props.uiActions.closeModal()
|
window.history.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
|
|||||||
@ -1,53 +0,0 @@
|
|||||||
|
|
||||||
import React, { PropTypes } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Link } from 'react-router';
|
|
||||||
import { createStore, bindActionCreators } from 'redux';
|
|
||||||
|
|
||||||
import * as uiActions from '../../services/ui/actions'
|
|
||||||
import * as helpers from '../../helpers'
|
|
||||||
|
|
||||||
import Icon from '../Icon'
|
|
||||||
import Thumbnail from '../Thumbnail'
|
|
||||||
|
|
||||||
export default class extends React.Component{
|
|
||||||
|
|
||||||
constructor(props){
|
|
||||||
super(props)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleImport(e){
|
|
||||||
this.props.spotifyActions.importAuthorization(this.props.data)
|
|
||||||
this.props.uiActions.closeModal()
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
console.log(this.props.data)
|
|
||||||
if (!this.props.data || !this.props.data.user || !this.props.data.authorization){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
var user = this.props.data.user
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Spotify authorization received</h1>
|
|
||||||
<h2 className="grey-text">{user.display_name ? user.display_name : user.id} has shared their Spotify authorization with you. Importing this will overwrite your existing Spotify Authorization.</h2>
|
|
||||||
|
|
||||||
<div className="user-details">
|
|
||||||
<Thumbnail images={user.images} circle />
|
|
||||||
<h2>{user.display_name ? user.display_name : user.id}</h2>
|
|
||||||
<ul className="details">
|
|
||||||
<li>{user.id}</li>
|
|
||||||
<li>{user.followers.total} followers</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="actions centered-text">
|
|
||||||
<button className="large" onClick={e => this.props.uiActions.closeModal()}>Ignore</button>
|
|
||||||
<button className="primary large" onClick={e => this.handleImport(e)}>Import authorization</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -73,8 +73,15 @@ class EditPlaylist extends React.Component{
|
|||||||
this.setState({error: 'Name is required'})
|
this.setState({error: 'Name is required'})
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
this.props.coreActions.savePlaylist(this.props.params.uri, this.state.name, this.state.description, this.state.public, this.state.collaborative, this.state.image);
|
this.props.coreActions.savePlaylist(
|
||||||
this.props.uiActions.closeModal();
|
this.props.params.uri,
|
||||||
|
this.state.name,
|
||||||
|
this.state.description,
|
||||||
|
this.state.public,
|
||||||
|
this.state.collaborative,
|
||||||
|
this.state.image
|
||||||
|
);
|
||||||
|
window.history.back();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ class EditRadio extends React.Component{
|
|||||||
|
|
||||||
if (valid_seeds){
|
if (valid_seeds){
|
||||||
this.props.pusherActions.startRadio(this.state.seeds);
|
this.props.pusherActions.startRadio(this.state.seeds);
|
||||||
this.props.uiActions.closeModal();
|
window.history.back();
|
||||||
} else {
|
} else {
|
||||||
this.setState({error_message: "Invalid seed URI(s)"});
|
this.setState({error_message: "Invalid seed URI(s)"});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,11 +56,11 @@ class InitialSetup extends React.Component{
|
|||||||
// We've changed a connection setting, so need to reload
|
// We've changed a connection setting, so need to reload
|
||||||
if (self.state.host !== self.props.host || self.state.port !== self.props.port || self.state.ssl !== self.props.ssl){
|
if (self.state.host !== self.props.host || self.state.port !== self.props.port || self.state.ssl !== self.props.ssl){
|
||||||
|
|
||||||
window.location.reload(true);
|
window.location = global.baseURL;
|
||||||
|
|
||||||
// Safe to just close modal
|
// Safe to just close modal
|
||||||
} else {
|
} else {
|
||||||
self.props.uiActions.closeModal();
|
window.history.back();
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,10 @@ class ShareAuthorization_Send extends React.Component {
|
|||||||
super(props)
|
super(props)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount(){
|
||||||
|
this.props.uiActions.setWindowTitle("Share Spotify authorization");
|
||||||
|
}
|
||||||
|
|
||||||
handleClick(e, connection_id){
|
handleClick(e, connection_id){
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.props.pusherActions.deliverMessage(
|
this.props.pusherActions.deliverMessage(
|
||||||
@ -27,14 +31,14 @@ class ShareAuthorization_Send extends React.Component {
|
|||||||
user: this.props.me
|
user: this.props.me
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.props.uiActions.closeModal()
|
window.history.back();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderConnectionsList(){
|
renderConnectionsList(){
|
||||||
var connections = []
|
var connections = []
|
||||||
for (var connection_id in this.props.connections){
|
for (var connection_id in this.props.connections){
|
||||||
if (this.props.connections.hasOwnProperty(connection_id) && connection_id !== this.props.connection_id){
|
if (this.props.connections.hasOwnProperty(connection_id) && connection_id != this.props.connection_id){
|
||||||
connections.push(this.props.connections[connection_id])
|
connections.push(this.props.connections[connection_id])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +66,7 @@ class ShareAuthorization_Send extends React.Component {
|
|||||||
|
|
||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<Modal className="modal--share-authorization--send">
|
<Modal className="modal--share-authorization">
|
||||||
<h1>Share Spotify authentication</h1>
|
<h1>Share Spotify authentication</h1>
|
||||||
<h2 className="grey-text">Send your authentication tokens to another client. When the recipient client imports this, their Iris will have full access to your Spotify account ({this.props.me.id}).</h2>
|
<h2 className="grey-text">Send your authentication tokens to another client. When the recipient client imports this, their Iris will have full access to your Spotify account ({this.props.me.id}).</h2>
|
||||||
{this.renderConnectionsList()}
|
{this.renderConnectionsList()}
|
||||||
@ -251,24 +251,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--send-authorization {
|
&--share-authorization {
|
||||||
.list {
|
.list {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--receive-authorization {
|
.list-item {
|
||||||
.user-details {
|
cursor: pointer;
|
||||||
@include clearfix();
|
|
||||||
padding: 70px 0 0 120px;
|
|
||||||
min-height: 100px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.thumbnail {
|
|
||||||
max-width: 100px;
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
left: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user