forked from Mirrors/gomuks
web/timeline: reorganize components slightly
This commit is contained in:
parent
e1c937849e
commit
b67095f0fd
10 changed files with 83 additions and 34 deletions
|
@ -18,7 +18,7 @@ import { getAvatarURL } from "@/api/media.ts"
|
||||||
import { RoomStateStore, useRoomEvent } from "@/api/statestore"
|
import { RoomStateStore, useRoomEvent } from "@/api/statestore"
|
||||||
import type { EventID, MemDBEvent, MemberEventContent } from "@/api/types"
|
import type { EventID, MemDBEvent, MemberEventContent } from "@/api/types"
|
||||||
import { ClientContext } from "../ClientContext.ts"
|
import { ClientContext } from "../ClientContext.ts"
|
||||||
import getBodyType from "./content/getBodyType.ts"
|
import getBodyType from "./content"
|
||||||
import CloseButton from "@/icons/close.svg?react"
|
import CloseButton from "@/icons/close.svg?react"
|
||||||
import "./ReplyBody.css"
|
import "./ReplyBody.css"
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,7 @@ import { isEventID } from "@/util/validation.ts"
|
||||||
import { ClientContext } from "../ClientContext.ts"
|
import { ClientContext } from "../ClientContext.ts"
|
||||||
import { LightboxContext } from "../Lightbox.tsx"
|
import { LightboxContext } from "../Lightbox.tsx"
|
||||||
import { ReplyIDBody } from "./ReplyBody.tsx"
|
import { ReplyIDBody } from "./ReplyBody.tsx"
|
||||||
import HiddenEvent from "./content/HiddenEvent.tsx"
|
import getBodyType, { EventContentProps, HiddenEvent, MemberBody } from "./content"
|
||||||
import MemberBody from "./content/MemberBody.tsx"
|
|
||||||
import getBodyType from "./content/getBodyType.ts"
|
|
||||||
import { EventContentProps } from "./content/props.ts"
|
|
||||||
import ErrorIcon from "../../icons/error.svg?react"
|
import ErrorIcon from "../../icons/error.svg?react"
|
||||||
import PendingIcon from "../../icons/pending.svg?react"
|
import PendingIcon from "../../icons/pending.svg?react"
|
||||||
import SentIcon from "../../icons/sent.svg?react"
|
import SentIcon from "../../icons/sent.svg?react"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { EventContentProps } from "./props.ts"
|
import EventContentProps from "./props.ts"
|
||||||
import LockIcon from "../../../icons/lock.svg?react"
|
import LockIcon from "../../../icons/lock.svg?react"
|
||||||
import LockClockIcon from "../../../icons/lock.svg?react"
|
import LockClockIcon from "../../../icons/lock.svg?react"
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { EventContentProps } from "./props.ts"
|
import EventContentProps from "./props.ts"
|
||||||
|
|
||||||
const HiddenEvent = ({ event }: EventContentProps) => {
|
const HiddenEvent = ({ event }: EventContentProps) => {
|
||||||
return <code>{`{ "type": "${event.type}" }`}</code>
|
return <code>{`{ "type": "${event.type}" }`}</code>
|
||||||
|
|
36
web/src/ui/timeline/content/MediaMessageBody.tsx
Normal file
36
web/src/ui/timeline/content/MediaMessageBody.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import { MediaMessageEventContent } from "@/api/types"
|
||||||
|
import TextMessageBody from "./TextMessageBody.tsx"
|
||||||
|
import EventContentProps from "./props.ts"
|
||||||
|
import { useMediaContent } from "./useMediaContent.tsx"
|
||||||
|
|
||||||
|
const MediaMessageBody = ({ event, room }: EventContentProps) => {
|
||||||
|
const content = event.content as MediaMessageEventContent
|
||||||
|
let caption = null
|
||||||
|
if (content.body && content.filename && content.body !== content.filename) {
|
||||||
|
caption = <TextMessageBody event={event} room={room} />
|
||||||
|
}
|
||||||
|
const [mediaContent, containerClass, containerStyle] = useMediaContent(content, event.type)
|
||||||
|
return <>
|
||||||
|
<div className={`media-container ${containerClass}`} style={containerStyle}>
|
||||||
|
{mediaContent}
|
||||||
|
</div>
|
||||||
|
{caption}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MediaMessageBody
|
|
@ -17,7 +17,7 @@ import React, { use } from "react"
|
||||||
import { getAvatarURL } from "@/api/media.ts"
|
import { getAvatarURL } from "@/api/media.ts"
|
||||||
import { MemberEventContent, UserID } from "@/api/types"
|
import { MemberEventContent, UserID } from "@/api/types"
|
||||||
import { LightboxContext } from "../../Lightbox.tsx"
|
import { LightboxContext } from "../../Lightbox.tsx"
|
||||||
import { EventContentProps } from "./props.ts"
|
import EventContentProps from "./props.ts"
|
||||||
|
|
||||||
function useChangeDescription(
|
function useChangeDescription(
|
||||||
sender: UserID, target: UserID, content: MemberEventContent, prevContent?: MemberEventContent,
|
sender: UserID, target: UserID, content: MemberEventContent, prevContent?: MemberEventContent,
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { MediaMessageEventContent, MemberEventContent, MessageEventContent } from "@/api/types"
|
import { MemberEventContent, MessageEventContent } from "@/api/types"
|
||||||
import { EventContentProps } from "./props.ts"
|
import EventContentProps from "./props.ts"
|
||||||
import { useMediaContent } from "./useMediaContent.tsx"
|
|
||||||
|
|
||||||
const onClickHTML = (evt: React.MouseEvent<HTMLDivElement>) => {
|
const onClickHTML = (evt: React.MouseEvent<HTMLDivElement>) => {
|
||||||
if ((evt.target as HTMLElement).closest("span.hicli-spoiler")?.classList.toggle("spoiler-revealed")) {
|
if ((evt.target as HTMLElement).closest("span.hicli-spoiler")?.classList.toggle("spoiler-revealed")) {
|
||||||
|
@ -24,7 +23,7 @@ const onClickHTML = (evt: React.MouseEvent<HTMLDivElement>) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TextMessageBody = ({ event, room }: EventContentProps) => {
|
const TextMessageBody = ({ event, room }: EventContentProps) => {
|
||||||
const content = event.content as MessageEventContent
|
const content = event.content as MessageEventContent
|
||||||
const classNames = ["message-text"]
|
const classNames = ["message-text"]
|
||||||
let eventSenderName: string | undefined
|
let eventSenderName: string | undefined
|
||||||
|
@ -51,22 +50,4 @@ export const TextMessageBody = ({ event, room }: EventContentProps) => {
|
||||||
return <div className={classNames.join(" ")} data-event-sender={eventSenderName}>{content.body}</div>
|
return <div className={classNames.join(" ")} data-event-sender={eventSenderName}>{content.body}</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MediaMessageBody = ({ event, room }: EventContentProps) => {
|
export default TextMessageBody
|
||||||
const content = event.content as MediaMessageEventContent
|
|
||||||
let caption = null
|
|
||||||
if (content.body && content.filename && content.body !== content.filename) {
|
|
||||||
caption = <TextMessageBody event={event} room={room} />
|
|
||||||
}
|
|
||||||
const [mediaContent, containerClass, containerStyle] = useMediaContent(content, event.type)
|
|
||||||
return <>
|
|
||||||
<div className={`media-container ${containerClass}`} style={containerStyle}>
|
|
||||||
{mediaContent}
|
|
||||||
</div>
|
|
||||||
{caption}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UnknownMessageBody = ({ event }: EventContentProps) => {
|
|
||||||
const content = event.content as MessageEventContent
|
|
||||||
return <code>{`{ "type": "${event.type}", "content": { "msgtype": "${content.msgtype}" } }`}</code>
|
|
||||||
}
|
|
24
web/src/ui/timeline/content/UnknownMessageBody.tsx
Normal file
24
web/src/ui/timeline/content/UnknownMessageBody.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import { MessageEventContent } from "@/api/types"
|
||||||
|
import EventContentProps from "./props.ts"
|
||||||
|
|
||||||
|
const UnknownMessageBody = ({ event }: EventContentProps) => {
|
||||||
|
const content = event.content as MessageEventContent
|
||||||
|
return <code>{`{ "type": "${event.type}", "content": { "msgtype": "${content.msgtype}" } }`}</code>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UnknownMessageBody
|
|
@ -2,10 +2,21 @@ import React from "react"
|
||||||
import { MemDBEvent } from "@/api/types"
|
import { MemDBEvent } from "@/api/types"
|
||||||
import EncryptedBody from "./EncryptedBody.tsx"
|
import EncryptedBody from "./EncryptedBody.tsx"
|
||||||
import HiddenEvent from "./HiddenEvent.tsx"
|
import HiddenEvent from "./HiddenEvent.tsx"
|
||||||
|
import MediaMessageBody from "./MediaMessageBody.tsx"
|
||||||
import MemberBody from "./MemberBody.tsx"
|
import MemberBody from "./MemberBody.tsx"
|
||||||
import { MediaMessageBody, TextMessageBody, UnknownMessageBody } from "./MessageBody.tsx"
|
|
||||||
import RedactedBody from "./RedactedBody.tsx"
|
import RedactedBody from "./RedactedBody.tsx"
|
||||||
import { EventContentProps } from "./props.ts"
|
import TextMessageBody from "./TextMessageBody.tsx"
|
||||||
|
import UnknownMessageBody from "./UnknownMessageBody.tsx"
|
||||||
|
import EventContentProps from "./props.ts"
|
||||||
|
|
||||||
|
export { default as EncryptedBody } from "./EncryptedBody.tsx"
|
||||||
|
export { default as HiddenEvent } from "./HiddenEvent.tsx"
|
||||||
|
export { default as MediaMessageBody } from "./MediaMessageBody.tsx"
|
||||||
|
export { default as MemberBody } from "./MemberBody.tsx"
|
||||||
|
export { default as RedactedBody } from "./RedactedBody.tsx"
|
||||||
|
export { default as TextMessageBody } from "./TextMessageBody.tsx"
|
||||||
|
export { default as UnknownMessageBody } from "./UnknownMessageBody.tsx"
|
||||||
|
export type { default as EventContentProps } from "./props.ts"
|
||||||
|
|
||||||
export default function getBodyType(evt: MemDBEvent, forReply = false): React.FunctionComponent<EventContentProps> {
|
export default function getBodyType(evt: MemDBEvent, forReply = false): React.FunctionComponent<EventContentProps> {
|
||||||
if (evt.relation_type === "m.replace") {
|
if (evt.relation_type === "m.replace") {
|
|
@ -16,7 +16,7 @@
|
||||||
import { RoomStateStore } from "@/api/statestore"
|
import { RoomStateStore } from "@/api/statestore"
|
||||||
import { MemDBEvent } from "@/api/types"
|
import { MemDBEvent } from "@/api/types"
|
||||||
|
|
||||||
export interface EventContentProps {
|
export default interface EventContentProps {
|
||||||
room: RoomStateStore
|
room: RoomStateStore
|
||||||
event: MemDBEvent
|
event: MemDBEvent
|
||||||
sender?: MemDBEvent
|
sender?: MemDBEvent
|
||||||
|
|
Loading…
Add table
Reference in a new issue