Commit 9e310bf9 authored by boojack's avatar boojack

chore(memo): clarify displayed update time

parent 9bf648ac
......@@ -44,8 +44,11 @@ export const useMemoViewDerived = () => {
const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`) || location.pathname.startsWith("/memos/shares/");
const commentAmount = computeCommentAmount(memo);
const displayTimestamp = timeBasis === "update_time" ? memo.updateTime : memo.createTime;
const displayTime = displayTimestamp ? timestampDate(displayTimestamp) : undefined;
const createTime = memo.createTime ? timestampDate(memo.createTime) : 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" =
displayTime && Date.now() - displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto";
......@@ -54,7 +57,10 @@ export const useMemoViewDerived = () => {
readonly,
isInMemoDetailPage,
commentAmount,
createTime,
updateTime,
displayTime,
isDisplayingUpdatedTime,
relativeTimeFormat,
};
};
......@@ -22,7 +22,7 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false);
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 handleGotoMemoDetailPage = useCallback(() => {
......@@ -31,19 +31,30 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
const { unpinMemo } = useMemoActions(memo);
const displayTime = isArchived ? (
const timeValue = isArchived ? (
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 (
<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">
{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>
......@@ -93,10 +104,11 @@ const MemoHeader: React.FC<MemoHeaderProps> = ({ showCreator, showVisibility, sh
interface CreatorDisplayProps {
creator: User;
displayTime: React.ReactNode;
timeTooltip: TimeTooltipContent;
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">
<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} />
......@@ -109,6 +121,7 @@ const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, o
>
{creator.displayName || creator.username}
</Link>
<TimeTooltip content={timeTooltip}>
<button
type="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"
......@@ -116,23 +129,42 @@ const CreatorDisplay: React.FC<CreatorDisplayProps> = ({ creator, displayTime, o
>
{displayTime}
</button>
</TimeTooltip>
</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 {
displayTime: React.ReactNode;
timeTooltip: TimeTooltipContent;
onGotoDetail: () => void;
}
const TimeDisplay: React.FC<TimeDisplayProps> = ({ displayTime, onGotoDetail }) => (
const TimeDisplay: React.FC<TimeDisplayProps> = ({ displayTime, timeTooltip, onGotoDetail }) => (
<TimeTooltip content={timeTooltip}>
<button
type="button"
className="w-full text-sm leading-tight text-muted-foreground select-none cursor-pointer hover:text-foreground transition-colors text-left"
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>
</TimeTooltip>
);
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