-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathauto-delete-events.ts
More file actions
116 lines (91 loc) · 2.96 KB
/
auto-delete-events.ts
File metadata and controls
116 lines (91 loc) · 2.96 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { storeToRefs } from "pinia";
import { watch } from "vue";
import { useEventsStore, useSettingsStore } from "../../stores";
import type { EventId } from "../../types";
import { useEventsApi } from "./use-events-api";
type AutoDeleteTime = number | "none";
const autoDeleteTimers = new Map<EventId, ReturnType<typeof setTimeout>>();
let autoDeleteInitialized = false;
const toAutoDeleteMs = (val: AutoDeleteTime): number | null => {
if (val === "none") return null;
return val * 60 * 1000;
};
const clearAutoDeleteTimer = (eventId: EventId) => {
const timer = autoDeleteTimers.get(eventId);
if (!timer) return;
globalThis.clearTimeout(timer);
autoDeleteTimers.delete(eventId);
};
const clearAllAutoDeleteTimers = () => {
autoDeleteTimers.forEach((timer) => globalThis.clearTimeout(timer));
autoDeleteTimers.clear();
};
export const ensureAutoDeleteWatcher = () => {
if (autoDeleteInitialized) return;
autoDeleteInitialized = true;
const eventsStore = useEventsStore();
const settingsStore = useSettingsStore();
const eventsApi = useEventsApi();
const { events, lockedIds } = storeToRefs(eventsStore);
const { autoDeleteEventsTime } = storeToRefs(settingsStore);
const schedule = (eventId: EventId) => {
const ms = toAutoDeleteMs(autoDeleteEventsTime.value);
if (ms === null || autoDeleteTimers.has(eventId)) return;
const timer = globalThis.setTimeout(() => {
autoDeleteTimers.delete(eventId);
const locked = lockedIds.value ?? [];
if (locked.includes(eventId)) return;
void eventsApi.removeById(eventId);
}, ms);
autoDeleteTimers.set(eventId, timer);
};
const rescheduleAll = () => {
clearAllAutoDeleteTimers();
const ms = toAutoDeleteMs(autoDeleteEventsTime.value);
if (ms === null) return;
events.value.forEach(({ uuid }) => {
schedule(uuid);
});
};
const syncTimers = (currentIds: Set<EventId>, prevIds: Set<EventId>) => {
prevIds.forEach((id) => {
if (!currentIds.has(id)) {
clearAutoDeleteTimer(id);
}
});
if (toAutoDeleteMs(autoDeleteEventsTime.value) === null) return;
currentIds.forEach((id) => {
if (!prevIds.has(id)) {
schedule(id);
}
});
};
watch(
autoDeleteEventsTime,
() => {
rescheduleAll();
},
{ immediate: true },
);
watch(
() => events.value.map(({ uuid }) => uuid),
(current, prev) => {
const currentIds = new Set(current);
const prevIds = new Set(prev ?? []);
syncTimers(currentIds, prevIds);
},
);
watch(
() => lockedIds.value.slice(),
(current, prev) => {
const currentIds = new Set(current);
const prevIds = new Set(prev ?? []);
const eventsIds = new Set(events.value.map(({ uuid }) => uuid));
const unlockedIds = new Set(
[...prevIds].filter((id) => !currentIds.has(id) && eventsIds.has(id)),
);
syncTimers(currentIds, prevIds);
syncTimers(unlockedIds, new Set<EventId>());
},
);
};