forked from home-assistant/frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiconsets.ts
86 lines (74 loc) · 2.31 KB
/
iconsets.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
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
import { iconMetadata } from "../resources/icon-metadata";
import { IconMeta } from "../types";
import { get, set, clear, Store } from "idb-keyval";
export interface Icons {
[key: string]: string;
}
export interface Chunks {
[key: string]: Promise<Icons>;
}
export const iconStore = new Store("hass-icon-db", "mdi-icon-store");
export const MDI_PREFIXES = ["mdi", "hass", "hassio", "hademo"];
let toRead: Array<[string, (string) => void, () => void]> = [];
// Queue up as many icon fetches in 1 transaction
export const getIcon = (iconName: string) =>
new Promise<string>((resolve, reject) => {
toRead.push([iconName, resolve, reject]);
if (toRead.length > 1) {
return;
}
const results: Array<[(string) => void, IDBRequest]> = [];
iconStore
._withIDBStore("readonly", (store) => {
for (const [iconName_, resolve_] of toRead) {
results.push([resolve_, store.get(iconName_)]);
}
toRead = [];
})
.then(() => {
for (const [resolve_, request] of results) {
resolve_(request.result);
}
})
.catch(() => {
// Firefox in private mode doesn't support IDB
for (const [, , reject_] of toRead) {
reject_();
}
toRead = [];
});
});
export const findIconChunk = (icon): string => {
let lastChunk: IconMeta;
for (const chunk of iconMetadata.parts) {
if (chunk.start !== undefined && icon < chunk.start) {
break;
}
lastChunk = chunk;
}
return lastChunk!.file;
};
export const writeCache = async (chunks: Chunks) => {
const keys = Object.keys(chunks);
const iconsSets: Icons[] = await Promise.all(Object.values(chunks));
// We do a batch opening the store just once, for (considerable) performance
iconStore._withIDBStore("readwrite", (store) => {
iconsSets.forEach((icons, idx) => {
Object.entries(icons).forEach(([name, path]) => {
store.put(path, name);
});
delete chunks[keys[idx]];
});
});
};
export const checkCacheVersion = () => {
get("_version", iconStore).then((version) => {
if (!version) {
set("_version", iconMetadata.version, iconStore);
} else if (version !== iconMetadata.version) {
clear(iconStore).then(() =>
set("_version", iconMetadata.version, iconStore)
);
}
});
};