Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/fix/17686
Conflicts: src/components/views/dialogs/AddExistingToSpaceDialog.tsx
This commit is contained in:
commit
1b25ab930e
27 changed files with 178 additions and 123 deletions
|
@ -57,7 +57,6 @@
|
||||||
@import "./views/avatars/_BaseAvatar.scss";
|
@import "./views/avatars/_BaseAvatar.scss";
|
||||||
@import "./views/avatars/_DecoratedRoomAvatar.scss";
|
@import "./views/avatars/_DecoratedRoomAvatar.scss";
|
||||||
@import "./views/avatars/_MemberStatusMessageAvatar.scss";
|
@import "./views/avatars/_MemberStatusMessageAvatar.scss";
|
||||||
@import "./views/avatars/_PulsedAvatar.scss";
|
|
||||||
@import "./views/avatars/_WidgetAvatar.scss";
|
@import "./views/avatars/_WidgetAvatar.scss";
|
||||||
@import "./views/beta/_BetaCard.scss";
|
@import "./views/beta/_BetaCard.scss";
|
||||||
@import "./views/context_menus/_CallContextMenu.scss";
|
@import "./views/context_menus/_CallContextMenu.scss";
|
||||||
|
|
|
@ -121,23 +121,51 @@ $pulse-color: $pinned-unread-color;
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 1);
|
box-shadow: 0 0 0 0 rgba($pulse-color, 1);
|
||||||
animation: mx_RightPanel_indicator_pulse 2s infinite;
|
animation: mx_RightPanel_indicator_pulse 2s infinite;
|
||||||
animation-iteration-count: 1;
|
animation-iteration-count: 1;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: scale(1);
|
||||||
|
transform-origin: center center;
|
||||||
|
animation-name: mx_RightPanel_indicator_pulse_shadow;
|
||||||
|
animation-duration: inherit;
|
||||||
|
animation-iteration-count: inherit;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba($pulse-color, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes mx_RightPanel_indicator_pulse {
|
@keyframes mx_RightPanel_indicator_pulse {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 0.7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
70% {
|
70% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
box-shadow: 0 0 0 10px rgba($pulse-color, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 0);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes mx_RightPanel_indicator_pulse_shadow {
|
||||||
|
0% {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: scale(2.2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,14 +57,15 @@ limitations under the License.
|
||||||
|
|
||||||
@keyframes mx_RoomView_fileDropTarget_image_animation {
|
@keyframes mx_RoomView_fileDropTarget_image_animation {
|
||||||
from {
|
from {
|
||||||
width: 0px;
|
transform: scaleX(0);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
width: 32px;
|
transform: scaleX(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_fileDropTarget_image {
|
.mx_RoomView_fileDropTarget_image {
|
||||||
|
width: 32px;
|
||||||
animation: mx_RoomView_fileDropTarget_image_animation;
|
animation: mx_RoomView_fileDropTarget_image_animation;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.mx_PulsedAvatar {
|
|
||||||
@keyframes shadow-pulse {
|
|
||||||
0% {
|
|
||||||
box-shadow: 0 0 0 0px rgba($accent-color, 0.2);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 0 0 6px rgba($accent-color, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
animation: shadow-pulse 1s infinite;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -110,24 +110,52 @@ $dot-size: 12px;
|
||||||
width: $dot-size;
|
width: $dot-size;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
background: rgba($pulse-color, 1);
|
background: rgba($pulse-color, 1);
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 1);
|
|
||||||
animation: mx_Beta_bluePulse 2s infinite;
|
animation: mx_Beta_bluePulse 2s infinite;
|
||||||
animation-iteration-count: 20;
|
animation-iteration-count: 20;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: scale(1);
|
||||||
|
transform-origin: center center;
|
||||||
|
animation-name: mx_Beta_bluePulse_shadow;
|
||||||
|
animation-duration: inherit;
|
||||||
|
animation-iteration-count: inherit;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba($pulse-color, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes mx_Beta_bluePulse {
|
@keyframes mx_Beta_bluePulse {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 0.7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
70% {
|
70% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
box-shadow: 0 0 0 10px rgba($pulse-color, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
box-shadow: 0 0 0 0 rgba($pulse-color, 0);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes mx_Beta_bluePulse_shadow {
|
||||||
|
0% {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: scale(2.2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ limitations under the License.
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 2px; // alignment
|
top: 2px; // alignment
|
||||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AccessSecretStorageDialog_reset_link {
|
.mx_AccessSecretStorageDialog_reset_link {
|
||||||
|
|
|
@ -16,12 +16,12 @@ limitations under the License.
|
||||||
|
|
||||||
import { randomString } from "matrix-js-sdk/src/randomstring";
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||||||
import { IContent } from "matrix-js-sdk/src/models/event";
|
import { IContent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { getCurrentLanguage } from './languageHandler';
|
import { getCurrentLanguage } from './languageHandler';
|
||||||
import PlatformPeg from './PlatformPeg';
|
import PlatformPeg from './PlatformPeg';
|
||||||
import SdkConfig from './SdkConfig';
|
import SdkConfig from './SdkConfig';
|
||||||
import { MatrixClientPeg } from "./MatrixClientPeg";
|
import { MatrixClientPeg } from "./MatrixClientPeg";
|
||||||
import { sleep } from "./utils/promise";
|
|
||||||
import RoomViewStore from "./stores/RoomViewStore";
|
import RoomViewStore from "./stores/RoomViewStore";
|
||||||
import { Action } from "./dispatcher/actions";
|
import { Action } from "./dispatcher/actions";
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { defer } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import Analytics from './Analytics';
|
import Analytics from './Analytics';
|
||||||
import dis from './dispatcher/dispatcher';
|
import dis from './dispatcher/dispatcher';
|
||||||
import { defer } from './utils/promise';
|
|
||||||
import AsyncWrapper from './AsyncWrapper';
|
import AsyncWrapper from './AsyncWrapper';
|
||||||
|
|
||||||
const DIALOG_CONTAINER_ID = "mx_Dialog_Container";
|
const DIALOG_CONTAINER_ID = "mx_Dialog_Container";
|
||||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types';
|
||||||
|
|
||||||
import { MatrixClientPeg } from './MatrixClientPeg';
|
import { MatrixClientPeg } from './MatrixClientPeg';
|
||||||
import * as sdk from '.';
|
import * as sdk from '.';
|
||||||
|
@ -32,7 +33,7 @@ export class Service {
|
||||||
* @param {string} baseUrl The Base URL of the service (ie. before '/_matrix')
|
* @param {string} baseUrl The Base URL of the service (ie. before '/_matrix')
|
||||||
* @param {string} accessToken The user's access token for the service
|
* @param {string} accessToken The user's access token for the service
|
||||||
*/
|
*/
|
||||||
constructor(public serviceType: string, public baseUrl: string, public accessToken: string) {
|
constructor(public serviceType: SERVICE_TYPES, public baseUrl: string, public accessToken: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import React from 'react';
|
||||||
|
|
||||||
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 { EventTimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
|
||||||
|
import { Direction } from "matrix-js-sdk/src/models/event-timeline";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||||
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
|
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
|
||||||
|
@ -129,7 +130,7 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchFileEventsServer(room: Room): Promise<void> {
|
public async fetchFileEventsServer(room: Room): Promise<EventTimelineSet> {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
|
|
||||||
const filter = new Filter(client.credentials.userId);
|
const filter = new Filter(client.credentials.userId);
|
||||||
|
@ -153,7 +154,11 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||||
return timelineSet;
|
return timelineSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onPaginationRequest = (timelineWindow: TimelineWindow, direction: string, limit: number): void => {
|
private onPaginationRequest = (
|
||||||
|
timelineWindow: TimelineWindow,
|
||||||
|
direction: Direction,
|
||||||
|
limit: number,
|
||||||
|
): Promise<boolean> => {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const eventIndex = EventIndexPeg.get();
|
const eventIndex = EventIndexPeg.get();
|
||||||
const roomId = this.props.roomId;
|
const roomId = this.props.roomId;
|
||||||
|
|
|
@ -36,7 +36,7 @@ import FlairStore from '../../stores/FlairStore';
|
||||||
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||||
import { makeGroupPermalink, makeUserPermalink } from "../../utils/permalinks/Permalinks";
|
import { makeGroupPermalink, makeUserPermalink } from "../../utils/permalinks/Permalinks";
|
||||||
import { Group } from "matrix-js-sdk/src/models/group";
|
import { Group } from "matrix-js-sdk/src/models/group";
|
||||||
import { sleep } from "../../utils/promise";
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
import RightPanelStore from "../../stores/RightPanelStore";
|
import RightPanelStore from "../../stores/RightPanelStore";
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
import { mediaFromMxc } from "../../customisations/Media";
|
import { mediaFromMxc } from "../../customisations/Media";
|
||||||
|
|
|
@ -19,6 +19,8 @@ import { createClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { sleep, defer, IDeferred } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
// focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
|
// focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
|
||||||
import 'focus-visible';
|
import 'focus-visible';
|
||||||
// what-input helps improve keyboard accessibility
|
// what-input helps improve keyboard accessibility
|
||||||
|
@ -55,7 +57,6 @@ import DMRoomMap from '../../utils/DMRoomMap';
|
||||||
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
|
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
|
||||||
import { FontWatcher } from '../../settings/watchers/FontWatcher';
|
import { FontWatcher } from '../../settings/watchers/FontWatcher';
|
||||||
import { storeRoomAliasInCache } from '../../RoomAliasCache';
|
import { storeRoomAliasInCache } from '../../RoomAliasCache';
|
||||||
import { defer, IDeferred, sleep } from "../../utils/promise";
|
|
||||||
import ToastStore from "../../stores/ToastStore";
|
import ToastStore from "../../stores/ToastStore";
|
||||||
import * as StorageManager from "../../utils/StorageManager";
|
import * as StorageManager from "../../utils/StorageManager";
|
||||||
import type LoggedInViewType from "./LoggedInView";
|
import type LoggedInViewType from "./LoggedInView";
|
||||||
|
|
|
@ -16,11 +16,13 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { createRef, ReactNode, SyntheticEvent } from 'react';
|
import React, { createRef, ReactNode, SyntheticEvent } from 'react';
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { TimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
|
import { EventTimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
|
||||||
import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
|
import { Direction, EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
|
||||||
import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
|
import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
|
||||||
|
import { EventType, RelationType } from 'matrix-js-sdk/src/@types/event';
|
||||||
|
import { SyncState } from 'matrix-js-sdk/src/sync.api';
|
||||||
|
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
import { Layout } from "../../settings/Layout";
|
import { Layout } from "../../settings/Layout";
|
||||||
|
@ -39,10 +41,8 @@ import { UIFeature } from "../../settings/UIFeature";
|
||||||
import { replaceableComponent } from "../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../utils/replaceableComponent";
|
||||||
import { arrayFastClone } from "../../utils/arrays";
|
import { arrayFastClone } from "../../utils/arrays";
|
||||||
import MessagePanel from "./MessagePanel";
|
import MessagePanel from "./MessagePanel";
|
||||||
import { SyncState } from 'matrix-js-sdk/src/sync.api';
|
|
||||||
import { IScrollState } from "./ScrollPanel";
|
import { IScrollState } from "./ScrollPanel";
|
||||||
import { ActionPayload } from "../../dispatcher/payloads";
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
import { EventType } from 'matrix-js-sdk/src/@types/event';
|
|
||||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||||
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
|
@ -65,7 +65,7 @@ interface IProps {
|
||||||
// representing. This may or may not have a room, depending on what it's
|
// representing. This may or may not have a room, depending on what it's
|
||||||
// a timeline representing. If it has a room, we maintain RRs etc for
|
// a timeline representing. If it has a room, we maintain RRs etc for
|
||||||
// that room.
|
// that room.
|
||||||
timelineSet: TimelineSet;
|
timelineSet: EventTimelineSet;
|
||||||
showReadReceipts?: boolean;
|
showReadReceipts?: boolean;
|
||||||
// Enable managing RRs and RMs. These require the timelineSet to have a room.
|
// Enable managing RRs and RMs. These require the timelineSet to have a room.
|
||||||
manageReadReceipts?: boolean;
|
manageReadReceipts?: boolean;
|
||||||
|
@ -388,7 +388,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private onPaginationRequest = (
|
private onPaginationRequest = (
|
||||||
timelineWindow: TimelineWindow,
|
timelineWindow: TimelineWindow,
|
||||||
direction: string,
|
direction: Direction,
|
||||||
size: number,
|
size: number,
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
if (this.props.onPaginationRequest) {
|
if (this.props.onPaginationRequest) {
|
||||||
|
@ -579,7 +579,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private onRoomTimelineReset = (room: Room, timelineSet: TimelineSet): void => {
|
private onRoomTimelineReset = (room: Room, timelineSet: EventTimelineSet): void => {
|
||||||
if (timelineSet !== this.props.timelineSet) return;
|
if (timelineSet !== this.props.timelineSet) return;
|
||||||
|
|
||||||
if (this.messagePanel.current && this.messagePanel.current.isAtBottom()) {
|
if (this.messagePanel.current && this.messagePanel.current.isAtBottom()) {
|
||||||
|
@ -792,8 +792,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
// that sending an RR for the latest message will set our notif counter
|
// that sending an RR for the latest message will set our notif counter
|
||||||
// to zero: it may not do this if we send an RR for somewhere before the end.
|
// to zero: it may not do this if we send an RR for somewhere before the end.
|
||||||
if (this.isAtEndOfLiveTimeline()) {
|
if (this.isAtEndOfLiveTimeline()) {
|
||||||
this.props.timelineSet.room.setUnreadNotificationCount('total', 0);
|
this.props.timelineSet.room.setUnreadNotificationCount(NotificationCountType.Total, 0);
|
||||||
this.props.timelineSet.room.setUnreadNotificationCount('highlight', 0);
|
this.props.timelineSet.room.setUnreadNotificationCount(NotificationCountType.Highlight, 0);
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'on_room_read',
|
action: 'on_room_read',
|
||||||
roomId: this.props.timelineSet.room.roomId,
|
roomId: this.props.timelineSet.room.roomId,
|
||||||
|
@ -1416,7 +1416,11 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRelationsForEvent = (...args) => this.props.timelineSet.getRelationsForEvent(...args);
|
private getRelationsForEvent = (
|
||||||
|
eventId: string,
|
||||||
|
relationType: RelationType,
|
||||||
|
eventType: EventType | string,
|
||||||
|
) => this.props.timelineSet.getRelationsForEvent(eventId, relationType, eventType);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// just show a spinner while the timeline loads.
|
// just show a spinner while the timeline loads.
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
import React, { ReactNode, useContext, useMemo, useState } from "react";
|
import React, { ReactNode, useContext, useMemo, useState } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { IDialogProps } from "./IDialogProps";
|
import { IDialogProps } from "./IDialogProps";
|
||||||
|
@ -28,7 +29,6 @@ import RoomAvatar from "../avatars/RoomAvatar";
|
||||||
import { getDisplayAliasForRoom } from "../../../Rooms";
|
import { getDisplayAliasForRoom } from "../../../Rooms";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
import { sleep } from "../../../utils/promise";
|
|
||||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||||
import { calculateRoomVia } from "../../../utils/permalinks/Permalinks";
|
import { calculateRoomVia } from "../../../utils/permalinks/Permalinks";
|
||||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||||
|
|
|
@ -19,6 +19,7 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { createRef } from 'react';
|
import React, { createRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { _t, _td } from '../../../languageHandler';
|
import { _t, _td } from '../../../languageHandler';
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
|
@ -30,7 +31,6 @@ import * as Email from '../../../email';
|
||||||
import IdentityAuthClient from '../../../IdentityAuthClient';
|
import IdentityAuthClient from '../../../IdentityAuthClient';
|
||||||
import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils';
|
import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils';
|
||||||
import { abbreviateUrl } from '../../../utils/UrlUtils';
|
import { abbreviateUrl } from '../../../utils/UrlUtils';
|
||||||
import { sleep } from "../../../utils/promise";
|
|
||||||
import { Key } from "../../../Keyboard";
|
import { Key } from "../../../Keyboard";
|
||||||
import { Action } from "../../../dispatcher/actions";
|
import { Action } from "../../../dispatcher/actions";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
|
|
@ -122,7 +122,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
||||||
const image = this.image.current;
|
const image = this.image.current;
|
||||||
const imageWrapper = this.imageWrapper.current;
|
const imageWrapper = this.imageWrapper.current;
|
||||||
|
|
||||||
const rotation = inputRotation || this.state.rotation;
|
const rotation = inputRotation ?? this.state.rotation;
|
||||||
|
|
||||||
const imageIsNotFlipped = rotation % 180 === 0;
|
const imageIsNotFlipped = rotation % 180 === 0;
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,19 @@ limitations under the License.
|
||||||
import React, { ClipboardEvent, createRef, KeyboardEvent } from 'react';
|
import React, { ClipboardEvent, createRef, KeyboardEvent } from 'react';
|
||||||
import EMOJI_REGEX from 'emojibase-regex';
|
import EMOJI_REGEX from 'emojibase-regex';
|
||||||
import { IContent, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
import { IContent, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
|
import { DebouncedFunc, throttle } from 'lodash';
|
||||||
|
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
import EditorModel from '../../../editor/model';
|
import EditorModel from '../../../editor/model';
|
||||||
import {
|
import {
|
||||||
htmlSerializeIfNeeded,
|
|
||||||
textSerialize,
|
|
||||||
containsEmote,
|
containsEmote,
|
||||||
stripEmoteCommand,
|
htmlSerializeIfNeeded,
|
||||||
unescapeMessage,
|
|
||||||
startsWith,
|
startsWith,
|
||||||
|
stripEmoteCommand,
|
||||||
stripPrefix,
|
stripPrefix,
|
||||||
|
textSerialize,
|
||||||
|
unescapeMessage,
|
||||||
} from '../../../editor/serialize';
|
} from '../../../editor/serialize';
|
||||||
import { CommandPartCreator, Part, PartCreator, SerializedPart } from '../../../editor/parts';
|
import { CommandPartCreator, Part, PartCreator, SerializedPart } from '../../../editor/parts';
|
||||||
import BasicMessageComposer from "./BasicMessageComposer";
|
import BasicMessageComposer from "./BasicMessageComposer";
|
||||||
|
@ -52,7 +54,6 @@ import { Room } from 'matrix-js-sdk/src/models/room';
|
||||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||||
import QuestionDialog from "../dialogs/QuestionDialog";
|
import QuestionDialog from "../dialogs/QuestionDialog";
|
||||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||||
import { DebouncedFunc, throttle } from 'lodash';
|
|
||||||
|
|
||||||
function addReplyToMessageContent(
|
function addReplyToMessageContent(
|
||||||
content: IContent,
|
content: IContent,
|
||||||
|
@ -258,12 +259,12 @@ export default class SendMessageComposer extends React.Component<IProps> {
|
||||||
const events = timeline.getEvents();
|
const events = timeline.getEvents();
|
||||||
const reaction = this.model.parts[1].text;
|
const reaction = this.model.parts[1].text;
|
||||||
for (let i = events.length - 1; i >= 0; i--) {
|
for (let i = events.length - 1; i >= 0; i--) {
|
||||||
if (events[i].getType() === "m.room.message") {
|
if (events[i].getType() === EventType.RoomMessage) {
|
||||||
let shouldReact = true;
|
let shouldReact = true;
|
||||||
const lastMessage = events[i];
|
const lastMessage = events[i];
|
||||||
const userId = MatrixClientPeg.get().getUserId();
|
const userId = MatrixClientPeg.get().getUserId();
|
||||||
const messageReactions = this.props.room.getUnfilteredTimelineSet()
|
const messageReactions = this.props.room.getUnfilteredTimelineSet()
|
||||||
.getRelationsForEvent(lastMessage.getId(), "m.annotation", "m.reaction");
|
.getRelationsForEvent(lastMessage.getId(), RelationType.Annotation, EventType.Reaction);
|
||||||
|
|
||||||
// if we have already sent this reaction, don't redact but don't re-send
|
// if we have already sent this reaction, don't redact but don't re-send
|
||||||
if (messageReactions) {
|
if (messageReactions) {
|
||||||
|
@ -274,9 +275,9 @@ export default class SendMessageComposer extends React.Component<IProps> {
|
||||||
shouldReact = !myReactionKeys.includes(reaction);
|
shouldReact = !myReactionKeys.includes(reaction);
|
||||||
}
|
}
|
||||||
if (shouldReact) {
|
if (shouldReact) {
|
||||||
MatrixClientPeg.get().sendEvent(lastMessage.getRoomId(), "m.reaction", {
|
MatrixClientPeg.get().sendEvent(lastMessage.getRoomId(), EventType.Reaction, {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"rel_type": "m.annotation",
|
"rel_type": RelationType.Annotation,
|
||||||
"event_id": lastMessage.getId(),
|
"event_id": lastMessage.getId(),
|
||||||
"key": reaction,
|
"key": reaction,
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,6 +24,8 @@ import * as sdk from "../../../../..";
|
||||||
import PlatformPeg from "../../../../../PlatformPeg";
|
import PlatformPeg from "../../../../../PlatformPeg";
|
||||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||||
|
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
|
||||||
|
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
autoLaunch: boolean;
|
autoLaunch: boolean;
|
||||||
|
@ -45,6 +47,10 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
|
||||||
'breadcrumbs',
|
'breadcrumbs',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static KEYBINDINGS_SETTINGS = [
|
||||||
|
'ctrlFForSearch',
|
||||||
|
];
|
||||||
|
|
||||||
static COMPOSER_SETTINGS = [
|
static COMPOSER_SETTINGS = [
|
||||||
'MessageComposerInput.autoReplaceEmoji',
|
'MessageComposerInput.autoReplaceEmoji',
|
||||||
'MessageComposerInput.suggestEmoji',
|
'MessageComposerInput.suggestEmoji',
|
||||||
|
@ -53,28 +59,32 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
|
||||||
'MessageComposerInput.showStickersButton',
|
'MessageComposerInput.showStickersButton',
|
||||||
];
|
];
|
||||||
|
|
||||||
static TIMELINE_SETTINGS = [
|
static TIME_SETTINGS = [
|
||||||
'showTypingNotifications',
|
|
||||||
'autoplayGifsAndVideos',
|
|
||||||
'urlPreviewsEnabled',
|
|
||||||
'TextualBody.enableBigEmoji',
|
|
||||||
'showReadReceipts',
|
|
||||||
'showTwelveHourTimestamps',
|
'showTwelveHourTimestamps',
|
||||||
'alwaysShowTimestamps',
|
'alwaysShowTimestamps',
|
||||||
'showRedactions',
|
];
|
||||||
|
static CODE_BLOCKS_SETTINGS = [
|
||||||
'enableSyntaxHighlightLanguageDetection',
|
'enableSyntaxHighlightLanguageDetection',
|
||||||
'expandCodeByDefault',
|
'expandCodeByDefault',
|
||||||
'scrollToBottomOnMessageSent',
|
|
||||||
'showCodeLineNumbers',
|
'showCodeLineNumbers',
|
||||||
'showJoinLeaves',
|
|
||||||
'showAvatarChanges',
|
|
||||||
'showDisplaynameChanges',
|
|
||||||
'showImages',
|
|
||||||
'showChatEffects',
|
|
||||||
'Pill.shouldShowPillAvatar',
|
|
||||||
'ctrlFForSearch',
|
|
||||||
];
|
];
|
||||||
|
static IMAGES_AND_VIDEOS_SETTINGS = [
|
||||||
|
'urlPreviewsEnabled',
|
||||||
|
'autoplayGifsAndVideos',
|
||||||
|
'showImages',
|
||||||
|
];
|
||||||
|
static TIMELINE_SETTINGS = [
|
||||||
|
'showTypingNotifications',
|
||||||
|
'showRedactions',
|
||||||
|
'showReadReceipts',
|
||||||
|
'showJoinLeaves',
|
||||||
|
'showDisplaynameChanges',
|
||||||
|
'showChatEffects',
|
||||||
|
'showAvatarChanges',
|
||||||
|
'Pill.shouldShowPillAvatar',
|
||||||
|
'TextualBody.enableBigEmoji',
|
||||||
|
'scrollToBottomOnMessageSent',
|
||||||
|
];
|
||||||
static GENERAL_SETTINGS = [
|
static GENERAL_SETTINGS = [
|
||||||
'TagPanel.enableTagPanel',
|
'TagPanel.enableTagPanel',
|
||||||
'promptBeforeInviteUnknownUsers',
|
'promptBeforeInviteUnknownUsers',
|
||||||
|
@ -222,11 +232,34 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
|
||||||
{this.renderGroup(PreferencesUserSettingsTab.ROOM_LIST_SETTINGS)}
|
{this.renderGroup(PreferencesUserSettingsTab.ROOM_LIST_SETTINGS)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="mx_SettingsTab_section">
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Keyboard shortcuts")}</span>
|
||||||
|
<AccessibleButton className="mx_SettingsFlag" onClick={KeyboardShortcuts.toggleDialog}>
|
||||||
|
{ _t("To view all keyboard shortcuts, click here.") }
|
||||||
|
</AccessibleButton>
|
||||||
|
{this.renderGroup(PreferencesUserSettingsTab.KEYBINDINGS_SETTINGS)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mx_SettingsTab_section">
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Displaying time")}</span>
|
||||||
|
{this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mx_SettingsTab_section">
|
<div className="mx_SettingsTab_section">
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Composer")}</span>
|
<span className="mx_SettingsTab_subheading">{_t("Composer")}</span>
|
||||||
{this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS)}
|
{this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="mx_SettingsTab_section">
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Code blocks")}</span>
|
||||||
|
{this.renderGroup(PreferencesUserSettingsTab.CODE_BLOCKS_SETTINGS)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mx_SettingsTab_section">
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Images, GIFs and videos")}</span>
|
||||||
|
{this.renderGroup(PreferencesUserSettingsTab.IMAGES_AND_VIDEOS_SETTINGS)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mx_SettingsTab_section">
|
<div className="mx_SettingsTab_section">
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Timeline")}</span>
|
<span className="mx_SettingsTab_subheading">{_t("Timeline")}</span>
|
||||||
{this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS)}
|
{this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS)}
|
||||||
|
|
|
@ -17,6 +17,8 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { _t } from "../../../../../languageHandler";
|
import { _t } from "../../../../../languageHandler";
|
||||||
import SdkConfig from "../../../../../SdkConfig";
|
import SdkConfig from "../../../../../SdkConfig";
|
||||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||||
|
@ -25,7 +27,6 @@ import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
import Analytics from "../../../../../Analytics";
|
import Analytics from "../../../../../Analytics";
|
||||||
import Modal from "../../../../../Modal";
|
import Modal from "../../../../../Modal";
|
||||||
import * as sdk from "../../../../..";
|
import * as sdk from "../../../../..";
|
||||||
import { sleep } from "../../../../../utils/promise";
|
|
||||||
import dis from "../../../../../dispatcher/dispatcher";
|
import dis from "../../../../../dispatcher/dispatcher";
|
||||||
import { privateShouldBeEncrypted } from "../../../../../createRoom";
|
import { privateShouldBeEncrypted } from "../../../../../createRoom";
|
||||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||||
|
|
|
@ -16,11 +16,11 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import { copyPlaintext } from "../../../utils/strings";
|
import { copyPlaintext } from "../../../utils/strings";
|
||||||
import { sleep } from "../../../utils/promise";
|
|
||||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||||
import { showRoomInviteDialog } from "../../../RoomInvite";
|
import { showRoomInviteDialog } from "../../../RoomInvite";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
|
|
|
@ -850,8 +850,8 @@
|
||||||
"Enable big emoji in chat": "Enable big emoji in chat",
|
"Enable big emoji in chat": "Enable big emoji in chat",
|
||||||
"Send typing notifications": "Send typing notifications",
|
"Send typing notifications": "Send typing notifications",
|
||||||
"Show typing notifications": "Show typing notifications",
|
"Show typing notifications": "Show typing notifications",
|
||||||
"Use Command + F to search": "Use Command + F to search",
|
"Use Command + F to search timeline": "Use Command + F to search timeline",
|
||||||
"Use Ctrl + F to search": "Use Ctrl + F to search",
|
"Use Ctrl + F to search timeline": "Use Ctrl + F to search timeline",
|
||||||
"Use Command + Enter to send a message": "Use Command + Enter to send a message",
|
"Use Command + Enter to send a message": "Use Command + Enter to send a message",
|
||||||
"Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message",
|
"Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message",
|
||||||
"Automatically replace plain text Emoji": "Automatically replace plain text Emoji",
|
"Automatically replace plain text Emoji": "Automatically replace plain text Emoji",
|
||||||
|
@ -1348,7 +1348,12 @@
|
||||||
"Show tray icon and minimize window to it on close": "Show tray icon and minimize window to it on close",
|
"Show tray icon and minimize window to it on close": "Show tray icon and minimize window to it on close",
|
||||||
"Preferences": "Preferences",
|
"Preferences": "Preferences",
|
||||||
"Room list": "Room list",
|
"Room list": "Room list",
|
||||||
|
"Keyboard shortcuts": "Keyboard shortcuts",
|
||||||
|
"To view all keyboard shortcuts, click here.": "To view all keyboard shortcuts, click here.",
|
||||||
|
"Displaying time": "Displaying time",
|
||||||
"Composer": "Composer",
|
"Composer": "Composer",
|
||||||
|
"Code blocks": "Code blocks",
|
||||||
|
"Images, GIFs and videos": "Images, GIFs and videos",
|
||||||
"Timeline": "Timeline",
|
"Timeline": "Timeline",
|
||||||
"Autocomplete delay (ms)": "Autocomplete delay (ms)",
|
"Autocomplete delay (ms)": "Autocomplete delay (ms)",
|
||||||
"Read Marker lifetime (ms)": "Read Marker lifetime (ms)",
|
"Read Marker lifetime (ms)": "Read Marker lifetime (ms)",
|
||||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
||||||
|
|
||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
|
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
|
||||||
import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
|
import { Direction, EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
|
||||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||||
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
import { EventTimelineSet } from 'matrix-js-sdk/src/models/event-timeline-set';
|
import { EventTimelineSet } from 'matrix-js-sdk/src/models/event-timeline-set';
|
||||||
import { RoomState } from 'matrix-js-sdk/src/models/room-state';
|
import { RoomState } from 'matrix-js-sdk/src/models/room-state';
|
||||||
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
|
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import PlatformPeg from "../PlatformPeg";
|
import PlatformPeg from "../PlatformPeg";
|
||||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||||
import { sleep } from "../utils/promise";
|
|
||||||
import SettingsStore from "../settings/SettingsStore";
|
import SettingsStore from "../settings/SettingsStore";
|
||||||
import { SettingLevel } from "../settings/SettingLevel";
|
import { SettingLevel } from "../settings/SettingLevel";
|
||||||
import { ICrawlerCheckpoint, ILoadArgs, ISearchArgs } from "./BaseEventIndexManager";
|
import { ICrawlerCheckpoint, ILoadArgs, ISearchArgs } from "./BaseEventIndexManager";
|
||||||
|
@ -109,7 +109,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
// our message crawler.
|
// our message crawler.
|
||||||
await Promise.all(encryptedRooms.map(async (room) => {
|
await Promise.all(encryptedRooms.map(async (room) => {
|
||||||
const timeline = room.getLiveTimeline();
|
const timeline = room.getLiveTimeline();
|
||||||
const token = timeline.getPaginationToken("b");
|
const token = timeline.getPaginationToken(Direction.Backward);
|
||||||
|
|
||||||
const backCheckpoint: ICrawlerCheckpoint = {
|
const backCheckpoint: ICrawlerCheckpoint = {
|
||||||
roomId: room.roomId,
|
roomId: room.roomId,
|
||||||
|
@ -371,7 +371,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|
||||||
const timeline = room.getLiveTimeline();
|
const timeline = room.getLiveTimeline();
|
||||||
const token = timeline.getPaginationToken("b");
|
const token = timeline.getPaginationToken(Direction.Backward);
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
// The room doesn't contain any tokens, meaning the live timeline
|
// The room doesn't contain any tokens, meaning the live timeline
|
||||||
|
@ -862,7 +862,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
* @returns {Promise<boolean>} Resolves to a boolean which is true if more
|
* @returns {Promise<boolean>} Resolves to a boolean which is true if more
|
||||||
* events were successfully retrieved.
|
* events were successfully retrieved.
|
||||||
*/
|
*/
|
||||||
public paginateTimelineWindow(room: Room, timelineWindow: TimelineWindow, direction: string, limit: number) {
|
public paginateTimelineWindow(room: Room, timelineWindow: TimelineWindow, direction: Direction, limit: number) {
|
||||||
const tl = timelineWindow.getTimelineIndex(direction);
|
const tl = timelineWindow.getTimelineIndex(direction);
|
||||||
|
|
||||||
if (!tl) return Promise.resolve(false);
|
if (!tl) return Promise.resolve(false);
|
||||||
|
|
|
@ -455,7 +455,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
},
|
},
|
||||||
"ctrlFForSearch": {
|
"ctrlFForSearch": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
displayName: isMac ? _td("Use Command + F to search") : _td("Use Ctrl + F to search"),
|
displayName: isMac ? _td("Use Command + F to search timeline") : _td("Use Ctrl + F to search timeline"),
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
"MessageComposerInput.ctrlEnterToSend": {
|
"MessageComposerInput.ctrlEnterToSend": {
|
||||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixError } from "matrix-js-sdk/src/http-api";
|
import { MatrixError } from "matrix-js-sdk/src/http-api";
|
||||||
|
import { defer, IDeferred } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
import { AddressType, getAddressType } from '../UserAddress';
|
import { AddressType, getAddressType } from '../UserAddress';
|
||||||
|
@ -22,7 +23,6 @@ import GroupStore from '../stores/GroupStore';
|
||||||
import { _t } from "../languageHandler";
|
import { _t } from "../languageHandler";
|
||||||
import Modal from "../Modal";
|
import Modal from "../Modal";
|
||||||
import SettingsStore from "../settings/SettingsStore";
|
import SettingsStore from "../settings/SettingsStore";
|
||||||
import { defer, IDeferred } from "./promise";
|
|
||||||
import AskInviteAnywayDialog from "../components/views/dialogs/AskInviteAnywayDialog";
|
import AskInviteAnywayDialog from "../components/views/dialogs/AskInviteAnywayDialog";
|
||||||
|
|
||||||
export enum InviteState {
|
export enum InviteState {
|
||||||
|
|
|
@ -14,11 +14,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Returns a promise which resolves with a given value after the given number of ms
|
|
||||||
export function sleep<T>(ms: number, value?: T): Promise<T> {
|
|
||||||
return new Promise((resolve => { setTimeout(resolve, ms, value); }));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a promise which resolves when the input promise resolves with its value
|
// Returns a promise which resolves when the input promise resolves with its value
|
||||||
// or when the timeout of ms is reached with the value of given timeoutValue
|
// or when the timeout of ms is reached with the value of given timeoutValue
|
||||||
export async function timeout<T>(promise: Promise<T>, timeoutValue: T, ms: number): Promise<T> {
|
export async function timeout<T>(promise: Promise<T>, timeoutValue: T, ms: number): Promise<T> {
|
||||||
|
@ -32,25 +27,6 @@ export async function timeout<T>(promise: Promise<T>, timeoutValue: T, ms: numbe
|
||||||
return Promise.race([promise, timeoutPromise]);
|
return Promise.race([promise, timeoutPromise]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDeferred<T> {
|
|
||||||
resolve: (value: T) => void;
|
|
||||||
reject: (any) => void;
|
|
||||||
promise: Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a Deferred
|
|
||||||
export function defer<T>(): IDeferred<T> {
|
|
||||||
let resolve;
|
|
||||||
let reject;
|
|
||||||
|
|
||||||
const promise = new Promise<T>((_resolve, _reject) => {
|
|
||||||
resolve = _resolve;
|
|
||||||
reject = _reject;
|
|
||||||
});
|
|
||||||
|
|
||||||
return { resolve, reject, promise };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method to retry a Promise a given number of times or until a predicate fails
|
// Helper method to retry a Promise a given number of times or until a predicate fails
|
||||||
export async function retry<T, E extends Error>(fn: () => Promise<T>, num: number, predicate?: (e: E) => boolean) {
|
export async function retry<T, E extends Error>(fn: () => Promise<T>, num: number, predicate?: (e: E) => boolean) {
|
||||||
let lastErr: E;
|
let lastErr: E;
|
||||||
|
|
|
@ -18,12 +18,12 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import ReactTestUtils from 'react-dom/test-utils';
|
import ReactTestUtils from 'react-dom/test-utils';
|
||||||
import MatrixReactTestUtils from 'matrix-react-test-utils';
|
import MatrixReactTestUtils from 'matrix-react-test-utils';
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import sdk from '../../../skinned-sdk';
|
import sdk from '../../../skinned-sdk';
|
||||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||||
|
|
||||||
import * as TestUtilsMatrix from '../../../test-utils';
|
import * as TestUtilsMatrix from '../../../test-utils';
|
||||||
import { sleep } from "../../../../src/utils/promise";
|
|
||||||
|
|
||||||
const InteractiveAuthDialog = sdk.getComponent(
|
const InteractiveAuthDialog = sdk.getComponent(
|
||||||
'views.dialogs.InteractiveAuthDialog',
|
'views.dialogs.InteractiveAuthDialog',
|
||||||
|
|
|
@ -19,6 +19,8 @@ import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||||
import { configure, mount } from "enzyme";
|
import { configure, mount } from "enzyme";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { act } from "react-dom/test-utils";
|
import { act } from "react-dom/test-utils";
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import SendMessageComposer, {
|
import SendMessageComposer, {
|
||||||
createMessageContent,
|
createMessageContent,
|
||||||
isQuickReaction,
|
isQuickReaction,
|
||||||
|
@ -29,7 +31,6 @@ import { createPartCreator, createRenderer } from "../../../editor/mock";
|
||||||
import { createTestClient, mkEvent, mkStubRoom } from "../../../test-utils";
|
import { createTestClient, mkEvent, mkStubRoom } from "../../../test-utils";
|
||||||
import BasicMessageComposer from "../../../../src/components/views/rooms/BasicMessageComposer";
|
import BasicMessageComposer from "../../../../src/components/views/rooms/BasicMessageComposer";
|
||||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||||
import { sleep } from "../../../../src/utils/promise";
|
|
||||||
import SpecPermalinkConstructor from "../../../../src/utils/permalinks/SpecPermalinkConstructor";
|
import SpecPermalinkConstructor from "../../../../src/utils/permalinks/SpecPermalinkConstructor";
|
||||||
import defaultDispatcher from "../../../../src/dispatcher/dispatcher";
|
import defaultDispatcher from "../../../../src/dispatcher/dispatcher";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue