Symbole in beiden Leisten, aus einer Quelle

Die Pixelraster stehen jetzt in web/glyphs.json — einmal. Der Schreibtisch
laedt die Datei selbst, die HoneyBar bekommt sie mit der App-Liste mit;
sie bleibt damit eine einzelne Datei ohne zweite Anfrage. Die abgetippten
Wettersymbole in honeybar.js sind weg, und die Symbolauswahl im
Programm-Editor kommt jetzt aus derselben Datei statt aus einer Liste im
Quelltext.

Neu: Symbole neben den App-Namen im Streifen beider Leisten, mit einem
Schalter (Einstellungen -> HoneyBar) fuer beide zugleich. In den
Aufklappmenues und auf den Kacheln stehen sie immer.
This commit is contained in:
marc committed 2026-08-29 22:21:53 +02:00
1 parent d29b69a426
commit 53ab62d220
9 files changed
+395 -278

No files matched your search

+38 -20
View File
@@ -56,6 +56,7 @@
let apps = DEFAULT_APPS;
let settings = null;
let glyphs = {};
// Was die Seite oben schon hatte, bevor die HoneyBar sie heruntergeschoben hat.
let urspruenglichesPolster = null;
@@ -69,22 +70,13 @@
const SAFE = "env(safe-area-inset-top, 0px)";
const HOEHE = "calc(" + BAR_H + "px + " + SAFE + ")";
/* Wettersymbole als Pixelraster, dieselben Namen wie in weather.go.
Sie stehen auch in os.js — bis die geteilte Symbolquelle (1.3) gebaut ist,
ist das die kleinere Sünde: Die HoneyBar soll eine einzelne Datei bleiben,
die eine fremde App mit einer Zeile einbindet. */
const WX = {
sonne: "............;.....##.....;..#..##..#..;...#....#...;....####....;..##....##..;..##....##..;....####....;...#....#...;..#..##..#..;.....##.....;............",
heiter: "............;...##.......;..####..#...;...##..###..;......#####.;...####...#.;..#....##.#.;.##........#;#..........#;.##########.;............;............",
wolke: "............;....####....;...#....#...;..#......##.;.##........#;##.........#;#..........#;#..........#;.##########.;............;............;............",
nebel: "............;....####....;..##....##..;.##.......#.;#..........#;.##########.;............;.#########..;............;..#########.;............;.#########..",
regen: "............;....####....;...#....#...;..#......##.;.##........#;##.........#;.##########.;............;..#..#..#...;.#..#..#....;..#..#..#...;.#..#..#....",
schnee: "............;....####....;...#....#...;..#......##.;.##........#;##.........#;.##########.;............;..#...#...#.;.#.#.#.#.#..;..#...#...#.;............",
gewitter: "............;....####....;...#....#...;..#......##.;.##........#;##.........#;.##########.;......##....;.....##.....;....####....;......##....;.....##.....",
};
function wxSvg(name) {
const grid = (WX[name] || WX.wolke).split(";");
/* Alle Pixelraster kommen mit der App-Liste vom Server (web/glyphs.json).
Frueher standen die Wettersymbole hier noch einmal abgetippt — genau das
war schon einmal auseinandergelaufen. Diese Datei bleibt trotzdem eine
einzelne ohne zweite Anfrage: Sie fragt ohnehin nach der App-Liste, und
die bringt die Raster einfach mit. */
function rasterSvg(grid) {
if (!grid) return "";
let d = "";
grid.forEach((row, y) => {
let run = 0;
@@ -93,7 +85,7 @@
else if (run) { d += `<rect x="${x - run}" y="${y}" width="${run}" height="1"/>`; run = 0; }
}
});
return `<svg viewBox="0 0 12 12" fill="currentColor" aria-hidden="true">${d}</svg>`;
return `<svg viewBox="0 0 12 12" fill="currentColor" shape-rendering="crispEdges" aria-hidden="true">${d}</svg>`;
}
const host = document.createElement("honey-bar");
@@ -163,6 +155,11 @@
}
.apps::-webkit-scrollbar { display: none; }
.app { color: var(--p-mid); letter-spacing: .08em; flex: 0 0 auto; scroll-snap-align: end; }
/* Symbol und Name in einer Zeile. Das Symbol traegt die Textfarbe, also
stimmt es in jeder Roehre und im umgekehrten Zustand von selbst. */
.app, .menu a[role="menuitem"] { display: inline-flex; align-items: center; gap: 6px; }
.ico { display: block; width: 12px; height: 12px; flex: 0 0 auto; }
.ico svg { width: 12px; height: 12px; display: block; }
.app:hover { color: var(--p); border-color: var(--p-dim); }
.app[aria-current="page"] {
background: var(--p); border-color: var(--p); color: var(--bg); text-shadow: none;
@@ -261,20 +258,40 @@
nav.innerHTML = "";
menuApps.innerHTML = "";
// Der Schalter gilt nur fuer den Streifen. Im Aufklappmenue stehen die
// Symbole immer: Dort ist Platz, und dort sucht man eine App, statt sie
// im Vorbeigehen wiederzuerkennen.
const symboleImStreifen = !settings || settings.barGlyphs !== "off";
const symbol = (app) => {
const grid = glyphs[app.glyph] || glyphs.box;
if (!grid) return null;
const span = document.createElement("span");
span.className = "ico";
span.innerHTML = rasterSvg(grid);
return span;
};
apps.forEach((app) => {
if (app.id === "honeyos") return; // steckt schon links im Logo
const a = document.createElement("a");
a.className = "app";
a.href = app.url;
a.textContent = app.name;
if (symboleImStreifen) {
const ico = symbol(app);
if (ico) a.appendChild(ico);
}
a.appendChild(document.createTextNode(app.name));
if (app.id === current) a.setAttribute("aria-current", "page");
nav.appendChild(a);
const m = document.createElement("a");
m.href = app.url;
m.setAttribute("role", "menuitem");
m.textContent = (app.id === current ? "▸ " : "  ") + app.name;
const ico = symbol(app);
if (ico) m.appendChild(ico);
m.appendChild(document.createTextNode((app.id === current ? "\u25b8 " : "") + app.name));
menuApps.appendChild(m);
});
}
@@ -300,7 +317,7 @@
return; // offline oder HoneyOS aus — die App geht das nichts an
}
const el = root.getElementById("wx");
el.innerHTML = wxSvg(w.glyph) + `<span class="grad">${Math.round(w.grad)}°</span>`;
el.innerHTML = rasterSvg(glyphs[w.glyph] || glyphs.wolke) + `<span class="grad">${Math.round(w.grad)}°</span>`;
el.title = `${w.ort}: ${w.text}, ${Math.round(w.grad)}°`;
el.hidden = false;
}
@@ -510,6 +527,7 @@
apps = [{ id: "honeyos", name: "DESKTOP", url: homeUrl }].concat(data.apps);
}
settings = data.settings || null;
if (data.glyphs) glyphs = data.glyphs;
}
} catch {
/* nicht angemeldet, kein CORS, kein Netz → eingebaute Liste;