Animate closing of processes

This commit is contained in:
James Barnsley
2018-02-28 09:15:34 +13:00
parent 2a95af89de
commit 90f719c8f4
9 changed files with 50 additions and 21 deletions

View File

@ -56,7 +56,7 @@ export default class Notifications extends React.Component{
switch (process.status){
case 'running':
return(
<div className={"process notification"+(notification.closing ? ' closing' : '')} key={process.key}>
<div className={"process notification"+(process.closing ? ' closing' : '')} key={process.key}>
<div className="loader">
<div className="progress">
<div className="fill" style={{width: progress+'%'}}></div>
@ -69,7 +69,7 @@ export default class Notifications extends React.Component{
case 'cancelling':
return(
<div className={"process notification cancelling"+(notification.closing ? ' closing' : '')} key={process.key}>
<div className={"process notification cancelling"+(process.closing ? ' closing' : '')} key={process.key}>
<div className="loader"></div>
Cancelling
</div>

View File

@ -587,7 +587,7 @@ const MopidyMiddleware = (function(){
// no batches means we're done here
} else {
store.dispatch(uiActions.processFinished('MOPIDY_ENQUEUE_URIS_PROCESSOR'))
store.dispatch(uiActions.processFinishing('MOPIDY_ENQUEUE_URIS_PROCESSOR'))
break
}
@ -786,7 +786,7 @@ const MopidyMiddleware = (function(){
// No more schemes, so we're done!
} else if (!action.data.uri_scheme){
store.dispatch(uiActions.processFinished('MOPIDY_GET_SEARCH_RESULTS_PROCESSOR'))
store.dispatch(uiActions.processFinishing('MOPIDY_GET_SEARCH_RESULTS_PROCESSOR'))
return
}
@ -958,7 +958,7 @@ const MopidyMiddleware = (function(){
))
var continue_process = () => {
store.dispatch(uiActions.processFinished('MOPIDY_GET_SEARCH_RESULTS_PROCESSOR'))
store.dispatch(uiActions.processFinishing('MOPIDY_GET_SEARCH_RESULTS_PROCESSOR'))
}
instruct(socket, store, 'playlists.asList')
@ -1608,7 +1608,7 @@ const MopidyMiddleware = (function(){
))
store.dispatch(mopidyActions.getAlbums(uris_to_load, {name: 'MOPIDY_LIBRARY_ALBUMS_PROCESSOR', data: {uris: uris}}))
} else {
store.dispatch(uiActions.processFinished('MOPIDY_LIBRARY_ALBUMS_PROCESSOR'))
store.dispatch(uiActions.processFinishing('MOPIDY_LIBRARY_ALBUMS_PROCESSOR'))
}
break
@ -1793,7 +1793,7 @@ const MopidyMiddleware = (function(){
store.dispatch(uiActions.updateProcess('MOPIDY_LIBRARY_ARTISTS_PROCESSOR', 'Loading '+uris.length+' local artists', {uris: uris}));
store.dispatch(mopidyActions.getArtists(uris_to_load, {name: 'MOPIDY_LIBRARY_ARTISTS_PROCESSOR', data: {uris: uris}}));
} else {
store.dispatch(uiActions.processFinished('MOPIDY_LIBRARY_ARTISTS_PROCESSOR'));
store.dispatch(uiActions.processFinishing('MOPIDY_LIBRARY_ARTISTS_PROCESSOR'));
}
break;

View File

@ -379,13 +379,13 @@ const PusherMiddleware = (function(){
request(store, 'change_radio', data)
.then(
response => {
store.dispatch(uiActions.processFinished('PUSHER_RADIO_PROCESS'));
store.dispatch(uiActions.processFinishing('PUSHER_RADIO_PROCESS'));
if (response.status == 0){
store.dispatch(uiActions.createNotification({content: response.message, type: 'bad'}));
}
},
error => {
store.dispatch(uiActions.processFinished('PUSHER_RADIO_PROCESS'));
store.dispatch(uiActions.processFinishing('PUSHER_RADIO_PROCESS'));
store.dispatch(coreActions.handleException(
'Could not change radio',
error

View File

@ -621,7 +621,7 @@ export function getSearchResults(type, query, limit = 50, offset = 0){
});
}
dispatch(uiActions.processFinished('SPOTIFY_GET_SEARCH_RESULTS_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_SEARCH_RESULTS_PROCESSOR'))
},
error => {
dispatch(coreActions.handleException(
@ -1615,7 +1615,7 @@ export function getLibraryTracksAndPlayProcessor(data){
))
} else {
dispatch(mopidyActions.playURIs(uris, data.uri));
dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_TRACKS_AND_PLAY_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_LIBRARY_TRACKS_AND_PLAY_PROCESSOR'))
}
},
error => {
@ -1695,7 +1695,7 @@ export function getPlaylistTracksAndPlayProcessor(data){
))
} else {
dispatch(mopidyActions.playURIs(uris, data.uri))
dispatch(uiActions.processFinished('SPOTIFY_GET_PLAYLIST_TRACKS_AND_PLAY_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_PLAYLIST_TRACKS_AND_PLAY_PROCESSOR'))
}
},
error => {
@ -1870,7 +1870,7 @@ export function getLibraryPlaylistsProcessor(data){
))
dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR', {next: response.next}))
} else {
dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR'))
dispatch({type: 'SPOTIFY_LIBRARY_PLAYLISTS_LOADED_ALL'})
}
},
@ -1941,7 +1941,7 @@ export function getLibraryArtistsProcessor(data){
))
dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR', {next: response.artists.next}))
} else {
dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR'))
}
},
error => {
@ -2011,7 +2011,7 @@ export function getLibraryAlbumsProcessor(data){
))
dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR', {next: response.next}))
} else {
dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'))
dispatch(uiActions.processFinishing('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'))
}
},
error => {

View File

@ -277,6 +277,13 @@ export function processCancelled(key){
}
}
export function processFinishing(key){
return {
type: 'PROCESS_FINISHING',
key: key
}
}
export function processFinished(key){
return {
type: 'PROCESS_FINISHED',

View File

@ -158,12 +158,26 @@ const UIMiddleware = (function(){
next(action)
break
case 'PROCESS_FINISHING':
// start a timeout to remove this notification
// This gives us time to animate out the notification before we remove the data
var timeout = setTimeout(
function(){
store.dispatch(uiActions.processFinished(action.key))
},
200
)
next(action);
break;
case 'PROCESS_FINISHED':
store.dispatch({
type: action.key+'_FINISHED'
})
next(action)
break
});
next(action);
break;
// This action is irrelevant to us, pass it on to the next middleware
default:

View File

@ -170,10 +170,17 @@ export default function reducer(ui = {}, action){
}
return Object.assign({}, ui, {processes: processes})
case 'PROCESS_FINISHING':
var processes = Object.assign({}, (ui.processes ? ui.processes : {}))
if (processes[action.key]){
processes[action.key] = Object.assign({}, processes[action.key], {closing: true})
}
return Object.assign({}, ui, {processes: processes})
case 'PROCESS_FINISHED':
var processes = Object.assign({}, (ui.processes ? ui.processes : {}))
if (processes[action.key]){
processes[action.key] = Object.assign({}, processes[action.key], {status: 'finished'})
processes[action.key] = Object.assign({}, processes[action.key], {status: 'finished', closing: false})
}
return Object.assign({}, ui, {processes: processes})

View File

@ -114,7 +114,7 @@ class Debug extends React.Component{
<div className="input">
<a className="button secondary" onClick={e => this.props.uiActions.createNotification({content: 'Test notification'})}>Create notification</a>
<a className="button secondary" onClick={e => this.props.uiActions.startProcess('test_process', 'Test process', {total: 100, remaining: 17})}>Start process</a>
<a className="button secondary" onClick={e => this.props.uiActions.processFinished('test_process')}>Stop process</a>
<a className="button secondary" onClick={e => this.props.uiActions.processFinishing('test_process')}>Stop process</a>
</div>
</div>
</form>

View File

@ -71,7 +71,8 @@
background: $red;
}
&.closing {
&.closing,
&.finishing {
@include fadeout();
}