feat(gui): gruene Nadel bei angehefteter Aufnahme, Logo fuehrt zu den Aufnahmen

Der Anheften-Knopf zeigte bei angehefteter Aufnahme nur die Zahl, die Nadel
blieb rot. Sie ist jetzt gruen (--ok, wie das "KI ✓"-Abzeichen). Dafuer
ersetzt ein SVG mit currentColor (ICON_PIN, gleiches Muster wie ICON_TABLE)
das 📌-Emoji: ein Farb-Emoji rendert immer rot, color greift daran nicht.

Klick auf Wellen-Logo und Schriftzug wechselt auf den Reiter "Aufnahmen".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
schakal00783
2026-08-02 23:14:41 +02:00
co-authored by Claude Opus 5
parent d0e02eb976
commit 3496b4a2df
4 changed files with 192 additions and 160 deletions
+12 -2
View File
@@ -33,7 +33,7 @@ function render() {
const theme = document.documentElement.dataset.theme || 'dark'; const theme = document.documentElement.dataset.theme || 'dark';
app.innerHTML = ` app.innerHTML = `
<header class="topbar"> <header class="topbar">
<div class="brand"> <div class="brand" id="brandhome" title="Zu den Aufnahmen">
<svg class="brand-wave" viewBox="0 0 34 20" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><line x1="3" y1="7" x2="3" y2="13"/><line x1="9" y1="4" x2="9" y2="16"/><line x1="15" y1="1" x2="15" y2="19"/><line x1="21" y1="5" x2="21" y2="15"/><line x1="27" y1="8" x2="27" y2="12"/><line x1="33" y1="9.5" x2="33" y2="10.5"/></g></svg> <svg class="brand-wave" viewBox="0 0 34 20" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><line x1="3" y1="7" x2="3" y2="13"/><line x1="9" y1="4" x2="9" y2="16"/><line x1="15" y1="1" x2="15" y2="19"/><line x1="21" y1="5" x2="21" y2="15"/><line x1="27" y1="8" x2="27" y2="12"/><line x1="33" y1="9.5" x2="33" y2="10.5"/></g></svg>
<h1>Aime <span class="sub">Anruf-Assistent</span></h1> <h1>Aime <span class="sub">Anruf-Assistent</span></h1>
</div> </div>
@@ -53,6 +53,12 @@ function render() {
</header> </header>
<main id="view"></main>`; <main id="view"></main>`;
app.querySelectorAll('.tab').forEach(b => b.onclick = () => { state.tab = b.dataset.tab; render(); }); app.querySelectorAll('.tab').forEach(b => b.onclick = () => { state.tab = b.dataset.tab; render(); });
// Logo + Schriftzug = Heimweg zurück auf die Aufnahmen.
app.querySelector('#brandhome').onclick = () => {
if (state.tab === 'recordings') return;
state.tab = 'recordings';
render();
};
app.querySelector('#themetoggle').onclick = () => app.querySelector('#themetoggle').onclick = () =>
applyTheme(document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark'); applyTheme(document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark');
app.querySelector('#recbtn').onclick = toggleRecord; app.querySelector('#recbtn').onclick = toggleRecord;
@@ -903,7 +909,7 @@ async function refreshRecList() {
${r.summary ? `<div class="summary-snip">${escapeHtml(r.summary)}</div>` : ''} ${r.summary ? `<div class="summary-snip">${escapeHtml(r.summary)}</div>` : ''}
</div> </div>
<button class="btn icon pinbtn ${pinCounts[r.id] ? 'pinned' : ''}" data-pin="${r.id}" <button class="btn icon pinbtn ${pinCounts[r.id] ? 'pinned' : ''}" data-pin="${r.id}"
title="${pinCounts[r.id] ? `In ${pinCounts[r.id]} Projekt(en) angeheftet — verwalten` : 'An ein Projekt anheften'}">📌${pinCounts[r.id] ? `<span class="pin-n">${pinCounts[r.id]}</span>` : ''}</button> title="${pinCounts[r.id] ? `In ${pinCounts[r.id]} Projekt(en) angeheftet — verwalten` : 'An ein Projekt anheften'}">${ICON_PIN}${pinCounts[r.id] ? `<span class="pin-n">${pinCounts[r.id]}</span>` : ''}</button>
<button class="btn icon" data-ren="${r.id}" title="Titel umbenennen">✏️</button> <button class="btn icon" data-ren="${r.id}" title="Titel umbenennen">✏️</button>
<button class="btn danger icon" data-del="${r.id}" title="In den Papierkorb">🗑</button> <button class="btn danger icon" data-del="${r.id}" title="In den Papierkorb">🗑</button>
</div>`; }).join(''); </div>`; }).join('');
@@ -1500,6 +1506,10 @@ const BUBBLE_W = 54;
function tableSeats(n) { return SEAT_LAYOUTS[Math.min(6, Math.max(1, n))] || SEAT_LAYOUTS[6]; } function tableSeats(n) { return SEAT_LAYOUTS[Math.min(6, Math.max(1, n))] || SEAT_LAYOUTS[6]; }
// Toggle-button icons: three people around a table / a text sheet. // Toggle-button icons: three people around a table / a text sheet.
// Stecknadel als SVG statt 📌: ein Farb-Emoji bleibt immer rot, `currentColor`
// lässt sich dagegen einfärben — angeheftet = grün, sonst blass wie die
// übrigen Zeilenknöpfe.
const ICON_PIN = `<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 3.5h6l-1 5 3.2 3.2H6.8L10 8.5z"/><line x1="12" y1="11.7" x2="12" y2="20.5"/></g></svg>`;
const ICON_TABLE = `<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true"><g fill="currentColor"><rect x="6" y="10" width="12" height="6" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="12" cy="4.6" r="2.1"/><circle cx="4" cy="19.4" r="2.1"/><circle cx="20" cy="19.4" r="2.1"/></g></svg>`; const ICON_TABLE = `<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true"><g fill="currentColor"><rect x="6" y="10" width="12" height="6" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="12" cy="4.6" r="2.1"/><circle cx="4" cy="19.4" r="2.1"/><circle cx="20" cy="19.4" r="2.1"/></g></svg>`;
const ICON_SHEET = `<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"><rect x="5" y="3" width="14" height="18" rx="2"/><line x1="8.5" y1="8" x2="15.5" y2="8"/><line x1="8.5" y1="12" x2="15.5" y2="12"/><line x1="8.5" y1="16" x2="13" y2="16"/></g></svg>`; const ICON_SHEET = `<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"><rect x="5" y="3" width="14" height="18" rx="2"/><line x1="8.5" y1="8" x2="15.5" y2="8"/><line x1="8.5" y1="12" x2="15.5" y2="12"/><line x1="8.5" y1="16" x2="13" y2="16"/></g></svg>`;
+12 -4
View File
@@ -534,11 +534,14 @@ body.resizing { cursor: col-resize; user-select: none; }
.proj-level-head .grow { flex: 1; } .proj-level-head .grow { flex: 1; }
.proj-level .item.rec { cursor: pointer; } .proj-level .item.rec { cursor: pointer; }
/* 📌 in der Aufnahmenliste: blass, solange die Aufnahme nirgends hängt. */ /* Stecknadel in der Aufnahmenliste: blass, solange die Aufnahme nirgends
.pinbtn { opacity: .45; position: relative; } hängt — angeheftet wird sie gruen (dieselbe Farbe wie „KI ✓“, also
„erledigt/zugeordnet“). Das Icon ist ein SVG mit currentColor; ein 📌-Emoji
wäre in jedem Zustand rot geblieben. */
.pinbtn { opacity: .45; position: relative; display: inline-flex; align-items: center; gap: 1px; }
.item.rec:hover .pinbtn { opacity: 1; } .item.rec:hover .pinbtn { opacity: 1; }
.pinbtn.pinned { opacity: 1; border-color: var(--accent); color: var(--accent); } .pinbtn.pinned { opacity: 1; border-color: var(--ok); color: var(--ok); background: var(--ok-soft); }
.pin-n { font-size: 10px; font-weight: 700; margin-left: 2px; vertical-align: super; } .pin-n { font-size: 10px; font-weight: 700; vertical-align: super; }
/* ---- Modal ---- */ /* ---- Modal ---- */
.modal-back { .modal-back {
@@ -550,3 +553,8 @@ body.resizing { cursor: col-resize; user-select: none; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; } .modal-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.modal select[size] { height: auto; padding: 4px; } .modal select[size] { height: auto; padding: 4px; }
.pin-current .item { padding: 6px 10px; } .pin-current .item { padding: 6px 10px; }
/* Logo + Schriftzug führen zurück auf die Aufnahmen. */
.brand { cursor: pointer; user-select: none; }
.brand:hover .brand-wave { filter: brightness(1.15); }
.brand:hover h1 { color: var(--accent); }
+12
View File
@@ -3,6 +3,18 @@
Chronik der Entwicklungsschritte. **Regel: jede zukünftige Änderung bekommt hier einen Eintrag** (Datum, Chronik der Entwicklungsschritte. **Regel: jede zukünftige Änderung bekommt hier einen Eintrag** (Datum,
Was, Warum, betroffene Dateien/Backups). Was, Warum, betroffene Dateien/Backups).
## 2026-08-02 (nachgereicht) — Grüne Nadel, Logo führt zurück zu den Aufnahmen
**Nadel grün statt rot:** der Anheften-Knopf in der Aufnahmenliste zeigte bei einer angehefteten Aufnahme
nur die Zahl, die Nadel selbst blieb rot. Sie ist jetzt grün (`--ok`, dieselbe Farbe wie das „KI ✓"-Abzeichen).
Dafür musste das **📌-Emoji einem SVG mit `currentColor` weichen** (`ICON_PIN`, gleiches Muster wie
`ICON_TABLE`/`ICON_SHEET`): ein Farb-Emoji rendert die Schriftart immer rot, `color` greift daran nicht.
**Logo als Heimweg:** ein Klick auf Wellen-Logo und Schriftzug „Aime" wechselt auf den Reiter „Aufnahmen"
(`#brandhome` in `render()`), mit Zeiger-Cursor und Hover-Andeutung als Hinweis darauf.
Dateien: `app/web/src/main.js`, `app/web/src/style.css`.
## 2026-08-02 (nachgereicht) — Ordner-Ebene umbenennbar ## 2026-08-02 (nachgereicht) — Ordner-Ebene umbenennbar
Der erste Reiter eines Projekts hieß fest „Ordner". Er trägt jetzt einen frei wählbaren Namen, genau wie Der erste Reiter eines Projekts hieß fest „Ordner". Er trägt jetzt einen frei wählbaren Namen, genau wie
+5 -3
View File
@@ -84,9 +84,11 @@ flowchart LR
end end
``` ```
Der 📌-Knopf in der Aufnahmenliste trägt die Zahl der Projekte, in denen die Aufnahme hängt, und ist Der Nadel-Knopf in der Aufnahmenliste trägt die Zahl der Projekte, in denen die Aufnahme hängt, und wird
farbig markiert, sobald sie irgendwo angeheftet ist (`GET /api/pins/counts` — ein Request für die ganze **grün** (`--ok`, dieselbe Farbe wie „KI ✓"), sobald sie irgendwo angeheftet ist — sonst bleibt er blass
Liste, nicht einer pro Zeile). Die Zahl steckt zusätzlich in der Listen-Signatur `state.lastListSig`, damit wie die übrigen Zeilenknöpfe (`GET /api/pins/counts` — ein Request für die ganze Liste, nicht einer pro
Zeile). Die Nadel ist deshalb ein **SVG mit `currentColor` (`ICON_PIN`) und kein 📌-Emoji**: ein
Farb-Emoji ist in jedem Zustand rot und lässt sich per CSS nicht umfärben. Die Zahl steckt zusätzlich in der Listen-Signatur `state.lastListSig`, damit
eine neue Anheftung die Liste neu zeichnet, ohne die 5-Sekunden-Regel („keine Änderung → DOM nicht eine neue Anheftung die Liste neu zeichnet, ohne die 5-Sekunden-Regel („keine Änderung → DOM nicht
anfassen") aufzuweichen. anfassen") aufzuweichen.