Convert multiple pages into SPA
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
BIN
res/static/img/carina.webp
Normal file
After Width: | Height: | Size: 195 KiB |
BIN
res/static/img/catspaw.webp
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
res/static/img/fnx_logo.png
Normal file
After Width: | Height: | Size: 777 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.3 KiB |
@@ -58,12 +58,6 @@ a>svg {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
/* This makes sure that no scrollbar shows up when the menu is open on small screens*/
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: system-ui, sans-serif;
|
||||
@@ -76,12 +70,6 @@ body {
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.checkers {
|
||||
background-image: var(--background_pattern);
|
||||
background-color: var(--background_pattern_color);
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
header,
|
||||
footer {
|
||||
text-align: center;
|
||||
@@ -90,24 +78,16 @@ footer {
|
||||
}
|
||||
|
||||
footer {
|
||||
background-image: url("/res/img/nebula.webp");
|
||||
background-color: var(--background_color);
|
||||
background-blend-mode: luminosity;
|
||||
box-shadow: inset 0 0 10px -4px var(--shadow_color);
|
||||
border-radius: 8px;
|
||||
margin: 16px;
|
||||
background-color: var(--shaded_background);
|
||||
backdrop-filter: blur(4px);
|
||||
border-top: 1px solid var(--separator);
|
||||
}
|
||||
|
||||
footer>.footer_content {
|
||||
background: var(--body_background);
|
||||
color: var(--body_text_color);
|
||||
display: inline-block;
|
||||
width: 1000px;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 8px;
|
||||
margin: 120px 0 60px 0;
|
||||
}
|
||||
|
||||
header>h1 {
|
||||
@@ -173,52 +153,17 @@ pre>code {
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.page_body {
|
||||
position: relative;
|
||||
right: 0;
|
||||
height: auto;
|
||||
left: 0;
|
||||
margin-left: 300px;
|
||||
min-width: 300px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
/* Center the header and body */
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
transition: margin 0.5s;
|
||||
}
|
||||
|
||||
.page_content {
|
||||
background: var(--body_background);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: var(--shaded_background);
|
||||
backdrop-filter: blur(4px);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page_content,
|
||||
.page_margins,
|
||||
footer {
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
@media (max-width: 1000px) {
|
||||
.page_navigation {
|
||||
left: -300px;
|
||||
}
|
||||
|
||||
.page_body {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page_content,
|
||||
.page_margins,
|
||||
footer {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
header>h1 {
|
||||
/* We want the header text to appear below the menu button, so the top
|
||||
margin needs to be fairly large when the screen is small */
|
||||
@@ -537,6 +482,12 @@ input[type="color"] {
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.button.flat {
|
||||
background: none;
|
||||
color: var(--body_text_color);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
.button:hover,
|
||||
input[type="submit"]:hover,
|
||||
|
@@ -1,34 +0,0 @@
|
||||
{{define "admin"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{if and .Authenticated .User.IsAdmin}}
|
||||
<head>
|
||||
{{template "meta_tags" "Administrator panel"}}
|
||||
|
||||
<script>
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
<script defer src='/res/svelte/admin_panel.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div id="page_body" class="page_body"></div>
|
||||
</body>
|
||||
{{else}}
|
||||
<head>
|
||||
{{template "meta_tags" "Administrator panel"}}
|
||||
</head>
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>Admin Panel</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
;-)
|
||||
</div>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
{{end}}
|
||||
</html>
|
||||
{{end}}
|
@@ -1,152 +0,0 @@
|
||||
{{define "appearance"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Appearance settings"}}
|
||||
<link id="stylesheet_theme_2" rel="stylesheet" type="text/css" href="/theme.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<header>
|
||||
<h1>Change website appearance</h1>
|
||||
</header>
|
||||
<div id="page_content" class="page_content">
|
||||
<section>
|
||||
<p>
|
||||
You can change how pixeldrain looks! Your theme choice will
|
||||
be saved in a cookie.
|
||||
</p>
|
||||
<h2>Theme</h2>
|
||||
<input type="radio" id="style_nord" name="style"><label for="style_nord">Nord</label>
|
||||
(Inspired by <a href="https://www.nordtheme.com/" target="_blank">Nord</a>)
|
||||
<br/>
|
||||
Dynamic theme, changes based on operating system settings. Here you can choose a specific variant:
|
||||
<br/>
|
||||
<input type="radio" id="style_nord_dark" name="style"><label for="style_nord_dark">Nord dark</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_nord_light" name="style"><label for="style_nord_light">Nord light</label>
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="radio" id="style_solarized" name="style"><label for="style_solarized">Solarized</label>
|
||||
(Inspired by <a href="https://ethanschoonover.com/solarized/" target="_blank">Solarized</a>)
|
||||
<br/>
|
||||
Dynamic theme, changes based on operating system settings. Here you can choose a specific variant:
|
||||
<br/>
|
||||
<input type="radio" id="style_solarized_dark" name="style"><label for="style_solarized_dark">Solarized dark</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_solarized_light" name="style"><label for="style_solarized_light">Solarized light</label>
|
||||
<br/>
|
||||
<!-- <br/> -->
|
||||
<!-- <input type="radio" id="style_adwaita" name="style"><label for="style_adwaita">Adwaita</label><br/> -->
|
||||
<br/>
|
||||
<input type="radio" id="style_purple_drain" name="style"><label for="style_purple_drain">Purple drain</label>
|
||||
<br/>
|
||||
Classic 2022 style, with purple gradients
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="radio" id="style_classic" name="style"><label for="style_classic">Pixeldrain classic (gray)</label>
|
||||
<br/>
|
||||
Classic pre-2020 pixeldrain style, dark gray
|
||||
<br/>
|
||||
<br/>
|
||||
Other (experimental) themes
|
||||
<br/>
|
||||
<input type="radio" id="style_maroon" name="style"><label for="style_maroon">Maroon Style</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_hacker" name="style"><label for="style_hacker">Hacker Style</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_canta" name="style"><label for="style_canta">Canta Style</label>
|
||||
(Inspired by <a href="https://github.com/vinceliuice/Canta-theme" target="_blank">Canta GTK</a>)
|
||||
<br/>
|
||||
<input type="radio" id="style_skeuos" name="style"><label for="style_skeuos">Skeuos Style</label>
|
||||
(Inspired by <a href="https://www.gnome-look.org/p/1441725/" target="_blank">Skeuos GTK</a>)
|
||||
<br/>
|
||||
<input type="radio" id="style_sweet" name="style"><label for="style_sweet">Sweet</label>
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="radio" id="style_adwaita" name="style"><label for="style_adwaita">Adwaita (dynamic)</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_adwaita_dark" name="style"><label for="style_adwaita_dark">Adwaita dark</label>
|
||||
<br/>
|
||||
<input type="radio" id="style_adwaita_light" name="style"><label for="style_adwaita_light">Adwaita light</label>
|
||||
<br/><br/>
|
||||
<input type="radio" id="style_pixeldrain98" name="style"><label for="style_pixeldrain98">Pixeldrain 98</label>
|
||||
|
||||
<h2>Hue</h2>
|
||||
<p>
|
||||
Many themes support custom hues. The hue does not change the
|
||||
contrast of the theme, only the color itself.
|
||||
</p>
|
||||
<input type="radio" id="hue_default" name="hue"><label for="hue_default">Default</label><br/>
|
||||
<input type="radio" id="hue_354" name="hue"><label for="hue_354">Red</label><br/>
|
||||
<input type="radio" id="hue_14" name="hue"><label for="hue_14">Orange</label><br/>
|
||||
<input type="radio" id="hue_40" name="hue"><label for="hue_40">Yellow</label><br/>
|
||||
<input type="radio" id="hue_92" name="hue"><label for="hue_92">Green</label><br/>
|
||||
<input type="radio" id="hue_311" name="hue"><label for="hue_311">Purple</label><br/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function get_cookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
let style = get_cookie("style")
|
||||
let hue = get_cookie("hue")
|
||||
|
||||
// Style selector
|
||||
document.getElementsByName("style").forEach(function(elem) {
|
||||
elem.addEventListener("change", e => {
|
||||
style = e.target.id.substring(6)
|
||||
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (10 * 365 * 24 * 60 * 60 * 1000));
|
||||
document.cookie = "style="+style+"; expires=" + date.toUTCString() + "; path=/"
|
||||
|
||||
reload_sheet()
|
||||
})
|
||||
});
|
||||
document.getElementsByName("hue").forEach(function(elem) {
|
||||
elem.addEventListener("change", e => {
|
||||
hue = e.target.id.substring(4)
|
||||
if (hue === "default") {
|
||||
hue = -1
|
||||
document.cookie = "hue=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (10 * 365 * 24 * 60 * 60 * 1000));
|
||||
document.cookie = "hue="+hue+"; expires=" + date.toUTCString() + "; path=/"
|
||||
|
||||
reload_sheet()
|
||||
})
|
||||
});
|
||||
|
||||
function reload_sheet() {
|
||||
let stylesheet1 = document.getElementById("stylesheet_theme")
|
||||
let stylesheet2 = document.getElementById("stylesheet_theme_2")
|
||||
|
||||
// First load the sheet in the secondary tag, wait for it to load,
|
||||
// and replace the original sheet when it has finished loading
|
||||
stylesheet2.href= "/theme.css?style="+style+"&hue="+hue
|
||||
stylesheet2.onload = e => {
|
||||
stylesheet1.href= "/theme.css?style="+style+"&hue="+hue
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{template "page_bottom" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,19 +0,0 @@
|
||||
{{define "home"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Cloud storage and data transfer services"}}
|
||||
|
||||
<script>
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.user = {{.User}};
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
<script defer src='/res/svelte/home_page.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div id="page_body" class="page_body"></div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,19 +0,0 @@
|
||||
{{define "login"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Login" }}
|
||||
|
||||
<script>
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.user = {{.User}};
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
<script defer src='/res/svelte/login.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div id="page_body" class="page_body"></div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,19 +0,0 @@
|
||||
{{define "speedtest"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Speedtest"}}
|
||||
|
||||
<script>
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.user = {{.User}};
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
<script defer src='/res/svelte/speedtest.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div id="page_body" class="page_body"></div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,19 +0,0 @@
|
||||
{{define "user_home"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" .User.Username }}
|
||||
|
||||
<script>
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.user = {{.User}};
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
<script defer src='/res/svelte/user_home.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div id="page_body" class="page_body"></div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,4 +1,4 @@
|
||||
{{define "filesystem"}}
|
||||
{{define "wrap"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
{{ template "opengraph" .OGData }}
|
||||
<script>
|
||||
window.initial_node = {{.Other}};
|
||||
window.user = {{.User}};
|
||||
window.api_endpoint = '{{.APIEndpoint}}';
|
||||
window.server_hostname = "{{.Hostname}}";
|
||||
</script>
|
||||
|
||||
<script defer src='/res/svelte/filesystem.js?v{{cacheID}}'></script>
|
||||
<script defer src='/res/svelte/wrap.js?v{{cacheID}}'></script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|