diff --git a/README.md b/README.md index e4df1f5..e9e4eda 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@
-App Demo + +![Conduit Demo](fastlane/metadata/en-US/images/conduit-demo.gif) +

@@ -73,7 +75,7 @@ flutter run -d ios # or: -d android | | | | | | --- | --- | --- | --- | -| Screenshot 2 | Screenshot 3 | Screenshot 4 | Screenshot 5 | +| Screenshot 2 | Screenshot 3 | Screenshot 4 | Screenshot 5 | ## Requirements diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png deleted file mode 100644 index 3f1eeb9..0000000 Binary files a/fastlane/metadata/android/en-US/images/icon.png and /dev/null differ diff --git a/fastlane/metadata/android/en-US/videos/conduit-demo.mp4 b/fastlane/metadata/android/en-US/videos/conduit-demo.mp4 deleted file mode 100644 index de09b88..0000000 Binary files a/fastlane/metadata/android/en-US/videos/conduit-demo.mp4 and /dev/null differ diff --git a/fastlane/metadata/en-US/description.txt b/fastlane/metadata/en-US/description.txt deleted file mode 100644 index f8ae6dc..0000000 --- a/fastlane/metadata/en-US/description.txt +++ /dev/null @@ -1,24 +0,0 @@ -Conduit is an open-source, native mobile client for Open‑WebUI. Connect to your own server to chat with AI models, manage conversations, and take your self‑hosted AI with you—securely and on the go. - -Key Features -- Real-time streaming chat -- Model selection -- Conversation search and management -- Voice input (speech-to-text) -- File and image uploads for retrieval-augmented generation (RAG) -- Vision and multi‑modal support -- Markdown rendering with syntax highlighting -- Light, dark, and system themes -- Secure credential storage - -Requirements -- An existing Open‑WebUI server (Conduit does not host or provide AI models). - -Privacy & Permissions -- Microphone: For voice input -- Camera and Photos: For image/file attachments -- Network: To connect to your Open‑WebUI server - -Open Source -Built with Flutter and maintained by the community. Contributions are welcome. - diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/en-US/full_description.txt similarity index 100% rename from fastlane/metadata/android/en-US/full_description.txt rename to fastlane/metadata/en-US/full_description.txt diff --git a/fastlane/metadata/en-US/images/conduit-demo.gif b/fastlane/metadata/en-US/images/conduit-demo.gif new file mode 100644 index 0000000..fda0d94 Binary files /dev/null and b/fastlane/metadata/en-US/images/conduit-demo.gif differ diff --git a/fastlane/metadata/en-US/images/icon.png b/fastlane/metadata/en-US/images/icon.png index 72600be..3f1eeb9 100644 Binary files a/fastlane/metadata/en-US/images/icon.png and b/fastlane/metadata/en-US/images/icon.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/en-US/images/phoneScreenshots/1.png similarity index 100% rename from fastlane/metadata/android/en-US/images/phoneScreenshots/1.png rename to fastlane/metadata/en-US/images/phoneScreenshots/1.png diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/en-US/images/phoneScreenshots/2.png similarity index 100% rename from fastlane/metadata/android/en-US/images/phoneScreenshots/2.png rename to fastlane/metadata/en-US/images/phoneScreenshots/2.png diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/en-US/images/phoneScreenshots/3.png similarity index 100% rename from fastlane/metadata/android/en-US/images/phoneScreenshots/3.png rename to fastlane/metadata/en-US/images/phoneScreenshots/3.png diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/en-US/images/phoneScreenshots/4.png similarity index 100% rename from fastlane/metadata/android/en-US/images/phoneScreenshots/4.png rename to fastlane/metadata/en-US/images/phoneScreenshots/4.png diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/en-US/images/phoneScreenshots/5.png similarity index 100% rename from fastlane/metadata/android/en-US/images/phoneScreenshots/5.png rename to fastlane/metadata/en-US/images/phoneScreenshots/5.png diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_01.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_01.png deleted file mode 100644 index 82baa03..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_01.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_02.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_02.png deleted file mode 100644 index 1bf2ec7..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_02.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_03.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_03.png deleted file mode 100644 index d933a39..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_03.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_04.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_04.png deleted file mode 100644 index 497eae2..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_04.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_05.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_05.png deleted file mode 100644 index ccac460..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_05.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_06.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_06.png deleted file mode 100644 index c3a4675..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_06.png and /dev/null differ diff --git a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_07.png b/fastlane/metadata/en-US/images/phoneScreenshots/flutter_07.png deleted file mode 100644 index 56a9ad9..0000000 Binary files a/fastlane/metadata/en-US/images/phoneScreenshots/flutter_07.png and /dev/null differ diff --git a/fastlane/metadata/en-US/name.txt b/fastlane/metadata/en-US/name.txt deleted file mode 100644 index a454a94..0000000 --- a/fastlane/metadata/en-US/name.txt +++ /dev/null @@ -1,2 +0,0 @@ -Conduit - diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/en-US/short_description.txt similarity index 100% rename from fastlane/metadata/android/en-US/short_description.txt rename to fastlane/metadata/en-US/short_description.txt diff --git a/fastlane/metadata/en-US/subtitle.txt b/fastlane/metadata/en-US/subtitle.txt deleted file mode 100644 index f8cd883..0000000 --- a/fastlane/metadata/en-US/subtitle.txt +++ /dev/null @@ -1,2 +0,0 @@ -Chat with your self‑hosted AI - diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/en-US/title.txt similarity index 100% rename from fastlane/metadata/android/en-US/title.txt rename to fastlane/metadata/en-US/title.txt diff --git a/lib/features/auth/views/authentication_page.dart b/lib/features/auth/views/authentication_page.dart index 7e5650d..2ea2ad1 100644 --- a/lib/features/auth/views/authentication_page.dart +++ b/lib/features/auth/views/authentication_page.dart @@ -483,7 +483,7 @@ class _AuthenticationPageState extends ConsumerState { ), ]), obscureText: _obscurePassword, - semanticLabel: 'Enter your API key', + semanticLabel: AppLocalizations.of(context)!.enterApiKey, prefixIcon: Icon( Platform.isIOS ? CupertinoIcons.lock_shield @@ -516,14 +516,14 @@ class _AuthenticationPageState extends ConsumerState { children: [ AccessibleFormField( label: AppLocalizations.of(context)!.usernameOrEmail, - hint: 'Enter your username or email', + hint: AppLocalizations.of(context)!.usernameOrEmailHint, controller: _usernameController, validator: InputValidationService.combine([ InputValidationService.validateRequired, (value) => InputValidationService.validateEmailOrUsername(value), ]), keyboardType: TextInputType.emailAddress, - semanticLabel: 'Enter your username or email', + semanticLabel: AppLocalizations.of(context)!.usernameOrEmailHint, prefixIcon: Icon( Platform.isIOS ? CupertinoIcons.person : Icons.person_outline, color: context.conduitTheme.iconSecondary, @@ -534,18 +534,18 @@ class _AuthenticationPageState extends ConsumerState { const SizedBox(height: Spacing.lg), AccessibleFormField( label: AppLocalizations.of(context)!.password, - hint: 'Enter your password', + hint: AppLocalizations.of(context)!.passwordHint, controller: _passwordController, validator: InputValidationService.combine([ InputValidationService.validateRequired, (value) => InputValidationService.validateMinLength( value, 1, - fieldName: 'Password', + fieldName: AppLocalizations.of(context)!.password, ), ]), obscureText: _obscurePassword, - semanticLabel: 'Enter your password', + semanticLabel: AppLocalizations.of(context)!.passwordHint, prefixIcon: Icon( Platform.isIOS ? CupertinoIcons.lock : Icons.lock_outline, color: context.conduitTheme.iconSecondary, @@ -576,7 +576,7 @@ class _AuthenticationPageState extends ConsumerState { child: ConduitButton( text: _isSigningIn - ? 'Signing in...' + ? AppLocalizations.of(context)!.signingIn : _useApiKey ? AppLocalizations.of(context)!.signInWithApiKey : AppLocalizations.of(context)!.signIn, diff --git a/lib/features/auth/views/server_connection_page.dart b/lib/features/auth/views/server_connection_page.dart index 5542448..def2905 100644 --- a/lib/features/auth/views/server_connection_page.dart +++ b/lib/features/auth/views/server_connection_page.dart @@ -360,7 +360,7 @@ class _ServerConnectionPageState extends ConsumerState { Positioned( bottom: 0, child: ConduitBadge( - text: 'Demo', + text: AppLocalizations.of(context)!.demoBadge, backgroundColor: context.conduitTheme.warning.withValues(alpha: 0.15), textColor: context.conduitTheme.warning, isCompact: true, @@ -425,7 +425,7 @@ class _ServerConnectionPageState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Demo Mode Active', + AppLocalizations.of(context)!.demoModeActive, style: context.conduitTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, color: context.conduitTheme.warning, @@ -433,7 +433,7 @@ class _ServerConnectionPageState extends ConsumerState { ), const SizedBox(height: Spacing.xs), Text( - 'Skip server setup and try the demo', + AppLocalizations.of(context)!.skipServerSetupTryDemo, style: context.conduitTheme.bodySmall?.copyWith( color: context.conduitTheme.textSecondary, ), @@ -445,7 +445,7 @@ class _ServerConnectionPageState extends ConsumerState { ), const SizedBox(height: Spacing.lg), ConduitButton( - text: 'Enter Demo', + text: AppLocalizations.of(context)!.enterDemo, icon: Platform.isIOS ? CupertinoIcons.play_fill : Icons.play_arrow, onPressed: () { Navigator.of(context).push( @@ -470,15 +470,15 @@ class _ServerConnectionPageState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ AccessibleFormField( - label: 'Server URL', - hint: 'https://your-server.com', + label: AppLocalizations.of(context)!.serverUrl, + hint: AppLocalizations.of(context)!.serverUrlHint, controller: _urlController, validator: InputValidationService.combine([ InputValidationService.validateRequired, (value) => InputValidationService.validateUrl(value, required: true), ]), keyboardType: TextInputType.url, - semanticLabel: 'Enter your server URL or IP address', + semanticLabel: AppLocalizations.of(context)!.enterServerUrlSemantic, onSubmitted: (_) => _connectToServer(), prefixIcon: Icon( Platform.isIOS ? CupertinoIcons.globe : Icons.public, @@ -533,7 +533,7 @@ class _ServerConnectionPageState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Advanced Settings', + AppLocalizations.of(context)!.advancedSettings, style: context.conduitTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, ), @@ -582,7 +582,7 @@ class _ServerConnectionPageState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - 'Custom Headers', + AppLocalizations.of(context)!.customHeaders, style: context.conduitTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, ), @@ -600,7 +600,7 @@ class _ServerConnectionPageState extends ConsumerState { ), const SizedBox(height: Spacing.xs), Text( - 'Add custom HTTP headers for authentication, API keys, or special server requirements.', + AppLocalizations.of(context)!.customHeadersDescription, style: context.conduitTheme.bodySmall?.copyWith( color: context.conduitTheme.textSecondary, ), @@ -787,13 +787,13 @@ class _ServerConnectionPageState extends ConsumerState { // Check for duplicates if (_customHeaders.containsKey(key)) { - _showHeaderError('Header "$key" already exists. Remove it first to update.'); + _showHeaderError(AppLocalizations.of(context)!.headerAlreadyExists(key)); return; } // Check header count limit if (_customHeaders.length >= 10) { - _showHeaderError('Maximum of 10 custom headers allowed. Remove some to add more.'); + _showHeaderError(AppLocalizations.of(context)!.maxHeadersReachedDetail); return; } @@ -807,47 +807,47 @@ class _ServerConnectionPageState extends ConsumerState { String? _validateHeaderKey(String key) { // RFC 7230 compliant header name validation - if (key.isEmpty) return 'Header name cannot be empty'; - if (key.length > 64) return 'Header name too long (max 64 characters)'; + if (key.isEmpty) return AppLocalizations.of(context)!.headerNameEmpty; + if (key.length > 64) return AppLocalizations.of(context)!.headerNameTooLong; // Check for valid characters (RFC 7230: token characters) if (!RegExp(r'^[a-zA-Z0-9!#$&\-^_`|~]+$').hasMatch(key)) { - return 'Invalid header name. Use only letters, numbers, and these symbols: !#\$&-^_`|~'; + return AppLocalizations.of(context)!.headerNameInvalidChars; } // Check for reserved headers that should not be overridden final lowerKey = key.toLowerCase(); final reservedHeaders = { - 'authorization', 'content-type', 'content-length', 'host', + 'authorization', 'content-type', 'content-length', 'host', 'user-agent', 'accept', 'accept-encoding', 'connection', 'transfer-encoding', 'upgrade', 'via', 'warning' }; if (reservedHeaders.contains(lowerKey)) { - return 'Cannot override reserved header "$key"'; + return AppLocalizations.of(context)!.headerNameReserved(key); } return null; } String? _validateHeaderValue(String value) { - if (value.isEmpty) return 'Header value cannot be empty'; - if (value.length > 1024) return 'Header value too long (max 1024 characters)'; + if (value.isEmpty) return AppLocalizations.of(context)!.headerValueEmpty; + if (value.length > 1024) return AppLocalizations.of(context)!.headerValueTooLong; // Check for valid characters (no control characters except tab) for (int i = 0; i < value.length; i++) { final char = value.codeUnitAt(i); // Allow printable ASCII (32-126) and tab (9) if (char != 9 && (char < 32 || char > 126)) { - return 'Header value contains invalid characters. Use only printable ASCII.'; + return AppLocalizations.of(context)!.headerValueInvalidChars; } } // Check for security-sensitive patterns - if (value.toLowerCase().contains('script') || - value.contains('<') || + if (value.toLowerCase().contains('script') || + value.contains('<') || value.contains('>')) { - return 'Header value appears to contain potentially unsafe content'; + return AppLocalizations.of(context)!.headerValueUnsafe; } return null; diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index ae04311..284e84a 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -404,19 +404,43 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Username or Email'** String get usernameOrEmail; - + /// No description provided for @password. /// /// In en, this message translates to: /// **'Password'** String get password; + /// No description provided for @usernameOrEmailHint. + /// + /// In en, this message translates to: + /// **'Enter your username or email'** + String get usernameOrEmailHint; + + /// No description provided for @passwordHint. + /// + /// In en, this message translates to: + /// **'Enter your password'** + String get passwordHint; + /// No description provided for @signInWithApiKey. /// /// In en, this message translates to: /// **'Sign in with API Key'** String get signInWithApiKey; + /// No description provided for @enterApiKey. + /// + /// In en, this message translates to: + /// **'Enter your API key'** + String get enterApiKey; + + /// No description provided for @signingIn. + /// + /// In en, this message translates to: + /// **'Signing in...'** + String get signingIn; + /// No description provided for @connectToServer. /// /// In en, this message translates to: @@ -483,6 +507,84 @@ abstract class AppLocalizations { /// **'Remove header'** String get removeHeader; + /// No description provided for @advancedSettings. + /// + /// In en, this message translates to: + /// **'Advanced Settings'** + String get advancedSettings; + + /// No description provided for @customHeaders. + /// + /// In en, this message translates to: + /// **'Custom Headers'** + String get customHeaders; + + /// No description provided for @customHeadersDescription. + /// + /// In en, this message translates to: + /// **'Add custom HTTP headers for authentication, API keys, or special server requirements.'** + String get customHeadersDescription; + + /// No description provided for @headerNameEmpty. + /// + /// In en, this message translates to: + /// **'Header name cannot be empty'** + String get headerNameEmpty; + + /// No description provided for @headerNameTooLong. + /// + /// In en, this message translates to: + /// **'Header name too long (max 64 characters)'** + String get headerNameTooLong; + + /// No description provided for @headerNameInvalidChars. + /// + /// In en, this message translates to: + /// **'Invalid header name. Use only letters, numbers, and these symbols: !#\$&-^_`|~'** + String get headerNameInvalidChars; + + /// No description provided for @headerNameReserved. + /// + /// In en, this message translates to: + /// **'Cannot override reserved header "{key}"'** + String headerNameReserved(String key); + + /// No description provided for @headerValueEmpty. + /// + /// In en, this message translates to: + /// **'Header value cannot be empty'** + String get headerValueEmpty; + + /// No description provided for @headerValueTooLong. + /// + /// In en, this message translates to: + /// **'Header value too long (max 1024 characters)'** + String get headerValueTooLong; + + /// No description provided for @headerValueInvalidChars. + /// + /// In en, this message translates to: + /// **'Header value contains invalid characters. Use only printable ASCII.'** + String get headerValueInvalidChars; + + /// No description provided for @headerValueUnsafe. + /// + /// In en, this message translates to: + /// **'Header value appears to contain potentially unsafe content'** + String get headerValueUnsafe; + + /// No description provided for @headerAlreadyExists. + /// + /// In en, this message translates to: + /// **'Header "{key}" already exists. Remove it first to update.'** + String headerAlreadyExists(String key); + + /// No description provided for @maxHeadersReachedDetail. + /// + /// In en, this message translates to: + /// **'Maximum of 10 custom headers allowed. Remove some to add more.'** + String get maxHeadersReachedDetail; + /// No description provided for @connecting. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index d53df83..fa48259 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -177,9 +177,21 @@ class AppLocalizationsDe extends AppLocalizations { @override String get password => 'Passwort'; + @override + String get usernameOrEmailHint => 'Gib deinen Benutzernamen oder deine E‑Mail ein'; + + @override + String get passwordHint => 'Gib dein Passwort ein'; + @override String get signInWithApiKey => 'Mit API-Schlüssel anmelden'; + @override + String get enterApiKey => 'Gib deinen API-Schlüssel ein'; + + @override + String get signingIn => 'Anmeldung läuft...'; + @override String get connectToServer => 'Mit Server verbinden'; @@ -213,6 +225,51 @@ class AppLocalizationsDe extends AppLocalizations { @override String get removeHeader => 'Header entfernen'; + @override + String get advancedSettings => 'Erweiterte Einstellungen'; + + @override + String get customHeaders => 'Benutzerdefinierte Header'; + + @override + String get customHeadersDescription => + 'Füge benutzerdefinierte HTTP-Header für Authentifizierung, API-Schlüssel oder spezielle Serveranforderungen hinzu.'; + + @override + String get headerNameEmpty => 'Header-Name darf nicht leer sein'; + + @override + String get headerNameTooLong => 'Header-Name zu lang (max. 64 Zeichen)'; + + @override + String get headerNameInvalidChars => + 'Ungültiger Header-Name. Verwende nur Buchstaben, Zahlen und diese Symbole: !#\$&-^_`|~'; + + @override + String headerNameReserved(String key) => 'Reservierter Header "$key" kann nicht überschrieben werden'; + + @override + String get headerValueEmpty => 'Header-Wert darf nicht leer sein'; + + @override + String get headerValueTooLong => 'Header-Wert zu lang (max. 1024 Zeichen)'; + + @override + String get headerValueInvalidChars => + 'Header-Wert enthält ungültige Zeichen. Verwende nur druckbare ASCII-Zeichen.'; + + @override + String get headerValueUnsafe => + 'Header-Wert scheint potenziell unsicheren Inhalt zu enthalten'; + + @override + String headerAlreadyExists(String key) => + 'Header "$key" existiert bereits. Entferne ihn zuerst, um ihn zu aktualisieren.'; + + @override + String get maxHeadersReachedDetail => + 'Maximal 10 benutzerdefinierte Header erlaubt. Entferne einige, um weitere hinzuzufügen.'; + @override String get connecting => 'Verbindung wird hergestellt...'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index e5cc131..cd5a0b5 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -177,9 +177,21 @@ class AppLocalizationsEn extends AppLocalizations { @override String get password => 'Password'; + @override + String get usernameOrEmailHint => 'Enter your username or email'; + + @override + String get passwordHint => 'Enter your password'; + @override String get signInWithApiKey => 'Sign in with API Key'; + @override + String get enterApiKey => 'Enter your API key'; + + @override + String get signingIn => 'Signing in...'; + @override String get connectToServer => 'Connect to Server'; @@ -213,6 +225,51 @@ class AppLocalizationsEn extends AppLocalizations { @override String get removeHeader => 'Remove header'; + @override + String get advancedSettings => 'Advanced Settings'; + + @override + String get customHeaders => 'Custom Headers'; + + @override + String get customHeadersDescription => + 'Add custom HTTP headers for authentication, API keys, or special server requirements.'; + + @override + String get headerNameEmpty => 'Header name cannot be empty'; + + @override + String get headerNameTooLong => 'Header name too long (max 64 characters)'; + + @override + String get headerNameInvalidChars => + 'Invalid header name. Use only letters, numbers, and these symbols: !#\$&-^_`|~'; + + @override + String headerNameReserved(String key) => 'Cannot override reserved header "$key"'; + + @override + String get headerValueEmpty => 'Header value cannot be empty'; + + @override + String get headerValueTooLong => 'Header value too long (max 1024 characters)'; + + @override + String get headerValueInvalidChars => + 'Header value contains invalid characters. Use only printable ASCII.'; + + @override + String get headerValueUnsafe => + 'Header value appears to contain potentially unsafe content'; + + @override + String headerAlreadyExists(String key) => + 'Header "$key" already exists. Remove it first to update.'; + + @override + String get maxHeadersReachedDetail => + 'Maximum of 10 custom headers allowed. Remove some to add more.'; + @override String get connecting => 'Connecting...'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index e40f8fc..185db46 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -177,9 +177,21 @@ class AppLocalizationsFr extends AppLocalizations { @override String get password => 'Mot de passe'; + @override + String get usernameOrEmailHint => 'Entrez votre nom d\'utilisateur ou e‑mail'; + + @override + String get passwordHint => 'Entrez votre mot de passe'; + @override String get signInWithApiKey => 'Se connecter avec une clé API'; + @override + String get enterApiKey => 'Entrez votre clé API'; + + @override + String get signingIn => 'Connexion en cours...'; + @override String get connectToServer => 'Se connecter au serveur'; @@ -213,6 +225,53 @@ class AppLocalizationsFr extends AppLocalizations { @override String get removeHeader => 'Supprimer l\'en-tête'; + @override + String get advancedSettings => 'Paramètres avancés'; + + @override + String get customHeaders => 'En-têtes personnalisés'; + + @override + String get customHeadersDescription => + 'Ajoutez des en-têtes HTTP personnalisés pour l\'authentification, les clés API ou des exigences spécifiques du serveur.'; + + @override + String get headerNameEmpty => 'Le nom de l\'en-tête ne peut pas être vide'; + + @override + String get headerNameTooLong => 'Nom d\'en-tête trop long (max 64 caractères)'; + + @override + String get headerNameInvalidChars => + 'Nom d\'en-tête invalide. Utilisez uniquement des lettres, des chiffres et ces symboles : !#\$&-^_`|~'; + + @override + String headerNameReserved(String key) => + 'Impossible d\'écraser l\'en-tête réservé « $key »'; + + @override + String get headerValueEmpty => 'La valeur de l\'en-tête ne peut pas être vide'; + + @override + String get headerValueTooLong => + 'Valeur d\'en-tête trop longue (max 1024 caractères)'; + + @override + String get headerValueInvalidChars => + 'La valeur de l\'en-tête contient des caractères invalides. Utilisez uniquement des caractères ASCII imprimables.'; + + @override + String get headerValueUnsafe => + 'La valeur de l\'en-tête semble contenir du contenu potentiellement dangereux'; + + @override + String headerAlreadyExists(String key) => + 'L\'en-tête « $key » existe déjà. Supprimez-le d\'abord pour le modifier.'; + + @override + String get maxHeadersReachedDetail => + 'Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter.'; + @override String get connecting => 'Connexion en cours...'; diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index ed0db42..5dd5f6c 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -177,9 +177,21 @@ class AppLocalizationsIt extends AppLocalizations { @override String get password => 'Password'; + @override + String get usernameOrEmailHint => 'Inserisci il tuo username o e‑mail'; + + @override + String get passwordHint => 'Inserisci la password'; + @override String get signInWithApiKey => 'Accedi con chiave API'; + @override + String get enterApiKey => 'Inserisci la tua chiave API'; + + @override + String get signingIn => 'Accesso in corso...'; + @override String get connectToServer => 'Connetti al server'; @@ -213,6 +225,52 @@ class AppLocalizationsIt extends AppLocalizations { @override String get removeHeader => 'Rimuovi header'; + @override + String get advancedSettings => 'Impostazioni avanzate'; + + @override + String get customHeaders => 'Header personalizzati'; + + @override + String get customHeadersDescription => + 'Aggiungi header HTTP personalizzati per autenticazione, chiavi API o requisiti speciali del server.'; + + @override + String get headerNameEmpty => 'Il nome header non può essere vuoto'; + + @override + String get headerNameTooLong => 'Nome header troppo lungo (max 64 caratteri)'; + + @override + String get headerNameInvalidChars => + 'Nome header non valido. Usa solo lettere, numeri e questi simboli: !#\$&-^_`|~'; + + @override + String headerNameReserved(String key) => + 'Impossibile sovrascrivere l\'header riservato "$key"'; + + @override + String get headerValueEmpty => 'Il valore header non può essere vuoto'; + + @override + String get headerValueTooLong => 'Valore header troppo lungo (max 1024 caratteri)'; + + @override + String get headerValueInvalidChars => + 'Il valore header contiene caratteri non validi. Usa solo ASCII stampabile.'; + + @override + String get headerValueUnsafe => + 'Il valore header sembra contenere contenuto potenzialmente non sicuro'; + + @override + String headerAlreadyExists(String key) => + 'L\'header "$key" esiste già. Rimuovilo prima per aggiornarlo.'; + + @override + String get maxHeadersReachedDetail => + 'Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri.'; + @override String get connecting => 'Connessione in corso...';