Merge remote-tracking branch 'origin/develop' into bwindels/remove-composer-overlay-icons
This commit is contained in:
commit
fe1d375dd2
126 changed files with 2735 additions and 915 deletions
|
@ -210,6 +210,11 @@ const FilePanel = createReactClass({
|
|||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
const emptyState = (<div className="mx_RightPanel_empty mx_FilePanel_empty">
|
||||
<h2>{_t('No files visible in this room')}</h2>
|
||||
<p>{_t('Attach files from chat or just drag and drop them anywhere in a room.')}</p>
|
||||
</div>);
|
||||
|
||||
if (this.state.timelineSet) {
|
||||
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
||||
// "(" + this.state.timelineSet._timelines.join(", ") + ")" + " with key " + this.props.roomId);
|
||||
|
@ -223,7 +228,7 @@ const FilePanel = createReactClass({
|
|||
onPaginationRequest={this.onPaginationRequest}
|
||||
tileShape="file_grid"
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
empty={_t('There are no visible files in this room')}
|
||||
empty={emptyState}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -54,6 +54,7 @@ import LeftPanel from "./LeftPanel";
|
|||
import CallContainer from '../views/voip/CallContainer';
|
||||
import { ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||
import NonUrgentToastContainer from "./NonUrgentToastContainer";
|
||||
import { ToggleRightPanelPayload } from "../../dispatcher/payloads/ToggleRightPanelPayload";
|
||||
|
||||
// We need to fetch each pinned message individually (if we don't already have it)
|
||||
|
@ -688,6 +689,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
|||
</DragDropContext>
|
||||
</div>
|
||||
<CallContainer />
|
||||
<NonUrgentToastContainer />
|
||||
</MatrixClientContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import { getHomePageUrl } from '../../utils/pages';
|
|||
|
||||
import createRoom from "../../createRoom";
|
||||
import {_t, _td, getCurrentLanguage} from '../../languageHandler';
|
||||
import SettingsStore, { SettingLevel } from "../../settings/SettingsStore";
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import ThemeController from "../../settings/controllers/ThemeController";
|
||||
import { startAnyRegistrationFlow } from "../../Registration.js";
|
||||
import { messageForSyncError } from '../../utils/ErrorUtils';
|
||||
|
@ -75,6 +75,7 @@ import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificat
|
|||
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
|
||||
import ErrorDialog from "../views/dialogs/ErrorDialog";
|
||||
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
|
||||
import { SettingLevel } from "../../settings/SettingLevel";
|
||||
|
||||
/** constants for MatrixChat.state.view */
|
||||
export enum Views {
|
||||
|
|
63
src/components/structures/NonUrgentToastContainer.tsx
Normal file
63
src/components/structures/NonUrgentToastContainer.tsx
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
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 * as React from "react";
|
||||
import { ComponentClass } from "../../@types/common";
|
||||
import NonUrgentToastStore from "../../stores/NonUrgentToastStore";
|
||||
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
||||
|
||||
interface IProps {
|
||||
}
|
||||
|
||||
interface IState {
|
||||
toasts: ComponentClass[],
|
||||
}
|
||||
|
||||
export default class NonUrgentToastContainer extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
toasts: NonUrgentToastStore.instance.components,
|
||||
};
|
||||
|
||||
NonUrgentToastStore.instance.on(UPDATE_EVENT, this.onUpdateToasts);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
NonUrgentToastStore.instance.off(UPDATE_EVENT, this.onUpdateToasts);
|
||||
}
|
||||
|
||||
private onUpdateToasts = () => {
|
||||
this.setState({toasts: NonUrgentToastStore.instance.components});
|
||||
};
|
||||
|
||||
public render() {
|
||||
const toasts = this.state.toasts.map((t, i) => {
|
||||
return (
|
||||
<div className="mx_NonUrgentToastContainer_toast" key={`toast-${i}`}>
|
||||
{React.createElement(t, {})}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="mx_NonUrgentToastContainer" role="alert">
|
||||
{toasts}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -36,6 +36,11 @@ const NotificationPanel = createReactClass({
|
|||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
const emptyState = (<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
||||
<h2>{_t('You’re all caught up')}</h2>
|
||||
<p>{_t('You have no visible notifications in this room.')}</p>
|
||||
</div>);
|
||||
|
||||
const timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
||||
if (timelineSet) {
|
||||
return (
|
||||
|
@ -46,7 +51,7 @@ const NotificationPanel = createReactClass({
|
|||
timelineSet={timelineSet}
|
||||
showUrlPreview={false}
|
||||
tileShape="notif"
|
||||
empty={_t('You have no visible notifications')}
|
||||
empty={emptyState}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -48,7 +48,7 @@ import RightPanel from './RightPanel';
|
|||
import RoomViewStore from '../../stores/RoomViewStore';
|
||||
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
||||
import WidgetEchoStore from '../../stores/WidgetEchoStore';
|
||||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||
import RightPanelStore from "../../stores/RightPanelStore";
|
||||
import {haveTileForEvent} from "../views/rooms/EventTile";
|
||||
|
@ -56,6 +56,7 @@ import RoomContext from "../../contexts/RoomContext";
|
|||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||
import { shieldStatusForRoom } from '../../utils/ShieldUtils';
|
||||
import {Action} from "../../dispatcher/actions";
|
||||
import {SettingLevel} from "../../settings/SettingLevel";
|
||||
|
||||
const DEBUG = false;
|
||||
let debuglog = function() {};
|
||||
|
|
|
@ -26,7 +26,7 @@ import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
|
|||
import RedesignFeedbackDialog from "../views/dialogs/RedesignFeedbackDialog";
|
||||
import Modal from "../../Modal";
|
||||
import LogoutDialog from "../views/dialogs/LogoutDialog";
|
||||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import {getCustomTheme} from "../../theme";
|
||||
import {getHostingLink} from "../../utils/HostingLink";
|
||||
import {ButtonEvent} from "../views/elements/AccessibleButton";
|
||||
|
@ -37,6 +37,7 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
|||
import BaseAvatar from '../views/avatars/BaseAvatar';
|
||||
import classNames from "classnames";
|
||||
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
||||
import { SettingLevel } from "../../settings/SettingLevel";
|
||||
|
||||
interface IProps {
|
||||
isMinimized: boolean;
|
||||
|
|
|
@ -16,10 +16,11 @@ limitations under the License.
|
|||
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import {getCurrentLanguage} from "../../../languageHandler";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import PlatformPeg from "../../../PlatformPeg";
|
||||
import * as sdk from '../../../index';
|
||||
import React from 'react';
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
function onChange(newLang) {
|
||||
if (getCurrentLanguage() !== newLang) {
|
||||
|
|
|
@ -19,8 +19,8 @@ import PropTypes from 'prop-types';
|
|||
import createReactClass from 'create-react-class';
|
||||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
export default createReactClass({
|
||||
propTypes: {
|
||||
|
|
124
src/components/views/dialogs/ServerOfflineDialog.tsx
Normal file
124
src/components/views/dialogs/ServerOfflineDialog.tsx
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
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 * as React from 'react';
|
||||
import BaseDialog from './BaseDialog';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { EchoStore } from "../../../stores/local-echo/EchoStore";
|
||||
import { formatTime } from "../../../DateUtils";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { RoomEchoContext } from "../../../stores/local-echo/RoomEchoContext";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import { TransactionStatus } from "../../../stores/local-echo/EchoTransaction";
|
||||
import Spinner from "../elements/Spinner";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
interface IProps {
|
||||
onFinished: (bool) => void;
|
||||
}
|
||||
|
||||
export default class ServerOfflineDialog extends React.PureComponent<IProps> {
|
||||
public componentDidMount() {
|
||||
EchoStore.instance.on(UPDATE_EVENT, this.onEchosUpdated);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
EchoStore.instance.off(UPDATE_EVENT, this.onEchosUpdated);
|
||||
}
|
||||
|
||||
private onEchosUpdated = () => {
|
||||
this.forceUpdate(); // no state to worry about
|
||||
};
|
||||
|
||||
private renderTimeline(): React.ReactElement[] {
|
||||
return EchoStore.instance.contexts.map((c, i) => {
|
||||
if (!c.firstFailedTime) return null; // not useful
|
||||
if (!(c instanceof RoomEchoContext)) throw new Error("Cannot render unknown context: " + c);
|
||||
const header = (
|
||||
<div className="mx_ServerOfflineDialog_content_context_timeline_header">
|
||||
<RoomAvatar width={24} height={24} room={c.room} />
|
||||
<span>{c.room.name}</span>
|
||||
</div>
|
||||
);
|
||||
const entries = c.transactions
|
||||
.filter(t => t.status === TransactionStatus.Error || t.didPreviouslyFail)
|
||||
.map((t, j) => {
|
||||
let button = <Spinner w={19} h={19} />;
|
||||
if (t.status === TransactionStatus.Error) {
|
||||
button = (
|
||||
<AccessibleButton kind="link" onClick={() => t.run()}>{_t("Resend")}</AccessibleButton>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="mx_ServerOfflineDialog_content_context_txn" key={`txn-${j}`}>
|
||||
<span className="mx_ServerOfflineDialog_content_context_txn_desc">
|
||||
{t.auditName}
|
||||
</span>
|
||||
{button}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="mx_ServerOfflineDialog_content_context" key={`context-${i}`}>
|
||||
<div className="mx_ServerOfflineDialog_content_context_timestamp">
|
||||
{formatTime(c.firstFailedTime, SettingsStore.getValue("showTwelveHourTimestamps"))}
|
||||
</div>
|
||||
<div className="mx_ServerOfflineDialog_content_context_timeline">
|
||||
{header}
|
||||
{entries}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
let timeline = this.renderTimeline().filter(c => !!c); // remove nulls for next check
|
||||
if (timeline.length === 0) {
|
||||
timeline = [<div key={1}>{_t("You're all caught up.")}</div>];
|
||||
}
|
||||
|
||||
const serverName = MatrixClientPeg.getHomeserverName();
|
||||
return <BaseDialog title={_t("Server isn't responding")}
|
||||
className='mx_ServerOfflineDialog'
|
||||
contentId='mx_Dialog_content'
|
||||
onFinished={this.props.onFinished}
|
||||
hasCancel={true}
|
||||
>
|
||||
<div className="mx_ServerOfflineDialog_content">
|
||||
<p>{_t(
|
||||
"Your server isn't responding to some of your requests. " +
|
||||
"Below are some of the most likely reasons.",
|
||||
)}</p>
|
||||
<ul>
|
||||
<li>{_t("The server (%(serverName)s) took too long to respond.", {serverName})}</li>
|
||||
<li>{_t("Your firewall or anti-virus is blocking the request.")}</li>
|
||||
<li>{_t("A browser extension is preventing the request.")}</li>
|
||||
<li>{_t("The server is offline.")}</li>
|
||||
<li>{_t("The server has denied your request.")}</li>
|
||||
<li>{_t("Your area is experiencing difficulties connecting to the internet.")}</li>
|
||||
<li>{_t("A connection error occurred while trying to contact the server.")}</li>
|
||||
<li>{_t("The server is not configured to indicate what the problem is (CORS).")}</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2>{_t("Recent changes that have not yet been received")}</h2>
|
||||
{timeline}
|
||||
</div>
|
||||
</BaseDialog>;
|
||||
}
|
||||
}
|
|
@ -17,10 +17,11 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import * as sdk from "../../../index";
|
||||
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
|
||||
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
export default class WidgetOpenIDPermissionsDialog extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -35,12 +35,13 @@ import dis from '../../../dispatcher/dispatcher';
|
|||
import ActiveWidgetStore from '../../../stores/ActiveWidgetStore';
|
||||
import classNames from 'classnames';
|
||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {aboveLeftOf, ContextMenu, ContextMenuButton} from "../../structures/ContextMenu";
|
||||
import PersistedElement from "./PersistedElement";
|
||||
import {WidgetType} from "../../../widgets/WidgetType";
|
||||
import {Capability} from "../../../widgets/WidgetApi";
|
||||
import {sleep} from "../../../utils/promise";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
||||
const ENABLE_REACT_PERF = false;
|
||||
|
|
|
@ -15,8 +15,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import Draggable, {ILocationState} from './Draggable';
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
|
||||
interface IProps {
|
||||
// Current room
|
||||
|
|
|
@ -20,11 +20,12 @@ import SettingsStore from "../../../settings/SettingsStore";
|
|||
import { _t } from '../../../languageHandler';
|
||||
import ToggleSwitch from "./ToggleSwitch";
|
||||
import StyledCheckbox from "./StyledCheckbox";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
|
||||
interface IProps {
|
||||
// The setting must be a boolean
|
||||
name: string;
|
||||
level: string;
|
||||
level: SettingLevel;
|
||||
roomId?: string; // for per-room settings
|
||||
label?: string; // untranslated
|
||||
isExplicit?: boolean;
|
||||
|
@ -52,8 +53,8 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
private onChange = (checked: boolean): void => {
|
||||
this.save(checked);
|
||||
private onChange = async (checked: boolean) => {
|
||||
await this.save(checked);
|
||||
this.setState({ value: checked });
|
||||
if (this.props.onChange) this.props.onChange(checked);
|
||||
};
|
||||
|
@ -62,8 +63,8 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
this.onChange(e.target.checked);
|
||||
};
|
||||
|
||||
private save = (val?: boolean): void => {
|
||||
return SettingsStore.setValue(
|
||||
private save = async (val?: boolean) => {
|
||||
await SettingsStore.setValue(
|
||||
this.props.name,
|
||||
this.props.roomId,
|
||||
this.props.level,
|
||||
|
|
|
@ -550,7 +550,9 @@ const RedactMessagesButton = ({member}) => {
|
|||
let eventsToRedact = [];
|
||||
while (timeline) {
|
||||
eventsToRedact = timeline.getEvents().reduce((events, event) => {
|
||||
if (event.getSender() === userId && !event.isRedacted() && !event.isRedaction()) {
|
||||
if (event.getSender() === userId && !event.isRedacted() && !event.isRedaction() &&
|
||||
event.getType() !== "m.room.create"
|
||||
) {
|
||||
return events.concat(event);
|
||||
} else {
|
||||
return events;
|
||||
|
|
|
@ -20,7 +20,8 @@ import createReactClass from 'create-react-class';
|
|||
|
||||
import Tinter from '../../../Tinter';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
const ROOM_COLORS = [
|
||||
// magic room default values courtesy of Ribot
|
||||
|
|
|
@ -22,10 +22,11 @@ import PropTypes from 'prop-types';
|
|||
import createReactClass from 'create-react-class';
|
||||
import * as sdk from "../../../index";
|
||||
import { _t, _td } from '../../../languageHandler';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import {Action} from "../../../dispatcher/actions";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
|
||||
export default createReactClass({
|
||||
|
|
|
@ -21,7 +21,8 @@ import * as sdk from "../../../index";
|
|||
import { _t } from "../../../languageHandler";
|
||||
import Modal from "../../../Modal";
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
export default class RoomRecoveryReminder extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
|
|
@ -17,12 +17,13 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {createRef} from "react";
|
||||
import React, { createRef } from "react";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import classNames from "classnames";
|
||||
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
|
||||
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import defaultDispatcher from '../../../dispatcher/dispatcher';
|
||||
import { Key } from "../../../Keyboard";
|
||||
import ActiveRoomObserver from "../../../ActiveRoomObserver";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -30,31 +31,26 @@ import {
|
|||
ChevronFace,
|
||||
ContextMenu,
|
||||
ContextMenuTooltipButton,
|
||||
MenuItemRadio,
|
||||
MenuItemCheckbox,
|
||||
MenuItem,
|
||||
MenuItemCheckbox,
|
||||
MenuItemRadio,
|
||||
} from "../../structures/ContextMenu";
|
||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||
import { MessagePreviewStore, ROOM_PREVIEW_CHANGED } from "../../../stores/room-list/MessagePreviewStore";
|
||||
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
|
||||
import {
|
||||
getRoomNotifsState,
|
||||
setRoomNotifsState,
|
||||
ALL_MESSAGES,
|
||||
ALL_MESSAGES_LOUD,
|
||||
MENTIONS_ONLY,
|
||||
MUTE,
|
||||
} from "../../../RoomNotifs";
|
||||
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE, } from "../../../RoomNotifs";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import NotificationBadge from "./NotificationBadge";
|
||||
import { Volume } from "../../../RoomNotifsTypes";
|
||||
import RoomListStore from "../../../stores/room-list/RoomListStore";
|
||||
import RoomListActions from "../../../actions/RoomListActions";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import {ActionPayload} from "../../../dispatcher/payloads";
|
||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
||||
import { NOTIFICATION_STATE_UPDATE, NotificationState } from "../../../stores/notifications/NotificationState";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import { EchoChamber } from "../../../stores/local-echo/EchoChamber";
|
||||
import { CachedRoomKey, RoomEchoChamber } from "../../../stores/local-echo/RoomEchoChamber";
|
||||
import { PROPERTY_UPDATED } from "../../../stores/local-echo/GenericEchoChamber";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
|
@ -112,6 +108,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
private dispatcherRef: string;
|
||||
private roomTileRef = createRef<HTMLDivElement>();
|
||||
private notificationState: NotificationState;
|
||||
private roomProps: RoomEchoChamber;
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -130,12 +127,19 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
MessagePreviewStore.instance.on(ROOM_PREVIEW_CHANGED, this.onRoomPreviewChanged);
|
||||
this.notificationState = RoomNotificationStateStore.instance.getRoomState(this.props.room);
|
||||
this.notificationState.on(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
|
||||
this.roomProps = EchoChamber.forRoom(this.props.room);
|
||||
this.roomProps.on(PROPERTY_UPDATED, this.onRoomPropertyUpdate);
|
||||
}
|
||||
|
||||
private onNotificationUpdate = () => {
|
||||
this.forceUpdate(); // notification state changed - update
|
||||
};
|
||||
|
||||
private onRoomPropertyUpdate = (property: CachedRoomKey) => {
|
||||
if (property === CachedRoomKey.NotificationVolume) this.onNotificationUpdate();
|
||||
// else ignore - not important for this tile
|
||||
};
|
||||
|
||||
private get showContextMenu(): boolean {
|
||||
return !this.props.isMinimized && this.props.tag !== DefaultTagID.Invite;
|
||||
}
|
||||
|
@ -307,17 +311,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
ev.stopPropagation();
|
||||
if (MatrixClientPeg.get().isGuest()) return;
|
||||
|
||||
// get key before we go async and React discards the nativeEvent
|
||||
const key = (ev as React.KeyboardEvent).key;
|
||||
try {
|
||||
// TODO add local echo - https://github.com/vector-im/riot-web/issues/14280
|
||||
await setRoomNotifsState(this.props.room.roomId, newState);
|
||||
} catch (error) {
|
||||
// TODO: some form of error notification to the user to inform them that their state change failed.
|
||||
// See https://github.com/vector-im/riot-web/issues/14281
|
||||
console.error(error);
|
||||
}
|
||||
this.roomProps.notificationVolume = newState;
|
||||
|
||||
const key = (ev as React.KeyboardEvent).key;
|
||||
if (key === Key.ENTER) {
|
||||
// Implements https://www.w3.org/TR/wai-aria-practices/#keyboard-interaction-12
|
||||
this.setState({notificationsMenuPosition: null}); // hide the menu
|
||||
|
@ -335,7 +331,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
return null;
|
||||
}
|
||||
|
||||
const state = getRoomNotifsState(this.props.room.roomId);
|
||||
const state = this.roomProps.notificationVolume;
|
||||
|
||||
let contextMenu = null;
|
||||
if (this.state.notificationsMenuPosition) {
|
||||
|
|
|
@ -18,7 +18,7 @@ import React from 'react';
|
|||
|
||||
import * as sdk from '../../../index';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions";
|
||||
|
||||
|
|
|
@ -20,10 +20,11 @@ import { _t } from '../../../languageHandler';
|
|||
import SdkConfig from "../../../SdkConfig";
|
||||
import * as sdk from '../../../index';
|
||||
import Modal from '../../../Modal';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import {formatBytes, formatCountLong} from "../../../utils/FormattingUtils";
|
||||
import EventIndexPeg from "../../../indexing/EventIndexPeg";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
export default class EventIndexPanel extends React.Component {
|
||||
constructor() {
|
||||
|
|
|
@ -20,7 +20,7 @@ import createReactClass from 'create-react-class';
|
|||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import SettingsStore, {SettingLevel} from '../../../settings/SettingsStore';
|
||||
import SettingsStore from '../../../settings/SettingsStore';
|
||||
import Modal from '../../../Modal';
|
||||
import {
|
||||
NotificationUtils,
|
||||
|
@ -31,6 +31,7 @@ import {
|
|||
import SdkConfig from "../../../SdkConfig";
|
||||
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
// TODO: this "view" component still has far too much application logic in it,
|
||||
// which should be factored out to other files.
|
||||
|
|
|
@ -18,7 +18,8 @@ import React from 'react';
|
|||
import {_t} from "../../../languageHandler";
|
||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||
import * as sdk from '../../../index';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
|
||||
export default class SetIntegrationManager extends React.Component {
|
||||
constructor() {
|
||||
|
|
|
@ -21,7 +21,7 @@ import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
|||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import Notifier from "../../../../../Notifier";
|
||||
import SettingsStore from '../../../../../settings/SettingsStore';
|
||||
import { SettingLevel } from '../../../../../settings/SettingsStore';
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export default class NotificationsSettingsTab extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -20,9 +20,9 @@ import {_t} from "../../../../../languageHandler";
|
|||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../..";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import Modal from "../../../../../Modal";
|
||||
import QuestionDialog from "../../../dialogs/QuestionDialog";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export default class SecurityRoomSettingsTab extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import SettingsStore, {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import { enumerateThemes } from "../../../../../theme";
|
||||
import ThemeWatcher from "../../../../../settings/watchers/ThemeWatcher";
|
||||
import Slider from "../../../elements/Slider";
|
||||
|
@ -35,6 +35,7 @@ import Field from '../../../elements/Field';
|
|||
import EventTilePreview from '../../../elements/EventTilePreview';
|
||||
import StyledRadioGroup from "../../../elements/StyledRadioGroup";
|
||||
import classNames from 'classnames';
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
|
||||
interface IProps {
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import React from 'react';
|
|||
import {_t} from "../../../../../languageHandler";
|
||||
import ProfileSettings from "../../ProfileSettings";
|
||||
import * as languageHandler from "../../../../../languageHandler";
|
||||
import {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import LanguageDropdown from "../../../elements/LanguageDropdown";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
|
@ -37,6 +36,7 @@ import IdentityAuthClient from "../../../../../IdentityAuthClient";
|
|||
import {abbreviateUrl} from "../../../../../utils/UrlUtils";
|
||||
import { getThreepidsWithBindStatus } from '../../../../../boundThreepids';
|
||||
import Spinner from "../../../elements/Spinner";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export default class GeneralUserSettingsTab extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -17,9 +17,10 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import PropTypes from "prop-types";
|
||||
import SettingsStore, {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import * as sdk from "../../../../../index";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export class LabsSettingToggle extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import Field from "../../../elements/Field";
|
||||
import * as sdk from "../../../../..";
|
||||
import PlatformPeg from "../../../../../PlatformPeg";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export default class PreferencesUserSettingsTab extends React.Component {
|
||||
static ROOM_LIST_SETTINGS = [
|
||||
|
|
|
@ -19,7 +19,6 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import * as FormattingUtils from "../../../../../utils/FormattingUtils";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
|
@ -29,6 +28,7 @@ import * as sdk from "../../../../..";
|
|||
import {sleep} from "../../../../../utils/promise";
|
||||
import dis from "../../../../../dispatcher/dispatcher";
|
||||
import {privateShouldBeEncrypted} from "../../../../../createRoom";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export class IgnoredUser extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -21,10 +21,10 @@ import SdkConfig from "../../../../../SdkConfig";
|
|||
import CallMediaHandler from "../../../../../CallMediaHandler";
|
||||
import Field from "../../../elements/Field";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import {SettingLevel} from "../../../../../settings/SettingsStore";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../../index";
|
||||
import Modal from "../../../../../Modal";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
|
||||
export default class VoiceUserSettingsTab extends React.Component {
|
||||
constructor() {
|
||||
|
|
40
src/components/views/toasts/NonUrgentEchoFailureToast.tsx
Normal file
40
src/components/views/toasts/NonUrgentEchoFailureToast.tsx
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
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 } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import Modal from "../../../Modal";
|
||||
import ServerOfflineDialog from "../dialogs/ServerOfflineDialog";
|
||||
|
||||
export default class NonUrgentEchoFailureToast extends React.PureComponent {
|
||||
private openDialog = () => {
|
||||
Modal.createTrackedDialog('Local Echo Server Error', '', ServerOfflineDialog, {});
|
||||
};
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div className="mx_NonUrgentEchoFailureToast">
|
||||
<span className="mx_NonUrgentEchoFailureToast_icon" />
|
||||
{_t("Your server isn't responding to some <a>requests</a>.", {}, {
|
||||
'a': (sub) => (
|
||||
<AccessibleButton kind="link" onClick={this.openDialog}>{sub}</AccessibleButton>
|
||||
),
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue