-
Notifications
You must be signed in to change notification settings - Fork 1
/
useBubbleData.ts
57 lines (48 loc) · 1.5 KB
/
useBubbleData.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import { useEffect, useState } from "./deps/preact.tsx";
import { load, subscribe, unsubscribe } from "./bubble.ts";
import { createDebug } from "./debug.ts";
import { ID } from "./id.ts";
import { Bubble } from "./storage.ts";
const logger = createDebug("ScrapBubble:useBubbleData.ts");
/** bubbleデータを取得するhooks
*
* @param pageIds 取得するページのID
* @returns bubble data
*/
export const useBubbleData = (
pageIds: readonly ID[],
): readonly Bubble[] => {
const [bubbles, setBubbles] = useState<readonly Bubble[]>(
makeBubbles(pageIds),
);
// データ更新用listenerの登録
useEffect(() => {
setBubbles(makeBubbles(pageIds));
let timer: number | undefined;
/** ページデータを更新する */
const updateData = () => {
// 少し待ってからまとめて更新する
clearTimeout(timer);
timer = setTimeout(() => {
logger.debug(`Update ${pageIds.length} pages`);
setBubbles(makeBubbles(pageIds));
}, 10);
};
// 更新を購読する
pageIds.forEach((id) => subscribe(id, updateData));
return () => pageIds.forEach((id) => unsubscribe(id, updateData));
}, pageIds);
// debug用
return bubbles;
};
const makeBubbles = (pageIds: readonly ID[]): readonly Bubble[] => {
const bubbles = [...load(pageIds)].flatMap((bubble) =>
bubble ? [bubble] : []
);
// debug用
logger.debug(
`Required: ${pageIds.length} pages, ${bubbles.length} found`,
bubbles,
);
return bubbles;
};