mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-11-01 02:43:35 +08:00 
			
		
		
		
	feature (notification): proper notification system
This commit is contained in:
		| @ -1,68 +1,107 @@ | ||||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; | ||||
|  | ||||
| import { NgIf } from './'; | ||||
| import { notify } from '../helpers/'; | ||||
| import './notification.scss'; | ||||
|  | ||||
| export class Notification extends React.Component { | ||||
|     constructor(props){ | ||||
|         super(props); | ||||
|         this.state = { | ||||
|             visible: null, | ||||
|             error: null, | ||||
|             timeout: null | ||||
|             appear: false, | ||||
|             message_text: null, | ||||
|             message_type: null | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     componentWillMount(){ | ||||
|         this.componentWillReceiveProps(this.props); | ||||
|     } | ||||
|         function TaskManager(){ | ||||
|             let jobs = []; | ||||
|             let is_running = false; | ||||
|  | ||||
|     componentWillUnmount(){ | ||||
|         window.clearTimeout(this.timeout); | ||||
|     } | ||||
|  | ||||
|     componentWillReceiveProps(props){ | ||||
|         if(props.error !== null){ | ||||
|             this.componentWillUnmount(); | ||||
|             this.setState({visible: true, error: props.error}); | ||||
|             this.timeout = window.setTimeout(() => { | ||||
|                 this.setState({visible: null}); | ||||
|             }, 5000); | ||||
|             const ret = { | ||||
|                 addJob: (job) => { | ||||
|                     jobs.push(job); | ||||
|                     if(is_running === false){ | ||||
|                         is_running = true; | ||||
|                         ret._executor(); | ||||
|                     } | ||||
|                 }, | ||||
|                 _executor: () => { | ||||
|                     let job = jobs.shift(); | ||||
|                     if(!job){ | ||||
|                         is_running = false; | ||||
|                         return Promise.resolve(); | ||||
|                     } | ||||
|                     return job().then(ret._executor); | ||||
|                 } | ||||
|             }; | ||||
|             return ret; | ||||
|         } | ||||
|         this.runner = new TaskManager(); | ||||
|     } | ||||
|  | ||||
|     toggleVisibility(){ | ||||
|         this.setState({visible: !this.state.visible}); | ||||
|     } | ||||
|  | ||||
|     formatError(err){ | ||||
|         if(typeof err === 'object'){ | ||||
|             if(err && err.message){ | ||||
|                 return err.message; | ||||
|             }else{ | ||||
|                 return JSON.stringify(err); | ||||
|     componentDidMount(){ | ||||
|         notify.subscribe((_message, type) => { | ||||
|             let job = playMessage.bind(this, { | ||||
|                 text: stringify(_message), | ||||
|                 type: type | ||||
|             }); | ||||
|             this.runner.addJob(job); | ||||
|         }); | ||||
|         function stringify(data){ | ||||
|             if(typeof data === 'object' && data.message){ | ||||
|                 return data.message; | ||||
|             }else if(typeof data === 'string'){ | ||||
|                 return data; | ||||
|             } | ||||
|         }else if(typeof err === 'string'){ | ||||
|             return err; | ||||
|         }else{ | ||||
|             throw('unrecognized notification'); | ||||
|             return JSON.stringify(data); | ||||
|         } | ||||
|         function playMessage(message){ | ||||
|             const displayMessage = (message) => { | ||||
|                 this.setState({ | ||||
|                     appear: true, | ||||
|                     message_text: message.text, | ||||
|                     message_type: message.type | ||||
|                 }); | ||||
|                 return Promise.resolve(message); | ||||
|             }; | ||||
|             const waitForABit = (timeout, message) => { | ||||
|                 return new Promise((done, err) => { | ||||
|                     window.setTimeout(() => { | ||||
|                         done(message); | ||||
|                     }, timeout); | ||||
|                 }); | ||||
|             }; | ||||
|             const hideMessage = (message) => { | ||||
|                 this.setState({ | ||||
|                     appear: false | ||||
|                 }); | ||||
|                 return Promise.resolve(message); | ||||
|             }; | ||||
|  | ||||
|             return displayMessage(message) | ||||
|                 .then(waitForABit.bind(this, 5000)) | ||||
|                 .then(hideMessage) | ||||
|                 .then(waitForABit.bind(this, 1000)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     close(){ | ||||
|         this.setState({ appear: false }); | ||||
|     } | ||||
|  | ||||
|     render(){ | ||||
|         return ( | ||||
|             <NgIf cond={this.state.visible === true}> | ||||
|               <div className="component_notification"> | ||||
|                 <div onClick={this.toggleVisibility.bind(this)}> | ||||
|                   {this.formatError(this.state.error)} | ||||
|             <NgIf cond={this.state.appear === true} className="component_notification no-select"> | ||||
|               <ReactCSSTransitionGroup transitionName="notification" transitionLeave={true} transitionLeaveTimeout={200} transitionEnter={true} transitionEnterTimeout={500}> | ||||
|                 <div className={"component_notification--container "+(this.state.message_type || 'info')}> | ||||
|                   <div className="message"> | ||||
|                     { this.state.message_text } | ||||
|                   </div> | ||||
|                   <div className="close" onClick={this.close.bind(this)}>X</div> | ||||
|                 </div> | ||||
|               </div> | ||||
|               </ReactCSSTransitionGroup> | ||||
|             </NgIf> | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| Notification.propTypes = { | ||||
|     error: PropTypes.any | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Mickael KERJEAN
					Mickael KERJEAN