forked from Mirrors/gomuks
web/timeline: fix rendering replies to non-message events
This commit is contained in:
parent
d73cf4d863
commit
e1c937849e
3 changed files with 58 additions and 46 deletions
|
@ -18,7 +18,7 @@ import { getAvatarURL } from "@/api/media.ts"
|
|||
import { RoomStateStore, useRoomEvent } from "@/api/statestore"
|
||||
import type { EventID, MemDBEvent, MemberEventContent } from "@/api/types"
|
||||
import { ClientContext } from "../ClientContext.ts"
|
||||
import { TextMessageBody } from "./content/MessageBody.tsx"
|
||||
import getBodyType from "./content/getBodyType.ts"
|
||||
import CloseButton from "@/icons/close.svg?react"
|
||||
import "./ReplyBody.css"
|
||||
|
||||
|
@ -65,6 +65,7 @@ const onClickReply = (evt: React.MouseEvent) => {
|
|||
export const ReplyBody = ({ room, event, onClose }: ReplyBodyProps) => {
|
||||
const memberEvt = room.getStateEvent("m.room.member", event.sender)
|
||||
const memberEvtContent = memberEvt?.content as MemberEventContent | undefined
|
||||
const BodyType = getBodyType(event, true)
|
||||
return <blockquote
|
||||
data-reply-to={event.event_id}
|
||||
className={`reply-body ${onClose ? "composer" : ""}`}
|
||||
|
@ -82,6 +83,6 @@ export const ReplyBody = ({ room, event, onClose }: ReplyBodyProps) => {
|
|||
<span className="event-sender">{memberEvtContent?.displayname || event.sender}</span>
|
||||
{onClose && <button className="close-reply" onClick={onClose}><CloseButton/></button>}
|
||||
</div>
|
||||
<TextMessageBody room={room} event={event}/>
|
||||
<BodyType room={room} event={event}/>
|
||||
</blockquote>
|
||||
}
|
||||
|
|
|
@ -21,11 +21,9 @@ import { isEventID } from "@/util/validation.ts"
|
|||
import { ClientContext } from "../ClientContext.ts"
|
||||
import { LightboxContext } from "../Lightbox.tsx"
|
||||
import { ReplyIDBody } from "./ReplyBody.tsx"
|
||||
import EncryptedBody from "./content/EncryptedBody.tsx"
|
||||
import HiddenEvent from "./content/HiddenEvent.tsx"
|
||||
import MemberBody from "./content/MemberBody.tsx"
|
||||
import { MediaMessageBody, TextMessageBody, UnknownMessageBody } from "./content/MessageBody.tsx"
|
||||
import RedactedBody from "./content/RedactedBody.tsx"
|
||||
import getBodyType from "./content/getBodyType.ts"
|
||||
import { EventContentProps } from "./content/props.ts"
|
||||
import ErrorIcon from "../../icons/error.svg?react"
|
||||
import PendingIcon from "../../icons/pending.svg?react"
|
||||
|
@ -39,47 +37,6 @@ export interface TimelineEventProps {
|
|||
setReplyToRef: React.RefObject<(evt: EventID | null) => void>
|
||||
}
|
||||
|
||||
function getBodyType(evt: MemDBEvent): React.FunctionComponent<EventContentProps> {
|
||||
if (evt.relation_type === "m.replace") {
|
||||
return HiddenEvent
|
||||
}
|
||||
switch (evt.type) {
|
||||
case "m.room.message":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
}
|
||||
switch (evt.content.msgtype) {
|
||||
case "m.text":
|
||||
case "m.notice":
|
||||
case "m.emote":
|
||||
return TextMessageBody
|
||||
case "m.image":
|
||||
case "m.video":
|
||||
case "m.audio":
|
||||
case "m.file":
|
||||
return MediaMessageBody
|
||||
case "m.location":
|
||||
// return LocationMessageBody
|
||||
// fallthrough
|
||||
default:
|
||||
return UnknownMessageBody
|
||||
}
|
||||
case "m.sticker":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
}
|
||||
return MediaMessageBody
|
||||
case "m.room.encrypted":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
}
|
||||
return EncryptedBody
|
||||
case "m.room.member":
|
||||
return MemberBody
|
||||
}
|
||||
return HiddenEvent
|
||||
}
|
||||
|
||||
const fullTimeFormatter = new Intl.DateTimeFormat("en-GB", { dateStyle: "full", timeStyle: "medium" })
|
||||
const dateFormatter = new Intl.DateTimeFormat("en-GB", { dateStyle: "full" })
|
||||
const formatShortTime = (time: Date) =>
|
||||
|
|
54
web/src/ui/timeline/content/getBodyType.ts
Normal file
54
web/src/ui/timeline/content/getBodyType.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import React from "react"
|
||||
import { MemDBEvent } from "@/api/types"
|
||||
import EncryptedBody from "./EncryptedBody.tsx"
|
||||
import HiddenEvent from "./HiddenEvent.tsx"
|
||||
import MemberBody from "./MemberBody.tsx"
|
||||
import { MediaMessageBody, TextMessageBody, UnknownMessageBody } from "./MessageBody.tsx"
|
||||
import RedactedBody from "./RedactedBody.tsx"
|
||||
import { EventContentProps } from "./props.ts"
|
||||
|
||||
export default function getBodyType(evt: MemDBEvent, forReply = false): React.FunctionComponent<EventContentProps> {
|
||||
if (evt.relation_type === "m.replace") {
|
||||
return HiddenEvent
|
||||
}
|
||||
switch (evt.type) {
|
||||
case "m.room.message":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
}
|
||||
switch (evt.content.msgtype) {
|
||||
case "m.text":
|
||||
case "m.notice":
|
||||
case "m.emote":
|
||||
return TextMessageBody
|
||||
case "m.image":
|
||||
case "m.video":
|
||||
case "m.audio":
|
||||
case "m.file":
|
||||
if (forReply) {
|
||||
return TextMessageBody
|
||||
}
|
||||
return MediaMessageBody
|
||||
case "m.location":
|
||||
// return LocationMessageBody
|
||||
// fallthrough
|
||||
default:
|
||||
return UnknownMessageBody
|
||||
}
|
||||
case "m.sticker":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
} else if (forReply) {
|
||||
return TextMessageBody
|
||||
}
|
||||
return MediaMessageBody
|
||||
case "m.room.encrypted":
|
||||
if (evt.redacted_by) {
|
||||
return RedactedBody
|
||||
}
|
||||
return EncryptedBody
|
||||
case "m.room.member":
|
||||
return MemberBody
|
||||
}
|
||||
return HiddenEvent
|
||||
}
|
Loading…
Add table
Reference in a new issue