chore: prepare for weblate
This commit is contained in:
30
.github/workflows/l10n.yml
vendored
Normal file
30
.github/workflows/l10n.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: L10n
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'lib/l10n/*.arb'
|
||||
push:
|
||||
paths:
|
||||
- 'lib/l10n/*.arb'
|
||||
|
||||
jobs:
|
||||
l10n:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
- run: flutter --version
|
||||
- run: flutter pub get
|
||||
- run: flutter pub run build_runner build --delete-conflicting-outputs
|
||||
- name: Generate localizations
|
||||
run: flutter gen-l10n --arb-dir=lib/l10n --output-dir=lib/l10n --template-arb-file=app_en.arb --output-localization-file=app_localizations.dart
|
||||
- name: Analyze
|
||||
run: flutter analyze
|
||||
- name: Verify ARB descriptions
|
||||
run: dart run tool/verify_arb_descriptions.dart
|
||||
- name: Validate ARB locales and placeholders
|
||||
run: dart run tool/validate_arb_locales.dart
|
||||
# Generated files are ignored; no diff check needed.
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -93,6 +93,8 @@ coverage/
|
||||
# Generated files
|
||||
*.g.dart
|
||||
*.freezed.dart
|
||||
lib/l10n/app_localizations.dart
|
||||
lib/l10n/app_localizations_*.dart
|
||||
|
||||
# FVM (Flutter Version Management)
|
||||
.fvm/
|
||||
|
||||
@@ -1,65 +1,63 @@
|
||||
## Localization (i18n)
|
||||
# Localization Guidelines
|
||||
|
||||
- Supported locales: `en`, `de`, `fr`, `it`.
|
||||
- Uses Flutter's `gen_l10n` with ARB files and the `intl` package for date/number formatting.
|
||||
This app uses Flutter's gen-l10n with ARB files in `lib/l10n`.
|
||||
|
||||
### Install & Generate
|
||||
- Source language: `en` (`lib/l10n/app_en.arb`)
|
||||
- Translations: `lib/l10n/app_<lang>.arb` (e.g., `app_de.arb`)
|
||||
- Generated Dart: `lib/l10n/app_localizations*.dart` (generated by Flutter)
|
||||
|
||||
- Install packages:
|
||||
- `flutter_localizations` (Flutter SDK)
|
||||
- `intl: ^0.20.2`
|
||||
- Files are under `lib/l10n/*.arb`. The template is `app_en.arb`.
|
||||
- Generate localizations:
|
||||
- `flutter gen-l10n`
|
||||
- or run a full build: `flutter pub get && flutter gen-l10n`
|
||||
## Adding New Strings
|
||||
|
||||
### Usage Examples
|
||||
1. Edit `lib/l10n/app_en.arb` and add a key with a clear description meta entry.
|
||||
- Example:
|
||||
```json
|
||||
"greeting": "Hello, {name}!",
|
||||
"@greeting": {
|
||||
"description": "Friendly greeting with user name.",
|
||||
"placeholders": { "name": { "type": "String", "example": "Alex" } }
|
||||
}
|
||||
```
|
||||
2. Run `flutter gen-l10n` or just `flutter run` to regenerate localizations.
|
||||
3. Use it in code: `AppLocalizations.of(context)!.greeting(name)`.
|
||||
|
||||
- Basic text:
|
||||
- `Text(AppLocalizations.of(context)!.appTitle)`
|
||||
- With placeholder:
|
||||
- `Text(AppLocalizations.of(context)!.dynamicContentWithPlaceholder('Alex'))`
|
||||
- Pluralization:
|
||||
- `Text(AppLocalizations.of(context)!.itemsCount(3))`
|
||||
- Date/time formatting:
|
||||
- `final dateText = DateFormat.yMMMMEEEEd(Localizations.localeOf(context).toString()).format(DateTime.now());`
|
||||
- `Text(dateText)`
|
||||
- Number formatting:
|
||||
- `final price = NumberFormat.currency(locale: Localizations.localeOf(context).toString(), symbol: '€').format(1234.56);`
|
||||
- `Text(price)`
|
||||
## Placeholders and ICU
|
||||
|
||||
### Add a New Language
|
||||
- Always declare placeholders under the `@key.placeholders` block with `type` and optional `example`.
|
||||
- Use ICU for plurals/select:
|
||||
```json
|
||||
"itemsCount": "{count, plural, =0{No items} one{1 item} other{{count} items}}",
|
||||
"@itemsCount": { "placeholders": { "count": { "type": "int" } } }
|
||||
```
|
||||
|
||||
- Create a new ARB file in `lib/l10n/`, e.g. `app_es.arb`.
|
||||
- Copy keys from `app_en.arb` and provide translated values.
|
||||
- Ensure placeholders and plural rules match the template.
|
||||
- Add the locale to `supportedLocales` in `MaterialApp` (see `lib/main.dart`).
|
||||
- Regenerate: `flutter gen-l10n`.
|
||||
## Punctuation and Style
|
||||
|
||||
### Best Practices
|
||||
- Prefer typographic ellipsis `…` over `...`.
|
||||
- Keep capitalization consistent across locales.
|
||||
- Avoid embedding brand names in placeholders; keep them literal in strings.
|
||||
|
||||
- Key naming: use lowerCamelCase (e.g., `loginButton`, `errorMessage`).
|
||||
- Include `@` metadata with `description` for context and `placeholders` with examples.
|
||||
- Prefer ICU plural/select syntax for quantities and genders.
|
||||
- Avoid concatenating strings at runtime; use placeholders in ARB.
|
||||
## Weblate
|
||||
|
||||
### In‑App Locale Switching
|
||||
This repository includes `weblate.yaml` to help auto-configure Weblate.
|
||||
|
||||
- Open the Profile page → Settings tile → choose `System`, `English`, `Deutsch`, `Français`, or `Italiano`.
|
||||
- Selection persists across app launches.
|
||||
- File mask: `lib/l10n/app_*.arb`
|
||||
- Template: `lib/l10n/app_en.arb`
|
||||
- New language file path: `lib/l10n/app_{language}.arb`
|
||||
- Monolingual: `true`
|
||||
- Base language: `en`
|
||||
|
||||
### Troubleshooting
|
||||
Recommended Weblate add-ons:
|
||||
- “JSON/ARB reformat” to keep formatting stable.
|
||||
- “String freeze” (when preparing releases).
|
||||
- Checks for placeholders to ensure `{name}`, `{count}`, etc. are preserved.
|
||||
|
||||
- Build fails with ARB placeholder errors:
|
||||
- Ensure every placeholder has an example string and correct type.
|
||||
- Missing translation at runtime:
|
||||
- Flutter falls back to English; search for hard‑coded strings and replace with `AppLocalizations`.
|
||||
- iOS strings not changing:
|
||||
- Restart the app after changing system language or use the in‑app language selector.
|
||||
## Generated Files Policy
|
||||
|
||||
### References
|
||||
|
||||
- Flutter localization: https://docs.flutter.dev/ui/accessibility-and-localization/internationalization
|
||||
- Intl package: https://pub.dev/packages/intl
|
||||
- Generated localization Dart files are NOT committed. They are ignored via `.gitignore` and generated during CI/build.
|
||||
- Run `flutter gen-l10n` locally when you need IDE completion, or rely on `flutter run` which generates them automatically.
|
||||
|
||||
## Common Tasks
|
||||
|
||||
- Regenerate after ARB edits:
|
||||
- `flutter gen-l10n --arb-dir=lib/l10n --output-dir=lib/l10n --template-arb-file=app_en.arb --output-localization-file=app_localizations.dart`
|
||||
- Validate:
|
||||
- `flutter analyze`
|
||||
|
||||
10
l10n.yaml
Normal file
10
l10n.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
arb-dir: lib/l10n
|
||||
template-arb-file: app_en.arb
|
||||
output-localization-file: app_localizations.dart
|
||||
output-class: AppLocalizations
|
||||
output-dir: lib/l10n
|
||||
preferred-supported-locales:
|
||||
- en
|
||||
- de
|
||||
- fr
|
||||
- it
|
||||
@@ -1,26 +1,47 @@
|
||||
{
|
||||
"@@locale": "en",
|
||||
"appTitle": "Conduit",
|
||||
"@appTitle": {"description": "Application name displayed in the app and OS UI."},
|
||||
"initializationFailed": "Initialization Failed",
|
||||
"@initializationFailed": {"description": "Shown if the app fails to initialize critical services."},
|
||||
"retry": "Retry",
|
||||
"@retry": {"description": "Button label to try an action again."},
|
||||
"back": "Back",
|
||||
"@back": {"description": "Back navigation label/tooltip."},
|
||||
"you": "You",
|
||||
"@you": {"description": "Profile tab title."},
|
||||
"loadingProfile": "Loading profile...",
|
||||
"@loadingProfile": {"description": "Progress message while fetching profile data."},
|
||||
"unableToLoadProfile": "Unable to load profile",
|
||||
"@unableToLoadProfile": {"description": "Error title shown when profile request fails."},
|
||||
"pleaseCheckConnection": "Please check your connection and try again",
|
||||
"@pleaseCheckConnection": {"description": "Generic connectivity hint after an error."},
|
||||
"account": "Account",
|
||||
"@account": {"description": "Section header for account-related options."},
|
||||
"signOut": "Sign Out",
|
||||
"@signOut": {"description": "Button/title for signing out of the app."},
|
||||
"endYourSession": "End your session",
|
||||
"@endYourSession": {"description": "Subtitle explaining the sign-out action."},
|
||||
"defaultModel": "Default Model",
|
||||
"@defaultModel": {"description": "Label for choosing a default AI model."},
|
||||
"autoSelect": "Auto-select",
|
||||
"@autoSelect": {"description": "Option to let the app pick a suitable model automatically."},
|
||||
"loadingModels": "Loading models...",
|
||||
"@loadingModels": {"description": "Progress message while fetching model list."},
|
||||
"failedToLoadModels": "Failed to load models",
|
||||
"@failedToLoadModels": {"description": "Error message shown when model list cannot be retrieved."},
|
||||
"availableModels": "Available Models",
|
||||
"@availableModels": {"description": "Header above a list of models to select from."},
|
||||
"noResults": "No results",
|
||||
"@noResults": {"description": "Shown when a search returns no matches."},
|
||||
"searchModels": "Search models...",
|
||||
"@searchModels": {"description": "Hint text for model search input."},
|
||||
"errorMessage": "Something went wrong. Please try again.",
|
||||
"@errorMessage": {"description": "Generic error message for unexpected failures."},
|
||||
"loginButton": "Login",
|
||||
"@loginButton": {"description": "Button text for the login action."},
|
||||
"menuItem": "Settings",
|
||||
"@menuItem": {"description": "Generic settings menu item label."},
|
||||
"dynamicContentWithPlaceholder": "Welcome, {name}!",
|
||||
"@dynamicContentWithPlaceholder": {
|
||||
"description": "Greeting message with a dynamic user name.",
|
||||
@@ -42,242 +63,459 @@
|
||||
}
|
||||
},
|
||||
"closeButtonSemantic": "Close",
|
||||
"@closeButtonSemantic": {"description": "Accessible label for a generic Close button."},
|
||||
"loadingContent": "Loading content",
|
||||
"@loadingContent": {"description": "Shown while loading page content."},
|
||||
"noItems": "No items",
|
||||
"@noItems": {"description": "Placeholder text when a list is empty."},
|
||||
"noItemsToDisplay": "No items to display",
|
||||
"@noItemsToDisplay": {"description": "Alternative empty-state description."},
|
||||
"loadMore": "Load More",
|
||||
"@loadMore": {"description": "Button label to load additional items in a paged list."},
|
||||
"workspace": "Workspace",
|
||||
"@workspace": {"description": "Section/tab label for documents and files."},
|
||||
"recentFiles": "Recent Files",
|
||||
"@recentFiles": {"description": "Header for recently accessed files."},
|
||||
"knowledgeBase": "Knowledge Base",
|
||||
"@knowledgeBase": {"description": "Section for knowledge base content."},
|
||||
"noFilesYet": "No files yet",
|
||||
"@noFilesYet": {"description": "Empty state when no files are present."},
|
||||
"uploadDocsPrompt": "Upload documents to reference in your conversations with Conduit",
|
||||
"@uploadDocsPrompt": {"description": "Prompt encouraging users to upload documents."},
|
||||
"uploadFirstFile": "Upload your first file",
|
||||
"@uploadFirstFile": {"description": "CTA to add the first file."},
|
||||
"knowledgeBaseEmpty": "Knowledge base is empty",
|
||||
"@knowledgeBaseEmpty": {"description": "Empty state title for the knowledge base section."},
|
||||
"createCollectionsPrompt": "Create collections of related documents for easy reference",
|
||||
"@createCollectionsPrompt": {"description": "Prompt describing the benefit of creating collections."},
|
||||
"chooseSourcePhoto": "Choose your source",
|
||||
"@chooseSourcePhoto": {"description": "Sheet title to pick camera or photo library."},
|
||||
"takePhoto": "Take a photo",
|
||||
"@takePhoto": {"description": "Action to open camera and capture a new photo."},
|
||||
"chooseFromGallery": "Choose from your photos",
|
||||
"@chooseFromGallery": {"description": "Action to pick an existing photo from library."},
|
||||
"document": "Document",
|
||||
"@document": {"description": "Generic document label used in UI."},
|
||||
"documentHint": "PDF, Word, or text file",
|
||||
"@documentHint": {"description": "Helper hint listing supported document types."},
|
||||
"uploadFileTitle": "Upload File",
|
||||
"@uploadFileTitle": {"description": "Dialog/sheet title for file upload."},
|
||||
"fileUploadComingSoon": "File upload for {type} is coming soon!",
|
||||
"@fileUploadComingSoon": {
|
||||
"placeholders": {"type": {"type": "String", "example": "gallery"}},
|
||||
"description": "Temporary message for upcoming upload feature by type"
|
||||
},
|
||||
"kbCreationComingSoon": "Knowledge base creation is coming soon!",
|
||||
"@kbCreationComingSoon": {"description": "Temporary message indicating KB creation feature is not yet available."},
|
||||
"backToServerSetup": "Back to server setup",
|
||||
"@backToServerSetup": {"description": "Button/back label to return to server configuration flow."},
|
||||
"connectedToServer": "Connected to Server",
|
||||
"@connectedToServer": {"description": "Status label indicating a successful server connection."},
|
||||
"signIn": "Sign In",
|
||||
"@signIn": {"description": "Button/heading for sign-in flows."},
|
||||
"enterCredentials": "Enter your credentials to access your AI conversations",
|
||||
"@enterCredentials": {"description": "Instructional text on the sign-in screen."},
|
||||
"credentials": "Credentials",
|
||||
"@credentials": {"description": "Header for credential input section."},
|
||||
"apiKey": "API Key",
|
||||
"@apiKey": {"description": "Label for API key input field."},
|
||||
"usernameOrEmail": "Username or Email",
|
||||
"@usernameOrEmail": {"description": "Label for username/email input field."},
|
||||
"password": "Password",
|
||||
"@password": {"description": "Label for password input field."},
|
||||
"signInWithApiKey": "Sign in with API Key",
|
||||
"@signInWithApiKey": {"description": "Alternative sign-in method using an API key."},
|
||||
"connectToServer": "Connect to Server",
|
||||
"@connectToServer": {"description": "Call-to-action button for server connection."},
|
||||
"enterServerAddress": "Enter your Open-WebUI server address to get started",
|
||||
"@enterServerAddress": {"description": "Instruction telling user to provide server URL to begin."},
|
||||
"serverUrl": "Server URL",
|
||||
"@serverUrl": {"description": "Label for server URL field."},
|
||||
"serverUrlHint": "https://your-server.com",
|
||||
"@serverUrlHint": {"description": "Hint text showing example server URL format."},
|
||||
"enterServerUrlSemantic": "Enter your server URL or IP address",
|
||||
"@enterServerUrlSemantic": {"description": "Semantic/ARIA label instructing to enter server URL or IP."},
|
||||
"headerName": "Header Name",
|
||||
"@headerName": {"description": "Label for custom header key."},
|
||||
"headerValue": "Header Value",
|
||||
"@headerValue": {"description": "Label for custom header value."},
|
||||
"headerValueHint": "api-key-123 or Bearer token",
|
||||
"@headerValueHint": {"description": "Hint text with example header values, including API key or Bearer token."},
|
||||
"addHeader": "Add header",
|
||||
"@addHeader": {"description": "Button to add a new custom header row."},
|
||||
"maximumHeadersReached": "Maximum headers reached",
|
||||
"@maximumHeadersReached": {"description": "Warning when custom header limit is reached."},
|
||||
"removeHeader": "Remove header",
|
||||
"@removeHeader": {"description": "Action to remove a custom header row."},
|
||||
"connecting": "Connecting...",
|
||||
"@connecting": {"description": "Status while attempting to connect to server."},
|
||||
"connectToServerButton": "Connect to Server",
|
||||
"@connectToServerButton": {"description": "Primary action button to initiate server connection."},
|
||||
"demoModeActive": "Demo Mode Active",
|
||||
"@demoModeActive": {"description": "Banner/text indicating the app runs in demo mode."},
|
||||
"skipServerSetupTryDemo": "Skip server setup and try the demo",
|
||||
"@skipServerSetupTryDemo": {"description": "CTA to bypass server configuration and enter demo mode."},
|
||||
"enterDemo": "Enter Demo",
|
||||
"@enterDemo": {"description": "Button to enter demo mode."},
|
||||
"demoBadge": "Demo",
|
||||
"@demoBadge": {"description": "Small badge label for demo content."},
|
||||
"serverNotOpenWebUI": "This does not appear to be an Open-WebUI server.",
|
||||
"@serverNotOpenWebUI": {"description": "Validation error when the server does not resemble Open-WebUI."},
|
||||
"serverUrlEmpty": "Server URL cannot be empty",
|
||||
"@serverUrlEmpty": {"description": "Validation message for empty server URL."},
|
||||
"invalidUrlFormat": "Invalid URL format. Please check your input.",
|
||||
"@invalidUrlFormat": {"description": "Validation message when URL format is incorrect."},
|
||||
"onlyHttpHttps": "Only HTTP and HTTPS protocols are supported.",
|
||||
"@onlyHttpHttps": {"description": "Validation note restricting protocols to HTTP/HTTPS."},
|
||||
"serverAddressRequired": "Server address is required (e.g., 192.168.1.10 or example.com).",
|
||||
"@serverAddressRequired": {"description": "Validation hint providing examples for server addresses."},
|
||||
"portRange": "Port must be between 1 and 65535.",
|
||||
"@portRange": {"description": "Validation message for allowed port range."},
|
||||
"invalidIpFormat": "Invalid IP address format. Use format like 192.168.1.10.",
|
||||
"@invalidIpFormat": {"description": "Validation message for IP addresses with example."},
|
||||
"couldNotConnectGeneric": "Couldn't connect. Double-check the address and try again.",
|
||||
"@couldNotConnectGeneric": {"description": "Generic failure when connecting to the server."},
|
||||
"weCouldntReachServer": "We couldn't reach the server. Check your connection and that the server is running.",
|
||||
"@weCouldntReachServer": {"description": "Connectivity error with hints to verify server status."},
|
||||
"connectionTimedOut": "Connection timed out. The server might be busy or blocked by a firewall.",
|
||||
"@connectionTimedOut": {"description": "Timeout error while connecting to server."},
|
||||
"useHttpOrHttpsOnly": "Use http:// or https:// only.",
|
||||
"@useHttpOrHttpsOnly": {"description": "Note instructing the user to include protocol in URL."},
|
||||
"loginFailed": "Login failed",
|
||||
"@loginFailed": {"description": "Title for failed login attempts."},
|
||||
"invalidCredentials": "Invalid username or password. Please try again.",
|
||||
"@invalidCredentials": {"description": "Detailed message when authentication fails."},
|
||||
"serverRedirectingHttps": "The server is redirecting requests. Check your server's HTTPS configuration.",
|
||||
"@serverRedirectingHttps": {"description": "Warning about HTTP→HTTPS redirect issues."},
|
||||
"unableToConnectServer": "Unable to connect to server. Please check your connection.",
|
||||
"@unableToConnectServer": {"description": "Generic server connection failure message."},
|
||||
"requestTimedOut": "The request timed out. Please try again.",
|
||||
"@requestTimedOut": {"description": "Timeout while waiting for a server response."},
|
||||
"genericSignInFailed": "We couldn't sign you in. Check your credentials and server settings.",
|
||||
"@genericSignInFailed": {"description": "Fallback sign-in error when no specific cause is known."}
|
||||
,
|
||||
"skip": "Skip",
|
||||
"@skip": {"description": "Onboarding: skip current step."},
|
||||
"next": "Next",
|
||||
"@next": {"description": "Onboarding: go to the next step."},
|
||||
"done": "Done",
|
||||
"@done": {"description": "Onboarding: finish the flow."},
|
||||
"onboardStartTitle": "Start a conversation",
|
||||
"@onboardStartTitle": {"description": "Onboarding card: start chatting title."},
|
||||
"onboardStartSubtitle": "Choose a model, then type below to begin. Tap New Chat anytime.",
|
||||
"@onboardStartSubtitle": {"description": "Onboarding card: brief guidance to begin a chat."},
|
||||
"onboardStartBullet1": "Tap the model name in the top bar to switch models",
|
||||
"@onboardStartBullet1": {"description": "Bullet: how to switch models."},
|
||||
"onboardStartBullet2": "Use New Chat to reset context",
|
||||
"@onboardStartBullet2": {"description": "Bullet: how to reset context."},
|
||||
"onboardAttachTitle": "Add context",
|
||||
"@onboardAttachTitle": {"description": "Onboarding card: attach context title."},
|
||||
"onboardAttachSubtitle": "Ground replies with content from Workspace or photos.",
|
||||
"@onboardAttachSubtitle": {"description": "Onboarding card: why attaching context helps."},
|
||||
"onboardAttachBullet1": "Workspace: PDFs, docs, datasets",
|
||||
"@onboardAttachBullet1": {"description": "Bullet: types of workspace files."},
|
||||
"onboardAttachBullet2": "Photos: camera or library",
|
||||
"@onboardAttachBullet2": {"description": "Bullet: photo sources supported."},
|
||||
"onboardSpeakTitle": "Speak naturally",
|
||||
"@onboardSpeakTitle": {"description": "Onboarding card: voice input title."},
|
||||
"onboardSpeakSubtitle": "Tap the mic to dictate with live waveform feedback.",
|
||||
"@onboardSpeakSubtitle": {"description": "Onboarding card: how voice input works."},
|
||||
"onboardSpeakBullet1": "Stop anytime; partial text is preserved",
|
||||
"@onboardSpeakBullet1": {"description": "Bullet: stop dictation preserves text."},
|
||||
"onboardSpeakBullet2": "Great for quick notes or long prompts",
|
||||
"@onboardSpeakBullet2": {"description": "Bullet: benefits of voice input."},
|
||||
"onboardQuickTitle": "Quick actions",
|
||||
"@onboardQuickTitle": {"description": "Onboarding card: quick actions title."},
|
||||
"onboardQuickSubtitle": "Open the menu to switch between Chats, Workspace, and Profile.",
|
||||
"@onboardQuickSubtitle": {"description": "Onboarding card: how to use the app menu."},
|
||||
"onboardQuickBullet1": "Tap the menu to access Chats, Workspace, Profile",
|
||||
"onboardQuickBullet2": "Start New Chat or manage models from the top bar"
|
||||
"@onboardQuickBullet1": {"description": "Bullet: menu access to sections."},
|
||||
"onboardQuickBullet2": "Start New Chat or manage models from the top bar",
|
||||
"@onboardQuickBullet2": {"description": "Bullet: actions available in the top bar."}
|
||||
,
|
||||
"addAttachment": "Add attachment",
|
||||
"@addAttachment": {"description": "Button to add an attachment (file/photo)."},
|
||||
"tools": "Tools",
|
||||
"@tools": {"description": "Header for a tools/actions section."},
|
||||
"voiceInput": "Voice input",
|
||||
"@voiceInput": {"description": "Label for voice input feature."},
|
||||
"messageInputLabel": "Message input",
|
||||
"@messageInputLabel": {"description": "Accessibility label for the message input."},
|
||||
"messageInputHint": "Type your message",
|
||||
"@messageInputHint": {"description": "Hint shown in the message input field."},
|
||||
"messageHintText": "Message...",
|
||||
"@messageHintText": {"description": "Short placeholder text in the message input."},
|
||||
"stopGenerating": "Stop generating",
|
||||
"@stopGenerating": {"description": "Action to stop the assistant's response generation."},
|
||||
"send": "Send",
|
||||
"@send": {"description": "Primary action to send a message."},
|
||||
"sendMessage": "Send message",
|
||||
"@sendMessage": {"description": "Semantic label for sending a message."},
|
||||
"file": "File",
|
||||
"@file": {"description": "A file item or attachment type label."},
|
||||
"photo": "Photo",
|
||||
"@photo": {"description": "A photo item or attachment type label."},
|
||||
"camera": "Camera",
|
||||
"@camera": {"description": "Camera source label."},
|
||||
"apiUnavailable": "API service not available",
|
||||
"@apiUnavailable": {"description": "Shown when backend API service is unavailable."},
|
||||
"unableToLoadImage": "Unable to load image",
|
||||
"@unableToLoadImage": {"description": "General failure to load an image."},
|
||||
"notAnImageFile": "Not an image file: {fileName}",
|
||||
"@notAnImageFile": {"placeholders": {"fileName": {"type": "String", "example": "image.txt"}}},
|
||||
"@notAnImageFile": {
|
||||
"description": "Error when a referenced file is not an image.",
|
||||
"placeholders": {"fileName": {"type": "String", "example": "image.txt"}}
|
||||
},
|
||||
"failedToLoadImage": "Failed to load image: {error}",
|
||||
"@failedToLoadImage": {"placeholders": {"error": {"type": "String", "example": "Network error"}}},
|
||||
"@failedToLoadImage": {
|
||||
"description": "Error including the underlying reason when image loading fails.",
|
||||
"placeholders": {"error": {"type": "String", "example": "Network error"}}
|
||||
},
|
||||
"invalidDataUrl": "Invalid data URL format",
|
||||
"@invalidDataUrl": {"description": "Error for malformed data: URLs."},
|
||||
"failedToDecodeImage": "Failed to decode image",
|
||||
"@failedToDecodeImage": {"description": "Error when decoding image bytes/base64."},
|
||||
"invalidImageFormat": "Invalid image format",
|
||||
"emptyImageData": "Empty image data"
|
||||
"@invalidImageFormat": {"description": "Error when image type/format is not supported."},
|
||||
"emptyImageData": "Empty image data",
|
||||
"@emptyImageData": {"description": "Error when image data buffer is empty."}
|
||||
,
|
||||
"offlineBanner": "You're offline. Some features may be limited.",
|
||||
"@offlineBanner": {"description": "Banner warning when device is offline."},
|
||||
"featureRequiresInternet": "This feature requires an internet connection",
|
||||
"@featureRequiresInternet": {"description": "Informational text explaining internet requirement."},
|
||||
"messagesWillSendWhenOnline": "Messages will be sent when you're back online",
|
||||
"@messagesWillSendWhenOnline": {"description": "Queue behavior notice while offline."},
|
||||
"confirm": "Confirm",
|
||||
"cancel": "Cancel"
|
||||
"@confirm": {"description": "Confirmation button label."},
|
||||
"cancel": "Cancel",
|
||||
"@cancel": {"description": "Cancel button label."}
|
||||
,
|
||||
"ok": "OK",
|
||||
"@ok": {"description": "Generic OK button label."},
|
||||
"inputField": "Input field",
|
||||
"@inputField": {"description": "Accessibility label describing an input field."},
|
||||
"captureDocumentOrImage": "Capture a document or image",
|
||||
"@captureDocumentOrImage": {"description": "Action to capture a document or image using camera."},
|
||||
"checkConnection": "Check Connection",
|
||||
"@checkConnection": {"description": "CTA to verify network connectivity."},
|
||||
"openSettings": "Open Settings",
|
||||
"@openSettings": {"description": "CTA to open device or app settings."},
|
||||
"chooseDifferentFile": "Choose Different File",
|
||||
"@chooseDifferentFile": {"description": "CTA to pick an alternative file."},
|
||||
"goBack": "Go Back",
|
||||
"@goBack": {"description": "CTA to navigate back."},
|
||||
"technicalDetails": "Technical Details",
|
||||
"@technicalDetails": {"description": "Expandable section label to show error details or logs."},
|
||||
"save": "Save",
|
||||
"@save": {"description": "Primary action to save changes."},
|
||||
"chooseModel": "Choose Model",
|
||||
"@chooseModel": {"description": "Button/label to choose a model."},
|
||||
"reviewerMode": "REVIEWER MODE",
|
||||
"@reviewerMode": {"description": "Developer/reviewer mode indicator."},
|
||||
"selectLanguage": "Select Language",
|
||||
"@selectLanguage": {"description": "Dialog title to pick application language."},
|
||||
"newFolder": "New Folder",
|
||||
"@newFolder": {"description": "Action to create a new folder."},
|
||||
"folderName": "Folder name",
|
||||
"@folderName": {"description": "Label for entering a folder's name."},
|
||||
"newChat": "New Chat",
|
||||
"@newChat": {"description": "Action to start a new chat."},
|
||||
"more": "More",
|
||||
"@more": {"description": "Opens additional actions or content."},
|
||||
"clear": "Clear",
|
||||
"@clear": {"description": "Action to clear input or selection."},
|
||||
"searchHint": "Search...",
|
||||
"@searchHint": {"description": "Generic search input hint."},
|
||||
"searchConversations": "Search conversations...",
|
||||
"@searchConversations": {"description": "Search input hint scoped to conversations."},
|
||||
"create": "Create",
|
||||
"@create": {"description": "Primary action to create a resource."},
|
||||
"folderCreated": "Folder created",
|
||||
"@folderCreated": {"description": "Toast/notice after successfully creating a folder."},
|
||||
"failedToCreateFolder": "Failed to create folder",
|
||||
"@failedToCreateFolder": {"description": "Error notice when folder creation fails."},
|
||||
"movedChatToFolder": "Moved \"{title}\" to \"{folder}\"",
|
||||
"@movedChatToFolder": {
|
||||
"description": "Toast indicating a chat titled {title} was moved to folder {folder}.",
|
||||
"placeholders": {
|
||||
"title": {"type": "String"},
|
||||
"folder": {"type": "String"}
|
||||
}
|
||||
},
|
||||
"failedToMoveChat": "Failed to move chat",
|
||||
"@failedToMoveChat": {"description": "Error notice when moving a chat fails."},
|
||||
"failedToLoadChats": "Failed to load chats",
|
||||
"@failedToLoadChats": {"description": "Error notice when fetching chat list fails."},
|
||||
"failedToUpdatePin": "Failed to update pin",
|
||||
"@failedToUpdatePin": {"description": "Error notice when updating pin star/flag fails."},
|
||||
"failedToDeleteChat": "Failed to delete chat",
|
||||
"@failedToDeleteChat": {"description": "Error notice when deleting a chat fails."},
|
||||
"manage": "Manage",
|
||||
"@manage": {"description": "Context action to manage an item."},
|
||||
"rename": "Rename",
|
||||
"@rename": {"description": "Context action to rename an item."},
|
||||
"delete": "Delete",
|
||||
"@delete": {"description": "Context action to delete an item."},
|
||||
"renameChat": "Rename Chat",
|
||||
"@renameChat": {"description": "Dialog title to rename a chat."},
|
||||
"enterChatName": "Enter chat name",
|
||||
"@enterChatName": {"description": "Input hint/label for new chat name."},
|
||||
"failedToRenameChat": "Failed to rename chat",
|
||||
"@failedToRenameChat": {"description": "Error notice when renaming chat fails."},
|
||||
"failedToUpdateArchive": "Failed to update archive",
|
||||
"@failedToUpdateArchive": {"description": "Error notice when archiving/unarchiving fails."},
|
||||
"unarchive": "Unarchive",
|
||||
"@unarchive": {"description": "Action to unarchive an item."},
|
||||
"archive": "Archive",
|
||||
"@archive": {"description": "Action to archive an item."},
|
||||
"pin": "Pin",
|
||||
"@pin": {"description": "Action to pin/star an item."},
|
||||
"unpin": "Unpin",
|
||||
"@unpin": {"description": "Action to remove pin from an item."},
|
||||
"recent": "Recent",
|
||||
"@recent": {"description": "List filter for recently used items."},
|
||||
"system": "System",
|
||||
"@system": {"description": "Option indicating the device/system default."},
|
||||
"english": "English",
|
||||
"@english": {"description": "Language name: English."},
|
||||
"deutsch": "Deutsch",
|
||||
"@deutsch": {"description": "Language name: German."},
|
||||
"francais": "Français",
|
||||
"@francais": {"description": "Language name: French."},
|
||||
"italiano": "Italiano",
|
||||
"@italiano": {"description": "Language name: Italian."},
|
||||
"deleteMessagesTitle": "Delete Messages",
|
||||
"@deleteMessagesTitle": {"description": "Dialog title asking to confirm deletion of messages."},
|
||||
"deleteMessagesMessage": "Delete {count} messages?",
|
||||
"@deleteMessagesMessage": {
|
||||
"description": "Confirmation prompt asking to delete a number of messages.",
|
||||
"placeholders": {
|
||||
"count": {"type": "int"}
|
||||
}
|
||||
},
|
||||
"routeNotFound": "Route not found: {routeName}",
|
||||
"@routeNotFound": {
|
||||
"description": "Displayed when navigation fails to find a route name.",
|
||||
"placeholders": {
|
||||
"routeName": {"type": "String"}
|
||||
}
|
||||
},
|
||||
"deleteChatTitle": "Delete Chat",
|
||||
"@deleteChatTitle": {"description": "Dialog title asking to confirm deletion of a chat."},
|
||||
"deleteChatMessage": "This chat will be permanently deleted.",
|
||||
"@deleteChatMessage": {"description": "Warning that deleting a chat cannot be undone."},
|
||||
"aboutApp": "About App",
|
||||
"@aboutApp": {"description": "Settings tile title to view app information."},
|
||||
"aboutAppSubtitle": "Conduit information and links",
|
||||
"@aboutAppSubtitle": {"description": "Subtitle/description for the About section."},
|
||||
"typeBelowToBegin": "Type below to begin",
|
||||
"@typeBelowToBegin": {"description": "Hint shown in empty chat input area."},
|
||||
"web": "Web",
|
||||
"@web": {"description": "Tab/section label for web features."},
|
||||
"imageGen": "Image Gen",
|
||||
"@imageGen": {"description": "Short label for image generation section/tab."},
|
||||
"pinned": "Pinned",
|
||||
"@pinned": {"description": "Filter/tab for pinned items."},
|
||||
"folders": "Folders",
|
||||
"@folders": {"description": "Tab listing chat folders."},
|
||||
"archived": "Archived",
|
||||
"@archived": {"description": "Filter/tab for archived chats."},
|
||||
"appLanguage": "App Language",
|
||||
"@appLanguage": {"description": "Label for choosing the app's display language."},
|
||||
"darkMode": "Dark Mode",
|
||||
"@darkMode": {"description": "Label for toggling dark theme."},
|
||||
"webSearch": "Web Search",
|
||||
"@webSearch": {"description": "Feature toggle/section for web search."},
|
||||
"webSearchDescription": "Search the web and cite sources in replies.",
|
||||
"@webSearchDescription": {"description": "Explains that responses can include citations from the web."},
|
||||
"imageGeneration": "Image Generation",
|
||||
"@imageGeneration": {"description": "Feature toggle/section for image generation."},
|
||||
"imageGenerationDescription": "Create images from your prompts.",
|
||||
"@imageGenerationDescription": {"description": "Explains creating images via model prompts."},
|
||||
"copy": "Copy",
|
||||
"@copy": {"description": "Action to copy text to clipboard."},
|
||||
"edit": "Edit",
|
||||
"@edit": {"description": "Action to edit an item/message."},
|
||||
"regenerate": "Regenerate",
|
||||
"noConversationsYet": "No conversations yet"
|
||||
"@regenerate": {"description": "Action to request a new assistant response."},
|
||||
"noConversationsYet": "No conversations yet",
|
||||
"@noConversationsYet": {"description": "Empty state when the user has no chats."}
|
||||
,
|
||||
"usernameOrEmailHint": "Enter your username or email",
|
||||
"@usernameOrEmailHint": {"description": "Hint text for username/email input."},
|
||||
"passwordHint": "Enter your password",
|
||||
"@passwordHint": {"description": "Hint text for password input."},
|
||||
"enterApiKey": "Enter your API key",
|
||||
"@enterApiKey": {"description": "Hint text for API key input."},
|
||||
"signingIn": "Signing in...",
|
||||
"@signingIn": {"description": "Status message shown while signing in."},
|
||||
"advancedSettings": "Advanced Settings",
|
||||
"@advancedSettings": {"description": "Section that contains additional/optional configuration."},
|
||||
"customHeaders": "Custom Headers",
|
||||
"@customHeaders": {"description": "Section title for adding custom HTTP headers."},
|
||||
"customHeadersDescription": "Add custom HTTP headers for authentication, API keys, or special server requirements.",
|
||||
"@customHeadersDescription": {"description": "Helper text explaining use-cases for custom headers."},
|
||||
"headerNameEmpty": "Header name cannot be empty",
|
||||
"@headerNameEmpty": {"description": "Validation message for empty header name."},
|
||||
"headerNameTooLong": "Header name too long (max 64 characters)",
|
||||
"@headerNameTooLong": {"description": "Validation message for header name length."},
|
||||
"headerNameInvalidChars": "Invalid header name. Use only letters, numbers, and these symbols: !#$&-^_`|~",
|
||||
"@headerNameInvalidChars": {"description": "Validation message for invalid characters in header name."},
|
||||
"headerNameReserved": "Cannot override reserved header \"{key}\"",
|
||||
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
|
||||
"@headerNameReserved": {
|
||||
"description": "Error when attempting to override a reserved HTTP header {key}.",
|
||||
"placeholders": {"key": {"type": "String"}}
|
||||
},
|
||||
"headerValueEmpty": "Header value cannot be empty",
|
||||
"@headerValueEmpty": {"description": "Validation message for empty header value."},
|
||||
"headerValueTooLong": "Header value too long (max 1024 characters)",
|
||||
"@headerValueTooLong": {"description": "Validation message for header value length."},
|
||||
"headerValueInvalidChars": "Header value contains invalid characters. Use only printable ASCII.",
|
||||
"@headerValueInvalidChars": {"description": "Validation message for invalid characters in header value."},
|
||||
"headerValueUnsafe": "Header value appears to contain potentially unsafe content",
|
||||
"@headerValueUnsafe": {"description": "Security warning for suspicious header values."},
|
||||
"headerAlreadyExists": "Header \"{key}\" already exists. Remove it first to update.",
|
||||
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
|
||||
"maxHeadersReachedDetail": "Maximum of 10 custom headers allowed. Remove some to add more."
|
||||
"@headerAlreadyExists": {
|
||||
"description": "Error when a custom header with key {key} already exists.",
|
||||
"placeholders": {"key": {"type": "String"}}
|
||||
},
|
||||
"maxHeadersReachedDetail": "Maximum of 10 custom headers allowed. Remove some to add more.",
|
||||
"@maxHeadersReachedDetail": {"description": "Explains the upper limit of custom headers."}
|
||||
,
|
||||
"editMessage": "Edit Message"
|
||||
"editMessage": "Edit Message",
|
||||
"@editMessage": {"description": "Action to edit a previously sent message."}
|
||||
,
|
||||
"noModelsAvailable": "No models available",
|
||||
"@noModelsAvailable": {"description": "Shown when model list is empty or failed to load."},
|
||||
"followingSystem": "Following system: {theme}",
|
||||
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
|
||||
"@followingSystem": {
|
||||
"description": "Indicates the app is following the system theme (\"Dark\"/\"Light\").",
|
||||
"placeholders": {"theme": {"type": "String"}}
|
||||
},
|
||||
"themeDark": "Dark",
|
||||
"@themeDark": {"description": "Theme label for dark appearance."},
|
||||
"themeLight": "Light",
|
||||
"@themeLight": {"description": "Theme label for light appearance."},
|
||||
"currentlyUsingDarkTheme": "Currently using Dark theme",
|
||||
"@currentlyUsingDarkTheme": {"description": "Status text indicating dark theme is active."},
|
||||
"currentlyUsingLightTheme": "Currently using Light theme",
|
||||
"@currentlyUsingLightTheme": {"description": "Status text indicating light theme is active."},
|
||||
"aboutConduit": "About Conduit",
|
||||
"@aboutConduit": {"description": "Dialog title for app information."},
|
||||
"versionLabel": "Version: {version} ({build})",
|
||||
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
|
||||
"@versionLabel": {
|
||||
"description": "Displays version and build number in the About dialog.",
|
||||
"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}
|
||||
},
|
||||
"githubRepository": "GitHub Repository",
|
||||
"@githubRepository": {"description": "Link label pointing to the app repository."},
|
||||
"unableToLoadAppInfo": "Unable to load app info",
|
||||
"@unableToLoadAppInfo": {"description": "Error text when package info cannot be retrieved."},
|
||||
"thinking": "Thinking…",
|
||||
"@thinking": {"description": "Label shown while the assistant is reasoning."},
|
||||
"thoughts": "Thoughts",
|
||||
"@thoughts": {"description": "Section title for showing reasoning content."},
|
||||
"thoughtForDuration": "Thought for {duration}",
|
||||
"@thoughtForDuration": {
|
||||
"description": "Shows how long the assistant thought before replying.",
|
||||
@@ -285,16 +523,30 @@
|
||||
}
|
||||
,
|
||||
"appCustomization": "App Customization",
|
||||
"@appCustomization": {"description": "Title of the customization settings page."},
|
||||
"appCustomizationSubtitle": "Personalize how names and UI display",
|
||||
"@appCustomizationSubtitle": {"description": "Subtitle shown under App Customization tile and page header."},
|
||||
"display": "Display",
|
||||
"@display": {"description": "Section header for visual and layout related settings."},
|
||||
"realtime": "Realtime",
|
||||
"@realtime": {"description": "Section header for realtime/transport settings."},
|
||||
"hideProviderInModelNames": "Hide provider in model names",
|
||||
"@hideProviderInModelNames": {"description": "Toggle label to hide the provider prefix in model names (e.g., show gpt-4o instead of openai/gpt-4o)."},
|
||||
"hideProviderInModelNamesDescription": "Show names like \"gpt-4o\" instead of \"openai/gpt-4o\".",
|
||||
"@hideProviderInModelNamesDescription": {"description": "Helper text for provider hiding toggle."},
|
||||
"transportMode": "Transport mode",
|
||||
"@transportMode": {"description": "Title for selecting the networking transport used for realtime."},
|
||||
"transportModeDescription": "Choose how the app connects for realtime updates.",
|
||||
"@transportModeDescription": {"description": "Helper text explaining the transport setting."},
|
||||
"mode": "Mode",
|
||||
"@mode": {"description": "Form field label for transport mode dropdown."},
|
||||
"transportModeAuto": "Auto (Polling + WebSocket)",
|
||||
"@transportModeAuto": {"description": "Dropdown option label for automatic transport selection."},
|
||||
"transportModeWs": "WebSocket only",
|
||||
"@transportModeWs": {"description": "Dropdown option label for WebSocket-only transport."},
|
||||
"transportModeAutoInfo": "More robust on restrictive networks. Upgrades to WebSocket when possible.",
|
||||
"@transportModeAutoInfo": {"description": "Footnote text for the Auto transport mode."},
|
||||
"transportModeWsInfo": "Lower overhead, but may fail behind strict proxies/firewalls."
|
||||
,
|
||||
"@transportModeWsInfo": {"description": "Footnote text for the WebSocket-only transport mode."}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get unableToLoadProfile => 'Profil konnte nicht geladen werden';
|
||||
|
||||
@override
|
||||
String get pleaseCheckConnection => 'Bitte überprüfe deine Verbindung und versuche es erneut';
|
||||
String get pleaseCheckConnection =>
|
||||
'Bitte überprüfe deine Verbindung und versuche es erneut';
|
||||
|
||||
@override
|
||||
String get account => 'Konto';
|
||||
@@ -63,7 +64,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get searchModels => 'Modelle suchen...';
|
||||
|
||||
@override
|
||||
String get errorMessage => 'Etwas ist schief gelaufen. Bitte versuche es erneut.';
|
||||
String get errorMessage =>
|
||||
'Etwas ist schief gelaufen. Bitte versuche es erneut.';
|
||||
|
||||
@override
|
||||
String get loginButton => 'Anmelden';
|
||||
@@ -116,7 +118,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get noFilesYet => 'Noch keine Dateien';
|
||||
|
||||
@override
|
||||
String get uploadDocsPrompt => 'Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden';
|
||||
String get uploadDocsPrompt =>
|
||||
'Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden';
|
||||
|
||||
@override
|
||||
String get uploadFirstFile => 'Erste Datei hochladen';
|
||||
@@ -125,7 +128,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get knowledgeBaseEmpty => 'Wissensdatenbank ist leer';
|
||||
|
||||
@override
|
||||
String get createCollectionsPrompt => 'Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz';
|
||||
String get createCollectionsPrompt =>
|
||||
'Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz';
|
||||
|
||||
@override
|
||||
String get chooseSourcePhoto => 'Quelle auswählen';
|
||||
@@ -151,7 +155,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get kbCreationComingSoon => 'Erstellung der Wissensdatenbank kommt bald!';
|
||||
String get kbCreationComingSoon =>
|
||||
'Erstellung der Wissensdatenbank kommt bald!';
|
||||
|
||||
@override
|
||||
String get backToServerSetup => 'Zur Servereinrichtung zurück';
|
||||
@@ -163,7 +168,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get signIn => 'Anmelden';
|
||||
|
||||
@override
|
||||
String get enterCredentials => 'Gib deine Anmeldedaten ein, um auf deine KI-Unterhaltungen zuzugreifen';
|
||||
String get enterCredentials =>
|
||||
'Gib deine Anmeldedaten ein, um auf deine KI-Unterhaltungen zuzugreifen';
|
||||
|
||||
@override
|
||||
String get credentials => 'Zugangsdaten';
|
||||
@@ -184,7 +190,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get connectToServer => 'Mit Server verbinden';
|
||||
|
||||
@override
|
||||
String get enterServerAddress => 'Gib die Adresse deines Open-WebUI-Servers ein, um zu beginnen';
|
||||
String get enterServerAddress =>
|
||||
'Gib die Adresse deines Open-WebUI-Servers ein, um zu beginnen';
|
||||
|
||||
@override
|
||||
String get serverUrl => 'Server-URL';
|
||||
@@ -193,7 +200,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get serverUrlHint => 'https://dein-server.com';
|
||||
|
||||
@override
|
||||
String get enterServerUrlSemantic => 'Gib deine Server-URL oder IP-Adresse ein';
|
||||
String get enterServerUrlSemantic =>
|
||||
'Gib deine Server-URL oder IP-Adresse ein';
|
||||
|
||||
@override
|
||||
String get headerName => 'Header-Name';
|
||||
@@ -223,7 +231,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get demoModeActive => 'Demo-Modus aktiv';
|
||||
|
||||
@override
|
||||
String get skipServerSetupTryDemo => 'Servereinrichtung überspringen und Demo testen';
|
||||
String get skipServerSetupTryDemo =>
|
||||
'Servereinrichtung überspringen und Demo testen';
|
||||
|
||||
@override
|
||||
String get enterDemo => 'Demo starten';
|
||||
@@ -232,7 +241,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get demoBadge => 'Demo';
|
||||
|
||||
@override
|
||||
String get serverNotOpenWebUI => 'Dies scheint kein Open-WebUI-Server zu sein.';
|
||||
String get serverNotOpenWebUI =>
|
||||
'Dies scheint kein Open-WebUI-Server zu sein.';
|
||||
|
||||
@override
|
||||
String get serverUrlEmpty => 'Server-URL darf nicht leer sein';
|
||||
@@ -241,10 +251,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get invalidUrlFormat => 'Ungültiges URL-Format. Bitte Eingabe prüfen.';
|
||||
|
||||
@override
|
||||
String get onlyHttpHttps => 'Nur HTTP- und HTTPS-Protokolle werden unterstützt.';
|
||||
String get onlyHttpHttps =>
|
||||
'Nur HTTP- und HTTPS-Protokolle werden unterstützt.';
|
||||
|
||||
@override
|
||||
String get serverAddressRequired => 'Serveradresse erforderlich (z. B. 192.168.1.10 oder example.com).';
|
||||
String get serverAddressRequired =>
|
||||
'Serveradresse erforderlich (z. B. 192.168.1.10 oder example.com).';
|
||||
|
||||
@override
|
||||
String get portRange => 'Port muss zwischen 1 und 65535 liegen.';
|
||||
@@ -253,13 +265,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get invalidIpFormat => 'Ungültiges IP-Format. Beispiel: 192.168.1.10.';
|
||||
|
||||
@override
|
||||
String get couldNotConnectGeneric => 'Verbindung fehlgeschlagen. Adresse prüfen und erneut versuchen.';
|
||||
String get couldNotConnectGeneric =>
|
||||
'Verbindung fehlgeschlagen. Adresse prüfen und erneut versuchen.';
|
||||
|
||||
@override
|
||||
String get weCouldntReachServer => 'Server nicht erreichbar. Verbindung und Serverstatus prüfen.';
|
||||
String get weCouldntReachServer =>
|
||||
'Server nicht erreichbar. Verbindung und Serverstatus prüfen.';
|
||||
|
||||
@override
|
||||
String get connectionTimedOut => 'Zeitüberschreitung. Server eventuell ausgelastet oder blockiert.';
|
||||
String get connectionTimedOut =>
|
||||
'Zeitüberschreitung. Server eventuell ausgelastet oder blockiert.';
|
||||
|
||||
@override
|
||||
String get useHttpOrHttpsOnly => 'Nur http:// oder https:// verwenden.';
|
||||
@@ -268,19 +283,23 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get loginFailed => 'Anmeldung fehlgeschlagen';
|
||||
|
||||
@override
|
||||
String get invalidCredentials => 'Ungültiger Benutzername oder Passwort. Bitte erneut versuchen.';
|
||||
String get invalidCredentials =>
|
||||
'Ungültiger Benutzername oder Passwort. Bitte erneut versuchen.';
|
||||
|
||||
@override
|
||||
String get serverRedirectingHttps => 'Server leitet um. HTTPS-Konfiguration prüfen.';
|
||||
String get serverRedirectingHttps =>
|
||||
'Server leitet um. HTTPS-Konfiguration prüfen.';
|
||||
|
||||
@override
|
||||
String get unableToConnectServer => 'Verbindung zum Server nicht möglich. Bitte Verbindung prüfen.';
|
||||
String get unableToConnectServer =>
|
||||
'Verbindung zum Server nicht möglich. Bitte Verbindung prüfen.';
|
||||
|
||||
@override
|
||||
String get requestTimedOut => 'Zeitüberschreitung. Bitte erneut versuchen.';
|
||||
|
||||
@override
|
||||
String get genericSignInFailed => 'Anmeldung nicht möglich. Zugangsdaten und Server prüfen.';
|
||||
String get genericSignInFailed =>
|
||||
'Anmeldung nicht möglich. Zugangsdaten und Server prüfen.';
|
||||
|
||||
@override
|
||||
String get skip => 'Überspringen';
|
||||
@@ -295,7 +314,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get onboardStartTitle => 'Unterhaltung starten';
|
||||
|
||||
@override
|
||||
String get onboardStartSubtitle => 'Wähle ein Modell und tippe los. Tippe jederzeit auf Neuer Chat.';
|
||||
String get onboardStartSubtitle =>
|
||||
'Wähle ein Modell und tippe los. Tippe jederzeit auf Neuer Chat.';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet1 => 'Modellname oben antippen, um zu wechseln';
|
||||
@@ -307,10 +327,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get onboardAttachTitle => 'Kontext hinzufügen';
|
||||
|
||||
@override
|
||||
String get onboardAttachSubtitle => 'Antworten mit Inhalten aus Arbeitsbereich oder Fotos untermauern.';
|
||||
String get onboardAttachSubtitle =>
|
||||
'Antworten mit Inhalten aus Arbeitsbereich oder Fotos untermauern.';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet1 => 'Arbeitsbereich: PDFs, Dokumente, Datensätze';
|
||||
String get onboardAttachBullet1 =>
|
||||
'Arbeitsbereich: PDFs, Dokumente, Datensätze';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet2 => 'Fotos: Kamera oder Bibliothek';
|
||||
@@ -325,19 +347,23 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get onboardSpeakBullet1 => 'Jederzeit stoppen; Text bleibt erhalten';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet2 => 'Ideal für kurze Notizen oder lange Prompts';
|
||||
String get onboardSpeakBullet2 =>
|
||||
'Ideal für kurze Notizen oder lange Prompts';
|
||||
|
||||
@override
|
||||
String get onboardQuickTitle => 'Schnellaktionen';
|
||||
|
||||
@override
|
||||
String get onboardQuickSubtitle => 'Menü öffnen, um zwischen Chats, Arbeitsbereich und Profil zu wechseln.';
|
||||
String get onboardQuickSubtitle =>
|
||||
'Menü öffnen, um zwischen Chats, Arbeitsbereich und Profil zu wechseln.';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet1 => 'Menü tippen für Chats, Arbeitsbereich, Profil';
|
||||
String get onboardQuickBullet1 =>
|
||||
'Menü tippen für Chats, Arbeitsbereich, Profil';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet2 => 'Neuer Chat starten oder Modelle oben verwalten';
|
||||
String get onboardQuickBullet2 =>
|
||||
'Neuer Chat starten oder Modelle oben verwalten';
|
||||
|
||||
@override
|
||||
String get addAttachment => 'Anhang hinzufügen';
|
||||
@@ -404,13 +430,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get emptyImageData => 'Leere Bilddaten';
|
||||
|
||||
@override
|
||||
String get offlineBanner => 'Du bist offline. Einige Funktionen sind eingeschränkt.';
|
||||
String get offlineBanner =>
|
||||
'Du bist offline. Einige Funktionen sind eingeschränkt.';
|
||||
|
||||
@override
|
||||
String get featureRequiresInternet => 'Diese Funktion erfordert eine Internetverbindung';
|
||||
String get featureRequiresInternet =>
|
||||
'Diese Funktion erfordert eine Internetverbindung';
|
||||
|
||||
@override
|
||||
String get messagesWillSendWhenOnline => 'Nachrichten werden gesendet, sobald du wieder online bist';
|
||||
String get messagesWillSendWhenOnline =>
|
||||
'Nachrichten werden gesendet, sobald du wieder online bist';
|
||||
|
||||
@override
|
||||
String get confirm => 'Bestätigen';
|
||||
@@ -611,7 +640,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get imageGeneration => 'Bildgenerierung';
|
||||
|
||||
@override
|
||||
String get imageGenerationDescription => 'Bilder aus deinen Prompts erstellen.';
|
||||
String get imageGenerationDescription =>
|
||||
'Bilder aus deinen Prompts erstellen.';
|
||||
|
||||
@override
|
||||
String get copy => 'Kopieren';
|
||||
@@ -626,7 +656,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get noConversationsYet => 'Noch keine Unterhaltungen';
|
||||
|
||||
@override
|
||||
String get usernameOrEmailHint => 'Gib deinen Benutzernamen oder deine E‑Mail ein';
|
||||
String get usernameOrEmailHint =>
|
||||
'Gib deinen Benutzernamen oder deine E‑Mail ein';
|
||||
|
||||
@override
|
||||
String get passwordHint => 'Gib dein Passwort ein';
|
||||
@@ -644,7 +675,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get customHeaders => 'Benutzerdefinierte Header';
|
||||
|
||||
@override
|
||||
String get customHeadersDescription => 'Füge benutzerdefinierte HTTP-Header für Authentifizierung, API-Schlüssel oder spezielle Serveranforderungen hinzu.';
|
||||
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';
|
||||
@@ -653,7 +685,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get headerNameTooLong => 'Header-Name zu lang (max. 64 Zeichen)';
|
||||
|
||||
@override
|
||||
String get headerNameInvalidChars => 'Ungültiger Header-Name. Verwende nur Buchstaben, Zahlen und diese Zeichen: !#\$&-^_`|~';
|
||||
String get headerNameInvalidChars =>
|
||||
'Ungültiger Header-Name. Verwende nur Buchstaben, Zahlen und diese Zeichen: !#\$&-^_`|~';
|
||||
|
||||
@override
|
||||
String headerNameReserved(String key) {
|
||||
@@ -667,10 +700,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get headerValueTooLong => 'Header-Wert zu lang (max. 1024 Zeichen)';
|
||||
|
||||
@override
|
||||
String get headerValueInvalidChars => 'Header-Wert enthält ungültige Zeichen. Nur druckbare ASCII-Zeichen verwenden.';
|
||||
String get headerValueInvalidChars =>
|
||||
'Header-Wert enthält ungültige Zeichen. Nur druckbare ASCII-Zeichen verwenden.';
|
||||
|
||||
@override
|
||||
String get headerValueUnsafe => 'Header-Wert scheint potenziell unsicheren Inhalt zu enthalten';
|
||||
String get headerValueUnsafe =>
|
||||
'Header-Wert scheint potenziell unsicheren Inhalt zu enthalten';
|
||||
|
||||
@override
|
||||
String headerAlreadyExists(String key) {
|
||||
@@ -678,7 +713,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get maxHeadersReachedDetail => 'Maximal 10 benutzerdefinierte Header zulässig. Einige entfernen, um mehr hinzuzufügen.';
|
||||
String get maxHeadersReachedDetail =>
|
||||
'Maximal 10 benutzerdefinierte Header zulässig. Einige entfernen, um mehr hinzuzufügen.';
|
||||
|
||||
@override
|
||||
String get editMessage => 'Nachricht bearbeiten';
|
||||
@@ -715,7 +751,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get githubRepository => 'GitHub-Repository';
|
||||
|
||||
@override
|
||||
String get unableToLoadAppInfo => 'App-Informationen konnten nicht geladen werden';
|
||||
String get unableToLoadAppInfo =>
|
||||
'App-Informationen konnten nicht geladen werden';
|
||||
|
||||
@override
|
||||
String get thinking => 'Denkt…';
|
||||
@@ -732,7 +769,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get appCustomization => 'App-Anpassung';
|
||||
|
||||
@override
|
||||
String get appCustomizationSubtitle => 'Personalisieren, wie Namen und UI angezeigt werden';
|
||||
String get appCustomizationSubtitle =>
|
||||
'Personalisieren, wie Namen und UI angezeigt werden';
|
||||
|
||||
@override
|
||||
String get display => 'Anzeige';
|
||||
@@ -744,13 +782,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get hideProviderInModelNames => 'Anbieter in Modellnamen ausblenden';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNamesDescription => 'Zeige Namen wie \"gpt-4o\" statt \"openai/gpt-4o\".';
|
||||
String get hideProviderInModelNamesDescription =>
|
||||
'Zeige Namen wie \"gpt-4o\" statt \"openai/gpt-4o\".';
|
||||
|
||||
@override
|
||||
String get transportMode => 'Transportmodus';
|
||||
|
||||
@override
|
||||
String get transportModeDescription => 'Wähle, wie die App für Echtzeit-Updates verbindet.';
|
||||
String get transportModeDescription =>
|
||||
'Wähle, wie die App für Echtzeit-Updates verbindet.';
|
||||
|
||||
@override
|
||||
String get mode => 'Modus';
|
||||
@@ -762,8 +802,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get transportModeWs => 'Nur WebSocket';
|
||||
|
||||
@override
|
||||
String get transportModeAutoInfo => 'Robuster in restriktiven Netzwerken. Wechselt nach Möglichkeit zu WebSocket.';
|
||||
String get transportModeAutoInfo =>
|
||||
'Robuster in restriktiven Netzwerken. Wechselt nach Möglichkeit zu WebSocket.';
|
||||
|
||||
@override
|
||||
String get transportModeWsInfo => 'Geringerer Overhead, kann jedoch hinter strikten Proxys/Firewalls fehlschlagen.';
|
||||
String get transportModeWsInfo =>
|
||||
'Geringerer Overhead, kann jedoch hinter strikten Proxys/Firewalls fehlschlagen.';
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get unableToLoadProfile => 'Unable to load profile';
|
||||
|
||||
@override
|
||||
String get pleaseCheckConnection => 'Please check your connection and try again';
|
||||
String get pleaseCheckConnection =>
|
||||
'Please check your connection and try again';
|
||||
|
||||
@override
|
||||
String get account => 'Account';
|
||||
@@ -116,7 +117,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get noFilesYet => 'No files yet';
|
||||
|
||||
@override
|
||||
String get uploadDocsPrompt => 'Upload documents to reference in your conversations with Conduit';
|
||||
String get uploadDocsPrompt =>
|
||||
'Upload documents to reference in your conversations with Conduit';
|
||||
|
||||
@override
|
||||
String get uploadFirstFile => 'Upload your first file';
|
||||
@@ -125,7 +127,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get knowledgeBaseEmpty => 'Knowledge base is empty';
|
||||
|
||||
@override
|
||||
String get createCollectionsPrompt => 'Create collections of related documents for easy reference';
|
||||
String get createCollectionsPrompt =>
|
||||
'Create collections of related documents for easy reference';
|
||||
|
||||
@override
|
||||
String get chooseSourcePhoto => 'Choose your source';
|
||||
@@ -163,7 +166,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get signIn => 'Sign In';
|
||||
|
||||
@override
|
||||
String get enterCredentials => 'Enter your credentials to access your AI conversations';
|
||||
String get enterCredentials =>
|
||||
'Enter your credentials to access your AI conversations';
|
||||
|
||||
@override
|
||||
String get credentials => 'Credentials';
|
||||
@@ -184,7 +188,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get connectToServer => 'Connect to Server';
|
||||
|
||||
@override
|
||||
String get enterServerAddress => 'Enter your Open-WebUI server address to get started';
|
||||
String get enterServerAddress =>
|
||||
'Enter your Open-WebUI server address to get started';
|
||||
|
||||
@override
|
||||
String get serverUrl => 'Server URL';
|
||||
@@ -232,7 +237,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get demoBadge => 'Demo';
|
||||
|
||||
@override
|
||||
String get serverNotOpenWebUI => 'This does not appear to be an Open-WebUI server.';
|
||||
String get serverNotOpenWebUI =>
|
||||
'This does not appear to be an Open-WebUI server.';
|
||||
|
||||
@override
|
||||
String get serverUrlEmpty => 'Server URL cannot be empty';
|
||||
@@ -244,22 +250,27 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get onlyHttpHttps => 'Only HTTP and HTTPS protocols are supported.';
|
||||
|
||||
@override
|
||||
String get serverAddressRequired => 'Server address is required (e.g., 192.168.1.10 or example.com).';
|
||||
String get serverAddressRequired =>
|
||||
'Server address is required (e.g., 192.168.1.10 or example.com).';
|
||||
|
||||
@override
|
||||
String get portRange => 'Port must be between 1 and 65535.';
|
||||
|
||||
@override
|
||||
String get invalidIpFormat => 'Invalid IP address format. Use format like 192.168.1.10.';
|
||||
String get invalidIpFormat =>
|
||||
'Invalid IP address format. Use format like 192.168.1.10.';
|
||||
|
||||
@override
|
||||
String get couldNotConnectGeneric => 'Couldn\'t connect. Double-check the address and try again.';
|
||||
String get couldNotConnectGeneric =>
|
||||
'Couldn\'t connect. Double-check the address and try again.';
|
||||
|
||||
@override
|
||||
String get weCouldntReachServer => 'We couldn\'t reach the server. Check your connection and that the server is running.';
|
||||
String get weCouldntReachServer =>
|
||||
'We couldn\'t reach the server. Check your connection and that the server is running.';
|
||||
|
||||
@override
|
||||
String get connectionTimedOut => 'Connection timed out. The server might be busy or blocked by a firewall.';
|
||||
String get connectionTimedOut =>
|
||||
'Connection timed out. The server might be busy or blocked by a firewall.';
|
||||
|
||||
@override
|
||||
String get useHttpOrHttpsOnly => 'Use http:// or https:// only.';
|
||||
@@ -268,19 +279,23 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get loginFailed => 'Login failed';
|
||||
|
||||
@override
|
||||
String get invalidCredentials => 'Invalid username or password. Please try again.';
|
||||
String get invalidCredentials =>
|
||||
'Invalid username or password. Please try again.';
|
||||
|
||||
@override
|
||||
String get serverRedirectingHttps => 'The server is redirecting requests. Check your server\'s HTTPS configuration.';
|
||||
String get serverRedirectingHttps =>
|
||||
'The server is redirecting requests. Check your server\'s HTTPS configuration.';
|
||||
|
||||
@override
|
||||
String get unableToConnectServer => 'Unable to connect to server. Please check your connection.';
|
||||
String get unableToConnectServer =>
|
||||
'Unable to connect to server. Please check your connection.';
|
||||
|
||||
@override
|
||||
String get requestTimedOut => 'The request timed out. Please try again.';
|
||||
|
||||
@override
|
||||
String get genericSignInFailed => 'We couldn\'t sign you in. Check your credentials and server settings.';
|
||||
String get genericSignInFailed =>
|
||||
'We couldn\'t sign you in. Check your credentials and server settings.';
|
||||
|
||||
@override
|
||||
String get skip => 'Skip';
|
||||
@@ -295,10 +310,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get onboardStartTitle => 'Start a conversation';
|
||||
|
||||
@override
|
||||
String get onboardStartSubtitle => 'Choose a model, then type below to begin. Tap New Chat anytime.';
|
||||
String get onboardStartSubtitle =>
|
||||
'Choose a model, then type below to begin. Tap New Chat anytime.';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet1 => 'Tap the model name in the top bar to switch models';
|
||||
String get onboardStartBullet1 =>
|
||||
'Tap the model name in the top bar to switch models';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet2 => 'Use New Chat to reset context';
|
||||
@@ -307,7 +324,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get onboardAttachTitle => 'Add context';
|
||||
|
||||
@override
|
||||
String get onboardAttachSubtitle => 'Ground replies with content from Workspace or photos.';
|
||||
String get onboardAttachSubtitle =>
|
||||
'Ground replies with content from Workspace or photos.';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet1 => 'Workspace: PDFs, docs, datasets';
|
||||
@@ -319,7 +337,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get onboardSpeakTitle => 'Speak naturally';
|
||||
|
||||
@override
|
||||
String get onboardSpeakSubtitle => 'Tap the mic to dictate with live waveform feedback.';
|
||||
String get onboardSpeakSubtitle =>
|
||||
'Tap the mic to dictate with live waveform feedback.';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet1 => 'Stop anytime; partial text is preserved';
|
||||
@@ -331,13 +350,16 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get onboardQuickTitle => 'Quick actions';
|
||||
|
||||
@override
|
||||
String get onboardQuickSubtitle => 'Open the menu to switch between Chats, Workspace, and Profile.';
|
||||
String get onboardQuickSubtitle =>
|
||||
'Open the menu to switch between Chats, Workspace, and Profile.';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet1 => 'Tap the menu to access Chats, Workspace, Profile';
|
||||
String get onboardQuickBullet1 =>
|
||||
'Tap the menu to access Chats, Workspace, Profile';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet2 => 'Start New Chat or manage models from the top bar';
|
||||
String get onboardQuickBullet2 =>
|
||||
'Start New Chat or manage models from the top bar';
|
||||
|
||||
@override
|
||||
String get addAttachment => 'Add attachment';
|
||||
@@ -407,10 +429,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get offlineBanner => 'You\'re offline. Some features may be limited.';
|
||||
|
||||
@override
|
||||
String get featureRequiresInternet => 'This feature requires an internet connection';
|
||||
String get featureRequiresInternet =>
|
||||
'This feature requires an internet connection';
|
||||
|
||||
@override
|
||||
String get messagesWillSendWhenOnline => 'Messages will be sent when you\'re back online';
|
||||
String get messagesWillSendWhenOnline =>
|
||||
'Messages will be sent when you\'re back online';
|
||||
|
||||
@override
|
||||
String get confirm => 'Confirm';
|
||||
@@ -605,7 +629,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get webSearch => 'Web Search';
|
||||
|
||||
@override
|
||||
String get webSearchDescription => 'Search the web and cite sources in replies.';
|
||||
String get webSearchDescription =>
|
||||
'Search the web and cite sources in replies.';
|
||||
|
||||
@override
|
||||
String get imageGeneration => 'Image Generation';
|
||||
@@ -644,7 +669,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get customHeaders => 'Custom Headers';
|
||||
|
||||
@override
|
||||
String get customHeadersDescription => 'Add custom HTTP headers for authentication, API keys, or special server requirements.';
|
||||
String get customHeadersDescription =>
|
||||
'Add custom HTTP headers for authentication, API keys, or special server requirements.';
|
||||
|
||||
@override
|
||||
String get headerNameEmpty => 'Header name cannot be empty';
|
||||
@@ -653,7 +679,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get headerNameTooLong => 'Header name too long (max 64 characters)';
|
||||
|
||||
@override
|
||||
String get headerNameInvalidChars => 'Invalid header name. Use only letters, numbers, and these symbols: !#\$&-^_`|~';
|
||||
String get headerNameInvalidChars =>
|
||||
'Invalid header name. Use only letters, numbers, and these symbols: !#\$&-^_`|~';
|
||||
|
||||
@override
|
||||
String headerNameReserved(String key) {
|
||||
@@ -664,13 +691,16 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get headerValueEmpty => 'Header value cannot be empty';
|
||||
|
||||
@override
|
||||
String get headerValueTooLong => 'Header value too long (max 1024 characters)';
|
||||
String get headerValueTooLong =>
|
||||
'Header value too long (max 1024 characters)';
|
||||
|
||||
@override
|
||||
String get headerValueInvalidChars => 'Header value contains invalid characters. Use only printable ASCII.';
|
||||
String get headerValueInvalidChars =>
|
||||
'Header value contains invalid characters. Use only printable ASCII.';
|
||||
|
||||
@override
|
||||
String get headerValueUnsafe => 'Header value appears to contain potentially unsafe content';
|
||||
String get headerValueUnsafe =>
|
||||
'Header value appears to contain potentially unsafe content';
|
||||
|
||||
@override
|
||||
String headerAlreadyExists(String key) {
|
||||
@@ -678,7 +708,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get maxHeadersReachedDetail => 'Maximum of 10 custom headers allowed. Remove some to add more.';
|
||||
String get maxHeadersReachedDetail =>
|
||||
'Maximum of 10 custom headers allowed. Remove some to add more.';
|
||||
|
||||
@override
|
||||
String get editMessage => 'Edit Message';
|
||||
@@ -744,13 +775,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get hideProviderInModelNames => 'Hide provider in model names';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNamesDescription => 'Show names like \"gpt-4o\" instead of \"openai/gpt-4o\".';
|
||||
String get hideProviderInModelNamesDescription =>
|
||||
'Show names like \"gpt-4o\" instead of \"openai/gpt-4o\".';
|
||||
|
||||
@override
|
||||
String get transportMode => 'Transport mode';
|
||||
|
||||
@override
|
||||
String get transportModeDescription => 'Choose how the app connects for realtime updates.';
|
||||
String get transportModeDescription =>
|
||||
'Choose how the app connects for realtime updates.';
|
||||
|
||||
@override
|
||||
String get mode => 'Mode';
|
||||
@@ -762,8 +795,10 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get transportModeWs => 'WebSocket only';
|
||||
|
||||
@override
|
||||
String get transportModeAutoInfo => 'More robust on restrictive networks. Upgrades to WebSocket when possible.';
|
||||
String get transportModeAutoInfo =>
|
||||
'More robust on restrictive networks. Upgrades to WebSocket when possible.';
|
||||
|
||||
@override
|
||||
String get transportModeWsInfo => 'Lower overhead, but may fail behind strict proxies/firewalls.';
|
||||
String get transportModeWsInfo =>
|
||||
'Lower overhead, but may fail behind strict proxies/firewalls.';
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get unableToLoadProfile => 'Impossible de charger le profil';
|
||||
|
||||
@override
|
||||
String get pleaseCheckConnection => 'Veuillez vérifier votre connexion et réessayer';
|
||||
String get pleaseCheckConnection =>
|
||||
'Veuillez vérifier votre connexion et réessayer';
|
||||
|
||||
@override
|
||||
String get account => 'Compte';
|
||||
@@ -116,7 +117,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get noFilesYet => 'Pas encore de fichiers';
|
||||
|
||||
@override
|
||||
String get uploadDocsPrompt => 'Importez des documents à utiliser dans vos conversations avec Conduit';
|
||||
String get uploadDocsPrompt =>
|
||||
'Importez des documents à utiliser dans vos conversations avec Conduit';
|
||||
|
||||
@override
|
||||
String get uploadFirstFile => 'Importer votre premier fichier';
|
||||
@@ -125,7 +127,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get knowledgeBaseEmpty => 'La base de connaissances est vide';
|
||||
|
||||
@override
|
||||
String get createCollectionsPrompt => 'Créez des collections de documents liés pour une référence facile';
|
||||
String get createCollectionsPrompt =>
|
||||
'Créez des collections de documents liés pour une référence facile';
|
||||
|
||||
@override
|
||||
String get chooseSourcePhoto => 'Choisir la source';
|
||||
@@ -151,7 +154,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get kbCreationComingSoon => 'La création de la base de connaissances arrive bientôt !';
|
||||
String get kbCreationComingSoon =>
|
||||
'La création de la base de connaissances arrive bientôt !';
|
||||
|
||||
@override
|
||||
String get backToServerSetup => 'Retour à la configuration du serveur';
|
||||
@@ -163,7 +167,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get signIn => 'Se connecter';
|
||||
|
||||
@override
|
||||
String get enterCredentials => 'Entrez vos identifiants pour accéder à vos conversations IA';
|
||||
String get enterCredentials =>
|
||||
'Entrez vos identifiants pour accéder à vos conversations IA';
|
||||
|
||||
@override
|
||||
String get credentials => 'Identifiants';
|
||||
@@ -184,7 +189,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get connectToServer => 'Se connecter au serveur';
|
||||
|
||||
@override
|
||||
String get enterServerAddress => 'Saisissez l\'adresse de votre serveur Open-WebUI pour commencer';
|
||||
String get enterServerAddress =>
|
||||
'Saisissez l\'adresse de votre serveur Open-WebUI pour commencer';
|
||||
|
||||
@override
|
||||
String get serverUrl => 'URL du serveur';
|
||||
@@ -193,7 +199,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get serverUrlHint => 'https://votre-serveur.com';
|
||||
|
||||
@override
|
||||
String get enterServerUrlSemantic => 'Saisissez l\'URL ou l\'adresse IP de votre serveur';
|
||||
String get enterServerUrlSemantic =>
|
||||
'Saisissez l\'URL ou l\'adresse IP de votre serveur';
|
||||
|
||||
@override
|
||||
String get headerName => 'Nom de l\'en-tête';
|
||||
@@ -223,7 +230,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get demoModeActive => 'Mode démo activé';
|
||||
|
||||
@override
|
||||
String get skipServerSetupTryDemo => 'Ignorer la configuration et essayer la démo';
|
||||
String get skipServerSetupTryDemo =>
|
||||
'Ignorer la configuration et essayer la démo';
|
||||
|
||||
@override
|
||||
String get enterDemo => 'Entrer en démo';
|
||||
@@ -232,34 +240,42 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get demoBadge => 'Démo';
|
||||
|
||||
@override
|
||||
String get serverNotOpenWebUI => 'Ceci ne semble pas être un serveur Open-WebUI.';
|
||||
String get serverNotOpenWebUI =>
|
||||
'Ceci ne semble pas être un serveur Open-WebUI.';
|
||||
|
||||
@override
|
||||
String get serverUrlEmpty => 'L\'URL du serveur ne peut pas être vide';
|
||||
|
||||
@override
|
||||
String get invalidUrlFormat => 'Format d\'URL invalide. Veuillez vérifier votre saisie.';
|
||||
String get invalidUrlFormat =>
|
||||
'Format d\'URL invalide. Veuillez vérifier votre saisie.';
|
||||
|
||||
@override
|
||||
String get onlyHttpHttps => 'Seuls les protocoles HTTP et HTTPS sont pris en charge.';
|
||||
String get onlyHttpHttps =>
|
||||
'Seuls les protocoles HTTP et HTTPS sont pris en charge.';
|
||||
|
||||
@override
|
||||
String get serverAddressRequired => 'Adresse du serveur requise (ex. 192.168.1.10 ou example.com).';
|
||||
String get serverAddressRequired =>
|
||||
'Adresse du serveur requise (ex. 192.168.1.10 ou example.com).';
|
||||
|
||||
@override
|
||||
String get portRange => 'Le port doit être compris entre 1 et 65535.';
|
||||
|
||||
@override
|
||||
String get invalidIpFormat => 'Format d\'IP invalide. Exemple : 192.168.1.10.';
|
||||
String get invalidIpFormat =>
|
||||
'Format d\'IP invalide. Exemple : 192.168.1.10.';
|
||||
|
||||
@override
|
||||
String get couldNotConnectGeneric => 'Connexion impossible. Vérifiez l\'adresse et réessayez.';
|
||||
String get couldNotConnectGeneric =>
|
||||
'Connexion impossible. Vérifiez l\'adresse et réessayez.';
|
||||
|
||||
@override
|
||||
String get weCouldntReachServer => 'Impossible d\'atteindre le serveur. Vérifiez la connexion et l\'état du serveur.';
|
||||
String get weCouldntReachServer =>
|
||||
'Impossible d\'atteindre le serveur. Vérifiez la connexion et l\'état du serveur.';
|
||||
|
||||
@override
|
||||
String get connectionTimedOut => 'Délai d\'attente dépassé. Le serveur est peut-être occupé ou bloqué.';
|
||||
String get connectionTimedOut =>
|
||||
'Délai d\'attente dépassé. Le serveur est peut-être occupé ou bloqué.';
|
||||
|
||||
@override
|
||||
String get useHttpOrHttpsOnly => 'Utilisez uniquement http:// ou https://.';
|
||||
@@ -268,19 +284,23 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get loginFailed => 'Échec de la connexion';
|
||||
|
||||
@override
|
||||
String get invalidCredentials => 'Nom d\'utilisateur ou mot de passe invalide. Réessayez.';
|
||||
String get invalidCredentials =>
|
||||
'Nom d\'utilisateur ou mot de passe invalide. Réessayez.';
|
||||
|
||||
@override
|
||||
String get serverRedirectingHttps => 'Le serveur redirige les requêtes. Vérifiez la configuration HTTPS.';
|
||||
String get serverRedirectingHttps =>
|
||||
'Le serveur redirige les requêtes. Vérifiez la configuration HTTPS.';
|
||||
|
||||
@override
|
||||
String get unableToConnectServer => 'Impossible de se connecter au serveur. Vérifiez votre connexion.';
|
||||
String get unableToConnectServer =>
|
||||
'Impossible de se connecter au serveur. Vérifiez votre connexion.';
|
||||
|
||||
@override
|
||||
String get requestTimedOut => 'Délai d\'attente dépassé. Réessayez.';
|
||||
|
||||
@override
|
||||
String get genericSignInFailed => 'Connexion impossible. Vérifiez vos identifiants et le serveur.';
|
||||
String get genericSignInFailed =>
|
||||
'Connexion impossible. Vérifiez vos identifiants et le serveur.';
|
||||
|
||||
@override
|
||||
String get skip => 'Ignorer';
|
||||
@@ -295,22 +315,27 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get onboardStartTitle => 'Commencer une conversation';
|
||||
|
||||
@override
|
||||
String get onboardStartSubtitle => 'Choisissez un modèle puis commencez à écrire. Touchez Nouveau chat à tout moment.';
|
||||
String get onboardStartSubtitle =>
|
||||
'Choisissez un modèle puis commencez à écrire. Touchez Nouveau chat à tout moment.';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet1 => 'Touchez le nom du modèle en haut pour changer';
|
||||
String get onboardStartBullet1 =>
|
||||
'Touchez le nom du modèle en haut pour changer';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet2 => 'Utilisez Nouveau chat pour réinitialiser le contexte';
|
||||
String get onboardStartBullet2 =>
|
||||
'Utilisez Nouveau chat pour réinitialiser le contexte';
|
||||
|
||||
@override
|
||||
String get onboardAttachTitle => 'Ajouter du contexte';
|
||||
|
||||
@override
|
||||
String get onboardAttachSubtitle => 'Ancrez les réponses avec l\'Espace de travail ou des photos.';
|
||||
String get onboardAttachSubtitle =>
|
||||
'Ancrez les réponses avec l\'Espace de travail ou des photos.';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet1 => 'Espace de travail : PDF, documents, jeux de données';
|
||||
String get onboardAttachBullet1 =>
|
||||
'Espace de travail : PDF, documents, jeux de données';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet2 => 'Photos : appareil photo ou galerie';
|
||||
@@ -319,25 +344,31 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get onboardSpeakTitle => 'Parlez naturellement';
|
||||
|
||||
@override
|
||||
String get onboardSpeakSubtitle => 'Touchez le micro pour dicter avec retour visuel.';
|
||||
String get onboardSpeakSubtitle =>
|
||||
'Touchez le micro pour dicter avec retour visuel.';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet1 => 'Arrêtez à tout moment ; le texte partiel est conservé';
|
||||
String get onboardSpeakBullet1 =>
|
||||
'Arrêtez à tout moment ; le texte partiel est conservé';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet2 => 'Idéal pour des notes rapides ou de longs prompts';
|
||||
String get onboardSpeakBullet2 =>
|
||||
'Idéal pour des notes rapides ou de longs prompts';
|
||||
|
||||
@override
|
||||
String get onboardQuickTitle => 'Actions rapides';
|
||||
|
||||
@override
|
||||
String get onboardQuickSubtitle => 'Ouvrez le menu pour passer entre Chats, Espace de travail et Profil.';
|
||||
String get onboardQuickSubtitle =>
|
||||
'Ouvrez le menu pour passer entre Chats, Espace de travail et Profil.';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet1 => 'Touchez le menu pour accéder à Chats, Espace, Profil';
|
||||
String get onboardQuickBullet1 =>
|
||||
'Touchez le menu pour accéder à Chats, Espace, Profil';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet2 => 'Lancez Nouveau chat ou gérez les modèles depuis la barre';
|
||||
String get onboardQuickBullet2 =>
|
||||
'Lancez Nouveau chat ou gérez les modèles depuis la barre';
|
||||
|
||||
@override
|
||||
String get addAttachment => 'Ajouter une pièce jointe';
|
||||
@@ -404,13 +435,16 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get emptyImageData => 'Données d\'image vides';
|
||||
|
||||
@override
|
||||
String get offlineBanner => 'Vous êtes hors ligne. Certaines fonctions peuvent être limitées.';
|
||||
String get offlineBanner =>
|
||||
'Vous êtes hors ligne. Certaines fonctions peuvent être limitées.';
|
||||
|
||||
@override
|
||||
String get featureRequiresInternet => 'Cette fonctionnalité nécessite une connexion Internet';
|
||||
String get featureRequiresInternet =>
|
||||
'Cette fonctionnalité nécessite une connexion Internet';
|
||||
|
||||
@override
|
||||
String get messagesWillSendWhenOnline => 'Les messages seront envoyés lorsque vous serez de nouveau en ligne';
|
||||
String get messagesWillSendWhenOnline =>
|
||||
'Les messages seront envoyés lorsque vous serez de nouveau en ligne';
|
||||
|
||||
@override
|
||||
String get confirm => 'Confirmer';
|
||||
@@ -605,13 +639,15 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get webSearch => 'Recherche Web';
|
||||
|
||||
@override
|
||||
String get webSearchDescription => 'Recherchez sur le web et citez les sources.';
|
||||
String get webSearchDescription =>
|
||||
'Recherchez sur le web et citez les sources.';
|
||||
|
||||
@override
|
||||
String get imageGeneration => 'Génération d\'images';
|
||||
|
||||
@override
|
||||
String get imageGenerationDescription => 'Créez des images à partir de vos prompts.';
|
||||
String get imageGenerationDescription =>
|
||||
'Créez des images à partir de vos prompts.';
|
||||
|
||||
@override
|
||||
String get copy => 'Copier';
|
||||
@@ -644,16 +680,19 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
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.';
|
||||
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)';
|
||||
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 : !#\$&-^_`|~';
|
||||
String get headerNameInvalidChars =>
|
||||
'Nom d\'en-tête invalide. Utilisez uniquement des lettres, des chiffres et ces symboles : !#\$&-^_`|~';
|
||||
|
||||
@override
|
||||
String headerNameReserved(String key) {
|
||||
@@ -661,16 +700,20 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get headerValueEmpty => 'La valeur de l\'en-tête ne peut pas être vide';
|
||||
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)';
|
||||
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.';
|
||||
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';
|
||||
String get headerValueUnsafe =>
|
||||
'La valeur de l\'en-tête semble contenir du contenu potentiellement dangereux';
|
||||
|
||||
@override
|
||||
String headerAlreadyExists(String key) {
|
||||
@@ -678,7 +721,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get maxHeadersReachedDetail => 'Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter.';
|
||||
String get maxHeadersReachedDetail =>
|
||||
'Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter.';
|
||||
|
||||
@override
|
||||
String get editMessage => 'Modifier le message';
|
||||
@@ -715,7 +759,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get githubRepository => 'Dépôt GitHub';
|
||||
|
||||
@override
|
||||
String get unableToLoadAppInfo => 'Impossible de charger les informations de l\'application';
|
||||
String get unableToLoadAppInfo =>
|
||||
'Impossible de charger les informations de l\'application';
|
||||
|
||||
@override
|
||||
String get thinking => 'Réflexion…';
|
||||
@@ -732,7 +777,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get appCustomization => 'Personnalisation de l\'app';
|
||||
|
||||
@override
|
||||
String get appCustomizationSubtitle => 'Personnalisez l\'affichage des noms et de l\'UI';
|
||||
String get appCustomizationSubtitle =>
|
||||
'Personnalisez l\'affichage des noms et de l\'UI';
|
||||
|
||||
@override
|
||||
String get display => 'Affichage';
|
||||
@@ -741,16 +787,19 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get realtime => 'Temps réel';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNames => 'Masquer le fournisseur dans les noms de modèles';
|
||||
String get hideProviderInModelNames =>
|
||||
'Masquer le fournisseur dans les noms de modèles';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNamesDescription => 'Afficher des noms comme \"gpt-4o\" au lieu de \"openai/gpt-4o\".';
|
||||
String get hideProviderInModelNamesDescription =>
|
||||
'Afficher des noms comme \"gpt-4o\" au lieu de \"openai/gpt-4o\".';
|
||||
|
||||
@override
|
||||
String get transportMode => 'Mode de transport';
|
||||
|
||||
@override
|
||||
String get transportModeDescription => 'Choisissez comment l\'app se connecte pour les mises à jour en temps réel.';
|
||||
String get transportModeDescription =>
|
||||
'Choisissez comment l\'app se connecte pour les mises à jour en temps réel.';
|
||||
|
||||
@override
|
||||
String get mode => 'Mode';
|
||||
@@ -762,8 +811,10 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get transportModeWs => 'WebSocket uniquement';
|
||||
|
||||
@override
|
||||
String get transportModeAutoInfo => 'Plus robuste sur les réseaux restrictifs. Passe à WebSocket lorsque possible.';
|
||||
String get transportModeAutoInfo =>
|
||||
'Plus robuste sur les réseaux restrictifs. Passe à WebSocket lorsque possible.';
|
||||
|
||||
@override
|
||||
String get transportModeWsInfo => 'Moins de surcharge, mais peut échouer derrière des proxys/firewalls stricts.';
|
||||
String get transportModeWsInfo =>
|
||||
'Moins de surcharge, mais peut échouer derrière des proxys/firewalls stricts.';
|
||||
}
|
||||
|
||||
@@ -116,7 +116,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get noFilesYet => 'Ancora nessun file';
|
||||
|
||||
@override
|
||||
String get uploadDocsPrompt => 'Carica documenti da usare nelle conversazioni con Conduit';
|
||||
String get uploadDocsPrompt =>
|
||||
'Carica documenti da usare nelle conversazioni con Conduit';
|
||||
|
||||
@override
|
||||
String get uploadFirstFile => 'Carica il tuo primo file';
|
||||
@@ -125,7 +126,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get knowledgeBaseEmpty => 'La base di conoscenza è vuota';
|
||||
|
||||
@override
|
||||
String get createCollectionsPrompt => 'Crea raccolte di documenti correlati per un rapido riferimento';
|
||||
String get createCollectionsPrompt =>
|
||||
'Crea raccolte di documenti correlati per un rapido riferimento';
|
||||
|
||||
@override
|
||||
String get chooseSourcePhoto => 'Scegli origine';
|
||||
@@ -151,7 +153,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get kbCreationComingSoon => 'La creazione della base di conoscenza arriverà presto!';
|
||||
String get kbCreationComingSoon =>
|
||||
'La creazione della base di conoscenza arriverà presto!';
|
||||
|
||||
@override
|
||||
String get backToServerSetup => 'Torna alla configurazione del server';
|
||||
@@ -163,7 +166,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get signIn => 'Accedi';
|
||||
|
||||
@override
|
||||
String get enterCredentials => 'Inserisci le credenziali per accedere alle conversazioni IA';
|
||||
String get enterCredentials =>
|
||||
'Inserisci le credenziali per accedere alle conversazioni IA';
|
||||
|
||||
@override
|
||||
String get credentials => 'Credenziali';
|
||||
@@ -184,7 +188,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get connectToServer => 'Connetti al server';
|
||||
|
||||
@override
|
||||
String get enterServerAddress => 'Inserisci l\'indirizzo del server Open-WebUI per iniziare';
|
||||
String get enterServerAddress =>
|
||||
'Inserisci l\'indirizzo del server Open-WebUI per iniziare';
|
||||
|
||||
@override
|
||||
String get serverUrl => 'URL del server';
|
||||
@@ -193,7 +198,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get serverUrlHint => 'https://tuo-server.com';
|
||||
|
||||
@override
|
||||
String get enterServerUrlSemantic => 'Inserisci l\'URL o l\'indirizzo IP del server';
|
||||
String get enterServerUrlSemantic =>
|
||||
'Inserisci l\'URL o l\'indirizzo IP del server';
|
||||
|
||||
@override
|
||||
String get headerName => 'Nome header';
|
||||
@@ -223,7 +229,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get demoModeActive => 'Modalità demo attiva';
|
||||
|
||||
@override
|
||||
String get skipServerSetupTryDemo => 'Salta configurazione server e prova la demo';
|
||||
String get skipServerSetupTryDemo =>
|
||||
'Salta configurazione server e prova la demo';
|
||||
|
||||
@override
|
||||
String get enterDemo => 'Entra in demo';
|
||||
@@ -244,7 +251,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get onlyHttpHttps => 'Sono supportati solo i protocolli HTTP e HTTPS.';
|
||||
|
||||
@override
|
||||
String get serverAddressRequired => 'Indirizzo server richiesto (es. 192.168.1.10 o example.com).';
|
||||
String get serverAddressRequired =>
|
||||
'Indirizzo server richiesto (es. 192.168.1.10 o example.com).';
|
||||
|
||||
@override
|
||||
String get portRange => 'La porta deve essere tra 1 e 65535.';
|
||||
@@ -253,13 +261,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get invalidIpFormat => 'Formato IP non valido. Esempio: 192.168.1.10.';
|
||||
|
||||
@override
|
||||
String get couldNotConnectGeneric => 'Impossibile connettersi. Verifica l\'indirizzo e riprova.';
|
||||
String get couldNotConnectGeneric =>
|
||||
'Impossibile connettersi. Verifica l\'indirizzo e riprova.';
|
||||
|
||||
@override
|
||||
String get weCouldntReachServer => 'Impossibile raggiungere il server. Verifica connessione e stato del server.';
|
||||
String get weCouldntReachServer =>
|
||||
'Impossibile raggiungere il server. Verifica connessione e stato del server.';
|
||||
|
||||
@override
|
||||
String get connectionTimedOut => 'Tempo scaduto. Il server potrebbe essere occupato o bloccato.';
|
||||
String get connectionTimedOut =>
|
||||
'Tempo scaduto. Il server potrebbe essere occupato o bloccato.';
|
||||
|
||||
@override
|
||||
String get useHttpOrHttpsOnly => 'Usa solo http:// o https://.';
|
||||
@@ -268,19 +279,23 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get loginFailed => 'Accesso non riuscito';
|
||||
|
||||
@override
|
||||
String get invalidCredentials => 'Nome utente o password non validi. Riprova.';
|
||||
String get invalidCredentials =>
|
||||
'Nome utente o password non validi. Riprova.';
|
||||
|
||||
@override
|
||||
String get serverRedirectingHttps => 'Il server sta reindirizzando. Controlla la configurazione HTTPS.';
|
||||
String get serverRedirectingHttps =>
|
||||
'Il server sta reindirizzando. Controlla la configurazione HTTPS.';
|
||||
|
||||
@override
|
||||
String get unableToConnectServer => 'Impossibile connettersi al server. Controlla la connessione.';
|
||||
String get unableToConnectServer =>
|
||||
'Impossibile connettersi al server. Controlla la connessione.';
|
||||
|
||||
@override
|
||||
String get requestTimedOut => 'Richiesta scaduta. Riprova.';
|
||||
|
||||
@override
|
||||
String get genericSignInFailed => 'Impossibile accedere. Controlla credenziali e server.';
|
||||
String get genericSignInFailed =>
|
||||
'Impossibile accedere. Controlla credenziali e server.';
|
||||
|
||||
@override
|
||||
String get skip => 'Salta';
|
||||
@@ -295,10 +310,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get onboardStartTitle => 'Inizia una conversazione';
|
||||
|
||||
@override
|
||||
String get onboardStartSubtitle => 'Scegli un modello e inizia a scrivere. Tocca Nuova chat in qualsiasi momento.';
|
||||
String get onboardStartSubtitle =>
|
||||
'Scegli un modello e inizia a scrivere. Tocca Nuova chat in qualsiasi momento.';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet1 => 'Tocca il nome del modello in alto per cambiare';
|
||||
String get onboardStartBullet1 =>
|
||||
'Tocca il nome del modello in alto per cambiare';
|
||||
|
||||
@override
|
||||
String get onboardStartBullet2 => 'Usa Nuova chat per azzerare il contesto';
|
||||
@@ -307,7 +324,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get onboardAttachTitle => 'Aggiungi contesto';
|
||||
|
||||
@override
|
||||
String get onboardAttachSubtitle => 'Collega le risposte a Workspace o alle foto.';
|
||||
String get onboardAttachSubtitle =>
|
||||
'Collega le risposte a Workspace o alle foto.';
|
||||
|
||||
@override
|
||||
String get onboardAttachBullet1 => 'Workspace: PDF, documenti, dataset';
|
||||
@@ -319,10 +337,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get onboardSpeakTitle => 'Parla in modo naturale';
|
||||
|
||||
@override
|
||||
String get onboardSpeakSubtitle => 'Tocca il microfono per dettare con feedback visivo.';
|
||||
String get onboardSpeakSubtitle =>
|
||||
'Tocca il microfono per dettare con feedback visivo.';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet1 => 'Interrompi in qualsiasi momento; il testo parziale viene mantenuto';
|
||||
String get onboardSpeakBullet1 =>
|
||||
'Interrompi in qualsiasi momento; il testo parziale viene mantenuto';
|
||||
|
||||
@override
|
||||
String get onboardSpeakBullet2 => 'Ottimo per note rapide o prompt lunghi';
|
||||
@@ -331,13 +351,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get onboardQuickTitle => 'Azioni rapide';
|
||||
|
||||
@override
|
||||
String get onboardQuickSubtitle => 'Apri il menu per passare tra Chat, Workspace e Profilo.';
|
||||
String get onboardQuickSubtitle =>
|
||||
'Apri il menu per passare tra Chat, Workspace e Profilo.';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet1 => 'Tocca il menu per accedere a Chat, Workspace, Profilo';
|
||||
String get onboardQuickBullet1 =>
|
||||
'Tocca il menu per accedere a Chat, Workspace, Profilo';
|
||||
|
||||
@override
|
||||
String get onboardQuickBullet2 => 'Avvia Nuova chat o gestisci i modelli dalla barra';
|
||||
String get onboardQuickBullet2 =>
|
||||
'Avvia Nuova chat o gestisci i modelli dalla barra';
|
||||
|
||||
@override
|
||||
String get addAttachment => 'Aggiungi allegato';
|
||||
@@ -404,13 +427,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get emptyImageData => 'Dati immagine vuoti';
|
||||
|
||||
@override
|
||||
String get offlineBanner => 'Sei offline. Alcune funzioni potrebbero essere limitate.';
|
||||
String get offlineBanner =>
|
||||
'Sei offline. Alcune funzioni potrebbero essere limitate.';
|
||||
|
||||
@override
|
||||
String get featureRequiresInternet => 'Questa funzione richiede una connessione Internet';
|
||||
String get featureRequiresInternet =>
|
||||
'Questa funzione richiede una connessione Internet';
|
||||
|
||||
@override
|
||||
String get messagesWillSendWhenOnline => 'I messaggi verranno inviati quando tornerai online';
|
||||
String get messagesWillSendWhenOnline =>
|
||||
'I messaggi verranno inviati quando tornerai online';
|
||||
|
||||
@override
|
||||
String get confirm => 'Conferma';
|
||||
@@ -569,7 +595,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get deleteChatTitle => 'Elimina chat';
|
||||
|
||||
@override
|
||||
String get deleteChatMessage => 'Questa chat verrà eliminata definitivamente.';
|
||||
String get deleteChatMessage =>
|
||||
'Questa chat verrà eliminata definitivamente.';
|
||||
|
||||
@override
|
||||
String get aboutApp => 'Informazioni sull\'app';
|
||||
@@ -644,7 +671,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get customHeaders => 'Header personalizzati';
|
||||
|
||||
@override
|
||||
String get customHeadersDescription => 'Aggiungi header HTTP personalizzati per autenticazione, chiavi API o requisiti speciali del server.';
|
||||
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';
|
||||
@@ -653,7 +681,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
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: !#\$&-^_`|~';
|
||||
String get headerNameInvalidChars =>
|
||||
'Nome header non valido. Usa solo lettere, numeri e questi simboli: !#\$&-^_`|~';
|
||||
|
||||
@override
|
||||
String headerNameReserved(String key) {
|
||||
@@ -664,13 +693,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get headerValueEmpty => 'Il valore dell\'header non può essere vuoto';
|
||||
|
||||
@override
|
||||
String get headerValueTooLong => 'Valore header troppo lungo (max 1024 caratteri)';
|
||||
String get headerValueTooLong =>
|
||||
'Valore header troppo lungo (max 1024 caratteri)';
|
||||
|
||||
@override
|
||||
String get headerValueInvalidChars => 'Il valore dell\'header contiene caratteri non validi. Usa solo ASCII stampabile.';
|
||||
String get headerValueInvalidChars =>
|
||||
'Il valore dell\'header contiene caratteri non validi. Usa solo ASCII stampabile.';
|
||||
|
||||
@override
|
||||
String get headerValueUnsafe => 'Il valore dell\'header sembra contenere contenuti potenzialmente non sicuri';
|
||||
String get headerValueUnsafe =>
|
||||
'Il valore dell\'header sembra contenere contenuti potenzialmente non sicuri';
|
||||
|
||||
@override
|
||||
String headerAlreadyExists(String key) {
|
||||
@@ -678,7 +710,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get maxHeadersReachedDetail => 'Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri.';
|
||||
String get maxHeadersReachedDetail =>
|
||||
'Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri.';
|
||||
|
||||
@override
|
||||
String get editMessage => 'Modifica messaggio';
|
||||
@@ -715,7 +748,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get githubRepository => 'Repository GitHub';
|
||||
|
||||
@override
|
||||
String get unableToLoadAppInfo => 'Impossibile caricare le informazioni dell\'app';
|
||||
String get unableToLoadAppInfo =>
|
||||
'Impossibile caricare le informazioni dell\'app';
|
||||
|
||||
@override
|
||||
String get thinking => 'Sta pensando…';
|
||||
@@ -732,7 +766,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get appCustomization => 'Personalizzazione app';
|
||||
|
||||
@override
|
||||
String get appCustomizationSubtitle => 'Personalizza la visualizzazione dei nomi e dell\'UI';
|
||||
String get appCustomizationSubtitle =>
|
||||
'Personalizza la visualizzazione dei nomi e dell\'UI';
|
||||
|
||||
@override
|
||||
String get display => 'Schermo';
|
||||
@@ -741,16 +776,19 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get realtime => 'Tempo reale';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNames => 'Nascondi provider nei nomi dei modelli';
|
||||
String get hideProviderInModelNames =>
|
||||
'Nascondi provider nei nomi dei modelli';
|
||||
|
||||
@override
|
||||
String get hideProviderInModelNamesDescription => 'Mostra nomi come \"gpt-4o\" invece di \"openai/gpt-4o\".';
|
||||
String get hideProviderInModelNamesDescription =>
|
||||
'Mostra nomi come \"gpt-4o\" invece di \"openai/gpt-4o\".';
|
||||
|
||||
@override
|
||||
String get transportMode => 'Modalità di trasporto';
|
||||
|
||||
@override
|
||||
String get transportModeDescription => 'Scegli come l\'app si connette per gli aggiornamenti in tempo reale.';
|
||||
String get transportModeDescription =>
|
||||
'Scegli come l\'app si connette per gli aggiornamenti in tempo reale.';
|
||||
|
||||
@override
|
||||
String get mode => 'Modalità';
|
||||
@@ -762,8 +800,10 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get transportModeWs => 'Solo WebSocket';
|
||||
|
||||
@override
|
||||
String get transportModeAutoInfo => 'Più robusto nelle reti restrittive. Passa a WebSocket quando possibile.';
|
||||
String get transportModeAutoInfo =>
|
||||
'Più robusto nelle reti restrittive. Passa a WebSocket quando possibile.';
|
||||
|
||||
@override
|
||||
String get transportModeWsInfo => 'Minore overhead, ma può fallire dietro proxy/firewall restrittivi.';
|
||||
String get transportModeWsInfo =>
|
||||
'Minore overhead, ma può fallire dietro proxy/firewall restrittivi.';
|
||||
}
|
||||
|
||||
17
pubspec.yaml
17
pubspec.yaml
@@ -75,21 +75,8 @@ dependency_overrides:
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
generate: true
|
||||
# Localization configuration
|
||||
# The default synthetic package is used for generated localizations:
|
||||
# import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
# ARB files live in lib/l10n
|
||||
# You can customize output via the `l10n:` section if needed.
|
||||
#
|
||||
# l10n:
|
||||
# arb-dir: lib/l10n
|
||||
# template-arb-file: app_en.arb
|
||||
# output-localization-file: app_localizations.dart
|
||||
# preferred-supported-locales:
|
||||
# - en
|
||||
# - de
|
||||
# - fr
|
||||
# - it
|
||||
# Localization
|
||||
# ARB files live in lib/l10n (configured via l10n.yaml)
|
||||
|
||||
assets:
|
||||
- assets/icons/
|
||||
|
||||
139
tool/validate_arb_locales.dart
Normal file
139
tool/validate_arb_locales.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
/// Validates ARB locale files against the English template (app_en.arb).
|
||||
/// - Ensures no duplicate keys within any ARB file.
|
||||
/// - Ensures each non-meta key in EN exists in other locales.
|
||||
/// - Ensures placeholder names match between EN and other locales.
|
||||
/// - Reports unused keys (best-effort) by scanning lib/ for usages of
|
||||
/// AppLocalizations.of(context)!.<key>. Unused keys are WARNINGS by default.
|
||||
///
|
||||
/// Exit codes:
|
||||
/// 0 = success (no hard errors; warnings may be printed)
|
||||
/// 1 = validation errors (duplicates, missing keys, placeholder mismatches)
|
||||
Future<void> main(List<String> args) async {
|
||||
final basePath = 'lib/l10n/app_en.arb';
|
||||
final dir = Directory('lib/l10n');
|
||||
if (!await File(basePath).exists()) {
|
||||
stderr.writeln('Base ARB not found: $basePath');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
final arbFiles = await dir
|
||||
.list()
|
||||
.where((e) => e.path.endsWith('.arb'))
|
||||
.map((e) => File(e.path))
|
||||
.toList();
|
||||
|
||||
final baseFile = File(basePath);
|
||||
final base = _readJson(baseFile);
|
||||
final baseKeys = _nonMetaKeys(base);
|
||||
final basePlaceholders = _placeholdersMap(base);
|
||||
|
||||
final errors = <String>[];
|
||||
final warnings = <String>[];
|
||||
|
||||
// NOTE: Duplicate keys at the top-level are invalid JSON and unlikely.
|
||||
// We skip duplicate detection to avoid false positives from nested meta keys.
|
||||
|
||||
// Validate translations against base
|
||||
for (final f in arbFiles) {
|
||||
if (f.path.endsWith('_en.arb')) continue;
|
||||
final data = _readJson(f);
|
||||
final keys = _nonMetaKeys(data);
|
||||
|
||||
// Missing keys
|
||||
final missing = baseKeys.difference(keys);
|
||||
if (missing.isNotEmpty) {
|
||||
errors.add('[${f.path}] Missing keys: ${missing.toList()..sort()}');
|
||||
}
|
||||
|
||||
// Placeholder parity checks
|
||||
final transPlaceholders = _placeholdersMap(data);
|
||||
for (final k in basePlaceholders.keys) {
|
||||
final basePh = basePlaceholders[k] ?? const <String>{};
|
||||
final trPh = transPlaceholders[k];
|
||||
if (trPh == null) {
|
||||
// If string exists but no meta placeholders, warn only.
|
||||
if (keys.contains(k) && basePh.isNotEmpty) {
|
||||
warnings.add('[${f.path}] Key "$k" missing @meta placeholders; base has ${basePh.toList()..sort()}');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (basePh.length != trPh.length || !basePh.containsAll(trPh)) {
|
||||
warnings.add('[${f.path}] Placeholder mismatch for "$k": expected ${basePh.toList()..sort()}, got ${trPh.toList()..sort()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unused keys (best-effort) — WARNINGS only
|
||||
final usedKeys = await _scanUsedLocalizationKeys();
|
||||
final unused = baseKeys.difference(usedKeys);
|
||||
if (unused.isNotEmpty) {
|
||||
warnings.add('Unused keys in EN (best-effort): ${unused.toList()..sort()}');
|
||||
}
|
||||
|
||||
// Print results
|
||||
if (errors.isNotEmpty) {
|
||||
stderr.writeln('ARB validation errors:');
|
||||
for (final e in errors) {
|
||||
stderr.writeln(' - $e');
|
||||
}
|
||||
}
|
||||
if (warnings.isNotEmpty) {
|
||||
stdout.writeln('ARB validation warnings:');
|
||||
for (final w in warnings) {
|
||||
stdout.writeln(' - $w');
|
||||
}
|
||||
}
|
||||
|
||||
exit(errors.isEmpty ? 0 : 1);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _readJson(File f) {
|
||||
final content = f.readAsStringSync();
|
||||
return json.decode(content) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Set<String> _nonMetaKeys(Map<String, dynamic> m) {
|
||||
return m.keys
|
||||
.where((k) => !k.startsWith('@') && k != '@@locale')
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Map<String, Set<String>> _placeholdersMap(Map<String, dynamic> m) {
|
||||
final map = <String, Set<String>>{};
|
||||
for (final entry in m.entries) {
|
||||
final key = entry.key;
|
||||
if (!key.startsWith('@')) continue;
|
||||
final value = entry.value;
|
||||
if (value is! Map<String, dynamic>) continue;
|
||||
final placeholders = value['placeholders'];
|
||||
if (placeholders is Map<String, dynamic>) {
|
||||
map[key.substring(1)] = placeholders.keys.toSet();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// Duplicate detection intentionally omitted (see note above).
|
||||
|
||||
Future<Set<String>> _scanUsedLocalizationKeys() async {
|
||||
final libDir = Directory('lib');
|
||||
final used = <String>{};
|
||||
final dartFiles = await libDir
|
||||
.list(recursive: true)
|
||||
.where((e) => e.path.endsWith('.dart'))
|
||||
.map((e) => File(e.path))
|
||||
.toList();
|
||||
|
||||
final regex = RegExp(r'AppLocalizations\.of\([^)]*\)!\.([a-zA-Z0-9_]+)');
|
||||
for (final f in dartFiles) {
|
||||
final text = await f.readAsString();
|
||||
for (final m in regex.allMatches(text)) {
|
||||
final key = m.group(1);
|
||||
if (key != null) used.add(key);
|
||||
}
|
||||
}
|
||||
return used;
|
||||
}
|
||||
63
tool/verify_arb_descriptions.dart
Normal file
63
tool/verify_arb_descriptions.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
/// Verifies that every non-meta key in app_en.arb has a corresponding
|
||||
/// @key entry with a non-empty `description`.
|
||||
///
|
||||
/// Usage: dart run tool/verify_arb_descriptions.dart
|
||||
Future<void> main() async {
|
||||
final arbPath = 'lib/l10n/app_en.arb';
|
||||
final file = File(arbPath);
|
||||
if (!await file.exists()) {
|
||||
stderr.writeln('ARB file not found: $arbPath');
|
||||
exit(2);
|
||||
}
|
||||
|
||||
final content = await file.readAsString();
|
||||
late final Map<String, dynamic> data;
|
||||
try {
|
||||
data = json.decode(content) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
stderr.writeln('Failed to parse $arbPath as JSON: $e');
|
||||
exit(2);
|
||||
}
|
||||
|
||||
final missingMeta = <String>[];
|
||||
final missingDescription = <String>[];
|
||||
|
||||
for (final entry in data.entries) {
|
||||
final key = entry.key;
|
||||
if (key.startsWith('@') || key == '@@locale') continue; // meta
|
||||
|
||||
final metaKey = '@$key';
|
||||
final meta = data[metaKey];
|
||||
if (meta == null || meta is! Map) {
|
||||
missingMeta.add(key);
|
||||
continue;
|
||||
}
|
||||
final desc = meta['description'];
|
||||
if (desc is! String || desc.trim().isEmpty) {
|
||||
missingDescription.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingMeta.isEmpty && missingDescription.isEmpty) {
|
||||
stdout.writeln('ARB descriptions check passed: all keys have @meta.description.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (missingMeta.isNotEmpty) {
|
||||
stderr.writeln('Missing @meta for keys (${missingMeta.length}):');
|
||||
for (final k in missingMeta) {
|
||||
stderr.writeln(' - $k');
|
||||
}
|
||||
}
|
||||
if (missingDescription.isNotEmpty) {
|
||||
stderr.writeln('Missing description in @meta for keys (${missingDescription.length}):');
|
||||
for (final k in missingDescription) {
|
||||
stderr.writeln(' - $k');
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
19
weblate.yaml
Normal file
19
weblate.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
projects:
|
||||
- name: Conduit
|
||||
slug: conduit
|
||||
components:
|
||||
- name: Mobile App
|
||||
slug: app
|
||||
# Weblate will use the repository connected via the UI.
|
||||
# Configure file discovery for Flutter ARB localization files.
|
||||
filemask: lib/l10n/app_*.arb
|
||||
template: lib/l10n/app_en.arb
|
||||
new_base: lib/l10n/app_{language}.arb
|
||||
base_language: en
|
||||
file_format: arb
|
||||
monolingual: true
|
||||
# Prefer PRs from Weblate instead of direct pushes
|
||||
pull_request: true
|
||||
# Optional: auto-add new languages when enabled in Weblate
|
||||
add_new_languages: true
|
||||
|
||||
Reference in New Issue
Block a user