Migrate Server Limit Bar Banner to a Toast
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
5d0040b8b3
commit
ccf9e65123
3 changed files with 80 additions and 125 deletions
|
@ -47,6 +47,10 @@ import {
|
||||||
showToast as showSetPasswordToast,
|
showToast as showSetPasswordToast,
|
||||||
hideToast as hideSetPasswordToast
|
hideToast as hideSetPasswordToast
|
||||||
} from "../../toasts/SetPasswordToast";
|
} from "../../toasts/SetPasswordToast";
|
||||||
|
import {
|
||||||
|
showToast as showServerLimitToast,
|
||||||
|
hideToast as hideServerLimitToast
|
||||||
|
} from "../../toasts/ServerLimitToast";
|
||||||
|
|
||||||
// We need to fetch each pinned message individually (if we don't already have it)
|
// We need to fetch each pinned message individually (if we don't already have it)
|
||||||
// so each pinned message may trigger a request. Limit the number per room for sanity.
|
// so each pinned message may trigger a request. Limit the number per room for sanity.
|
||||||
|
@ -99,7 +103,6 @@ interface IState {
|
||||||
};
|
};
|
||||||
syncErrorData: any;
|
syncErrorData: any;
|
||||||
useCompactLayout: boolean;
|
useCompactLayout: boolean;
|
||||||
serverNoticeEvents: MatrixEvent[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,8 +147,6 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
syncErrorData: undefined,
|
syncErrorData: undefined,
|
||||||
// use compact timeline view
|
// use compact timeline view
|
||||||
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
||||||
// any currently active server notice events
|
|
||||||
serverNoticeEvents: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// stash the MatrixClient in case we log out before we are unmounted
|
// stash the MatrixClient in case we log out before we are unmounted
|
||||||
|
@ -293,6 +294,8 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
if (oldSyncState === 'PREPARED' && syncState === 'SYNCING') {
|
if (oldSyncState === 'PREPARED' && syncState === 'SYNCING') {
|
||||||
this._updateServerNoticeEvents();
|
this._updateServerNoticeEvents();
|
||||||
|
} else {
|
||||||
|
this._calculateServerLimitToast(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -303,11 +306,24 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_calculateServerLimitToast(syncErrorData, usageLimitEventContent?) {
|
||||||
|
const error = syncErrorData && syncErrorData.error && syncErrorData.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
|
||||||
|
if (error) {
|
||||||
|
usageLimitEventContent = syncErrorData.error.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usageLimitEventContent) {
|
||||||
|
showServerLimitToast(usageLimitEventContent.limit_type, usageLimitEventContent.admin_contact, error);
|
||||||
|
} else {
|
||||||
|
hideServerLimitToast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_updateServerNoticeEvents = async () => {
|
_updateServerNoticeEvents = async () => {
|
||||||
const roomLists = RoomListStoreTempProxy.getRoomLists();
|
const roomLists = RoomListStoreTempProxy.getRoomLists();
|
||||||
if (!roomLists[DefaultTagID.ServerNotice]) return [];
|
if (!roomLists[DefaultTagID.ServerNotice]) return [];
|
||||||
|
|
||||||
const pinnedEvents = [];
|
const events = [];
|
||||||
for (const room of roomLists[DefaultTagID.ServerNotice]) {
|
for (const room of roomLists[DefaultTagID.ServerNotice]) {
|
||||||
const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", "");
|
const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", "");
|
||||||
|
|
||||||
|
@ -317,12 +333,18 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
for (const eventId of pinnedEventIds) {
|
for (const eventId of pinnedEventIds) {
|
||||||
const timeline = await this._matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId, 0);
|
const timeline = await this._matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId, 0);
|
||||||
const event = timeline.getEvents().find(ev => ev.getId() === eventId);
|
const event = timeline.getEvents().find(ev => ev.getId() === eventId);
|
||||||
if (event) pinnedEvents.push(event);
|
if (event) events.push(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
serverNoticeEvents: pinnedEvents,
|
const usageLimitEvent = events.find((e) => {
|
||||||
|
return (
|
||||||
|
e && e.getType() === 'm.room.message' &&
|
||||||
|
e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEvent && usageLimitEvent.getContent());
|
||||||
};
|
};
|
||||||
|
|
||||||
_onPaste = (ev) => {
|
_onPaste = (ev) => {
|
||||||
|
@ -600,7 +622,6 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
const ToastContainer = sdk.getComponent('structures.ToastContainer');
|
const ToastContainer = sdk.getComponent('structures.ToastContainer');
|
||||||
const NewVersionBar = sdk.getComponent('globals.NewVersionBar');
|
const NewVersionBar = sdk.getComponent('globals.NewVersionBar');
|
||||||
const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar');
|
const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar');
|
||||||
const ServerLimitBar = sdk.getComponent('globals.ServerLimitBar');
|
|
||||||
|
|
||||||
let pageElement;
|
let pageElement;
|
||||||
|
|
||||||
|
@ -644,25 +665,8 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usageLimitEvent = this.state.serverNoticeEvents.find((e) => {
|
|
||||||
return (
|
|
||||||
e && e.getType() === 'm.room.message' &&
|
|
||||||
e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let topBar;
|
let topBar;
|
||||||
if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
|
if (this.props.hasNewVersion) {
|
||||||
topBar = <ServerLimitBar kind='hard'
|
|
||||||
adminContact={this.state.syncErrorData.error.data.admin_contact}
|
|
||||||
limitType={this.state.syncErrorData.error.data.limit_type}
|
|
||||||
/>;
|
|
||||||
} else if (usageLimitEvent) {
|
|
||||||
topBar = <ServerLimitBar kind='soft'
|
|
||||||
adminContact={usageLimitEvent.getContent().admin_contact}
|
|
||||||
limitType={usageLimitEvent.getContent().limit_type}
|
|
||||||
/>;
|
|
||||||
} else if (this.props.hasNewVersion) {
|
|
||||||
topBar = <NewVersionBar version={this.props.version} newVersion={this.props.newVersion}
|
topBar = <NewVersionBar version={this.props.version} newVersion={this.props.newVersion}
|
||||||
releaseNotes={this.props.newVersionReleaseNotes}
|
releaseNotes={this.props.newVersionReleaseNotes}
|
||||||
/>;
|
/>;
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 New Vector Ltd
|
|
||||||
|
|
||||||
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 React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import createReactClass from 'create-react-class';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { _td } from '../../../languageHandler';
|
|
||||||
import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
|
|
||||||
|
|
||||||
export default createReactClass({
|
|
||||||
propTypes: {
|
|
||||||
// 'hard' if the logged in user has been locked out, 'soft' if they haven't
|
|
||||||
kind: PropTypes.string,
|
|
||||||
adminContact: PropTypes.string,
|
|
||||||
// The type of limit that has been hit.
|
|
||||||
limitType: PropTypes.string.isRequired,
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function() {
|
|
||||||
return {
|
|
||||||
kind: 'hard',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
const toolbarClasses = {
|
|
||||||
'mx_MatrixToolbar': true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let adminContact;
|
|
||||||
let limitError;
|
|
||||||
if (this.props.kind === 'hard') {
|
|
||||||
toolbarClasses['mx_MatrixToolbar_error'] = true;
|
|
||||||
|
|
||||||
adminContact = messageForResourceLimitError(
|
|
||||||
this.props.limitType,
|
|
||||||
this.props.adminContact,
|
|
||||||
{
|
|
||||||
'': _td("Please <a>contact your service administrator</a> to continue using the service."),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
limitError = messageForResourceLimitError(
|
|
||||||
this.props.limitType,
|
|
||||||
this.props.adminContact,
|
|
||||||
{
|
|
||||||
'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."),
|
|
||||||
'': _td("This homeserver has exceeded one of its resource limits."),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
toolbarClasses['mx_MatrixToolbar_info'] = true;
|
|
||||||
adminContact = messageForResourceLimitError(
|
|
||||||
this.props.limitType,
|
|
||||||
this.props.adminContact,
|
|
||||||
{
|
|
||||||
'': _td("Please <a>contact your service administrator</a> to get this limit increased."),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
limitError = messageForResourceLimitError(
|
|
||||||
this.props.limitType,
|
|
||||||
this.props.adminContact,
|
|
||||||
{
|
|
||||||
'monthly_active_user': _td(
|
|
||||||
"This homeserver has hit its Monthly Active User limit so " +
|
|
||||||
"<b>some users will not be able to log in</b>.",
|
|
||||||
),
|
|
||||||
'': _td(
|
|
||||||
"This homeserver has exceeded one of its resource limits so " +
|
|
||||||
"<b>some users will not be able to log in</b>.",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{'b': sub => <b>{sub}</b>},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className={classNames(toolbarClasses)}>
|
|
||||||
<div className="mx_MatrixToolbar_content">
|
|
||||||
{limitError}
|
|
||||||
{' '}
|
|
||||||
{adminContact}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
50
src/toasts/ServerLimitToast.tsx
Normal file
50
src/toasts/ServerLimitToast.tsx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
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 React from "react";
|
||||||
|
|
||||||
|
import { _t, _td } from "../languageHandler";
|
||||||
|
import GenericToast from "../components/views/toasts/GenericToast";
|
||||||
|
import ToastStore from "../stores/ToastStore";
|
||||||
|
import {messageForResourceLimitError} from "../utils/ErrorUtils";
|
||||||
|
|
||||||
|
const TOAST_KEY = "serverlimit";
|
||||||
|
|
||||||
|
export const showToast = (limitType: string, 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."),
|
||||||
|
});
|
||||||
|
const contactText = messageForResourceLimitError(limitType, adminContact, {
|
||||||
|
'': _td("Contact your <a>server admin</a>."),
|
||||||
|
});
|
||||||
|
|
||||||
|
ToastStore.sharedInstance().addOrReplaceToast({
|
||||||
|
key: TOAST_KEY,
|
||||||
|
title: _t("Notifications"),
|
||||||
|
props: {
|
||||||
|
description: <React.Fragment>{errorText} {contactText}</React.Fragment>,
|
||||||
|
acceptLabel: _t("Ok"),
|
||||||
|
onAccept: hideToast,
|
||||||
|
},
|
||||||
|
component: GenericToast,
|
||||||
|
priority: 20,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hideToast = () => {
|
||||||
|
ToastStore.sharedInstance().dismissToast(TOAST_KEY);
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue