Abmelden nur noch in den Einstellungen, App-Menue statt Zahnrad

Marcs Entscheidung: In der HoneyBar fremder Apps steht kein Abmelden mehr
— es war dort ohnehin nur ein Link auf den Schreibtisch. Als einzige
Schaltflaeche, die eine Sitzung beendet, steht es jetzt an genau einer
Stelle: unten in den Einstellungen, sichtbar nur bei eigener Anmeldung.
Damit faellt auch der ?abmelden=1-Pfad wieder weg und /api/apps braucht
das oidc-Feld nicht mehr.

Das Zahnrad rechts in der Menueleiste ist durch den Pfeil mit der
App-Liste ersetzt — derselbe wie in der HoneyBar. Beide Leisten tragen
damit dieselben vier Dinge: Logo, Apps, Wetter/Uhr, Aufklappmenue.
This commit is contained in:
marc committed 2026-08-29 21:51:00 +02:00
1 parent 0a5cd94ba0
commit 6d75ce78c2
7 files changed
+136 -65

No files matched your search

+72 -20
View File
@@ -590,7 +590,15 @@ function openSettings() {
<p class="login-note" style="margin-top:4px">
Diese Einstellungen liegen auf dem Server, nicht im Browser — auf jedem
Gerät, an dem du angemeldet bist, sieht HoneyOS gleich aus.
</p>`,
</p>` +
// Abmelden steht hier und nur hier: Es ist das Einzige, was man aus einer
// fremden App heraus nicht anklicken können soll (siehe honeybar.js), und
// von HoneyOS aus findet man es dort, wo alles andere auch steht.
(state.oidc
? `<div class="field field-out">
<button class="btn btn-out" id="btnLogout">⏻ Abmelden</button>
</div>`
: ""),
(root) => {
root.querySelectorAll(".seg").forEach((segEl) => {
segEl.addEventListener("click", (e) => {
@@ -662,6 +670,7 @@ function openSettings() {
});
root.querySelector("#btnApps").addEventListener("click", openApps);
root.querySelector("#btnLogout")?.addEventListener("click", logout);
},
420
);
@@ -791,6 +800,58 @@ function openAbout() {
/* ── Hilfsmittel ───────────────────────────────────────────────────────── */
/* ── App-Menü im Pfeil rechts ──────────────────────────────────────────────
* Der Zwilling des Pfeils in honeybar.js. Die Apps stehen zwar schon als
* Streifen in der Leiste, aber der schiebt bei vielen Apps seitwärts — das
* Menü zeigt sie alle untereinander. Das Zahnrad ist dafür weggefallen:
* Einstellungen stehen im Systemmenü links, wie in jeder App.
*/
function buildAppMenu() {
const menu = document.createElement("div");
menu.className = "startmenu appmenu";
menu.id = "appmenu";
$("desktop").appendChild(menu);
const btn = $("btnAppMenu");
btn.addEventListener("click", (e) => {
e.stopPropagation();
if (menu.dataset.open === "1") return closeAppMenu();
closeSystemMenu();
closeStartMenu();
menu.innerHTML =
`<div class="sm-head">wechseln zu</div>` +
(state.cfg.apps.length
? state.cfg.apps.map((a) => `<button data-app="${escapeAttr(a.id)}">${escapeHtml(a.name)}</button>`).join("")
: `<button data-settings="1">keine app eingetragen …</button>`);
menu.querySelectorAll("[data-app]").forEach((b) =>
b.addEventListener("click", () => {
const app = state.cfg.apps.find((a) => a.id === b.dataset.app);
closeAppMenu();
if (app) launch(app);
})
);
menu.querySelector("[data-settings]")?.addEventListener("click", () => {
closeAppMenu();
openApps();
});
menu.dataset.open = "1";
btn.setAttribute("aria-expanded", "true");
});
document.addEventListener("click", closeAppMenu);
}
function closeAppMenu() {
const menu = $("appmenu");
if (!menu) return;
menu.dataset.open = "0";
$("btnAppMenu").setAttribute("aria-expanded", "false");
}
/* ── Systemmenü im Logo ────────────────────────────────────────────────────
* Der Zwilling des Menüs in honeybar.js: gleiche Punkte, gleiche Reihenfolge.
* Hier sind es Handlungen, dort Links hierher — denn nur hier ist man
@@ -809,6 +870,7 @@ function buildSystemMenu() {
e.stopPropagation();
if (menu.dataset.open === "1") return closeSystemMenu();
closeStartMenu();
closeAppMenu();
const terminal = state.settings.mode === "terminal";
menu.innerHTML =
@@ -816,8 +878,7 @@ function buildSystemMenu() {
<button data-do="about">Über HoneyOS</button>
<button data-do="settings">Einstellungen</button>
<hr />
<button data-do="mode">${terminal ? "▣ Desktop-Modus" : "↩ Terminal-Modus"}</button>` +
(state.oidc ? `<hr /><button data-do="logout">⏻ Abmelden</button>` : "");
<button data-do="mode">${terminal ? "▣ Desktop-Modus" : "↩ Terminal-Modus"}</button>`;
menu.querySelectorAll("[data-do]").forEach((b) =>
b.addEventListener("click", () => {
@@ -826,7 +887,6 @@ function buildSystemMenu() {
about: openAbout,
settings: openSettings,
mode: () => setMode(terminal ? "desktop" : "terminal"),
logout,
})[b.dataset.do]();
})
);
@@ -858,10 +918,11 @@ function buildStartMenu() {
e.stopPropagation();
const open = menu.dataset.open === "1";
if (open) return closeStartMenu();
// Beide Menüs offen ginge, sähe aber aus wie ein Fehler: Der Klick auf den
// Startknopf hält sein Ereignis auf, also erreicht es den Schließer des
// Systemmenüs nicht von selbst.
// Zwei offene Menüs sähen aus wie ein Fehler: Der Klick auf den Startknopf
// hält sein Ereignis auf, also erreicht es die Schließer der anderen nicht
// von selbst.
closeSystemMenu();
closeAppMenu();
menu.innerHTML = `<div class="sm-head">starten</div>` +
state.cfg.apps.map((a) => `<button data-app="${a.id}">${escapeHtml(a.name)}</button>`).join("") +
@@ -869,10 +930,7 @@ function buildStartMenu() {
<button data-win="system">System</button>
<button data-win="settings">Einstellungen</button>
<button data-win="about">Über HoneyOS</button>
<hr /><button data-mode="terminal">↩ Terminal-Modus</button>` +
// Ohne Anbieter gibt es nichts abzumelden — im Systemmenü steht der
// Punkt aus demselben Grund nur bei Anmeldung.
(state.oidc ? `<button data-logout="1">⏻ Abmelden</button>` : "");
<hr /><button data-mode="terminal">↩ Terminal-Modus</button>`;
menu.querySelectorAll("[data-app]").forEach((b) =>
b.addEventListener("click", () => {
@@ -893,7 +951,6 @@ function buildStartMenu() {
closeStartMenu();
setMode("terminal");
});
menu.querySelector("[data-logout]")?.addEventListener("click", logout);
menu.dataset.open = "1";
btn.setAttribute("aria-expanded", "true");
@@ -981,13 +1038,6 @@ async function main() {
loadLocalSettings();
applySettings();
// ?abmelden=1 kommt aus dem Systemmenü der HoneyBar. Es hier zu erledigen
// statt am Server heißt: Die Abmeldung bleibt ein POST von dieser Seite aus,
// und keine fremde Seite kann sie durch ein eingebettetes Bild auslösen.
if (new URLSearchParams(location.search).get("abmelden") === "1") {
return logout();
}
let pub = { oidc: false, buttonLabel: "Anmelden" };
try {
pub = await api("/api/public");
@@ -1015,11 +1065,11 @@ async function main() {
renderShell();
buildStartMenu();
buildSystemMenu();
buildAppMenu();
probeApps();
setInterval(tickClock, 15000);
setInterval(probeApps, 120000);
$("btnSettings").addEventListener("click", openSettings);
$("btnClose").addEventListener("click", closeModal);
$("modal").addEventListener("click", (e) => {
if (e.target === $("modal")) closeModal();
@@ -1044,6 +1094,8 @@ async function main() {
if (menu && menu.dataset.open === "1") return closeStartMenu();
const sys = $("sysmenu");
if (sys && sys.dataset.open === "1") return closeSystemMenu();
const apps = $("appmenu");
if (apps && apps.dataset.open === "1") return closeAppMenu();
return state.settings.mode === "desktop" ? closeTopWindow() : closeModal();
}
if (typing) return;