Migrate SnackStore to mobx
This commit is contained in:
parent
8947dbb9bd
commit
9fe00bf004
|
|
@ -2,44 +2,37 @@ import IconButton from '@material-ui/core/IconButton';
|
|||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import Close from '@material-ui/icons/Close';
|
||||
import React, {Component} from 'react';
|
||||
import SnackBarStore from '../stores/SnackBarStore';
|
||||
import {observable, reaction} from 'mobx';
|
||||
import {observer} from 'mobx-react';
|
||||
import SnackManager from '../stores/SnackManager';
|
||||
|
||||
interface IState {
|
||||
current: string;
|
||||
hasNext: boolean;
|
||||
open: boolean;
|
||||
openWhen: number;
|
||||
}
|
||||
|
||||
class SnackBarHandler extends Component<{}, IState> {
|
||||
@observer
|
||||
class SnackBarHandler extends Component {
|
||||
private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000;
|
||||
private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000;
|
||||
|
||||
public state = {
|
||||
current: '',
|
||||
hasNext: false,
|
||||
open: false,
|
||||
openWhen: 0,
|
||||
};
|
||||
@observable
|
||||
private open = false;
|
||||
@observable
|
||||
private openWhen = 0;
|
||||
|
||||
public componentWillMount() {
|
||||
SnackBarStore.on('change', this.onNewSnack);
|
||||
}
|
||||
private dispose: () => void = () => {};
|
||||
|
||||
public componentWillUnmount() {
|
||||
SnackBarStore.removeListener('change', this.onNewSnack);
|
||||
}
|
||||
public componentDidMount = () =>
|
||||
(this.dispose = reaction(() => SnackManager.counter, this.onNewSnack));
|
||||
|
||||
public componentWillUnmount = () => this.dispose();
|
||||
|
||||
public render() {
|
||||
const {open, current, hasNext} = this.state;
|
||||
const duration = hasNext
|
||||
const {message: current, hasNext} = SnackManager;
|
||||
const duration = hasNext()
|
||||
? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS
|
||||
: SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS;
|
||||
|
||||
return (
|
||||
<Snackbar
|
||||
anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}
|
||||
open={open}
|
||||
open={this.open}
|
||||
autoHideDuration={duration}
|
||||
onClose={this.closeCurrentSnack}
|
||||
onExited={this.openNextSnack}
|
||||
|
|
@ -58,7 +51,7 @@ class SnackBarHandler extends Component<{}, IState> {
|
|||
}
|
||||
|
||||
private onNewSnack = () => {
|
||||
const {open, openWhen} = this.state;
|
||||
const {open, openWhen} = this;
|
||||
|
||||
if (!open) {
|
||||
this.openNextSnack();
|
||||
|
|
@ -77,18 +70,14 @@ class SnackBarHandler extends Component<{}, IState> {
|
|||
};
|
||||
|
||||
private openNextSnack = () => {
|
||||
if (SnackBarStore.hasNext()) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
open: true,
|
||||
openWhen: Date.now(),
|
||||
current: SnackBarStore.next(),
|
||||
hasNext: SnackBarStore.hasNext(),
|
||||
});
|
||||
if (SnackManager.hasNext()) {
|
||||
this.open = true;
|
||||
this.openWhen = Date.now();
|
||||
SnackManager.next();
|
||||
}
|
||||
};
|
||||
|
||||
private closeCurrentSnack = () => this.setState({...this.state, open: false});
|
||||
private closeCurrentSnack = () => (this.open = false);
|
||||
}
|
||||
|
||||
export default SnackBarHandler;
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
import {EventEmitter} from 'events';
|
||||
import dispatcher, {IEvent} from './dispatcher';
|
||||
|
||||
class SnackBarStore extends EventEmitter {
|
||||
public messages: string[] = [];
|
||||
|
||||
public next(): string {
|
||||
if (!this.hasNext()) {
|
||||
throw new Error('no such element');
|
||||
}
|
||||
return this.messages.shift() as string;
|
||||
}
|
||||
|
||||
public hasNext(): boolean {
|
||||
return this.messages.length !== 0;
|
||||
}
|
||||
|
||||
public handle(data: IEvent): void {
|
||||
if (data.type === 'SNACK') {
|
||||
this.messages.push(data.payload);
|
||||
this.emit('change');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const store = new SnackBarStore();
|
||||
dispatcher.register(store.handle.bind(store));
|
||||
export default store;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import {action, observable} from 'mobx';
|
||||
|
||||
export interface SnackReporter {
|
||||
(message: string): void;
|
||||
}
|
||||
|
||||
class SnackManager {
|
||||
@observable
|
||||
private messages: string[] = [];
|
||||
@observable
|
||||
public message: string | null;
|
||||
@observable
|
||||
public counter = 0;
|
||||
|
||||
@action
|
||||
public next = (): void => {
|
||||
if (!this.hasNext()) {
|
||||
throw new Error('There is nothing here :(');
|
||||
}
|
||||
this.message = this.messages.shift() as string;
|
||||
};
|
||||
|
||||
public hasNext = () => this.messages.length > 0;
|
||||
|
||||
@action
|
||||
public snack: SnackReporter = (message: string): void => {
|
||||
this.messages.push(message);
|
||||
this.counter++;
|
||||
};
|
||||
}
|
||||
|
||||
export default new SnackManager();
|
||||
Loading…
Reference in New Issue