feat(ui): browser back and forward step through the app
The app's place (page, open note, workspace view, zoomed bullet, on phones list or note) goes into the browser history (lib/navHistory.ts), so the back button of the mouse, the browser or Android steps back inside the app: out of a zoom, to the previous note, to the previous page. Changes from one action become one entry, the app's own choice of a first note replaces the entry, and following a step adds nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5b711730a7
commit
1eef388fa5
5 files changed
+185
-6
No files matched your search
@@ -34,6 +34,7 @@ import { Presence } from '../../lib/docSync/transport';
|
||||
import { OutlinerTree, OutlinerTreeHandle } from './OutlinerTree';
|
||||
import { extractHashtags } from '../../lib/hashtags';
|
||||
import { moveSibling } from '../../lib/outlineList';
|
||||
import { reportNav, onNavStep, restoringNavPlace } from '../../lib/navHistory';
|
||||
|
||||
export type DocSaveStatus = 'saved' | 'saving' | 'unsaved' | 'error';
|
||||
|
||||
@@ -260,7 +261,11 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
const [loading, setLoading] = useState<boolean>(!initialDoc);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [showEmojiPicker, setShowEmojiPicker] = useState<boolean>(false);
|
||||
const [zoomedBlockId, setZoomedBlockId] = useState<string | null>(null);
|
||||
// Zoomed bullet; coming here by the browser's back/forward it is the zoom of that step
|
||||
const [zoomedBlockId, setZoomedBlockId] = useState<string | null>(() => {
|
||||
const place = restoringNavPlace();
|
||||
return !inJournal && !inTagPage && place?.docId === docId ? place.zoom ?? null : null;
|
||||
});
|
||||
const [showActionsMenu, setShowActionsMenu] = useState<boolean>(false);
|
||||
const actionsMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
@@ -317,10 +322,22 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
}, [loading, autoFocusTitle, doc?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (zoomedBlockId && !blocks.some((b) => b.id === zoomedBlockId)) {
|
||||
if (!loading && zoomedBlockId && !blocks.some((b) => b.id === zoomedBlockId)) {
|
||||
setZoomedBlockId(null);
|
||||
}
|
||||
}, [blocks, zoomedBlockId]);
|
||||
}, [blocks, zoomedBlockId, loading]);
|
||||
|
||||
// Zooming in and out are steps of the browser history: back zooms out again (lib/navHistory.ts)
|
||||
useEffect(() => {
|
||||
if (!embedded) reportNav({ zoom: zoomedBlockId });
|
||||
}, [zoomedBlockId, embedded]);
|
||||
useEffect(
|
||||
() =>
|
||||
onNavStep((place) => {
|
||||
if (!embedded && place.docId === docId) setZoomedBlockId(place.zoom ?? null);
|
||||
}),
|
||||
[embedded, docId]
|
||||
);
|
||||
|
||||
const { zoomedBlock, childBlocks, levelOffset } = useMemo(() => {
|
||||
return getZoomedSubtree(blocks, zoomedBlockId);
|
||||
|
||||
Reference in new issue
Block a user