From 0daed986275b34287a9ef8383f500cf07b93b093 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 12:51:17 +0000 Subject: [PATCH 1/5] Do not process an older usage event if we've already processed a newer one --- src/components/structures/LoggedInView.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index c76cd7cee7..77c846d816 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -108,6 +108,7 @@ interface IState { }; }; usageLimitEventContent?: IUsageLimit; + usageLimitEventTs?: number; useCompactLayout: boolean; } @@ -339,9 +340,18 @@ class LoggedInView extends React.Component { e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' ); }); + if (this.state.usageLimitEventTs > usageLimitEvent.getTs()) { + // We've processed a newer event than this one, so ignore it. + return; + } const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent(); this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent); - this.setState({ usageLimitEventContent }); + this.setState({ + usageLimitEventContent, + usageLimitEventTs: usageLimitEvent.getTs(), + // This is a fresh toast, we can show toasts again + usageLimitDismissed: false, + }); }; _onPaste = (ev) => { From aa86c1d751087d0f49b624bbc3fc82589d6e69ac Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 12:51:47 +0000 Subject: [PATCH 2/5] Ensure that a dismissed usage alert toast stays dismissed --- src/components/structures/LoggedInView.tsx | 19 +++++++++++++++++-- src/toasts/ServerLimitToast.tsx | 7 +++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 77c846d816..60969e3220 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -107,6 +107,7 @@ interface IState { errcode: string; }; }; + usageLimitDismissed: boolean; usageLimitEventContent?: IUsageLimit; usageLimitEventTs?: number; useCompactLayout: boolean; @@ -152,6 +153,7 @@ class LoggedInView extends React.Component { syncErrorData: undefined, // use compact timeline view useCompactLayout: SettingsStore.getValue('useCompactLayout'), + usageLimitDismissed: false, }; // stash the MatrixClient in case we log out before we are unmounted @@ -303,14 +305,27 @@ class LoggedInView extends React.Component { } }; + _onHideToast = () => { + this.setState({ + usageLimitDismissed: true, + }); + } + _calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) { const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED"; if (error) { usageLimitEventContent = syncError.error.data; } - if (usageLimitEventContent) { - showServerLimitToast(usageLimitEventContent.limit_type, usageLimitEventContent.admin_contact, error); + // usageLimitDismissed is true when the user has explicitly hidden the toast + // and it will be reset to false if a *new* usage alert comes in. + if (usageLimitEventContent && this.state.usageLimitDismissed) { + showServerLimitToast( + usageLimitEventContent.limit_type, + this._onHideToast, + usageLimitEventContent.admin_contact, + error, + ); } else { hideServerLimitToast(); } diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index d35140be3d..068d62f9ea 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -23,7 +23,7 @@ import {messageForResourceLimitError} from "../utils/ErrorUtils"; const TOAST_KEY = "serverlimit"; -export const showToast = (limitType: string, adminContact?: string, syncError?: boolean) => { +export const showToast = (limitType: string, onHideToast: () => void, adminContact?: string, syncError?: boolean) => { const errorText = messageForResourceLimitError(limitType, adminContact, { 'monthly_active_user': _td("Your homeserver has exceeded its user limit."), '': _td("Your homeserver has exceeded one of its resource limits."), @@ -38,7 +38,10 @@ export const showToast = (limitType: string, adminContact?: string, syncError?: props: { description: {errorText} {contactText}, acceptLabel: _t("Ok"), - onAccept: hideToast, + onAccept: () => { + hideToast() + onHideToast() + }, }, component: GenericToast, priority: 70, From 84bcdf66f2a02f0fa779a5e80646b5e108614439 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 13:00:05 +0000 Subject: [PATCH 3/5] Fix TS check --- src/components/structures/LoggedInView.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 60969e3220..f3cce3ef34 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -336,10 +336,12 @@ class LoggedInView extends React.Component { if (!serverNoticeList) return []; const events = []; + let pinnedEventTs = 0; for (const room of serverNoticeList) { const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", ""); if (!pinStateEvent || !pinStateEvent.getContent().pinned) continue; + pinnedEventTs = pinStateEvent.getTs(); const pinnedEventIds = pinStateEvent.getContent().pinned.slice(0, MAX_PINNED_NOTICES_PER_ROOM); for (const eventId of pinnedEventIds) { @@ -349,21 +351,22 @@ class LoggedInView extends React.Component { } } + if (pinnedEventTs && this.state.usageLimitEventTs > pinnedEventTs) { + // We've processed a newer event than this one, so ignore it. + return; + } + const usageLimitEvent = events.find((e) => { return ( e && e.getType() === 'm.room.message' && e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' ); }); - if (this.state.usageLimitEventTs > usageLimitEvent.getTs()) { - // We've processed a newer event than this one, so ignore it. - return; - } const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent(); this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent); this.setState({ usageLimitEventContent, - usageLimitEventTs: usageLimitEvent.getTs(), + usageLimitEventTs: pinnedEventTs, // This is a fresh toast, we can show toasts again usageLimitDismissed: false, }); From c78d1c49abc6b278f16e289681ed61a7d3f5dd0e Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Feb 2021 17:32:00 +0000 Subject: [PATCH 4/5] Apply changes from review --- src/components/structures/LoggedInView.tsx | 4 ++-- src/toasts/ServerLimitToast.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index f3cce3ef34..c01214f3f4 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -305,7 +305,7 @@ class LoggedInView extends React.Component { } }; - _onHideToast = () => { + private onUsageLimitDismissed = () => { this.setState({ usageLimitDismissed: true, }); @@ -322,7 +322,7 @@ class LoggedInView extends React.Component { if (usageLimitEventContent && this.state.usageLimitDismissed) { showServerLimitToast( usageLimitEventContent.limit_type, - this._onHideToast, + this.onUsageLimitDismissed, usageLimitEventContent.admin_contact, error, ); diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index 068d62f9ea..28c0ec9598 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -40,7 +40,7 @@ export const showToast = (limitType: string, onHideToast: () => void, adminConta acceptLabel: _t("Ok"), onAccept: () => { hideToast() - onHideToast() + if (onHideToast) { onHideToast() } }, }, component: GenericToast, From c11c8c2fafc23564e9cacbfc947e941e341b3cc3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 24 Feb 2021 11:20:58 -0700 Subject: [PATCH 5/5] Update src/toasts/ServerLimitToast.tsx --- src/toasts/ServerLimitToast.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index 28c0ec9598..81b5492402 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -40,7 +40,7 @@ export const showToast = (limitType: string, onHideToast: () => void, adminConta acceptLabel: _t("Ok"), onAccept: () => { hideToast() - if (onHideToast) { onHideToast() } + if (onHideToast) onHideToast(); }, }, component: GenericToast,