mirror of
https://github.com/element-hq/element-web
synced 2024-11-22 17:25:50 +03:00
Warning bar for MAU limit hit
Somewhat untested, sorry
This commit is contained in:
parent
f44cc8e66e
commit
6593ee09d1
6 changed files with 115 additions and 6 deletions
|
@ -28,6 +28,12 @@ limitations under the License.
|
|||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_info {
|
||||
padding-left: 16px;
|
||||
padding-right: 8px;
|
||||
background-color: $info-bg-color;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_error {
|
||||
padding-left: 16px;
|
||||
padding-right: 8px;
|
||||
|
|
|
@ -20,6 +20,7 @@ $focus-brightness: 200%;
|
|||
// red warning colour
|
||||
$warning-color: #ff0064;
|
||||
$warning-bg-color: #DF2A8B;
|
||||
$info-bg-color: #2A9EDF;
|
||||
|
||||
// groups
|
||||
$info-plinth-bg-color: #454545;
|
||||
|
|
|
@ -27,6 +27,7 @@ $focus-brightness: 125%;
|
|||
$warning-color: #ff0064;
|
||||
// background colour for warnings
|
||||
$warning-bg-color: #DF2A8B;
|
||||
$info-bg-color: #2A9EDF;
|
||||
$mention-user-pill-bg-color: #ff0064;
|
||||
$other-user-pill-bg-color: rgba(0, 0, 0, 0.1);
|
||||
|
||||
|
|
|
@ -30,10 +30,16 @@ import dis from '../../dispatcher';
|
|||
import sessionStore from '../../stores/SessionStore';
|
||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import RoomListStore from "../../stores/RoomListStore";
|
||||
|
||||
import TagOrderActions from '../../actions/TagOrderActions';
|
||||
import RoomListActions from '../../actions/RoomListActions';
|
||||
|
||||
// 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.
|
||||
// NB. this is just for server notices rather than pinned messages in general.
|
||||
const MAX_PINNED_NOTICES_PER_ROOM = 2;
|
||||
|
||||
/**
|
||||
* This is what our MatrixChat shows when we are logged in. The precise view is
|
||||
* determined by the page_type property.
|
||||
|
@ -80,6 +86,8 @@ const LoggedInView = React.createClass({
|
|||
return {
|
||||
// use compact timeline view
|
||||
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
||||
// any currently active server notice events
|
||||
serverNoticeEvents: [],
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -97,13 +105,18 @@ const LoggedInView = React.createClass({
|
|||
);
|
||||
this._setStateFromSessionStore();
|
||||
|
||||
this._updateServerNoticeEvents();
|
||||
|
||||
this._matrixClient.on("accountData", this.onAccountData);
|
||||
this._matrixClient.on("sync", this.onSync);
|
||||
this._matrixClient.on("RoomState.events", this.onRoomStateEvents);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
document.removeEventListener('keydown', this._onKeyDown);
|
||||
this._matrixClient.removeListener("accountData", this.onAccountData);
|
||||
this._matrixClient.removeListener("sync", this.onSync);
|
||||
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
|
||||
if (this._sessionStoreToken) {
|
||||
this._sessionStoreToken.remove();
|
||||
}
|
||||
|
@ -157,8 +170,42 @@ const LoggedInView = React.createClass({
|
|||
syncErrorData: null,
|
||||
});
|
||||
}
|
||||
|
||||
if (oldSyncState === 'PREPARED' && syncState === 'SYNCING') {
|
||||
this._updateServerNoticeEvents();
|
||||
}
|
||||
},
|
||||
|
||||
onRoomStateEvents: function(ev, state) {
|
||||
const roomLists = RoomListStore.getRoomLists();
|
||||
if (roomLists['m.server_notices'] && roomLists['m.server_notices'].includes(ev.getRoomId())) {
|
||||
this._updateServerNoticeEvents();
|
||||
}
|
||||
},
|
||||
|
||||
_updateServerNoticeEvents: async function() {
|
||||
const roomLists = RoomListStore.getRoomLists();
|
||||
if (!roomLists['m.server_notice']) return [];
|
||||
|
||||
const pinnedEvents = [];
|
||||
for (const room of roomLists['m.server_notice']) {
|
||||
const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", "");
|
||||
|
||||
if (!pinStateEvent || !pinStateEvent.getContent().pinned) continue;
|
||||
|
||||
const pinnedEventIds = pinStateEvent.getContent().pinned.slice(0, MAX_PINNED_NOTICES_PER_ROOM);
|
||||
for (const eventId of pinnedEventIds) {
|
||||
const timeline = await this._matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId, 0);
|
||||
const ev = timeline.getEvents().find(ev => ev.getId() === eventId);
|
||||
if (ev) pinnedEvents.push(ev);
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
serverNoticeEvents: pinnedEvents,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
_onKeyDown: function(ev) {
|
||||
/*
|
||||
// Remove this for now as ctrl+alt = alt-gr so this breaks keyboards which rely on alt-gr for numbers
|
||||
|
@ -386,10 +433,18 @@ const LoggedInView = React.createClass({
|
|||
break;
|
||||
}
|
||||
|
||||
const mauLimitEvent = this.state.serverNoticeEvents.find((e) => {
|
||||
return e && e.getType() === 'm.server_notice.usage_limit_reached' &&
|
||||
e.getContent().limit &&
|
||||
e.getContent().limit === 'monthly_active_user'
|
||||
});
|
||||
|
||||
let topBar;
|
||||
const isGuest = this.props.matrixClient.isGuest();
|
||||
if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_MAU_LIMIT_EXCEEDED') {
|
||||
topBar = <ServerLimitBar />;
|
||||
topBar = <ServerLimitBar kind='hard' />;
|
||||
} else if (mauLimitEvent) {
|
||||
topBar = <ServerLimitBar kind='soft' adminContact={mauLimitEvent.getContent().admin_contact} />;
|
||||
} else if (this.props.showCookieBar &&
|
||||
this.props.config.piwik
|
||||
) {
|
||||
|
|
|
@ -15,15 +15,60 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
export default React.createClass({
|
||||
propTypes: {
|
||||
// 'hard' if the logged in user has been locked out, 'soft' if they haven't
|
||||
kind: PropTypes.string,
|
||||
adminContent: PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
kind: 'hard',
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const toolbarClasses = "mx_MatrixToolbar mx_MatrixToolbar_error";
|
||||
const toolbarClasses = {
|
||||
'mx_MatrixToolbar': true,
|
||||
};
|
||||
let content;
|
||||
|
||||
const translateLink = (sub) => {
|
||||
if (this.props.adminContent) {
|
||||
return <a href={this.props.adminContent}>{sub}</a>;
|
||||
} else {
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.props.kind === 'hard') {
|
||||
toolbarClasses['mx_MatrixToolbar_error'] = true;
|
||||
content = _t(
|
||||
"This homeserver has hit its Monthly Active User limit. Please <a>contact your service administrator</a> to continue using the service.",
|
||||
{},
|
||||
{
|
||||
'a': translateLink,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
toolbarClasses['mx_MatrixToolbar_info'] = true;
|
||||
content = _t(
|
||||
"This homeserver has hit its Monthly Active User limit so some users will not be able to log in. Please <a>contact your service administrator</a> to get this limit increased.",
|
||||
{},
|
||||
{
|
||||
'a': translateLink,
|
||||
},
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className={toolbarClasses}>
|
||||
<div className={classNames(toolbarClasses)}>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
{ _t("This homeserver has hit its Monthly Active User limit. Please contact your service administrator to continue using the service.") }
|
||||
{ content }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -464,9 +464,9 @@
|
|||
"People": "People",
|
||||
"Rooms": "Rooms",
|
||||
"Low priority": "Low priority",
|
||||
"System Alerts": "System Alerts",
|
||||
"You have no historical rooms": "You have no historical rooms",
|
||||
"Historical": "Historical",
|
||||
"System Alerts": "System Alerts",
|
||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.",
|
||||
"This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:",
|
||||
"You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.",
|
||||
|
@ -678,7 +678,8 @@
|
|||
"A new version of Riot is available.": "A new version of Riot is available.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>",
|
||||
"Set Password": "Set Password",
|
||||
"This homeserver has hit its Monthly Active User limit. Please contact your service administrator to continue using the service.": "This homeserver has hit its Monthly Active User limit. Please contact your service administrator to continue using the service.",
|
||||
"This homeserver has hit its Monthly Active User limit. Please <a>contact your service administrator</a> to continue using the service.": "This homeserver has hit its Monthly Active User limit. Please <a>contact your service administrator</a> to continue using the service.",
|
||||
"This homeserver has hit its Monthly Active User limit so some users will not be able to log in. Please <a>contact your service administrator</a> to get this limit increased.": "This homeserver has hit its Monthly Active User limit so some users will not be able to log in. Please <a>contact your service administrator</a> to get this limit increased.",
|
||||
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
|
||||
"Checking for an update...": "Checking for an update...",
|
||||
"No update available.": "No update available.",
|
||||
|
|
Loading…
Reference in a new issue