a tool for shared writing and social publishing
1import { Replicache } from "replicache"; 2import { Fact, ReplicacheMutators } from "src/replicache"; 3import { useUIState } from "src/useUIState"; 4import { scanIndex } from "src/replicache/utils"; 5import { scrollIntoViewIfNeeded } from "src/utils/scrollIntoViewIfNeeded"; 6import { elementId } from "src/utils/elementId"; 7import { focusBlock } from "src/utils/focusBlock"; 8 9export async function focusPage( 10 pageID: string, 11 rep: Replicache<ReplicacheMutators>, 12 focusFirstBlock?: "focusFirstBlock", 13) { 14 // if this page is already focused, 15 let focusedBlock = useUIState.getState().focusedEntity; 16 // else set this page as focused 17 useUIState.setState(() => ({ 18 focusedEntity: { 19 entityType: "page", 20 entityID: pageID, 21 }, 22 })); 23 24 setTimeout(async () => { 25 //scroll to page 26 27 scrollIntoViewIfNeeded( 28 document.getElementById(elementId.page(pageID).container), 29 false, 30 "smooth", 31 ); 32 33 // if we asked that the function focus the first block, focus the first block 34 if (focusFirstBlock === "focusFirstBlock") { 35 let firstBlock = await rep.query(async (tx) => { 36 let type = await scanIndex(tx).eav(pageID, "page/type"); 37 let blocks = await scanIndex(tx).eav( 38 pageID, 39 type[0]?.data.value === "canvas" ? "canvas/block" : "card/block", 40 ); 41 42 let firstBlock = blocks[0]; 43 44 if (!firstBlock) { 45 return null; 46 } 47 48 let blockType = ( 49 await tx 50 .scan< 51 Fact<"block/type"> 52 >({ indexName: "eav", prefix: `${firstBlock.data.value}-block/type` }) 53 .toArray() 54 )[0]; 55 56 if (!blockType) return null; 57 58 return { 59 value: firstBlock.data.value, 60 type: blockType.data.value, 61 parent: firstBlock.entity, 62 position: firstBlock.data.position, 63 }; 64 }); 65 66 if (firstBlock) { 67 setTimeout(() => { 68 focusBlock(firstBlock, { type: "start" }); 69 }, 500); 70 } 71 } 72 }, 50); 73}