diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index c59c44ebd8..978743ca87 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -64,6 +64,7 @@ import { ThemeWatcher } from "../../theme";
import { storeRoomAliasInCache } from '../../RoomAliasCache';
import { defer } from "../../utils/promise";
import KeyVerificationStateObserver from '../../utils/KeyVerificationStateObserver';
+import ToastStore from "../../stores/ToastStore";
/** constants for MatrixChat.state.view */
export const VIEWS = {
@@ -1458,15 +1459,12 @@ export default createReactClass({
}
if (!requestObserver || requestObserver.pending) {
- dis.dispatch({
- action: "show_toast",
- toast: {
- key: request.event.getId(),
- title: _t("Verification Request"),
- icon: "verification",
- props: {request, requestObserver},
- component: sdk.getComponent("toasts.VerificationRequestToast"),
- },
+ ToastStore.sharedInstance().addOrReplaceToast({
+ key: 'verifreq_' + request.event.getId(),
+ title: _t("Verification Request"),
+ icon: "verification",
+ props: {request, requestObserver},
+ component: sdk.getComponent("toasts.VerificationRequestToast"),
});
}
});
diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js
index a8dca35747..bc74133433 100644
--- a/src/components/structures/ToastContainer.js
+++ b/src/components/structures/ToastContainer.js
@@ -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 = (
{title}{countIndicator}
diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js
index 6d53c23743..18db5eae66 100644
--- a/src/components/views/toasts/VerificationRequestToast.js
+++ b/src/components/views/toasts/VerificationRequestToast.js
@@ -23,6 +23,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg';
import {verificationMethods} from 'matrix-js-sdk/src/crypto';
import KeyVerificationStateObserver, {userLabelForEventRoom} from "../../../utils/KeyVerificationStateObserver";
import dis from "../../../dispatcher";
+import ToastStore from "../../../stores/ToastStore";
export default class VerificationRequestToast extends React.PureComponent {
constructor(props) {
@@ -63,12 +64,12 @@ export default class VerificationRequestToast extends React.PureComponent {
_checkRequestIsPending = () => {
if (!this.props.requestObserver.pending) {
- this.props.dismiss();
+ ToastStore.sharedInstance().dismissToast(this.props.toastKey);
}
}
cancel = () => {
- this.props.dismiss();
+ ToastStore.sharedInstance().dismissToast(this.props.toastKey);
try {
this.props.request.cancel();
} catch (err) {
@@ -77,7 +78,7 @@ export default class VerificationRequestToast extends React.PureComponent {
}
accept = () => {
- this.props.dismiss();
+ ToastStore.sharedInstance().dismissToast(this.props.toastKey);
const {event} = this.props.request;
// no room id for to_device requests
if (event.getRoomId()) {
@@ -119,7 +120,7 @@ export default class VerificationRequestToast extends React.PureComponent {
}
VerificationRequestToast.propTypes = {
- dismiss: PropTypes.func.isRequired,
request: PropTypes.object.isRequired,
requestObserver: PropTypes.instanceOf(KeyVerificationStateObserver),
+ toastKey: PropTypes.string.isRequired,
};
diff --git a/src/stores/ToastStore.js b/src/stores/ToastStore.js
new file mode 100644
index 0000000000..f6cc30db67
--- /dev/null
+++ b/src/stores/ToastStore.js
@@ -0,0 +1,52 @@
+/*
+Copyright 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.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import EventEmitter from 'events';
+
+/**
+ * Holds the active toasts
+ */
+export default class ToastStore extends EventEmitter {
+ static sharedInstance() {
+ if (!global.mx_ToastStore) global.mx_ToastStore = new ToastStore();
+ return global.mx_ToastStore;
+ }
+
+ constructor() {
+ super();
+ this._dispatcherRef = null;
+ this._toasts = [];
+ }
+
+ addOrReplaceToast(newToast) {
+ const oldIndex = this._toasts.findIndex(t => t.key === newToast.key);
+ if (oldIndex === -1) {
+ this._toasts.push(newToast);
+ } else {
+ this._toasts[oldIndex] = newToast;
+ }
+ this.emit('update');
+ }
+
+ dismissToast(key) {
+ this._toasts = this._toasts.filter(t => t.key !== key);
+ this.emit('update');
+ }
+
+ getToasts() {
+ return this._toasts;
+ }
+}