Schublade: Symbol, Name, Untertitel
Der Pfeil rechts klappt in beiden Leisten ein Raster auf statt einer Liste. Symbol gross, Name, Untertitel als dritte Zeile — der stand bisher nur auf den Kacheln. Entschieden gegen Symbol allein: Acht geteilte Glyphen identifizieren nicht, zwei Apps koennen dieselbe Wolke tragen. Und die Schublade macht man auf, weil man sucht — der Streifen ist der Ort fuers Wiedererkennen, dort sind die Symbole abschaltbar. Dazu 1.4 (CORS in Aether) und 1.5 (Cookie-Sitzung fuer InkNote) aus den Ideen gestrichen: Widgets, die Daten aus den eigenen Apps holen, sind nicht mehr gewollt. Der Rest ist neu durchnummeriert.
This commit is contained in:
1 parent
6fe6533667
commit
e27d1cb56b
5 files changed
+144
-48
No files matched your search
@@ -59,7 +59,7 @@ hält — dieselbe Liste, die heute schon die CORS-Freigabe steuert. Das ist ein
|
|||||||
Sicherheitsentscheidung und keine Kleinigkeit; erst bauen, wenn der Umweg über
|
Sicherheitsentscheidung und keine Kleinigkeit; erst bauen, wenn der Umweg über
|
||||||
den Schreibtisch wirklich nervt.
|
den Schreibtisch wirklich nervt.
|
||||||
|
|
||||||
### 1.3 App-Schublade mit Symbolen — ✅ halb gebaut (29.08.2026)
|
### 1.3 App-Schublade mit Symbolen — ✅ gebaut (29.08.2026)
|
||||||
|
|
||||||
**Gebaut: die geteilte Symbolquelle.** Die Raster liegen in `web/glyphs.json`,
|
**Gebaut: die geteilte Symbolquelle.** Die Raster liegen in `web/glyphs.json`,
|
||||||
der Schreibtisch lädt sie, die HoneyBar bekommt sie mit der App-Liste mit
|
der Schreibtisch lädt sie, die HoneyBar bekommt sie mit der App-Liste mit
|
||||||
@@ -71,9 +71,20 @@ aus, für beide Leisten zugleich. In den Aufklappmenüs und auf den Kacheln
|
|||||||
stehen sie immer — dort ist Platz, und dort sucht man eine App, statt sie im
|
stehen sie immer — dort ist Platz, und dort sucht man eine App, statt sie im
|
||||||
Vorbeigehen wiederzuerkennen.
|
Vorbeigehen wiederzuerkennen.
|
||||||
|
|
||||||
**Offen bleibt die Schublade selbst:** ein Raster aus Symbolen statt einer
|
**Ebenfalls gebaut: die Schublade.** Der Pfeil rechts klappt in beiden Leisten
|
||||||
Liste, wenn es viele Apps werden. Heute reicht der Streifen samt Menü; das ist
|
ein Raster auf — Symbol groß, Name, Untertitel als dritte Zeile. Drei Spalten,
|
||||||
erst ab sechs, sieben Apps eine echte Frage.
|
am Handy dieselben drei.
|
||||||
|
|
||||||
|
Entschieden (29.08.2026): **Symbol und Name, nie nur Symbol.** Der Grund ist
|
||||||
|
nicht Geschmack, sondern der geteilte Satz von acht generischen Glyphen — zwei
|
||||||
|
Apps können dieselbe Wolke tragen, und bei Homelab-Diensten ist das der
|
||||||
|
Normalfall. Ein Symbol identifiziert erst, wenn es einzigartig ist. Dazu: Den
|
||||||
|
Streifen sieht man im Vorbeigehen, die Schublade macht man auf, *weil man
|
||||||
|
sucht* — Suchen heißt Lesen, und Platz ist dort genug. Namen wegzunehmen ist
|
||||||
|
später eine CSS-Zeile; ohne sie anzufangen kostet die Zeit, in der man rät.
|
||||||
|
|
||||||
|
Der Untertitel bekommt damit endlich einen Ort: Er stand bisher nur auf den
|
||||||
|
Kacheln und beantwortet genau die Frage, die ein generisches Symbol offenlässt.
|
||||||
|
|
||||||
**Ebenfalls offen: eigene Logos hochladen** (beschlossen als Planung,
|
**Ebenfalls offen: eigene Logos hochladen** (beschlossen als Planung,
|
||||||
25.08.2026). Je App ein Bild in HoneyOS, die Pixelglyphe als Rückfall, wenn
|
25.08.2026). Je App ein Bild in HoneyOS, die Pixelglyphe als Rückfall, wenn
|
||||||
@@ -121,28 +132,7 @@ HoneyBar. Zählen, wie oft etwas benutzt wird, heißt Nutzungsdaten speichern
|
|||||||
dafür ist der Nutzen hier zu klein. **Zu entscheiden, sobald die vierte App
|
dafür ist der Nutzen hier zu klein. **Zu entscheiden, sobald die vierte App
|
||||||
dazukommt**, nicht vorher.
|
dazukommt**, nicht vorher.
|
||||||
|
|
||||||
### 1.4 CORS in Aether
|
### 1.4 HoneyOS selbst als PWA
|
||||||
|
|
||||||
Damit der Desktop Aether überhaupt etwas fragen darf. Aethers Sitzung ist ein
|
|
||||||
Cookie, und weil alles unter derselben Domain liegt, schickt der Browser es
|
|
||||||
schon heute mit — es fehlt allein die Freigabe im Go-Backend
|
|
||||||
(`Access-Control-Allow-Origin` für `os.…` plus `Allow-Credentials`).
|
|
||||||
|
|
||||||
Kleiner Eingriff, aber **die Voraussetzung für jedes Aether-Widget** und
|
|
||||||
nebenbei auch für die Anmeldeanzeige auf der Kachel.
|
|
||||||
|
|
||||||
### 1.5 InkNote: Sitzung zusätzlich als Cookie
|
|
||||||
|
|
||||||
InkNote weist sich mit einem Bearer-Token aus, der im localStorage liegt. Der
|
|
||||||
ist **pro Domain** — von `os.…` aus grundsätzlich unerreichbar, und daran ändert
|
|
||||||
keine Konfiguration etwas.
|
|
||||||
|
|
||||||
Solange das so bleibt, kann HoneyOS **keine InkNote-Daten anzeigen**. Der Weg
|
|
||||||
wäre, dass InkNote seine Sitzung zusätzlich als `HttpOnly`-Cookie setzt; der
|
|
||||||
Token-Weg kann daneben bleiben, damit PWA und Offline-Betrieb unangetastet sind.
|
|
||||||
|
|
||||||
|
|
||||||
### 1.5b HoneyOS selbst als PWA
|
|
||||||
|
|
||||||
Heute ist HoneyOS eine Website: Es hat `theme-color`, aber kein Manifest, kein
|
Heute ist HoneyOS eine Website: Es hat `theme-color`, aber kein Manifest, kein
|
||||||
Symbol und keinen Service Worker — installierbar ist es damit nicht. Am Handy
|
Symbol und keinen Service Worker — installierbar ist es damit nicht. Am Handy
|
||||||
@@ -179,7 +169,7 @@ Cache nur als Rückfall.
|
|||||||
Ursprungswechsel macht aus einer installierten PWA eine fremde App — wer
|
Ursprungswechsel macht aus einer installierten PWA eine fremde App — wer
|
||||||
vorher installiert, installiert zweimal.
|
vorher installiert, installiert zweimal.
|
||||||
|
|
||||||
### 1.6 Widget-Rahmen
|
### 1.5 Widget-Rahmen
|
||||||
|
|
||||||
Ein Fenstertyp, der einen Inhalt holt, ihn anzeigt und sich benimmt, wenn es
|
Ein Fenstertyp, der einen Inhalt holt, ihn anzeigt und sich benimmt, wenn es
|
||||||
schiefgeht: lädt gerade, nichts da, nicht angemeldet, Fehler. Einmal richtig
|
schiefgeht: lädt gerade, nichts da, nicht angemeldet, Fehler. Einmal richtig
|
||||||
@@ -192,9 +182,9 @@ Terminal als Kachel.
|
|||||||
|
|
||||||
Eines bauen, benutzen, dann entscheiden.
|
Eines bauen, benutzen, dann entscheiden.
|
||||||
|
|
||||||
- **Letzte Dateien** (Aether) — die naheliegendste; braucht nur 1.2
|
Widgets, die Daten aus den eigenen Apps holen, sind gestrichen (siehe „Bewusst
|
||||||
- **Speicherplatz** (Aether) — eine Zahl, ein Balken, billig zu bauen
|
nicht geplant"). Was bleibt, ist alles, was für sich allein steht: Wetter
|
||||||
- **Letzte Notizen** (InkNote) — braucht 1.3, kommt also später
|
(gebaut), ein Bild, später vielleicht Uhr, Notizzettel, Systemzustand.
|
||||||
|
|
||||||
### Wetter in der HoneyBar, neben der Uhr — ✅ gebaut (25.08.2026)
|
### Wetter in der HoneyBar, neben der Uhr — ✅ gebaut (25.08.2026)
|
||||||
|
|
||||||
@@ -338,7 +328,7 @@ schon gebaut) oder am Handy Pfeiltasten statt Ziehen anbieten. Nicht vergessen:
|
|||||||
Ohne das ist die Funktion am Handy schlicht nicht da.
|
Ohne das ist die Funktion am Handy schlicht nicht da.
|
||||||
|
|
||||||
Voraussetzung ist ein Widget-Verzeichnis — heute stehen Benutzer und Wetter
|
Voraussetzung ist ein Widget-Verzeichnis — heute stehen Benutzer und Wetter
|
||||||
fest im HTML. Sinnvoll zusammen mit dem Widget-Rahmen (1.6) zu bauen, nicht
|
fest im HTML. Sinnvoll zusammen mit dem Widget-Rahmen (1.5) zu bauen, nicht
|
||||||
davor.
|
davor.
|
||||||
|
|
||||||
### Widgets in der HoneyBar selbst
|
### Widgets in der HoneyBar selbst
|
||||||
@@ -348,17 +338,12 @@ ist aber die Seite, die man am seltensten offen hat — die HoneyBar dagegen ist
|
|||||||
überall. Naheliegend also: ein Knopf in der HoneyBar klappt dasselbe Widget als
|
überall. Naheliegend also: ein Knopf in der HoneyBar klappt dasselbe Widget als
|
||||||
kleines Feld auf, ohne die App zu verlassen.
|
kleines Feld auf, ohne die App zu verlassen.
|
||||||
|
|
||||||
Technisch ist das dieselbe Sache wie 1.6, nur ein zweites Zuhause für denselben
|
Technisch ist das dieselbe Sache wie 1.5, nur ein zweites Zuhause für denselben
|
||||||
Inhalt: Der Rahmen muss dann drei Formen können — Fenster, Kachel, Aufklappfeld.
|
Inhalt: Der Rahmen muss dann drei Formen können — Fenster, Kachel, Aufklappfeld.
|
||||||
Das ist beim **Bauen** von 1.6 zu bedenken, hinterher wird es teuer.
|
Das ist beim **Bauen** von 1.5 zu bedenken, hinterher wird es teuer.
|
||||||
|
|
||||||
**Eine Einschränkung vorweg:** Die HoneyBar läuft in einer fremden App. Ein
|
Für Widgets, die nur sich selbst brauchen (Wetter, Bild, Uhr), ist das
|
||||||
Aether-Widget in der HoneyBar **von InkNote aus** braucht deshalb dasselbe, was
|
geschenkt — sie fragen HoneyOS, nicht die App.
|
||||||
1.4 für den Schreibtisch regelt, nur für einen weiteren Ursprung. In der App
|
|
||||||
selbst (Aether-Widget in Aethers eigener HoneyBar) ist es geschenkt.
|
|
||||||
|
|
||||||
→ Anfangen mit **letzte Dateien**. Wenn du danach merkst, dass du morgens
|
|
||||||
wirklich draufschaust, lohnt der Rest. Wenn nicht, war es ein Abend.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -508,6 +493,11 @@ Damit es nicht alle paar Monate neu diskutiert wird:
|
|||||||
installierte PWA, wenn die Adresse in ihren Bereich fällt — das funktioniert
|
installierte PWA, wenn die Adresse in ihren Bereich fällt — das funktioniert
|
||||||
heute und darf nicht durch JavaScript-Navigation oder Rahmen kaputtgemacht
|
heute und darf nicht durch JavaScript-Navigation oder Rahmen kaputtgemacht
|
||||||
werden.
|
werden.
|
||||||
|
- **Keine Widgets, die Daten aus Aether oder InkNote holen** (gestrichen
|
||||||
|
29.08.2026). Dafür standen einmal zwei Punkte im Fundament: CORS in Aether
|
||||||
|
und eine Cookie-Sitzung für InkNote. Beides ist nicht mehr gewollt — der Weg
|
||||||
|
über den HoneyBar-Proxy zeigt HoneyOS in den Apps, statt die Apps in HoneyOS
|
||||||
|
nachzubauen.
|
||||||
- **HoneyOS speichert keine Inhalte.** Keine Dateien, keine Notizen, keine
|
- **HoneyOS speichert keine Inhalte.** Keine Dateien, keine Notizen, keine
|
||||||
Kopien. Es zeigt, was die Apps hergeben, und hört da auf.
|
Kopien. Es zeigt, was die Apps hergeben, und hört da auf.
|
||||||
- **Keine Rechteverwaltung.** Die App-Liste gilt für alle Angemeldeten. Für eine
|
- **Keine Rechteverwaltung.** Die App-Liste gilt für alle Angemeldeten. Für eine
|
||||||
|
|||||||
@@ -114,6 +114,21 @@ Gespeichert wird die Liste als Ganzes; der Server prüft sie noch einmal und ant
|
|||||||
dem, was er wirklich behalten hat. Eine Adresse ohne `https://` kommt als Fehlermeldung
|
dem, was er wirklich behalten hat. Eine Adresse ohne `https://` kommt als Fehlermeldung
|
||||||
zurück, nicht als kaputter Eintrag.
|
zurück, nicht als kaputter Eintrag.
|
||||||
|
|
||||||
|
## Die Schublade
|
||||||
|
|
||||||
|
Der Pfeil rechts in beiden Leisten klappt alle Apps als Raster auf: **Symbol,
|
||||||
|
Name, Untertitel.** Drei Spalten, am Handy dieselben drei.
|
||||||
|
|
||||||
|
Warum nicht nur Symbole? Weil acht geteilte Pixelglyphen nicht identifizieren —
|
||||||
|
zwei Apps können dieselbe Wolke tragen, und bei Homelab-Diensten ist das der
|
||||||
|
Normalfall. Dazu der Unterschied der beiden Orte: Den Streifen oben sieht man
|
||||||
|
im Vorbeigehen, da reicht ein Blick und die Symbole sind abschaltbar. Die
|
||||||
|
Schublade macht man auf, **weil man sucht** — Suchen heißt Lesen.
|
||||||
|
|
||||||
|
Der Untertitel aus der App-Liste steht damit endlich dort, wo er nützt: Er
|
||||||
|
beantwortet die Frage, die ein generisches Symbol offenlässt. Ist er leer,
|
||||||
|
fällt die Zeile weg.
|
||||||
|
|
||||||
## Ein Satz Symbole für alles
|
## Ein Satz Symbole für alles
|
||||||
|
|
||||||
Die Pixelraster stehen **an genau einer Stelle**: `web/glyphs.json`, 12×12
|
Die Pixelraster stehen **an genau einer Stelle**: `web/glyphs.json`, 12×12
|
||||||
|
|||||||
@@ -831,6 +831,47 @@ body {
|
|||||||
.startmenu button:hover { background: var(--p); color: var(--bg); text-shadow: none; }
|
.startmenu button:hover { background: var(--p); color: var(--bg); text-shadow: none; }
|
||||||
.startmenu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; }
|
.startmenu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; }
|
||||||
|
|
||||||
|
/* Die Schublade — der Zwilling der Schublade in honeybar.js. Symbol groß,
|
||||||
|
Name darunter, Untertitel als dritte Zeile: Wer sie aufmacht, sucht etwas,
|
||||||
|
und acht geteilte Pixelsymbole allein sagen dafür zu wenig. */
|
||||||
|
.appmenu { min-width: 318px; max-width: min(360px, calc(100vw - 12px)); }
|
||||||
|
/* minmax(0, 1fr): Ohne das darf eine lange Beschreibung ihre Spalte
|
||||||
|
auseinanderdrücken, und die Schublade wird breiter als der Schirm. */
|
||||||
|
.drawer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; }
|
||||||
|
.startmenu .drawer button.d-app {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 9px 4px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.startmenu .drawer .d-name,
|
||||||
|
.startmenu .drawer .d-sub { max-width: 100%; }
|
||||||
|
.startmenu .drawer .d-name { overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.startmenu .drawer button.d-app:hover {
|
||||||
|
background: none;
|
||||||
|
color: var(--p);
|
||||||
|
border-color: var(--p-dim);
|
||||||
|
text-shadow: var(--glow);
|
||||||
|
}
|
||||||
|
.d-ico { width: 24px; height: 24px; }
|
||||||
|
.d-ico svg { width: 24px; height: 24px; display: block; }
|
||||||
|
.d-name { letter-spacing: 0.08em; }
|
||||||
|
/* Umbrechen darf er, wachsen nicht — sonst stehen die Kacheln unterschiedlich
|
||||||
|
hoch und das Raster franst aus. */
|
||||||
|
.d-sub {
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1.25;
|
||||||
|
color: var(--p-dim);
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 620px) {
|
@media (max-width: 620px) {
|
||||||
.task-btn { min-width: 0; }
|
.task-btn { min-width: 0; }
|
||||||
.task-date { display: none; }
|
.task-date { display: none; }
|
||||||
|
|||||||
@@ -188,6 +188,37 @@
|
|||||||
color: var(--p); text-shadow: var(--glow);
|
color: var(--p); text-shadow: var(--glow);
|
||||||
}
|
}
|
||||||
.menu[data-open="1"] { display: flex; }
|
.menu[data-open="1"] { display: flex; }
|
||||||
|
/* Die Schublade: Symbol, Name, Untertitel. Sie wird absichtlich
|
||||||
|
aufgemacht, weil man etwas sucht — also wird gelesen, nicht nur
|
||||||
|
wiedererkannt. Deshalb stehen hier immer Namen, anders als im
|
||||||
|
Streifen oben, wo ein Blick reichen muss. */
|
||||||
|
.menu.apps { min-width: 318px; max-width: min(360px, calc(100vw - 12px)); }
|
||||||
|
/* minmax(0, 1fr): Ohne das darf eine lange Beschreibung ihre Spalte
|
||||||
|
auseinanderdruecken, und die Schublade wird breiter als der Schirm. */
|
||||||
|
.drawer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; }
|
||||||
|
.d-app {
|
||||||
|
display: flex; flex-direction: column; align-items: center; gap: 5px;
|
||||||
|
padding: 9px 4px; text-align: center; color: var(--p-mid);
|
||||||
|
border: 1px solid transparent; min-width: 0;
|
||||||
|
}
|
||||||
|
/* Die Regel fuer a und button oben setzt nowrap — richtig fuer den
|
||||||
|
Streifen, falsch
|
||||||
|
hier: Der Untertitel soll umbrechen statt abgeschnitten zu werden. */
|
||||||
|
.d-name, .d-sub { max-width: 100%; }
|
||||||
|
.d-sub { white-space: normal; }
|
||||||
|
.d-name { overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.d-app:hover { border-color: var(--p-dim); color: var(--p); }
|
||||||
|
.d-app[aria-current="page"] { border-color: var(--p); color: var(--p); }
|
||||||
|
.d-app .ico { width: 24px; height: 24px; }
|
||||||
|
.d-app .ico svg { width: 24px; height: 24px; }
|
||||||
|
.d-name { letter-spacing: .08em; }
|
||||||
|
/* Der Untertitel darf umbrechen, aber nicht wachsen — sonst stehen die
|
||||||
|
Kacheln unterschiedlich hoch. */
|
||||||
|
.d-sub {
|
||||||
|
font-size: 10px; line-height: 1.25; color: var(--p-dim);
|
||||||
|
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
.menu a, .menu button { text-align: left; padding: 6px 8px; color: var(--p-mid); }
|
.menu a, .menu button { text-align: left; padding: 6px 8px; color: var(--p-mid); }
|
||||||
.menu a:hover, .menu button:hover { background: var(--p-faint); color: var(--p); }
|
.menu a:hover, .menu button:hover { background: var(--p-faint); color: var(--p); }
|
||||||
.menu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; }
|
.menu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; }
|
||||||
@@ -219,9 +250,9 @@
|
|||||||
<button id="hide" role="menuitem">HoneyBar einklappen</button>
|
<button id="hide" role="menuitem">HoneyBar einklappen</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu" id="menu" role="menu">
|
<div class="menu apps" id="menu" role="menu">
|
||||||
<div class="head">wechseln zu</div>
|
<div class="head">wechseln zu</div>
|
||||||
<div id="menuApps"></div>
|
<div class="drawer" id="menuApps"></div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
/* ── Aussehen ─────────────────────────────────────────────────────────────
|
/* ── Aussehen ─────────────────────────────────────────────────────────────
|
||||||
@@ -287,11 +318,22 @@
|
|||||||
nav.appendChild(a);
|
nav.appendChild(a);
|
||||||
|
|
||||||
const m = document.createElement("a");
|
const m = document.createElement("a");
|
||||||
|
m.className = "d-app";
|
||||||
m.href = app.url;
|
m.href = app.url;
|
||||||
m.setAttribute("role", "menuitem");
|
m.setAttribute("role", "menuitem");
|
||||||
const ico = symbol(app);
|
const ico = symbol(app);
|
||||||
if (ico) m.appendChild(ico);
|
if (ico) m.appendChild(ico);
|
||||||
m.appendChild(document.createTextNode((app.id === current ? "\u25b8 " : "") + app.name));
|
const name = document.createElement("span");
|
||||||
|
name.className = "d-name";
|
||||||
|
name.textContent = app.name;
|
||||||
|
m.appendChild(name);
|
||||||
|
if (app.subtitle) {
|
||||||
|
const sub = document.createElement("span");
|
||||||
|
sub.className = "d-sub";
|
||||||
|
sub.textContent = app.subtitle;
|
||||||
|
m.appendChild(sub);
|
||||||
|
}
|
||||||
|
if (app.id === current) m.setAttribute("aria-current", "page");
|
||||||
menuApps.appendChild(m);
|
menuApps.appendChild(m);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -840,17 +840,25 @@ function buildAppMenu() {
|
|||||||
closeSystemMenu();
|
closeSystemMenu();
|
||||||
closeStartMenu();
|
closeStartMenu();
|
||||||
|
|
||||||
|
// Dieselbe Schublade wie in honeybar.js: Symbol, Name, Untertitel. Sie wird
|
||||||
|
// absichtlich aufgemacht, weil man etwas sucht — also wird gelesen, nicht
|
||||||
|
// nur wiedererkannt. Im Streifen oben reicht ein Blick, dort ist der Name
|
||||||
|
// abschaltbar; hier steht er immer.
|
||||||
menu.innerHTML =
|
menu.innerHTML =
|
||||||
`<div class="sm-head">wechseln zu</div>` +
|
`<div class="sm-head">wechseln zu</div>` +
|
||||||
(state.cfg.apps.length
|
(state.cfg.apps.length
|
||||||
? state.cfg.apps
|
? `<div class="drawer">` +
|
||||||
|
state.cfg.apps
|
||||||
.map(
|
.map(
|
||||||
(a) =>
|
(a) =>
|
||||||
// Im Menü stehen die Symbole immer — dort ist Platz, und dort
|
`<button class="d-app" data-app="${escapeAttr(a.id)}">
|
||||||
// sucht man eine App, statt sie im Vorbeigehen zu erkennen.
|
<span class="d-ico">${glyphSvg(a.glyph)}</span>
|
||||||
`<button data-app="${escapeAttr(a.id)}"><span class="sm-ico">${glyphSvg(a.glyph)}</span>${escapeHtml(a.name)}</button>`
|
<span class="d-name">${escapeHtml(a.name)}</span>
|
||||||
|
${a.subtitle ? `<span class="d-sub">${escapeHtml(a.subtitle)}</span>` : ""}
|
||||||
|
</button>`
|
||||||
)
|
)
|
||||||
.join("")
|
.join("") +
|
||||||
|
`</div>`
|
||||||
: `<button data-settings="1">keine app eingetragen …</button>`);
|
: `<button data-settings="1">keine app eingetragen …</button>`);
|
||||||
|
|
||||||
menu.querySelectorAll("[data-app]").forEach((b) =>
|
menu.querySelectorAll("[data-app]").forEach((b) =>
|
||||||
|
|||||||
Reference in new issue
Block a user