Merge pull request #5678 from matrix-org/hs/fix-usage-alerts
Fix MAU usage alerts
This commit is contained in:
commit
83078a67c2
2 changed files with 36 additions and 5 deletions
|
@ -107,7 +107,9 @@ interface IState {
|
||||||
errcode: string;
|
errcode: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
usageLimitDismissed: boolean;
|
||||||
usageLimitEventContent?: IUsageLimit;
|
usageLimitEventContent?: IUsageLimit;
|
||||||
|
usageLimitEventTs?: number;
|
||||||
useCompactLayout: boolean;
|
useCompactLayout: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +153,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
syncErrorData: undefined,
|
syncErrorData: undefined,
|
||||||
// use compact timeline view
|
// use compact timeline view
|
||||||
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
||||||
|
usageLimitDismissed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// stash the MatrixClient in case we log out before we are unmounted
|
// stash the MatrixClient in case we log out before we are unmounted
|
||||||
|
@ -302,14 +305,27 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onUsageLimitDismissed = () => {
|
||||||
|
this.setState({
|
||||||
|
usageLimitDismissed: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
|
_calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
|
||||||
const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
|
const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
|
||||||
if (error) {
|
if (error) {
|
||||||
usageLimitEventContent = syncError.error.data;
|
usageLimitEventContent = syncError.error.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usageLimitEventContent) {
|
// usageLimitDismissed is true when the user has explicitly hidden the toast
|
||||||
showServerLimitToast(usageLimitEventContent.limit_type, usageLimitEventContent.admin_contact, error);
|
// and it will be reset to false if a *new* usage alert comes in.
|
||||||
|
if (usageLimitEventContent && this.state.usageLimitDismissed) {
|
||||||
|
showServerLimitToast(
|
||||||
|
usageLimitEventContent.limit_type,
|
||||||
|
this.onUsageLimitDismissed,
|
||||||
|
usageLimitEventContent.admin_contact,
|
||||||
|
error,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
hideServerLimitToast();
|
hideServerLimitToast();
|
||||||
}
|
}
|
||||||
|
@ -320,10 +336,12 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
if (!serverNoticeList) return [];
|
if (!serverNoticeList) return [];
|
||||||
|
|
||||||
const events = [];
|
const events = [];
|
||||||
|
let pinnedEventTs = 0;
|
||||||
for (const room of serverNoticeList) {
|
for (const room of serverNoticeList) {
|
||||||
const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", "");
|
const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", "");
|
||||||
|
|
||||||
if (!pinStateEvent || !pinStateEvent.getContent().pinned) continue;
|
if (!pinStateEvent || !pinStateEvent.getContent().pinned) continue;
|
||||||
|
pinnedEventTs = pinStateEvent.getTs();
|
||||||
|
|
||||||
const pinnedEventIds = pinStateEvent.getContent().pinned.slice(0, MAX_PINNED_NOTICES_PER_ROOM);
|
const pinnedEventIds = pinStateEvent.getContent().pinned.slice(0, MAX_PINNED_NOTICES_PER_ROOM);
|
||||||
for (const eventId of pinnedEventIds) {
|
for (const eventId of pinnedEventIds) {
|
||||||
|
@ -333,6 +351,11 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pinnedEventTs && this.state.usageLimitEventTs > pinnedEventTs) {
|
||||||
|
// We've processed a newer event than this one, so ignore it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const usageLimitEvent = events.find((e) => {
|
const usageLimitEvent = events.find((e) => {
|
||||||
return (
|
return (
|
||||||
e && e.getType() === 'm.room.message' &&
|
e && e.getType() === 'm.room.message' &&
|
||||||
|
@ -341,7 +364,12 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
});
|
});
|
||||||
const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent();
|
const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent();
|
||||||
this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent);
|
this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent);
|
||||||
this.setState({ usageLimitEventContent });
|
this.setState({
|
||||||
|
usageLimitEventContent,
|
||||||
|
usageLimitEventTs: pinnedEventTs,
|
||||||
|
// This is a fresh toast, we can show toasts again
|
||||||
|
usageLimitDismissed: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onPaste = (ev) => {
|
_onPaste = (ev) => {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {messageForResourceLimitError} from "../utils/ErrorUtils";
|
||||||
|
|
||||||
const TOAST_KEY = "serverlimit";
|
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, {
|
const errorText = messageForResourceLimitError(limitType, adminContact, {
|
||||||
'monthly_active_user': _td("Your homeserver has exceeded its user limit."),
|
'monthly_active_user': _td("Your homeserver has exceeded its user limit."),
|
||||||
'': _td("Your homeserver has exceeded one of its resource limits."),
|
'': _td("Your homeserver has exceeded one of its resource limits."),
|
||||||
|
@ -38,7 +38,10 @@ export const showToast = (limitType: string, adminContact?: string, syncError?:
|
||||||
props: {
|
props: {
|
||||||
description: <React.Fragment>{errorText} {contactText}</React.Fragment>,
|
description: <React.Fragment>{errorText} {contactText}</React.Fragment>,
|
||||||
acceptLabel: _t("Ok"),
|
acceptLabel: _t("Ok"),
|
||||||
onAccept: hideToast,
|
onAccept: () => {
|
||||||
|
hideToast()
|
||||||
|
if (onHideToast) onHideToast();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
component: GenericToast,
|
component: GenericToast,
|
||||||
priority: 70,
|
priority: 70,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue