Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ All notable changes to `doc` are documented here.

### Fixed

- Add an in-app back button to the TopBar that appears only after the first in-app navigation,
and scope the entry-document flag to `sessionStorage` so it survives SPA navigation but resets
on full page reload (#66).
- Replace hardcoded `timeAgo` strings with `next-intl` translation keys and return ISO-8601
`createdAt` from the version API so clients can format timestamps with `Intl.DateTimeFormat`.
Remove unused `useTimeAgo` hook export and use real `messages/zh-cn.json` in `dt.test.ts`
Expand Down
3 changes: 2 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"documentActions": "Document actions",
"moreDocumentActions": "More document actions",
"changeLanguage": "Change language, current {locale}",
"closeDialog": "Close dialog"
"closeDialog": "Close dialog",
"goBack": "Go back"
},
"metadata": {
"title": "doc — self-hosted collaborative document infrastructure",
Expand Down
3 changes: 2 additions & 1 deletion messages/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"documentActions": "文档操作",
"moreDocumentActions": "更多文档操作",
"changeLanguage": "切换语言,当前为 {locale}",
"closeDialog": "关闭对话框"
"closeDialog": "关闭对话框",
"goBack": "返回上一页"
},
"metadata": {
"title": "doc — 自托管协作文档基础设施",
Expand Down
8 changes: 6 additions & 2 deletions src/app/[locale]/work/[id]/(content)/content-for-my-doc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ export default function ContentForMyDoc() {
const updateDocTitle = useDocsStore((s) => s.updateDocTitle)
const updateDocIcon = useDocsStore((s) => s.updateDocIcon)

// record last doc id
// Record entry doc id only once per page session.
// Uses sessionStorage to survive SPA navigation but reset on full page reload.
useEffect(() => {
localStorage.setItem(LAST_DOC_ID_KEY, id) // 保存最后一次打开的文档 id
if (!sessionStorage.getItem('hasRecordedEntryDoc')) {
localStorage.setItem(LAST_DOC_ID_KEY, id)
sessionStorage.setItem('hasRecordedEntryDoc', 'true')
}
}, [id])

useEffect(() => {
Expand Down
27 changes: 25 additions & 2 deletions src/app/[locale]/work/[id]/top-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { useMemo, useState } from 'react'
import { Ellipsis } from 'lucide-react'
import { useMemo, useState, useEffect } from 'react'
import { ArrowLeft, Ellipsis } from 'lucide-react'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { Button } from '@/components/ui/button'
import Logo from '@/components/logo-component'
Expand All @@ -24,6 +24,8 @@ import { useUserStore } from '@/stores/user-store'
import { Topbar } from '@fullstack-ai-infra/ui'
import { useTranslations } from 'next-intl'
import { useCompactWorkspace } from '@/hooks/use-compact-workspace'
import emitter from '@/lib/emitter'
import { EVENT_KEY_NAV_DOC } from '@/constants'

export default function TopBar() {
const t = useTranslations('common')
Expand All @@ -33,12 +35,33 @@ export default function TopBar() {
const doc = useMemo(() => docs.find((d) => d.id === id), [docs, id])
const userInfo = useUserStore((s) => s.userInfo)

// Track whether there's in-app navigation history for the back button.
const [hasHistory, setHasHistory] = useState(false)
useEffect(() => {
const onNav = () => setHasHistory(true)
emitter.on(EVENT_KEY_NAV_DOC, onNav)
return () => {
emitter.off(EVENT_KEY_NAV_DOC, onNav)
}
}, [])

return (
<Topbar
aria-label={t('documentToolbar')}
className="max-[1023px]:pl-14 max-[480px]:pr-2"
breadcrumbs={
<div className="inline-flex items-center gap-3">
{hasHistory && (
<Button
type="button"
variant="ghost"
size="icon"
aria-label={t('goBack')}
onClick={() => window.history.back()}
>
<ArrowLeft aria-hidden="true" className="h-4 w-4" />
</Button>
)}
<Logo />
<div className="max-[479px]:hidden">
<DocUpdateStatus id={id} />
Expand Down
Loading