done simplefox theme

This commit is contained in:
Help-14 2022-05-07 10:34:49 +07:00
parent 137eb1cd91
commit 4a7d6c1766
12 changed files with 377 additions and 14 deletions

View file

@ -3,3 +3,16 @@ greeting:
afternoon: Good afternoon!
evening: Good evening!
night: Good night!
weather:
thunderstorm: Thunderstorm
drizzle: Drizzle
rain: Rain
snow: Snow
clear-day: Clear day
clear-night: Clear night
cloudy: Cloudy
partly-cloudy-day: Partly cloudy day
partly-cloudy-night: Partly cloudy night
sleet: Sleet
windy: Windy
foggy: Foggy

View file

@ -3,3 +3,16 @@ greeting:
afternoon: Chiều làm việc hiệu quả!
evening: Chiều tối vui vẻ!
night: Chúc ngủ ngon!
weather:
thunderstorm: dông bão
drizzle: mưa phùn
rain: mưa lớn
snow: tuyết
clear-day: trời quang
clear-night: đêm trời quang
cloudy: nhiều mây
partly-cloudy-day: ngày có mây
partly-cloudy-night: đêm có mây
sleet: mưa đá
windy: gió todd
foggy: sương mù

View file

@ -84,7 +84,6 @@ func loadData() {
// Load template engine
themeDir := filepath.Join(pwd, "themes", appConfig.Website.Theme)
log.Println(themeDir)
themefs = http.FileServer(http.Dir(themeDir))
tmpl, _ := template.ParseFiles(filepath.Join(themeDir, "index.html"))
webTemplate = tmpl

View file

@ -18,11 +18,13 @@ type ContentData struct {
type GroupData struct {
Title string `yaml:"title"`
Columns []ColumnData `yaml:"columns"`
Icon string `yaml:"icon"`
}
type ColumnData struct {
Title string `yaml:"title"`
Bookmarks []BookmarkData `yaml:"bookmarks"`
Icon string `yaml:"icon"`
}
type BookmarkData struct {
@ -32,14 +34,6 @@ type BookmarkData struct {
Icon string `yaml:"icon"`
}
func (b *BookmarkData) IsSVG() bool {
return strings.Contains(b.Icon, ".svg")
}
func (b *BookmarkData) IsImage() bool {
return contains(b.Icon, ".jpg", ".jpeg", ".png", ".gif", ".apng", ".bmp", ".ico", ".webp")
}
func LoadContent() ContentData {
emptyData := ContentData{}
@ -80,3 +74,27 @@ func contains(str string, subStrs ...string) bool {
}
return true
}
func (b *BookmarkData) IsSVG() bool {
return strings.Contains(b.Icon, ".svg")
}
func (b *BookmarkData) IsImage() bool {
return contains(b.Icon, ".jpg", ".jpeg", ".png", ".gif", ".apng", ".bmp", ".ico", ".webp")
}
func (b *GroupData) IsSVG() bool {
return strings.Contains(b.Icon, ".svg")
}
func (b *GroupData) IsImage() bool {
return contains(b.Icon, ".jpg", ".jpeg", ".png", ".gif", ".apng", ".bmp", ".ico", ".webp")
}
func (b *ColumnData) IsSVG() bool {
return strings.Contains(b.Icon, ".svg")
}
func (b *ColumnData) IsImage() bool {
return contains(b.Icon, ".jpg", ".jpeg", ".png", ".gif", ".apng", ".bmp", ".ico", ".webp")
}

View file

@ -10,6 +10,7 @@ import (
type Language struct {
Greeting LanguageGreeting `yaml:"greeting"`
Weather LanguageWeather `yaml:"weather"`
}
type LanguageGreeting struct {
@ -19,6 +20,21 @@ type LanguageGreeting struct {
Night string `yaml:"night"`
}
type LanguageWeather struct {
Thunderstorm string `yaml:"thunderstorm"`
Drizzle string `yaml:"drizzle"`
Rain string `yaml:"rain"`
Snow string `yaml:"snow"`
ClearDay string `yaml:"clear-day"`
ClearNight string `yaml:"clear-night"`
Cloudy string `yaml:"cloudy"`
PartlyCloudyDay string `yaml:"partly-cloudy-day"`
PartlyCloudyNight string `yaml:"partly-cloudy-night"`
Sleet string `yaml:"sleet"`
Windy string `yaml:"windy"`
Foggy string `yaml:"foggy"`
}
func LoadLanguage(language string) Language {
yamlFile, err := ioutil.ReadFile(filepath.Join("languages", language+".yaml"))
if err != nil {

View file

@ -6,15 +6,16 @@
<title>{{.Config.Title}}</title>
<meta name="description" content="{{.Config.Description}}" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="common/assets/favicon.ico" />
<link rel="stylesheet" href="common/css/core.css">
<link rel="stylesheet" href="common/css/custom.css">
<link rel="icon" type="image/png" href="/common/assets/favicon.ico" />
<link rel="stylesheet" href="/common/css/all.min.css">
<link rel="stylesheet" href="/common/css/core.css">
<link rel="stylesheet" href="/common/css/custom.css">
</head>
<body>
<script src="common/js/core.js"></script>
<script src="common/js/custom.js"></script>
<script src="/common/js/core.js"></script>
<script src="/common/js/custom.js"></script>
</body>
</html>

View file

@ -0,0 +1,40 @@
body {
background-color: var(--bgColor);
color: var(--foreground);
z-index: -999;
}
.foreground {
color: var(--foreground);
}
.box {
background-color: #201E21;
border: 1px solid rgba(0, 0, 0, 0) !important;
}
.box-hover {
background-color: var(--accentColor) !important;
}
.icon-container {
width: 32px;
height: 32px;
}
.icon-container-small {
width: 24px;
height: 24px;
align-content: center;
}
.icon {
vertical-align: middle;
}
.svg-icon {
vertical-align: middle;
fill: var(--foreground) !important;
width: 32px !important;
height: 32px !important;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,192 @@
<!DOCTYPE html>
<html lang="{{.Config.Language}}">
<head>
<meta charset="UTF-8">
<title>{{.Config.Title}}</title>
<meta name="description" content="{{.Config.Description}}" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/common/assets/favicon.ico" />
<link href="/theme/css/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="/common/css/all.min.css">
<link rel="stylesheet" href="/common/css/core.css">
<link rel="stylesheet" href="/theme/css/simplefox.css">
<link rel="stylesheet" href="/common/css/custom.css">
<script>
customElements.define("svg-file", class extends HTMLElement {
async connectedCallback(
src = this.getAttribute("src"),
shadowRoot = this.shadowRoot || this.attachShadow({ mode: "open" })
) {
shadowRoot.innerHTML = await (await fetch(src)).text()
shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))
this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
}
})
</script>
</head>
<body>
<div class="grid place-items-center h-screen">
<div class="flex">
<div class="shrink place-items-center inset-0">
<div class="grid gap-4 grid-cols-2 grid-rows-2">
<div class="content-center">
<p id="clock" class="text-6xl font-bold text-center"></p>
<p id="greeting" class="text-2xl font-bold text-center"></p>
</div>
<div class="content-center">
<p id="date" class="text-6xl font-bold text-center"></p>
<div id="weather-info" class="flex place-items-center gap-3 justify-center">
<div></div>
<canvas id="weather-icon" width="40" height="40"></canvas>
<p id="temp" class="text-2xl font-bold text-center"></p>
<p id="weather-desc" class="text-center"></p>
<div></div>
</div>
</div>
<div class="grid grid-cols-4 gap-4">
{{range (index (index .Contents 0).Columns 0).Bookmarks}}
<div class="hover:bg-gray-800 box rounded-lg p-10 drop-shadow-xl cursor-pointer" onclick="window.location.href='{{.Url}}'">
<div class="icon-container">
{{if .IsImage}}
<img src="{{.Icon}}" class="icon">
{{else if .IsSVG}}
<svg-file src="{{.Icon}}" class="svg-icon"></svg-file>
{{else}}
<i class="{{.Icon}} fa-2xl icon"></i>
{{end}}
</div>
</div>
{{end}}
</div>
<div class="grid gap-4 grid-cols-2">
{{range (index .Contents 1).Columns}}
<div class="box rounded-lg drop-shadow-xl gap-2 p-5 grid grid-flow-row auto-rows-max justify-center">
<div class="icon-container-small mb-4">
<center>
{{if .IsImage}}
<img src="{{.Icon}}" class="icon">
{{else if .IsSVG}}
<svg-file src="{{.Icon}}" class="svg-icon"></svg-file>
{{else}}
<i class="{{.Icon}} fa-xl icon"></i>
{{end}}
</center>
</div>
{{range .Bookmarks}}
<a href="{{.Url}}" class="text-center">{{.Name}}</a>
{{end}}
</div>
{{end}}
</div>
</div>
</div>
</div>
</div>
<script src="/theme/js/skycons.min.js"></script>
<script src="/common/js/core.js"></script>
<script>
window.config = {
localization: {{.Config.Localization}},
language: {{.Config.Language}},
useMetric: {{.Config.UseMetric}}
};
(function setTimer() {
const clock = document.querySelector("#clock");
const datetb = document.querySelector("#date");
const clockOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' };
(function clockTick() {
const now = new Date();
clock.innerText = `${now.getHours()}:${now.getMinutes().toLocaleString(window.config.localization, { minimumIntegerDigits: 2, useGrouping: false })}`;
datetb.innerText = now.toLocaleTimeString(window.config.localization, { month: 'short', day: 'numeric' }).split(',')[0];
setTimeout(clockTick, 2000);
})();
//Set greeting
const greeting = document.querySelector("#greeting");
const hour = new Date().getHours();
if (hour >= 5 && hour < 12) {
greeting.innerText = {{.Language.Greeting.Morning}};
}
else if (hour >= 12 && hour < 17) {
greeting.innerText = {{.Language.Greeting.Afternoon}};
}
else if (hour >= 17 && hour < 20) {
greeting.innerText = {{.Language.Greeting.Evening}};
}
else {
greeting.innerText = {{.Language.Greeting.Night}};
}
}) ();
async function loadWeather() {
// Get info from api
const weather = await (await fetch("./weather")).json();
if (!weather) return;
// Parse weather id
let icon = null;
let weatherDesc = "";
let hour = new Date().getHours();
let isDay = hour >= 6 && hour < 18;
const weatherCode = weather.weather[0].id;
if ([200, 201, 202, 210, 211, 212, 221, 230, 231, 232].includes(weatherCode)) {
icon = Skycons.RAIN; //Thunderstorm
weatherDesc = {{.Language.Weather.Thunderstorm}};
} else if ([300, 301, 302, 310, 311, 312, 313, 314, 321].includes(weatherCode)) {
icon = Skycons.RAIN; //Drizzle
weatherDesc = {{.Language.Weather.Drizzle}};
} else if ([500, 501, 502, 503, 504, 511, 520, 521, 522, 531].includes(weatherCode)) {
icon = Skycons.RAIN;
weatherDesc = {{.Language.Weather.Rain}};
} else if ([600, 601, 602, 611, 612, 613, 615, 616, 620, 621, 622].includes(weatherCode)) {
icon = Skycons.SNOW;
weatherDesc = {{.Language.Weather.Snow}};
} else if (weatherCode === 800) {
icon = isDay ? Skycons.CLEAR_DAY : Skycons.CLEAR_NIGHT;
weatherDesc = isDay ? {{.Language.Weather.ClearDay}} : {{.Language.Weather.ClearNight}};
} else if ([801, 802, 803, 804].includes(weatherCode)) {
if (weatherCode >= 803) {
icon = Skycons.CLOUDY;
weatherDesc = {{.Language.Weather.Cloudy}};
} else {
icon = isDay ? Skycons.PARTLY_CLOUDY_DAY : Skycons.PARTLY_CLOUDY_NIGHT;
weatherDesc = isDay ? {{.Language.Weather.PartlyCloudyDay}} : {{.Language.Weather.PartlyCloudyNight}};
}
} else if ([762, 761, 751, 731, 721].includes(weatherCode)) {
icon = Skycons.SLEET;
weatherDesc = {{.Language.Weather.Sleet}};
} else if ([771, 781].includes(weatherCode)) {
icon = Skycons.WIND;
weatherDesc = {{.Language.Weather.Windy}};
} else if ([701, 711, 741].includes(weatherCode)) {
icon = Skycons.FOG;
weatherDesc = {{.Language.Weather.Foggy}};
} else {
return;
}
// Set weather icon to canvas
var skycons = new Skycons({ "color": window.cssRoot["--accentColor"] });
skycons.add("weather-icon", icon);
skycons.play();
// Set weather info
if (window.config.useMetric) {
document.querySelector("#temp").innerText = Math.floor(weather.main.temp - 273.15) + "°C";
} else {
document.querySelector("#temp").innerText = Math.floor((weather.main.temp - 32) * 5 / 9) + "°F";
}
document.querySelector("#weather-info").style.visibility = "visible";
document.querySelector("#weather-desc").innerText = weatherDesc;
}
(function weatherTick() {
loadWeather();
setTimeout(weatherTick, 3600000);
})();
</script>
<script src="/common/js/custom.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
website:
theme: "simplefox"
title: "Magma Dashboard"
description: ""
language: "en"
localization: "en-US"
useMetric: true
openweathermap:
apiKey: demo
lon: 0
lat: 0
addons:

View file

@ -0,0 +1,57 @@
data:
- title: Applications
columns:
- bookmarks:
- name: OpenWRT
icon: fa-solid fa-wifi
url: http://192.168.2.1
- name: Proxmox
icon: https://iconape.com/wp-content/files/pk/18549/svg/cib-proxmox.svg
url: http://192.168.2.200
- name: Home Assistant
icon: fa-solid fa-house
url: http://huawei.lan:8123/
- name: Docker
icon: fa-brands fa-docker
url: http://docker.lan/#!/2/docker/containers
- name: OpenWRT
icon: fa-solid fa-wifi
url: http://192.168.2.1
- name: Proxmox
icon: https://iconape.com/wp-content/files/pk/18549/svg/cib-proxmox.svg
url: http://192.168.2.200
- name: Home Assistant
icon: fa-solid fa-house
url: http://huawei.lan:8123/
- name: Docker
icon: fa-brands fa-docker
url: http://docker.lan/#!/2/docker/containers
- title: Bookmarks
columns:
- title: Social Media
icon: fa-solid fa-user-group
bookmarks:
- name: Facebook
icon: fa-brands fa-facebook
url: https://www.facebook.com
- name: Reddit
icon: fa-brands fa-reddit
url: https://www.reddit.com
- name: Voz
icon: https://files.help14.com/voz.svg
url: https://voz.vn
- name: Youtube
icon: fa-brands fa-youtube
url: https://www.youtube.com
- title: Shopping
icon: fa-solid fa-cart-shopping
bookmarks:
- name: Shopee
icon: fa-solid fa-bag-shopping
url: https://shopee.vn
- name: Lazada
icon: fa-solid fa-heart
url: https://www.lazada.vn/
- name: Shipping
icon: fa-solid fa-truck
url: http://nhaphang.com/i/#