mirror of https://github.com/Lissy93/dashy.git
🔀 Merge pull request #141 from Lissy93/FEATURE/brand-icon-support
[FEATURE] - Support for Material Icons Closes #139
This commit is contained in:
commit
ff1249bb13
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## ✨ 1.5.7 - Adds Support for Material Design Icons [PR #141](https://github.com/Lissy93/dashy/pull/141)
|
||||||
|
- Enables user to use any icon from [materialdesignicons.com](https://dev.materialdesignicons.com/icons), Re: #139
|
||||||
|
- Also adds support for [simpleicons.org](https://simpleicons.org/)
|
||||||
|
- Assets only loaded when needed
|
||||||
|
- Adds docs for using MDI icons
|
||||||
|
|
||||||
## ⚡️ 1.5.6 - Refactor + Couple of small things [PR #135](https://github.com/Lissy93/dashy/pull/135)
|
## ⚡️ 1.5.6 - Refactor + Couple of small things [PR #135](https://github.com/Lissy93/dashy/pull/135)
|
||||||
- The main Dockerfile now uses yarn.lock instead of package-lock.json
|
- The main Dockerfile now uses yarn.lock instead of package-lock.json
|
||||||
- Adds a check to verify password is not empty in cloud backup screen
|
- Adds a check to verify password is not empty in cloud backup screen
|
||||||
|
|
12
README.md
12
README.md
|
@ -102,7 +102,7 @@ Are using Dashy? Want to share your dashboard here too - [Submit your Screenshot
|
||||||
|
|
||||||
> For full setup instructions, see: [**Deployment**](./docs/deployment.md)
|
> For full setup instructions, see: [**Deployment**](./docs/deployment.md)
|
||||||
|
|
||||||
#### Deploying from Docker Hub 🐳
|
### Deploying from Docker Hub 🐳
|
||||||
|
|
||||||
You will need [Docker](https://docs.docker.com/get-docker/) installed on your system
|
You will need [Docker](https://docs.docker.com/get-docker/) installed on your system
|
||||||
|
|
||||||
|
@ -122,13 +122,12 @@ docker run -d \
|
||||||
```
|
```
|
||||||
|
|
||||||
If you prefer to use Docker Compose, [here is an example](./docs/deployment.md#using-docker-compose).
|
If you prefer to use Docker Compose, [here is an example](./docs/deployment.md#using-docker-compose).
|
||||||
You can also build the Docker container from source, by cloning the repo, cd'ing into it and running `docker build .` and `docker compose up`.
|
|
||||||
|
|
||||||
> Once you've got Dashy running, you can take a look at [App Management Docs](./docs/management.md), for info on using health checks, provisioning assets, configuring web servers, securing your app, logs, performance and more.
|
> Once you've got Dashy running, you can take a look at [App Management Docs](./docs/management.md), for info on using health checks, provisioning assets, configuring web servers, securing your app, logs, performance and more.
|
||||||
|
|
||||||
#### Deploying from Source 🚀
|
### Deploying from Source 🚀
|
||||||
|
|
||||||
You will need both [git](https://git-scm.com/downloads) and the latest or LTS version of [Node.js](https://nodejs.org/) installed on your system
|
You will need [git](https://git-scm.com/downloads), the latest or LTS version of [Node.js](https://nodejs.org/) and (optionally) [Yarn](https://yarnpkg.com/) installed on your system.
|
||||||
|
|
||||||
- Get Code: `git clone git@github.com:Lissy93/dashy.git` and `cd dashy`
|
- Get Code: `git clone git@github.com:Lissy93/dashy.git` and `cd dashy`
|
||||||
- Configuration: Fill in you're settings in `./public/conf.yml`
|
- Configuration: Fill in you're settings in `./public/conf.yml`
|
||||||
|
@ -138,7 +137,7 @@ You will need both [git](https://git-scm.com/downloads) and the latest or LTS ve
|
||||||
|
|
||||||
> See docs [Full list of Dashy's commands](./docs/management.md#basic-commands)
|
> See docs [Full list of Dashy's commands](./docs/management.md#basic-commands)
|
||||||
|
|
||||||
#### Deploy to the Cloud ☁️
|
### Deploy to the Cloud ☁️
|
||||||
|
|
||||||
Dashy supports 1-Click deployments on several popular cloud platforms. To spin up a new instance, just click a link below:
|
Dashy supports 1-Click deployments on several popular cloud platforms. To spin up a new instance, just click a link below:
|
||||||
- [<img src="https://i.ibb.co/ZxtzrP3/netlify.png" width="18"/> Deploy to Netlify](https://app.netlify.com/start/deploy?repository=https://github.com/lissy93/dashy)
|
- [<img src="https://i.ibb.co/ZxtzrP3/netlify.png" width="18"/> Deploy to Netlify](https://app.netlify.com/start/deploy?repository=https://github.com/lissy93/dashy)
|
||||||
|
@ -207,7 +206,8 @@ Both sections and items can have an icon associated with them, and defined under
|
||||||
- **Generative**: Setting `icon: generative`, will generate a unique for a given service, based on it's URL or IP
|
- **Generative**: Setting `icon: generative`, will generate a unique for a given service, based on it's URL or IP
|
||||||
- **Emoji**: Use an emoji as a tile icon, by putting the emoji's code as the icon attribute. Emojis can be specified either as emojis (`🚀`), unicode (`'U+1F680'`) or shortcode (`':rocket:'`).
|
- **Emoji**: Use an emoji as a tile icon, by putting the emoji's code as the icon attribute. Emojis can be specified either as emojis (`🚀`), unicode (`'U+1F680'`) or shortcode (`':rocket:'`).
|
||||||
- **URL**: You can also pass in a URL to an icon asset, hosted either locally or using any CDN service. E.g. `icon: https://i.ibb.co/710B3Yc/space-invader-x256.png`.
|
- **URL**: You can also pass in a URL to an icon asset, hosted either locally or using any CDN service. E.g. `icon: https://i.ibb.co/710B3Yc/space-invader-x256.png`.
|
||||||
- **Local Image**: To use a local image, store it in `./public/item-icons/` (or create a volume in Docker: `-v /local/image/directory:/app/public/item-icons/`) , and reference it by name and extension - e.g. set `icon: image.png` to use `./public/item-icon/image.png`. You can also use sub-folders here if you have a lot of icons, to keep them organized.
|
- **Local Image**: To use a local image, store it in `./public/item-icons/` (or create a volume in Docker: `-v /local/image/directory:/app/public/item-icons/`) , and reference it by name and extension - e.g. set `icon: image.png` to use `./public/item-icon/image.png`. You can also use sub-folders here.
|
||||||
|
- **Material Design Icons**: You can also use any icon from [materialdesignicons.com](https://dev.materialdesignicons.com/icons) by setting the icon to `mdi-[icon-name]`.
|
||||||
|
|
||||||
**[⬆️ Back to Top](#dashy)**
|
**[⬆️ Back to Top](#dashy)**
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ To disallow any changes from being written to disk via the UI config editor, set
|
||||||
|
|
||||||
**Field** | **Type** | **Required**| **Description**
|
**Field** | **Type** | **Required**| **Description**
|
||||||
--- | --- | --- | ---
|
--- | --- | --- | ---
|
||||||
**`icon`** | `string` | _Optional_ | The icon for a given item or section. Can be a font-awesome icon, favicon, remote URL or local URL. If set to `favicon`, the icon will be automatically fetched from the items website URL. To use font-awesome, specify the category, followed by the icon name, e.g. `fas fa-rocket`, `fab fa-monero` or `fal fa-duck` - note that to use pro icons, you mut specify `appConfig.fontAwesomeKey`. If set to `generative`, then a unique icon is generated from the apps URL or IP. You can also use hosted any by specifying it's URL, e.g. `https://i.ibb.co/710B3Yc/space-invader-x256.png`. To use a local image, first store it in `./public/item-icons/` (or `-v /app/public/item-icons/` in Docker) , and reference it by name and extension - e.g. set `image.png` to use `./public/item-icon/image.png`, you can also use sub-folders if you have a lot of icons, to keep them organised.
|
**`icon`** | `string` | _Optional_ | The icon for a given item or section. Can be a font-awesome icon, favicon, remote URL or local URL. If set to `favicon`, the icon will be automatically fetched from the items website URL. To use font-awesome, specify the category, followed by the icon name, e.g. `fas fa-rocket`, `fab fa-monero` or `fal fa-duck` - note that to use pro icons, you mut specify `appConfig.fontAwesomeKey`. Similarly, you can also use [simple-icons](https://simpleicons.org/) by setting icon to `si-[icon-name]` or [material-design-icons](https://dev.materialdesignicons.com/icons) by setting icon to `mdi-[icon-name]`. If set to `generative`, then a unique icon is generated from the apps URL or IP. You can also use hosted any by specifying it's URL, e.g. `https://i.ibb.co/710B3Yc/space-invader-x256.png`. To use a local image, first store it in `./public/item-icons/` (or `-v /app/public/item-icons/` in Docker) , and reference it by name and extension - e.g. set `image.png` to use `./public/item-icon/image.png`, you can also use sub-folders if you have a lot of icons, to keep them organised.
|
||||||
|
|
||||||
**[⬆️ Back to Top](#configuring)**
|
**[⬆️ Back to Top](#configuring)**
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ Both sections and items can have an icon, which is specified using the `icon` at
|
||||||
<img width="500" src="https://i.ibb.co/GTVmZnc/dashy-example-icons.png" />
|
<img width="500" src="https://i.ibb.co/GTVmZnc/dashy-example-icons.png" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
Note that, if you are using icons from an external source (like font-awesome or material-design-icons), then the relevant font file will be loaded in automatically if and when needed, but combining icons from multiple services may have a negative impact on performance.
|
||||||
|
|
||||||
### Font Awesome
|
### Font Awesome
|
||||||
You can use any [Font Awesome Icon](https://fontawesome.com/icons) simply by specifying it's identifier. This is in the format of `[category] [name]` and can be found on the page for any given icon on the Font Awesome site. For example: `fas fa-rocket`, `fab fa-monero` or `fas fa-unicorn`.
|
You can use any [Font Awesome Icon](https://fontawesome.com/icons) simply by specifying it's identifier. This is in the format of `[category] [name]` and can be found on the page for any given icon on the Font Awesome site. For example: `fas fa-rocket`, `fab fa-monero` or `fas fa-unicorn`.
|
||||||
|
|
||||||
|
@ -54,7 +56,7 @@ You can use almost any emoji as an icon for items or sections. You can specify t
|
||||||
<img width="580" src="https://i.ibb.co/YLwgTf9/emoji-icons-1.png" />
|
<img width="580" src="https://i.ibb.co/YLwgTf9/emoji-icons-1.png" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
The following example shows the unicode options available, all three will render the 🚀 emoji.
|
The following examples will all render the same rocket (🚀) emoji:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
items:
|
items:
|
||||||
|
@ -74,5 +76,25 @@ You may also want to store your icons locally, bundled within Dashy so that ther
|
||||||
|
|
||||||
You can also use sub-folders within the `item-icons` directory to keep things organised. You would then specify an icon with it's folder name slash image name. For example: `networking/monit.png`
|
You can also use sub-folders within the `item-icons` directory to keep things organised. You would then specify an icon with it's folder name slash image name. For example: `networking/monit.png`
|
||||||
|
|
||||||
|
### Material Design Icons
|
||||||
|
Dashy also supports 5000+ [material-design-icons](https://github.com/Templarian/MaterialDesign). To use these, first find the name/ slug for your icon [here](https://dev.materialdesignicons.com/icons), and then prefix is with `mdi-`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```yaml
|
||||||
|
sections:
|
||||||
|
- name: Material Design Icons Example
|
||||||
|
items:
|
||||||
|
- title: Alien Icon
|
||||||
|
icon: mdi-alien
|
||||||
|
- title: Fire Icon
|
||||||
|
icon: mdi-fire
|
||||||
|
- title: Dino Icon
|
||||||
|
icon: mdi-google-downasaur
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Simple Icons
|
||||||
|
To use glyphs from [SimpleIcons.org](https://simpleicons.org/), first find the icon slug, and then prefix it with `si-`. The image will be loaded directly from the Simple Icons
|
||||||
|
|
||||||
### No Icon
|
### No Icon
|
||||||
If you don't wish for a given item or section to have an icon, just leave out the `icon` attribute.
|
If you don't wish for a given item or section to have an icon, just leave out the `icon` attribute.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Dashy",
|
"name": "Dashy",
|
||||||
"version": "1.5.6",
|
"version": "1.5.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "server",
|
"main": "server",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="item-icon">
|
<div class="item-icon">
|
||||||
|
<!-- Font-Awesome Icon -->
|
||||||
<i v-if="iconType === 'font-awesome'" :class="`${icon} ${size}`" ></i>
|
<i v-if="iconType === 'font-awesome'" :class="`${icon} ${size}`" ></i>
|
||||||
|
<!-- Emoji Icon -->
|
||||||
<i v-else-if="iconType === 'emoji'" :class="`emoji-icon ${size}`" >{{getEmoji(iconPath)}}</i>
|
<i v-else-if="iconType === 'emoji'" :class="`emoji-icon ${size}`" >{{getEmoji(iconPath)}}</i>
|
||||||
|
<!-- Material Design Icon -->
|
||||||
|
<span v-else-if="iconType === 'mdi'" :class=" `mdi ${icon} ${size}`"></span>
|
||||||
|
<!-- Simple-Icons -->
|
||||||
|
<object v-else-if="iconType === 'si'" :class="`simple-icons ${size}`"
|
||||||
|
type="image/svg+xml" :data="getSimpleIcon(icon)"></object>
|
||||||
|
<!-- Standard image asset icon -->
|
||||||
<img v-else-if="icon" :src="iconPath" @error="imageNotFound"
|
<img v-else-if="icon" :src="iconPath" @error="imageNotFound"
|
||||||
:class="`tile-icon ${size} ${broken ? 'broken' : ''}`"
|
:class="`tile-icon ${size} ${broken ? 'broken' : ''}`"
|
||||||
/>
|
/>
|
||||||
|
<!-- Icon could not load/ broken url -->
|
||||||
<BrokenImage v-if="broken" class="missing-image" />
|
<BrokenImage v-if="broken" class="missing-image" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -12,7 +21,7 @@
|
||||||
<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';
|
import { faviconApi as defaultFaviconApi, faviconApiEndpoints, iconCdns } from '@/utils/defaults';
|
||||||
import EmojiUnicodeRegex from '@/utils/EmojiUnicodeRegex';
|
import EmojiUnicodeRegex from '@/utils/EmojiUnicodeRegex';
|
||||||
import emojiLookup from '@/utils/emojis.json';
|
import emojiLookup from '@/utils/emojis.json';
|
||||||
|
|
||||||
|
@ -28,17 +37,18 @@ export default {
|
||||||
BrokenImage,
|
BrokenImage,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
/* Determines the type of icon */
|
||||||
iconType: function iconType() {
|
iconType: function iconType() {
|
||||||
return this.determineImageType(this.icon);
|
return this.determineImageType(this.icon);
|
||||||
},
|
},
|
||||||
|
/* Gets the icon path, dependent on icon type */
|
||||||
iconPath: function iconPath() {
|
iconPath: function iconPath() {
|
||||||
return this.getIconPath(this.icon, this.url);
|
return this.getIconPath(this.icon, this.url);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
broken: false,
|
broken: false, // If true, was unable to resolve icon
|
||||||
// faviconApi: this.config.appConfig.faviconApi || defaultFaviconApi,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -80,7 +90,7 @@ export default {
|
||||||
getFavicon(fullUrl) {
|
getFavicon(fullUrl) {
|
||||||
if (this.shouldUseDefaultFavicon(fullUrl)) { // Check if we should use local icon
|
if (this.shouldUseDefaultFavicon(fullUrl)) { // Check if we should use local icon
|
||||||
const urlParts = fullUrl.split('/');
|
const urlParts = fullUrl.split('/');
|
||||||
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/favicon.ico`;
|
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/${iconCdns.faviconName}`;
|
||||||
} else if (fullUrl.includes('http')) { // Service is running publicly
|
} else if (fullUrl.includes('http')) { // Service is running publicly
|
||||||
const host = this.getHostName(fullUrl);
|
const host = this.getHostName(fullUrl);
|
||||||
const faviconApi = this.config.appConfig.faviconApi || defaultFaviconApi;
|
const faviconApi = this.config.appConfig.faviconApi || defaultFaviconApi;
|
||||||
|
@ -95,11 +105,18 @@ export default {
|
||||||
const isLocalIP = /(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD])|(localhost)/;
|
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');
|
return (isLocalIP.test(fullUrl) || this.config.appConfig.faviconApi === 'local');
|
||||||
},
|
},
|
||||||
|
/* Fetches the path of local images, from Docker container */
|
||||||
getLocalImagePath(img) {
|
getLocalImagePath(img) {
|
||||||
return `/item-icons/${img}`;
|
return `${iconCdns.localPath}/${img}`;
|
||||||
},
|
},
|
||||||
|
/* Formats the URL for fetching the generative icons */
|
||||||
getGenerativeIcon(url) {
|
getGenerativeIcon(url) {
|
||||||
return `https://ipsicon.io/${this.getHostName(url)}.svg`;
|
return `${iconCdns.generative}/${this.getHostName(url)}.svg`;
|
||||||
|
},
|
||||||
|
/* Formats the URL for getting Simple-Icons SVG asset */
|
||||||
|
getSimpleIcon(img) {
|
||||||
|
const imageName = img.replace('si-', '');
|
||||||
|
return `${iconCdns.si}/${imageName}.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) {
|
||||||
|
@ -108,8 +125,10 @@ export default {
|
||||||
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 'generative': return this.getGenerativeIcon(url);
|
||||||
case 'svg': return img;
|
case 'mdi': return img; // Material design icons
|
||||||
case 'emoji': return img;
|
case 'simple-icons': return this.getSimpleIcon(img);
|
||||||
|
case 'svg': return img; // Local SVG icon
|
||||||
|
case 'emoji': return img; // Emoji/ unicode
|
||||||
default: return '';
|
default: return '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -121,12 +140,15 @@ export default {
|
||||||
else if (this.isUrl(img)) imgType = 'url';
|
else if (this.isUrl(img)) imgType = 'url';
|
||||||
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.includes('mdi-')) imgType = 'mdi';
|
||||||
|
else if (img.includes('si-')) imgType = 'si';
|
||||||
else if (img === 'favicon') imgType = 'favicon';
|
else if (img === 'favicon') imgType = 'favicon';
|
||||||
else if (img === 'generative') imgType = 'generative';
|
else if (img === 'generative') imgType = 'generative';
|
||||||
else if (this.isEmoji(img).isEmoji) imgType = 'emoji';
|
else if (this.isEmoji(img).isEmoji) imgType = 'emoji';
|
||||||
else imgType = 'none';
|
else imgType = 'none';
|
||||||
return imgType;
|
return imgType;
|
||||||
},
|
},
|
||||||
|
/* For a given URL, return the hostname only. Used for favicon and generative icons */
|
||||||
getHostName(url) {
|
getHostName(url) {
|
||||||
try { return new URL(url).hostname; } catch (e) { return url; }
|
try { return new URL(url).hostname; } catch (e) { return url; }
|
||||||
},
|
},
|
||||||
|
@ -140,6 +162,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
/* Default Image Icon */
|
||||||
.tile-icon {
|
.tile-icon {
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
// filter: var(--item-icon-transform);
|
// filter: var(--item-icon-transform);
|
||||||
|
@ -152,7 +175,8 @@ export default {
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.fas, i.fab, i.far, i.fal, i.fad {
|
/* Font-Awesome and Material Design Icons */
|
||||||
|
i.fas, i.fab, i.far, i.fal, i.fad, span.mdi {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
color: currentColor;
|
color: currentColor;
|
||||||
margin: 1px 4px;
|
margin: 1px 4px;
|
||||||
|
@ -163,6 +187,9 @@ export default {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
span.mdi {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
object.tile-icon {
|
object.tile-icon {
|
||||||
width: 55px;
|
width: 55px;
|
||||||
height: 55px;
|
height: 55px;
|
||||||
|
@ -170,6 +197,13 @@ export default {
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Simple Icons */
|
||||||
|
object.simple-icons {
|
||||||
|
width: 2rem;
|
||||||
|
&.small { width: 1.5rem; }
|
||||||
|
&.large { width: 2.5rem; }
|
||||||
|
}
|
||||||
|
/* Emoji Icons */
|
||||||
i.emoji-icon {
|
i.emoji-icon {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
|
@ -181,6 +215,7 @@ export default {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Icon Not Found */
|
||||||
.missing-image {
|
.missing-image {
|
||||||
width: 3.5rem;
|
width: 3.5rem;
|
||||||
path {
|
path {
|
||||||
|
|
|
@ -126,6 +126,15 @@ module.exports = {
|
||||||
allesedv: 'https://f1.allesedv.com/128/$URL',
|
allesedv: 'https://f1.allesedv.com/128/$URL',
|
||||||
webmasterapi: 'https://api.webmasterapi.com/v1/favicon/yEwx0ZFs0CSPshHq/$URL',
|
webmasterapi: 'https://api.webmasterapi.com/v1/favicon/yEwx0ZFs0CSPshHq/$URL',
|
||||||
},
|
},
|
||||||
|
/* The URL to CDNs used for external icons. These are only loaded when required */
|
||||||
|
iconCdns: {
|
||||||
|
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',
|
||||||
|
localPath: '/item-icons',
|
||||||
|
faviconName: 'favicon.ico',
|
||||||
|
},
|
||||||
/* Available built-in colors for the theme builder */
|
/* Available built-in colors for the theme builder */
|
||||||
swatches: [
|
swatches: [
|
||||||
['#eb5cad', '#985ceb', '#5346f3', '#5c90eb'],
|
['#eb5cad', '#985ceb', '#5346f3', '#5c90eb'],
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
import SettingsContainer from '@/components/Settings/SettingsContainer.vue';
|
import SettingsContainer from '@/components/Settings/SettingsContainer.vue';
|
||||||
import ItemGroup from '@/components/LinkItems/ItemGroup.vue';
|
import ItemGroup from '@/components/LinkItems/ItemGroup.vue';
|
||||||
import Defaults, { localStorageKeys } from '@/utils/defaults';
|
import Defaults, { localStorageKeys, iconCdns } from '@/utils/defaults';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'home',
|
name: 'home',
|
||||||
|
@ -160,16 +160,21 @@ export default {
|
||||||
availibleThemes.Default = '#';
|
availibleThemes.Default = '#';
|
||||||
return availibleThemes;
|
return availibleThemes;
|
||||||
},
|
},
|
||||||
/* Checks if any of the icons are Font Awesome glyphs */
|
/* Checks if any sections or items use icons from a given CDN */
|
||||||
checkIfFontAwesomeNeeded() {
|
checkIfIconLibraryNeeded(prefix) {
|
||||||
let isNeeded = false;
|
let isNeeded = false;
|
||||||
if (!this.sections) return false;
|
if (!this.sections) return false;
|
||||||
this.sections.forEach((section) => {
|
this.sections.forEach((section) => {
|
||||||
if (section.icon && section.icon.includes('fa-')) isNeeded = true;
|
if (section.icon && section.icon.includes(prefix)) isNeeded = true;
|
||||||
section.items.forEach((item) => {
|
section.items.forEach((item) => {
|
||||||
if (item.icon && item.icon.includes('fa-')) isNeeded = true;
|
if (item.icon && item.icon.includes(prefix)) isNeeded = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return isNeeded;
|
||||||
|
},
|
||||||
|
/* Checks if any of the icons are Font Awesome glyphs */
|
||||||
|
checkIfFontAwesomeNeeded() {
|
||||||
|
let isNeeded = this.checkIfIconLibraryNeeded('fa-');
|
||||||
const currentTheme = localStorage[localStorageKeys.THEME]; // Some themes require FA
|
const currentTheme = localStorage[localStorageKeys.THEME]; // Some themes require FA
|
||||||
if (['material', 'material-dark'].includes(currentTheme)) isNeeded = true;
|
if (['material', 'material-dark'].includes(currentTheme)) isNeeded = true;
|
||||||
return isNeeded;
|
return isNeeded;
|
||||||
|
@ -179,10 +184,23 @@ export default {
|
||||||
if (this.appConfig.enableFontAwesome || this.checkIfFontAwesomeNeeded()) {
|
if (this.appConfig.enableFontAwesome || this.checkIfFontAwesomeNeeded()) {
|
||||||
const fontAwesomeScript = document.createElement('script');
|
const fontAwesomeScript = document.createElement('script');
|
||||||
const faKey = this.appConfig.fontAwesomeKey || Defaults.fontAwesomeKey;
|
const faKey = this.appConfig.fontAwesomeKey || Defaults.fontAwesomeKey;
|
||||||
fontAwesomeScript.setAttribute('src', `https://kit.fontawesome.com/${faKey}.js`);
|
fontAwesomeScript.setAttribute('src', `${iconCdns.fa}/${faKey}.js`);
|
||||||
document.head.appendChild(fontAwesomeScript);
|
document.head.appendChild(fontAwesomeScript);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/* Checks if any of the icons are Material Design Icons */
|
||||||
|
checkIfMdiNeeded() {
|
||||||
|
return this.checkIfIconLibraryNeeded('mdi-');
|
||||||
|
},
|
||||||
|
/* Injects Material Design Icons, only if needed */
|
||||||
|
initiateMaterialDesignIcons() {
|
||||||
|
if (this.checkIfMdiNeeded()) {
|
||||||
|
const mdiStylesheet = document.createElement('link');
|
||||||
|
mdiStylesheet.setAttribute('rel', 'stylesheet');
|
||||||
|
mdiStylesheet.setAttribute('href', iconCdns.mdi);
|
||||||
|
document.head.appendChild(mdiStylesheet);
|
||||||
|
}
|
||||||
|
},
|
||||||
/* Returns true if there is more than 1 sub-result visible during searching */
|
/* Returns true if there is more than 1 sub-result visible during searching */
|
||||||
checkIfResults() {
|
checkIfResults() {
|
||||||
if (!this.sections) return false;
|
if (!this.sections) return false;
|
||||||
|
@ -204,6 +222,7 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initiateFontAwesome();
|
this.initiateFontAwesome();
|
||||||
|
this.initiateMaterialDesignIcons();
|
||||||
this.layout = this.layoutOrientation;
|
this.layout = this.layoutOrientation;
|
||||||
this.itemSizeBound = this.iconSize;
|
this.itemSizeBound = this.iconSize;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue