Live: patrickstubner.github.io/Travel-Talk
Reise-Sprachhilfe für eine Familie. Version 0.9.1. Ohne Konto, ohne Tracking. Mehrere Personen können auf einem Gerät lernen. Lernstand und Sätze bleiben auf dem Gerät. Eine Stimme ist lokal, nachdem sie geladen wurde. Stimmen und Audiodateien sind gemeinsam. Nach dem Nachsprechen liegen die eigene Tonhöhe und die der gehörten Datei auf einer Achse, mit Farben an den Wörtern und Balken für Melodie und Rhythmus. Eine Note zum Satz gibt es in dieser Fassung nicht.
Die App hilft beim Üben kurzer Sätze entlang einer Reise: Notfall, Menschen treffen, Ankunft, Restaurant, Transport und ein Anfang für Visum, Unterkunft, Einkaufen, Sehenswürdigkeiten und Alltag. Die Sprache der App und die Lernsprache sind zwei getrennte Wahlen. Hören, Verstehen und Sprechen kommen zuerst. Lesen stützt das Hören. Schreiben ist nicht der Weg durch die Sitzung. Vor den neuen Sätzen kommen höchstens sechs Wörter am Tag, auch über mehrere Sitzungen. Ein Satz ohne geprüftes Wort ist sofort offen. Sonst geht er auf, wenn jedes geprüfte Wort einmal richtig war. Freie Satzplätze gehen zuerst an die Sätze, deren Wörter heute richtig waren. Höchstens 15 neue Karten am Tag, Wörter und Sätze zusammen, über alle Richtungen.
Die Sätze auf Vietnamesisch und Portugiesisch (Brasilien) sind noch nicht von einer muttersprachlichen Person geprüft. Dasselbe gilt für Deutsch und Englisch. Im UI steht das an den Sätzen.
Deutsch, Englisch, Portugiesisch (Brasilien) und Vietnamesisch. Jede Richtung aus zwei verschiedenen Sprachen läuft aus denselben 123 Konzepten. Eine fehlende Zeile wird ausgelassen, und der Start sagt das. Die Zahlen pro Situation stehen unten. Ein Konzept kann in zwei Situationen hängen, zum Beispiel die Allergie im Notfall und im Restaurant. Deshalb ist die Summe der Situationen grösser als 123.
| Situation | Stand | Konzepte |
|---|---|---|
| Notfall | ausgearbeitet | 20 |
| Menschen treffen | ausgearbeitet | 29 |
| Ankunft und Einreise | kleiner Satz | 11 |
| Restaurant, Essen, Trinken | kleiner Satz | 14 |
| Visum vor der Reise | Anfang | 8 |
| Unterkunft | Anfang | 8 |
| Alltag | Anfang | 8 |
| Einkaufen | Anfang | 7 |
| Sehenswürdigkeiten | Anfang | 6 |
| Transport | kleiner Satz | 20 |
Vietnamesisch ist im Text südlich voreingestellt. Nord ist eine Variante, zum Beispiel đậu phộng und lạc. Eine neue Installation spricht mit einer Männerstimme. Die nördliche Frauenstimme bleibt wählbar. Der Akzent der Männerstimmen ist nicht dokumentiert. Das Tempo hat drei Stufen, 70 %, 85 % und 100 %, als eigene Dateien, damit die Tonhöhe gleich bleibt. Die Wahl sitzt nur am Player. Details in docs/audio.md.
Voraussetzung: Node 22.
npm ci
npm run devDie App liegt unter http://127.0.0.1:5173/Travel-Talk/. Der Build ist Rsbuild. Der Service Worker entsteht nach dem Build mit workbox-build. Er speichert die Oberfläche. Audiodateien gehören nicht zum Installieren, und ein Update übernimmt sie nicht aus dem alten Cache. Die Startseite sagt «Für offline noch nicht vollständig geladen», solange die Lernsprache nicht vollständig geladen ist. Eine Stimme wird mit «Für offline laden» geholt. Ein Rspack-Plugin sähe nur die kompilierten Assets. Die Tests laufen mit Vitest, getrennt vom Build. Weitere Befehle:
npm test
npm run test:clips
npm run typecheck
npm run lint
npm run buildnpm test braucht kein ffmpeg. npm run test:clips dekodiert die mitgelieferten Aufnahmen und rechnet die Melodie. Dafür wird ffmpeg benötigt. Ohne ffmpeg bricht der Lauf lokal mit einem Hinweis ab und wird übersprungen. In CI wird ffmpeg verlangt.
Der Build schreibt die App nach dist/ und kopiert index.html nach 404.html, weil GitHub Pages kein SPA-Fallback hat. Die Navigation läuft über den Hash. Die Basis ist /Travel-Talk/.
Lernstand, Aufnahmen und die persönliche Notiz bleiben im Browser. Export und Import sind JSON. Der Export wartet, bis beide Sprachen gewählt sind. Die Notiz kommt nur in den Export, wenn der Haken gesetzt ist, weil sie Gesundheitsangaben enthalten kann. Der Import prüft die Datei, zeigt eine Zusammenfassung und lehnt Unpassendes ab, ohne den Inhalt anzuzeigen. Eine Aufnahme stoppt, wenn der Tab versteckt wird oder die Seite zugeht.
Die Daten sind konzept-zentriert. Ein Konzept hat pro Sprache eine Realisierung. Die Seiten lesen diese Realisierung, sie enthalten keine eigenen Sätze.
Situation. Ein Eintrag in content/situations.ts mit id, Reihenfolge, Tiefe (core, sample oder starter) und Titel plus Kurztext in de, en, pt-BR und vi. Die Navigation nimmt jede Situation aus dieser Liste.
Sätze. Eine Datei unter content/phrases/ und der Eintrag in content/index.ts. phrase() setzt geprueft auf false. Vietnamesisch mit allen Zeichen. Portugiesisch in brasilianischer Verwendung: você, nicht das europäische tu. Beispielnamen sind erfunden. Wo die Anrede die Grammatik nicht bricht, steht {addr} oder {Addr}. Deutsch mit wechselndem Verb bekommt volle Varianten (Sie und du), keine Token. Tests in src/content/catalog.test.ts prüfen das Schema.
Kulturhinweis. Ein Eintrag in content/culture.ts mit Situationen, Regionen (VN, BR, DE-CH, EN), Text in vier Sprachen, mindestens einer https-Quelle und dem Lesedatum. Im Text «häufig» oder «vielerorts», keine Regel für alle Menschen. Die Quelle erscheint in der Oberfläche.
Sprache. Eine weitere Sprache ist eine weitere Realisierung pro Konzept, kein neues Layout. Die Liste der Sprachen in content/phrase.ts und im Schema ist geschlossen, weil nur diese vier vorkommen. Sprache der App und Lernsprache sind zwei Wahlen. Die Richtung entsteht daraus, in src/domain/direction.ts. Für eine fünfte Sprache kommt der Code dort dazu und, wenn Audio mitgeliefert wird, eine Stimme in tools/generate_audio.py und docs/audio.md. Die Seiten bleiben dieselben.
Audio neu bauen steht in docs/audio.md. Die Prüfung der Abhängigkeiten und der Eingaben steht in docs/SECURITY.md.
GitHub Pages baut über die Action in .github/workflows/ci.yml, nur beim Push auf main. Lint, Typprüfung, Tests, Build und npm audit laufen auch auf Pull Requests. Der Audit bricht ab der Stufe moderate ab.