]>
git.immae.eu Git - github/bastienwirtz/homer.git/blob - app.js
11 created: async
function () {
14 this.isDark
= 'overrideDark' in localStorage
?
15 JSON
.parse(localStorage
.overrideDark
) : matchMedia("(prefers-color-scheme: dark)").matches
;
17 if ('vlayout' in localStorage
) {
18 this.vlayout
= JSON
.parse(localStorage
.vlayout
)
23 this.config
= await
this.getConfig();
24 document
.title
= this.config
.title
+ ' | Homer';
29 // Look for a new message if an endpoint is provided.
30 if (this.config
.message
&& this.config
.message
.url
) {
31 this.getMessage(this.config
.message
.url
).then(function(message
){
32 // keep the original config value if no value is provided by the endpoint
33 for (const prop
of ['title','style','content']) {
34 if (prop
in message
&& message
[prop
] !== null) {
35 that
.config
.message
[prop
] = message
[prop
];
41 document
.addEventListener('visibilitychange', function () {
42 if (document
.visibilityState
== "visible") {
48 checkOffline: function () {
50 return fetch(window
.location
.href
+ "?alive", {
55 }).catch(function () {
59 getConfig: function (event
) {
60 return fetch('config.yml').then(function (response
) {
61 if (response
.status
!= 200) {
64 return response
.text().then(function (body
) {
65 return jsyaml
.load(body
);
69 getMessage: function (url
) {
70 return fetch(url
).then(function (response
) {
71 if (response
.status
!= 200) {
74 return response
.json();
77 toggleTheme: function() {
78 this.isDark
= !this.isDark
;
79 localStorage
.overrideDark
= this.isDark
;
81 toggleLayout: function() {
82 this.vlayout
= !this.vlayout
;
83 localStorage
.vlayout
= this.vlayout
;
85 toggleMenu: function() {
86 this.showMenu
= !this.showMenu
;
88 matchesFilter: function(item
) {
89 return (item
.name
.toLowerCase().includes(this.filter
.toLowerCase())
90 || (item
.tag
&& item
.tag
.toLowerCase().includes(this.filter
.toLowerCase())))
92 firstMatchingService: function() {
93 for (group
of this.config
.services
) {
94 for (item
of group
.items
) {
95 if (this.matchesFilter(item
)) {
102 navigateToFirstService: function(target
) {
103 service
= this.firstMatchingService();
105 window
.open(service
.url
, target
|| service
.target
|| '_self');
110 function isSmallScreen() {
111 return window
.matchMedia('screen and (max-width: 1023px)').matches
;
113 this._keyListener = function(e
) {
115 if (isSmallScreen()) {
116 this.showMenu
= true;
119 this.$refs
.search
.focus();
124 if (e
.key
=== 'Escape') {
126 this.$refs
.search
.blur();
127 if (isSmallScreen()) {
128 this.showMenu
= false;
133 document
.addEventListener('keydown', this._keyListener
.bind(this));
136 document
.removeEventListener('keydown', this._keyListener
);
140 Vue
.component('service', {
144 <a :href="item.url" :target="item.target">
145 <div class="card-content">
147 <div v-if="item.logo" class="media-left">
148 <figure class="image is-48x48">
149 <img :src="item.logo" />
152 <div v-if="item.icon" class="media-left">
153 <figure class="image is-48x48">
154 <i style="font-size: 35px" :class="item.icon"></i>
157 <div class="media-content">
158 <p class="title is-4">{{ item.name }}</p>
159 <p class="subtitle is-6">{{ item.subtitle }}</p>
162 <div class="tag" :class="item.tagstyle" v-if="item.tag">
163 <strong class="tag-text">#{{ item.tag }}</strong>
170 if ('serviceWorker' in navigator
) {
171 window
.addEventListener('load', function () {
172 navigator
.serviceWorker
.register('worker.js');