Merge branch 'develop' into midhun/fix-spotlight-1

This commit is contained in:
Michael Telatynski 2024-11-13 15:38:56 +00:00 committed by GitHub
commit ec96d33ed7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
215 changed files with 3574 additions and 2704 deletions

View file

@ -31,4 +31,3 @@ export const BackdropPanel: React.FC<IProps> = ({ backgroundImage, blurMultiplie
</div>
);
};
export default BackdropPanel;

View file

@ -49,11 +49,10 @@ import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../LegacyCallHandl
import AudioFeedArrayForLegacyCall from "../views/voip/AudioFeedArrayForLegacyCall";
import { OwnProfileStore } from "../../stores/OwnProfileStore";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import RoomView from "./RoomView";
import type { RoomView as RoomViewType } from "./RoomView";
import { RoomView } from "./RoomView";
import ToastContainer from "./ToastContainer";
import UserView from "./UserView";
import BackdropPanel from "./BackdropPanel";
import { BackdropPanel } from "./BackdropPanel";
import { mediaFromMxc } from "../../customisations/Media";
import { UserTab } from "../views/dialogs/UserTab";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
@ -125,7 +124,7 @@ class LoggedInView extends React.Component<IProps, IState> {
public static displayName = "LoggedInView";
protected readonly _matrixClient: MatrixClient;
protected readonly _roomView: React.RefObject<RoomViewType>;
protected readonly _roomView: React.RefObject<RoomView>;
protected readonly _resizeContainer: React.RefObject<HTMLDivElement>;
protected readonly resizeHandler: React.RefObject<HTMLDivElement>;
protected layoutWatcherRef?: string;

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import React, { createRef } from "react";
import React, { createRef, lazy } from "react";
import {
ClientEvent,
createClient,
@ -28,8 +28,6 @@ import { TooltipProvider } from "@vector-im/compound-web";
// what-input helps improve keyboard accessibility
import "what-input";
import type NewRecoveryMethodDialog from "../../async-components/views/dialogs/security/NewRecoveryMethodDialog";
import type RecoveryMethodRemovedDialog from "../../async-components/views/dialogs/security/RecoveryMethodRemovedDialog";
import PosthogTrackers from "../../PosthogTrackers";
import { DecryptionFailureTracker } from "../../DecryptionFailureTracker";
import { IMatrixClientCreds, MatrixClientPeg } from "../../MatrixClientPeg";
@ -1649,16 +1647,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
if (haveNewVersion) {
Modal.createDialogAsync(
import(
"../../async-components/views/dialogs/security/NewRecoveryMethodDialog"
) as unknown as Promise<typeof NewRecoveryMethodDialog>,
Modal.createDialog(
lazy(() => import("../../async-components/views/dialogs/security/NewRecoveryMethodDialog")),
);
} else {
Modal.createDialogAsync(
import(
"../../async-components/views/dialogs/security/RecoveryMethodRemovedDialog"
) as unknown as Promise<typeof RecoveryMethodRemovedDialog>,
Modal.createDialog(
lazy(() => import("../../async-components/views/dialogs/security/RecoveryMethodRemovedDialog")),
);
}
});

View file

@ -45,7 +45,7 @@ import ResizeNotifier from "../../utils/ResizeNotifier";
import ContentMessages from "../../ContentMessages";
import Modal from "../../Modal";
import { LegacyCallHandlerEvent } from "../../LegacyCallHandler";
import dis, { defaultDispatcher } from "../../dispatcher/dispatcher";
import defaultDispatcher from "../../dispatcher/dispatcher";
import * as Rooms from "../../Rooms";
import MainSplit from "./MainSplit";
import RightPanel from "./RightPanel";
@ -437,7 +437,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
private onWidgetLayoutChange = (): void => {
if (!this.state.room) return;
dis.dispatch({
defaultDispatcher.dispatch({
action: "appsDrawer",
show: true,
});
@ -598,7 +598,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// Handle the use case of a link to a thread message
// ie: #/room/roomId/eventId (eventId of a thread message)
if (thread?.rootEvent && !initialEvent?.isThreadRoot) {
dis.dispatch<ShowThreadPayload>({
defaultDispatcher.dispatch<ShowThreadPayload>({
action: Action.ShowThread,
rootEvent: thread.rootEvent,
initialEvent,
@ -704,7 +704,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const activeCall = CallStore.instance.getActiveCall(this.state.roomId);
if (activeCall === null) {
// We disconnected from the call, so stop viewing it
dis.dispatch<ViewRoomPayload>(
defaultDispatcher.dispatch<ViewRoomPayload>(
{
action: Action.ViewRoom,
room_id: this.state.roomId,
@ -850,7 +850,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
public componentDidMount(): void {
this.unmounted = false;
this.dispatcherRef = dis.register(this.onAction);
this.dispatcherRef = defaultDispatcher.register(this.onAction);
if (this.context.client) {
this.context.client.on(ClientEvent.Room, this.onRoom);
this.context.client.on(RoomEvent.Timeline, this.onRoomTimeline);
@ -967,7 +967,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// stop tracking room changes to format permalinks
this.stopAllPermalinkCreators();
dis.unregister(this.dispatcherRef);
defaultDispatcher.unregister(this.dispatcherRef);
if (this.context.client) {
this.context.client.removeListener(ClientEvent.Room, this.onRoom);
this.context.client.removeListener(RoomEvent.Timeline, this.onRoomTimeline);
@ -1045,7 +1045,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
handled = true;
break;
case KeyBindingAction.UploadFile: {
dis.dispatch(
defaultDispatcher.dispatch(
{
action: "upload_file",
context: TimelineRenderingType.Room,
@ -1145,7 +1145,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
if (payload.event && payload.event.getRoomId() !== this.state.roomId) {
// If the event is in a different room (e.g. because the event to be edited is being displayed
// in the results of an all-rooms search), we need to view that room first.
dis.dispatch<ViewRoomPayload>({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: payload.event.getRoomId(),
metricsTrigger: undefined,
@ -1188,7 +1188,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}
// re-dispatch to the correct composer
dis.dispatch<ComposerInsertPayload>({
defaultDispatcher.dispatch<ComposerInsertPayload>({
...(payload as ComposerInsertPayload),
timelineRenderingType,
composerType: this.state.editState ? ComposerType.Edit : ComposerType.Send,
@ -1197,7 +1197,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}
case Action.FocusAComposer: {
dis.dispatch<FocusComposerPayload>({
defaultDispatcher.dispatch<FocusComposerPayload>({
...(payload as FocusComposerPayload),
// re-dispatch to the correct composer (the send message will still be on screen even when editing a message)
action: this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer,
@ -1303,7 +1303,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) {
// For initial threads launch, chat effects are disabled see #19731
if (!ev.isRelation(THREAD_RELATION_TYPE.name)) {
dis.dispatch({ action: `effects.${effect.command}`, event: ev });
defaultDispatcher.dispatch({ action: `effects.${effect.command}`, event: ev });
}
}
});
@ -1363,7 +1363,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
liveTimeline: room.getLiveTimeline(),
});
dis.dispatch<ActionPayload>({ action: Action.RoomLoaded });
defaultDispatcher.dispatch<ActionPayload>({ action: Action.RoomLoaded });
};
private onRoomTimelineReset = (room?: Room): void => {
@ -1561,7 +1561,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
private onInviteClick = (): void => {
// open the room inviter
dis.dispatch({
defaultDispatcher.dispatch({
action: "view_invite",
roomId: this.getRoomId(),
});
@ -1572,7 +1572,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
if (this.context.client?.isGuest()) {
// Join this room once the user has registered and logged in
// (If we failed to peek, we may not have a valid room object.)
dis.dispatch<DoAfterSyncPreparedPayload<ViewRoomPayload>>({
defaultDispatcher.dispatch<DoAfterSyncPreparedPayload<ViewRoomPayload>>({
action: Action.DoAfterSyncPrepared,
deferred_action: {
action: Action.ViewRoom,
@ -1580,13 +1580,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
metricsTrigger: undefined,
},
});
dis.dispatch({ action: "require_registration" });
defaultDispatcher.dispatch({ action: "require_registration" });
} else {
Promise.resolve().then(() => {
const signUrl = this.props.threepidInvite?.signUrl;
const roomId = this.getRoomId();
if (isNotUndefined(roomId)) {
dis.dispatch<JoinRoomPayload>({
defaultDispatcher.dispatch<JoinRoomPayload>({
action: Action.JoinRoom,
roomId,
opts: { inviteSignUrl: signUrl },
@ -1622,7 +1622,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.state.initialEventId === eventId
) {
debuglog("Removing scroll_into_view flag from initial event");
dis.dispatch<ViewRoomPayload>({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: this.getRoomId(),
event_id: this.state.initialEventId,
@ -1638,7 +1638,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const roomId = this.getRoomId();
if (!this.context.client || !roomId) return;
if (this.context.client.isGuest()) {
dis.dispatch({ action: "require_registration" });
defaultDispatcher.dispatch({ action: "require_registration" });
return;
}
@ -1688,7 +1688,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
};
private onForgetClick = (): void => {
dis.dispatch({
defaultDispatcher.dispatch({
action: "forget_room",
room_id: this.getRoomId(),
});
@ -1702,7 +1702,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
});
this.context.client?.leave(roomId).then(
() => {
dis.dispatch({ action: Action.ViewHomePage });
defaultDispatcher.dispatch({ action: Action.ViewHomePage });
this.setState({
rejecting: false,
});
@ -1736,7 +1736,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
await this.context.client!.setIgnoredUsers(ignoredUsers);
await this.context.client!.leave(this.state.roomId!);
dis.dispatch({ action: Action.ViewHomePage });
defaultDispatcher.dispatch({ action: Action.ViewHomePage });
this.setState({
rejecting: false,
});
@ -1760,7 +1760,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// using /leave rather than /join. In the short term though, we
// just ignore them.
// https://github.com/vector-im/vector-web/issues/1134
dis.fire(Action.ViewRoomDirectory);
defaultDispatcher.fire(Action.ViewRoomDirectory);
};
private onSearchChange = debounce((e: ChangeEvent): void => {
@ -1786,7 +1786,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// If we were viewing a highlighted event, firing view_room without
// an event will take care of both clearing the URL fragment and
// jumping to the bottom
dis.dispatch<ViewRoomPayload>({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: this.getRoomId(),
metricsTrigger: undefined, // room doesn't change
@ -1794,7 +1794,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
} else {
// Otherwise we have to jump manually
this.messagePanel?.jumpToLiveTimeline();
dis.fire(Action.FocusSendMessageComposer);
defaultDispatcher.fire(Action.FocusSendMessageComposer);
}
};
@ -1918,7 +1918,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
public onHiddenHighlightsClick = (): void => {
const oldRoom = this.getOldRoom();
if (!oldRoom) return;
dis.dispatch<ViewRoomPayload>({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: oldRoom.roomId,
metricsTrigger: "Predecessor",
@ -2001,7 +2001,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const roomId = this.getRoomId();
if (isNotUndefined(roomId)) {
dis.dispatch<SubmitAskToJoinPayload>({
defaultDispatcher.dispatch<SubmitAskToJoinPayload>({
action: Action.SubmitAskToJoin,
roomId,
opts: { reason },
@ -2018,7 +2018,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const roomId = this.getRoomId();
if (isNotUndefined(roomId)) {
dis.dispatch<CancelAskToJoinPayload>({
defaultDispatcher.dispatch<CancelAskToJoinPayload>({
action: Action.CancelAskToJoin,
roomId,
});
@ -2547,5 +2547,3 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
);
}
}
export default RoomView;

View file

@ -1217,7 +1217,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
return;
}
const lastDisplayedEvent = this.state.events[lastDisplayedIndex];
this.setReadMarker(lastDisplayedEvent.getId()!, lastDisplayedEvent.getTs());
await this.setReadMarker(lastDisplayedEvent.getId()!, lastDisplayedEvent.getTs());
// the read-marker should become invisible, so that if the user scrolls
// down, they don't see it.
@ -1335,7 +1335,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
}
// Update the read marker to the values we found
this.setReadMarker(rmId, rmTs);
await this.setReadMarker(rmId, rmTs);
// Send the receipts to the server immediately (don't wait for activity)
await this.sendReadReceipts();
@ -1866,7 +1866,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
return receiptStore?.getEventReadUpTo(myUserId, ignoreSynthesized) ?? null;
}
private setReadMarker(eventId: string | null, eventTs?: number, inhibitSetState = false): void {
private async setReadMarker(eventId: string | null, eventTs?: number, inhibitSetState = false): Promise<void> {
const roomId = this.props.timelineSet.room?.roomId;
// don't update the state (and cause a re-render) if there is
@ -1890,12 +1890,17 @@ class TimelinePanel extends React.Component<IProps, IState> {
// Do the local echo of the RM
// run the render cycle before calling the callback, so that
// getReadMarkerPosition() returns the right thing.
this.setState(
{
readMarkerEventId: eventId,
},
this.props.onReadMarkerUpdated,
);
await new Promise<void>((resolve) => {
this.setState(
{
readMarkerEventId: eventId,
},
() => {
this.props.onReadMarkerUpdated?.();
resolve();
},
);
});
}
private shouldPaginate(): boolean {

View file

@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
import React, { ReactNode } from "react";
import { Tooltip } from "@vector-im/compound-web";
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import AccessibleButton from "../../../views/elements/AccessibleButton";
import { Icon as EMailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
import { _t } from "../../../../languageHandler";
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
import { ErrorMessage } from "../../ErrorMessage";
@ -60,7 +60,7 @@ export const CheckEmail: React.FC<CheckEmailProps> = ({
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
<RetryIcon className="mx_Icon mx_Icon_16" />
<RestartIcon className="mx_Icon mx_Icon_16" />
{_t("action|resend")}
</AccessibleButton>
</Tooltip>

View file

@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
import React, { ReactNode } from "react";
import { Tooltip } from "@vector-im/compound-web";
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import { _t } from "../../../../languageHandler";
import AccessibleButton from "../../../views/elements/AccessibleButton";
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
import { Icon as EmailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
import { ErrorMessage } from "../../ErrorMessage";
@ -59,7 +59,7 @@ export const VerifyEmailModal: React.FC<Props> = ({
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
<RetryIcon className="mx_Icon mx_Icon_16" />
<RestartIcon className="mx_Icon mx_Icon_16" />
{_t("action|resend")}
</AccessibleButton>
</Tooltip>