Merge branch 'develop' into johannes/find-myself

This commit is contained in:
Johannes Marbach 2023-02-08 16:42:14 +01:00 committed by GitHub
commit f842e319de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 707 additions and 271 deletions

View file

@ -39,7 +39,7 @@ const ZoomButtons: React.FC<Props> = ({ map }) => {
<div className="mx_ZoomButtons">
<AccessibleButton
onClick={onZoomIn}
data-test-id="map-zoom-in-button"
data-testid="map-zoom-in-button"
title={_t("Zoom in")}
className="mx_ZoomButtons_button"
>
@ -47,7 +47,7 @@ const ZoomButtons: React.FC<Props> = ({ map }) => {
</AccessibleButton>
<AccessibleButton
onClick={onZoomOut}
data-test-id="map-zoom-out-button"
data-testid="map-zoom-out-button"
title={_t("Zoom out")}
className="mx_ZoomButtons_button"
>

View file

@ -0,0 +1,109 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useEffect, useState, useContext } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { M_TEXT } from "matrix-js-sdk/src/@types/extensible_events";
import { logger } from "matrix-js-sdk/src/logger";
import { Icon as PollIcon } from "../../../../res/img/element-icons/room/composer/poll.svg";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { textForEvent } from "../../../TextForEvent";
import { IBodyProps } from "./IBodyProps";
import MPollBody from "./MPollBody";
const getRelatedPollStartEventId = (event: MatrixEvent): string | undefined => {
const relation = event.getRelation();
return relation?.event_id;
};
/**
* Attempt to retrieve the related poll start event for this end event
* If the event already exists in the rooms timeline, return it
* Otherwise try to fetch the event from the server
* @param event
* @returns
*/
const usePollStartEvent = (event: MatrixEvent): { pollStartEvent?: MatrixEvent; isLoadingPollStartEvent: boolean } => {
const matrixClient = useContext(MatrixClientContext);
const [pollStartEvent, setPollStartEvent] = useState<MatrixEvent>();
const [isLoadingPollStartEvent, setIsLoadingPollStartEvent] = useState(false);
const pollStartEventId = getRelatedPollStartEventId(event);
useEffect(() => {
const room = matrixClient.getRoom(event.getRoomId());
const fetchPollStartEvent = async (roomId: string, pollStartEventId: string): Promise<void> => {
setIsLoadingPollStartEvent(true);
try {
const startEventJson = await matrixClient.fetchRoomEvent(roomId, pollStartEventId);
const startEvent = new MatrixEvent(startEventJson);
// add the poll to the room polls state
room?.processPollEvents([startEvent, event]);
// end event is not a valid end to the related start event
// if not sent by the same user
if (startEvent.getSender() === event.getSender()) {
setPollStartEvent(startEvent);
}
} catch (error) {
logger.error("Failed to fetch related poll start event", error);
} finally {
setIsLoadingPollStartEvent(false);
}
};
if (pollStartEvent || !room || !pollStartEventId) {
return;
}
const timelineSet = room.getUnfilteredTimelineSet();
const localEvent = timelineSet
?.getTimelineForEvent(pollStartEventId)
?.getEvents()
.find((e) => e.getId() === pollStartEventId);
if (localEvent) {
// end event is not a valid end to the related start event
// if not sent by the same user
if (localEvent.getSender() === event.getSender()) {
setPollStartEvent(localEvent);
}
} else {
// pollStartEvent is not in the current timeline,
// fetch it
fetchPollStartEvent(room.roomId, pollStartEventId);
}
}, [event, pollStartEventId, pollStartEvent, matrixClient]);
return { pollStartEvent, isLoadingPollStartEvent };
};
export const MPollEndBody = React.forwardRef<any, IBodyProps>(({ mxEvent, ...props }, ref) => {
const { pollStartEvent, isLoadingPollStartEvent } = usePollStartEvent(mxEvent);
if (!pollStartEvent) {
const pollEndFallbackMessage = M_TEXT.findIn(mxEvent.getContent()) || textForEvent(mxEvent);
return (
<>
<PollIcon className="mx_MPollEndBody_icon" />
{!isLoadingPollStartEvent && pollEndFallbackMessage}
</>
);
}
return <MPollBody mxEvent={pollStartEvent} {...props} />;
});

View file

@ -18,7 +18,7 @@ import React, { createRef } from "react";
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
import { M_POLL_START } from "matrix-js-sdk/src/@types/polls";
import { M_POLL_END, M_POLL_START } from "matrix-js-sdk/src/@types/polls";
import { MatrixEventEvent } from "matrix-js-sdk/src/models/event";
import SettingsStore from "../../../settings/SettingsStore";
@ -37,6 +37,7 @@ import MVoiceOrAudioBody from "./MVoiceOrAudioBody";
import MVideoBody from "./MVideoBody";
import MStickerBody from "./MStickerBody";
import MPollBody from "./MPollBody";
import { MPollEndBody } from "./MPollEndBody";
import MLocationBody from "./MLocationBody";
import MjolnirBody from "./MjolnirBody";
import MBeaconBody from "./MBeaconBody";
@ -73,6 +74,8 @@ const baseEvTypes = new Map<string, React.ComponentType<Partial<IBodyProps>>>([
[EventType.Sticker, MStickerBody],
[M_POLL_START.name, MPollBody],
[M_POLL_START.altName, MPollBody],
[M_POLL_END.name, MPollEndBody],
[M_POLL_END.altName, MPollEndBody],
[M_BEACON_INFO.name, MBeaconBody],
[M_BEACON_INFO.altName, MBeaconBody],
]);