mirror of https://github.com/Lissy93/dashy.git
✨ Implements new icon features, better favicon support and generative
This commit is contained in:
parent
4b3d20f43f
commit
b4b9d29170
|
@ -11,7 +11,7 @@
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
>
|
>
|
||||||
<label :for="`collapsible-${uniqueKey}`" class="lbl-toggle" tabindex="-1">
|
<label :for="`collapsible-${uniqueKey}`" class="lbl-toggle" tabindex="-1">
|
||||||
<Icon v-if="icon" :icon="icon" size="small" class="section-icon" />
|
<Icon v-if="icon" :icon="icon" size="small" :url="title" class="section-icon" />
|
||||||
<h3>{{ title }}</h3>
|
<h3>{{ title }}</h3>
|
||||||
</label>
|
</label>
|
||||||
<div class="collapsible-content">
|
<div class="collapsible-content">
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
<script>
|
<script>
|
||||||
import BrokenImage from '@/assets/interface-icons/broken-icon.svg';
|
import BrokenImage from '@/assets/interface-icons/broken-icon.svg';
|
||||||
import ErrorHandler from '@/utils/ErrorHandler';
|
import ErrorHandler from '@/utils/ErrorHandler';
|
||||||
|
import { faviconApi as defaultFaviconApi, faviconApiEndpoints } from '@/utils/defaults';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Icon',
|
name: 'Icon',
|
||||||
|
inject: ['config'],
|
||||||
props: {
|
props: {
|
||||||
icon: String, // Path to icon asset
|
icon: String, // Path to icon asset
|
||||||
url: String, // Used for fetching the favicon
|
url: String, // Used for fetching the favicon
|
||||||
|
@ -33,6 +35,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
broken: false,
|
broken: false,
|
||||||
|
// faviconApi: this.config.appConfig.faviconApi || defaultFaviconApi,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -51,26 +54,36 @@ export default {
|
||||||
},
|
},
|
||||||
/* Get favicon URL, for items which use the favicon as their icon */
|
/* Get favicon URL, for items which use the favicon as their icon */
|
||||||
getFavicon(fullUrl) {
|
getFavicon(fullUrl) {
|
||||||
const isLocalIP = /(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD])|(localhost)/;
|
if (this.shouldUseDefaultFavicon(fullUrl)) { // Check if we should use local icon
|
||||||
if (isLocalIP.test(fullUrl)) { // Check if using a local IP format or localhost
|
|
||||||
const urlParts = fullUrl.split('/');
|
const urlParts = fullUrl.split('/');
|
||||||
// For locally running services, use the default path for favicon
|
|
||||||
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/favicon.ico`;
|
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/favicon.ico`;
|
||||||
} else if (fullUrl.includes('http')) {
|
} else if (fullUrl.includes('http')) { // Service is running publicly
|
||||||
// For publicly accessible sites, a more reliable method is using Google's API
|
const host = this.getHostName(fullUrl);
|
||||||
return `https://s2.googleusercontent.com/s2/favicons?domain=${fullUrl}`;
|
const faviconApi = this.config.appConfig.faviconApi || defaultFaviconApi;
|
||||||
|
const endpoint = faviconApiEndpoints[faviconApi];
|
||||||
|
return endpoint.replace('$URL', host);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
/* If using favicon for icon, and if service is running locally (determined by local IP) */
|
||||||
|
/* or if user prefers local favicon, then return true */
|
||||||
|
shouldUseDefaultFavicon(fullUrl) {
|
||||||
|
const isLocalIP = /(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD])|(localhost)/;
|
||||||
|
return (isLocalIP.test(fullUrl) || this.config.appConfig.faviconApi === 'local');
|
||||||
|
},
|
||||||
getLocalImagePath(img) {
|
getLocalImagePath(img) {
|
||||||
return `/item-icons/${img}`;
|
return `/item-icons/${img}`;
|
||||||
},
|
},
|
||||||
|
getGenerativeIcon(url) {
|
||||||
|
return `https://ipsicon.io/${this.getHostName(url)}.svg`;
|
||||||
|
},
|
||||||
/* Checks if the icon is from a local image, remote URL, SVG or font-awesome */
|
/* Checks if the icon is from a local image, remote URL, SVG or font-awesome */
|
||||||
getIconPath(img, url) {
|
getIconPath(img, url) {
|
||||||
switch (this.determineImageType(img)) {
|
switch (this.determineImageType(img)) {
|
||||||
case 'url': return img;
|
case 'url': return img;
|
||||||
case 'img': return this.getLocalImagePath(img);
|
case 'img': return this.getLocalImagePath(img);
|
||||||
case 'favicon': return this.getFavicon(url);
|
case 'favicon': return this.getFavicon(url);
|
||||||
|
case 'generative': return this.getGenerativeIcon(url);
|
||||||
case 'svg': return img;
|
case 'svg': return img;
|
||||||
default: return '';
|
default: return '';
|
||||||
}
|
}
|
||||||
|
@ -84,9 +97,13 @@ export default {
|
||||||
else if (this.isImage(img)) imgType = 'img';
|
else if (this.isImage(img)) imgType = 'img';
|
||||||
else if (img.includes('fa-')) imgType = 'font-awesome';
|
else if (img.includes('fa-')) imgType = 'font-awesome';
|
||||||
else if (img === 'favicon') imgType = 'favicon';
|
else if (img === 'favicon') imgType = 'favicon';
|
||||||
|
else if (img === 'generative') imgType = 'generative';
|
||||||
else imgType = 'none';
|
else imgType = 'none';
|
||||||
return imgType;
|
return imgType;
|
||||||
},
|
},
|
||||||
|
getHostName(url) {
|
||||||
|
try { return new URL(url).hostname; } catch (e) { return url; }
|
||||||
|
},
|
||||||
/* Called when the path to the image cannot be resolved */
|
/* Called when the path to the image cannot be resolved */
|
||||||
imageNotFound() {
|
imageNotFound() {
|
||||||
this.broken = true;
|
this.broken = true;
|
||||||
|
|
Loading…
Reference in New Issue