Slide 4: das Menue haengt sichtbar am Pluszeichen

Vier Sachen an derselben Slide.

BREITE AUS DEM INHALT. Sie stand als feste 470 in der Zeichenfunktion,
gemessen fuer Beschriftungen mit "senden", und liess ein Drittel
Leerraum rechts. Sie kommt jetzt aus dem laengsten Eintrag. Dabei
kippte die Zeichnung von quer auf hochkant, und ein hochkantes Bild
richtet sich nach der Hoehe: bei den alten 940 px wurde der Kasten
1093 hoch und lief in die Ueberschrift. Jetzt 680.

Gerechnet ist die Breite am sichtbaren Blatt und nicht am Kasten -- der
ist um den Stapelrand groesser als das, was man sieht, und mit seiner
Oberkante gerechnet stand die Zeichnung noch einmal 60 px zu hoch.

OBEN OHNE VERB. Wer das Menue ueber das Pluszeichen geoeffnet hat,
weiss, dass er etwas schickt; "Dokument senden", "Fotos und Videos
senden", "Audio senden", "Kontakt teilen" schreiben es viermal daneben.
Jetzt stehen dort die Dinge: Dokumente, Medien, Audio, Kontakt. Unten
bleibt das Verb, weil es etwas hinzufuegt -- "Termin" allein waere ein
Anhang, "Termin erstellen" ist eine Handlung. Das ist eine Abweichung
vom Composer und steht als solche in POST-6.md 4.

DIE EINGABEZEILE IST ZURUECK. Sie war weggenommen worden mit der
Begruendung, die Slide zeige ja, was man anhaengen kann. Das stimmte
nur, solange man wusste, worauf man schaut: ohne das Feld ist die Karte
eine Liste im Nichts. Das Pluszeichen traegt jetzt die gruene Marke wie
ein gedruecktes Element, der Zeiger steht darauf, und das Menue klappt
nach oben auf -- so wie im Werkzeug.

TEILEN STATT TELEFONHOERER. Ein Hoerer sagt "anrufen"; bei "Kontakt"
wird eine Karte weitergegeben. ShareNetwork aus demselben
Phosphor-bold-Satz, entnommen aus @phosphor-icons/react im
Website-Repo statt abgemalt. "phone" stand danach nirgends mehr und ist
aus der Tabelle heraus: 19 Zeichen, jedes in Gebrauch.

Das Bewegtbild ist nicht betroffen, es nutzt das Nachrichtenmenue.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-29 20:51:07 +02:00
1 parent 9c1d900da9
commit b422b492e6
2 files changed
+138 -22

No files matched your search

+45 -2
View File
@@ -29,7 +29,7 @@ einem eigenen Knopf. Wie das funktioniert, steht im
| 1 | Team-Chat | Büro und Baustelle, **endlich im selben Chat.** | Kanalliste und Verlauf nebeneinander, mit Filterzeile und Eingabefeld |
| 2 | Die Kanäle | Ein Kanal **pro Projekt.** | Links das Durcheinander als Zeichnung, rechts die Kanalliste |
| 3 | Die Aufgabe | Foto rein, **Aufgabe raus.** | Baustellenfotos, die Aufgabe daraus, die Bestätigung im Projekt |
| 4 | Das Pluszeichen | Nicht nur **Text.** | Das Menü hinter dem Plus, auf dem Stapel |
| 4 | Das Pluszeichen | Nicht nur **Text.** | Das Menü über der Eingabezeile, aus der es aufklappt |
| 5 | Bald verfügbar | Der Chat für unterwegs **wird gerade gebaut.** | Zwei Ausschnitte der Oberfläche, versetzt übereinander, mit dem Absperrband darüber |
Dazu, außerhalb des Streifens:
@@ -94,7 +94,7 @@ Quelle ist `components/general/GeneralTeamChatPage.tsx` aus dem Pitch-Paket
| Sinnbild je Kanalsorte (Koffer, Personen, Kürzel) | `ChatAvatar` |
| Kopfzeile „P-2026-0042 · 8 Mitglieder · aktiv" | `ChatHeader` |
| Filterzeile Alle / Projekte / Direkt / Ungelesen | der Typ `ChatFilter` |
| Das Menü hinter dem Plus, samt Trenner | `Composer` |
| Das Menü hinter dem Plus, samt Trenner und Reihenfolge | `Composer` (Beschriftungen oben geändert, §4) |
| Eingabefeld „Nachricht schreiben …" | derselbe Ort |
| Farben, Ränder, Plättchentöne | `ui/theme.css` |
| Alle Symbole | `@subframe/core`, Pfade aus dem Paket kopiert |
@@ -179,6 +179,49 @@ Abgelegt als **320 × 320 JPEG** bei Qualität 2. Der Avatar misst 42 px auf der
Slide, bei Renderqualität 3 also 126 — 320 lässt Luft, und JPEG ist für Fotos
das richtige Format; als PNG wäre es das Fünffache. Zusammen 100 KB.
**Im Menü hinter dem Plus fällt oben das Verb weg.** Im Werkzeug heißen die
vier oberen Einträge „Dokument senden", „Fotos und Videos senden", „Audio
senden" und „Kontakt teilen" — viermal ein Wort, das der Ort schon sagt: wer
das Menü über das Pluszeichen geöffnet hat, weiß, dass er etwas schickt. Hier
stehen nur die Dinge: **Dokumente, Medien, Audio, Kontakt.** Unten bleibt das
Verb, weil es dort etwas hinzufügt — „Termin" allein wäre ein Anhang, „Termin
erstellen" ist eine Handlung.
„Dokument" steht dabei in der Mehrzahl, weil man mehrere anhängen kann; Audio
und Kontakt bleiben einzeln, man schickt eine Aufnahme und einen Kontakt. Aus
„Fotos und Videos" wird **„Medien"** — dasselbe in einem Wort.
**Bei „Kontakt" steht jetzt das Teilen-Zeichen statt des Telefonhörers.** Ein
Hörer sagt „anrufen"; hier wird eine Karte weitergegeben. `ShareNetwork` aus
demselben Phosphor-bold-Satz wie alle anderen Zeichen, entnommen aus
`@phosphor-icons/react` im Website-Repo statt abgemalt. `phone` stand danach
nirgends mehr und ist aus der Tabelle heraus — sie zählt jetzt 19 Zeichen, und
jedes davon wird benutzt.
**Und die Eingabezeile ist zurück.** Sie stand einmal unter dem Menü und war
weggenommen worden mit der Begründung, die Slide zeige, was man anhängen kann,
und dafür brauche es das Feld nicht. Das stimmte nur so lange, wie man wusste,
worauf man schaut: ohne das Feld ist die Karte eine Liste im Nichts, und dass
sie aufklappt, wenn man im Chat auf das Pluszeichen tippt, stand nirgends.
Das Pluszeichen trägt jetzt die grüne Marke wie ein gedrücktes Element, und
der Zeiger steht darauf — derselbe, der im Bewegtbild die Nachricht anklickt.
Beides zusammen sagt den Zusammenhang, ohne dass ein Wort danebenstehen muss.
Das Menü öffnet nach oben, weil es das im Werkzeug auch tut.
Mit den kürzeren Beschriftungen kommt die Breite der Karte jetzt aus dem
längsten Eintrag statt aus einer festen Zahl. Vorher standen dort 470 Einheiten
— gemessen für Beschriftungen mit „senden" —, und die Karte lief mit einem
Drittel Leerraum quer über die Slide.
> **Ein hochkantes Bild richtet sich nach der Höhe, nicht nach der Breite.**
> Der Kasten misst 460 × 535. Bei der alten Breite von 940 px wurde er 1093 px
> hoch und lief in die Überschrift. Gerechnet wird die neue Breite außerdem am
> **sichtbaren Blatt** und nicht am Kasten: der ist um den Stapelrand größer
> als das, was man sieht, und mit seiner Oberkante gerechnet stand die
> Zeichnung noch einmal 60 px zu hoch und berührte den Fließtext. Bei 680 px
> bleiben rund 115 px Luft.
**Die Plakette für Ungelesenes trägt eine Zahl und ist grün.** In der Quelle
ist `unread` ein Wahrheitswert und der Punkt violett. Beides ist geändert:
violett ist im Produkt die Farbe der Projekte, das Kanalsymbol in derselben
+93 -20
View File
@@ -1450,7 +1450,15 @@ if (location.search.indexOf("nur=anim") >= 0)
eyebrow: "Das Pluszeichen",
head: 'Nicht nur<br><span class="a">Text.</span>',
body: "Versende mehr als nur Textnachrichten: Dokumente, Fotos, Sprachnachrichten.",
vis: "menue", visW: 940, visLeft: 70, visBottom: 120,
/* Schmaler und hoeher als vorher: die Zeichnung ist kein breites Menue
mehr, sondern ein Ausschnitt mit Eingabezeile darunter. Der Kasten
misst 460 x 535 -- hochkant, und die Breite richtet sich deshalb nach
der Hoehe. Gerechnet ist sie am sichtbaren Blatt und nicht am Kasten:
der ist um den Stapelrand groesser als das, was man sieht, und mit
seiner Oberkante gerechnet stand die Zeichnung 60 px zu hoch und
beruehrte den Fliesstext. Bei 680 px bleiben rund 115 px Luft.
Mittig gesetzt, (1080 - 680) / 2 = 200. */
vis: "menue", visW: 680, visLeft: 200, visBottom: 120,
},
{
/* Ein Ausblick, kein Beleg. Die App gibt es noch nicht -- deshalb steht
@@ -2062,7 +2070,11 @@ if (location.search.indexOf("nur=anim") >= 0)
"file-text": '<path d="M216.49,79.52l-56-56A12,12,0,0,0,152,20H56A20,20,0,0,0,36,40V216a20,20,0,0,0,20,20H200a20,20,0,0,0,20-20V88A12,12,0,0,0,216.49,79.52ZM160,57l23,23H160ZM60,212V44h76V92a12,12,0,0,0,12,12h48V212Zm112-80a12,12,0,0,1-12,12H96a12,12,0,0,1,0-24h64A12,12,0,0,1,172,132Zm0,40a12,12,0,0,1-12,12H96a12,12,0,0,1,0-24h64A12,12,0,0,1,172,172Z"/>',
"image": '<path d="M144,96a16,16,0,1,1,16,16A16,16,0,0,1,144,96Zm92-40V200a20,20,0,0,1-20,20H40a20,20,0,0,1-20-20V56A20,20,0,0,1,40,36H216A20,20,0,0,1,236,56ZM44,60v79.72l33.86-33.86a20,20,0,0,1,28.28,0L147.31,147l17.18-17.17a20,20,0,0,1,28.28,0L212,149.09V60Zm0,136H162.34L92,125.66l-48,48Zm168,0V183l-33.37-33.37L164.28,164l32,32Z"/>',
"mic": '<path d="M128,180a52.06,52.06,0,0,0,52-52V64A52,52,0,0,0,76,64v64A52.06,52.06,0,0,0,128,180ZM100,64a28,28,0,0,1,56,0v64a28,28,0,0,1-56,0Zm40,155.22V240a12,12,0,0,1-24,0V219.22A92.14,92.14,0,0,1,36,128a12,12,0,0,1,24,0,68,68,0,0,0,136,0,12,12,0,0,1,24,0A92.14,92.14,0,0,1,140,219.22Z"/>',
"phone": '<path d="M224,154.8l-47.09-21.11-.18-.08a19.94,19.94,0,0,0-19,1.75,13.08,13.08,0,0,0-1.12.84l-22.31,19c-13-7.05-26.43-20.37-33.49-33.21l19.06-22.66a11.76,11.76,0,0,0,.85-1.15,20,20,0,0,0,1.66-18.83,1.42,1.42,0,0,1-.08-.18L101.2,32A20.06,20.06,0,0,0,80.42,20.15,60.27,60.27,0,0,0,28,80c0,81.61,66.39,148,148,148a60.27,60.27,0,0,0,59.85-52.42A20.06,20.06,0,0,0,224,154.8ZM176,204A124.15,124.15,0,0,1,52,80,36.29,36.29,0,0,1,80.48,44.46l18.82,42L80.14,109.28a12,12,0,0,0-.86,1.16A20,20,0,0,0,78,130.08c9.42,19.28,28.83,38.56,48.31,48A20,20,0,0,0,146,176.63a11.63,11.63,0,0,0,1.11-.85l22.43-19.07,42,18.81A36.29,36.29,0,0,1,176,204Z"/>',
/* Teilen statt Telefonhoerer. Der Eintrag heisst "Kontakt", und ein
Hoerer sagt "anrufen" -- hier wird eine Karte weitergegeben, nicht
telefoniert. ShareNetwork aus demselben Phosphor-bold-Satz; "phone"
stand danach nirgends mehr und ist mit heraus. */
"share-network": '<path d="M176,156a43.78,43.78,0,0,0-29.09,11L106.1,140.8a44.07,44.07,0,0,0,0-25.6L146.91,89a43.83,43.83,0,1,0-13-20.17L93.09,95a44,44,0,1,0,0,65.94L133.9,187.2A44,44,0,1,0,176,156Zm0-120a20,20,0,1,1-20,20A20,20,0,0,1,176,36ZM64,148a20,20,0,1,1,20-20A20,20,0,0,1,64,148Zm112,72a20,20,0,1,1,20-20A20,20,0,0,1,176,220Z"/>',
"calendar": '<path d="M208,28H188V24a12,12,0,0,0-24,0v4H92V24a12,12,0,0,0-24,0v4H48A20,20,0,0,0,28,48V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V48A20,20,0,0,0,208,28ZM68,52a12,12,0,0,0,24,0h72a12,12,0,0,0,24,0h16V76H52V52ZM52,204V100H204V204Z"/>',
"square-check": '<path d="M79.51,144.49a12,12,0,1,1,17-17L112,143l47.51-47.52a12,12,0,0,1,17,17l-56,56a12,12,0,0,1-17,0ZM228,48V208a20,20,0,0,1-20,20H48a20,20,0,0,1-20-20V48A20,20,0,0,1,48,28H208A20,20,0,0,1,228,48Zm-24,4H52V204H204Z"/>',
"plus": '<path d="M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"/>',
@@ -3205,39 +3217,100 @@ if (location.search.indexOf("nur=anim") >= 0)
}
/* ─── Slide 4 · Was noch in den Chat passt ───────────────────────────────
Das Menue hinter dem Plus im Eingabefeld, woertlich aus Composer. Der
Trenner sitzt an derselben Stelle: darueber, was man anhaengt, darunter,
was man anlegt. Deshalb steht er hier auch. */
Das Menue hinter dem Plus im Eingabefeld. Der Trenner sitzt an derselben
Stelle wie im Composer: darueber, was man anhaengt, darunter, was man
anlegt.
ZWEI ABWEICHUNGEN VON DER QUELLE, beide der Lesbarkeit wegen.
Oben faellt das Verb weg. Im Werkzeug heissen die vier Eintraege
"Dokument senden", "Fotos und Videos senden", "Audio senden" und
"Kontakt teilen" -- viermal ein Wort, das der Ort schon sagt: wer das
Menue ueber das Pluszeichen im Eingabefeld geoeffnet hat, weiss, dass er
etwas schickt. Hier stehen nur die Dinge. Unten bleibt das Verb, weil es
dort etwas hinzufuegt: "Termin" allein waere ein Anhang, "Termin
erstellen" ist eine Handlung.
Und "Dokument" steht in der Mehrzahl, weil man mehrere anhaengen kann.
Audio und Kontakt bleiben einzeln -- man schickt eine Aufnahme und einen
Kontakt. Aus "Fotos und Videos" wird "Medien": dasselbe in einem Wort,
und die Karte wird noch einmal schmaler.
Das Zeichen bei "Kontakt" ist das Teilen-Zeichen und nicht mehr der
Telefonhoerer. Der Hoerer sagt "anrufen"; hier wird eine Karte
weitergegeben. */
const MENUE = [
["file-text", "Dokument senden"],
["image", "Fotos und Videos senden"],
["mic", "Audio senden"],
["phone", "Kontakt teilen"],
["file-text", "Dokumente"],
["image", "Medien"],
["mic", "Audio"],
["share-network", "Kontakt"],
null,
["calendar", "Termin erstellen"],
["square-check", "Aufgabe erstellen"],
];
function visMenue() {
const W = 470, ZH = 52, PAD = 14, RAND = 30;
const ZH = 52, PAD = 14, RAND = 30, GR = 19;
const TX = PAD + 50; // wo der Text im Menue anfaengt
const FELD = 76; // Hoehe der Eingabezeile
const LUFT = 20; // Abstand zwischen Menue und Feld
/* Die Breite kommt aus dem laengsten Eintrag statt aus einer festen Zahl.
Vorher standen hier 470 -- gemessen fuer Beschriftungen mit "senden",
und danach lief die Karte quer ueber die Slide, mit einem Drittel
Leerraum rechts. */
const breit = Math.max(...MENUE.filter(Boolean).map(e => messen(e[1], GR, 500)));
const W = Math.round(TX + breit + 44);
const hoehe = 2 * PAD + MENUE.reduce((a, e) => a + (e ? ZH : 13), 0);
let g = "";
let y = PAD + RAND;
/* Das Blatt ist breiter als das Menue: die Eingabezeile laeuft darunter
ueber die ganze Breite, so wie sie es im Fenster tut. */
const B = RAND + W + 118, H = RAND + hoehe + LUFT + FELD;
/* Das Menue als eigene Karte mit eigenem Schatten -- es liegt ueber dem
Fenster und nicht darin. */
let g = '<g filter="url(#hgschatten)"><path d="' +
rundRechteck(RAND, RAND, W, hoehe, 16) + '" fill="' + FL_KARTE +
'" stroke="' + CHAT_RAND + '" stroke-width="1.2"/></g>';
let y = RAND + PAD;
for (const e of MENUE) {
if (!e) {
g += '<path d="M' + (PAD + RAND) + ',' + n1(y + 6) + 'H' + n1(W + RAND - PAD) +
g += '<path d="M' + n1(RAND + PAD) + ',' + n1(y + 6) + 'H' + n1(RAND + W - PAD) +
'" stroke="' + CHAT_RAND + '" stroke-width="1.2"/>';
y += 13; continue;
}
g += ikon(e[0], PAD + RAND + 26, y + ZH / 2, 20, CHAT_TEXT2);
g += uiText(PAD + RAND + 50, y + ZH / 2 + 7, e[1], 19, 500, CHAT_TEXT);
g += ikon(e[0], RAND + PAD + 26, y + ZH / 2, 20, CHAT_TEXT2);
g += uiText(RAND + PAD + 50, y + ZH / 2 + 7, e[1], GR, 500, CHAT_TEXT);
y += ZH;
}
/* Unter dem Menue stand einmal das Eingabefeld, an dem es haengt. Es ist
weg: die Slide zeigt, was man anhaengen kann, und dafuer braucht es
das Feld nicht. Der Stapel sagt ohnehin, dass hier ein Bildschirm
liegt und nicht ein Kasten im Nichts. */
return stapelKasten(W + 2 * RAND, hoehe + 2 * RAND, 20, g);
/* ── Die Eingabezeile, aus der das Menue kommt ──────────────────────────
Sie stand hier einmal und war weggenommen worden: die Slide zeige, was
man anhaengen kann, und dafuer brauche es das Feld nicht. Das stimmte
nur so lange, wie man wusste, worauf man schaut. Ohne das Feld ist die
Karte eine Liste im Nichts -- dass sie aufklappt, wenn man im Chat auf
das Pluszeichen tippt, stand nirgends.
Das Pluszeichen traegt deshalb die gruene Marke wie ein gedruecktes
Element, und der Zeiger steht darauf. Beides zusammen sagt, was der
Zusammenhang ist, ohne dass ein Wort danebenstehen muss. Das Menue
oeffnet nach oben, weil es das im Werkzeug auch tut -- unten waere
kein Platz. */
const fy = H - FELD, pcx = RAND + 26, pcy = fy + FELD / 2;
g += '<path d="M0,' + n1(fy) + 'H' + n1(B) + '" stroke="' + CHAT_RAND +
'" stroke-width="1.2"/>';
g += '<circle cx="' + n1(pcx) + '" cy="' + n1(pcy) + '" r="21" fill="' +
MARKE.flaeche + '" stroke="' + MARKE.rand + '" stroke-width="1.2"/>';
g += ikon("plus", pcx, pcy, 21, MARKE.zeichen);
g += '<rect x="' + n1(pcx + 34) + '" y="' + n1(pcy - 21) + '" width="' +
n1(B - pcx - 34 - RAND - 44) + '" height="42" rx="21" fill="' + FL_SPALTE +
'" stroke="' + CHAT_RAND + '" stroke-width="1.2"/>';
g += uiText(pcx + 54, pcy + 6, "Nachricht schreiben …", 16, 400, "#C9C9CE");
g += ikon("mic", B - RAND - 12, pcy, 21, CHAT_TEXT2);
g += zeiger(pcx + 5, pcy + 3, 1.5);
return stapelKasten(B, H, 20, g);
}