Migrate SnackStore to mobx

This commit is contained in:
Jannis Mattheis 2018-10-21 12:36:16 +02:00
parent 8947dbb9bd
commit 9fe00bf004
3 changed files with 55 additions and 62 deletions

View File

@ -2,44 +2,37 @@ import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar'; import Snackbar from '@material-ui/core/Snackbar';
import Close from '@material-ui/icons/Close'; import Close from '@material-ui/icons/Close';
import React, {Component} from 'react'; 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 { @observer
current: string; class SnackBarHandler extends Component {
hasNext: boolean;
open: boolean;
openWhen: number;
}
class SnackBarHandler extends Component<{}, IState> {
private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000; private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000;
private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000; private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000;
public state = { @observable
current: '', private open = false;
hasNext: false, @observable
open: false, private openWhen = 0;
openWhen: 0,
};
public componentWillMount() { private dispose: () => void = () => {};
SnackBarStore.on('change', this.onNewSnack);
}
public componentWillUnmount() { public componentDidMount = () =>
SnackBarStore.removeListener('change', this.onNewSnack); (this.dispose = reaction(() => SnackManager.counter, this.onNewSnack));
}
public componentWillUnmount = () => this.dispose();
public render() { public render() {
const {open, current, hasNext} = this.state; const {message: current, hasNext} = SnackManager;
const duration = hasNext const duration = hasNext()
? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS ? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS
: SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS; : SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS;
return ( return (
<Snackbar <Snackbar
anchorOrigin={{vertical: 'bottom', horizontal: 'left'}} anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}
open={open} open={this.open}
autoHideDuration={duration} autoHideDuration={duration}
onClose={this.closeCurrentSnack} onClose={this.closeCurrentSnack}
onExited={this.openNextSnack} onExited={this.openNextSnack}
@ -58,7 +51,7 @@ class SnackBarHandler extends Component<{}, IState> {
} }
private onNewSnack = () => { private onNewSnack = () => {
const {open, openWhen} = this.state; const {open, openWhen} = this;
if (!open) { if (!open) {
this.openNextSnack(); this.openNextSnack();
@ -77,18 +70,14 @@ class SnackBarHandler extends Component<{}, IState> {
}; };
private openNextSnack = () => { private openNextSnack = () => {
if (SnackBarStore.hasNext()) { if (SnackManager.hasNext()) {
this.setState({ this.open = true;
...this.state, this.openWhen = Date.now();
open: true, SnackManager.next();
openWhen: Date.now(),
current: SnackBarStore.next(),
hasNext: SnackBarStore.hasNext(),
});
} }
}; };
private closeCurrentSnack = () => this.setState({...this.state, open: false}); private closeCurrentSnack = () => (this.open = false);
} }
export default SnackBarHandler; export default SnackBarHandler;

View File

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

View File

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