a tool for shared writing and social publishing
1"use client";
2
3import { useEffect, useState } from "react";
4import {
5 useBlocks,
6 useCanvasBlocksWithType,
7} from "src/hooks/queries/useBlocks";
8import { useEntity, useReplicache } from "src/replicache";
9import * as Y from "yjs";
10import * as base64 from "base64-js";
11import { YJSFragmentToString } from "src/utils/yjsFragmentToString";
12import { useParams, useRouter, useSearchParams } from "next/navigation";
13import { focusBlock } from "src/utils/focusBlock";
14import { useIsMobile } from "src/hooks/isMobile";
15import { useLeafletPublicationData } from "components/PageSWRDataProvider";
16
17export function UpdateLeafletTitle(props: { entityID: string }) {
18 let { data: pub } = useLeafletPublicationData();
19 let firstPage = useEntity(props.entityID, "root/page")[0];
20 let entityID = firstPage?.data.value || props.entityID;
21
22 let blocks = useBlocks(entityID).filter(
23 (b) => b.type === "text" || b.type === "heading",
24 );
25 let firstBlock = blocks[0];
26 let title = usePageTitle(entityID);
27 useEffect(() => {
28 if (pub?.title) {
29 document.title = pub.title;
30 return;
31 }
32 if (title) {
33 document.title = title;
34 }
35 }, [title, pub]);
36 let params = useSearchParams();
37 let focusFirstBlock = params.get("focusFirstBlock");
38 let router = useRouter();
39 let isMobile = useIsMobile();
40 useEffect(() => {
41 if (isMobile) return;
42 if (!firstBlock || focusFirstBlock === null) return;
43
44 router.replace(location.pathname);
45 setTimeout(() => {
46 focusBlock(firstBlock, { type: "start" });
47 //remove url param
48 }, 100);
49 }, [focusFirstBlock, firstBlock, router, isMobile]);
50
51 return null;
52}
53
54export const usePageTitle = (entityID: string) => {
55 let [title, setTitle] = useState("");
56 let canvasBlocks = useCanvasBlocksWithType(entityID).filter(
57 (b) => b.type === "text" || b.type === "heading",
58 );
59 let blocks = useBlocks(entityID).filter(
60 (b) => b.type === "text" || b.type === "heading",
61 );
62 let firstBlock = canvasBlocks[0] || blocks[0];
63 let content = useEntity(firstBlock?.value, "block/text");
64 useEffect(() => {
65 if (content) {
66 let doc = new Y.Doc();
67 const update = base64.toByteArray(content.data.value);
68 Y.applyUpdate(doc, update);
69 let nodes = doc.getXmlElement("prosemirror").toArray();
70 setTitle(YJSFragmentToString(nodes[0]) || "Untitled Leaflet");
71 }
72 }, [content]);
73 return title;
74};