mirror of
https://github.com/taigrr/homer
synced 2025-01-18 04:53:12 -08:00
Merge branches 'fixDuplicateKeys', 'info' and 'scheme+layout' into main
This commit is contained in:
commit
8ada6cca70
@ -22,10 +22,12 @@ header: true # Set to false to hide the header
|
||||
footer: '<p>Created with <span class="has-text-danger">❤️</span> with <a href="https://bulma.io/">bulma</a>, <a href="https://vuejs.org/">vuejs</a> & <a href="https://fontawesome.com/">font awesome</a> // Fork me on <a href="https://github.com/bastienwirtz/homer"><i class="fab fa-github-alt"></i></a></p>' # set false if you want to hide it.
|
||||
|
||||
columns: "3" # "auto" or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)
|
||||
vlayout: true # default to the vertical layout
|
||||
connectivityCheck: true # whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example)
|
||||
|
||||
# Optional theming
|
||||
theme: default # 'default' or one of the theme available in 'src/assets/themes'.
|
||||
theme_use_dark: false # true or false, useful for overriding browser default in new sessions
|
||||
|
||||
# Optional custom stylesheet
|
||||
# Will load custom CSS files. Especially useful for custom icon sets.
|
||||
@ -97,6 +99,8 @@ services:
|
||||
tag: "app"
|
||||
url: "https://www.reddit.com/r/selfhosted/"
|
||||
target: "_blank" # optional html tag target attribute
|
||||
info: "https://github.com/bastienwirtz/homer/tree/main/docs" # optional link to documentation
|
||||
infotarget: "_blank" # same as target, but for icon link
|
||||
- name: "Another one"
|
||||
logo: "assets/tools/sample2.png"
|
||||
subtitle: "Another application"
|
||||
|
25
src/App.vue
25
src/App.vue
@ -28,9 +28,10 @@
|
||||
:links="config.links"
|
||||
@navbar-toggle="showMenu = !showMenu"
|
||||
>
|
||||
<DarkMode @updated="isDark = $event" />
|
||||
<DarkMode :isDark="this.isDark" @updated="isDark = $event" />
|
||||
|
||||
<SettingToggle
|
||||
<LayoutToggle
|
||||
:vlayout="this.vlayout"
|
||||
@updated="vlayout = $event"
|
||||
name="vlayout"
|
||||
icon="fa-list"
|
||||
@ -119,7 +120,7 @@ import ConnectivityChecker from "./components/ConnectivityChecker.vue";
|
||||
import Service from "./components/Service.vue";
|
||||
import Message from "./components/Message.vue";
|
||||
import SearchInput from "./components/SearchInput.vue";
|
||||
import SettingToggle from "./components/SettingToggle.vue";
|
||||
import LayoutToggle from "./components/LayoutToggle.vue";
|
||||
import DarkMode from "./components/DarkMode.vue";
|
||||
import DynamicTheme from "./components/DynamicTheme.vue";
|
||||
|
||||
@ -128,24 +129,24 @@ import defaultConfig from "./assets/defaults.yml";
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
Navbar,
|
||||
ConnectivityChecker,
|
||||
Service,
|
||||
Message,
|
||||
SearchInput,
|
||||
SettingToggle,
|
||||
DarkMode,
|
||||
DynamicTheme,
|
||||
Message,
|
||||
Navbar,
|
||||
SearchInput,
|
||||
Service,
|
||||
LayoutToggle,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
config: null,
|
||||
services: null,
|
||||
offline: false,
|
||||
filter: "",
|
||||
vlayout: true,
|
||||
isDark: null,
|
||||
offline: false,
|
||||
services: null,
|
||||
showMenu: false,
|
||||
vlayout: null,
|
||||
};
|
||||
},
|
||||
created: async function () {
|
||||
@ -159,6 +160,8 @@ export default {
|
||||
}
|
||||
this.config = merge(defaults, config);
|
||||
this.services = this.config.services;
|
||||
this.isDark = this.config.theme_use_dark;
|
||||
this.vlayout = this.config.vlayout;
|
||||
document.title =
|
||||
this.config.documentTitle ||
|
||||
`${this.config.title} | ${this.config.subtitle}`;
|
||||
|
@ -49,6 +49,14 @@ body {
|
||||
&:hover {
|
||||
background-color: var(--card-background);
|
||||
}
|
||||
|
||||
.linkoverlay {
|
||||
position:absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
bottom:0;
|
||||
right:0;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
@ -196,17 +204,27 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media-left {
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
.media-content {
|
||||
overflow: hidden;
|
||||
text-overflow: inherit;
|
||||
}
|
||||
.infolink {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: var(--highlight-secondary);
|
||||
background-color: var(--highlight-secondary);
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
bottom: 1rem;
|
||||
right: -0.2rem;
|
||||
width: 3px;
|
||||
overflow: hidden;
|
||||
|
@ -11,23 +11,23 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "Darkmode",
|
||||
data: function () {
|
||||
return {
|
||||
isDark: null,
|
||||
};
|
||||
props: {
|
||||
isDark: Boolean,
|
||||
},
|
||||
created: function () {
|
||||
this.isDark =
|
||||
let isDark =
|
||||
"overrideDark" in localStorage
|
||||
? JSON.parse(localStorage.overrideDark)
|
||||
: matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
this.$emit("updated", this.isDark);
|
||||
: this.isDark === null
|
||||
? matchMedia("(prefers-color-scheme: dark)").matches
|
||||
: this.isDark;
|
||||
this.$emit("updated", isDark);
|
||||
},
|
||||
methods: {
|
||||
toggleTheme: function () {
|
||||
this.isDark = !this.isDark;
|
||||
localStorage.overrideDark = this.isDark;
|
||||
this.$emit("updated", this.isDark);
|
||||
let isDark = !this.isDark;
|
||||
localStorage.overrideDark = isDark;
|
||||
this.$emit("updated", isDark);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
43
src/components/LayoutToggle.vue
Normal file
43
src/components/LayoutToggle.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<a v-on:click="toggleLayout()" class="navbar-item is-inline-block-mobile">
|
||||
<span>
|
||||
<i :class="['fas', 'fa-fw', vlayout ? icon : secondaryIcon]"></i>
|
||||
</span>
|
||||
<slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LayoutToggle",
|
||||
props: {
|
||||
name: String,
|
||||
icon: String,
|
||||
iconAlt: String,
|
||||
vlayout: Boolean,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
secondaryIcon: null,
|
||||
};
|
||||
},
|
||||
created: function () {
|
||||
this.secondaryIcon = this.iconAlt || this.icon;
|
||||
let vlayout;
|
||||
if (this.name in localStorage) {
|
||||
vlayout = JSON.parse(localStorage[this.name]);
|
||||
} else {
|
||||
vlayout = this.vlayout === null ? true : this.vlayout;
|
||||
}
|
||||
|
||||
this.$emit("updated", vlayout);
|
||||
},
|
||||
methods: {
|
||||
toggleLayout: function () {
|
||||
let vlayout = !this.vlayout;
|
||||
localStorage[this.name] = vlayout;
|
||||
this.$emit("updated", vlayout);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -21,8 +21,8 @@
|
||||
<a
|
||||
class="navbar-item"
|
||||
rel="noreferrer"
|
||||
v-for="link in links"
|
||||
:key="link.url"
|
||||
v-for="(link, key) in links"
|
||||
:key="key"
|
||||
:href="link.url"
|
||||
:target="link.target"
|
||||
>
|
||||
|
@ -1,39 +0,0 @@
|
||||
<template>
|
||||
<a v-on:click="toggleSetting()" class="navbar-item is-inline-block-mobile">
|
||||
<span><i :class="['fas', 'fa-fw', value ? icon : secondaryIcon]"></i></span>
|
||||
<slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SettingToggle",
|
||||
props: {
|
||||
name: String,
|
||||
icon: String,
|
||||
iconAlt: String,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
secondaryIcon: null,
|
||||
value: true,
|
||||
};
|
||||
},
|
||||
created: function () {
|
||||
this.secondaryIcon = this.iconAlt || this.icon;
|
||||
|
||||
if (this.name in localStorage) {
|
||||
this.value = JSON.parse(localStorage[this.name]);
|
||||
}
|
||||
|
||||
this.$emit("updated", this.value);
|
||||
},
|
||||
methods: {
|
||||
toggleSetting: function () {
|
||||
this.value = !this.value;
|
||||
localStorage[this.name] = this.value;
|
||||
this.$emit("updated", this.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -2,7 +2,8 @@
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style></style> */
|
||||
<style></style>
|
||||
*/
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
@ -13,29 +14,42 @@ export default {};
|
||||
<template>
|
||||
<div>
|
||||
<div class="card" :class="item.class">
|
||||
<a :href="item.url" :target="item.target" rel="noreferrer">
|
||||
<div class="card-content">
|
||||
<div class="media">
|
||||
<div v-if="item.logo" class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<img :src="item.logo" :alt="`${item.name} logo`" />
|
||||
</figure>
|
||||
</div>
|
||||
<div v-if="item.icon" class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<i style="font-size: 35px;" :class="['fa-fw', item.icon]"></i>
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">{{ item.subtitle }}</p>
|
||||
</div>
|
||||
<a
|
||||
:href="item.url"
|
||||
class="linkoverlay"
|
||||
:target="item.target"
|
||||
rel="noreferrer"
|
||||
></a>
|
||||
<div class="card-content">
|
||||
<div class="media">
|
||||
<div v-if="item.logo" class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<img :src="item.logo" :alt="`${item.name} logo`" />
|
||||
</figure>
|
||||
</div>
|
||||
<div class="tag" :class="item.tagstyle" v-if="item.tag">
|
||||
<strong class="tag-text">#{{ item.tag }}</strong>
|
||||
<div v-if="item.icon" class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<i style="font-size: 35px;" :class="['fa-fw', item.icon]"></i>
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">{{ item.subtitle }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a v-if="item.info"
|
||||
:href="item.info"
|
||||
:target="item.infotarget"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<div class="infolink">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
</div>
|
||||
</a>
|
||||
<div class="tag" :class="item.tagstyle" v-if="item.tag">
|
||||
<strong class="tag-text">#{{ item.tag }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
Loading…
x
Reference in New Issue
Block a user