@bit.rhplus/ui2.emoji-icons 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -2
- package/dist/index.js +99 -57
- package/dist/index.js.map +1 -1
- package/index.jsx +109 -59
- package/package.json +4 -3
- /package/dist/{preview-1764590989376.js → preview-1768405724660.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,15 @@ export function preloadIcons(iconNames: string[]): Promise<void>;
|
|
|
2
2
|
export function clearIconCache(): void;
|
|
3
3
|
export default EmojiIcon;
|
|
4
4
|
/**
|
|
5
|
-
* Komponenta pro zobrazení
|
|
5
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
6
6
|
*
|
|
7
|
-
* @param {string} name - Název ikony
|
|
7
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
8
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
8
9
|
* @param {number} size - Velikost ikony v pixelech
|
|
9
10
|
*
|
|
10
11
|
* Příklad použití:
|
|
11
12
|
* <EmojiIcon name="airplane" size={20} />
|
|
13
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
14
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
12
15
|
*/
|
|
13
16
|
declare function EmojiIcon({ name, size }: string): import("react/jsx-runtime").JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,9 @@ import React, { useState, useEffect } from 'react';
|
|
|
5
5
|
const iconCache = new Map();
|
|
6
6
|
const loadingIcons = new Set();
|
|
7
7
|
// Lokální storage klíč pro persistentní cache
|
|
8
|
-
const CACHE_KEY = '
|
|
9
|
-
const CACHE_VERSION = '
|
|
8
|
+
const CACHE_KEY = 'iconify-cache';
|
|
9
|
+
const CACHE_VERSION = '2.0'; // Zvýšena verze kvůli změně struktury cache
|
|
10
|
+
const DEFAULT_PREFIX = 'fluent-emoji-flat';
|
|
10
11
|
// Načtení cache z localStorage při inicializaci
|
|
11
12
|
const loadCacheFromStorage = () => {
|
|
12
13
|
try {
|
|
@@ -19,7 +20,6 @@ const loadCacheFromStorage = () => {
|
|
|
19
20
|
iconCache.set(iconName, iconData);
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
|
-
console.log(`Loaded ${Object.keys(data).length} icons from cache`);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -43,28 +43,56 @@ const saveCacheToStorage = () => {
|
|
|
43
43
|
// Inicializace cache při načtení modulu
|
|
44
44
|
loadCacheFromStorage();
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Parsuje název ikony ve formátu "prefix:iconName"
|
|
47
|
+
* @param {string} name - Název ikony (např. 'airplane' nebo 'fluent-color:receipt-16')
|
|
48
|
+
* @returns {{ fullName: string, prefix: string, iconName: string }}
|
|
49
|
+
*/
|
|
50
|
+
const parseIconName = (name) => {
|
|
51
|
+
if (!name) {
|
|
52
|
+
return { fullName: '', prefix: DEFAULT_PREFIX, iconName: '' };
|
|
53
|
+
}
|
|
54
|
+
// Pokud obsahuje ":", rozdělíme na prefix a iconName
|
|
55
|
+
if (name.includes(':')) {
|
|
56
|
+
const [prefix, iconName] = name.split(':', 2);
|
|
57
|
+
return {
|
|
58
|
+
fullName: `${prefix}:${iconName}`,
|
|
59
|
+
prefix,
|
|
60
|
+
iconName
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Pokud neobsahuje ":", použijeme default prefix
|
|
64
|
+
return {
|
|
65
|
+
fullName: `${DEFAULT_PREFIX}:${name}`,
|
|
66
|
+
prefix: DEFAULT_PREFIX,
|
|
67
|
+
iconName: name
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
47
72
|
*
|
|
48
|
-
* @param {string} name - Název ikony
|
|
73
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
74
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
49
75
|
* @param {number} size - Velikost ikony v pixelech
|
|
50
76
|
*
|
|
51
77
|
* Příklad použití:
|
|
52
78
|
* <EmojiIcon name="airplane" size={20} />
|
|
79
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
80
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
53
81
|
*/
|
|
54
82
|
const EmojiIcon = ({ name, size = 20 }) => {
|
|
55
|
-
const iconName = name;
|
|
56
|
-
const [iconData, setIconData] = useState(iconCache.get(
|
|
83
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
84
|
+
const [iconData, setIconData] = useState(iconCache.get(fullName) || null);
|
|
57
85
|
useEffect(() => {
|
|
58
86
|
// Pokud už je ikona v cache, použijeme ji okamžitě
|
|
59
|
-
if (iconCache.has(
|
|
60
|
-
setIconData(iconCache.get(
|
|
87
|
+
if (iconCache.has(fullName)) {
|
|
88
|
+
setIconData(iconCache.get(fullName));
|
|
61
89
|
return;
|
|
62
90
|
}
|
|
63
91
|
// Pokud se ikona již načítá, počkáme
|
|
64
|
-
if (loadingIcons.has(
|
|
92
|
+
if (loadingIcons.has(fullName)) {
|
|
65
93
|
const checkInterval = setInterval(() => {
|
|
66
|
-
if (iconCache.has(
|
|
67
|
-
setIconData(iconCache.get(
|
|
94
|
+
if (iconCache.has(fullName)) {
|
|
95
|
+
setIconData(iconCache.get(fullName));
|
|
68
96
|
clearInterval(checkInterval);
|
|
69
97
|
}
|
|
70
98
|
}, 50);
|
|
@@ -77,9 +105,9 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
77
105
|
};
|
|
78
106
|
}
|
|
79
107
|
// Označíme ikonu jako načítající se
|
|
80
|
-
loadingIcons.add(
|
|
81
|
-
// Načteme ikonu z Iconify API
|
|
82
|
-
fetch(`https://api.iconify.design
|
|
108
|
+
loadingIcons.add(fullName);
|
|
109
|
+
// Načteme ikonu z Iconify API s použitím správného prefixu
|
|
110
|
+
fetch(`https://api.iconify.design/${prefix}.json?icons=${iconName}`)
|
|
83
111
|
.then(res => res.json())
|
|
84
112
|
.then(data => {
|
|
85
113
|
if (data && data.icons && data.icons[iconName]) {
|
|
@@ -88,18 +116,18 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
88
116
|
width: data.width || 32,
|
|
89
117
|
height: data.height || 32
|
|
90
118
|
};
|
|
91
|
-
// Uložíme do naší cache
|
|
92
|
-
iconCache.set(
|
|
119
|
+
// Uložíme do naší cache s plným názvem
|
|
120
|
+
iconCache.set(fullName, newIconData);
|
|
93
121
|
saveCacheToStorage();
|
|
94
122
|
setIconData(newIconData);
|
|
95
|
-
loadingIcons.delete(
|
|
123
|
+
loadingIcons.delete(fullName);
|
|
96
124
|
}
|
|
97
125
|
})
|
|
98
126
|
.catch(e => {
|
|
99
|
-
console.warn(`Failed to load icon ${
|
|
100
|
-
loadingIcons.delete(
|
|
127
|
+
console.warn(`Failed to load icon ${fullName}:`, e);
|
|
128
|
+
loadingIcons.delete(fullName);
|
|
101
129
|
});
|
|
102
|
-
}, [iconName]);
|
|
130
|
+
}, [fullName, prefix, iconName]);
|
|
103
131
|
// Pokud nemáme data, zobrazíme placeholder
|
|
104
132
|
if (!iconData) {
|
|
105
133
|
return (_jsx("span", { style: {
|
|
@@ -119,52 +147,66 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
119
147
|
* Funkce pro předběžné načtení ikon do cache
|
|
120
148
|
* Volej před prvním renderem pro načtení důležitých ikon
|
|
121
149
|
*
|
|
122
|
-
* @param {string[]} iconNames - Pole názvů ikon k načtení
|
|
150
|
+
* @param {string[]} iconNames - Pole názvů ikon k načtení (podporuje formát "prefix:iconName")
|
|
123
151
|
*
|
|
124
152
|
* Příklad:
|
|
125
|
-
* preloadIcons(['airplane', 'warning', '
|
|
153
|
+
* preloadIcons(['airplane', 'warning', 'fluent-color:receipt-16']);
|
|
126
154
|
*/
|
|
127
155
|
export const preloadIcons = async (iconNames) => {
|
|
128
|
-
//
|
|
129
|
-
const
|
|
130
|
-
|
|
156
|
+
// Seskupíme ikony podle prefixu
|
|
157
|
+
const iconsByPrefix = new Map();
|
|
158
|
+
iconNames.forEach(name => {
|
|
159
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
160
|
+
// Přeskočíme ikony, které už jsou v cache nebo se načítají
|
|
161
|
+
if (iconCache.has(fullName) || loadingIcons.has(fullName)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (!iconsByPrefix.has(prefix)) {
|
|
165
|
+
iconsByPrefix.set(prefix, []);
|
|
166
|
+
}
|
|
167
|
+
iconsByPrefix.get(prefix).push({ fullName, iconName });
|
|
131
168
|
});
|
|
132
|
-
if (
|
|
169
|
+
if (iconsByPrefix.size === 0) {
|
|
133
170
|
console.log('All icons already cached');
|
|
134
171
|
return;
|
|
135
172
|
}
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
173
|
+
// Načteme ikony pro každý prefix samostatně
|
|
174
|
+
const promises = Array.from(iconsByPrefix.entries()).map(async ([prefix, icons]) => {
|
|
175
|
+
// Označíme všechny jako načítající se
|
|
176
|
+
icons.forEach(({ fullName }) => {
|
|
177
|
+
loadingIcons.add(fullName);
|
|
178
|
+
});
|
|
179
|
+
try {
|
|
180
|
+
// Načteme všechny ikony daného prefixu najednou
|
|
181
|
+
const iconsParam = icons.map(i => i.iconName).join(',');
|
|
182
|
+
const response = await fetch(`https://api.iconify.design/${prefix}.json?icons=${iconsParam}`);
|
|
183
|
+
const data = await response.json();
|
|
184
|
+
if (data && data.icons) {
|
|
185
|
+
Object.entries(data.icons).forEach(([name, iconInfo]) => {
|
|
186
|
+
const fullName = `${prefix}:${name}`;
|
|
187
|
+
const iconData = {
|
|
188
|
+
body: iconInfo.body,
|
|
189
|
+
width: data.width || 32,
|
|
190
|
+
height: data.height || 32
|
|
191
|
+
};
|
|
192
|
+
// Uložíme do naší cache s plným názvem
|
|
193
|
+
iconCache.set(fullName, iconData);
|
|
194
|
+
loadingIcons.delete(fullName);
|
|
195
|
+
});
|
|
196
|
+
console.log(`Preloaded ${Object.keys(data.icons).length} icons from ${prefix}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
console.warn(`Failed to preload icons from ${prefix}:`, e);
|
|
201
|
+
// Odstraníme z loading state
|
|
202
|
+
icons.forEach(({ fullName }) => {
|
|
203
|
+
loadingIcons.delete(fullName);
|
|
155
204
|
});
|
|
156
|
-
// Uložíme celou cache do localStorage
|
|
157
|
-
saveCacheToStorage();
|
|
158
|
-
console.log(`Preloaded ${Object.keys(data.icons).length} icons`);
|
|
159
205
|
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
iconsToLoad.forEach(name => {
|
|
165
|
-
loadingIcons.delete(name);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
206
|
+
});
|
|
207
|
+
await Promise.all(promises);
|
|
208
|
+
// Uložíme celou cache do localStorage
|
|
209
|
+
saveCacheToStorage();
|
|
168
210
|
};
|
|
169
211
|
/**
|
|
170
212
|
* Vymazání cache ikon
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnD,sCAAsC;AACtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;AAC5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;AAE/B,8CAA8C;AAC9C,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":"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"}
|
package/index.jsx
CHANGED
|
@@ -6,8 +6,9 @@ const iconCache = new Map();
|
|
|
6
6
|
const loadingIcons = new Set();
|
|
7
7
|
|
|
8
8
|
// Lokální storage klíč pro persistentní cache
|
|
9
|
-
const CACHE_KEY = '
|
|
10
|
-
const CACHE_VERSION = '
|
|
9
|
+
const CACHE_KEY = 'iconify-cache';
|
|
10
|
+
const CACHE_VERSION = '2.0'; // Zvýšena verze kvůli změně struktury cache
|
|
11
|
+
const DEFAULT_PREFIX = 'fluent-emoji-flat';
|
|
11
12
|
|
|
12
13
|
// Načtení cache z localStorage při inicializaci
|
|
13
14
|
const loadCacheFromStorage = () => {
|
|
@@ -21,7 +22,6 @@ const loadCacheFromStorage = () => {
|
|
|
21
22
|
iconCache.set(iconName, iconData);
|
|
22
23
|
}
|
|
23
24
|
});
|
|
24
|
-
console.log(`Loaded ${Object.keys(data).length} icons from cache`);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
} catch (e) {
|
|
@@ -46,30 +46,61 @@ const saveCacheToStorage = () => {
|
|
|
46
46
|
loadCacheFromStorage();
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* Parsuje název ikony ve formátu "prefix:iconName"
|
|
50
|
+
* @param {string} name - Název ikony (např. 'airplane' nebo 'fluent-color:receipt-16')
|
|
51
|
+
* @returns {{ fullName: string, prefix: string, iconName: string }}
|
|
52
|
+
*/
|
|
53
|
+
const parseIconName = (name) => {
|
|
54
|
+
if (!name) {
|
|
55
|
+
return { fullName: '', prefix: DEFAULT_PREFIX, iconName: '' };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Pokud obsahuje ":", rozdělíme na prefix a iconName
|
|
59
|
+
if (name.includes(':')) {
|
|
60
|
+
const [prefix, iconName] = name.split(':', 2);
|
|
61
|
+
return {
|
|
62
|
+
fullName: `${prefix}:${iconName}`,
|
|
63
|
+
prefix,
|
|
64
|
+
iconName
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Pokud neobsahuje ":", použijeme default prefix
|
|
69
|
+
return {
|
|
70
|
+
fullName: `${DEFAULT_PREFIX}:${name}`,
|
|
71
|
+
prefix: DEFAULT_PREFIX,
|
|
72
|
+
iconName: name
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
50
78
|
*
|
|
51
|
-
* @param {string} name - Název ikony
|
|
79
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
80
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
52
81
|
* @param {number} size - Velikost ikony v pixelech
|
|
53
82
|
*
|
|
54
83
|
* Příklad použití:
|
|
55
84
|
* <EmojiIcon name="airplane" size={20} />
|
|
85
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
86
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
56
87
|
*/
|
|
57
88
|
const EmojiIcon = ({ name, size = 20 }) => {
|
|
58
|
-
const iconName = name;
|
|
59
|
-
const [iconData, setIconData] = useState(iconCache.get(
|
|
89
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
90
|
+
const [iconData, setIconData] = useState(iconCache.get(fullName) || null);
|
|
60
91
|
|
|
61
92
|
useEffect(() => {
|
|
62
93
|
// Pokud už je ikona v cache, použijeme ji okamžitě
|
|
63
|
-
if (iconCache.has(
|
|
64
|
-
setIconData(iconCache.get(
|
|
94
|
+
if (iconCache.has(fullName)) {
|
|
95
|
+
setIconData(iconCache.get(fullName));
|
|
65
96
|
return;
|
|
66
97
|
}
|
|
67
98
|
|
|
68
99
|
// Pokud se ikona již načítá, počkáme
|
|
69
|
-
if (loadingIcons.has(
|
|
100
|
+
if (loadingIcons.has(fullName)) {
|
|
70
101
|
const checkInterval = setInterval(() => {
|
|
71
|
-
if (iconCache.has(
|
|
72
|
-
setIconData(iconCache.get(
|
|
102
|
+
if (iconCache.has(fullName)) {
|
|
103
|
+
setIconData(iconCache.get(fullName));
|
|
73
104
|
clearInterval(checkInterval);
|
|
74
105
|
}
|
|
75
106
|
}, 50);
|
|
@@ -85,10 +116,10 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
85
116
|
}
|
|
86
117
|
|
|
87
118
|
// Označíme ikonu jako načítající se
|
|
88
|
-
loadingIcons.add(
|
|
119
|
+
loadingIcons.add(fullName);
|
|
89
120
|
|
|
90
|
-
// Načteme ikonu z Iconify API
|
|
91
|
-
fetch(`https://api.iconify.design
|
|
121
|
+
// Načteme ikonu z Iconify API s použitím správného prefixu
|
|
122
|
+
fetch(`https://api.iconify.design/${prefix}.json?icons=${iconName}`)
|
|
92
123
|
.then(res => res.json())
|
|
93
124
|
.then(data => {
|
|
94
125
|
if (data && data.icons && data.icons[iconName]) {
|
|
@@ -98,18 +129,18 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
98
129
|
height: data.height || 32
|
|
99
130
|
};
|
|
100
131
|
|
|
101
|
-
// Uložíme do naší cache
|
|
102
|
-
iconCache.set(
|
|
132
|
+
// Uložíme do naší cache s plným názvem
|
|
133
|
+
iconCache.set(fullName, newIconData);
|
|
103
134
|
saveCacheToStorage();
|
|
104
135
|
setIconData(newIconData);
|
|
105
|
-
loadingIcons.delete(
|
|
136
|
+
loadingIcons.delete(fullName);
|
|
106
137
|
}
|
|
107
138
|
})
|
|
108
139
|
.catch(e => {
|
|
109
|
-
console.warn(`Failed to load icon ${
|
|
110
|
-
loadingIcons.delete(
|
|
140
|
+
console.warn(`Failed to load icon ${fullName}:`, e);
|
|
141
|
+
loadingIcons.delete(fullName);
|
|
111
142
|
});
|
|
112
|
-
}, [iconName]);
|
|
143
|
+
}, [fullName, prefix, iconName]);
|
|
113
144
|
|
|
114
145
|
// Pokud nemáme data, zobrazíme placeholder
|
|
115
146
|
if (!iconData) {
|
|
@@ -145,57 +176,76 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
145
176
|
* Funkce pro předběžné načtení ikon do cache
|
|
146
177
|
* Volej před prvním renderem pro načtení důležitých ikon
|
|
147
178
|
*
|
|
148
|
-
* @param {string[]} iconNames - Pole názvů ikon k načtení
|
|
179
|
+
* @param {string[]} iconNames - Pole názvů ikon k načtení (podporuje formát "prefix:iconName")
|
|
149
180
|
*
|
|
150
181
|
* Příklad:
|
|
151
|
-
* preloadIcons(['airplane', 'warning', '
|
|
182
|
+
* preloadIcons(['airplane', 'warning', 'fluent-color:receipt-16']);
|
|
152
183
|
*/
|
|
153
184
|
export const preloadIcons = async (iconNames) => {
|
|
154
|
-
//
|
|
155
|
-
const
|
|
156
|
-
|
|
185
|
+
// Seskupíme ikony podle prefixu
|
|
186
|
+
const iconsByPrefix = new Map();
|
|
187
|
+
|
|
188
|
+
iconNames.forEach(name => {
|
|
189
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
190
|
+
|
|
191
|
+
// Přeskočíme ikony, které už jsou v cache nebo se načítají
|
|
192
|
+
if (iconCache.has(fullName) || loadingIcons.has(fullName)) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!iconsByPrefix.has(prefix)) {
|
|
197
|
+
iconsByPrefix.set(prefix, []);
|
|
198
|
+
}
|
|
199
|
+
iconsByPrefix.get(prefix).push({ fullName, iconName });
|
|
157
200
|
});
|
|
158
201
|
|
|
159
|
-
if (
|
|
202
|
+
if (iconsByPrefix.size === 0) {
|
|
160
203
|
console.log('All icons already cached');
|
|
161
204
|
return;
|
|
162
205
|
}
|
|
163
206
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
207
|
+
// Načteme ikony pro každý prefix samostatně
|
|
208
|
+
const promises = Array.from(iconsByPrefix.entries()).map(async ([prefix, icons]) => {
|
|
209
|
+
// Označíme všechny jako načítající se
|
|
210
|
+
icons.forEach(({ fullName }) => {
|
|
211
|
+
loadingIcons.add(fullName);
|
|
212
|
+
});
|
|
168
213
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
214
|
+
try {
|
|
215
|
+
// Načteme všechny ikony daného prefixu najednou
|
|
216
|
+
const iconsParam = icons.map(i => i.iconName).join(',');
|
|
217
|
+
const response = await fetch(`https://api.iconify.design/${prefix}.json?icons=${iconsParam}`);
|
|
218
|
+
const data = await response.json();
|
|
219
|
+
|
|
220
|
+
if (data && data.icons) {
|
|
221
|
+
Object.entries(data.icons).forEach(([name, iconInfo]) => {
|
|
222
|
+
const fullName = `${prefix}:${name}`;
|
|
223
|
+
const iconData = {
|
|
224
|
+
body: iconInfo.body,
|
|
225
|
+
width: data.width || 32,
|
|
226
|
+
height: data.height || 32
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Uložíme do naší cache s plným názvem
|
|
230
|
+
iconCache.set(fullName, iconData);
|
|
231
|
+
loadingIcons.delete(fullName);
|
|
232
|
+
});
|
|
187
233
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
234
|
+
console.log(`Preloaded ${Object.keys(data.icons).length} icons from ${prefix}`);
|
|
235
|
+
}
|
|
236
|
+
} catch (e) {
|
|
237
|
+
console.warn(`Failed to preload icons from ${prefix}:`, e);
|
|
238
|
+
// Odstraníme z loading state
|
|
239
|
+
icons.forEach(({ fullName }) => {
|
|
240
|
+
loadingIcons.delete(fullName);
|
|
241
|
+
});
|
|
191
242
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
await Promise.all(promises);
|
|
246
|
+
|
|
247
|
+
// Uložíme celou cache do localStorage
|
|
248
|
+
saveCacheToStorage();
|
|
199
249
|
};
|
|
200
250
|
|
|
201
251
|
/**
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bit.rhplus/ui2.emoji-icons",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"homepage": "https://bit.cloud/remote-scope/ui2/emoji-icons",
|
|
4
5
|
"main": "dist/index.js",
|
|
5
6
|
"componentId": {
|
|
7
|
+
"scope": "remote-scope",
|
|
6
8
|
"name": "ui2/emoji-icons",
|
|
7
|
-
"version": "0.0.
|
|
8
|
-
"scope": "remote-scope"
|
|
9
|
+
"version": "0.0.3"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {},
|
|
11
12
|
"devDependencies": {
|
|
File without changes
|