a tool for shared writing and social publishing
1import { Replicache } from "replicache";
2import { ReplicacheMutators } from "src/replicache";
3import { useUIState } from "src/useUIState";
4import { scanIndex } from "src/replicache/utils";
5import { getBlocksWithType } from "src/hooks/queries/useBlocks";
6import { focusBlock } from "src/utils/focusBlock";
7
8export async function deleteBlock(
9 entities: string[],
10 rep: Replicache<ReplicacheMutators>,
11) {
12 // get what pagess we need to close as a result of deleting this block
13 let pagesToClose = [] as string[];
14 for (let entity of entities) {
15 let [type] = await rep.query((tx) =>
16 scanIndex(tx).eav(entity, "block/type"),
17 );
18 if (type.data.value === "card") {
19 let [childPages] = await rep?.query(
20 (tx) => scanIndex(tx).eav(entity, "block/card") || [],
21 );
22 pagesToClose = [childPages?.data.value];
23 }
24 if (type.data.value === "mailbox") {
25 let [archive] = await rep?.query(
26 (tx) => scanIndex(tx).eav(entity, "mailbox/archive") || [],
27 );
28 let [draft] = await rep?.query(
29 (tx) => scanIndex(tx).eav(entity, "mailbox/draft") || [],
30 );
31 pagesToClose = [archive?.data.value, draft?.data.value];
32 }
33 }
34
35 // the next and previous blocks in the block list
36 // if the focused thing is a page and not a block, return
37 let focusedBlock = useUIState.getState().focusedEntity;
38 let parent =
39 focusedBlock?.entityType === "page"
40 ? focusedBlock.entityID
41 : focusedBlock?.parent;
42
43 if (parent) {
44 let parentType = await rep?.query((tx) =>
45 scanIndex(tx).eav(parent, "page/type"),
46 );
47 if (parentType[0]?.data.value === "canvas") {
48 useUIState
49 .getState()
50 .setFocusedBlock({ entityType: "page", entityID: parent });
51 useUIState.getState().setSelectedBlocks([]);
52 } else {
53 let siblings =
54 (await rep?.query((tx) => getBlocksWithType(tx, parent))) || [];
55
56 let selectedBlocks = useUIState.getState().selectedBlocks;
57 let firstSelected = selectedBlocks[0];
58 let lastSelected = selectedBlocks[entities.length - 1];
59
60 let prevBlock =
61 siblings?.[
62 siblings.findIndex((s) => s.value === firstSelected?.value) - 1
63 ];
64 let prevBlockType = await rep?.query((tx) =>
65 scanIndex(tx).eav(prevBlock?.value, "block/type"),
66 );
67
68 let nextBlock =
69 siblings?.[
70 siblings.findIndex((s) => s.value === lastSelected.value) + 1
71 ];
72 let nextBlockType = await rep?.query((tx) =>
73 scanIndex(tx).eav(nextBlock?.value, "block/type"),
74 );
75
76 if (prevBlock) {
77 useUIState.getState().setSelectedBlock({
78 value: prevBlock.value,
79 parent: prevBlock.parent,
80 });
81
82 focusBlock(
83 {
84 value: prevBlock.value,
85 type: prevBlockType?.[0].data.value,
86 parent: prevBlock.parent,
87 },
88 { type: "end" },
89 );
90 } else {
91 useUIState.getState().setSelectedBlock({
92 value: nextBlock.value,
93 parent: nextBlock.parent,
94 });
95
96 focusBlock(
97 {
98 value: nextBlock.value,
99 type: nextBlockType?.[0]?.data.value,
100 parent: nextBlock.parent,
101 },
102 { type: "start" },
103 );
104 }
105 }
106 }
107
108 pagesToClose.forEach((page) => page && useUIState.getState().closePage(page));
109 await Promise.all(
110 entities.map((entity) =>
111 rep?.mutate.removeBlock({
112 blockEntity: entity,
113 }),
114 ),
115 );
116}