1
0
mirror of https://github.com/coalaura/whiskr.git synced 2025-12-02 20:22:52 +00:00

add config to disable floaters

This commit is contained in:
Laura
2025-09-27 23:50:36 +02:00
parent 7d16b5e6e8
commit f7b43fb559
4 changed files with 83 additions and 62 deletions

7
env.go
View File

@@ -24,6 +24,10 @@ type EnvSettings struct {
ImageGeneration bool `json:"image-generation"` ImageGeneration bool `json:"image-generation"`
} }
type EnvUI struct {
ReducedMotion bool `json:"reduced-motion"`
}
type EnvUser struct { type EnvUser struct {
ID string `json:"id"` ID string `json:"id"`
Username string `json:"username"` Username string `json:"username"`
@@ -41,6 +45,7 @@ type Environment struct {
Debug bool `json:"debug"` Debug bool `json:"debug"`
Tokens EnvTokens `json:"tokens"` Tokens EnvTokens `json:"tokens"`
Settings EnvSettings `json:"settings"` Settings EnvSettings `json:"settings"`
UI EnvUI `json:"ui"`
Authentication EnvAuthentication `json:"authentication"` Authentication EnvAuthentication `json:"authentication"`
} }
@@ -165,6 +170,8 @@ func (e *Environment) Store() error {
"$.settings.title-model": {yaml.HeadComment(" model used to generate titles (needs to have structured output support; default: google/gemini-2.5-flash-lite)")}, "$.settings.title-model": {yaml.HeadComment(" model used to generate titles (needs to have structured output support; default: google/gemini-2.5-flash-lite)")},
"$.settings.image-generation": {yaml.HeadComment(" allow image generation (optional; default: true)")}, "$.settings.image-generation": {yaml.HeadComment(" allow image generation (optional; default: true)")},
"$.ui.reduced-motion": {yaml.HeadComment(" disables things like the floating stars in the background (optional; default: false)")},
"$.authentication.enabled": {yaml.HeadComment(" require login with username and password")}, "$.authentication.enabled": {yaml.HeadComment(" require login with username and password")},
"$.authentication.users": {yaml.HeadComment(" list of users with bcrypt password hashes")}, "$.authentication.users": {yaml.HeadComment(" list of users with bcrypt password hashes")},
} }

View File

@@ -16,6 +16,12 @@ settings:
cleanup: true cleanup: true
# model used to generate titles (needs to have structured output support; default: google/gemini-2.5-flash-lite) # model used to generate titles (needs to have structured output support; default: google/gemini-2.5-flash-lite)
title-model: google/gemini-2.5-flash-lite title-model: google/gemini-2.5-flash-lite
# allow image generation (optional; default: true)
image-generation: true
ui:
# disables things like the floating stars in the background (optional; default: false)
reduced-motion: false
authentication: authentication:
# require login with username and password # require login with username and password

17
main.go
View File

@@ -36,13 +36,16 @@ func main() {
r.Get("/-/data", func(w http.ResponseWriter, r *http.Request) { r.Get("/-/data", func(w http.ResponseWriter, r *http.Request) {
RespondJson(w, http.StatusOK, map[string]any{ RespondJson(w, http.StatusOK, map[string]any{
"authentication": env.Authentication.Enabled, "authenticated": IsAuthenticated(r),
"authenticated": IsAuthenticated(r), "config": map[string]any{
"search": env.Tokens.Exa != "", "auth": env.Authentication.Enabled,
"icons": icons, "search": env.Tokens.Exa != "",
"models": models, "motion": env.UI.ReducedMotion,
"prompts": Prompts, },
"version": Version, "icons": icons,
"models": models,
"prompts": Prompts,
"version": Version,
}) })
}) })

View File

@@ -1358,6 +1358,59 @@
$authentication.classList.add("open"); $authentication.classList.add("open");
} }
function initFloaters() {
const $floaters = document.getElementById("floaters"),
colors = ["#8aadf4", "#c6a0f6", "#8bd5ca", "#91d7e3", "#b7bdf8"],
count = Math.floor((window.outerHeight * window.outerWidth) / 98000);
function rand(a, b, rnd = false) {
const num = Math.random() * (b - a) + a;
if (rnd) {
return Math.floor(num);
}
return num;
}
function place(el, init = false) {
el.style.setProperty("--x", `${rand(0, 100).toFixed(4)}vw`);
el.style.setProperty("--y", `${rand(0, 100).toFixed(4)}vh`);
if (init) {
return;
}
const time = rand(140, 160);
el.style.setProperty("--time", `${time.toFixed(2)}s`);
setTimeout(() => {
place(el);
}, time * 1000);
}
for (let i = 0; i < count; i++) {
const el = document.createElement("div");
el.className = "floater";
el.style.setProperty("--size", `${rand(2, 4, true)}px`);
el.style.setProperty("--color", colors[rand(0, colors.length, true)]);
$floaters.appendChild(el);
place(el, true);
setTimeout(
() => {
place(el);
},
rand(0, 1000, true)
);
}
}
async function loadData() { async function loadData() {
const [_, data] = await Promise.all([connectDB(), json("/-/data")]); const [_, data] = await Promise.all([connectDB(), json("/-/data")]);
@@ -1383,10 +1436,15 @@
} }
// update search availability // update search availability
searchAvailable = data.search; searchAvailable = data.config.search;
// initialize floaters (unless disabled)
if (!data.config.motion) {
initFloaters();
}
// show login modal // show login modal
if (data.authentication && !data.authenticated) { if (data.config.authentication && !data.authenticated) {
$authentication.classList.add("open"); $authentication.classList.add("open");
} }
@@ -2022,56 +2080,3 @@
document.body.classList.remove("loading"); document.body.classList.remove("loading");
}); });
})(); })();
(() => {
const $floaters = document.getElementById("floaters"),
colors = ["#8aadf4", "#c6a0f6", "#8bd5ca", "#91d7e3", "#b7bdf8"],
count = Math.floor((window.outerHeight * window.outerWidth) / 98000);
function rand(a, b, rnd = false) {
const num = Math.random() * (b - a) + a;
if (rnd) {
return Math.floor(num);
}
return num;
}
function place(el, init = false) {
el.style.setProperty("--x", `${rand(0, 100).toFixed(4)}vw`);
el.style.setProperty("--y", `${rand(0, 100).toFixed(4)}vh`);
if (init) {
return;
}
const time = rand(140, 160);
el.style.setProperty("--time", `${time.toFixed(2)}s`);
setTimeout(() => {
place(el);
}, time * 1000);
}
for (let i = 0; i < count; i++) {
const el = document.createElement("div");
el.className = "floater";
el.style.setProperty("--size", `${rand(2, 4, true)}px`);
el.style.setProperty("--color", colors[rand(0, colors.length, true)]);
$floaters.appendChild(el);
place(el, true);
setTimeout(
() => {
place(el);
},
rand(0, 1000, true)
);
}
})();