🧹 perf: Share Voices Store, Gate Timestamp Ticker, Stabilize Greeting Springs (#14335)

This commit is contained in:
Danny Avila 2026-07-20 22:43:29 -04:00 committed by GitHub
parent eeb4ea226c
commit f4a0e0c194
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 118 additions and 76 deletions

View file

@ -19,6 +19,11 @@ import { useLocalize, useAuthContext } from '~/hooks';
const containerClassName =
'shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white dark:bg-presentation dark:text-white text-black dark:after:shadow-none ';
/** Stable references: fresh literals re-initialized SplitText's springs and
* re-rendered every grapheme span on each Landing render. */
const greetingAnimationFrom = { opacity: 0, transform: 'translate3d(0,50px,0)' };
const greetingAnimationTo = { opacity: 1, transform: 'translate3d(0,0,0)' };
function getTextSizeClass(text: string | undefined | null) {
if (!text) {
return 'text-xl sm:text-2xl';
@ -202,8 +207,8 @@ export default function Landing({ centerFormOnLanding }: { centerFormOnLanding:
className={`${getTextSizeClass(name)} font-medium text-text-primary`}
delay={50}
textAlign="center"
animationFrom={{ opacity: 0, transform: 'translate3d(0,50px,0)' }}
animationTo={{ opacity: 1, transform: 'translate3d(0,0,0)' }}
animationFrom={greetingAnimationFrom}
animationTo={greetingAnimationTo}
easing={easings.easeOutCubic}
threshold={0}
rootMargin="0px"
@ -217,8 +222,8 @@ export default function Landing({ centerFormOnLanding }: { centerFormOnLanding:
className={`${getTextSizeClass(greetingText)} font-medium text-text-primary`}
delay={50}
textAlign="center"
animationFrom={{ opacity: 0, transform: 'translate3d(0,50px,0)' }}
animationTo={{ opacity: 1, transform: 'translate3d(0,0,0)' }}
animationFrom={greetingAnimationFrom}
animationTo={greetingAnimationTo}
easing={easings.easeOutCubic}
threshold={0}
rootMargin="0px"

View file

@ -2,23 +2,9 @@ import { useTranslation } from 'react-i18next';
import useTimeTick from '~/hooks/useTimeTick';
import { getMessageTimestamp } from '~/utils';
/**
* Inline message timestamp shown next to the author name in the message header.
* On hover-capable pointers it reveals on row hover/focus; on touch and other
* non-hover devices it stays visible. Recent messages show the relative form
* ("10 minutes ago") with the absolute date on hover; older messages show the
* absolute date directly.
*/
export default function MessageTimestamp({ value }: { value?: string | null }) {
const { i18n } = useTranslation();
// Re-render on a shared interval so relative labels stay current while idle.
useTimeTick();
const timestamp = getMessageTimestamp(value, i18n.language);
if (!timestamp) {
return null;
}
type Timestamp = NonNullable<ReturnType<typeof getMessageTimestamp>>;
function TimestampText({ timestamp }: { timestamp: Timestamp }) {
return (
<time
dateTime={timestamp.iso}
@ -29,3 +15,38 @@ export default function MessageTimestamp({ value }: { value?: string | null }) {
</time>
);
}
/** Only recent timestamps subscribe to the shared minute ticker, so the
* per-minute sweep re-renders a handful of rows instead of every message. */
function RecentTimestamp({ value, language }: { value?: string | null; language: string }) {
useTimeTick();
const timestamp = getMessageTimestamp(value, language);
if (!timestamp) {
return null;
}
return <TimestampText timestamp={timestamp} />;
}
/**
* Inline message timestamp shown next to the author name in the message header.
* On hover-capable pointers it reveals on row hover/focus; on touch and other
* non-hover devices it stays visible. Recent messages show the relative form
* ("10 minutes ago") with the absolute date on hover; older messages show the
* absolute date directly.
*/
export default function MessageTimestamp({ value }: { value?: string | null }) {
const { i18n } = useTranslation();
const timestamp = getMessageTimestamp(value, i18n.language);
if (!timestamp) {
return null;
}
if (timestamp.isRecent) {
return <RecentTimestamp value={value} language={i18n.language} />;
}
return <TimestampText timestamp={timestamp} />;
}