diff --git a/docs/icons.md b/docs/icons.md index 7267dc81a1..df0b585033 100644 --- a/docs/icons.md +++ b/docs/icons.md @@ -75,10 +75,10 @@ If for a given service none of the APIs work in your situation, and nor does loc --- ## Generative Icons -Uses a unique and programmatically generated icon for a given service. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with [ipsicon.io](https://ipsicon.io/). To use this option, just set an item's to: `icon: generative`. +Uses a unique and programmatically generated icon for a given service. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with [DiceBear](https://avatars.dicebear.com/), and use a hash of the services domain/ ip for entropy, so each domain will always have the same icon. To use this option, just set an item's to: `icon: generative`.

- +

--- @@ -113,6 +113,11 @@ sections: icon: hl-whooglesearch ``` + +

+ +

+ --- ## Icons by URL diff --git a/src/components/LinkItems/ItemIcon.vue b/src/components/LinkItems/ItemIcon.vue index 0696e5d8d8..45aa5f1a91 100644 --- a/src/components/LinkItems/ItemIcon.vue +++ b/src/components/LinkItems/ItemIcon.vue @@ -23,9 +23,10 @@ import simpleIcons from 'simple-icons'; import BrokenImage from '@/assets/interface-icons/broken-icon.svg'; import ErrorHandler from '@/utils/ErrorHandler'; -import { faviconApi as defaultFaviconApi, faviconApiEndpoints, iconCdns } from '@/utils/defaults'; import EmojiUnicodeRegex from '@/utils/EmojiUnicodeRegex'; import emojiLookup from '@/utils/emojis.json'; +import { faviconApi as defaultFaviconApi, faviconApiEndpoints, iconCdns } from '@/utils/defaults'; +import { asciiHash } from '@/utils/MiscHelpers'; export default { name: 'Icon', @@ -127,7 +128,8 @@ export default { }, /* Formats the URL for fetching the generative icons */ getGenerativeIcon(url) { - return `${iconCdns.generative}/${this.getHostName(url)}.svg`; + const host = encodeURI(url) || Math.random().toString(); + return iconCdns.generative.replace('{icon}', asciiHash(host)); }, /* Returns the SVG path content */ getSimpleIcon(img) { @@ -138,7 +140,7 @@ export default { /* Gets home-lab icon from GitHub */ getHomeLabIcon(img) { const imageName = img.replace('hl-', '').toLocaleLowerCase(); - return `${iconCdns.homeLabIcons}/png/${imageName}.png`; + return iconCdns.homeLabIcons.replace('{icon}', imageName); }, /* Checks if the icon is from a local image, remote URL, SVG or font-awesome */ getIconPath(img, url) { diff --git a/src/utils/MiscHelpers.js b/src/utils/MiscHelpers.js index 212e74957b..add6f457c4 100644 --- a/src/utils/MiscHelpers.js +++ b/src/utils/MiscHelpers.js @@ -3,4 +3,11 @@ import { hideFurnitureOn } from '@/utils/defaults'; /* Returns false if page furniture should be hidden on said route */ export const shouldBeVisible = (routeName) => !hideFurnitureOn.includes(routeName); -export const x = () => null; +/* Very rudimentary hash function for generative icons */ +export const asciiHash = (input) => { + const str = (!input || input.length === 0) ? Math.random().toString() : input; + const reducer = (previousHash, char) => (previousHash || 0) + char.charCodeAt(0); + const asciiSum = str.split('').reduce(reducer).toString(); + const shortened = asciiSum.slice(0, 30) + asciiSum.slice(asciiSum.length - 30); + return window.btoa(shortened); +}; diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 387d26e40a..2a475d458b 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -173,10 +173,10 @@ module.exports = { fa: 'https://kit.fontawesome.com', mdi: 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css', si: 'https://unpkg.com/simple-icons@v5/icons', - generative: 'https://ipsicon.io', + generative: 'https://avatars.dicebear.com/api/identicon/{icon}.svg', localPath: '/item-icons', faviconName: 'favicon.ico', - homeLabIcons: 'https://raw.githubusercontent.com/WalkxCode/dashboard-icons/master/', + homeLabIcons: 'https://raw.githubusercontent.com/WalkxCode/dashboard-icons/master/png/{icon}.png', }, /* URLs for web search engines */ searchEngineUrls: {