// gomuks - A Matrix client written in Go. // Copyright (C) 2024 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import { use } from "react" import { getAvatarURL, getUserColorIndex } from "@/api/media.ts" import { RoomStateStore, useRoomEvent, useRoomState } from "@/api/statestore" import type { EventID, MemDBEvent, MemberEventContent } from "@/api/types" import { getDisplayname } from "@/util/validation.ts" import ClientContext from "../ClientContext.ts" import { ContentErrorBoundary, getBodyType } from "./content" import CloseButton from "@/icons/close.svg?react" import "./ReplyBody.css" interface ReplyBodyProps { room: RoomStateStore event: MemDBEvent isThread: boolean isEditing?: boolean onClose?: (evt: React.MouseEvent) => void } interface ReplyIDBodyProps { room: RoomStateStore eventID: EventID isThread: boolean } export const ReplyIDBody = ({ room, eventID, isThread }: ReplyIDBodyProps) => { const event = useRoomEvent(room, eventID) if (!event) { // This caches whether the event is requested or not, so it doesn't need to be wrapped in an effect. use(ClientContext)!.requestEvent(room, eventID) return
Reply to unknown event
{eventID}
} return } const onClickReply = (evt: React.MouseEvent) => { const targetEvt = document.querySelector( `div[data-event-id="${CSS.escape(evt.currentTarget.getAttribute("data-reply-to") ?? "")}"]`, ) if (targetEvt) { targetEvt.scrollIntoView({ block: "center", }) targetEvt.classList.add("jump-highlight") setTimeout(() => { targetEvt.classList.add("jump-highlight-fadeout") targetEvt.classList.remove("jump-highlight") setTimeout(() => { targetEvt.classList.remove("jump-highlight-fadeout") }, 1500) }, 3000) } } export const ReplyBody = ({ room, event, onClose, isThread, isEditing }: ReplyBodyProps) => { const memberEvt = useRoomState(room, "m.room.member", event.sender) if (!memberEvt) { use(ClientContext)?.requestMemberEvent(room, event.sender) } const memberEvtContent = memberEvt?.content as MemberEventContent | undefined const BodyType = getBodyType(event, true) const classNames = ["reply-body"] if (onClose) { classNames.push("composer") } if (isThread) { classNames.push("thread") } if (isEditing) { classNames.push("editing") } const userColorIndex = getUserColorIndex(event.sender) classNames.push(`sender-color-${userColorIndex}`) return
{getDisplayname(event.sender, memberEvtContent)} {onClose && }
}