diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b910e7a..589910c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -75,7 +75,7 @@ } }, "welcomeChecklistHeader": "ERSTE SCHRITTE", - "welcomeChecklistBody": "Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.", + "welcomeChecklistBody": "Vier Schritte zu einem funktionierenden Hub. Die Liste zeigt den Live-Zustand — nach einer Änderung oben rechts aktualisieren.", "welcomeChecklistAi": "System-KI konfigurieren", "welcomeChecklistAiHint": "Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.", "welcomeChecklistMcp": "Öffentlichen Werkzeug-Katalog verbinden", @@ -163,7 +163,7 @@ "settingsHost": "Host", "settingsPort": "Port", "settingsTls": "TLS", - "settingsSaveAndConnect": "Mit Endpoint verbinden", + "settingsSaveAndConnect": "Mit Endpunkt verbinden", "settingsLanguage": "Sprache", "settingsLanguageHint": "Sprache der App. Wirkt auf alle Seiten; mehrsprachige Store-Einträge folgen ebenfalls.", "settingsHubEndpointHint": "Wohin soll Studio sich verbinden? Standard ist der lokale Hub auf 127.0.0.1:50051.", @@ -1212,7 +1212,7 @@ "doctorDaemonFilesSection": "Daemon-Dateien", "doctorDaemonControlSection": "Daemon-Steuerung", "doctorChainIntact": "Hash-Kette intakt", - "doctorChainIntactDetail": "{n} {n, plural, =1{Ereignis} other{Ereignisse}} · prev_event_sha256 lückenlos verifiziert", + "doctorChainIntactDetail": "{n} {n, plural, =1{Ereignis} other{Ereignisse}} · Verkettung lückenlos geprüft", "@doctorChainIntactDetail": { "placeholders": { "n": { @@ -1235,7 +1235,7 @@ } } }, - "doctorChainPillOk": "Integritätskette geprüft", + "doctorChainPillOk": "Hash-Kette geprüft", "doctorChainPillTamper": "MANIPULIERT", "doctorVerifyNow": "Jetzt prüfen", "doctorRestart": "Neustart", @@ -1741,6 +1741,7 @@ "federationCopied": "In die Zwischenablage kopiert", "federationEnrollmentHint": "Übergeben Sie das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte Zertifikatsstelle authentifiziert die erste Verbindung des Satelliten.", "workspaceAll": "Alle Projekte", + "workspaceDefaultProject": "Allgemein", "workspaceSwitcherTooltip": "Arbeitsbereich — filtert diese Ansicht und stempelt neue Läufe mit dem gewählten Projekt", "workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.", "runsTitle": "Läufe", @@ -1765,6 +1766,8 @@ "workspaceSealedHeader": "ABGESCHOTTETE BEREICHE", "workspaceSealedRunning": "läuft", "workspaceSealedStopped": "gestoppt", + "workspaceSealedRunningHint": "Der abgeschottete Bereich läuft als eigener Hub-Prozess. Auswählen wechselt hinein.", + "workspaceSealedStoppedHint": "Der abgeschottete Bereich ist gerade nicht gestartet. Auswählen startet ihn und wechselt hinein.", "workspaceSealedStarting": "Starte abgeschotteten Bereich „{name}“…", "@workspaceSealedStarting": {"placeholders": {"name": {"type": "String"}}}, "workspaceSealedStarted": "Abgeschotteter Bereich „{name}“ gestartet.", @@ -1854,7 +1857,7 @@ "setupApplyNotes": "Hinweise aus der Einrichtung", "setupFreeTextHint": "z. B.: Eingehende Anträge vorprüfen und unvollständige markieren", "setupFreeTextSuggest": "Vorschlagen lassen", - "setupFreeTextPrivacyLocal": "Ihre Beschreibung wird lokal auf diesem Rechner verarbeitet ({model}).", + "setupFreeTextPrivacyLocal": "Ihre Beschreibung wird direkt auf diesem Rechner verarbeitet — durch das lokale KI-Modell {model}. Nichts verlässt das Gerät.", "@setupFreeTextPrivacyLocal": {"placeholders": {"model": {"type": "String"}}}, "setupFreeTextPrivacyRemote": "Ihre Beschreibung wird an die eingerichtete System-KI gesendet: {model} ({provider}).", "@setupFreeTextPrivacyRemote": {"placeholders": {"model": {"type": "String"}, "provider": {"type": "String"}}}, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a3ae888..6adb04f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -83,7 +83,7 @@ } }, "welcomeChecklistHeader": "GETTING STARTED", - "welcomeChecklistBody": "Four steps to a working hub. Live state — refresh after changing anything.", + "welcomeChecklistBody": "Four steps to a working hub. The list shows the live state — refresh top right after changing anything.", "welcomeChecklistAi": "Configure System AI", "welcomeChecklistAiHint": "Settings → System AI. Required for the AI search and inline failure explanations.", "welcomeChecklistMcp": "Connect a public tool catalog", @@ -1236,7 +1236,7 @@ "doctorDaemonFilesSection": "Daemon files", "doctorDaemonControlSection": "Daemon control", "doctorChainIntact": "Hash chain intact", - "doctorChainIntactDetail": "{n} {n, plural, =1{event} other{events}} · prev_event_sha256 verified end-to-end", + "doctorChainIntactDetail": "{n} {n, plural, =1{event} other{events}} · linkage verified end-to-end", "@doctorChainIntactDetail": { "placeholders": { "n": { @@ -1259,7 +1259,7 @@ } } }, - "doctorChainPillOk": "Integrity chain verified", + "doctorChainPillOk": "Hash chain verified", "doctorChainPillTamper": "TAMPER", "doctorVerifyNow": "Verify now", "doctorRestart": "Restart", @@ -1780,6 +1780,7 @@ "federationCopied": "Copied to clipboard", "federationEnrollmentHint": "Hand the token to the satellite operator over a secure channel. The bundled CA authenticates the satellite's first connect.", "workspaceAll": "All projects", + "workspaceDefaultProject": "General", "workspaceSwitcherTooltip": "Workspace — filters this view and stamps new runs with the selected project", "workspaceProtectedHint": "Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area.", "runsTitle": "Runs", @@ -1804,6 +1805,8 @@ "workspaceSealedHeader": "SEALED AREAS", "workspaceSealedRunning": "running", "workspaceSealedStopped": "stopped", + "workspaceSealedRunningHint": "The sealed area runs as its own hub process. Selecting it switches in.", + "workspaceSealedStoppedHint": "The sealed area is not running right now. Selecting it starts it and switches in.", "workspaceSealedStarting": "Starting sealed area “{name}”…", "@workspaceSealedStarting": {"placeholders": {"name": {"type": "String"}}}, "workspaceSealedStarted": "Started sealed area “{name}”.", @@ -1893,7 +1896,7 @@ "setupApplyNotes": "Notes from the setup", "setupFreeTextHint": "e.g.: pre-screen incoming applications and flag incomplete ones", "setupFreeTextSuggest": "Suggest a setup", - "setupFreeTextPrivacyLocal": "Your description is processed locally on this machine ({model}).", + "setupFreeTextPrivacyLocal": "Your description is processed right on this machine — by the local AI model {model}. Nothing leaves the device.", "@setupFreeTextPrivacyLocal": {"placeholders": {"model": {"type": "String"}}}, "setupFreeTextPrivacyRemote": "Your description is sent to the configured system AI: {model} ({provider}).", "@setupFreeTextPrivacyRemote": {"placeholders": {"model": {"type": "String"}, "provider": {"type": "String"}}}, diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 58e9408..8f1c9a3 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -509,7 +509,7 @@ abstract class AppLocalizations { /// No description provided for @welcomeChecklistBody. /// /// In en, this message translates to: - /// **'Four steps to a working hub. Live state — refresh after changing anything.'** + /// **'Four steps to a working hub. The list shows the live state — refresh top right after changing anything.'** String get welcomeChecklistBody; /// No description provided for @welcomeChecklistAi. @@ -3731,7 +3731,7 @@ abstract class AppLocalizations { /// No description provided for @doctorChainIntactDetail. /// /// In en, this message translates to: - /// **'{n} {n, plural, =1{event} other{events}} · prev_event_sha256 verified end-to-end'** + /// **'{n} {n, plural, =1{event} other{events}} · linkage verified end-to-end'** String doctorChainIntactDetail(int n); /// No description provided for @doctorChainTampered. @@ -3749,7 +3749,7 @@ abstract class AppLocalizations { /// No description provided for @doctorChainPillOk. /// /// In en, this message translates to: - /// **'Integrity chain verified'** + /// **'Hash chain verified'** String get doctorChainPillOk; /// No description provided for @doctorChainPillTamper. @@ -5281,6 +5281,12 @@ abstract class AppLocalizations { /// **'All projects'** String get workspaceAll; + /// No description provided for @workspaceDefaultProject. + /// + /// In en, this message translates to: + /// **'General'** + String get workspaceDefaultProject; + /// No description provided for @workspaceSwitcherTooltip. /// /// In en, this message translates to: @@ -5413,6 +5419,18 @@ abstract class AppLocalizations { /// **'stopped'** String get workspaceSealedStopped; + /// No description provided for @workspaceSealedRunningHint. + /// + /// In en, this message translates to: + /// **'The sealed area runs as its own hub process. Selecting it switches in.'** + String get workspaceSealedRunningHint; + + /// No description provided for @workspaceSealedStoppedHint. + /// + /// In en, this message translates to: + /// **'The sealed area is not running right now. Selecting it starts it and switches in.'** + String get workspaceSealedStoppedHint; + /// No description provided for @workspaceSealedStarting. /// /// In en, this message translates to: @@ -5884,7 +5902,7 @@ abstract class AppLocalizations { /// No description provided for @setupFreeTextPrivacyLocal. /// /// In en, this message translates to: - /// **'Your description is processed locally on this machine ({model}).'** + /// **'Your description is processed right on this machine — by the local AI model {model}. Nothing leaves the device.'** String setupFreeTextPrivacyLocal(String model); /// No description provided for @setupFreeTextPrivacyRemote. diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index bb396d1..a25dc15 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -247,7 +247,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get welcomeChecklistBody => - 'Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.'; + 'Vier Schritte zu einem funktionierenden Hub. Die Liste zeigt den Live-Zustand — nach einer Änderung oben rechts aktualisieren.'; @override String get welcomeChecklistAi => 'System-KI konfigurieren'; @@ -499,7 +499,7 @@ class AppLocalizationsDe extends AppLocalizations { String get settingsTls => 'TLS'; @override - String get settingsSaveAndConnect => 'Mit Endpoint verbinden'; + String get settingsSaveAndConnect => 'Mit Endpunkt verbinden'; @override String get settingsLanguage => 'Sprache'; @@ -2194,7 +2194,7 @@ class AppLocalizationsDe extends AppLocalizations { other: 'Ereignisse', one: 'Ereignis', ); - return '$n $_temp0 · prev_event_sha256 lückenlos verifiziert'; + return '$n $_temp0 · Verkettung lückenlos geprüft'; } @override @@ -2206,7 +2206,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get doctorChainPillOk => 'Integritätskette geprüft'; + String get doctorChainPillOk => 'Hash-Kette geprüft'; @override String get doctorChainPillTamper => 'MANIPULIERT'; @@ -3126,6 +3126,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get workspaceAll => 'Alle Projekte'; + @override + String get workspaceDefaultProject => 'Allgemein'; + @override String get workspaceSwitcherTooltip => 'Arbeitsbereich — filtert diese Ansicht und stempelt neue Läufe mit dem gewählten Projekt'; @@ -3201,6 +3204,14 @@ class AppLocalizationsDe extends AppLocalizations { @override String get workspaceSealedStopped => 'gestoppt'; + @override + String get workspaceSealedRunningHint => + 'Der abgeschottete Bereich läuft als eigener Hub-Prozess. Auswählen wechselt hinein.'; + + @override + String get workspaceSealedStoppedHint => + 'Der abgeschottete Bereich ist gerade nicht gestartet. Auswählen startet ihn und wechselt hinein.'; + @override String workspaceSealedStarting(String name) { return 'Starte abgeschotteten Bereich „$name“…'; @@ -3498,7 +3509,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String setupFreeTextPrivacyLocal(String model) { - return 'Ihre Beschreibung wird lokal auf diesem Rechner verarbeitet ($model).'; + return 'Ihre Beschreibung wird direkt auf diesem Rechner verarbeitet — durch das lokale KI-Modell $model. Nichts verlässt das Gerät.'; } @override diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 4b3a727..8bf9a7e 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -247,7 +247,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get welcomeChecklistBody => - 'Four steps to a working hub. Live state — refresh after changing anything.'; + 'Four steps to a working hub. The list shows the live state — refresh top right after changing anything.'; @override String get welcomeChecklistAi => 'Configure System AI'; @@ -2200,7 +2200,7 @@ class AppLocalizationsEn extends AppLocalizations { other: 'events', one: 'event', ); - return '$n $_temp0 · prev_event_sha256 verified end-to-end'; + return '$n $_temp0 · linkage verified end-to-end'; } @override @@ -2212,7 +2212,7 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String get doctorChainPillOk => 'Integrity chain verified'; + String get doctorChainPillOk => 'Hash chain verified'; @override String get doctorChainPillTamper => 'TAMPER'; @@ -3126,6 +3126,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get workspaceAll => 'All projects'; + @override + String get workspaceDefaultProject => 'General'; + @override String get workspaceSwitcherTooltip => 'Workspace — filters this view and stamps new runs with the selected project'; @@ -3201,6 +3204,14 @@ class AppLocalizationsEn extends AppLocalizations { @override String get workspaceSealedStopped => 'stopped'; + @override + String get workspaceSealedRunningHint => + 'The sealed area runs as its own hub process. Selecting it switches in.'; + + @override + String get workspaceSealedStoppedHint => + 'The sealed area is not running right now. Selecting it starts it and switches in.'; + @override String workspaceSealedStarting(String name) { return 'Starting sealed area “$name”…'; @@ -3492,7 +3503,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String setupFreeTextPrivacyLocal(String model) { - return 'Your description is processed locally on this machine ($model).'; + return 'Your description is processed right on this machine — by the local AI model $model. Nothing leaves the device.'; } @override diff --git a/lib/widgets/chain_workspace_switcher.dart b/lib/widgets/chain_workspace_switcher.dart index 98c0c8e..b9c85d6 100644 --- a/lib/widgets/chain_workspace_switcher.dart +++ b/lib/widgets/chain_workspace_switcher.dart @@ -11,6 +11,7 @@ import 'package:flutter/material.dart'; +import '../data/hub.dart' show ProjectRef; import '../data/sealed_areas.dart'; import '../data/workspace.dart'; import '../l10n/app_localizations.dart'; @@ -36,7 +37,11 @@ class ChainWorkspaceSwitcher extends StatelessWidget { final label = ws.inSealedArea ? ws.activeSealed!.name - : (ws.isAll ? l.workspaceAll : (ws.active?.name ?? ws.activeSlug)); + : (ws.isAll + ? l.workspaceAll + : (ws.active == null + ? ws.activeSlug + : _projectLabel(l, ws.active!))); return Tooltip( message: l.workspaceSwitcherTooltip, @@ -82,7 +87,12 @@ class ChainWorkspaceSwitcher extends StatelessWidget { children: [ _ProjectDot(color: p.color), const SizedBox(width: ChainSpace.sm), - Flexible(child: Text(p.name, overflow: TextOverflow.ellipsis)), + Flexible( + child: Text( + _projectLabel(l, p), + overflow: TextOverflow.ellipsis, + ), + ), if (p.isProtected) ...[ const SizedBox(width: ChainSpace.sm), Tooltip( @@ -130,12 +140,19 @@ class ChainWorkspaceSwitcher extends StatelessWidget { const SizedBox(width: 4), Flexible(child: Text(a.name, overflow: TextOverflow.ellipsis)), const SizedBox(width: ChainSpace.sm), - Text( - a.running ? l.workspaceSealedRunning : l.workspaceSealedStopped, - style: theme.textTheme.labelSmall?.copyWith( - color: a.running - ? ChainColors.success - : theme.colorScheme.onSurfaceVariant, + Tooltip( + message: a.running + ? l.workspaceSealedRunningHint + : l.workspaceSealedStoppedHint, + child: Text( + a.running + ? l.workspaceSealedRunning + : l.workspaceSealedStopped, + style: theme.textTheme.labelSmall?.copyWith( + color: a.running + ? ChainColors.success + : theme.colorScheme.onSurfaceVariant, + ), ), ), ], @@ -266,6 +283,12 @@ class ChainWorkspaceSwitcher extends StatelessWidget { } } +/// Display name for a registry project. The hub's default project +/// carries the fixed English name "General"; render it localized +/// ("Allgemein") so no English label sits in the German menu. +String _projectLabel(AppLocalizations l, ProjectRef p) => + p.slug == 'general' ? l.workspaceDefaultProject : p.name; + /// The project's registry colour as a small marking dot. Falls back /// to the theme's outline colour when unset. class _ProjectDot extends StatelessWidget {