{
- const {command, range} = this.getCurrentCommand(query, selection);
+ const { command, range } = this.getCurrentCommand(query, selection);
if (!query || !command) {
return [];
}
diff --git a/src/autocomplete/EmojiProvider.tsx b/src/autocomplete/EmojiProvider.tsx
index b7c4a5120a..2fc77e9a17 100644
--- a/src/autocomplete/EmojiProvider.tsx
+++ b/src/autocomplete/EmojiProvider.tsx
@@ -21,9 +21,9 @@ import React from 'react';
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
import QueryMatcher from './QueryMatcher';
-import {PillCompletion} from './Components';
-import {ICompletion, ISelectionRange} from './Autocompleter';
-import {uniq, sortBy} from 'lodash';
+import { PillCompletion } from './Components';
+import { ICompletion, ISelectionRange } from './Autocompleter';
+import { uniq, sortBy } from 'lodash';
import SettingsStore from "../settings/SettingsStore";
import { shortcodeToUnicode } from '../HtmlUtils';
import { EMOJI, IEmoji } from '../emoji';
@@ -95,7 +95,7 @@ export default class EmojiProvider extends AutocompleteProvider {
}
let completions = [];
- const {command, range} = this.getCurrentCommand(query, selection);
+ const { command, range } = this.getCurrentCommand(query, selection);
if (command) {
const matchedString = command[0];
completions = this.matcher.match(matchedString, limit);
@@ -121,7 +121,7 @@ export default class EmojiProvider extends AutocompleteProvider {
sorters.push((c) => c._orderBy);
completions = sortBy(uniq(completions), sorters);
- completions = completions.map(({shortname}) => {
+ completions = completions.map(({ shortname }) => {
const unicode = shortcodeToUnicode(shortname);
return {
completion: unicode,
diff --git a/src/autocomplete/NotifProvider.tsx b/src/autocomplete/NotifProvider.tsx
index 0bc7ead097..1d42915ec9 100644
--- a/src/autocomplete/NotifProvider.tsx
+++ b/src/autocomplete/NotifProvider.tsx
@@ -15,13 +15,14 @@ limitations under the License.
*/
import React from 'react';
-import Room from "matrix-js-sdk/src/models/room";
+import { Room } from "matrix-js-sdk/src/models/room";
+
import AutocompleteProvider from './AutocompleteProvider';
import { _t } from '../languageHandler';
-import {MatrixClientPeg} from '../MatrixClientPeg';
-import {PillCompletion} from './Components';
+import { MatrixClientPeg } from '../MatrixClientPeg';
+import { PillCompletion } from './Components';
import * as sdk from '../index';
-import {ICompletion, ISelectionRange} from "./Autocompleter";
+import { ICompletion, ISelectionRange } from "./Autocompleter";
const AT_ROOM_REGEX = /@\S*/g;
@@ -45,7 +46,7 @@ export default class NotifProvider extends AutocompleteProvider {
if (!this.room.currentState.mayTriggerNotifOfType('room', client.credentials.userId)) return [];
- const {command, range} = this.getCurrentCommand(query, selection, force);
+ const { command, range } = this.getCurrentCommand(query, selection, force);
if (command && command[0] && '@room'.startsWith(command[0]) && command[0].length > 1) {
return [{
completion: '@room',
diff --git a/src/autocomplete/QueryMatcher.ts b/src/autocomplete/QueryMatcher.ts
index 73bb37ff0f..3948be301c 100644
--- a/src/autocomplete/QueryMatcher.ts
+++ b/src/autocomplete/QueryMatcher.ts
@@ -16,8 +16,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import {at, uniq} from 'lodash';
-import {removeHiddenChars} from "matrix-js-sdk/src/utils";
+import { at, uniq } from 'lodash';
+import { removeHiddenChars } from "matrix-js-sdk/src/utils";
interface IOptions {
keys: Array;
@@ -112,7 +112,7 @@ export default class QueryMatcher {
const index = resultKey.indexOf(query);
if (index !== -1) {
matches.push(
- ...candidates.map((candidate) => ({index, ...candidate})),
+ ...candidates.map((candidate) => ({ index, ...candidate })),
);
}
}
diff --git a/src/autocomplete/RoomProvider.tsx b/src/autocomplete/RoomProvider.tsx
index ad55b19101..7865a76daa 100644
--- a/src/autocomplete/RoomProvider.tsx
+++ b/src/autocomplete/RoomProvider.tsx
@@ -17,28 +17,24 @@ limitations under the License.
*/
import React from "react";
-import {uniqBy, sortBy} from "lodash";
-import Room from "matrix-js-sdk/src/models/room";
+import { uniqBy, sortBy } from "lodash";
+import { Room } from "matrix-js-sdk/src/models/room";
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
-import {MatrixClientPeg} from '../MatrixClientPeg';
+import { MatrixClientPeg } from '../MatrixClientPeg';
import QueryMatcher from './QueryMatcher';
-import {PillCompletion} from './Components';
-import {makeRoomPermalink} from "../utils/permalinks/Permalinks";
-import {ICompletion, ISelectionRange} from "./Autocompleter";
+import { PillCompletion } from './Components';
+import { makeRoomPermalink } from "../utils/permalinks/Permalinks";
+import { ICompletion, ISelectionRange } from "./Autocompleter";
import RoomAvatar from '../components/views/avatars/RoomAvatar';
import SettingsStore from "../settings/SettingsStore";
const ROOM_REGEX = /\B#\S*/g;
-function score(query: string, space: string) {
- const index = space.indexOf(query);
- if (index === -1) {
- return Infinity;
- } else {
- return index;
- }
+// Prefer canonical aliases over non-canonical ones
+function canonicalScore(displayedAlias: string, room: Room): number {
+ return displayedAlias === room.getCanonicalAlias() ? 0 : 1;
}
function matcherObject(room: Room, displayedAlias: string, matchName = "") {
@@ -77,7 +73,7 @@ export default class RoomProvider extends AutocompleteProvider {
limit = -1,
): Promise {
let completions = [];
- const {command, range} = this.getCurrentCommand(query, selection, force);
+ const { command, range } = this.getCurrentCommand(query, selection, force);
if (command) {
// the only reason we need to do this is because Fuse only matches on properties
let matcherObjects = this.getRooms().reduce((aliases, room) => {
@@ -106,7 +102,7 @@ export default class RoomProvider extends AutocompleteProvider {
const matchedString = command[0];
completions = this.matcher.match(matchedString, limit);
completions = sortBy(completions, [
- (c) => score(matchedString, c.displayedAlias),
+ (c) => canonicalScore(c.displayedAlias, c.room),
(c) => c.displayedAlias.length,
]);
completions = uniqBy(completions, (match) => match.room);
diff --git a/src/autocomplete/SpaceProvider.tsx b/src/autocomplete/SpaceProvider.tsx
index 0361a2c91e..1c99aee5ac 100644
--- a/src/autocomplete/SpaceProvider.tsx
+++ b/src/autocomplete/SpaceProvider.tsx
@@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import { _t } from '../languageHandler';
-import {MatrixClientPeg} from '../MatrixClientPeg';
+import { MatrixClientPeg } from '../MatrixClientPeg';
import RoomProvider from "./RoomProvider";
export default class SpaceProvider extends RoomProvider {
diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx
index 3cf43d0b84..470e018e22 100644
--- a/src/autocomplete/UserProvider.tsx
+++ b/src/autocomplete/UserProvider.tsx
@@ -20,19 +20,19 @@ limitations under the License.
import React from 'react';
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
-import {PillCompletion} from './Components';
+import { PillCompletion } from './Components';
import * as sdk from '../index';
import QueryMatcher from './QueryMatcher';
-import {sortBy} from 'lodash';
-import {MatrixClientPeg} from '../MatrixClientPeg';
+import { sortBy } from 'lodash';
+import { MatrixClientPeg } from '../MatrixClientPeg';
-import MatrixEvent from "matrix-js-sdk/src/models/event";
-import Room from "matrix-js-sdk/src/models/room";
-import RoomMember from "matrix-js-sdk/src/models/room-member";
-import RoomState from "matrix-js-sdk/src/models/room-state";
-import EventTimeline from "matrix-js-sdk/src/models/event-timeline";
-import {makeUserPermalink} from "../utils/permalinks/Permalinks";
-import {ICompletion, ISelectionRange} from "./Autocompleter";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { Room } from "matrix-js-sdk/src/models/room";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
+import { RoomState } from "matrix-js-sdk/src/models/room-state";
+import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
+import { makeUserPermalink } from "../utils/permalinks/Permalinks";
+import { ICompletion, ISelectionRange } from "./Autocompleter";
const USER_REGEX = /\B@\S*/g;
@@ -114,7 +114,7 @@ export default class UserProvider extends AutocompleteProvider {
if (!this.users) this._makeUsers();
let completions = [];
- const {command, range} = this.getCurrentCommand(rawQuery, selection, force);
+ const { command, range } = this.getCurrentCommand(rawQuery, selection, force);
if (!command) return completions;
@@ -158,7 +158,7 @@ export default class UserProvider extends AutocompleteProvider {
}
const currentUserId = MatrixClientPeg.get().credentials.userId;
- this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId);
+ this.users = this.room.getJoinedMembers().filter(({ userId }) => userId !== currentUserId);
this.users = this.users.concat(this.room.getMembersWithMembership("invite"));
this.users = sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20);
diff --git a/src/components/structures/AutoHideScrollbar.tsx b/src/components/structures/AutoHideScrollbar.tsx
index 66f998b616..8650224fb3 100644
--- a/src/components/structures/AutoHideScrollbar.tsx
+++ b/src/components/structures/AutoHideScrollbar.tsx
@@ -15,9 +15,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React from "react";
+import React, { HTMLAttributes } from "react";
-interface IProps {
+interface IProps extends HTMLAttributes {
className?: string;
onScroll?: () => void;
onWheel?: () => void;
@@ -52,14 +52,18 @@ export default class AutoHideScrollbar extends React.Component {
}
public render() {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const { className, onScroll, onWheel, style, tabIndex, wrappedRef, children, ...otherProps } = this.props;
+
return (
- { this.props.children }
+ { children }
);
}
}
diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx
index 9d8665c176..407dc6f04c 100644
--- a/src/components/structures/ContextMenu.tsx
+++ b/src/components/structures/ContextMenu.tsx
@@ -16,13 +16,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React, {CSSProperties, RefObject, useRef, useState} from "react";
+import React, { CSSProperties, RefObject, useRef, useState } from "react";
import ReactDOM from "react-dom";
import classNames from "classnames";
-import {Key} from "../../Keyboard";
-import {Writeable} from "../../@types/common";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { Key } from "../../Keyboard";
+import { Writeable } from "../../@types/common";
+import { replaceableComponent } from "../../utils/replaceableComponent";
import UIStore from "../../stores/UIStore";
// Shamelessly ripped off Modal.js. There's probably a better way
@@ -371,7 +371,7 @@ export class ContextMenu extends React.PureComponent {
return (
@@ -399,7 +399,7 @@ export const toRightOf = (elementRect: Pick
const left = elementRect.right + window.pageXOffset + 3;
let top = elementRect.top + (elementRect.height / 2) + window.pageYOffset;
top -= chevronOffset + 8; // where 8 is half the height of the chevron
- return {left, top, chevronOffset};
+ return { left, top, chevronOffset };
};
// Placement method for to position context menu right-aligned and flowing to the left of elementRect,
@@ -498,15 +498,15 @@ export function createMenu(ElementClass, props) {
ReactDOM.render(menu, getOrCreateContainer());
- return {close: onFinished};
+ return { close: onFinished };
}
// re-export the semantic helper components for simplicity
-export {ContextMenuButton} from "../../accessibility/context_menu/ContextMenuButton";
-export {ContextMenuTooltipButton} from "../../accessibility/context_menu/ContextMenuTooltipButton";
-export {MenuGroup} from "../../accessibility/context_menu/MenuGroup";
-export {MenuItem} from "../../accessibility/context_menu/MenuItem";
-export {MenuItemCheckbox} from "../../accessibility/context_menu/MenuItemCheckbox";
-export {MenuItemRadio} from "../../accessibility/context_menu/MenuItemRadio";
-export {StyledMenuItemCheckbox} from "../../accessibility/context_menu/StyledMenuItemCheckbox";
-export {StyledMenuItemRadio} from "../../accessibility/context_menu/StyledMenuItemRadio";
+export { ContextMenuButton } from "../../accessibility/context_menu/ContextMenuButton";
+export { ContextMenuTooltipButton } from "../../accessibility/context_menu/ContextMenuTooltipButton";
+export { MenuGroup } from "../../accessibility/context_menu/MenuGroup";
+export { MenuItem } from "../../accessibility/context_menu/MenuItem";
+export { MenuItemCheckbox } from "../../accessibility/context_menu/MenuItemCheckbox";
+export { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio";
+export { StyledMenuItemCheckbox } from "../../accessibility/context_menu/StyledMenuItemCheckbox";
+export { StyledMenuItemRadio } from "../../accessibility/context_menu/StyledMenuItemRadio";
diff --git a/src/components/structures/CustomRoomTagPanel.js b/src/components/structures/CustomRoomTagPanel.js
index 73359f17a5..037d7c251c 100644
--- a/src/components/structures/CustomRoomTagPanel.js
+++ b/src/components/structures/CustomRoomTagPanel.js
@@ -21,7 +21,7 @@ import * as sdk from '../../index';
import dis from '../../dispatcher/dispatcher';
import classNames from 'classnames';
import * as FormattingUtils from '../../utils/FormattingUtils';
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
@replaceableComponent("structures.CustomRoomTagPanel")
class CustomRoomTagPanel extends React.Component {
@@ -34,7 +34,7 @@ class CustomRoomTagPanel extends React.Component {
componentDidMount() {
this._tagStoreToken = CustomRoomTagStore.addListener(() => {
- this.setState({tags: CustomRoomTagStore.getSortedTags()});
+ this.setState({ tags: CustomRoomTagStore.getSortedTags() });
});
}
@@ -64,7 +64,7 @@ class CustomRoomTagPanel extends React.Component {
class CustomRoomTagTile extends React.Component {
onClick = () => {
- dis.dispatch({action: 'select_custom_room_tag', tag: this.props.tag.name});
+ dis.dispatch({ action: 'select_custom_room_tag', tag: this.props.tag.name });
};
render() {
diff --git a/src/components/structures/EmbeddedPage.js b/src/components/structures/EmbeddedPage.js
index c37ab3df48..628c16f322 100644
--- a/src/components/structures/EmbeddedPage.js
+++ b/src/components/structures/EmbeddedPage.js
@@ -22,7 +22,7 @@ import request from 'browser-request';
import { _t } from '../../languageHandler';
import sanitizeHtml from 'sanitize-html';
import dis from '../../dispatcher/dispatcher';
-import {MatrixClientPeg} from '../../MatrixClientPeg';
+import { MatrixClientPeg } from '../../MatrixClientPeg';
import classnames from 'classnames';
import MatrixClientContext from "../../contexts/MatrixClientContext";
import AutoHideScrollbar from "./AutoHideScrollbar";
diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.tsx
similarity index 85%
rename from src/components/structures/FilePanel.js
rename to src/components/structures/FilePanel.tsx
index bb7c1f9642..21ef0c4f31 100644
--- a/src/components/structures/FilePanel.js
+++ b/src/components/structures/FilePanel.tsx
@@ -16,37 +16,49 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
-import {Filter} from 'matrix-js-sdk/src/filter';
+import { Filter } from 'matrix-js-sdk/src/filter';
+import { EventTimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { Room } from 'matrix-js-sdk/src/models/room';
+import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
+
import * as sdk from '../../index';
-import {MatrixClientPeg} from '../../MatrixClientPeg';
+import { MatrixClientPeg } from '../../MatrixClientPeg';
import EventIndexPeg from "../../indexing/EventIndexPeg";
import { _t } from '../../languageHandler';
import BaseCard from "../views/right_panel/BaseCard";
-import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
-import DesktopBuildsNotice, {WarningKind} from "../views/elements/DesktopBuildsNotice";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { RightPanelPhases } from "../../stores/RightPanelStorePhases";
+import DesktopBuildsNotice, { WarningKind } from "../views/elements/DesktopBuildsNotice";
+import { replaceableComponent } from "../../utils/replaceableComponent";
+
+import ResizeNotifier from '../../utils/ResizeNotifier';
+
+interface IProps {
+ roomId: string;
+ onClose: () => void;
+ resizeNotifier: ResizeNotifier
+}
+
+interface IState {
+ timelineSet: EventTimelineSet;
+}
/*
* Component which shows the filtered file using a TimelinePanel
*/
@replaceableComponent("structures.FilePanel")
-class FilePanel extends React.Component {
- static propTypes = {
- roomId: PropTypes.string.isRequired,
- onClose: PropTypes.func.isRequired,
- };
-
+class FilePanel extends React.Component {
// This is used to track if a decrypted event was a live event and should be
// added to the timeline.
- decryptingEvents = new Set();
+ private decryptingEvents = new Set();
+ public noRoom: boolean;
state = {
timelineSet: null,
};
- onRoomTimeline = (ev, room, toStartOfTimeline, removed, data) => {
+ private onRoomTimeline = (ev: MatrixEvent, room: Room, toStartOfTimeline: true, removed: true, data: any): void => {
if (room?.roomId !== this.props?.roomId) return;
if (toStartOfTimeline || !data || !data.liveEvent || ev.isRedacted()) return;
@@ -60,7 +72,7 @@ class FilePanel extends React.Component {
}
};
- onEventDecrypted = (ev, err) => {
+ private onEventDecrypted = (ev: MatrixEvent, err?: any): void => {
if (ev.getRoomId() !== this.props.roomId) return;
const eventId = ev.getId();
@@ -70,7 +82,7 @@ class FilePanel extends React.Component {
this.addEncryptedLiveEvent(ev);
};
- addEncryptedLiveEvent(ev, toStartOfTimeline) {
+ public addEncryptedLiveEvent(ev: MatrixEvent): void {
if (!this.state.timelineSet) return;
const timeline = this.state.timelineSet.getLiveTimeline();
@@ -84,7 +96,7 @@ class FilePanel extends React.Component {
}
}
- async componentDidMount() {
+ public async componentDidMount(): Promise {
const client = MatrixClientPeg.get();
await this.updateTimelineSet(this.props.roomId);
@@ -105,7 +117,7 @@ class FilePanel extends React.Component {
}
}
- componentWillUnmount() {
+ public componentWillUnmount(): void {
const client = MatrixClientPeg.get();
if (client === null) return;
@@ -117,7 +129,7 @@ class FilePanel extends React.Component {
}
}
- async fetchFileEventsServer(room) {
+ public async fetchFileEventsServer(room: Room): Promise {
const client = MatrixClientPeg.get();
const filter = new Filter(client.credentials.userId);
@@ -141,7 +153,7 @@ class FilePanel extends React.Component {
return timelineSet;
}
- onPaginationRequest = (timelineWindow, direction, limit) => {
+ private onPaginationRequest = (timelineWindow: TimelineWindow, direction: string, limit: number): void => {
const client = MatrixClientPeg.get();
const eventIndex = EventIndexPeg.get();
const roomId = this.props.roomId;
@@ -159,7 +171,7 @@ class FilePanel extends React.Component {
}
};
- async updateTimelineSet(roomId: string) {
+ public async updateTimelineSet(roomId: string): Promise {
const client = MatrixClientPeg.get();
const room = client.getRoom(roomId);
const eventIndex = EventIndexPeg.get();
@@ -195,7 +207,7 @@ class FilePanel extends React.Component {
}
}
- render() {
+ public render() {
if (MatrixClientPeg.get().isGuest()) {
return {
+ onClick = e => {
// only dispatch if its not a no-op
if (this.state.selectedTags.length > 0) {
- dis.dispatch({action: 'deselect_tags'});
+ dis.dispatch({ action: 'deselect_tags' });
}
};
onClearFilterClick = ev => {
- dis.dispatch({action: 'deselect_tags'});
+ dis.dispatch({ action: 'deselect_tags' });
};
renderGlobalIcon() {
@@ -151,28 +150,15 @@ class GroupFilterPanel extends React.Component {
return
-
- { (provided, snapshot) => (
-
- { this.renderGlobalIcon() }
- { tags }
-
- {createButton}
-
- { provided.placeholder }
-
- ) }
-
+
+ { this.renderGlobalIcon() }
+ { tags }
+
+ { createButton }
+
+
;
}
diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js
index 3a2c611cc9..93c44c4e50 100644
--- a/src/components/structures/GroupView.js
+++ b/src/components/structures/GroupView.js
@@ -18,7 +18,7 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import {MatrixClientPeg} from '../../MatrixClientPeg';
+import { MatrixClientPeg } from '../../MatrixClientPeg';
import * as sdk from '../../index';
import dis from '../../dispatcher/dispatcher';
import { getHostingLink } from '../../utils/HostingLink';
@@ -34,13 +34,13 @@ import classnames from 'classnames';
import GroupStore from '../../stores/GroupStore';
import FlairStore from '../../stores/FlairStore';
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
-import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks";
-import {Group} from "matrix-js-sdk/src/models/group";
-import {sleep} from "../../utils/promise";
+import { makeGroupPermalink, makeUserPermalink } from "../../utils/permalinks/Permalinks";
+import { Group } from "matrix-js-sdk/src/models/group";
+import { sleep } from "../../utils/promise";
import RightPanelStore from "../../stores/RightPanelStore";
import AutoHideScrollbar from "./AutoHideScrollbar";
-import {mediaFromMxc} from "../../customisations/Media";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { mediaFromMxc } from "../../customisations/Media";
+import { replaceableComponent } from "../../utils/replaceableComponent";
const LONG_DESC_PLACEHOLDER = _td(
`
HTML for your community's page
@@ -115,7 +115,7 @@ class CategoryRoomList extends React.Component {
{
title: _t(
"Failed to add the following rooms to the summary of %(groupId)s:",
- {groupId: this.props.groupId},
+ { groupId: this.props.groupId },
),
description: errorList.join(", "),
},
@@ -126,12 +126,11 @@ class CategoryRoomList extends React.Component {
};
render() {
- const TintableSvg = sdk.getComponent("elements.TintableSvg");
const addButton = this.props.editing ?
(
-
+
{ _t('Add a Room') }
@@ -195,9 +194,9 @@ class FeaturedRoom extends React.Component {
{
title: _t(
"Failed to remove the room from the summary of %(groupId)s",
- {groupId: this.props.groupId},
+ { groupId: this.props.groupId },
),
- description: _t("The room '%(roomName)s' could not be removed from the summary.", {roomName}),
+ description: _t("The room '%(roomName)s' could not be removed from the summary.", { roomName }),
},
);
});
@@ -289,7 +288,7 @@ class RoleUserList extends React.Component {
{
title: _t(
"Failed to add the following users to the summary of %(groupId)s:",
- {groupId: this.props.groupId},
+ { groupId: this.props.groupId },
),
description: errorList.join(", "),
},
@@ -300,10 +299,9 @@ class RoleUserList extends React.Component {
};
render() {
- const TintableSvg = sdk.getComponent("elements.TintableSvg");
const addButton = this.props.editing ?
(
-
+
{ _t('Add a User') }
@@ -361,9 +359,12 @@ class FeaturedUser extends React.Component {
{
title: _t(
"Failed to remove a user from the summary of %(groupId)s",
- {groupId: this.props.groupId},
+ { groupId: this.props.groupId },
+ ),
+ description: _t(
+ "The user '%(displayName)s' could not be removed from the summary.",
+ { displayName },
),
- description: _t("The user '%(displayName)s' could not be removed from the summary.", {displayName}),
},
);
});
@@ -470,7 +471,7 @@ export default class GroupView extends React.Component {
// Leave settings - the user might have clicked the "Leave" button
this._closeSettings();
}
- this.setState({membershipBusy: false});
+ this.setState({ membershipBusy: false });
};
_initGroupStore(groupId, firstInit) {
@@ -491,7 +492,7 @@ export default class GroupView extends React.Component {
group_id: groupId,
},
});
- dis.dispatch({action: 'require_registration', screen_after: {screen: `group/${groupId}`}});
+ dis.dispatch({ action: 'require_registration', screen_after: { screen: `group/${groupId}` } });
willDoOnboarding = true;
}
if (stateKey === GroupStore.STATE_KEY.Summary) {
@@ -592,7 +593,7 @@ export default class GroupView extends React.Component {
};
_closeSettings = () => {
- dis.dispatch({action: 'close_settings'});
+ dis.dispatch({ action: 'close_settings' });
};
_onNameChange = (value) => {
@@ -620,7 +621,7 @@ export default class GroupView extends React.Component {
const file = ev.target.files[0];
if (!file) return;
- this.setState({uploadingAvatar: true});
+ this.setState({ uploadingAvatar: true });
this._matrixClient.uploadContent(file).then((url) => {
const newProfileForm = Object.assign(this.state.profileForm, { avatar_url: url });
this.setState({
@@ -632,7 +633,7 @@ export default class GroupView extends React.Component {
avatarChanged: true,
});
}).catch((e) => {
- this.setState({uploadingAvatar: false});
+ this.setState({ uploadingAvatar: false });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to upload avatar image", e);
Modal.createTrackedDialog('Failed to upload image', '', ErrorDialog, {
@@ -649,7 +650,7 @@ export default class GroupView extends React.Component {
};
_onSaveClick = () => {
- this.setState({saving: true});
+ this.setState({ saving: true });
const savePromise = this.state.isUserPrivileged ? this._saveGroup() : Promise.resolve();
savePromise.then((result) => {
this.setState({
@@ -688,7 +689,7 @@ export default class GroupView extends React.Component {
}
_onAcceptInviteClick = async () => {
- this.setState({membershipBusy: true});
+ this.setState({ membershipBusy: true });
// Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the
// spinner disappearing after we have fetched new group data.
@@ -697,7 +698,7 @@ export default class GroupView extends React.Component {
GroupStore.acceptGroupInvite(this.props.groupId).then(() => {
// don't reset membershipBusy here: wait for the membership change to come down the sync
}).catch((e) => {
- this.setState({membershipBusy: false});
+ this.setState({ membershipBusy: false });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Error accepting invite', '', ErrorDialog, {
title: _t("Error"),
@@ -707,7 +708,7 @@ export default class GroupView extends React.Component {
};
_onRejectInviteClick = async () => {
- this.setState({membershipBusy: true});
+ this.setState({ membershipBusy: true });
// Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the
// spinner disappearing after we have fetched new group data.
@@ -716,7 +717,7 @@ export default class GroupView extends React.Component {
GroupStore.leaveGroup(this.props.groupId).then(() => {
// don't reset membershipBusy here: wait for the membership change to come down the sync
}).catch((e) => {
- this.setState({membershipBusy: false});
+ this.setState({ membershipBusy: false });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Error rejecting invite', '', ErrorDialog, {
title: _t("Error"),
@@ -727,11 +728,11 @@ export default class GroupView extends React.Component {
_onJoinClick = async () => {
if (this._matrixClient.isGuest()) {
- dis.dispatch({action: 'require_registration', screen_after: {screen: `group/${this.props.groupId}`}});
+ dis.dispatch({ action: 'require_registration', screen_after: { screen: `group/${this.props.groupId}` } });
return;
}
- this.setState({membershipBusy: true});
+ this.setState({ membershipBusy: true });
// Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the
// spinner disappearing after we have fetched new group data.
@@ -740,7 +741,7 @@ export default class GroupView extends React.Component {
GroupStore.joinGroup(this.props.groupId).then(() => {
// don't reset membershipBusy here: wait for the membership change to come down the sync
}).catch((e) => {
- this.setState({membershipBusy: false});
+ this.setState({ membershipBusy: false });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Error joining room', '', ErrorDialog, {
title: _t("Error"),
@@ -773,7 +774,7 @@ export default class GroupView extends React.Component {
title: _t("Leave Community"),
description: (
- { _t("Leave %(groupName)s?", {groupName: this.props.groupId}) }
+ { _t("Leave %(groupName)s?", { groupName: this.props.groupId }) }
{ warnings }
),
@@ -782,7 +783,7 @@ export default class GroupView extends React.Component {
onFinished: async (confirmed) => {
if (!confirmed) return;
- this.setState({membershipBusy: true});
+ this.setState({ membershipBusy: true });
// Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the
// spinner disappearing after we have fetched new group data.
@@ -791,7 +792,7 @@ export default class GroupView extends React.Component {
GroupStore.leaveGroup(this.props.groupId).then(() => {
// don't reset membershipBusy here: wait for the membership change to come down the sync
}).catch((e) => {
- this.setState({membershipBusy: false});
+ this.setState({ membershipBusy: false });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Error leaving community', '', ErrorDialog, {
title: _t("Error"),
@@ -855,7 +856,6 @@ export default class GroupView extends React.Component {
_getRoomsNode() {
const RoomDetailList = sdk.getComponent('rooms.RoomDetailList');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
- const TintableSvg = sdk.getComponent('elements.TintableSvg');
const Spinner = sdk.getComponent('elements.Spinner');
const TooltipButton = sdk.getComponent('elements.TooltipButton');
@@ -871,7 +871,7 @@ export default class GroupView extends React.Component {
onClick={this._onAddRoomsClick}
>
-
+
{ _t('Add rooms to this community') }
@@ -1336,7 +1336,7 @@ export default class GroupView extends React.Component {
if (this.state.error.httpStatus === 404) {
return (
- { _t('Community %(groupId)s not found', {groupId: this.props.groupId}) }
+ { _t('Community %(groupId)s not found', { groupId: this.props.groupId }) }
,
];
}
@@ -775,11 +781,11 @@ export default class RoomDirectory extends React.Component {
}
const explanation =
_t("If you can't find the room you're looking for, ask for an invite or Create a new room.", null,
- {a: sub => (
+ { a: sub => (
{ sub }
- )},
+ ) },
);
const title = this.state.selectedCommunityId
diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx
index bda46aef07..9cdd1efe7e 100644
--- a/src/components/structures/RoomSearch.tsx
+++ b/src/components/structures/RoomSearch.tsx
@@ -108,22 +108,22 @@ export default class RoomSearch extends React.PureComponent {
};
private openSearch = () => {
- defaultDispatcher.dispatch({action: "show_left_panel"});
- defaultDispatcher.dispatch({action: "focus_room_filter"});
+ defaultDispatcher.dispatch({ action: "show_left_panel" });
+ defaultDispatcher.dispatch({ action: "focus_room_filter" });
};
private onChange = () => {
if (!this.inputRef.current) return;
- this.setState({query: this.inputRef.current.value});
+ this.setState({ query: this.inputRef.current.value });
};
private onFocus = (ev: React.FocusEvent) => {
- this.setState({focused: true});
+ this.setState({ focused: true });
ev.target.select();
};
private onBlur = (ev: React.FocusEvent) => {
- this.setState({focused: false});
+ this.setState({ focused: false });
};
private onKeyDown = (ev: React.KeyboardEvent) => {
diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js
index 7d74229421..f6e42a4f9c 100644
--- a/src/components/structures/RoomStatusBar.js
+++ b/src/components/structures/RoomStatusBar.js
@@ -17,15 +17,15 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
import { _t, _td } from '../../languageHandler';
-import {MatrixClientPeg} from '../../MatrixClientPeg';
+import { MatrixClientPeg } from '../../MatrixClientPeg';
import Resend from '../../Resend';
import dis from '../../dispatcher/dispatcher';
-import {messageForResourceLimitError} from '../../utils/ErrorUtils';
-import {Action} from "../../dispatcher/actions";
-import {replaceableComponent} from "../../utils/replaceableComponent";
-import {EventStatus} from "matrix-js-sdk/src/models/event";
+import { messageForResourceLimitError } from '../../utils/ErrorUtils';
+import { Action } from "../../dispatcher/actions";
+import { replaceableComponent } from "../../utils/replaceableComponent";
+import { EventStatus } from "matrix-js-sdk/src/models/event";
import NotificationBadge from "../views/rooms/NotificationBadge";
-import {StaticNotificationState} from "../../stores/notifications/StaticNotificationState";
+import { StaticNotificationState } from "../../stores/notifications/StaticNotificationState";
import AccessibleButton from "../views/elements/AccessibleButton";
import InlineSpinner from "../views/elements/InlineSpinner";
@@ -115,9 +115,9 @@ export default class RoomStatusBar extends React.PureComponent {
_onResendAllClick = () => {
Resend.resendUnsentEvents(this.props.room).then(() => {
- this.setState({isResending: false});
+ this.setState({ isResending: false });
});
- this.setState({isResending: true});
+ this.setState({ isResending: true });
dis.fire(Action.FocusComposer);
};
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index c9645515bf..945103ebc1 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -23,8 +23,9 @@ limitations under the License.
import React, { createRef } from 'react';
import classNames from 'classnames';
-import { Room } from "matrix-js-sdk/src/models/room";
+import { IRecommendedVersion, NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { SearchResult } from "matrix-js-sdk/src/models/search-result";
import { EventSubscription } from "fbemitter";
import shouldHideEvent from '../../shouldHideEvent';
@@ -36,7 +37,6 @@ import Modal from '../../Modal';
import * as sdk from '../../index';
import CallHandler, { PlaceCallType } from '../../CallHandler';
import dis from '../../dispatcher/dispatcher';
-import Tinter from '../../Tinter';
import rateLimitedFunc from '../../ratelimitedfunc';
import * as Rooms from '../../Rooms';
import eventSearch, { searchPagination } from '../../Searching';
@@ -59,7 +59,7 @@ import ScrollPanel from "./ScrollPanel";
import TimelinePanel from "./TimelinePanel";
import ErrorBoundary from "../views/elements/ErrorBoundary";
import RoomPreviewBar from "../views/rooms/RoomPreviewBar";
-import SearchBar from "../views/rooms/SearchBar";
+import SearchBar, { SearchScope } from "../views/rooms/SearchBar";
import RoomUpgradeWarningBar from "../views/rooms/RoomUpgradeWarningBar";
import AuxPanel from "../views/rooms/AuxPanel";
import RoomHeader from "../views/rooms/RoomHeader";
@@ -81,6 +81,7 @@ import SpaceRoomView from "./SpaceRoomView";
import { IOpts } from "../../createRoom";
import { replaceableComponent } from "../../utils/replaceableComponent";
import UIStore from "../../stores/UIStore";
+import EditorStateTransfer from "../../utils/EditorStateTransfer";
const DEBUG = false;
let debuglog = function(msg: string) {};
@@ -138,11 +139,11 @@ export interface IState {
draggingFile: boolean;
searching: boolean;
searchTerm?: string;
- searchScope?: "All" | "Room";
+ searchScope?: SearchScope;
searchResults?: XOR<{}, {
count: number;
highlights: string[];
- results: MatrixEvent[];
+ results: SearchResult[];
next_batch: string; // eslint-disable-line camelcase
}>;
searchHighlights?: string[];
@@ -171,11 +172,7 @@ export interface IState {
// We load this later by asking the js-sdk to suggest a version for us.
// This object is the result of Room#getRecommendedVersion()
- upgradeRecommendation?: {
- version: string;
- needsUpgrade: boolean;
- urgent: boolean;
- };
+ upgradeRecommendation?: IRecommendedVersion;
canReact: boolean;
canReply: boolean;
layout: Layout;
@@ -195,6 +192,7 @@ export interface IState {
// whether or not a spaces context switch brought us here,
// if it did we don't want the room to be marked as read as soon as it is loaded.
wasContextSwitch?: boolean;
+ editState?: EditorStateTransfer;
}
@replaceableComponent("structures.RoomView")
@@ -288,7 +286,7 @@ export default class RoomView extends React.Component {
if (this.state.room) {
this.checkWidgets(this.state.room);
}
- }
+ };
private checkWidgets = (room) => {
this.setState({
@@ -531,7 +529,7 @@ export default class RoomView extends React.Component {
} else if (room) {
// Stop peeking because we have joined this room previously
this.context.stopPeeking();
- this.setState({isPeeking: false});
+ this.setState({ isPeeking: false });
}
}
}
@@ -680,10 +678,6 @@ export default class RoomView extends React.Component {
// cancel any pending calls to the rate_limited_funcs
this.updateRoomMembers.cancelPendingCall();
- // no need to do this as Dir & Settings are now overlays. It just burnt CPU.
- // console.log("Tinter.tint from RoomView.unmount");
- // Tinter.tint(); // reset colourscheme
-
for (const watcher of this.settingWatchers) {
SettingsStore.unwatchSetting(watcher);
}
@@ -699,7 +693,7 @@ export default class RoomView extends React.Component {
replyingToEvent: this.state.replyToEvent,
});
}
- }
+ };
private onRightPanelStoreUpdate = () => {
this.setState({
@@ -818,6 +812,36 @@ export default class RoomView extends React.Component {
case 'focus_search':
this.onSearchClick();
break;
+
+ case "edit_event": {
+ const editState = payload.event ? new EditorStateTransfer(payload.event) : null;
+ this.setState({ editState }, () => {
+ if (payload.event) {
+ this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
+ }
+ });
+ break;
+ }
+
+ case Action.ComposerInsert: {
+ // re-dispatch to the correct composer
+ if (this.state.editState) {
+ dis.dispatch({
+ ...payload,
+ action: "edit_composer_insert",
+ });
+ } else {
+ dis.dispatch({
+ ...payload,
+ action: "send_composer_insert",
+ });
+ }
+ break;
+ }
+
+ case "scroll_to_bottom":
+ this.messagePanel?.jumpToLiveTimeline();
+ break;
}
};
@@ -853,7 +877,7 @@ export default class RoomView extends React.Component {
// no change
} else if (!shouldHideEvent(ev, this.state)) {
this.setState((state, props) => {
- return {numUnreadMessages: state.numUnreadMessages + 1};
+ return { numUnreadMessages: state.numUnreadMessages + 1 };
});
}
}
@@ -878,7 +902,7 @@ export default class RoomView extends React.Component {
CHAT_EFFECTS.forEach(effect => {
if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) {
- dis.dispatch({action: `effects.${effect.command}`});
+ dis.dispatch({ action: `effects.${effect.command}` });
}
});
};
@@ -931,7 +955,7 @@ export default class RoomView extends React.Component {
try {
await room.loadMembersIfNeeded();
if (!this.unmounted) {
- this.setState({membersLoaded: true});
+ this.setState({ membersLoaded: true });
}
} catch (err) {
const errorMessage = `Fetching room members for ${room.roomId} failed.` +
@@ -959,7 +983,7 @@ export default class RoomView extends React.Component {
}
}
- private updatePreviewUrlVisibility({roomId}: Room) {
+ private updatePreviewUrlVisibility({ roomId }: Room) {
// URL Previews in E2EE rooms can be a privacy leak so use a different setting which is per-room explicit
const key = this.context.isRoomEncrypted(roomId) ? 'urlPreviewsEnabled_e2ee' : 'urlPreviewsEnabled';
this.setState({
@@ -1033,10 +1057,6 @@ export default class RoomView extends React.Component {
private updateTint() {
const room = this.state.room;
if (!room) return;
-
- console.log("Tinter.tint from updateTint");
- const colorScheme = SettingsStore.getValue("roomColor", room.roomId);
- Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color);
}
private onAccountData = (event: MatrixEvent) => {
@@ -1050,12 +1070,7 @@ export default class RoomView extends React.Component {
private onRoomAccountData = (event: MatrixEvent, room: Room) => {
if (room.roomId == this.state.roomId) {
const type = event.getType();
- if (type === "org.matrix.room.color_scheme") {
- const colorScheme = event.getContent();
- // XXX: we should validate the event
- console.log("Tinter.tint from onRoomAccountData");
- Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color);
- } else if (type === "org.matrix.room.preview_urls" || type === "im.vector.web.settings") {
+ if (type === "org.matrix.room.preview_urls" || type === "im.vector.web.settings") {
// non-e2ee url previews are stored in legacy event type `org.matrix.room.preview_urls`
this.updatePreviewUrlVisibility(room);
}
@@ -1099,7 +1114,7 @@ export default class RoomView extends React.Component {
const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me);
const canReply = room.maySendMessage();
- this.setState({canReact, canReply});
+ this.setState({ canReact, canReply });
}
}
@@ -1163,7 +1178,7 @@ export default class RoomView extends React.Component {
room_id: this.getRoomId(),
},
});
- dis.dispatch({action: 'require_registration'});
+ dis.dispatch({ action: 'require_registration' });
} else {
Promise.resolve().then(() => {
const signUrl = this.props.threepidInvite?.signUrl;
@@ -1198,13 +1213,13 @@ export default class RoomView extends React.Component {
// We always increment the counter no matter the types, because dragging is
// still happening. If we didn't, the drag counter would get out of sync.
- this.setState({dragCounter: this.state.dragCounter + 1});
+ this.setState({ dragCounter: this.state.dragCounter + 1 });
// See:
// https://docs.w3cub.com/dom/datatransfer/types
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file
if (ev.dataTransfer.types.includes("Files") || ev.dataTransfer.types.includes("application/x-moz-file")) {
- this.setState({draggingFile: true});
+ this.setState({ draggingFile: true });
}
};
@@ -1253,7 +1268,7 @@ export default class RoomView extends React.Component {
private injectSticker(url, info, text) {
if (this.context.isGuest()) {
- dis.dispatch({action: 'require_registration'});
+ dis.dispatch({ action: 'require_registration' });
return;
}
@@ -1266,7 +1281,7 @@ export default class RoomView extends React.Component {
});
}
- private onSearch = (term: string, scope) => {
+ private onSearch = (term: string, scope: SearchScope) => {
this.setState({
searchTerm: term,
searchScope: scope,
@@ -1287,7 +1302,7 @@ export default class RoomView extends React.Component {
this.searchId = new Date().getTime();
let roomId;
- if (scope === "Room") roomId = this.state.room.roomId;
+ if (scope === SearchScope.Room) roomId = this.state.room.roomId;
debuglog("sending search request");
const searchPromise = eventSearch(term, roomId);
@@ -1580,7 +1595,7 @@ export default class RoomView extends React.Component {
const showBar = this.messagePanel.canJumpToReadMarker();
if (this.state.showTopUnreadMessagesBar != showBar) {
- this.setState({showTopUnreadMessagesBar: showBar});
+ this.setState({ showTopUnreadMessagesBar: showBar });
}
};
@@ -1711,7 +1726,7 @@ export default class RoomView extends React.Component {
onHiddenHighlightsClick = () => {
const oldRoom = this.getOldRoom();
if (!oldRoom) return;
- dis.dispatch({action: "view_room", room_id: oldRoom.roomId});
+ dis.dispatch({ action: "view_room", room_id: oldRoom.roomId });
};
render() {
@@ -1919,7 +1934,7 @@ export default class RoomView extends React.Component {
>
{_t(
"You have %(count)s unread notifications in a prior version of this room.",
- {count: hiddenHighlightCount},
+ { count: hiddenHighlightCount },
)}
);
@@ -2042,6 +2057,7 @@ export default class RoomView extends React.Component {
resizeNotifier={this.props.resizeNotifier}
showReactions={true}
layout={this.state.layout}
+ editState={this.state.editState}
/>);
let topUnreadMessagesBar = null;
@@ -2057,7 +2073,7 @@ export default class RoomView extends React.Component {
if (!this.state.atEndOfLiveTimeline && !this.state.searchResults) {
const JumpToBottomButton = sdk.getComponent('rooms.JumpToBottomButton');
jumpToBottom = ( 0}
+ highlight={this.state.room.getUnreadNotificationCount(NotificationCountType.Highlight) > 0}
numUnreadMessages={this.state.numUnreadMessages}
onScrollToBottomClick={this.jumpToLiveTimeline}
roomId={this.state.roomId}
diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js
index f6e1530537..6a5018927d 100644
--- a/src/components/structures/ScrollPanel.js
+++ b/src/components/structures/ScrollPanel.js
@@ -14,12 +14,12 @@ 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 PropTypes from 'prop-types';
import Timer from '../../utils/Timer';
import AutoHideScrollbar from "./AutoHideScrollbar";
-import {replaceableComponent} from "../../utils/replaceableComponent";
-import {getKeyBindingsManager, RoomAction} from "../../KeyBindingsManager";
+import { replaceableComponent } from "../../utils/replaceableComponent";
+import { getKeyBindingsManager, RoomAction } from "../../KeyBindingsManager";
const DEBUG_SCROLL = false;
@@ -166,7 +166,7 @@ export default class ScrollPanel extends React.Component {
constructor(props) {
super(props);
- this._pendingFillRequests = {b: null, f: null};
+ this._pendingFillRequests = { b: null, f: null };
if (this.props.resizeNotifier) {
this.props.resizeNotifier.on("middlePanelResizedNoisy", this.onResize);
@@ -593,7 +593,7 @@ export default class ScrollPanel extends React.Component {
// This because when setting the scrollTop only 10 or so events might be loaded,
// not giving enough content below the trackedNode to scroll downwards
// enough so it ends up in the top of the viewport.
- debuglog("scrollToken: setting scrollTop", {offsetBase, pixelOffset, offsetTop: trackedNode.offsetTop});
+ debuglog("scrollToken: setting scrollTop", { offsetBase, pixelOffset, offsetTop: trackedNode.offsetTop });
scrollNode.scrollTop = (trackedNode.offsetTop - (scrollNode.clientHeight * offsetBase)) + pixelOffset;
this._saveScrollState();
}
@@ -730,7 +730,7 @@ export default class ScrollPanel extends React.Component {
// yield out of date values and cause a jump
// when setting it
sn.scrollBy(0, topDiff);
- debuglog("updateHeight to", {newHeight, topDiff});
+ debuglog("updateHeight to", { newHeight, topDiff });
}
}
}
@@ -862,7 +862,7 @@ export default class ScrollPanel extends React.Component {
const sn = this._getScrollNode();
const scrollState = this.scrollState;
const messageList = this._itemlist.current;
- const {offsetNode, offsetFromBottom} = this.preventShrinkingState;
+ const { offsetNode, offsetFromBottom } = this.preventShrinkingState;
// element used to set paddingBottom to balance the typing notifs disappearing
const balanceElement = messageList.parentElement;
// if the offsetNode got unmounted, clear
diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js
index abeb858274..5c966d2d3a 100644
--- a/src/components/structures/SearchBox.js
+++ b/src/components/structures/SearchBox.js
@@ -15,14 +15,14 @@ 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 PropTypes from 'prop-types';
import { Key } from '../../Keyboard';
import dis from '../../dispatcher/dispatcher';
-import {throttle} from 'lodash';
+import { throttle } from 'lodash';
import AccessibleButton from '../../components/views/elements/AccessibleButton';
import classNames from 'classnames';
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
@replaceableComponent("structures.SearchBox")
export default class SearchBox extends React.Component {
@@ -89,7 +89,7 @@ export default class SearchBox extends React.Component {
onSearch = throttle(() => {
this.props.onSearch(this._search.current.value);
- }, 200, {trailing: true, leading: true});
+ }, 200, { trailing: true, leading: true });
_onKeyDown = ev => {
switch (ev.key) {
@@ -101,7 +101,7 @@ export default class SearchBox extends React.Component {
};
_onFocus = ev => {
- this.setState({blurred: false});
+ this.setState({ blurred: false });
ev.target.select();
if (this.props.onFocus) {
this.props.onFocus(ev);
@@ -109,7 +109,7 @@ export default class SearchBox extends React.Component {
};
_onBlur = ev => {
- this.setState({blurred: true});
+ this.setState({ blurred: true });
if (this.props.onBlur) {
this.props.onBlur(ev);
}
@@ -147,7 +147,7 @@ export default class SearchBox extends React.Component {
this.props.placeholder;
const className = this.props.className || "";
return (
-
+
= ({
ev.preventDefault();
ev.stopPropagation();
onViewRoomClick(false);
- }
+ };
const onJoinClick = (ev: ButtonEvent) => {
ev.preventDefault();
ev.stopPropagation();
onViewRoomClick(true);
- }
+ };
let button;
if (joinedRoom) {
@@ -137,7 +137,7 @@ const Tile: React.FC = ({
} else {
checkbox = { ev.stopPropagation() }}
+ onClick={ev => { ev.stopPropagation(); }}
>
;
@@ -286,7 +286,7 @@ export const HierarchyLevel = ({
const children = Array.from(relations.get(spaceId)?.values() || []);
const sortedChildren = sortBy(children, ev => {
// XXX: Space Summary API doesn't give the child origin_server_ts but once it does we should use it for sorting
- return getOrder(ev.content.order, null, ev.state_key);
+ return getChildOrder(ev.content.order, null, ev.state_key);
});
const [subspaces, childRooms] = sortedChildren.reduce((result, ev: ISpaceSummaryEvent) => {
const roomId = ev.state_key;
@@ -340,7 +340,7 @@ export const HierarchyLevel = ({
))
}
-
+ ;
};
// mutate argument refreshToken to force a reload
@@ -635,9 +635,9 @@ const SpaceRoomDirectory: React.FC = ({ space, onFinished, initialText }
{ _t("If you can't find the room you're looking for, ask for an invite or create a new room.",
null,
- {a: sub => {
+ { a: sub => {
return {sub};
- }},
+ } },
) }
{
) : null}
}
-
diff --git a/src/components/structures/TabbedView.tsx b/src/components/structures/TabbedView.tsx
index 0097d55cf5..3d77eaeac1 100644
--- a/src/components/structures/TabbedView.tsx
+++ b/src/components/structures/TabbedView.tsx
@@ -17,10 +17,10 @@ limitations under the License.
*/
import * as React from "react";
-import {_t} from '../../languageHandler';
+import { _t } from '../../languageHandler';
import * as sdk from "../../index";
import AutoHideScrollbar from './AutoHideScrollbar';
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
/**
* Represents a tab for the TabbedView.
@@ -75,7 +75,7 @@ export default class TabbedView extends React.Component {
private _setActiveTab(tab: Tab) {
const idx = this.props.tabs.indexOf(tab);
if (idx !== -1) {
- this.setState({activeTabIndex: idx});
+ this.setState({ activeTabIndex: idx });
} else {
console.error("Could not find tab " + tab.label + " in tabs");
}
diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js
index bb62745d98..4cd71056a6 100644
--- a/src/components/structures/TimelinePanel.js
+++ b/src/components/structures/TimelinePanel.js
@@ -18,14 +18,14 @@ limitations under the License.
*/
import SettingsStore from "../../settings/SettingsStore";
-import {LayoutPropType} from "../../settings/Layout";
-import React, {createRef} from 'react';
+import { LayoutPropType } from "../../settings/Layout";
+import React, { createRef } from 'react';
import ReactDOM from "react-dom";
import PropTypes from 'prop-types';
-import {EventTimeline} from "matrix-js-sdk/src/models/event-timeline";
-import {TimelineWindow} from "matrix-js-sdk/src/timeline-window";
+import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
+import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
import { _t } from '../../languageHandler';
-import {MatrixClientPeg} from "../../MatrixClientPeg";
+import { MatrixClientPeg } from "../../MatrixClientPeg";
import RoomContext from "../../contexts/RoomContext";
import UserActivity from "../../UserActivity";
import Modal from "../../Modal";
@@ -34,10 +34,9 @@ import * as sdk from "../../index";
import { Key } from '../../Keyboard';
import Timer from '../../utils/Timer';
import shouldHideEvent from '../../shouldHideEvent';
-import EditorStateTransfer from '../../utils/EditorStateTransfer';
-import {haveTileForEvent} from "../views/rooms/EventTile";
-import {UIFeature} from "../../settings/UIFeature";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { haveTileForEvent } from "../views/rooms/EventTile";
+import { UIFeature } from "../../settings/UIFeature";
+import { replaceableComponent } from "../../utils/replaceableComponent";
import { arrayFastClone } from "../../utils/arrays";
const PAGINATE_SIZE = 20;
@@ -71,6 +70,8 @@ class TimelinePanel extends React.Component {
manageReadReceipts: PropTypes.bool,
sendReadReceiptOnLoad: PropTypes.bool,
manageReadMarkers: PropTypes.bool,
+ // with this enabled it'll listen and react to Action.ComposerInsert and `edit_event`
+ manageComposerDispatches: PropTypes.bool,
// true to give the component a 'display: none' style.
hidden: PropTypes.bool,
@@ -363,7 +364,7 @@ class TimelinePanel extends React.Component {
if (!this._timelineWindow.canPaginate(dir)) {
debuglog("TimelinePanel: can't", dir, "paginate any further");
- this.setState({[canPaginateKey]: false});
+ this.setState({ [canPaginateKey]: false });
return Promise.resolve(false);
}
@@ -373,7 +374,7 @@ class TimelinePanel extends React.Component {
}
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
- this.setState({[paginatingKey]: true});
+ this.setState({ [paginatingKey]: true });
return this.onPaginationRequest(this._timelineWindow, dir, PAGINATE_SIZE).then((r) => {
if (this.unmounted) { return; }
@@ -427,7 +428,7 @@ class TimelinePanel extends React.Component {
// it goes back off the top of the screen (presumably because the user
// clicks on the 'jump to bottom' button), we need to re-enable it.
if (rmPosition < 0) {
- this.setState({readMarkerVisible: true});
+ this.setState({ readMarkerVisible: true });
}
// if read marker position goes between 0 and -1/1,
@@ -439,21 +440,10 @@ class TimelinePanel extends React.Component {
};
onAction = payload => {
- if (payload.action === 'ignore_state_changed') {
- this.forceUpdate();
- }
- if (payload.action === "edit_event") {
- const editState = payload.event ? new EditorStateTransfer(payload.event) : null;
- this.setState({editState}, () => {
- if (payload.event && this._messagePanel.current) {
- this._messagePanel.current.scrollToEventIfNeeded(
- payload.event.getId(),
- );
- }
- });
- }
- if (payload.action === "scroll_to_bottom") {
- this.jumpToLiveTimeline();
+ switch (payload.action) {
+ case "ignore_state_changed":
+ this.forceUpdate();
+ break;
}
};
@@ -471,7 +461,7 @@ class TimelinePanel extends React.Component {
// we won't load this event now, because we don't want to push any
// events off the other end of the timeline. But we need to note
// that we can now paginate.
- this.setState({canForwardPaginate: true});
+ this.setState({ canForwardPaginate: true });
return;
}
@@ -613,7 +603,7 @@ class TimelinePanel extends React.Component {
};
onSync = (state, prevState, data) => {
- this.setState({clientSyncState: state});
+ this.setState({ clientSyncState: state });
};
_readMarkerTimeout(readMarkerPosition) {
@@ -791,7 +781,6 @@ class TimelinePanel extends React.Component {
this.sendReadReceipt();
};
-
// advance the read marker past any events we sent ourselves.
_advanceReadMarkerPastMyEvents() {
if (!this.props.manageReadMarkers) return;
@@ -844,6 +833,12 @@ class TimelinePanel extends React.Component {
}
};
+ scrollToEventIfNeeded = (eventId) => {
+ if (this._messagePanel.current) {
+ this._messagePanel.current.scrollToEventIfNeeded(eventId);
+ }
+ }
+
/* scroll to show the read-up-to marker. We put it 1/3 of the way down
* the container.
*/
@@ -903,7 +898,6 @@ class TimelinePanel extends React.Component {
&& !this._timelineWindow.canPaginate(EventTimeline.FORWARDS);
}
-
/* get the current scroll state. See ScrollPanel.getScrollState for
* details.
*
@@ -1003,7 +997,7 @@ class TimelinePanel extends React.Component {
_loadTimeline(eventId, pixelOffset, offsetBase) {
this._timelineWindow = new TimelineWindow(
MatrixClientPeg.get(), this.props.timelineSet,
- {windowLimit: this.props.timelineCap});
+ { windowLimit: this.props.timelineCap });
const onLoaded = () => {
// clear the timeline min-height when
@@ -1451,7 +1445,7 @@ class TimelinePanel extends React.Component {
tileShape={this.props.tileShape}
resizeNotifier={this.props.resizeNotifier}
getRelationsForEvent={this.getRelationsForEvent}
- editState={this.state.editState}
+ editState={this.props.editState}
showReactions={this.props.showReactions}
layout={this.props.layout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
diff --git a/src/components/structures/ToastContainer.tsx b/src/components/structures/ToastContainer.tsx
index 273c8a079f..79a73735f4 100644
--- a/src/components/structures/ToastContainer.tsx
+++ b/src/components/structures/ToastContainer.tsx
@@ -15,9 +15,9 @@ limitations under the License.
*/
import * as React from "react";
-import ToastStore, {IToast} from "../../stores/ToastStore";
+import ToastStore, { IToast } from "../../stores/ToastStore";
import classNames from "classnames";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
interface IState {
toasts: IToast[];
@@ -58,7 +58,7 @@ export default class ToastContainer extends React.Component<{}, IState> {
let containerClasses;
if (totalCount !== 0) {
const topToast = this.state.toasts[0];
- const {title, icon, key, component, className, props} = topToast;
+ const { title, icon, key, component, className, props } = topToast;
const toastClasses = classNames("mx_Toast_toast", {
"mx_Toast_hasIcon": icon,
[`mx_Toast_icon_${icon}`]: icon,
diff --git a/src/components/structures/UploadBar.tsx b/src/components/structures/UploadBar.tsx
index e19e312f58..b8dce48235 100644
--- a/src/components/structures/UploadBar.tsx
+++ b/src/components/structures/UploadBar.tsx
@@ -25,7 +25,7 @@ import { Action } from "../../dispatcher/actions";
import ProgressBar from "../views/elements/ProgressBar";
import AccessibleButton from "../views/elements/AccessibleButton";
import { IUpload } from "../../models/IUpload";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
interface IProps {
room: Room;
@@ -47,7 +47,7 @@ export default class UploadBar extends React.Component {
// Set initial state to any available upload in this room - we might be mounting
// earlier than the first progress event, so should show something relevant.
const uploadsHere = this.getUploadsInRoom();
- this.state = {currentUpload: uploadsHere[0], uploadsHere};
+ this.state = { currentUpload: uploadsHere[0], uploadsHere };
}
componentDidMount() {
@@ -74,7 +74,7 @@ export default class UploadBar extends React.Component {
case Action.UploadFailed: {
if (!this.mounted) return;
const uploadsHere = this.getUploadsInRoom();
- this.setState({currentUpload: uploadsHere[0], uploadsHere});
+ this.setState({ currentUpload: uploadsHere[0], uploadsHere });
break;
}
}
diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx
index 6a449cf1a2..d85817486b 100644
--- a/src/components/structures/UserMenu.tsx
+++ b/src/components/structures/UserMenu.tsx
@@ -26,14 +26,14 @@ import { ActionPayload } from "../../dispatcher/payloads";
import { Action } from "../../dispatcher/actions";
import { _t } from "../../languageHandler";
import { ContextMenuButton } from "./ContextMenu";
-import { USER_NOTIFICATIONS_TAB, USER_SECURITY_TAB } from "../views/dialogs/UserSettingsDialog";
+import { UserTab } from "../views/dialogs/UserSettingsDialog";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import FeedbackDialog from "../views/dialogs/FeedbackDialog";
import Modal from "../../Modal";
import LogoutDialog from "../views/dialogs/LogoutDialog";
import SettingsStore from "../../settings/SettingsStore";
-import {getCustomTheme} from "../../theme";
-import AccessibleButton, {ButtonEvent} from "../views/elements/AccessibleButton";
+import { getCustomTheme } from "../../theme";
+import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
import SdkConfig from "../../SdkConfig";
import { getHomePageUrl } from "../../utils/pages";
import { OwnProfileStore } from "../../stores/OwnProfileStore";
@@ -56,7 +56,7 @@ import HostSignupAction from "./HostSignupAction";
import { IHostSignupConfig } from "../views/dialogs/HostSignupDialogTypes";
import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore";
import RoomName from "../views/elements/RoomName";
-import {replaceableComponent} from "../../utils/replaceableComponent";
+import { replaceableComponent } from "../../utils/replaceableComponent";
import InlineSpinner from "../views/elements/InlineSpinner";
import TooltipButton from "../views/elements/TooltipButton";
interface IProps {
@@ -123,7 +123,7 @@ export default class UserMenu extends React.Component {
private onRoom = (room: Room): void => {
this.removePendingJoinRoom(room.roomId);
- }
+ };
private onTagStoreUpdate = () => {
this.forceUpdate(); // we don't have anything useful in state to update
@@ -152,14 +152,14 @@ export default class UserMenu extends React.Component {
};
private onThemeChanged = () => {
- this.setState({isDarkTheme: this.isUserOnDarkTheme()});
+ this.setState({ isDarkTheme: this.isUserOnDarkTheme() });
};
private onAction = (ev: ActionPayload) => {
switch (ev.action) {
case Action.ToggleUserMenu:
if (this.state.contextMenuPosition) {
- this.setState({contextMenuPosition: null});
+ this.setState({ contextMenuPosition: null });
} else {
if (this.buttonRef.current) this.buttonRef.current.click();
}
@@ -185,7 +185,7 @@ export default class UserMenu extends React.Component {
if (this.state.pendingRoomJoin.delete(roomId)) {
this.setState({
pendingRoomJoin: new Set(this.state.pendingRoomJoin),
- })
+ });
}
}
@@ -193,7 +193,7 @@ export default class UserMenu extends React.Component {
ev.preventDefault();
ev.stopPropagation();
const target = ev.target as HTMLButtonElement;
- this.setState({contextMenuPosition: target.getBoundingClientRect()});
+ this.setState({ contextMenuPosition: target.getBoundingClientRect() });
};
private onContextMenu = (ev: React.MouseEvent) => {
@@ -210,7 +210,7 @@ export default class UserMenu extends React.Component {
};
private onCloseMenu = () => {
- this.setState({contextMenuPosition: null});
+ this.setState({ contextMenuPosition: null });
};
private onSwitchThemeClick = (ev: React.MouseEvent) => {
@@ -228,9 +228,9 @@ export default class UserMenu extends React.Component {
ev.preventDefault();
ev.stopPropagation();
- const payload: OpenToTabPayload = {action: Action.ViewUserSettings, initialTabId: tabId};
+ const payload: OpenToTabPayload = { action: Action.ViewUserSettings, initialTabId: tabId };
defaultDispatcher.dispatch(payload);
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onShowArchived = (ev: ButtonEvent) => {
@@ -247,7 +247,7 @@ export default class UserMenu extends React.Component {
ev.stopPropagation();
Modal.createTrackedDialog('Feedback Dialog', '', FeedbackDialog);
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onSignOutClick = async (ev: ButtonEvent) => {
@@ -257,30 +257,30 @@ export default class UserMenu extends React.Component {
const cli = MatrixClientPeg.get();
if (!cli || !cli.isCryptoEnabled() || !(await cli.exportRoomKeys())?.length) {
// log out without user prompt if they have no local megolm sessions
- dis.dispatch({action: 'logout'});
+ dis.dispatch({ action: 'logout' });
} else {
Modal.createTrackedDialog('Logout from LeftPanel', '', LogoutDialog);
}
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onSignInClick = () => {
dis.dispatch({ action: 'start_login' });
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onRegisterClick = () => {
dis.dispatch({ action: 'start_registration' });
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onHomeClick = (ev: ButtonEvent) => {
ev.preventDefault();
ev.stopPropagation();
- defaultDispatcher.dispatch({action: 'view_home_page'});
- this.setState({contextMenuPosition: null}); // also close the menu
+ defaultDispatcher.dispatch({ action: 'view_home_page' });
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onCommunitySettingsClick = (ev: ButtonEvent) => {
@@ -290,7 +290,7 @@ export default class UserMenu extends React.Component {
Modal.createTrackedDialog('Edit Community', '', EditCommunityPrototypeDialog, {
communityId: CommunityPrototypeStore.instance.getSelectedCommunityId(),
});
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onCommunityMembersClick = (ev: ButtonEvent) => {
@@ -307,7 +307,7 @@ export default class UserMenu extends React.Component {
action: 'view_room',
room_id: chat.roomId,
}, true);
- dis.dispatch({action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomMemberList});
+ dis.dispatch({ action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomMemberList });
} else {
// "This should never happen" clauses go here for the prototype.
Modal.createTrackedDialog('Failed to find general chat', '', ErrorDialog, {
@@ -315,7 +315,7 @@ export default class UserMenu extends React.Component {
description: _t("Failed to find the general chat for this community"),
});
}
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onCommunityInviteClick = (ev: ButtonEvent) => {
@@ -323,7 +323,7 @@ export default class UserMenu extends React.Component {
ev.stopPropagation();
showCommunityInviteDialog(CommunityPrototypeStore.instance.getSelectedCommunityId());
- this.setState({contextMenuPosition: null}); // also close the menu
+ this.setState({ contextMenuPosition: null }); // also close the menu
};
private onDndToggle = (ev) => {
@@ -357,7 +357,7 @@ export default class UserMenu extends React.Component {
),
})}
- )
+ );
} else if (hostSignupConfig) {
if (hostSignupConfig && hostSignupConfig.url) {
// If hostSignup.domains is set to a non-empty array, only show
@@ -408,12 +408,12 @@ export default class UserMenu extends React.Component {
this.onSettingsOpen(e, USER_NOTIFICATIONS_TAB)}
+ onClick={(e) => this.onSettingsOpen(e, UserTab.Notifications)}
/>
this.onSettingsOpen(e, USER_SECURITY_TAB)}
+ onClick={(e) => this.onSettingsOpen(e, UserTab.Security)}
/>
{
/>
- )
+ );
} else if (MatrixClientPeg.get().isGuest()) {
primaryOptionList = (
diff --git a/src/components/structures/UserView.js b/src/components/structures/UserView.js
index 6b472783bb..eb839be7be 100644
--- a/src/components/structures/UserView.js
+++ b/src/components/structures/UserView.js
@@ -17,14 +17,14 @@ limitations under the License.
import React from "react";
import PropTypes from "prop-types";
-import {MatrixClientPeg} from "../../MatrixClientPeg";
+import { MatrixClientPeg } from "../../MatrixClientPeg";
import * as sdk from "../../index";
import Modal from '../../Modal';
import { _t } from '../../languageHandler';
import HomePage from "./HomePage";
-import {replaceableComponent} from "../../utils/replaceableComponent";
-import {MatrixEvent} from "matrix-js-sdk/src/models/event";
-import {RoomMember} from "matrix-js-sdk/src/models/room-member";
+import { replaceableComponent } from "../../utils/replaceableComponent";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
@replaceableComponent("structures.UserView")
export default class UserView extends React.Component {
@@ -56,7 +56,7 @@ export default class UserView extends React.Component {
async _loadProfileInfo() {
const cli = MatrixClientPeg.get();
- this.setState({loading: true});
+ this.setState({ loading: true });
let profileInfo;
try {
profileInfo = await cli.getProfileInfo(this.props.userId);
@@ -66,13 +66,13 @@ export default class UserView extends React.Component {
title: _t('Could not load user profile'),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
- this.setState({loading: false});
+ this.setState({ loading: false });
return;
}
- const fakeEvent = new MatrixEvent({type: "m.room.member", content: profileInfo});
+ const fakeEvent = new MatrixEvent({ type: "m.room.member", content: profileInfo });
const member = new RoomMember(null, this.props.userId);
member.setMembershipEvent(fakeEvent);
- this.setState({member, loading: false});
+ this.setState({ member, loading: false });
}
render() {
diff --git a/src/components/structures/ViewSource.js b/src/components/structures/ViewSource.js
index 6fe99dd464..b69a92dd61 100644
--- a/src/components/structures/ViewSource.js
+++ b/src/components/structures/ViewSource.js
@@ -55,7 +55,7 @@ export default class ViewSource extends React.Component {
viewSourceContent() {
const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit
const isEncrypted = mxEvent.isEncrypted();
- const decryptedEventSource = mxEvent._clearEvent; // FIXME: _clearEvent is private
+ const decryptedEventSource = mxEvent.clearEvent; // FIXME: clearEvent is private
const originalEventSource = mxEvent.event;
if (isEncrypted) {
diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js
index 49fcf20415..d691f6034b 100644
--- a/src/components/structures/auth/CompleteSecurity.js
+++ b/src/components/structures/auth/CompleteSecurity.js
@@ -18,16 +18,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import * as sdk from '../../../index';
-import {
- SetupEncryptionStore,
- PHASE_LOADING,
- PHASE_INTRO,
- PHASE_BUSY,
- PHASE_DONE,
- PHASE_CONFIRM_SKIP,
-} from '../../../stores/SetupEncryptionStore';
+import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore';
import SetupEncryptionBody from "./SetupEncryptionBody";
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("structures.auth.CompleteSecurity")
export default class CompleteSecurity extends React.Component {
@@ -40,12 +33,12 @@ export default class CompleteSecurity extends React.Component {
const store = SetupEncryptionStore.sharedInstance();
store.on("update", this._onStoreUpdate);
store.start();
- this.state = {phase: store.phase};
+ this.state = { phase: store.phase };
}
_onStoreUpdate = () => {
const store = SetupEncryptionStore.sharedInstance();
- this.setState({phase: store.phase});
+ this.setState({ phase: store.phase });
};
componentWillUnmount() {
@@ -57,22 +50,22 @@ export default class CompleteSecurity extends React.Component {
render() {
const AuthPage = sdk.getComponent("auth.AuthPage");
const CompleteSecurityBody = sdk.getComponent("auth.CompleteSecurityBody");
- const {phase} = this.state;
+ const { phase } = this.state;
let icon;
let title;
- if (phase === PHASE_LOADING) {
+ if (phase === Phase.Loading) {
return null;
- } else if (phase === PHASE_INTRO) {
+ } else if (phase === Phase.Intro) {
icon = ;
title = _t("Verify this login");
- } else if (phase === PHASE_DONE) {
+ } else if (phase === Phase.Done) {
icon = ;
title = _t("Session verified");
- } else if (phase === PHASE_CONFIRM_SKIP) {
+ } else if (phase === Phase.ConfirmSkip) {
icon = ;
title = _t("Are you sure?");
- } else if (phase === PHASE_BUSY) {
+ } else if (phase === Phase.Busy) {
icon = ;
title = _t("Verify this login");
} else {
diff --git a/src/components/structures/auth/E2eSetup.js b/src/components/structures/auth/E2eSetup.js
index 4e51ae828c..9b627449bc 100644
--- a/src/components/structures/auth/E2eSetup.js
+++ b/src/components/structures/auth/E2eSetup.js
@@ -19,7 +19,7 @@ import PropTypes from 'prop-types';
import AuthPage from '../../views/auth/AuthPage';
import CompleteSecurityBody from '../../views/auth/CompleteSecurityBody';
import CreateCrossSigningDialog from '../../views/dialogs/security/CreateCrossSigningDialog';
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("structures.auth.E2eSetup")
export default class E2eSetup extends React.Component {
diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js
index 6188fdb5e4..9f2ac9deed 100644
--- a/src/components/structures/auth/ForgotPassword.js
+++ b/src/components/structures/auth/ForgotPassword.js
@@ -22,13 +22,13 @@ import { _t, _td } from '../../../languageHandler';
import * as sdk from '../../../index';
import Modal from "../../../Modal";
import PasswordReset from "../../../PasswordReset";
-import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
+import AutoDiscoveryUtils, { ValidatedServerConfig } from "../../../utils/AutoDiscoveryUtils";
import classNames from 'classnames';
import AuthPage from "../../views/auth/AuthPage";
import CountlyAnalytics from "../../../CountlyAnalytics";
import ServerPicker from "../../views/elements/ServerPicker";
import PassphraseField from '../../views/auth/PassphraseField';
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
import { PASSWORD_MIN_SCORE } from '../../views/auth/RegistrationForm';
// Phases
diff --git a/src/components/structures/auth/Login.tsx b/src/components/structures/auth/Login.tsx
index d34582b0c3..61d3759dee 100644
--- a/src/components/structures/auth/Login.tsx
+++ b/src/components/structures/auth/Login.tsx
@@ -14,28 +14,28 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React, {ReactNode} from 'react';
-import {MatrixError} from "matrix-js-sdk/src/http-api";
+import React, { ReactNode } from 'react';
+import { MatrixError } from "matrix-js-sdk/src/http-api";
-import {_t, _td} from '../../../languageHandler';
+import { _t, _td } from '../../../languageHandler';
import * as sdk from '../../../index';
-import Login, {ISSOFlow, LoginFlow} from '../../../Login';
+import Login, { ISSOFlow, LoginFlow } from '../../../Login';
import SdkConfig from '../../../SdkConfig';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
-import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
+import AutoDiscoveryUtils, { ValidatedServerConfig } from "../../../utils/AutoDiscoveryUtils";
import classNames from "classnames";
import AuthPage from "../../views/auth/AuthPage";
import PlatformPeg from '../../../PlatformPeg';
import SettingsStore from "../../../settings/SettingsStore";
-import {UIFeature} from "../../../settings/UIFeature";
+import { UIFeature } from "../../../settings/UIFeature";
import CountlyAnalytics from "../../../CountlyAnalytics";
-import {IMatrixClientCreds} from "../../../MatrixClientPeg";
+import { IMatrixClientCreds } from "../../../MatrixClientPeg";
import PasswordLogin from "../../views/auth/PasswordLogin";
import InlineSpinner from "../../views/elements/InlineSpinner";
import Spinner from "../../views/elements/Spinner";
import SSOButtons from "../../views/elements/SSOButtons";
import ServerPicker from "../../views/elements/ServerPicker";
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
// These are used in several places, and come from the js-sdk's autodiscovery
// stuff. We define them here so that they'll be picked up by i18n.
@@ -166,7 +166,7 @@ export default class LoginComponent extends React.PureComponent
onPasswordLogin = async (username, phoneCountry, phoneNumber, password) => {
if (!this.state.serverIsAlive) {
- this.setState({busy: true});
+ this.setState({ busy: true });
// Do a quick liveliness check on the URLs
let aliveAgain = true;
try {
@@ -174,7 +174,7 @@ export default class LoginComponent extends React.PureComponent
this.props.serverConfig.hsUrl,
this.props.serverConfig.isUrl,
);
- this.setState({serverIsAlive: true, errorText: ""});
+ this.setState({ serverIsAlive: true, errorText: "" });
} catch (e) {
const componentState = AutoDiscoveryUtils.authComponentStateForError(e);
this.setState({
@@ -201,7 +201,7 @@ export default class LoginComponent extends React.PureComponent
this.loginLogic.loginViaPassword(
username, phoneCountry, phoneNumber, password,
).then((data) => {
- this.setState({serverIsAlive: true}); // it must be, we logged in.
+ this.setState({ serverIsAlive: true }); // it must be, we logged in.
this.props.onLoggedIn(data, password);
}, (error) => {
if (this.unmounted) {
@@ -252,7 +252,7 @@ export default class LoginComponent extends React.PureComponent
{_t(
'Please note you are logging into the %(hs)s server, not matrix.org.',
- {hs: this.props.serverConfig.hsName},
+ { hs: this.props.serverConfig.hsName },
)}
@@ -363,7 +363,7 @@ export default class LoginComponent extends React.PureComponent
}
};
- private async initLoginLogic({hsUrl, isUrl}: ValidatedServerConfig) {
+ private async initLoginLogic({ hsUrl, isUrl }: ValidatedServerConfig) {
let isDefaultServer = false;
if (this.props.serverConfig.isDefault
&& hsUrl === this.props.serverConfig.hsUrl
@@ -501,9 +501,9 @@ export default class LoginComponent extends React.PureComponent
return
{ flows.map(flow => {
const stepRenderer = this.stepRendererMap[flow.type];
- return { stepRenderer() }
+ return { stepRenderer() };
}) }
-
+ ;
}
private renderPasswordStep = () => {
diff --git a/src/components/structures/auth/Registration.tsx b/src/components/structures/auth/Registration.tsx
index 6feb1e34f7..f27bed2cc3 100644
--- a/src/components/structures/auth/Registration.tsx
+++ b/src/components/structures/auth/Registration.tsx
@@ -14,23 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import {createClient} from 'matrix-js-sdk/src/matrix';
-import React, {ReactNode} from 'react';
-import {MatrixClient} from "matrix-js-sdk/src/client";
+import { createClient } from 'matrix-js-sdk/src/matrix';
+import React, { ReactNode } from 'react';
+import { MatrixClient } from "matrix-js-sdk/src/client";
import * as sdk from '../../../index';
import { _t, _td } from '../../../languageHandler';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
-import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
+import AutoDiscoveryUtils, { ValidatedServerConfig } from "../../../utils/AutoDiscoveryUtils";
import classNames from "classnames";
import * as Lifecycle from '../../../Lifecycle';
-import {MatrixClientPeg} from "../../../MatrixClientPeg";
+import { MatrixClientPeg } from "../../../MatrixClientPeg";
import AuthPage from "../../views/auth/AuthPage";
-import Login, {ISSOFlow} from "../../../Login";
+import Login, { ISSOFlow } from "../../../Login";
import dis from "../../../dispatcher/dispatcher";
import SSOButtons from "../../views/elements/SSOButtons";
import ServerPicker from '../../views/elements/ServerPicker';
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
serverConfig: ValidatedServerConfig;
@@ -131,7 +131,7 @@ export default class Registration extends React.Component {
serverDeadError: "",
};
- const {hsUrl, isUrl} = this.props.serverConfig;
+ const { hsUrl, isUrl } = this.props.serverConfig;
this.loginLogic = new Login(hsUrl, isUrl, null, {
defaultDeviceDisplayName: "Element login check", // We shouldn't ever be used
});
@@ -180,7 +180,7 @@ export default class Registration extends React.Component {
}
}
- const {hsUrl, isUrl} = serverConfig;
+ const { hsUrl, isUrl } = serverConfig;
const cli = createClient({
baseUrl: hsUrl,
idBaseUrl: isUrl,
@@ -230,7 +230,7 @@ export default class Registration extends React.Component {
// the user off to the login page to figure their account out.
if (ssoFlow) {
// Redirect to login page - server probably expects SSO only
- dis.dispatch({action: 'start_login'});
+ dis.dispatch({ action: 'start_login' });
} else {
this.setState({
serverErrorIsFatal: true, // fatal because user cannot continue on this server
@@ -267,9 +267,9 @@ export default class Registration extends React.Component {
session_id: sessionId,
}),
);
- }
+ };
- private onUIAuthFinished = async (success, response, extra) => {
+ private onUIAuthFinished = async (success: boolean, response: any) => {
if (!success) {
let msg = response.message || response.toString();
// can we give a better error message?
@@ -432,7 +432,7 @@ export default class Registration extends React.Component {
private onLoginClickWithCheck = async ev => {
ev.preventDefault();
- const sessionLoaded = await Lifecycle.loadSession({ignoreGuest: true});
+ const sessionLoaded = await Lifecycle.loadSession({ ignoreGuest: true });
if (!sessionLoaded) {
// ok fine, there's still no session: really go to the login page
this.props.onLoginClick();
@@ -487,7 +487,13 @@ export default class Registration extends React.Component {
fragmentAfterLogin={this.props.fragmentAfterLogin}
/>