Add a ToastStore

To store toast. Rather than them being stored in the state of the
ToastContainer component, they now have a dedicated store. This mostly
fixes problems involving showing toasts when the app loaded because
we would otherwise have a race condition where something tries to
show a toast before the ToastContainer is mounted.
This commit is contained in:
David Baker 2020-01-16 20:23:47 +00:00
parent 3ed7beac78
commit 83b1505401
4 changed files with 71 additions and 31 deletions

View file

@ -1,5 +1,5 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,8 +15,8 @@ limitations under the License.
*/
import * as React from "react";
import dis from "../../dispatcher";
import { _t } from '../../languageHandler';
import ToastStore from "../../stores/ToastStore";
import classNames from "classnames";
export default class ToastContainer extends React.Component {
@ -26,26 +26,15 @@ export default class ToastContainer extends React.Component {
}
componentDidMount() {
this._dispatcherRef = dis.register(this.onAction);
ToastStore.sharedInstance().on('update', this._onToastStoreUpdate);
}
componentWillUnmount() {
dis.unregister(this._dispatcherRef);
ToastStore.sharedInstance().removeListener('update', this._onToastStoreUpdate);
}
onAction = (payload) => {
if (payload.action === "show_toast") {
this._addToast(payload.toast);
}
};
_addToast(toast) {
this.setState({toasts: this.state.toasts.concat(toast)});
}
dismissTopToast = () => {
const [, ...remaining] = this.state.toasts;
this.setState({toasts: remaining});
_onToastStoreUpdate = () => {
this.setState({toasts: ToastStore.sharedInstance().getToasts()});
};
render() {
@ -62,8 +51,8 @@ export default class ToastContainer extends React.Component {
const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null;
const toastProps = Object.assign({}, props, {
dismiss: this.dismissTopToast,
key,
toastKey: key,
});
toast = (<div className={toastClasses}>
<h2>{title}{countIndicator}</h2>