mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
web/timeline: allow jumping to reply if it's loaded in the timeline
This commit is contained in:
parent
e6121149b3
commit
3fdaf8ae4e
4 changed files with 40 additions and 4 deletions
|
@ -180,7 +180,10 @@ const MessageComposer = ({ room, scrollToBottomRef, setReplyToRef }: MessageComp
|
|||
}, [room, state])
|
||||
const openFilePicker = useCallback(() => fileInput.current!.click(), [])
|
||||
const clearMedia = useCallback(() => setState({ media: null }), [])
|
||||
const closeReply = useCallback(() => setState({ replyTo: null }), [])
|
||||
const closeReply = useCallback((evt: React.MouseEvent) => {
|
||||
evt.stopPropagation()
|
||||
setState({ replyTo: null })
|
||||
}, [])
|
||||
return <div className="message-composer">
|
||||
{replyToEvt && <ReplyBody room={room} event={replyToEvt} onClose={closeReply}/>}
|
||||
{loadingMedia && <div className="composer-media"><ScaleLoader/></div>}
|
||||
|
|
|
@ -25,7 +25,7 @@ import "./ReplyBody.css"
|
|||
interface ReplyBodyProps {
|
||||
room: RoomStateStore
|
||||
event: MemDBEvent
|
||||
onClose?: () => void
|
||||
onClose?: (evt: React.MouseEvent) => void
|
||||
}
|
||||
|
||||
interface ReplyIDBodyProps {
|
||||
|
@ -45,10 +45,31 @@ export const ReplyIDBody = ({ room, eventID }: ReplyIDBodyProps) => {
|
|||
return <ReplyBody room={room} event={event}/>
|
||||
}
|
||||
|
||||
const onClickReply = (evt: React.MouseEvent) => {
|
||||
const targetEvt = document.querySelector(`div[data-event-id="${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 }: ReplyBodyProps) => {
|
||||
const memberEvt = room.getStateEvent("m.room.member", event.sender)
|
||||
const memberEvtContent = memberEvt?.content as MemberEventContent | undefined
|
||||
return <blockquote className={`reply-body ${onClose ? "composer" : ""}`}>
|
||||
return <blockquote
|
||||
data-reply-to={event.event_id}
|
||||
className={`reply-body ${onClose ? "composer" : ""}`}
|
||||
onClick={onClickReply}
|
||||
>
|
||||
<div className="reply-sender">
|
||||
<div className="sender-avatar" title={event.sender}>
|
||||
<img
|
||||
|
|
|
@ -14,12 +14,24 @@ div.timeline-event {
|
|||
background-color: rgba(255, 255, 0, .1);
|
||||
}
|
||||
|
||||
&.jump-highlight {
|
||||
background-color: rgba(0, 255, 0, .2);
|
||||
}
|
||||
|
||||
&.jump-highlight-fadeout {
|
||||
transition: background-color 1s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
|
||||
&.highlight {
|
||||
background-color: #eec;
|
||||
}
|
||||
|
||||
&.jump-highlight {
|
||||
background-color: #cec;
|
||||
}
|
||||
}
|
||||
|
||||
> div.sender-avatar {
|
||||
|
|
|
@ -135,7 +135,7 @@ const TimelineEvent = ({ room, evt, prevEvt, setReplyToRef }: TimelineEventProps
|
|||
const shortTime = formatShortTime(eventTS)
|
||||
const editTime = editEventTS ? `Edited at ${fullTimeFormatter.format(editEventTS)}` : null
|
||||
const replyTo = (evt.orig_content ?? evt.content)["m.relates_to"]?.["m.in_reply_to"]?.event_id
|
||||
const mainEvent = <div className={wrapperClassNames.join(" ")}>
|
||||
const mainEvent = <div data-event-id={evt.event_id} className={wrapperClassNames.join(" ")}>
|
||||
<div className="sender-avatar" title={evt.sender}>
|
||||
<img
|
||||
className={`${smallAvatar ? "small" : ""} avatar`}
|
||||
|
|
Loading…
Add table
Reference in a new issue