From 7a5ace2defa7252b3cfc25e4223865f95c7cb82f Mon Sep 17 00:00:00 2001 From: Paul <paulmakles@gmail.com> Date: Fri, 9 Jul 2021 09:58:38 +0100 Subject: [PATCH] Highlight messages we jump to. --- src/components/common/messaging/Message.tsx | 3 +++ src/components/common/messaging/MessageBase.tsx | 17 ++++++++++++++++- .../common/messaging/SystemMessage.tsx | 4 +++- src/pages/channels/messaging/MessageArea.tsx | 7 +++++-- .../channels/messaging/MessageRenderer.tsx | 5 ++++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index f2ca22c..8e87ae2 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -28,12 +28,14 @@ interface Props { attachContext?: boolean; queued?: QueuedMessage; message: MessageObject; + highlight?: boolean; contrast?: boolean; content?: Children; head?: boolean; } function Message({ + highlight, attachContext, message, contrast, @@ -72,6 +74,7 @@ function Message({ /> ))} <MessageBase + highlight={highlight} head={head && !(message.replies && message.replies.length > 0)} contrast={contrast} sending={typeof queued !== "undefined"} diff --git a/src/components/common/messaging/MessageBase.tsx b/src/components/common/messaging/MessageBase.tsx index e040168..56b82e7 100644 --- a/src/components/common/messaging/MessageBase.tsx +++ b/src/components/common/messaging/MessageBase.tsx @@ -1,4 +1,4 @@ -import styled, { css } from "styled-components"; +import styled, { css, keyframes } from "styled-components"; import { decodeTime } from "ulid"; import { Text } from "preact-i18n"; @@ -17,8 +17,15 @@ export interface BaseMessageProps { blocked?: boolean; sending?: boolean; contrast?: boolean; + highlight?: boolean; } +const highlight = keyframes` + 0% { background: var(--mention); } + 66% { background: var(--mention); } + 100% { background: transparent; } +`; + export default styled.div<BaseMessageProps>` display: flex; overflow: none; @@ -70,6 +77,14 @@ export default styled.div<BaseMessageProps>` color: var(--error); `} + ${(props) => + props.highlight && + css` + animation-name: ${highlight}; + animation-timing-function: ease; + animation-duration: 3s; + `} + .detail { gap: 8px; display: flex; diff --git a/src/components/common/messaging/SystemMessage.tsx b/src/components/common/messaging/SystemMessage.tsx index c082292..67e0d49 100644 --- a/src/components/common/messaging/SystemMessage.tsx +++ b/src/components/common/messaging/SystemMessage.tsx @@ -35,9 +35,10 @@ type SystemMessageParsed = interface Props { attachContext?: boolean; message: MessageObject; + highlight?: boolean; } -export function SystemMessage({ attachContext, message }: Props) { +export function SystemMessage({ attachContext, message, highlight }: Props) { const ctx = useForceUpdate(); let data: SystemMessageParsed; @@ -143,6 +144,7 @@ export function SystemMessage({ attachContext, message }: Props) { return ( <MessageBase + highlight={highlight} onContextMenu={ attachContext ? attachContextMenu("Menu", { diff --git a/src/pages/channels/messaging/MessageArea.tsx b/src/pages/channels/messaging/MessageArea.tsx index 5f5f439..a5da03b 100644 --- a/src/pages/channels/messaging/MessageArea.tsx +++ b/src/pages/channels/messaging/MessageArea.tsx @@ -60,7 +60,9 @@ export function MessageArea({ id }: Props) { const status = useContext(StatusContext); const { focusTaken } = useContext(IntermediateContext); + // ? Required data for message links. const { message } = useParams<{ message: string }>(); + const [highlight, setHighlight] = useState<string | undefined>(undefined); // ? This is the scroll container. const ref = useRef<HTMLDivElement>(null); @@ -99,7 +101,7 @@ export function MessageArea({ id }: Props) { }); } else if (scrollState.current.type === "ScrollToView") { document.getElementById(scrollState.current.id) - ?.scrollIntoView(); + ?.scrollIntoView({ block: 'center' }); setScrollState({ type: "Free" }); } else if (scrollState.current.type === "OffsetTop") { @@ -170,6 +172,7 @@ export function MessageArea({ id }: Props) { // ? If message present or changes, load it as well. useEffect(() => { if (message) { + setHighlight(message); SingletonMessageRenderer.init(id, message); let channel = client.channels.get(id); @@ -284,7 +287,7 @@ export function MessageArea({ id }: Props) { </RequiresOnline> )} {state.type === "RENDER" && ( - <MessageRenderer id={id} state={state} /> + <MessageRenderer id={id} state={state} highlight={highlight} /> )} {state.type === "EMPTY" && <ConversationStart id={id} />} </div> diff --git a/src/pages/channels/messaging/MessageRenderer.tsx b/src/pages/channels/messaging/MessageRenderer.tsx index d573578..7201da1 100644 --- a/src/pages/channels/messaging/MessageRenderer.tsx +++ b/src/pages/channels/messaging/MessageRenderer.tsx @@ -28,6 +28,7 @@ import MessageEditor from "./MessageEditor"; interface Props { id: string; state: RenderState; + highlight?: string; queue: QueuedMessage[]; } @@ -42,7 +43,7 @@ const BlockedMessage = styled.div` } `; -function MessageRenderer({ id, state, queue }: Props) { +function MessageRenderer({ id, state, queue, highlight }: Props) { if (state.type !== "RENDER") return null; const client = useContext(AppContext); @@ -132,6 +133,7 @@ function MessageRenderer({ id, state, queue }: Props) { key={message._id} message={message} attachContext + highlight={highlight === message._id} />, ); } else { @@ -158,6 +160,7 @@ function MessageRenderer({ id, state, queue }: Props) { ) : undefined } attachContext + highlight={highlight === message._id} />, ); } -- GitLab