// source => icon data const enhancerIconSets = new Map(); getAsync(notionIconsUrl + 'icons.json', (iconsData) => { const data = JSON.parse(iconsData); (data.icons || data).forEach((set) => { enhancerIconSets.set(set.source, set); }); }); // array let customIconSets; if (store().json) { const customData = JSON.parse(fs.readFileSync(store().json)); customIconSets = customData.icons || customData; } // convert icons data into renderable function loadIconSets() { const iconSets = new DocumentFragment(); if (customIconSets) { customIconSets.forEach((i) => { iconSets.appendChild(renderIconSet(i)); }); // divider iconSets.appendChild(createElement('
')); } if (enhancerIconSets.size > 0) { enhancerIconSets.forEach((i, source) => { // ignore removed icon sets if (store().removedSets?.includes(source)) return; i.sourceUrl = i.sourceUrl || notionIconsUrl + source; iconSets.appendChild(renderIconSet(i, true)); }); } return iconSets; } // returns icon set element function renderIconSet(iconData, enhancerSet = false) { const iconSet = createElement('
'); try { const author = iconData.author ? iconData.authorUrl ? ` by ${iconData.author}` : ` by ${iconData.author}` : ''; const toggle = createElement(`
${menuIcons.triangle}
${iconData.name}${author}
`); const iconSetBody = createElement('
'); iconSet.append(toggle, iconSetBody); const promiseArray = []; // render icons for (let i = 0; i < (iconData.count || iconData.source.length); i++) { const iconUrl = iconData.sourceUrl ? Array.isArray(iconData.source) ? `${iconData.sourceUrl}/${iconData.source[i]}.${iconData.extension}` : `${iconData.sourceUrl}/${iconData.source}_${i}.${iconData.extension}` : iconData.source[i]; const icon = createElement(`
`); icon.innerHTML = enhancerSet ? // load sprite sheet `
` : ``; // add filters to filterMap const filters = []; if (iconData.filter) { if (iconData.filter === 'source') { const filename = iconUrl.match(/.*\/(.+?)\./); if (filename?.length > 1) { filters.push(...filename[1].split(/[ \-_]/)); } } else if (Array.isArray(iconData.filter)) { filters.push(...iconData.filter[i]); } icon.setAttribute('filter', filters.join(' ')); } // add set name and author to filters filters.push(...iconData.name.toLowerCase().split(' ')); if (iconData.author) filters.push(...iconData.author.toLowerCase().split(' ')); filterMap.set(icon, filters); // make sure icons load if (!enhancerSet) { promiseArray.push( new Promise((resolve, reject) => { icon.firstChild.onload = resolve; icon.firstChild.onerror = () => { reject(); icon.classList.add('error'); icon.innerHTML = '!'; }; }) ); } garbageCollector.push(icon); icon.addEventListener('click', () => setPageIcon(iconUrl)); iconSetBody.appendChild(icon); } // hide spinner after all icons finish loading (async () => { const spinner = toggle.querySelector('.notion-icons--spinner'), loadPromise = Promise.all(promiseArray); loadPromise.then( () => spinner.remove(), () => { iconSet.classList.add('alert'); spinner.remove(); } ); })(); // add remove icon set button if (enhancerSet) { const removeButton = createElement( `
${menuIcons.remove}
` ); removeButton.addEventListener('click', (e) => { e.stopPropagation(); removeIconSet(iconData); }); iconSet.querySelector('.notion-icons--actions').appendChild(removeButton); } // set up toggle toggle.addEventListener('click', (e) => { if (e.target.nodeName === 'A') return; toggleIconSet(iconSet); }); // hide by default? if (store().hide) requestAnimationFrame(() => toggleIconSet(iconSet)); // tooltip let timeout; iconSetBody.addEventListener('mouseover', (e) => { const el = e.target; if (!el.hasAttribute('filter')) return; document.querySelector('.notion-icons--tooltip')?.remove(); timeout = setTimeout(() => { renderTooltip(el, el.getAttribute('filter')); }, 300); }); iconSetBody.addEventListener('mouseout', (e) => { const el = e.target; if (!el.hasAttribute('filter')) return; document.querySelector('.notion-icons--tooltip')?.remove(); clearTimeout(timeout); }); } catch (err) { iconSet.classList.add('error'); iconSet.innerHTML = `Invalid Icon Set: ${iconData.name}`; } return iconSet; }