Commit 9e310bf9 authored by boojack's avatar boojack

chore(memo): clarify displayed update time

parent 9bf648ac
...@@ -44,8 +44,11 @@ export const useMemoViewDerived = () => { ...@@ -44,8 +44,11 @@ export const useMemoViewDerived = () => {
const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`) || location.pathname.startsWith("/memos/shares/"); const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`) || location.pathname.startsWith("/memos/shares/");
const commentAmount = computeCommentAmount(memo); const commentAmount = computeCommentAmount(memo);
const displayTimestamp = timeBasis === "update_time" ? memo.updateTime : memo.createTime; const createTime = memo.createTime ? timestampDate(memo.createTime) : undefined;
const displayTime = displayTimestamp ? timestampDate(displayTimestamp) : undefined; const updateTime = memo.updateTime ? timestampDate(memo.updateTime) : undefined;
const displayTime = timeBasis === "update_time" ? updateTime : createTime;
const isDisplayingUpdatedTime =
timeBasis === "update_time" && !!createTime && !!updateTime && updateTime.getTime() !== createTime.getTime();
const relativeTimeFormat: "datetime" | "auto" = const relativeTimeFormat: "datetime" | "auto" =
displayTime && Date.now() - displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto"; displayTime && Date.now() - displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto";
...@@ -54,7 +57,10 @@ export const useMemoViewDerived = () => { ...@@ -54,7 +57,10 @@ export const useMemoViewDerived = () => {
readonly, readonly,
isInMemoDetailPage, isInMemoDetailPage,
commentAmount, commentAmount,
createTime,
updateTime,
displayTime, displayTime,
isDisplayingUpdatedTime,
relativeTimeFormat, relativeTimeFormat,
}; };
}; };
...@@ -22,7 +22,7 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh ...@@ -22,7 +22,7 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false); const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false);
const { memo, creator, currentUser, parentPage, isArchived, readonly, openEditor } = useMemoViewContext(); const { memo, creator, currentUser, parentPage, isArchived, readonly, openEditor } = useMemoViewContext();
const { displayTime: memoDisplayTime, relativeTimeFormat } = useMemoViewDerived(); const { createTime, updateTime, displayTime: memoDisplayTime, isDisplayingUpdatedTime, relativeTimeFormat } = useMemoViewDerived();
const navigateTo = useNavigateTo(); const navigateTo = useNavigateTo();
const handleGotoMemoDetailPage = useCallback(() => { const handleGotoMemoDetailPage = useCallback(() => {
...@@ -31,19 +31,30 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh ...@@ -31,19 +31,30 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
const { unpinMemo } = useMemoActions(memo); const { unpinMemo } = useMemoActions(memo);
const displayTime = isArchived ? ( const timeValue = isArchived ? (
memoDisplayTime?.toLocaleString(i18n.language) memoDisplayTime?.toLocaleString(i18n.language)
) : ( ) : (
<relative-time datetime={memoDisplayTime?.toISOString()} lang={i18n.language} format={relativeTimeFormat}></relative-time> <relative-time datetime={memoDisplayTime?.toISOString()} lang={i18n.language} format={relativeTimeFormat} no-title=""></relative-time>
); );
const displayTime = isDisplayingUpdatedTime ? (
<>
{t("common.last-updated-at")} {timeValue}
</>
) : (
timeValue
);
const timeTooltip = {
createdAt: createTime ? `${t("common.created-at")}: ${createTime.toLocaleString(i18n.language)}` : undefined,
updatedAt: updateTime ? `${t("common.last-updated-at")}: ${updateTime.toLocaleString(i18n.language)}` : undefined,
};
return ( return (
<div className="w-full flex flex-row justify-between items-center gap-2"> <div className="w-full flex flex-row justify-between items-center gap-2">
<div className="w-auto max-w-[calc(100%-8rem)] grow flex flex-row justify-start items-center"> <div className="w-auto max-w-[calc(100%-8rem)] grow flex flex-row justify-start items-center">
{showCreator && creator ? ( {showCreator && creator ? (
<CreatorDisplay creator={creator} displayTime={displayTime} onGotoDetail={handleGotoMemoDetailPage} /> <CreatorDisplay creator={creator} displayTime={displayTime} timeTooltip={timeTooltip} onGotoDetail={handleGotoMemoDetailPage} />
) : ( ) : (
<TimeDisplay displayTime={displayTime} onGotoDetail={handleGotoMemoDetailPage} /> <TimeDisplay displayTime={displayTime} timeTooltip={timeTooltip} onGotoDetail={handleGotoMemoDetailPage} />
)} )}
</div> </div>
...@@ -93,10 +104,11 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh ...@@ -93,10 +104,11 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
interface CreatorDisplayProps { interface CreatorDisplayProps {
creator: User; creator: User;
displayTime: React.ReactNode; displayTime: React.ReactNode;
timeTooltip: TimeTooltipContent;
onGotoDetail: () => void; onGotoDetail: () => void;
} }
const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, onGotoDetail }) => ( const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, timeTooltip, onGotoDetail }) => (
<div className="w-full flex flex-row justify-start items-center"> <div className="w-full flex flex-row justify-start items-center">
<Link className="w-auto hover:opacity-80 rounded-md transition-colors" to={`/u/${encodeURIComponent(creator.username)}`} viewTransition> <Link className="w-auto hover:opacity-80 rounded-md transition-colors" to={`/u/${encodeURIComponent(creator.username)}`} viewTransition>
<UserAvatar className="mr-2 shrink-0" avatarUrl={creator.avatarUrl} /> <UserAvatar className="mr-2 shrink-0" avatarUrl={creator.avatarUrl} />
...@@ -109,30 +121,50 @@ const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, o ...@@ -109,30 +121,50 @@ const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, o
> >
{creator.displayName || creator.username} {creator.displayName || creator.username}
</Link> </Link>
<button <TimeTooltip content={timeTooltip}>
type="button" <button
className="w-auto -mt-0.5 text-xs leading-tight text-muted-foreground select-none cursor-pointer hover:opacity-80 transition-colors text-left" type="button"
onClick={onGotoDetail} className="w-auto -mt-0.5 text-xs leading-tight text-muted-foreground select-none cursor-pointer hover:opacity-80 transition-colors text-left"
> onClick={onGotoDetail}
{displayTime} >
</button> {displayTime}
</button>
</TimeTooltip>
</div> </div>
</div> </div>
); );
interface TimeTooltipContent {
createdAt?: string;
updatedAt?: string;
}
const TimeTooltip = ({ children, content }: { children: React.ReactElement; content: TimeTooltipContent }) => (
<Tooltip>
<TooltipTrigger asChild>{children}</TooltipTrigger>
<TooltipContent align="start" className="flex flex-col items-start gap-0.5 whitespace-nowrap text-left">
{content.createdAt && <span>{content.createdAt}</span>}
{content.updatedAt && <span>{content.updatedAt}</span>}
</TooltipContent>
</Tooltip>
);
interface TimeDisplayProps { interface TimeDisplayProps {
displayTime: React.ReactNode; displayTime: React.ReactNode;
timeTooltip: TimeTooltipContent;
onGotoDetail: () => void; onGotoDetail: () => void;
} }
const TimeDisplay: React.FC<TimeDisplayProps> = ({ displayTime, onGotoDetail }) => ( const TimeDisplay: React.FC<TimeDisplayProps> = ({ displayTime, timeTooltip, onGotoDetail }) => (
<button <TimeTooltip content={timeTooltip}>
type="button" <button
className="w-full text-sm leading-tight text-muted-foreground select-none cursor-pointer hover:text-foreground transition-colors text-left" type="button"
onClick={onGotoDetail} className="w-auto text-sm leading-tight text-muted-foreground select-none cursor-pointer hover:text-foreground transition-colors text-left"
> onClick={onGotoDetail}
{displayTime} >
</button> {displayTime}
</button>
</TimeTooltip>
); );
export default MemoHeader; export default MemoHeader;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment