Remaining modals; Error boundaries; Notification styles

This commit is contained in:
James Barnsley
2018-07-21 11:43:40 +12:00
parent 5f8956b376
commit 3af47a7903
17 changed files with 23207 additions and 25074 deletions

View File

@ -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

View File

@ -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

View 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;
}
}

View File

@ -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
} }
} }

View File

@ -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(){

View File

@ -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>
); );

View File

@ -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>
); );
} }
} }

View File

@ -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} />

View File

@ -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(){

View File

@ -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>
)
}
}

View File

@ -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;
} }
} }

View File

@ -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)"});
} }

View File

@ -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);

View File

@ -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()}

View File

@ -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;
} }
} }
} }