From edd2867a47fb3feb3e3fd1ea936165540623a890 Mon Sep 17 00:00:00 2001 From: anian Date: Sat, 4 Jul 2026 18:04:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AF=A6=E6=83=85=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- .../MemoActionMenu/MemoActionMenu.tsx | 11 +++- web/src/components/MemoActionMenu/types.ts | 3 ++ web/src/components/MemoView/MemoView.tsx | 7 +-- .../MemoView/components/MemoHeader.tsx | 54 +++++++++++++++---- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 96b3cab..506e154 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ > 基于原作者v0.29.1代码修改 -#### v0.29.1-2补丁 +#### v0.29.1-3 1. 修改设置页面commit基础链接 -2. 优化图标样式 +2. 优化图标样式、备忘录菜单跳转 3. 归档页面允许设置表情 #### v0.29.1-2 diff --git a/web/src/components/MemoActionMenu/MemoActionMenu.tsx b/web/src/components/MemoActionMenu/MemoActionMenu.tsx index e1f7200..8ca7dd0 100644 --- a/web/src/components/MemoActionMenu/MemoActionMenu.tsx +++ b/web/src/components/MemoActionMenu/MemoActionMenu.tsx @@ -1,4 +1,5 @@ import { + ArrowLeftIcon, ArchiveIcon, ArchiveRestoreIcon, BookmarkMinusIcon, @@ -6,6 +7,7 @@ import { CheckCheckIcon, CopyIcon, Edit3Icon, + EyeIcon, FileTextIcon, LinkIcon, ListChecksIcon, @@ -32,7 +34,7 @@ import { useMemoActionHandlers } from "./hooks"; import type { MemoActionMenuProps } from "./types"; const MemoActionMenu = (props: MemoActionMenuProps) => { - const { memo, readonly } = props; + const { memo, readonly, isInMemoDetailPage, onBack, onViewDetail } = props; const t = useTranslate(); // Dialog state @@ -45,6 +47,8 @@ const MemoActionMenu = (props: MemoActionMenuProps) => { const canMutateTasks = !readonly && !isArchived && taskStats.total > 0; const hasOpenTasks = taskStats.completed < taskStats.total; const hasCompletedTasks = taskStats.completed > 0; + const DetailActionIcon = isInMemoDetailPage ? ArrowLeftIcon : EyeIcon; + const detailActionLabel = isInMemoDetailPage ? t("common.collapse") : t("memo.view-detail"); // Action handlers const { @@ -71,6 +75,11 @@ const MemoActionMenu = (props: MemoActionMenuProps) => { + + + {detailActionLabel} + + {/* Edit actions (non-readonly) */} {!readonly && ( <> diff --git a/web/src/components/MemoActionMenu/types.ts b/web/src/components/MemoActionMenu/types.ts index 442c342..70d4acd 100644 --- a/web/src/components/MemoActionMenu/types.ts +++ b/web/src/components/MemoActionMenu/types.ts @@ -4,5 +4,8 @@ export interface MemoActionMenuProps { memo: Memo; readonly?: boolean; className?: string; + isInMemoDetailPage: boolean; + onBack: () => void; + onViewDetail: () => void; onEdit?: () => void; } diff --git a/web/src/components/MemoView/MemoView.tsx b/web/src/components/MemoView/MemoView.tsx index 7f45321..043c2fb 100644 --- a/web/src/components/MemoView/MemoView.tsx +++ b/web/src/components/MemoView/MemoView.tsx @@ -27,7 +27,10 @@ const MemoView: React.FC = (props: MemoViewProps) => { const creator = useUser(memoData.creator).data; const isArchived = memoData.state === State.ARCHIVED; const readonly = memoData.creator !== currentUser?.name && !isSuperUser(currentUser); - const parentPage = parentPageProp || "/"; + const location = useLocation(); + const isInMemoDetailPage = location.pathname.startsWith(`/${memoData.name}`) || location.pathname.startsWith("/memos/shares/"); + const currentPage = `${location.pathname}${location.search}${location.hash}`; + const parentPage = parentPageProp || (isInMemoDetailPage ? "/" : currentPage); // Blur content when any tag has blur_content enabled in the instance tag settings. const [showBlurredContent, setShowBlurredContent] = useState(false); @@ -39,8 +42,6 @@ const MemoView: React.FC = (props: MemoViewProps) => { const openEditor = useCallback(() => setShowEditor(true), []); const closeEditor = useCallback(() => setShowEditor(false), []); - const location = useLocation(); - const isInMemoDetailPage = location.pathname.startsWith(`/${memoData.name}`) || location.pathname.startsWith("/memos/shares/"); const showCommentPreview = !isInMemoDetailPage && computeCommentAmount(memoData) > 0; useEffect(() => { diff --git a/web/src/components/MemoView/components/MemoHeader.tsx b/web/src/components/MemoView/components/MemoHeader.tsx index 55db70c..3dea516 100644 --- a/web/src/components/MemoView/components/MemoHeader.tsx +++ b/web/src/components/MemoView/components/MemoHeader.tsx @@ -1,6 +1,6 @@ import { ArchiveIcon, BookmarkIcon } from "lucide-react"; import { useCallback, useState } from "react"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import useNavigateTo from "@/hooks/useNavigateTo"; import i18n from "@/i18n"; @@ -20,12 +20,37 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false); const { memo, creator, currentUser, parentPage, isArchived, readonly, openEditor } = useMemoViewContext(); - const { createTime, updateTime, displayTime: memoDisplayTime, isDisplayingUpdatedTime, relativeTimeFormat } = useMemoViewDerived(); + const { + createTime, + updateTime, + displayTime: memoDisplayTime, + isDisplayingUpdatedTime, + isInMemoDetailPage, + relativeTimeFormat, + } = useMemoViewDerived(); const navigateTo = useNavigateTo(); + const navigate = useNavigate(); const handleGotoMemoDetailPage = useCallback(() => { navigateTo(`/${memo.name}`, { state: { from: parentPage } }); }, [memo.name, parentPage, navigateTo]); + const handleBackToParentPage = useCallback(() => { + const historyState = window.history.state as { idx?: number } | null; + if (typeof historyState?.idx === "number" && historyState.idx > 0) { + navigate(-1); + return; + } + + navigateTo(parentPage, { preventScrollReset: true }); + }, [parentPage, navigate, navigateTo]); + const handleMemoTimeClick = useCallback(() => { + if (isInMemoDetailPage) { + handleBackToParentPage(); + return; + } + + handleGotoMemoDetailPage(); + }, [isInMemoDetailPage, handleBackToParentPage, handleGotoMemoDetailPage]); const timeValue = isArchived ? ( memoDisplayTime?.toLocaleString(i18n.language) @@ -48,9 +73,9 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh
{showCreator && creator ? ( - + ) : ( - + )}
@@ -102,7 +127,14 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh )} - +
); @@ -112,10 +144,10 @@ interface CreatorDisplayProps { creator: User; displayTime: React.ReactNode; timeTooltip: TimeTooltipContent; - onGotoDetail: () => void; + onTimeClick: () => void; } -const CreatorDisplay: React.FC = ({ creator, displayTime, timeTooltip, onGotoDetail }) => ( +const CreatorDisplay: React.FC = ({ creator, displayTime, timeTooltip, onTimeClick }) => (
@@ -132,7 +164,7 @@ const CreatorDisplay: React.FC = ({ creator, displayTime, t @@ -159,15 +191,15 @@ const TimeTooltip = ({ children, content }: { children: React.ReactElement; cont interface TimeDisplayProps { displayTime: React.ReactNode; timeTooltip: TimeTooltipContent; - onGotoDetail: () => void; + onTimeClick: () => void; } -const TimeDisplay: React.FC = ({ displayTime, timeTooltip, onGotoDetail }) => ( +const TimeDisplay: React.FC = ({ displayTime, timeTooltip, onTimeClick }) => (