feat(l10n): Update English localization with voice call states and model capabilities

This commit is contained in:
cogwheel0
2025-11-02 17:44:23 +05:30
parent b648ae29ea
commit 8321e3c721
23 changed files with 6242 additions and 1662 deletions

View File

@@ -1,12 +1,20 @@
import 'dart:math' as math;
import 'package:conduit/l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/semantics.dart';
import '../../shared/theme/tweakcn_themes.dart';
import '../../shared/theme/theme_extensions.dart';
import 'navigation_service.dart';
/// Enhanced accessibility service for WCAG 2.2 AA compliance
class EnhancedAccessibilityService {
static AppLocalizations? get _l10n {
final ctx = NavigationService.context;
if (ctx == null) return null;
return AppLocalizations.of(ctx);
}
/// Announce text to screen readers
static void announce(
String message, {
@@ -17,20 +25,28 @@ class EnhancedAccessibilityService {
/// Announce loading state
static void announceLoading(String loadingMessage) {
announce('Loading: $loadingMessage');
final l10n = _l10n;
final message =
l10n?.loadingAnnouncement(loadingMessage) ?? 'Loading: $loadingMessage';
announce(message);
}
/// Announce error with helpful context
static void announceError(String error, {String? suggestion}) {
final l10n = _l10n;
final message = suggestion != null
? 'Error: $error. $suggestion'
: 'Error: $error';
? l10n?.errorAnnouncementWithSuggestion(error, suggestion) ??
'Error: $error. $suggestion'
: l10n?.errorAnnouncement(error) ?? 'Error: $error';
announce(message);
}
/// Announce success with context
static void announceSuccess(String successMessage) {
announce('Success: $successMessage');
final l10n = _l10n;
announce(
l10n?.successAnnouncement(successMessage) ?? 'Success: $successMessage',
);
}
/// Check if reduce motion is enabled
@@ -117,7 +133,10 @@ class EnhancedAccessibilityService {
bool obscureText = false,
ValueChanged<String>? onChanged,
}) {
final effectiveLabel = isRequired ? '$label *' : label;
final l10n = _l10n;
final effectiveLabel = isRequired
? l10n?.requiredFieldLabel(label) ?? '$label *'
: label;
return Semantics(
label: effectiveLabel,
@@ -132,7 +151,9 @@ class EnhancedAccessibilityService {
labelText: effectiveLabel,
hintText: hintText,
errorText: errorText,
helperText: isRequired ? '* Required field' : null,
helperText: isRequired
? l10n?.requiredFieldHelper ?? 'Required field'
: null,
prefixIcon: errorText != null
? Builder(
builder: (context) => Icon(
@@ -176,8 +197,9 @@ class EnhancedAccessibilityService {
String? loadingMessage,
double size = 24,
}) {
final l10n = _l10n;
return Semantics(
label: loadingMessage ?? 'Loading',
label: loadingMessage ?? l10n?.loadingShort ?? 'Loading',
liveRegion: true,
child: SizedBox(
width: size,
@@ -217,10 +239,13 @@ class EnhancedAccessibilityService {
required String label,
String? description,
}) {
final l10n = _l10n;
final onLabel = l10n?.switchOnLabel ?? 'On';
final offLabel = l10n?.switchOffLabel ?? 'Off';
return Builder(
builder: (context) => Semantics(
label: label,
value: value ? 'On' : 'Off',
value: value ? onLabel : offLabel,
hint: description,
toggled: value,
onTap: onChanged != null ? () => onChanged(!value) : null,
@@ -291,15 +316,18 @@ class EnhancedAccessibilityService {
return showDialog<T>(
context: context,
barrierDismissible: barrierDismissible,
builder: (context) => Semantics(
builder: (dialogContext) {
final dialogL10n = AppLocalizations.of(dialogContext);
return Semantics(
scopesRoute: true,
explicitChildNodes: true,
label: 'Dialog: $title',
label: dialogL10n?.dialogSemanticLabel(title) ?? 'Dialog: $title',
child: AlertDialog(
title: Semantics(header: true, child: Text(title)),
content: child,
),
),
);
},
);
}

View File

@@ -1,3 +1,4 @@
import 'package:conduit/l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../shared/widgets/themed_dialogs.dart';
@@ -57,18 +58,21 @@ class NavigationService {
static Future<bool> confirmNavigation({
required String title,
required String message,
String confirmText = 'Continue',
String cancelText = 'Cancel',
String? confirmText,
String? cancelText,
}) async {
final ctx = context;
if (ctx == null) return false;
final l10n = AppLocalizations.of(ctx);
final resolvedConfirm = confirmText ?? l10n?.continueAction ?? 'Continue';
final resolvedCancel = cancelText ?? l10n?.cancel ?? 'Cancel';
final result = await ThemedDialogs.confirm(
ctx,
title: title,
message: message,
confirmText: confirmText,
cancelText: cancelText,
confirmText: resolvedConfirm,
cancelText: resolvedCancel,
barrierDismissible: false,
);

View File

@@ -12,48 +12,57 @@ class UserFriendlyErrorHandler {
factory UserFriendlyErrorHandler() => _instance;
UserFriendlyErrorHandler._internal();
AppLocalizations? get _l10n {
final ctx = NavigationService.context;
if (ctx == null) return null;
return AppLocalizations.of(ctx);
}
/// Convert technical errors to user-friendly messages
String getUserMessage(dynamic error) {
final errorString = error.toString().toLowerCase();
final l10n = _l10n;
if (_isNetworkError(errorString)) {
return _getNetworkErrorMessage(errorString);
return _getNetworkErrorMessage(errorString, l10n);
} else if (_isValidationError(errorString)) {
return _getValidationErrorMessage(errorString);
return _getValidationErrorMessage(errorString, l10n);
} else if (_isServerError(errorString)) {
return _getServerErrorMessage(errorString);
return _getServerErrorMessage(errorString, l10n);
} else if (_isAuthenticationError(errorString)) {
return _getAuthenticationErrorMessage(errorString);
return _getAuthenticationErrorMessage(errorString, l10n);
} else if (_isFileError(errorString)) {
return _getFileErrorMessage(errorString);
return _getFileErrorMessage(errorString, l10n);
} else if (_isPermissionError(errorString)) {
return _getPermissionErrorMessage(errorString);
return _getPermissionErrorMessage(errorString, l10n);
}
// Log technical details for debugging
_logError(error);
// Return generic user-friendly message
return 'Something unexpected happened. Please try again.';
return l10n?.errorMessage ??
'Something unexpected happened. Please try again.';
}
/// Get recovery actions for the error
List<ErrorRecoveryAction> getRecoveryActions(dynamic error) {
final errorString = error.toString().toLowerCase();
final l10n = _l10n;
if (_isNetworkError(errorString)) {
return _getNetworkRecoveryActions();
return _getNetworkRecoveryActions(l10n);
} else if (_isServerError(errorString)) {
return _getServerRecoveryActions();
return _getServerRecoveryActions(l10n);
} else if (_isAuthenticationError(errorString)) {
return _getAuthRecoveryActions();
return _getAuthRecoveryActions(l10n);
} else if (_isFileError(errorString)) {
return _getFileRecoveryActions();
return _getFileRecoveryActions(l10n);
} else if (_isPermissionError(errorString)) {
return _getPermissionRecoveryActions();
return _getPermissionRecoveryActions(l10n);
}
return _getGenericRecoveryActions();
return _getGenericRecoveryActions(l10n);
}
/// Build error widget with recovery options
@@ -135,28 +144,33 @@ class UserFriendlyErrorHandler {
error.contains('no address associated');
}
String _getNetworkErrorMessage(String error) {
String _getNetworkErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('timeout')) {
return 'Connection timed out. Please check your internet connection and try again.';
return l10n?.networkTimeoutError ??
'Connection timed out. Please check your internet connection and try again.';
} else if (error.contains('no address associated')) {
return 'Cannot reach the server. Please check your server URL and internet connection.';
return l10n?.networkUnreachableError ??
'Cannot reach the server. Please check your server URL and internet connection.';
} else if (error.contains('connection refused')) {
return 'Server is not responding. Please verify the server is running and accessible.';
return l10n?.networkServerNotResponding ??
'Server is not responding. Please verify the server is running and accessible.';
}
return 'Network connection problem. Please check your internet connection.';
return l10n?.networkGenericError ??
'Network connection problem. Please check your internet connection.';
}
List<ErrorRecoveryAction> _getNetworkRecoveryActions() {
List<ErrorRecoveryAction> _getNetworkRecoveryActions(AppLocalizations? l10n) {
return [
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Try the request again',
description: l10n?.actionRetryRequest ?? 'Try the request again',
),
ErrorRecoveryAction(
label: 'Check Connection',
label: l10n?.checkConnection ?? 'Check Connection',
action: ErrorActionType.checkConnection,
description: 'Verify your internet connection',
description:
l10n?.actionVerifyConnection ?? 'Verify your internet connection',
),
];
}
@@ -171,28 +185,33 @@ class UserFriendlyErrorHandler {
error.contains('internal server error');
}
String _getServerErrorMessage(String error) {
String _getServerErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('500')) {
return 'Server is experiencing issues. This is usually temporary.';
return l10n?.serverError500 ??
'Server is experiencing issues. This is usually temporary.';
} else if (error.contains('502') || error.contains('503')) {
return 'Server is temporarily unavailable. Please try again in a moment.';
return l10n?.serverErrorUnavailable ??
'Server is temporarily unavailable. Please try again in a moment.';
} else if (error.contains('504')) {
return 'Server took too long to respond. Please try again.';
return l10n?.serverErrorTimeout ??
'Server took too long to respond. Please try again.';
}
return 'Server is having problems. Please try again later.';
return l10n?.serverErrorGeneric ??
'Server is having problems. Please try again later.';
}
List<ErrorRecoveryAction> _getServerRecoveryActions() {
List<ErrorRecoveryAction> _getServerRecoveryActions(AppLocalizations? l10n) {
return [
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Retry your request',
description: l10n?.actionRetryRequest ?? 'Retry your request',
),
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retryLater,
description: 'Wait a moment then try again',
description:
l10n?.actionRetryAfterDelay ?? 'Wait a moment then try again',
),
];
}
@@ -207,28 +226,32 @@ class UserFriendlyErrorHandler {
error.contains('token');
}
String _getAuthenticationErrorMessage(String error) {
String _getAuthenticationErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('401') || error.contains('unauthorized')) {
return 'Your session has expired. Please sign in again.';
return l10n?.authSessionExpired ??
'Your session has expired. Please sign in again.';
} else if (error.contains('403') || error.contains('forbidden')) {
return 'You don\'t have permission to perform this action.';
return l10n?.authForbidden ??
'You don\'t have permission to perform this action.';
} else if (error.contains('token')) {
return 'Authentication token is invalid. Please sign in again.';
return l10n?.authInvalidToken ??
'Authentication token is invalid. Please sign in again.';
}
return 'Authentication problem. Please sign in again.';
return l10n?.authGenericError ??
'Authentication problem. Please sign in again.';
}
List<ErrorRecoveryAction> _getAuthRecoveryActions() {
List<ErrorRecoveryAction> _getAuthRecoveryActions(AppLocalizations? l10n) {
return [
ErrorRecoveryAction(
label: 'Sign In',
label: l10n?.signIn ?? 'Sign In',
action: ErrorActionType.signIn,
description: 'Sign in to your account',
description: l10n?.actionSignInToAccount ?? 'Sign in to your account',
),
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Retry the request',
description: l10n?.actionRetryOperation ?? 'Retry the request',
),
];
}
@@ -242,17 +265,22 @@ class UserFriendlyErrorHandler {
error.contains('400');
}
String _getValidationErrorMessage(String error) {
String _getValidationErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('email')) {
return 'Please enter a valid email address.';
return l10n?.validationInvalidEmail ??
'Please enter a valid email address.';
} else if (error.contains('password')) {
return 'Password doesn\'t meet requirements. Please check and try again.';
return l10n?.validationWeakPassword ??
'Password doesn\'t meet requirements. Please check and try again.';
} else if (error.contains('required')) {
return 'Please fill in all required fields.';
return l10n?.validationMissingRequired ??
'Please fill in all required fields.';
} else if (error.contains('format')) {
return 'Some information is in the wrong format. Please check and try again.';
return l10n?.validationFormatError ??
'Some information is in the wrong format. Please check and try again.';
}
return 'Please check your input and try again.';
return l10n?.validationGenericError ??
'Please check your input and try again.';
}
// File error detection and handling
@@ -264,28 +292,32 @@ class UserFriendlyErrorHandler {
error.contains('access denied');
}
String _getFileErrorMessage(String error) {
String _getFileErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('not found')) {
return 'File not found. It may have been moved or deleted.';
return l10n?.fileNotFound ??
'File not found. It may have been moved or deleted.';
} else if (error.contains('access denied')) {
return 'Cannot access the file. Please check permissions.';
return l10n?.fileAccessDenied ??
'Cannot access the file. Please check permissions.';
} else if (error.contains('too large')) {
return 'File is too large. Please choose a smaller file.';
return l10n?.fileTooLarge ??
'File is too large. Please choose a smaller file.';
}
return 'Problem with the file. Please try a different file.';
return l10n?.fileGenericError ??
'Problem with the file. Please try a different file.';
}
List<ErrorRecoveryAction> _getFileRecoveryActions() {
List<ErrorRecoveryAction> _getFileRecoveryActions(AppLocalizations? l10n) {
return [
ErrorRecoveryAction(
label: 'Choose Different File',
label: l10n?.chooseDifferentFile ?? 'Choose Different File',
action: ErrorActionType.chooseFile,
description: 'Select another file',
description: l10n?.actionSelectAnotherFile ?? 'Select another file',
),
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Retry the operation',
description: l10n?.actionRetryOperation ?? 'Retry the operation',
),
];
}
@@ -298,43 +330,54 @@ class UserFriendlyErrorHandler {
error.contains('access');
}
String _getPermissionErrorMessage(String error) {
String _getPermissionErrorMessage(String error, AppLocalizations? l10n) {
if (error.contains('camera')) {
return 'Camera permission is required. Please enable it in settings.';
return l10n?.permissionCameraRequired ??
'Camera permission is required. Please enable it in settings.';
} else if (error.contains('storage')) {
return 'Storage permission is required. Please enable it in settings.';
return l10n?.permissionStorageRequired ??
'Storage permission is required. Please enable it in settings.';
} else if (error.contains('microphone')) {
return 'Microphone permission is required. Please enable it in settings.';
return l10n?.permissionMicrophoneRequired ??
'Microphone permission is required. Please enable it in settings.';
}
return 'Permission required. Please check app permissions in settings.';
return l10n?.permissionGenericError ??
'Permission required. Please check app permissions in settings.';
}
List<ErrorRecoveryAction> _getPermissionRecoveryActions() {
List<ErrorRecoveryAction> _getPermissionRecoveryActions(
AppLocalizations? l10n,
) {
return [
ErrorRecoveryAction(
label: 'Open Settings',
label: l10n?.openSettings ?? 'Open Settings',
action: ErrorActionType.openSettings,
description: 'Open app settings to grant permissions',
description:
l10n?.actionOpenAppSettings ??
'Open app settings to grant permissions',
),
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Retry after granting permission',
description:
l10n?.actionRetryAfterPermission ??
'Retry after granting permission',
),
];
}
List<ErrorRecoveryAction> _getGenericRecoveryActions() {
List<ErrorRecoveryAction> _getGenericRecoveryActions(AppLocalizations? l10n) {
return [
ErrorRecoveryAction(
label: 'Retry',
label: l10n?.retry ?? 'Retry',
action: ErrorActionType.retry,
description: 'Retry the operation',
description: l10n?.actionRetryOperation ?? 'Retry the operation',
),
ErrorRecoveryAction(
label: 'Go Back',
label: l10n?.back ?? 'Go Back',
action: ErrorActionType.goBack,
description: 'Return to previous screen',
description:
l10n?.actionReturnToPrevious ?? 'Return to previous screen',
),
];
}

View File

@@ -2209,14 +2209,18 @@ class _ModelSelectorSheetState extends ConsumerState<_ModelSelectorSheet> {
icon: Platform.isIOS
? CupertinoIcons.photo
: Icons.image,
label: 'Multimodal',
label: AppLocalizations.of(
context,
)!.modelCapabilityMultimodal,
),
if (_modelSupportsReasoning(model))
_capabilityChip(
icon: Platform.isIOS
? CupertinoIcons.lightbulb
: Icons.psychology_alt,
label: 'Reasoning',
label: AppLocalizations.of(
context,
)!.modelCapabilityReasoning,
),
],
),

View File

@@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/providers/app_providers.dart';
import '../../../core/utils/markdown_to_text.dart';
import '../../../l10n/app_localizations.dart';
import '../services/voice_call_service.dart';
class VoiceCallPage extends ConsumerStatefulWidget {
@@ -102,8 +103,10 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
void _showErrorDialog(String message) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Error'),
builder: (ctx) {
final dialogL10n = AppLocalizations.of(ctx)!;
return AlertDialog(
title: Text(dialogL10n.error),
content: Text(message),
actions: [
TextButton(
@@ -113,10 +116,11 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
Navigator.of(context).pop();
}
},
child: const Text('OK'),
child: Text(dialogL10n.ok),
),
],
),
);
},
);
}
@@ -139,11 +143,12 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
final primaryColor = Theme.of(context).colorScheme.primary;
final backgroundColor = Theme.of(context).scaffoldBackgroundColor;
final textColor = Theme.of(context).colorScheme.onSurface;
final l10n = AppLocalizations.of(context)!;
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
title: const Text('Voice Call'),
title: Text(l10n.voiceCallTitle),
leading: IconButton(
icon: const Icon(CupertinoIcons.xmark),
onPressed: () async {
@@ -198,10 +203,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
vertical: 16,
),
child: Text(
'Please check:\n'
'• Microphone permissions are granted\n'
'• Speech recognition is available on your device\n'
'• You are connected to the server',
l10n.voiceCallErrorHelp,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
@@ -217,7 +219,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
// Control buttons
Padding(
padding: const EdgeInsets.all(32),
child: _buildControlButtons(primaryColor),
child: _buildControlButtons(primaryColor, l10n),
),
],
),
@@ -345,7 +347,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
);
}
Widget _buildControlButtons(Color primaryColor) {
Widget _buildControlButtons(Color primaryColor, AppLocalizations l10n) {
final errorColor = Theme.of(context).colorScheme.error;
final warningColor = Colors.orange;
final successColor = Theme.of(context).colorScheme.secondary;
@@ -357,7 +359,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
buttons.add(
_buildActionButton(
icon: CupertinoIcons.arrow_clockwise,
label: 'Retry',
label: l10n.retry,
color: primaryColor,
onPressed: () async {
await _initializeCall();
@@ -373,7 +375,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
buttons.add(
_buildActionButton(
icon: CupertinoIcons.pause_fill,
label: 'Pause',
label: l10n.voiceCallPause,
color: warningColor,
onPressed: () async {
await _service?.pauseListening();
@@ -384,7 +386,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
buttons.add(
_buildActionButton(
icon: CupertinoIcons.play_fill,
label: 'Resume',
label: l10n.voiceCallResume,
color: successColor,
onPressed: () async {
await _service?.resumeListening();
@@ -398,7 +400,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
buttons.add(
_buildActionButton(
icon: CupertinoIcons.stop_fill,
label: 'Stop',
label: l10n.voiceCallStop,
color: warningColor,
onPressed: () async {
await _service?.cancelSpeaking();
@@ -411,7 +413,7 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
buttons.add(
_buildActionButton(
icon: CupertinoIcons.phone_down_fill,
label: 'End Call',
label: l10n.voiceCallEnd,
color: errorColor,
onPressed: () async {
await _service?.stopCall();
@@ -453,23 +455,24 @@ class _VoiceCallPageState extends ConsumerState<VoiceCallPage>
}
String _getStateLabel() {
final l10n = AppLocalizations.of(context)!;
switch (_currentState) {
case VoiceCallState.idle:
return 'Ready';
return l10n.voiceCallReady;
case VoiceCallState.connecting:
return 'Connecting...';
return l10n.voiceCallConnecting;
case VoiceCallState.listening:
return 'Listening';
return l10n.voiceCallListening;
case VoiceCallState.paused:
return 'Paused';
return l10n.voiceCallPaused;
case VoiceCallState.processing:
return 'Thinking...';
return l10n.voiceCallProcessing;
case VoiceCallState.speaking:
return 'Speaking';
return l10n.voiceCallSpeaking;
case VoiceCallState.error:
return 'Error';
return l10n.error;
case VoiceCallState.disconnected:
return 'Disconnected';
return l10n.voiceCallDisconnected;
}
}
}

View File

@@ -1162,7 +1162,7 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
// Inline version toggle: Prev [1/n] Next
ChatActionButton(
icon: Icons.chevron_left,
label: 'Prev',
label: l10n.previousLabel,
onTap: () {
setState(() {
if (_activeVersionIndex < 0) {
@@ -1181,7 +1181,7 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
),
ChatActionButton(
icon: Icons.chevron_right,
label: 'Next',
label: l10n.nextLabel,
onTap: () {
setState(() {
if (_activeVersionIndex < 0) return; // already live

View File

@@ -23,17 +23,18 @@ class AppCustomizationPage extends ConsumerWidget {
final settings = ref.watch(appSettingsProvider);
final themeMode = ref.watch(appThemeModeProvider);
final platformBrightness = MediaQuery.platformBrightnessOf(context);
final l10n = AppLocalizations.of(context)!;
final themeDescription = () {
if (themeMode == ThemeMode.system) {
final systemThemeLabel = platformBrightness == Brightness.dark
? AppLocalizations.of(context)!.themeDark
: AppLocalizations.of(context)!.themeLight;
return AppLocalizations.of(context)!.followingSystem(systemThemeLabel);
? l10n.themeDark
: l10n.themeLight;
return l10n.followingSystem(systemThemeLabel);
}
if (themeMode == ThemeMode.dark) {
return AppLocalizations.of(context)!.currentlyUsingDarkTheme;
return l10n.currentlyUsingDarkTheme;
}
return AppLocalizations.of(context)!.currentlyUsingLightTheme;
return l10n.currentlyUsingLightTheme;
}();
final locale = ref.watch(appLocaleProvider);
final currentLanguageCode = locale?.languageCode ?? 'system';
@@ -237,11 +238,12 @@ class AppCustomizationPage extends ConsumerWidget {
WidgetRef ref,
TweakcnThemeDefinition activeTheme,
) {
final l10n = AppLocalizations.of(context)!;
final palettes = TweakcnThemes.all;
return _ExpandableCard(
title: AppLocalizations.of(context)!.themePalette,
subtitle: activeTheme.label,
title: l10n.themePalette,
subtitle: activeTheme.label(l10n),
icon: UiUtils.platformIcon(
ios: CupertinoIcons.square_fill_on_square_fill,
android: Icons.palette,
@@ -252,6 +254,7 @@ class AppCustomizationPage extends ConsumerWidget {
for (final palette in palettes)
_PaletteOption(
themeDefinition: palette,
l10n: l10n,
activeId: activeTheme.id,
onSelect: () => ref
.read(appThemePaletteProvider.notifier)
@@ -333,9 +336,7 @@ class AppCustomizationPage extends ConsumerWidget {
}
final l10n = AppLocalizations.of(context)!;
final selectedCountText = selectedCount == 0
? 'No actions'
: '$selectedCount action${selectedCount == 1 ? '' : 's'} selected';
final selectedCountText = l10n.quickActionsSelectedCount(selectedCount);
return _ExpandableCard(
title: l10n.quickActionsDescription,
@@ -501,7 +502,7 @@ class AppCustomizationPage extends ConsumerWidget {
),
const SizedBox(width: Spacing.sm),
Text(
'Engine',
l10n.ttsEngineLabel,
style:
theme.bodyMedium?.copyWith(
color: theme.sidebarForeground,
@@ -514,7 +515,7 @@ class AppCustomizationPage extends ConsumerWidget {
spacing: Spacing.sm,
children: [
ChoiceChip(
label: const Text('On Device'),
label: Text(l10n.ttsEngineDevice),
selected: settings.ttsEngine == TtsEngine.device,
showCheckmark: false,
selectedColor: theme.buttonPrimary,
@@ -541,7 +542,7 @@ class AppCustomizationPage extends ConsumerWidget {
},
),
ChoiceChip(
label: const Text('Server'),
label: Text(l10n.ttsEngineServer),
selected: settings.ttsEngine == TtsEngine.server,
showCheckmark: false,
selectedColor: theme.buttonPrimary,
@@ -1078,7 +1079,7 @@ class AppCustomizationPage extends ConsumerWidget {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${l10n.error}: $e'),
content: Text(l10n.errorWithMessage(e.toString())),
backgroundColor: theme.error,
),
);
@@ -1509,11 +1510,13 @@ class _PaletteOption extends StatelessWidget {
required this.themeDefinition,
required this.activeId,
required this.onSelect,
required this.l10n,
});
final TweakcnThemeDefinition themeDefinition;
final String activeId;
final VoidCallback onSelect;
final AppLocalizations l10n;
@override
Widget build(BuildContext context) {
@@ -1544,7 +1547,7 @@ class _PaletteOption extends StatelessWidget {
children: [
Expanded(
child: Text(
themeDefinition.label,
themeDefinition.label(l10n),
style: theme.bodyMedium?.copyWith(
color: theme.sidebarForeground,
fontWeight: isSelected
@@ -1567,7 +1570,7 @@ class _PaletteOption extends StatelessWidget {
),
const SizedBox(height: Spacing.xxs),
Text(
themeDefinition.description,
themeDefinition.description(l10n),
style:
theme.bodySmall?.copyWith(
color: theme.sidebarForeground.withValues(

View File

@@ -1172,7 +1172,7 @@ class _DefaultModelBottomSheetState
if (isAutoSelect) ...[
const SizedBox(height: Spacing.xs),
Text(
'Let the app choose the best model',
AppLocalizations.of(context)!.autoSelectDescription,
style: TextStyle(
fontSize: AppTypography.bodySmall,
color: context.conduitTheme.textSecondary,
@@ -1189,14 +1189,18 @@ class _DefaultModelBottomSheetState
icon: Platform.isIOS
? CupertinoIcons.photo
: Icons.image,
label: 'Multimodal',
label: AppLocalizations.of(
context,
)!.modelCapabilityMultimodal,
),
if (_modelSupportsReasoning(model))
_capabilityChip(
icon: Platform.isIOS
? CupertinoIcons.lightbulb
: Icons.psychology_alt,
label: 'Reasoning',
label: AppLocalizations.of(
context,
)!.modelCapabilityReasoning,
),
],
),

View File

@@ -1,7 +1,6 @@
{
"@@locale": "de",
"appTitle": "Conduit",
"initializationFailed": "Initialisierung fehlgeschlagen",
"retry": "Erneut versuchen",
"back": "Zurück",
"you": "Du",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Untertitel mit den verfügbaren Aktionen, wenn der Server nicht erreichbar ist"
},
"stillOfflineMessage": "Der Server ist weiterhin nicht erreichbar. Prüfe deine Verbindung und versuche es erneut.",
"@stillOfflineMessage": {
"description": "Statusnachricht nach einem erneuten Versuch ohne wiederhergestellte Verbindung"
},
"account": "Konto",
"supportConduit": "Conduit unterstützen",
"supportConduitSubtitle": "Hilf, die Weiterentwicklung und neue Funktionen zu finanzieren.",
@@ -37,32 +32,14 @@
"noResults": "Keine Ergebnisse",
"searchModels": "Modelle suchen...",
"errorMessage": "Etwas ist schief gelaufen. Bitte versuche es erneut.",
"loginButton": "Anmelden",
"menuItem": "Einstellungen",
"dynamicContentWithPlaceholder": "Willkommen, {name}!",
"itemsCount": "{count, plural, =0{Keine Elemente} one{1 Element} other{{count} Elemente}}",
"closeButtonSemantic": "Schließen",
"loadingContent": "Inhalt wird geladen",
"noItems": "Keine Elemente",
"noItemsToDisplay": "Keine Elemente zum Anzeigen",
"loadMore": "Mehr laden",
"workspace": "Arbeitsbereich",
"recentFiles": "Zuletzt verwendete Dateien",
"knowledgeBase": "Wissensdatenbank",
"noFilesYet": "Noch keine Dateien",
"uploadDocsPrompt": "Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden",
"uploadFirstFile": "Erste Datei hochladen",
"attachments": "Anhänge",
"knowledgeBaseEmpty": "Wissensdatenbank ist leer",
"createCollectionsPrompt": "Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz",
"chooseSourcePhoto": "Quelle auswählen",
"takePhoto": "Foto aufnehmen",
"chooseFromGallery": "Aus Fotos auswählen",
"document": "Dokument",
"documentHint": "PDF-, Word- oder Textdatei",
"uploadFileTitle": "Datei hochladen",
"fileUploadComingSoon": "Dateiupload für {type} kommt bald!",
"kbCreationComingSoon": "Erstellung der Wissensdatenbank kommt bald!",
"backToServerSetup": "Zur Servereinrichtung zurück",
"connectedToServer": "Mit Server verbunden",
"signIn": "Anmelden",
@@ -124,9 +101,7 @@
"onboardQuickTitle": "Schnellaktionen",
"onboardQuickSubtitle": "Menü öffnen, um zwischen Chats, Arbeitsbereich und Profil zu wechseln.",
"onboardQuickBullet1": "Menü tippen für Chats, Arbeitsbereich, Profil",
"onboardQuickBullet2": "Neuer Chat starten oder Modelle oben verwalten"
,
"addAttachment": "Anhang hinzufügen",
"onboardQuickBullet2": "Neuer Chat starten oder Modelle oben verwalten",
"attachmentLabel": "Anhang",
"tools": "Werkzeuge",
"voiceInput": "Spracheingabe",
@@ -157,19 +132,13 @@
"invalidDataUrl": "Ungültiges Data-URL-Format",
"failedToDecodeImage": "Bild konnte nicht decodiert werden",
"invalidImageFormat": "Ungültiges Bildformat",
"emptyImageData": "Leere Bilddaten"
,
"featureRequiresInternet": "Diese Funktion erfordert eine Internetverbindung",
"messagesWillSendWhenOnline": "Nachrichten werden gesendet, sobald du wieder online bist",
"emptyImageData": "Leere Bilddaten",
"confirm": "Bestätigen",
"cancel": "Abbrechen"
,
"cancel": "Abbrechen",
"ok": "OK",
"inputField": "Eingabefeld",
"captureDocumentOrImage": "Dokument oder Bild aufnehmen",
"checkConnection": "Verbindung prüfen",
"openSettings": "Einstellungen öffnen",
"chooseDifferentFile": "Andere Datei wählen",
"goBack": "Zurück",
"technicalDetails": "Technische Details",
"save": "Speichern",
@@ -181,18 +150,9 @@
"newChat": "Neuer Chat",
"more": "Mehr",
"clear": "Leeren",
"searchHint": "Suchen...",
"searchConversations": "Konversationen durchsuchen...",
"create": "Erstellen",
"folderCreated": "Ordner erstellt",
"failedToCreateFolder": "Ordner konnte nicht erstellt werden",
"movedChatToFolder": "\"{title}\" nach \"{folder}\" verschoben",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "Chat konnte nicht verschoben werden",
"failedToLoadChats": "Chats konnten nicht geladen werden",
"failedToUpdatePin": "Pin konnte nicht aktualisiert werden",
@@ -222,13 +182,17 @@
"deleteMessagesMessage": "{count} Nachrichten löschen?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Route nicht gefunden: {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Chat löschen",
@@ -254,8 +218,7 @@
"ttsStop": "Stoppen",
"edit": "Bearbeiten",
"regenerate": "Neu generieren",
"noConversationsYet": "Noch keine Unterhaltungen"
,
"noConversationsYet": "Noch keine Unterhaltungen",
"usernameOrEmailHint": "Gib deinen Benutzernamen oder deine EMail ein",
"passwordHint": "Gib dein Passwort ein",
"enterApiKey": "Gib deinen API-Schlüssel ein",
@@ -275,31 +238,55 @@
"headerNameTooLong": "Header-Name zu lang (max. 64 Zeichen)",
"headerNameInvalidChars": "Ungültiger Header-Name. Verwende nur Buchstaben, Zahlen und diese Zeichen: !#$&-^_`|~",
"headerNameReserved": "Reservierten Header \"{key}\" kann nicht überschrieben werden",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "Header-Wert darf nicht leer sein",
"headerValueTooLong": "Header-Wert zu lang (max. 1024 Zeichen)",
"headerValueInvalidChars": "Header-Wert enthält ungültige Zeichen. Nur druckbare ASCII-Zeichen verwenden.",
"headerValueUnsafe": "Header-Wert scheint potenziell unsicheren Inhalt zu enthalten",
"headerAlreadyExists": "Header \"{key}\" existiert bereits. Zum Aktualisieren zuerst entfernen.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"maxHeadersReachedDetail": "Maximal 10 benutzerdefinierte Header zulässig. Einige entfernen, um mehr hinzuzufügen."
,
"editMessage": "Nachricht bearbeiten"
,
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Maximal 10 benutzerdefinierte Header zulässig. Einige entfernen, um mehr hinzuzufügen.",
"noModelsAvailable": "Keine Modelle verfügbar",
"followingSystem": "Dem System folgen: {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Dunkel",
"themePalette": "Farbpalette",
"@themePalette": {"description": "Titel für die Auswahl der App-Farbpalette."},
"themePaletteDescription": "Wählen Sie die Akzentfarben für Schaltflächen, Karten und Chatblasen.",
"@themePaletteDescription": {"description": "Hilfetext zur Erklärung der Palettenauswahl."},
"@themePalette": {
"description": "Titel für die Auswahl der App-Farbpalette."
},
"themeLight": "Hell",
"currentlyUsingDarkTheme": "Aktuell dunkles Thema",
"currentlyUsingLightTheme": "Aktuell helles Thema",
"aboutConduit": "Über Conduit",
"versionLabel": "Version: {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "GitHub-Repository",
"unableToLoadAppInfo": "App-Informationen konnten nicht geladen werden",
"thinking": "Denkt…",
@@ -307,9 +294,13 @@
"thoughtForDuration": "Gedacht für {duration}",
"@thoughtForDuration": {
"description": "Zeigt an, wie lange der Assistent nachgedacht hat.",
"placeholders": {"duration": {"type": "String", "example": "3 s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3 s"
}
,
}
},
"appCustomization": "Anpassung",
"appCustomizationSubtitle": "Design, Sprache, Stimme und Quick Pills",
"quickActionsDescription": "Schnellzugriffe im Chat",
@@ -332,12 +323,413 @@
"display": "Anzeige",
"realtime": "Echtzeit",
"transportMode": "Transportmodus",
"transportModeDescription": "Wähle, wie die App für Echtzeit-Updates verbindet.",
"mode": "Modus",
"transportModePolling": "Polling-Fallback",
"transportModeWs": "Nur WebSocket",
"transportModePollingInfo": "Fällt auf HTTP-Polling zurück, wenn WebSockets blockiert sind. Wechselt nach Möglichkeit zu WebSocket.",
"transportModeWsInfo": "Geringerer Overhead, kann jedoch hinter strikten Proxys/Firewalls fehlschlagen.",
"websocketConnectionError": "Echtzeit-Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihr Netzwerk und die Serverkonfiguration.",
"websocketReconnectFailed": "Echtzeit-Verbindung fehlgeschlagen. Streaming funktioniert möglicherweise nicht ordnungsgemäß."
"quickActionsSelectedCount": "{count, plural, =0{Keine Aktionen ausgewählt} one{{count} Aktion ausgewählt} other{{count} Aktionen ausgewählt}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Lass die App das beste Modell auswählen",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Engine",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "Auf dem Gerät",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Server",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Multimodal",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Reasoning",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Sprachanruf",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Pause",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Fortsetzen",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Stopp",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Anruf beenden",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Andere Datei auswählen",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Fehler: {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "Verbindung abgelaufen. Bitte überprüfe deine Internetverbindung und versuche es erneut.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "Server nicht erreichbar. Bitte überprüfe die Server-URL und deine Internetverbindung.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "Server reagiert nicht. Bitte stelle sicher, dass der Server läuft und erreichbar ist.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Netzwerkproblem. Bitte überprüfe deine Internetverbindung.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "Der Server hat Probleme. Das ist meist nur vorübergehend.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "Server vorübergehend nicht verfügbar. Bitte versuche es gleich noch einmal.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "Der Server hat zu lange für eine Antwort gebraucht. Bitte versuche es erneut.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "Der Server hat Schwierigkeiten. Bitte versuche es später erneut.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "Du hast keine Berechtigung für diese Aktion.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "Der Authentifizierungstoken ist ungültig. Bitte melde dich erneut an.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Authentifizierungsproblem. Bitte melde dich erneut an.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Bitte gib eine gültige E-Mail-Adresse ein.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "Das Passwort erfüllt die Anforderungen nicht. Bitte überprüfe es und versuche es erneut.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Bitte fülle alle Pflichtfelder aus.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Einige Angaben haben ein falsches Format. Bitte überprüfe sie und versuche es erneut.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Bitte überprüfe deine Eingaben und versuche es erneut.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "Datei nicht gefunden. Vielleicht wurde sie verschoben oder gelöscht.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "Datei kann nicht geöffnet werden. Bitte prüfe die Berechtigungen.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "Datei ist zu groß. Bitte wähle eine kleinere Datei.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Problem mit der Datei. Bitte versuche eine andere Datei.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "Kamerazugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "Speicherzugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "Mikrofonzugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "Berechtigung erforderlich. Bitte prüfe die App-Berechtigungen in den Einstellungen.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Versuche die Anfrage erneut.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Überprüfe deine Internetverbindung.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Wiederhole den Vorgang.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Warte einen Moment und versuche es dann erneut.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Melde dich bei deinem Konto an.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Wähle eine andere Datei.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Öffne die App-Einstellungen, um Berechtigungen zu erteilen.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Versuche es erneut, nachdem du die Berechtigung erteilt hast.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Zur vorherigen Ansicht zurückkehren.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Weiter",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Laden",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Laden: {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Fehler: {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Fehler: {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Erfolg: {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Pflichtfeld",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Ein",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Aus",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Dialog: {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Zurück",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Weiter",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Schlichtes neutrales Design für Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Warmes, haptisches Farbschema aus dem Claude-Webclient.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Verspielte Verläufe inspiriert vom T3-Stack.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Sanfte Pastellpalette.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Warmes Orange-Schiefer-Farbschema.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Bereit",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Verbinden...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "Zuhören",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "Pausiert",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Denkt...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Spricht",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Getrennt",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Bitte prüfe:\n• Mikrofonberechtigungen sind erteilt\n• Spracherkennung ist auf deinem Gerät verfügbar\n• Du bist mit dem Server verbunden",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
{
"@@locale": "es",
"appTitle": "Conduit",
"initializationFailed": "Error de inicialización",
"retry": "Reintentar",
"back": "Atrás",
"you": "Tú",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Subtítulo que explica las acciones disponibles cuando no se puede acceder al servidor"
},
"stillOfflineMessage": "Todavía no podemos conectarnos al servidor. Verifica tu conexión e inténtalo de nuevo.",
"@stillOfflineMessage": {
"description": "Mensaje de estado después de un reintento cuando no se ha restaurado la conexión"
},
"account": "Cuenta",
"supportConduit": "Apoyar Conduit",
"supportConduitSubtitle": "Mantén Conduit independiente financiando el desarrollo continuo.",
@@ -37,32 +32,14 @@
"noResults": "Sin resultados",
"searchModels": "Buscar modelos...",
"errorMessage": "Algo salió mal. Por favor, inténtalo de nuevo.",
"loginButton": "Iniciar sesión",
"menuItem": "Configuración",
"dynamicContentWithPlaceholder": "¡Bienvenido, {name}!",
"itemsCount": "{count, plural, =0{Sin elementos} one{1 elemento} other{{count} elementos}}",
"closeButtonSemantic": "Cerrar",
"loadingContent": "Cargando contenido",
"noItems": "Sin elementos",
"noItemsToDisplay": "No hay elementos para mostrar",
"loadMore": "Cargar más",
"workspace": "Espacio de trabajo",
"recentFiles": "Archivos recientes",
"knowledgeBase": "Base de conocimientos",
"noFilesYet": "Aún no hay archivos",
"uploadDocsPrompt": "Sube documentos para referenciarlos en tus conversaciones con Conduit",
"uploadFirstFile": "Sube tu primer archivo",
"attachments": "Adjuntos",
"knowledgeBaseEmpty": "La base de conocimientos está vacía",
"createCollectionsPrompt": "Crea colecciones de documentos relacionados para referencia fácil",
"chooseSourcePhoto": "Elige tu fuente",
"takePhoto": "Tomar una foto",
"chooseFromGallery": "Elegir de tus fotos",
"document": "Documento",
"documentHint": "Archivo PDF, Word o de texto",
"uploadFileTitle": "Subir archivo",
"fileUploadComingSoon": "¡La carga de archivos para {type} estará disponible pronto!",
"kbCreationComingSoon": "¡La creación de base de conocimientos estará disponible pronto!",
"backToServerSetup": "Volver a configuración del servidor",
"connectedToServer": "Conectado al servidor",
"signIn": "Iniciar sesión",
@@ -125,7 +102,6 @@
"onboardQuickSubtitle": "Abre el menú para cambiar entre Conversaciones, Espacio de trabajo y Perfil.",
"onboardQuickBullet1": "Toca el menú para acceder a Conversaciones, Espacio de trabajo, Perfil",
"onboardQuickBullet2": "Inicia Nueva conversación o gestiona modelos desde la barra superior",
"addAttachment": "Añadir adjunto",
"attachmentLabel": "Adjunto",
"tools": "Herramientas",
"voiceInput": "Entrada de voz",
@@ -157,16 +133,12 @@
"failedToDecodeImage": "No se pudo decodificar la imagen",
"invalidImageFormat": "Formato de imagen inválido",
"emptyImageData": "Datos de imagen vacíos",
"featureRequiresInternet": "Esta función requiere conexión a Internet",
"messagesWillSendWhenOnline": "Los mensajes se enviarán cuando vuelvas a estar en línea",
"confirm": "Confirmar",
"cancel": "Cancelar",
"ok": "OK",
"inputField": "Campo de entrada",
"captureDocumentOrImage": "Capturar un documento o imagen",
"checkConnection": "Verificar conexión",
"openSettings": "Abrir configuración",
"chooseDifferentFile": "Elegir otro archivo",
"goBack": "Volver",
"technicalDetails": "Detalles técnicos",
"save": "Guardar",
@@ -178,18 +150,9 @@
"newChat": "Nueva conversación",
"more": "Más",
"clear": "Limpiar",
"searchHint": "Buscar...",
"searchConversations": "Buscar conversaciones...",
"create": "Crear",
"folderCreated": "Carpeta creada",
"failedToCreateFolder": "No se pudo crear la carpeta",
"movedChatToFolder": "Se movió \"{title}\" a \"{folder}\"",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "No se pudo mover la conversación",
"failedToLoadChats": "No se pudieron cargar las conversaciones",
"failedToUpdatePin": "No se pudo actualizar el anclaje",
@@ -219,13 +182,17 @@
"deleteMessagesMessage": "¿Eliminar {count} mensajes?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Ruta no encontrada: {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Eliminar conversación",
@@ -271,29 +238,55 @@
"headerNameTooLong": "Nombre de encabezado demasiado largo (máx. 64 caracteres)",
"headerNameInvalidChars": "Nombre de encabezado inválido. Usa solo letras, números y estos símbolos: !#$&-^_`|~",
"headerNameReserved": "No se puede sobrescribir el encabezado reservado \"{key}\"",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "El valor del encabezado no puede estar vacío",
"headerValueTooLong": "Valor de encabezado demasiado largo (máx. 1024 caracteres)",
"headerValueInvalidChars": "El valor del encabezado contiene caracteres inválidos. Usa solo ASCII imprimible.",
"headerValueUnsafe": "El valor del encabezado parece contener contenido potencialmente inseguro",
"headerAlreadyExists": "El encabezado \"{key}\" ya existe. Elimínalo primero para actualizarlo.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Máximo de 10 encabezados personalizados permitidos. Elimina algunos para añadir más.",
"editMessage": "Editar mensaje",
"noModelsAvailable": "No hay modelos disponibles",
"followingSystem": "Siguiendo el sistema: {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Oscuro",
"themePalette": "Paleta de acentos",
"@themePalette": {"description": "Título para seleccionar la paleta de colores de la aplicación."},
"themePaletteDescription": "Elige los colores de acento usados para botones, tarjetas y burbujas de chat.",
"@themePaletteDescription": {"description": "Texto de ayuda que explica la selección de paleta."},
"@themePalette": {
"description": "Título para seleccionar la paleta de colores de la aplicación."
},
"themeLight": "Claro",
"currentlyUsingDarkTheme": "Usando actualmente el tema oscuro",
"currentlyUsingLightTheme": "Usando actualmente el tema claro",
"aboutConduit": "Acerca de Conduit",
"versionLabel": "Versión: {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "Repositorio GitHub",
"unableToLoadAppInfo": "No se puede cargar información de la aplicación",
"thinking": "Pensando...",
@@ -301,7 +294,12 @@
"thoughtForDuration": "Pensó durante {duration}",
"@thoughtForDuration": {
"description": "Muestra cuánto tiempo el asistente estuvo pensando antes de responder.",
"placeholders": {"duration": {"type": "String", "example": "3s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3s"
}
}
},
"appCustomization": "Personalización",
"appCustomizationSubtitle": "Tema, idioma, voz y quickpills",
@@ -325,12 +323,413 @@
"display": "Visualización",
"realtime": "Tiempo real",
"transportMode": "Modo de transporte",
"transportModeDescription": "Elige cómo se conecta la aplicación para actualizaciones en tiempo real.",
"mode": "Modo",
"transportModePolling": "Polling de respaldo",
"transportModeWs": "Solo WebSocket",
"transportModePollingInfo": "Recurrirá a HTTP polling si WebSocket está bloqueado. Se actualizará a WebSocket cuando sea posible.",
"transportModeWsInfo": "Menor sobrecarga, pero puede fallar detrás de proxies/firewalls estrictos.",
"websocketConnectionError": "No se puede establecer la conexión en tiempo real. Por favor, verifica tu red y la configuración del servidor.",
"websocketReconnectFailed": "Fallo en la conexión en tiempo real. El streaming podría no funcionar correctamente."
"quickActionsSelectedCount": "{count, plural, =0{No hay acciones seleccionadas} one{{count} acción seleccionada} other{{count} acciones seleccionadas}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Deja que la aplicación elija el mejor modelo",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Motor",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "En el dispositivo",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Servidor",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Multimodal",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Razonamiento",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Llamada de voz",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Pausar",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Reanudar",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Detener",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Finalizar llamada",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Seleccionar otro archivo",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Error: {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "La conexión agotó el tiempo de espera. Verifica tu conexión a Internet e inténtalo de nuevo.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "No se puede alcanzar el servidor. Verifica la URL del servidor y tu conexión a Internet.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "El servidor no responde. Verifica que esté en ejecución y accesible.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Problema de conexión de red. Verifica tu conexión a Internet.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "El servidor tiene problemas. Normalmente es temporal.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "El servidor está temporalmente no disponible. Inténtalo de nuevo en un momento.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "El servidor tardó demasiado en responder. Inténtalo de nuevo.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "El servidor está teniendo problemas. Inténtalo más tarde.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "Tu sesión ha expirado. Vuelve a iniciar sesión.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "No tienes permiso para realizar esta acción.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "El token de autenticación no es válido. Vuelve a iniciar sesión.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Problema de autenticación. Vuelve a iniciar sesión.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Introduce una dirección de correo válida.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "La contraseña no cumple los requisitos. Revísala e inténtalo de nuevo.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Completa todos los campos obligatorios.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Algunos datos tienen un formato incorrecto. Revísalos e inténtalo de nuevo.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Revisa tu entrada e inténtalo de nuevo.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "Archivo no encontrado. Puede que se haya movido o eliminado.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "No se puede acceder al archivo. Verifica los permisos.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "El archivo es demasiado grande. Elige uno más pequeño.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Problema con el archivo. Prueba con otro archivo.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "Se requiere permiso de cámara. Actívalo en los ajustes.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "Se requiere permiso de almacenamiento. Actívalo en los ajustes.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "Se requiere permiso de micrófono. Actívalo en los ajustes.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "Se requiere un permiso. Revisa los permisos de la app en los ajustes.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Intenta la solicitud nuevamente.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Verifica tu conexión a Internet.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Vuelve a intentar la operación.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Espera un momento y vuelve a intentarlo.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Inicia sesión en tu cuenta.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Selecciona otro archivo.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Abre la configuración de la aplicación para otorgar permisos.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Vuelve a intentarlo después de otorgar el permiso.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Vuelve a la pantalla anterior.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Continuar",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Cargando",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Cargando: {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Error: {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Error: {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Éxito: {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Campo obligatorio",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Activado",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Desactivado",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Diálogo: {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Anterior",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Siguiente",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Tema neutro y limpio diseñado para Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Paleta cálida y táctil inspirada en el cliente web de Claude.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Degradados divertidos inspirados en la marca T3 Stack.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Paleta suave de tonos pastel.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Paleta cálida de tonos naranja y gris pizarra.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Listo",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Conectando...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "Escuchando",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "En pausa",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Pensando...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Hablando",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Desconectado",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Comprueba lo siguiente:\n• Los permisos del micrófono están concedidos\n• El reconocimiento de voz está disponible en tu dispositivo\n• Estás conectado al servidor",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -1,7 +1,6 @@
{
"@@locale": "fr",
"appTitle": "Conduit",
"initializationFailed": "Échec de l'initialisation",
"retry": "Réessayer",
"back": "Retour",
"you": "Vous",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Sous-titre expliquant les actions possibles quand le serveur est injoignable"
},
"stillOfflineMessage": "Nous ne pouvons toujours pas joindre le serveur. Vérifiez votre connexion et réessayez.",
"@stillOfflineMessage": {
"description": "Message d'état après une tentative de reconnexion sans succès"
},
"account": "Compte",
"supportConduit": "Soutenir Conduit",
"supportConduitSubtitle": "Financez le développement continu et les nouvelles fonctionnalités.",
@@ -37,32 +32,14 @@
"noResults": "Aucun résultat",
"searchModels": "Rechercher des modèles...",
"errorMessage": "Une erreur s'est produite. Veuillez réessayer.",
"loginButton": "Connexion",
"menuItem": "Paramètres",
"dynamicContentWithPlaceholder": "Bienvenue, {name} !",
"itemsCount": "{count, plural, =0{Aucun élément} one{1 élément} other{{count} éléments}}",
"closeButtonSemantic": "Fermer",
"loadingContent": "Chargement du contenu",
"noItems": "Aucun élément",
"noItemsToDisplay": "Aucun élément à afficher",
"loadMore": "Charger plus",
"workspace": "Espace de travail",
"recentFiles": "Fichiers récents",
"knowledgeBase": "Base de connaissances",
"noFilesYet": "Pas encore de fichiers",
"uploadDocsPrompt": "Importez des documents à utiliser dans vos conversations avec Conduit",
"uploadFirstFile": "Importer votre premier fichier",
"attachments": "Pièces jointes",
"knowledgeBaseEmpty": "La base de connaissances est vide",
"createCollectionsPrompt": "Créez des collections de documents liés pour une référence facile",
"chooseSourcePhoto": "Choisir la source",
"takePhoto": "Prendre une photo",
"chooseFromGallery": "Choisir depuis vos photos",
"document": "Document",
"documentHint": "Fichier PDF, Word ou texte",
"uploadFileTitle": "Importer un fichier",
"fileUploadComingSoon": "Le téléversement de fichiers pour {type} arrive bientôt !",
"kbCreationComingSoon": "La création de la base de connaissances arrive bientôt !",
"backToServerSetup": "Retour à la configuration du serveur",
"connectedToServer": "Connecté au serveur",
"signIn": "Se connecter",
@@ -124,9 +101,7 @@
"onboardQuickTitle": "Actions rapides",
"onboardQuickSubtitle": "Ouvrez le menu pour passer entre Chats, Espace de travail et Profil.",
"onboardQuickBullet1": "Touchez le menu pour accéder à Chats, Espace, Profil",
"onboardQuickBullet2": "Lancez Nouveau chat ou gérez les modèles depuis la barre"
,
"addAttachment": "Ajouter une pièce jointe",
"onboardQuickBullet2": "Lancez Nouveau chat ou gérez les modèles depuis la barre",
"attachmentLabel": "Pièce jointe",
"tools": "Outils",
"voiceInput": "Entrée vocale",
@@ -157,19 +132,13 @@
"invalidDataUrl": "Format d'URL de données invalide",
"failedToDecodeImage": "Échec du décodage de l'image",
"invalidImageFormat": "Format d'image invalide",
"emptyImageData": "Données d'image vides"
,
"featureRequiresInternet": "Cette fonctionnalité nécessite une connexion Internet",
"messagesWillSendWhenOnline": "Les messages seront envoyés lorsque vous serez de nouveau en ligne",
"emptyImageData": "Données d'image vides",
"confirm": "Confirmer",
"cancel": "Annuler"
,
"cancel": "Annuler",
"ok": "OK",
"inputField": "Champ de saisie",
"captureDocumentOrImage": "Capturer un document ou une image",
"checkConnection": "Vérifier la connexion",
"openSettings": "Ouvrir les réglages",
"chooseDifferentFile": "Choisir un autre fichier",
"goBack": "Retour",
"technicalDetails": "Détails techniques",
"save": "Enregistrer",
@@ -181,18 +150,9 @@
"newChat": "Nouveau chat",
"more": "Plus",
"clear": "Effacer",
"searchHint": "Rechercher...",
"searchConversations": "Rechercher des conversations...",
"create": "Créer",
"folderCreated": "Dossier créé",
"failedToCreateFolder": "Échec de la création du dossier",
"movedChatToFolder": "\"{title}\" déplacé vers \"{folder}\"",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "Échec du déplacement du chat",
"failedToLoadChats": "Échec du chargement des chats",
"failedToUpdatePin": "Échec de la mise à jour de l'épingle",
@@ -222,13 +182,17 @@
"deleteMessagesMessage": "Supprimer {count} messages ?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Route introuvable : {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Supprimer le chat",
@@ -254,8 +218,7 @@
"ttsStop": "Arrêter",
"edit": "Modifier",
"regenerate": "Régénérer",
"noConversationsYet": "Aucune conversation pour l'instant"
,
"noConversationsYet": "Aucune conversation pour l'instant",
"usernameOrEmailHint": "Entrez votre nom d'utilisateur ou email",
"passwordHint": "Entrez votre mot de passe",
"enterApiKey": "Entrez votre clé API",
@@ -275,31 +238,55 @@
"headerNameTooLong": "Nom d'en-tête trop long (max 64 caractères)",
"headerNameInvalidChars": "Nom d'en-tête invalide. Utilisez uniquement des lettres, des chiffres et ces symboles : !#$&-^_`|~",
"headerNameReserved": "Impossible d'écraser l'en-tête réservé « {key} »",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "La valeur de l'en-tête ne peut pas être vide",
"headerValueTooLong": "Valeur d'en-tête trop longue (max 1024 caractères)",
"headerValueInvalidChars": "La valeur de l'en-tête contient des caractères invalides. Utilisez uniquement des caractères ASCII imprimables.",
"headerValueUnsafe": "La valeur de l'en-tête semble contenir du contenu potentiellement dangereux",
"headerAlreadyExists": "L'en-tête « {key} » existe déjà. Supprimez-le d'abord pour le modifier.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"maxHeadersReachedDetail": "Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter."
,
"editMessage": "Modifier le message"
,
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter.",
"noModelsAvailable": "Aucun modèle disponible",
"followingSystem": "Selon le système : {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Sombre",
"themePalette": "Palette de couleurs",
"@themePalette": {"description": "Titre pour choisir la palette de couleurs de l'application."},
"themePaletteDescription": "Choisissez les couleurs d'accent utilisées pour les boutons, les cartes et les bulles de discussion.",
"@themePaletteDescription": {"description": "Texte d'aide expliquant la sélection de la palette."},
"@themePalette": {
"description": "Titre pour choisir la palette de couleurs de l'application."
},
"themeLight": "Clair",
"currentlyUsingDarkTheme": "Thème sombre actuellement utilisé",
"currentlyUsingLightTheme": "Thème clair actuellement utilisé",
"aboutConduit": "À propos de Conduit",
"versionLabel": "Version : {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "Dépôt GitHub",
"unableToLoadAppInfo": "Impossible de charger les informations de l'application",
"thinking": "Réflexion…",
@@ -307,9 +294,13 @@
"thoughtForDuration": "A réfléchi pendant {duration}",
"@thoughtForDuration": {
"description": "Indique la durée de réflexion de l'assistant.",
"placeholders": {"duration": {"type": "String", "example": "3 s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3 s"
}
,
}
},
"appCustomization": "Personnalisation",
"appCustomizationSubtitle": "Thème, langue, voix et quickpills",
"quickActionsDescription": "Raccourcis dans le chat",
@@ -332,12 +323,413 @@
"display": "Affichage",
"realtime": "Temps réel",
"transportMode": "Mode de transport",
"transportModeDescription": "Choisissez comment l'app se connecte pour les mises à jour en temps réel.",
"mode": "Mode",
"transportModePolling": "Polling de secours",
"transportModeWs": "WebSocket uniquement",
"transportModePollingInfo": "Bascule sur HTTP polling lorsque WebSocket est bloqué. Repasse à WebSocket dès que possible.",
"transportModeWsInfo": "Moins de surcharge, mais peut échouer derrière des proxys/firewalls stricts.",
"websocketConnectionError": "Impossible d'établir une connexion en temps réel. Veuillez vérifier votre réseau et la configuration du serveur.",
"websocketReconnectFailed": "Échec de la connexion en temps réel. Le streaming pourrait ne pas fonctionner correctement."
"quickActionsSelectedCount": "{count, plural, =0{Aucune action sélectionnée} one{{count} action sélectionnée} other{{count} actions sélectionnées}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Laissez l'application choisir le meilleur modèle",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Moteur",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "Sur l'appareil",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Serveur",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Multimodal",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Raisonnement",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Appel vocal",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Pause",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Reprendre",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Arrêter",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Terminer l'appel",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Choisir un autre fichier",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Erreur : {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "La connexion a expiré. Vérifiez votre connexion Internet et réessayez.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "Impossible d'atteindre le serveur. Vérifiez l'URL du serveur et votre connexion Internet.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "Le serveur ne répond pas. Vérifiez qu'il est en cours d'exécution et accessible.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Problème de connexion réseau. Vérifiez votre connexion Internet.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "Le serveur rencontre des problèmes. Cela est généralement temporaire.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "Le serveur est temporairement indisponible. Réessayez dans un instant.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "Le serveur a mis trop de temps à répondre. Réessayez.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "Le serveur rencontre des difficultés. Réessayez plus tard.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "Votre session a expiré. Veuillez vous reconnecter.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "Vous n'avez pas l'autorisation d'effectuer cette action.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "Le jeton d'authentification est invalide. Veuillez vous reconnecter.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Problème d'authentification. Veuillez vous reconnecter.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Veuillez saisir une adresse e-mail valide.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "Le mot de passe ne respecte pas les exigences. Vérifiez-le et réessayez.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Veuillez remplir tous les champs obligatoires.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Certaines informations sont au mauvais format. Vérifiez-les et réessayez.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Veuillez vérifier vos informations et réessayer.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "Fichier introuvable. Il a peut-être été déplacé ou supprimé.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "Impossible d'accéder au fichier. Vérifiez les autorisations.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "Le fichier est trop volumineux. Choisissez un fichier plus petit.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Problème avec le fichier. Essayez un autre fichier.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "L'autorisation de la caméra est nécessaire. Activez-la dans les paramètres.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "L'autorisation de stockage est nécessaire. Activez-la dans les paramètres.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "L'autorisation du microphone est nécessaire. Activez-la dans les paramètres.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "Autorisation requise. Vérifiez les autorisations de l'application dans les paramètres.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Réessayez la requête.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Vérifiez votre connexion Internet.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Réessayez l'opération.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Attendez un instant puis réessayez.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Connectez-vous à votre compte.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Sélectionnez un autre fichier.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Ouvrez les paramètres de l'application pour accorder les autorisations.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Réessayez après avoir accordé l'autorisation.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Revenir à l'écran précédent.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Continuer",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Chargement",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Chargement : {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Erreur : {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Erreur : {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Succès : {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Champ obligatoire",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Activé",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Désactivé",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Dialogue : {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Précédent",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Suivant",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Thème neutre et épuré conçu pour Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Palette chaleureuse inspirée du client web de Claude.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Dégradés ludiques inspirés de la marque T3 Stack.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Palette douce de tons pastel.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Palette chaleureuse d'oranges et d'ardoises.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Prêt",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Connexion…",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "Écoute",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "En pause",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Réflexion…",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Parle",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Déconnecté",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Veuillez vérifier :\n• Les autorisations du microphone sont accordées\n• La reconnaissance vocale est disponible sur votre appareil\n• Vous êtes connecté au serveur",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -1,7 +1,6 @@
{
"@@locale": "it",
"appTitle": "Conduit",
"initializationFailed": "Inizializzazione non riuscita",
"retry": "Riprova",
"back": "Indietro",
"you": "Tu",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Sottotitolo che spiega le azioni disponibili quando il server non è raggiungibile"
},
"stillOfflineMessage": "Non riusciamo ancora a raggiungere il server. Controlla la connessione e riprova.",
"@stillOfflineMessage": {
"description": "Messaggio di stato dopo un tentativo di riconnessione senza successo"
},
"account": "Account",
"supportConduit": "Sostieni Conduit",
"supportConduitSubtitle": "Mantieni Conduit indipendente finanziando lo sviluppo continuo.",
@@ -37,32 +32,14 @@
"noResults": "Nessun risultato",
"searchModels": "Cerca modelli...",
"errorMessage": "Qualcosa è andato storto. Riprova.",
"loginButton": "Accedi",
"menuItem": "Impostazioni",
"dynamicContentWithPlaceholder": "Benvenuto, {name}!",
"itemsCount": "{count, plural, =0{Nessun elemento} one{1 elemento} other{{count} elementi}}",
"closeButtonSemantic": "Chiudi",
"loadingContent": "Caricamento contenuto",
"noItems": "Nessun elemento",
"noItemsToDisplay": "Nessun elemento da visualizzare",
"loadMore": "Carica altro",
"workspace": "Spazio di lavoro",
"recentFiles": "File recenti",
"knowledgeBase": "Base di conoscenza",
"noFilesYet": "Ancora nessun file",
"uploadDocsPrompt": "Carica documenti da usare nelle conversazioni con Conduit",
"uploadFirstFile": "Carica il tuo primo file",
"attachments": "Allegati",
"knowledgeBaseEmpty": "La base di conoscenza è vuota",
"createCollectionsPrompt": "Crea raccolte di documenti correlati per un rapido riferimento",
"chooseSourcePhoto": "Scegli origine",
"takePhoto": "Scatta una foto",
"chooseFromGallery": "Scegli dalle foto",
"document": "Documento",
"documentHint": "File PDF, Word o di testo",
"uploadFileTitle": "Carica file",
"fileUploadComingSoon": "Il caricamento file per {type} arriverà presto!",
"kbCreationComingSoon": "La creazione della base di conoscenza arriverà presto!",
"backToServerSetup": "Torna alla configurazione del server",
"connectedToServer": "Connesso al server",
"signIn": "Accedi",
@@ -124,9 +101,7 @@
"onboardQuickTitle": "Azioni rapide",
"onboardQuickSubtitle": "Apri il menu per passare tra Chat, Workspace e Profilo.",
"onboardQuickBullet1": "Tocca il menu per accedere a Chat, Workspace, Profilo",
"onboardQuickBullet2": "Avvia Nuova chat o gestisci i modelli dalla barra"
,
"addAttachment": "Aggiungi allegato",
"onboardQuickBullet2": "Avvia Nuova chat o gestisci i modelli dalla barra",
"attachmentLabel": "Allegato",
"tools": "Strumenti",
"voiceInput": "Input vocale",
@@ -157,19 +132,13 @@
"invalidDataUrl": "Formato data URL non valido",
"failedToDecodeImage": "Impossibile decodificare l'immagine",
"invalidImageFormat": "Formato immagine non valido",
"emptyImageData": "Dati immagine vuoti"
,
"featureRequiresInternet": "Questa funzione richiede una connessione Internet",
"messagesWillSendWhenOnline": "I messaggi verranno inviati quando tornerai online",
"emptyImageData": "Dati immagine vuoti",
"confirm": "Conferma",
"cancel": "Annulla"
,
"cancel": "Annulla",
"ok": "OK",
"inputField": "Campo di input",
"captureDocumentOrImage": "Acquisisci un documento o un'immagine",
"checkConnection": "Controlla connessione",
"openSettings": "Apri impostazioni",
"chooseDifferentFile": "Scegli un altro file",
"goBack": "Indietro",
"technicalDetails": "Dettagli tecnici",
"save": "Salva",
@@ -181,18 +150,9 @@
"newChat": "Nuova chat",
"more": "Altro",
"clear": "Pulisci",
"searchHint": "Cerca...",
"searchConversations": "Cerca conversazioni...",
"create": "Crea",
"folderCreated": "Cartella creata",
"failedToCreateFolder": "Impossibile creare la cartella",
"movedChatToFolder": "\"{title}\" spostata in \"{folder}\"",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "Impossibile spostare la chat",
"failedToLoadChats": "Impossibile caricare le chat",
"failedToUpdatePin": "Impossibile aggiornare il pin",
@@ -222,13 +182,17 @@
"deleteMessagesMessage": "Eliminare {count} messaggi?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Percorso non trovato: {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Elimina chat",
@@ -254,8 +218,7 @@
"ttsStop": "Interrompi",
"edit": "Modifica",
"regenerate": "Rigenera",
"noConversationsYet": "Ancora nessuna conversazione"
,
"noConversationsYet": "Ancora nessuna conversazione",
"usernameOrEmailHint": "Inserisci il tuo username o email",
"passwordHint": "Inserisci la password",
"enterApiKey": "Inserisci la tua chiave API",
@@ -275,31 +238,55 @@
"headerNameTooLong": "Nome header troppo lungo (max 64 caratteri)",
"headerNameInvalidChars": "Nome header non valido. Usa solo lettere, numeri e questi simboli: !#$&-^_`|~",
"headerNameReserved": "Impossibile sovrascrivere l'header riservato \"{key}\"",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "Il valore dell'header non può essere vuoto",
"headerValueTooLong": "Valore header troppo lungo (max 1024 caratteri)",
"headerValueInvalidChars": "Il valore dell'header contiene caratteri non validi. Usa solo ASCII stampabile.",
"headerValueUnsafe": "Il valore dell'header sembra contenere contenuti potenzialmente non sicuri",
"headerAlreadyExists": "L'header \"{key}\" esiste già. Rimuovilo prima per aggiornarlo.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"maxHeadersReachedDetail": "Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri."
,
"editMessage": "Modifica messaggio"
,
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri.",
"noModelsAvailable": "Nessun modello disponibile",
"followingSystem": "Segue il sistema: {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Scuro",
"themePalette": "Palette di colori",
"@themePalette": {"description": "Titolo per scegliere la palette di colori dell'app."},
"themePaletteDescription": "Scegli i colori di accento usati per pulsanti, schede e bolle di chat.",
"@themePaletteDescription": {"description": "Testo di supporto che spiega la scelta della palette."},
"@themePalette": {
"description": "Titolo per scegliere la palette di colori dell'app."
},
"themeLight": "Chiaro",
"currentlyUsingDarkTheme": "Attualmente tema scuro",
"currentlyUsingLightTheme": "Attualmente tema chiaro",
"aboutConduit": "Informazioni su Conduit",
"versionLabel": "Versione: {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "Repository GitHub",
"unableToLoadAppInfo": "Impossibile caricare le informazioni dell'app",
"thinking": "Sta pensando…",
@@ -307,9 +294,13 @@
"thoughtForDuration": "Ha pensato per {duration}",
"@thoughtForDuration": {
"description": "Mostra per quanto tempo ha pensato l'assistente.",
"placeholders": {"duration": {"type": "String", "example": "3 s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3 s"
}
,
}
},
"appCustomization": "Personalizzazione",
"appCustomizationSubtitle": "Tema, lingua, voce e quickpills",
"quickActionsDescription": "Scorciatoie nella chat",
@@ -332,12 +323,413 @@
"display": "Schermo",
"realtime": "Tempo reale",
"transportMode": "Modalità di trasporto",
"transportModeDescription": "Scegli come l'app si connette per gli aggiornamenti in tempo reale.",
"mode": "Modalità",
"transportModePolling": "Polling di fallback",
"transportModeWs": "Solo WebSocket",
"transportModePollingInfo": "Quando WebSocket è bloccato passa a HTTP polling. Torna a WebSocket appena possibile.",
"transportModeWsInfo": "Minore overhead, ma può fallire dietro proxy/firewall restrittivi.",
"websocketConnectionError": "Impossibile stabilire una connessione in tempo reale. Si prega di controllare la rete e la configurazione del server.",
"websocketReconnectFailed": "Connessione in tempo reale fallita. Lo streaming potrebbe non funzionare correttamente."
"quickActionsSelectedCount": "{count, plural, =0{Nessuna azione selezionata} one{{count} azione selezionata} other{{count} azioni selezionate}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Lascia che l'app scelga il modello migliore",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Motore",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "Sul dispositivo",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Server",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Multimodale",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Ragionamento",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Chiamata vocale",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Pausa",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Riprendi",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Stop",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Termina chiamata",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Scegli un altro file",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Errore: {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "Connessione scaduta. Controlla la tua connessione Internet e riprova.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "Impossibile raggiungere il server. Controlla l'URL del server e la connessione Internet.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "Il server non risponde. Verifica che sia attivo e raggiungibile.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Problema di connessione di rete. Controlla la connessione Internet.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "Il server sta avendo problemi. Di solito è temporaneo.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "Il server è temporaneamente non disponibile. Riprova tra poco.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "Il server ha impiegato troppo tempo a rispondere. Riprova.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "Il server è in difficoltà. Riprova più tardi.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "La sessione è scaduta. Accedi di nuovo.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "Non hai l'autorizzazione per eseguire questa azione.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "Il token di autenticazione non è valido. Accedi di nuovo.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Problema di autenticazione. Accedi di nuovo.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Inserisci un indirizzo email valido.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "La password non soddisfa i requisiti. Controllala e riprova.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Compila tutti i campi obbligatori.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Alcune informazioni non sono nel formato corretto. Controllale e riprova.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Controlla i dati inseriti e riprova.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "File non trovato. Potrebbe essere stato spostato o eliminato.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "Impossibile accedere al file. Controlla i permessi.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "Il file è troppo grande. Scegline uno più piccolo.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Problema con il file. Prova con un file diverso.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "È necessario il permesso della fotocamera. Attivalo nelle impostazioni.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "È necessario il permesso di archiviazione. Attivalo nelle impostazioni.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "È necessario il permesso del microfono. Attivalo nelle impostazioni.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "È necessaria un'autorizzazione. Controlla i permessi dell'app nelle impostazioni.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Riprova la richiesta.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Verifica la connessione a Internet.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Riprova l'operazione.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Attendi un momento e riprova.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Accedi al tuo account.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Seleziona un altro file.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Apri le impostazioni dell'app per concedere i permessi.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Riprova dopo aver concesso il permesso.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Torna alla schermata precedente.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Continua",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Caricamento",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Caricamento: {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Errore: {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Errore: {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Operazione riuscita: {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Campo obbligatorio",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Attivo",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Disattivo",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Dialogo: {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Precedente",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Successivo",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Tema neutro e pulito progettato per Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Palette calda e tattile ispirata al client web Claude.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Sfumature vivaci ispirate al brand T3 Stack.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Palette morbida di tonalità pastello.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Palette calda arancione e ardesia.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Pronto",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Connessione...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "In ascolto",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "In pausa",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Elaborazione...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Sta parlando",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Disconnesso",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Controlla:\n• Sono state concesse le autorizzazioni del microfono\n• Il riconoscimento vocale è disponibile sul dispositivo\n• Sei connesso al server",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -116,12 +116,6 @@ abstract class AppLocalizations {
/// **'Conduit'**
String get appTitle;
/// Shown if the app fails to initialize critical services.
///
/// In en, this message translates to:
/// **'Initialization Failed'**
String get initializationFailed;
/// Button label to try an action again.
///
/// In en, this message translates to:
@@ -170,12 +164,6 @@ abstract class AppLocalizations {
/// **'Reconnect to continue or sign out to choose a different server.'**
String get connectionIssueSubtitle;
/// Status message after a retry when connectivity has not been restored
///
/// In en, this message translates to:
/// **'We still can\'t reach the server. Double-check your connection and try again.'**
String get stillOfflineMessage;
/// Section header for account-related options.
///
/// In en, this message translates to:
@@ -260,6 +248,18 @@ abstract class AppLocalizations {
/// **'Available Models'**
String get availableModels;
/// Capability chip label for models that support multimodal input.
///
/// In en, this message translates to:
/// **'Multimodal'**
String get modelCapabilityMultimodal;
/// Capability chip label for models that support reasoning features.
///
/// In en, this message translates to:
/// **'Reasoning'**
String get modelCapabilityReasoning;
/// Shown when a search returns no matches.
///
/// In en, this message translates to:
@@ -278,30 +278,6 @@ abstract class AppLocalizations {
/// **'Something went wrong. Please try again.'**
String get errorMessage;
/// Button text for the login action.
///
/// In en, this message translates to:
/// **'Login'**
String get loginButton;
/// Generic settings menu item label.
///
/// In en, this message translates to:
/// **'Settings'**
String get menuItem;
/// Greeting message with a dynamic user name.
///
/// In en, this message translates to:
/// **'Welcome, {name}!'**
String dynamicContentWithPlaceholder(String name);
/// Pluralized count of items.
///
/// In en, this message translates to:
/// **'{count, plural, =0{No items} one{1 item} other{{count} items}}'**
String itemsCount(int count);
/// Accessible label for a generic Close button.
///
/// In en, this message translates to:
@@ -314,6 +290,36 @@ abstract class AppLocalizations {
/// **'Loading content'**
String get loadingContent;
/// Short loading label used for accessibility.
///
/// In en, this message translates to:
/// **'Loading'**
String get loadingShort;
/// Screen reader announcement when loading a resource.
///
/// In en, this message translates to:
/// **'Loading: {message}'**
String loadingAnnouncement(String message);
/// Screen reader announcement for an error.
///
/// In en, this message translates to:
/// **'Error: {error}'**
String errorAnnouncement(String error);
/// Screen reader announcement for an error with a follow-up suggestion.
///
/// In en, this message translates to:
/// **'Error: {error}. {suggestion}'**
String errorAnnouncementWithSuggestion(String error, String suggestion);
/// Screen reader announcement for successful actions.
///
/// In en, this message translates to:
/// **'Success: {message}'**
String successAnnouncement(String message);
/// Placeholder text when a list is empty.
///
/// In en, this message translates to:
@@ -326,114 +332,30 @@ abstract class AppLocalizations {
/// **'No items to display'**
String get noItemsToDisplay;
/// Button label to load additional items in a paged list.
///
/// In en, this message translates to:
/// **'Load More'**
String get loadMore;
/// Section/tab label for documents and files.
///
/// In en, this message translates to:
/// **'Workspace'**
String get workspace;
/// Header for recently accessed files.
///
/// In en, this message translates to:
/// **'Recent Files'**
String get recentFiles;
/// Section for knowledge base content.
///
/// In en, this message translates to:
/// **'Knowledge Base'**
String get knowledgeBase;
/// Empty state when no files are present.
///
/// In en, this message translates to:
/// **'No files yet'**
String get noFilesYet;
/// Prompt encouraging users to upload documents.
///
/// In en, this message translates to:
/// **'Upload documents to reference in your conversations with Conduit'**
String get uploadDocsPrompt;
/// CTA to add the first file.
///
/// In en, this message translates to:
/// **'Upload your first file'**
String get uploadFirstFile;
/// Header above list of attached files in compose area.
///
/// In en, this message translates to:
/// **'Attachments'**
String get attachments;
/// Empty state title for the knowledge base section.
///
/// In en, this message translates to:
/// **'Knowledge base is empty'**
String get knowledgeBaseEmpty;
/// Prompt describing the benefit of creating collections.
///
/// In en, this message translates to:
/// **'Create collections of related documents for easy reference'**
String get createCollectionsPrompt;
/// Sheet title to pick camera or photo library.
///
/// In en, this message translates to:
/// **'Choose your source'**
String get chooseSourcePhoto;
/// Action to open camera and capture a new photo.
///
/// In en, this message translates to:
/// **'Take a photo'**
String get takePhoto;
/// Action to pick an existing photo from library.
///
/// In en, this message translates to:
/// **'Choose from your photos'**
String get chooseFromGallery;
/// Generic document label used in UI.
///
/// In en, this message translates to:
/// **'Document'**
String get document;
/// Helper hint listing supported document types.
///
/// In en, this message translates to:
/// **'PDF, Word, or text file'**
String get documentHint;
/// Dialog/sheet title for file upload.
///
/// In en, this message translates to:
/// **'Upload File'**
String get uploadFileTitle;
/// Temporary message for upcoming upload feature by type
///
/// In en, this message translates to:
/// **'File upload for {type} is coming soon!'**
String fileUploadComingSoon(String type);
/// Temporary message indicating KB creation feature is not yet available.
///
/// In en, this message translates to:
/// **'Knowledge base creation is coming soon!'**
String get kbCreationComingSoon;
/// Button/back label to return to server configuration flow.
///
/// In en, this message translates to:
@@ -806,12 +728,6 @@ abstract class AppLocalizations {
/// **'Start New Chat or manage models from the top bar'**
String get onboardQuickBullet2;
/// Button to add an attachment (file/photo).
///
/// In en, this message translates to:
/// **'Add attachment'**
String get addAttachment;
/// Label shown beside attachment chips in messages.
///
/// In en, this message translates to:
@@ -890,6 +806,84 @@ abstract class AppLocalizations {
/// **'Start'**
String get voiceActionStart;
/// Title displayed on the voice call screen.
///
/// In en, this message translates to:
/// **'Voice Call'**
String get voiceCallTitle;
/// Button label to pause a voice call.
///
/// In en, this message translates to:
/// **'Pause'**
String get voiceCallPause;
/// Button label to resume a paused voice call.
///
/// In en, this message translates to:
/// **'Resume'**
String get voiceCallResume;
/// Button label to stop the active voice call.
///
/// In en, this message translates to:
/// **'Stop'**
String get voiceCallStop;
/// Button label to end the voice call session.
///
/// In en, this message translates to:
/// **'End Call'**
String get voiceCallEnd;
/// Status label shown when the voice call is ready to start.
///
/// In en, this message translates to:
/// **'Ready'**
String get voiceCallReady;
/// Status label shown while the voice call is connecting.
///
/// In en, this message translates to:
/// **'Connecting...'**
String get voiceCallConnecting;
/// Status label shown while the call is listening for input.
///
/// In en, this message translates to:
/// **'Listening'**
String get voiceCallListening;
/// Status label shown when the call is paused.
///
/// In en, this message translates to:
/// **'Paused'**
String get voiceCallPaused;
/// Status label shown while the call processes a response.
///
/// In en, this message translates to:
/// **'Thinking...'**
String get voiceCallProcessing;
/// Status label shown while the assistant is speaking.
///
/// In en, this message translates to:
/// **'Speaking'**
String get voiceCallSpeaking;
/// Status label shown when the voice call has ended or disconnected.
///
/// In en, this message translates to:
/// **'Disconnected'**
String get voiceCallDisconnected;
/// Guidance shown when the voice call encounters an error.
///
/// In en, this message translates to:
/// **'Please check:\n• Microphone permissions are granted\n• Speech recognition is available on your device\n• You are connected to the server'**
String get voiceCallErrorHelp;
/// Accessibility label for the message input.
///
/// In en, this message translates to:
@@ -938,6 +932,12 @@ abstract class AppLocalizations {
/// **'File'**
String get file;
/// Action label prompting the user to pick another file.
///
/// In en, this message translates to:
/// **'Choose Different File'**
String get chooseDifferentFile;
/// A photo item or attachment type label.
///
/// In en, this message translates to:
@@ -998,24 +998,18 @@ abstract class AppLocalizations {
/// **'Empty image data'**
String get emptyImageData;
/// Informational text explaining internet requirement.
///
/// In en, this message translates to:
/// **'This feature requires an internet connection'**
String get featureRequiresInternet;
/// Queue behavior notice while offline.
///
/// In en, this message translates to:
/// **'Messages will be sent when you\'re back online'**
String get messagesWillSendWhenOnline;
/// Confirmation button label.
///
/// In en, this message translates to:
/// **'Confirm'**
String get confirm;
/// Button label to continue an action or flow.
///
/// In en, this message translates to:
/// **'Continue'**
String get continueAction;
/// Cancel button label.
///
/// In en, this message translates to:
@@ -1028,18 +1022,24 @@ abstract class AppLocalizations {
/// **'OK'**
String get ok;
/// Label for navigating to the previous item.
///
/// In en, this message translates to:
/// **'Prev'**
String get previousLabel;
/// Label for navigating to the next item.
///
/// In en, this message translates to:
/// **'Next'**
String get nextLabel;
/// Accessibility label describing an input field.
///
/// In en, this message translates to:
/// **'Input field'**
String get inputField;
/// Action to capture a document or image using camera.
///
/// In en, this message translates to:
/// **'Capture a document or image'**
String get captureDocumentOrImage;
/// CTA to verify network connectivity.
///
/// In en, this message translates to:
@@ -1052,12 +1052,6 @@ abstract class AppLocalizations {
/// **'Open Settings'**
String get openSettings;
/// CTA to pick an alternative file.
///
/// In en, this message translates to:
/// **'Choose Different File'**
String get chooseDifferentFile;
/// CTA to navigate back.
///
/// In en, this message translates to:
@@ -1070,6 +1064,36 @@ abstract class AppLocalizations {
/// **'Technical Details'**
String get technicalDetails;
/// Label text indicating a required field.
///
/// In en, this message translates to:
/// **'{label} *'**
String requiredFieldLabel(String label);
/// Helper text indicating that the field is required.
///
/// In en, this message translates to:
/// **'Required field'**
String get requiredFieldHelper;
/// Semantic label when a switch is enabled.
///
/// In en, this message translates to:
/// **'On'**
String get switchOnLabel;
/// Semantic label when a switch is disabled.
///
/// In en, this message translates to:
/// **'Off'**
String get switchOffLabel;
/// Semantic label describing the dialog title.
///
/// In en, this message translates to:
/// **'Dialog: {title}'**
String dialogSemanticLabel(String title);
/// Primary action to save changes.
///
/// In en, this message translates to:
@@ -1124,12 +1148,6 @@ abstract class AppLocalizations {
/// **'Clear'**
String get clear;
/// Generic search input hint.
///
/// In en, this message translates to:
/// **'Search...'**
String get searchHint;
/// Search input hint scoped to conversations.
///
/// In en, this message translates to:
@@ -1142,24 +1160,12 @@ abstract class AppLocalizations {
/// **'Create'**
String get create;
/// Toast/notice after successfully creating a folder.
///
/// In en, this message translates to:
/// **'Folder created'**
String get folderCreated;
/// Error notice when folder creation fails.
///
/// In en, this message translates to:
/// **'Failed to create folder'**
String get failedToCreateFolder;
/// Toast indicating a chat titled {title} was moved to folder {folder}.
///
/// In en, this message translates to:
/// **'Moved \"{title}\" to \"{folder}\"'**
String movedChatToFolder(String title, String folder);
/// Error notice when moving a chat fails.
///
/// In en, this message translates to:
@@ -1586,12 +1592,6 @@ abstract class AppLocalizations {
/// **'Maximum of 10 custom headers allowed. Remove some to add more.'**
String get maxHeadersReachedDetail;
/// Action to edit a previously sent message.
///
/// In en, this message translates to:
/// **'Edit Message'**
String get editMessage;
/// Shown when model list is empty or failed to load.
///
/// In en, this message translates to:
@@ -1616,11 +1616,65 @@ abstract class AppLocalizations {
/// **'Accent palette'**
String get themePalette;
/// Helper text explaining palette selection.
/// Palette name for the default Conduit theme.
///
/// In en, this message translates to:
/// **'Choose the accent colors used for buttons, cards, and chat bubbles.'**
String get themePaletteDescription;
/// **'Conduit'**
String get themePaletteConduitLabel;
/// Description of the Conduit palette.
///
/// In en, this message translates to:
/// **'Clean neutral theme designed for Conduit.'**
String get themePaletteConduitDescription;
/// Palette name inspired by the Claude web client.
///
/// In en, this message translates to:
/// **'Claude'**
String get themePaletteClaudeLabel;
/// Description of the Claude palette.
///
/// In en, this message translates to:
/// **'Warm, tactile palette lifted from the Claude web client.'**
String get themePaletteClaudeDescription;
/// Palette name inspired by the T3 Stack brand.
///
/// In en, this message translates to:
/// **'T3 Chat'**
String get themePaletteT3ChatLabel;
/// Description of the T3 Chat palette.
///
/// In en, this message translates to:
/// **'Playful gradients inspired by the T3 Stack brand.'**
String get themePaletteT3ChatDescription;
/// Palette name for Catppuccin colors.
///
/// In en, this message translates to:
/// **'Catppuccin'**
String get themePaletteCatppuccinLabel;
/// Description of the Catppuccin palette.
///
/// In en, this message translates to:
/// **'Soft pastel palette.'**
String get themePaletteCatppuccinDescription;
/// Palette name for Tangerine colors.
///
/// In en, this message translates to:
/// **'Tangerine'**
String get themePaletteTangerineLabel;
/// Description of the Tangerine palette.
///
/// In en, this message translates to:
/// **'Warm orange-and-slate palette.'**
String get themePaletteTangerineDescription;
/// Theme label for light appearance.
///
@@ -1700,6 +1754,18 @@ abstract class AppLocalizations {
/// **'Quickpills in chat'**
String get quickActionsDescription;
/// Subtitle indicating how many quick actions are selected.
///
/// In en, this message translates to:
/// **'{count, plural, =0{No actions selected} one{1 action selected} other{{count} actions selected}}'**
String quickActionsSelectedCount(int count);
/// Explains what the auto-select model setting does.
///
/// In en, this message translates to:
/// **'Let the app choose the best model'**
String get autoSelectDescription;
/// Section header for chat-related customization options.
///
/// In en, this message translates to:
@@ -1718,6 +1784,24 @@ abstract class AppLocalizations {
/// **'Enter sends (soft keyboard). Cmd/Ctrl+Enter also available'**
String get sendOnEnterDescription;
/// Label for selecting the text-to-speech engine.
///
/// In en, this message translates to:
/// **'Engine'**
String get ttsEngineLabel;
/// Chip label for using on-device text-to-speech.
///
/// In en, this message translates to:
/// **'On device'**
String get ttsEngineDevice;
/// Chip label for using server-side text-to-speech.
///
/// In en, this message translates to:
/// **'Server'**
String get ttsEngineServer;
/// Section header for TTS-related customization options.
///
/// In en, this message translates to:
@@ -1796,6 +1880,216 @@ abstract class AppLocalizations {
/// **'Error'**
String get error;
/// Error label with appended message text.
///
/// In en, this message translates to:
/// **'Error: {message}'**
String errorWithMessage(String message);
/// User-facing message when a network request times out.
///
/// In en, this message translates to:
/// **'Connection timed out. Please check your internet connection and try again.'**
String get networkTimeoutError;
/// User-facing message when the server cannot be reached.
///
/// In en, this message translates to:
/// **'Cannot reach the server. Please check your server URL and internet connection.'**
String get networkUnreachableError;
/// User-facing message when the server does not respond to a request.
///
/// In en, this message translates to:
/// **'Server is not responding. Please verify the server is running and accessible.'**
String get networkServerNotResponding;
/// Fallback message for generic network errors.
///
/// In en, this message translates to:
/// **'Network connection problem. Please check your internet connection.'**
String get networkGenericError;
/// Message when a 500 error is encountered.
///
/// In en, this message translates to:
/// **'Server is experiencing issues. This is usually temporary.'**
String get serverError500;
/// Message when a 502/503 error is encountered.
///
/// In en, this message translates to:
/// **'Server is temporarily unavailable. Please try again in a moment.'**
String get serverErrorUnavailable;
/// Message when the server times out.
///
/// In en, this message translates to:
/// **'Server took too long to respond. Please try again.'**
String get serverErrorTimeout;
/// Fallback server error message.
///
/// In en, this message translates to:
/// **'Server is having problems. Please try again later.'**
String get serverErrorGeneric;
/// Message when an authentication session expires.
///
/// In en, this message translates to:
/// **'Your session has expired. Please sign in again.'**
String get authSessionExpired;
/// Message when the user lacks required permissions.
///
/// In en, this message translates to:
/// **'You don\'t have permission to perform this action.'**
String get authForbidden;
/// Message when the authentication token is invalid.
///
/// In en, this message translates to:
/// **'Authentication token is invalid. Please sign in again.'**
String get authInvalidToken;
/// Fallback authentication error message.
///
/// In en, this message translates to:
/// **'Authentication problem. Please sign in again.'**
String get authGenericError;
/// Validation message for invalid email input.
///
/// In en, this message translates to:
/// **'Please enter a valid email address.'**
String get validationInvalidEmail;
/// Validation message for weak passwords.
///
/// In en, this message translates to:
/// **'Password doesn\'t meet requirements. Please check and try again.'**
String get validationWeakPassword;
/// Validation message when required fields are missing.
///
/// In en, this message translates to:
/// **'Please fill in all required fields.'**
String get validationMissingRequired;
/// Validation message for generic formatting issues.
///
/// In en, this message translates to:
/// **'Some information is in the wrong format. Please check and try again.'**
String get validationFormatError;
/// Fallback validation message.
///
/// In en, this message translates to:
/// **'Please check your input and try again.'**
String get validationGenericError;
/// Message when a file cannot be located.
///
/// In en, this message translates to:
/// **'File not found. It may have been moved or deleted.'**
String get fileNotFound;
/// Message when file access is denied.
///
/// In en, this message translates to:
/// **'Cannot access the file. Please check permissions.'**
String get fileAccessDenied;
/// Message when a file exceeds size limits.
///
/// In en, this message translates to:
/// **'File is too large. Please choose a smaller file.'**
String get fileTooLarge;
/// Fallback file error message.
///
/// In en, this message translates to:
/// **'Problem with the file. Please try a different file.'**
String get fileGenericError;
/// Message when camera permission is missing.
///
/// In en, this message translates to:
/// **'Camera permission is required. Please enable it in settings.'**
String get permissionCameraRequired;
/// Message when storage permission is missing.
///
/// In en, this message translates to:
/// **'Storage permission is required. Please enable it in settings.'**
String get permissionStorageRequired;
/// Message when microphone permission is missing.
///
/// In en, this message translates to:
/// **'Microphone permission is required. Please enable it in settings.'**
String get permissionMicrophoneRequired;
/// Fallback permission error message.
///
/// In en, this message translates to:
/// **'Permission required. Please check app permissions in settings.'**
String get permissionGenericError;
/// Description for retrying a failed request.
///
/// In en, this message translates to:
/// **'Try the request again.'**
String get actionRetryRequest;
/// Description for checking internet connectivity.
///
/// In en, this message translates to:
/// **'Verify your internet connection.'**
String get actionVerifyConnection;
/// Description for retrying the same operation.
///
/// In en, this message translates to:
/// **'Retry the operation.'**
String get actionRetryOperation;
/// Description suggesting a short delay before retrying.
///
/// In en, this message translates to:
/// **'Wait a moment then try again.'**
String get actionRetryAfterDelay;
/// Description for signing back into the app.
///
/// In en, this message translates to:
/// **'Sign in to your account.'**
String get actionSignInToAccount;
/// Description for choosing a different file.
///
/// In en, this message translates to:
/// **'Select another file.'**
String get actionSelectAnotherFile;
/// Description for opening system or app settings.
///
/// In en, this message translates to:
/// **'Open app settings to grant permissions.'**
String get actionOpenAppSettings;
/// Description for retrying once permissions are granted.
///
/// In en, this message translates to:
/// **'Retry after granting permission.'**
String get actionRetryAfterPermission;
/// Description for navigating back to the prior screen.
///
/// In en, this message translates to:
/// **'Return to previous screen.'**
String get actionReturnToPrevious;
/// Section header for visual and layout related settings.
///
/// In en, this message translates to:
@@ -1814,12 +2108,6 @@ abstract class AppLocalizations {
/// **'Transport mode'**
String get transportMode;
/// Helper text explaining the transport setting.
///
/// In en, this message translates to:
/// **'Choose how the app connects for realtime updates.'**
String get transportModeDescription;
/// Form field label for transport mode dropdown.
///
/// In en, this message translates to:
@@ -1849,18 +2137,6 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Lower overhead, but may fail behind strict proxies/firewalls.'**
String get transportModeWsInfo;
/// Error message shown when WebSocket connection fails initially.
///
/// In en, this message translates to:
/// **'Unable to establish real-time connection. Please check your network and server configuration.'**
String get websocketConnectionError;
/// Error message shown when WebSocket reconnection attempts fail.
///
/// In en, this message translates to:
/// **'Real-time connection failed. Streaming may not work properly.'**
String get websocketReconnectFailed;
}
class _AppLocalizationsDelegate

View File

@@ -11,9 +11,6 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get appTitle => 'Conduit';
@override
String get initializationFailed => 'Initialisierung fehlgeschlagen';
@override
String get retry => 'Erneut versuchen';
@@ -40,10 +37,6 @@ class AppLocalizationsDe extends AppLocalizations {
String get connectionIssueSubtitle =>
'Verbindung wiederherstellen oder abmelden, um einen anderen Server zu wählen.';
@override
String get stillOfflineMessage =>
'Der Server ist weiterhin nicht erreichbar. Prüfe deine Verbindung und versuche es erneut.';
@override
String get account => 'Konto';
@@ -89,6 +82,12 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get availableModels => 'Verfügbare Modelle';
@override
String get modelCapabilityMultimodal => 'Multimodal';
@override
String get modelCapabilityReasoning => 'Reasoning';
@override
String get noResults => 'Keine Ergebnisse';
@@ -99,100 +98,53 @@ class AppLocalizationsDe extends AppLocalizations {
String get errorMessage =>
'Etwas ist schief gelaufen. Bitte versuche es erneut.';
@override
String get loginButton => 'Anmelden';
@override
String get menuItem => 'Einstellungen';
@override
String dynamicContentWithPlaceholder(String name) {
return 'Willkommen, $name!';
}
@override
String itemsCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Elemente',
one: '1 Element',
zero: 'Keine Elemente',
);
return '$_temp0';
}
@override
String get closeButtonSemantic => 'Schließen';
@override
String get loadingContent => 'Inhalt wird geladen';
@override
String get loadingShort => 'Laden';
@override
String loadingAnnouncement(String message) {
return 'Laden: $message';
}
@override
String errorAnnouncement(String error) {
return 'Fehler: $error';
}
@override
String errorAnnouncementWithSuggestion(String error, String suggestion) {
return 'Fehler: $error. $suggestion';
}
@override
String successAnnouncement(String message) {
return 'Erfolg: $message';
}
@override
String get noItems => 'Keine Elemente';
@override
String get noItemsToDisplay => 'Keine Elemente zum Anzeigen';
@override
String get loadMore => 'Mehr laden';
@override
String get workspace => 'Arbeitsbereich';
@override
String get recentFiles => 'Zuletzt verwendete Dateien';
@override
String get knowledgeBase => 'Wissensdatenbank';
@override
String get noFilesYet => 'Noch keine Dateien';
@override
String get uploadDocsPrompt =>
'Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden';
@override
String get uploadFirstFile => 'Erste Datei hochladen';
@override
String get attachments => 'Anhänge';
@override
String get knowledgeBaseEmpty => 'Wissensdatenbank ist leer';
@override
String get createCollectionsPrompt =>
'Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz';
@override
String get chooseSourcePhoto => 'Quelle auswählen';
@override
String get takePhoto => 'Foto aufnehmen';
@override
String get chooseFromGallery => 'Aus Fotos auswählen';
@override
String get document => 'Dokument';
@override
String get documentHint => 'PDF-, Word- oder Textdatei';
@override
String get uploadFileTitle => 'Datei hochladen';
@override
String fileUploadComingSoon(String type) {
return 'Dateiupload für $type kommt bald!';
}
@override
String get kbCreationComingSoon =>
'Erstellung der Wissensdatenbank kommt bald!';
@override
String get backToServerSetup => 'Zur Servereinrichtung zurück';
@@ -402,9 +354,6 @@ class AppLocalizationsDe extends AppLocalizations {
String get onboardQuickBullet2 =>
'Neuer Chat starten oder Modelle oben verwalten';
@override
String get addAttachment => 'Anhang hinzufügen';
@override
String get attachmentLabel => 'Anhang';
@@ -444,6 +393,46 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get voiceActionStart => 'Starten';
@override
String get voiceCallTitle => 'Sprachanruf';
@override
String get voiceCallPause => 'Pause';
@override
String get voiceCallResume => 'Fortsetzen';
@override
String get voiceCallStop => 'Stopp';
@override
String get voiceCallEnd => 'Anruf beenden';
@override
String get voiceCallReady => 'Bereit';
@override
String get voiceCallConnecting => 'Verbinden...';
@override
String get voiceCallListening => 'Zuhören';
@override
String get voiceCallPaused => 'Pausiert';
@override
String get voiceCallProcessing => 'Denkt...';
@override
String get voiceCallSpeaking => 'Spricht';
@override
String get voiceCallDisconnected => 'Getrennt';
@override
String get voiceCallErrorHelp =>
'Bitte prüfe:\n• Mikrofonberechtigungen sind erteilt\n• Spracherkennung ist auf deinem Gerät verfügbar\n• Du bist mit dem Server verbunden';
@override
String get messageInputLabel => 'Nachrichteneingabe';
@@ -468,6 +457,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get file => 'Datei';
@override
String get chooseDifferentFile => 'Andere Datei auswählen';
@override
String get photo => 'Foto';
@@ -502,17 +494,12 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get emptyImageData => 'Leere Bilddaten';
@override
String get featureRequiresInternet =>
'Diese Funktion erfordert eine Internetverbindung';
@override
String get messagesWillSendWhenOnline =>
'Nachrichten werden gesendet, sobald du wieder online bist';
@override
String get confirm => 'Bestätigen';
@override
String get continueAction => 'Weiter';
@override
String get cancel => 'Abbrechen';
@@ -520,10 +507,13 @@ class AppLocalizationsDe extends AppLocalizations {
String get ok => 'OK';
@override
String get inputField => 'Eingabefeld';
String get previousLabel => 'Zurück';
@override
String get captureDocumentOrImage => 'Dokument oder Bild aufnehmen';
String get nextLabel => 'Weiter';
@override
String get inputField => 'Eingabefeld';
@override
String get checkConnection => 'Verbindung prüfen';
@@ -531,15 +521,31 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get openSettings => 'Einstellungen öffnen';
@override
String get chooseDifferentFile => 'Andere Datei wählen';
@override
String get goBack => 'Zurück';
@override
String get technicalDetails => 'Technische Details';
@override
String requiredFieldLabel(String label) {
return '$label *';
}
@override
String get requiredFieldHelper => 'Pflichtfeld';
@override
String get switchOnLabel => 'Ein';
@override
String get switchOffLabel => 'Aus';
@override
String dialogSemanticLabel(String title) {
return 'Dialog: $title';
}
@override
String get save => 'Speichern';
@@ -567,26 +573,15 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get clear => 'Leeren';
@override
String get searchHint => 'Suchen...';
@override
String get searchConversations => 'Konversationen durchsuchen...';
@override
String get create => 'Erstellen';
@override
String get folderCreated => 'Ordner erstellt';
@override
String get failedToCreateFolder => 'Ordner konnte nicht erstellt werden';
@override
String movedChatToFolder(String title, String folder) {
return '\"$title\" nach \"$folder\" verschoben';
}
@override
String get failedToMoveChat => 'Chat konnte nicht verschoben werden';
@@ -818,9 +813,6 @@ class AppLocalizationsDe extends AppLocalizations {
String get maxHeadersReachedDetail =>
'Maximal 10 benutzerdefinierte Header zulässig. Einige entfernen, um mehr hinzuzufügen.';
@override
String get editMessage => 'Nachricht bearbeiten';
@override
String get noModelsAvailable => 'Keine Modelle verfügbar';
@@ -836,8 +828,38 @@ class AppLocalizationsDe extends AppLocalizations {
String get themePalette => 'Farbpalette';
@override
String get themePaletteDescription =>
'Wählen Sie die Akzentfarben für Schaltflächen, Karten und Chatblasen.';
String get themePaletteConduitLabel => 'Conduit';
@override
String get themePaletteConduitDescription =>
'Schlichtes neutrales Design für Conduit.';
@override
String get themePaletteClaudeLabel => 'Claude';
@override
String get themePaletteClaudeDescription =>
'Warmes, haptisches Farbschema aus dem Claude-Webclient.';
@override
String get themePaletteT3ChatLabel => 'T3 Chat';
@override
String get themePaletteT3ChatDescription =>
'Verspielte Verläufe inspiriert vom T3-Stack.';
@override
String get themePaletteCatppuccinLabel => 'Catppuccin';
@override
String get themePaletteCatppuccinDescription => 'Sanfte Pastellpalette.';
@override
String get themePaletteTangerineLabel => 'Tangerine';
@override
String get themePaletteTangerineDescription =>
'Warmes Orange-Schiefer-Farbschema.';
@override
String get themeLight => 'Hell';
@@ -884,6 +906,21 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get quickActionsDescription => 'Schnellzugriffe im Chat';
@override
String quickActionsSelectedCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Aktionen ausgewählt',
one: '$count Aktion ausgewählt',
zero: 'Keine Aktionen ausgewählt',
);
return '$_temp0';
}
@override
String get autoSelectDescription => 'Lass die App das beste Modell auswählen';
@override
String get chatSettings => 'Chat';
@@ -894,6 +931,15 @@ class AppLocalizationsDe extends AppLocalizations {
String get sendOnEnterDescription =>
'Enter sendet (Soft-Tastatur). Cmd/Ctrl+Enter ebenfalls verfügbar';
@override
String get ttsEngineLabel => 'Engine';
@override
String get ttsEngineDevice => 'Auf dem Gerät';
@override
String get ttsEngineServer => 'Server';
@override
String get ttsSettings => 'Text zu Sprache';
@@ -936,6 +982,139 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get error => 'Fehler';
@override
String errorWithMessage(String message) {
return 'Fehler: $message';
}
@override
String get networkTimeoutError =>
'Verbindung abgelaufen. Bitte überprüfe deine Internetverbindung und versuche es erneut.';
@override
String get networkUnreachableError =>
'Server nicht erreichbar. Bitte überprüfe die Server-URL und deine Internetverbindung.';
@override
String get networkServerNotResponding =>
'Server reagiert nicht. Bitte stelle sicher, dass der Server läuft und erreichbar ist.';
@override
String get networkGenericError =>
'Netzwerkproblem. Bitte überprüfe deine Internetverbindung.';
@override
String get serverError500 =>
'Der Server hat Probleme. Das ist meist nur vorübergehend.';
@override
String get serverErrorUnavailable =>
'Server vorübergehend nicht verfügbar. Bitte versuche es gleich noch einmal.';
@override
String get serverErrorTimeout =>
'Der Server hat zu lange für eine Antwort gebraucht. Bitte versuche es erneut.';
@override
String get serverErrorGeneric =>
'Der Server hat Schwierigkeiten. Bitte versuche es später erneut.';
@override
String get authSessionExpired =>
'Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.';
@override
String get authForbidden => 'Du hast keine Berechtigung für diese Aktion.';
@override
String get authInvalidToken =>
'Der Authentifizierungstoken ist ungültig. Bitte melde dich erneut an.';
@override
String get authGenericError =>
'Authentifizierungsproblem. Bitte melde dich erneut an.';
@override
String get validationInvalidEmail =>
'Bitte gib eine gültige E-Mail-Adresse ein.';
@override
String get validationWeakPassword =>
'Das Passwort erfüllt die Anforderungen nicht. Bitte überprüfe es und versuche es erneut.';
@override
String get validationMissingRequired => 'Bitte fülle alle Pflichtfelder aus.';
@override
String get validationFormatError =>
'Einige Angaben haben ein falsches Format. Bitte überprüfe sie und versuche es erneut.';
@override
String get validationGenericError =>
'Bitte überprüfe deine Eingaben und versuche es erneut.';
@override
String get fileNotFound =>
'Datei nicht gefunden. Vielleicht wurde sie verschoben oder gelöscht.';
@override
String get fileAccessDenied =>
'Datei kann nicht geöffnet werden. Bitte prüfe die Berechtigungen.';
@override
String get fileTooLarge =>
'Datei ist zu groß. Bitte wähle eine kleinere Datei.';
@override
String get fileGenericError =>
'Problem mit der Datei. Bitte versuche eine andere Datei.';
@override
String get permissionCameraRequired =>
'Kamerazugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.';
@override
String get permissionStorageRequired =>
'Speicherzugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.';
@override
String get permissionMicrophoneRequired =>
'Mikrofonzugriff erforderlich. Bitte aktiviere ihn in den Einstellungen.';
@override
String get permissionGenericError =>
'Berechtigung erforderlich. Bitte prüfe die App-Berechtigungen in den Einstellungen.';
@override
String get actionRetryRequest => 'Versuche die Anfrage erneut.';
@override
String get actionVerifyConnection => 'Überprüfe deine Internetverbindung.';
@override
String get actionRetryOperation => 'Wiederhole den Vorgang.';
@override
String get actionRetryAfterDelay =>
'Warte einen Moment und versuche es dann erneut.';
@override
String get actionSignInToAccount => 'Melde dich bei deinem Konto an.';
@override
String get actionSelectAnotherFile => 'Wähle eine andere Datei.';
@override
String get actionOpenAppSettings =>
'Öffne die App-Einstellungen, um Berechtigungen zu erteilen.';
@override
String get actionRetryAfterPermission =>
'Versuche es erneut, nachdem du die Berechtigung erteilt hast.';
@override
String get actionReturnToPrevious => 'Zur vorherigen Ansicht zurückkehren.';
@override
String get display => 'Anzeige';
@@ -945,10 +1124,6 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get transportMode => 'Transportmodus';
@override
String get transportModeDescription =>
'Wähle, wie die App für Echtzeit-Updates verbindet.';
@override
String get mode => 'Modus';
@@ -965,12 +1140,4 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get transportModeWsInfo =>
'Geringerer Overhead, kann jedoch hinter strikten Proxys/Firewalls fehlschlagen.';
@override
String get websocketConnectionError =>
'Echtzeit-Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihr Netzwerk und die Serverkonfiguration.';
@override
String get websocketReconnectFailed =>
'Echtzeit-Verbindung fehlgeschlagen. Streaming funktioniert möglicherweise nicht ordnungsgemäß.';
}

View File

@@ -11,9 +11,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get appTitle => 'Conduit';
@override
String get initializationFailed => 'Initialization Failed';
@override
String get retry => 'Retry';
@@ -40,10 +37,6 @@ class AppLocalizationsEn extends AppLocalizations {
String get connectionIssueSubtitle =>
'Reconnect to continue or sign out to choose a different server.';
@override
String get stillOfflineMessage =>
'We still can\'t reach the server. Double-check your connection and try again.';
@override
String get account => 'Account';
@@ -88,6 +81,12 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get availableModels => 'Available Models';
@override
String get modelCapabilityMultimodal => 'Multimodal';
@override
String get modelCapabilityReasoning => 'Reasoning';
@override
String get noResults => 'No results';
@@ -97,99 +96,53 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get errorMessage => 'Something went wrong. Please try again.';
@override
String get loginButton => 'Login';
@override
String get menuItem => 'Settings';
@override
String dynamicContentWithPlaceholder(String name) {
return 'Welcome, $name!';
}
@override
String itemsCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count items',
one: '1 item',
zero: 'No items',
);
return '$_temp0';
}
@override
String get closeButtonSemantic => 'Close';
@override
String get loadingContent => 'Loading content';
@override
String get loadingShort => 'Loading';
@override
String loadingAnnouncement(String message) {
return 'Loading: $message';
}
@override
String errorAnnouncement(String error) {
return 'Error: $error';
}
@override
String errorAnnouncementWithSuggestion(String error, String suggestion) {
return 'Error: $error. $suggestion';
}
@override
String successAnnouncement(String message) {
return 'Success: $message';
}
@override
String get noItems => 'No items';
@override
String get noItemsToDisplay => 'No items to display';
@override
String get loadMore => 'Load More';
@override
String get workspace => 'Workspace';
@override
String get recentFiles => 'Recent Files';
@override
String get knowledgeBase => 'Knowledge Base';
@override
String get noFilesYet => 'No files yet';
@override
String get uploadDocsPrompt =>
'Upload documents to reference in your conversations with Conduit';
@override
String get uploadFirstFile => 'Upload your first file';
@override
String get attachments => 'Attachments';
@override
String get knowledgeBaseEmpty => 'Knowledge base is empty';
@override
String get createCollectionsPrompt =>
'Create collections of related documents for easy reference';
@override
String get chooseSourcePhoto => 'Choose your source';
@override
String get takePhoto => 'Take a photo';
@override
String get chooseFromGallery => 'Choose from your photos';
@override
String get document => 'Document';
@override
String get documentHint => 'PDF, Word, or text file';
@override
String get uploadFileTitle => 'Upload File';
@override
String fileUploadComingSoon(String type) {
return 'File upload for $type is coming soon!';
}
@override
String get kbCreationComingSoon => 'Knowledge base creation is coming soon!';
@override
String get backToServerSetup => 'Back to server setup';
@@ -397,9 +350,6 @@ class AppLocalizationsEn extends AppLocalizations {
String get onboardQuickBullet2 =>
'Start New Chat or manage models from the top bar';
@override
String get addAttachment => 'Add attachment';
@override
String get attachmentLabel => 'Attachment';
@@ -439,6 +389,46 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get voiceActionStart => 'Start';
@override
String get voiceCallTitle => 'Voice Call';
@override
String get voiceCallPause => 'Pause';
@override
String get voiceCallResume => 'Resume';
@override
String get voiceCallStop => 'Stop';
@override
String get voiceCallEnd => 'End Call';
@override
String get voiceCallReady => 'Ready';
@override
String get voiceCallConnecting => 'Connecting...';
@override
String get voiceCallListening => 'Listening';
@override
String get voiceCallPaused => 'Paused';
@override
String get voiceCallProcessing => 'Thinking...';
@override
String get voiceCallSpeaking => 'Speaking';
@override
String get voiceCallDisconnected => 'Disconnected';
@override
String get voiceCallErrorHelp =>
'Please check:\n• Microphone permissions are granted\n• Speech recognition is available on your device\n• You are connected to the server';
@override
String get messageInputLabel => 'Message input';
@@ -463,6 +453,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get file => 'File';
@override
String get chooseDifferentFile => 'Choose Different File';
@override
String get photo => 'Photo';
@@ -497,17 +490,12 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get emptyImageData => 'Empty image data';
@override
String get featureRequiresInternet =>
'This feature requires an internet connection';
@override
String get messagesWillSendWhenOnline =>
'Messages will be sent when you\'re back online';
@override
String get confirm => 'Confirm';
@override
String get continueAction => 'Continue';
@override
String get cancel => 'Cancel';
@@ -515,10 +503,13 @@ class AppLocalizationsEn extends AppLocalizations {
String get ok => 'OK';
@override
String get inputField => 'Input field';
String get previousLabel => 'Prev';
@override
String get captureDocumentOrImage => 'Capture a document or image';
String get nextLabel => 'Next';
@override
String get inputField => 'Input field';
@override
String get checkConnection => 'Check Connection';
@@ -526,15 +517,31 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get openSettings => 'Open Settings';
@override
String get chooseDifferentFile => 'Choose Different File';
@override
String get goBack => 'Go Back';
@override
String get technicalDetails => 'Technical Details';
@override
String requiredFieldLabel(String label) {
return '$label *';
}
@override
String get requiredFieldHelper => 'Required field';
@override
String get switchOnLabel => 'On';
@override
String get switchOffLabel => 'Off';
@override
String dialogSemanticLabel(String title) {
return 'Dialog: $title';
}
@override
String get save => 'Save';
@@ -562,26 +569,15 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get clear => 'Clear';
@override
String get searchHint => 'Search...';
@override
String get searchConversations => 'Search conversations...';
@override
String get create => 'Create';
@override
String get folderCreated => 'Folder created';
@override
String get failedToCreateFolder => 'Failed to create folder';
@override
String movedChatToFolder(String title, String folder) {
return 'Moved \"$title\" to \"$folder\"';
}
@override
String get failedToMoveChat => 'Failed to move chat';
@@ -812,9 +808,6 @@ class AppLocalizationsEn extends AppLocalizations {
String get maxHeadersReachedDetail =>
'Maximum of 10 custom headers allowed. Remove some to add more.';
@override
String get editMessage => 'Edit Message';
@override
String get noModelsAvailable => 'No models available';
@@ -830,8 +823,38 @@ class AppLocalizationsEn extends AppLocalizations {
String get themePalette => 'Accent palette';
@override
String get themePaletteDescription =>
'Choose the accent colors used for buttons, cards, and chat bubbles.';
String get themePaletteConduitLabel => 'Conduit';
@override
String get themePaletteConduitDescription =>
'Clean neutral theme designed for Conduit.';
@override
String get themePaletteClaudeLabel => 'Claude';
@override
String get themePaletteClaudeDescription =>
'Warm, tactile palette lifted from the Claude web client.';
@override
String get themePaletteT3ChatLabel => 'T3 Chat';
@override
String get themePaletteT3ChatDescription =>
'Playful gradients inspired by the T3 Stack brand.';
@override
String get themePaletteCatppuccinLabel => 'Catppuccin';
@override
String get themePaletteCatppuccinDescription => 'Soft pastel palette.';
@override
String get themePaletteTangerineLabel => 'Tangerine';
@override
String get themePaletteTangerineDescription =>
'Warm orange-and-slate palette.';
@override
String get themeLight => 'Light';
@@ -877,6 +900,21 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get quickActionsDescription => 'Quickpills in chat';
@override
String quickActionsSelectedCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count actions selected',
one: '1 action selected',
zero: 'No actions selected',
);
return '$_temp0';
}
@override
String get autoSelectDescription => 'Let the app choose the best model';
@override
String get chatSettings => 'Chat';
@@ -887,6 +925,15 @@ class AppLocalizationsEn extends AppLocalizations {
String get sendOnEnterDescription =>
'Enter sends (soft keyboard). Cmd/Ctrl+Enter also available';
@override
String get ttsEngineLabel => 'Engine';
@override
String get ttsEngineDevice => 'On device';
@override
String get ttsEngineServer => 'Server';
@override
String get ttsSettings => 'Text to Speech';
@@ -928,6 +975,134 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get error => 'Error';
@override
String errorWithMessage(String message) {
return 'Error: $message';
}
@override
String get networkTimeoutError =>
'Connection timed out. Please check your internet connection and try again.';
@override
String get networkUnreachableError =>
'Cannot reach the server. Please check your server URL and internet connection.';
@override
String get networkServerNotResponding =>
'Server is not responding. Please verify the server is running and accessible.';
@override
String get networkGenericError =>
'Network connection problem. Please check your internet connection.';
@override
String get serverError500 =>
'Server is experiencing issues. This is usually temporary.';
@override
String get serverErrorUnavailable =>
'Server is temporarily unavailable. Please try again in a moment.';
@override
String get serverErrorTimeout =>
'Server took too long to respond. Please try again.';
@override
String get serverErrorGeneric =>
'Server is having problems. Please try again later.';
@override
String get authSessionExpired =>
'Your session has expired. Please sign in again.';
@override
String get authForbidden =>
'You don\'t have permission to perform this action.';
@override
String get authInvalidToken =>
'Authentication token is invalid. Please sign in again.';
@override
String get authGenericError =>
'Authentication problem. Please sign in again.';
@override
String get validationInvalidEmail => 'Please enter a valid email address.';
@override
String get validationWeakPassword =>
'Password doesn\'t meet requirements. Please check and try again.';
@override
String get validationMissingRequired => 'Please fill in all required fields.';
@override
String get validationFormatError =>
'Some information is in the wrong format. Please check and try again.';
@override
String get validationGenericError => 'Please check your input and try again.';
@override
String get fileNotFound =>
'File not found. It may have been moved or deleted.';
@override
String get fileAccessDenied =>
'Cannot access the file. Please check permissions.';
@override
String get fileTooLarge => 'File is too large. Please choose a smaller file.';
@override
String get fileGenericError =>
'Problem with the file. Please try a different file.';
@override
String get permissionCameraRequired =>
'Camera permission is required. Please enable it in settings.';
@override
String get permissionStorageRequired =>
'Storage permission is required. Please enable it in settings.';
@override
String get permissionMicrophoneRequired =>
'Microphone permission is required. Please enable it in settings.';
@override
String get permissionGenericError =>
'Permission required. Please check app permissions in settings.';
@override
String get actionRetryRequest => 'Try the request again.';
@override
String get actionVerifyConnection => 'Verify your internet connection.';
@override
String get actionRetryOperation => 'Retry the operation.';
@override
String get actionRetryAfterDelay => 'Wait a moment then try again.';
@override
String get actionSignInToAccount => 'Sign in to your account.';
@override
String get actionSelectAnotherFile => 'Select another file.';
@override
String get actionOpenAppSettings => 'Open app settings to grant permissions.';
@override
String get actionRetryAfterPermission => 'Retry after granting permission.';
@override
String get actionReturnToPrevious => 'Return to previous screen.';
@override
String get display => 'Display';
@@ -937,10 +1112,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get transportMode => 'Transport mode';
@override
String get transportModeDescription =>
'Choose how the app connects for realtime updates.';
@override
String get mode => 'Mode';
@@ -957,12 +1128,4 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get transportModeWsInfo =>
'Lower overhead, but may fail behind strict proxies/firewalls.';
@override
String get websocketConnectionError =>
'Unable to establish real-time connection. Please check your network and server configuration.';
@override
String get websocketReconnectFailed =>
'Real-time connection failed. Streaming may not work properly.';
}

View File

@@ -11,9 +11,6 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get appTitle => 'Conduit';
@override
String get initializationFailed => 'Échec de l\'initialisation';
@override
String get retry => 'Réessayer';
@@ -40,10 +37,6 @@ class AppLocalizationsFr extends AppLocalizations {
String get connectionIssueSubtitle =>
'Reconnectez-vous pour continuer ou déconnectez-vous pour choisir un autre serveur.';
@override
String get stillOfflineMessage =>
'Nous ne pouvons toujours pas joindre le serveur. Vérifiez votre connexion et réessayez.';
@override
String get account => 'Compte';
@@ -89,6 +82,12 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get availableModels => 'Modèles disponibles';
@override
String get modelCapabilityMultimodal => 'Multimodal';
@override
String get modelCapabilityReasoning => 'Raisonnement';
@override
String get noResults => 'Aucun résultat';
@@ -98,100 +97,53 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get errorMessage => 'Une erreur s\'est produite. Veuillez réessayer.';
@override
String get loginButton => 'Connexion';
@override
String get menuItem => 'Paramètres';
@override
String dynamicContentWithPlaceholder(String name) {
return 'Bienvenue, $name !';
}
@override
String itemsCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count éléments',
one: '1 élément',
zero: 'Aucun élément',
);
return '$_temp0';
}
@override
String get closeButtonSemantic => 'Fermer';
@override
String get loadingContent => 'Chargement du contenu';
@override
String get loadingShort => 'Chargement';
@override
String loadingAnnouncement(String message) {
return 'Chargement : $message';
}
@override
String errorAnnouncement(String error) {
return 'Erreur : $error';
}
@override
String errorAnnouncementWithSuggestion(String error, String suggestion) {
return 'Erreur : $error. $suggestion';
}
@override
String successAnnouncement(String message) {
return 'Succès : $message';
}
@override
String get noItems => 'Aucun élément';
@override
String get noItemsToDisplay => 'Aucun élément à afficher';
@override
String get loadMore => 'Charger plus';
@override
String get workspace => 'Espace de travail';
@override
String get recentFiles => 'Fichiers récents';
@override
String get knowledgeBase => 'Base de connaissances';
@override
String get noFilesYet => 'Pas encore de fichiers';
@override
String get uploadDocsPrompt =>
'Importez des documents à utiliser dans vos conversations avec Conduit';
@override
String get uploadFirstFile => 'Importer votre premier fichier';
@override
String get attachments => 'Pièces jointes';
@override
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';
@override
String get chooseSourcePhoto => 'Choisir la source';
@override
String get takePhoto => 'Prendre une photo';
@override
String get chooseFromGallery => 'Choisir depuis vos photos';
@override
String get document => 'Document';
@override
String get documentHint => 'Fichier PDF, Word ou texte';
@override
String get uploadFileTitle => 'Importer un fichier';
@override
String fileUploadComingSoon(String type) {
return 'Le téléversement de fichiers pour $type arrive bientôt !';
}
@override
String get kbCreationComingSoon =>
'La création de la base de connaissances arrive bientôt !';
@override
String get backToServerSetup => 'Retour à la configuration du serveur';
@@ -407,9 +359,6 @@ class AppLocalizationsFr extends AppLocalizations {
String get onboardQuickBullet2 =>
'Lancez Nouveau chat ou gérez les modèles depuis la barre';
@override
String get addAttachment => 'Ajouter une pièce jointe';
@override
String get attachmentLabel => 'Pièce jointe';
@@ -449,6 +398,46 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get voiceActionStart => 'Démarrer';
@override
String get voiceCallTitle => 'Appel vocal';
@override
String get voiceCallPause => 'Pause';
@override
String get voiceCallResume => 'Reprendre';
@override
String get voiceCallStop => 'Arrêter';
@override
String get voiceCallEnd => 'Terminer l\'appel';
@override
String get voiceCallReady => 'Prêt';
@override
String get voiceCallConnecting => 'Connexion…';
@override
String get voiceCallListening => 'Écoute';
@override
String get voiceCallPaused => 'En pause';
@override
String get voiceCallProcessing => 'Réflexion…';
@override
String get voiceCallSpeaking => 'Parle';
@override
String get voiceCallDisconnected => 'Déconnecté';
@override
String get voiceCallErrorHelp =>
'Veuillez vérifier :\n• Les autorisations du microphone sont accordées\n• La reconnaissance vocale est disponible sur votre appareil\n• Vous êtes connecté au serveur';
@override
String get messageInputLabel => 'Saisie du message';
@@ -473,6 +462,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get file => 'Fichier';
@override
String get chooseDifferentFile => 'Choisir un autre fichier';
@override
String get photo => 'Photo';
@@ -507,17 +499,12 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get emptyImageData => 'Données d\'image vides';
@override
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';
@override
String get confirm => 'Confirmer';
@override
String get continueAction => 'Continuer';
@override
String get cancel => 'Annuler';
@@ -525,10 +512,13 @@ class AppLocalizationsFr extends AppLocalizations {
String get ok => 'OK';
@override
String get inputField => 'Champ de saisie';
String get previousLabel => 'Précédent';
@override
String get captureDocumentOrImage => 'Capturer un document ou une image';
String get nextLabel => 'Suivant';
@override
String get inputField => 'Champ de saisie';
@override
String get checkConnection => 'Vérifier la connexion';
@@ -536,15 +526,31 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get openSettings => 'Ouvrir les réglages';
@override
String get chooseDifferentFile => 'Choisir un autre fichier';
@override
String get goBack => 'Retour';
@override
String get technicalDetails => 'Détails techniques';
@override
String requiredFieldLabel(String label) {
return '$label *';
}
@override
String get requiredFieldHelper => 'Champ obligatoire';
@override
String get switchOnLabel => 'Activé';
@override
String get switchOffLabel => 'Désactivé';
@override
String dialogSemanticLabel(String title) {
return 'Dialogue : $title';
}
@override
String get save => 'Enregistrer';
@@ -572,26 +578,15 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get clear => 'Effacer';
@override
String get searchHint => 'Rechercher...';
@override
String get searchConversations => 'Rechercher des conversations...';
@override
String get create => 'Créer';
@override
String get folderCreated => 'Dossier créé';
@override
String get failedToCreateFolder => 'Échec de la création du dossier';
@override
String movedChatToFolder(String title, String folder) {
return '\"$title\" déplacé vers \"$folder\"';
}
@override
String get failedToMoveChat => 'Échec du déplacement du chat';
@@ -826,9 +821,6 @@ class AppLocalizationsFr extends AppLocalizations {
String get maxHeadersReachedDetail =>
'Maximum 10 en-têtes personnalisés. Supprimez-en pour en ajouter.';
@override
String get editMessage => 'Modifier le message';
@override
String get noModelsAvailable => 'Aucun modèle disponible';
@@ -844,8 +836,39 @@ class AppLocalizationsFr extends AppLocalizations {
String get themePalette => 'Palette de couleurs';
@override
String get themePaletteDescription =>
'Choisissez les couleurs d\'accent utilisées pour les boutons, les cartes et les bulles de discussion.';
String get themePaletteConduitLabel => 'Conduit';
@override
String get themePaletteConduitDescription =>
'Thème neutre et épuré conçu pour Conduit.';
@override
String get themePaletteClaudeLabel => 'Claude';
@override
String get themePaletteClaudeDescription =>
'Palette chaleureuse inspirée du client web de Claude.';
@override
String get themePaletteT3ChatLabel => 'T3 Chat';
@override
String get themePaletteT3ChatDescription =>
'Dégradés ludiques inspirés de la marque T3 Stack.';
@override
String get themePaletteCatppuccinLabel => 'Catppuccin';
@override
String get themePaletteCatppuccinDescription =>
'Palette douce de tons pastel.';
@override
String get themePaletteTangerineLabel => 'Tangerine';
@override
String get themePaletteTangerineDescription =>
'Palette chaleureuse d\'oranges et d\'ardoises.';
@override
String get themeLight => 'Clair';
@@ -891,6 +914,22 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get quickActionsDescription => 'Raccourcis dans le chat';
@override
String quickActionsSelectedCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count actions sélectionnées',
one: '$count action sélectionnée',
zero: 'Aucune action sélectionnée',
);
return '$_temp0';
}
@override
String get autoSelectDescription =>
'Laissez l\'application choisir le meilleur modèle';
@override
String get chatSettings => 'Discussion';
@@ -901,6 +940,15 @@ class AppLocalizationsFr extends AppLocalizations {
String get sendOnEnterDescription =>
'Entrée envoie (clavier logiciel). Cmd/Ctrl+Entrée aussi disponible';
@override
String get ttsEngineLabel => 'Moteur';
@override
String get ttsEngineDevice => 'Sur l\'appareil';
@override
String get ttsEngineServer => 'Serveur';
@override
String get ttsSettings => 'Synthèse vocale';
@@ -942,6 +990,140 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get error => 'Erreur';
@override
String errorWithMessage(String message) {
return 'Erreur : $message';
}
@override
String get networkTimeoutError =>
'La connexion a expiré. Vérifiez votre connexion Internet et réessayez.';
@override
String get networkUnreachableError =>
'Impossible d\'atteindre le serveur. Vérifiez l\'URL du serveur et votre connexion Internet.';
@override
String get networkServerNotResponding =>
'Le serveur ne répond pas. Vérifiez qu\'il est en cours d\'exécution et accessible.';
@override
String get networkGenericError =>
'Problème de connexion réseau. Vérifiez votre connexion Internet.';
@override
String get serverError500 =>
'Le serveur rencontre des problèmes. Cela est généralement temporaire.';
@override
String get serverErrorUnavailable =>
'Le serveur est temporairement indisponible. Réessayez dans un instant.';
@override
String get serverErrorTimeout =>
'Le serveur a mis trop de temps à répondre. Réessayez.';
@override
String get serverErrorGeneric =>
'Le serveur rencontre des difficultés. Réessayez plus tard.';
@override
String get authSessionExpired =>
'Votre session a expiré. Veuillez vous reconnecter.';
@override
String get authForbidden =>
'Vous n\'avez pas l\'autorisation d\'effectuer cette action.';
@override
String get authInvalidToken =>
'Le jeton d\'authentification est invalide. Veuillez vous reconnecter.';
@override
String get authGenericError =>
'Problème d\'authentification. Veuillez vous reconnecter.';
@override
String get validationInvalidEmail =>
'Veuillez saisir une adresse e-mail valide.';
@override
String get validationWeakPassword =>
'Le mot de passe ne respecte pas les exigences. Vérifiez-le et réessayez.';
@override
String get validationMissingRequired =>
'Veuillez remplir tous les champs obligatoires.';
@override
String get validationFormatError =>
'Certaines informations sont au mauvais format. Vérifiez-les et réessayez.';
@override
String get validationGenericError =>
'Veuillez vérifier vos informations et réessayer.';
@override
String get fileNotFound =>
'Fichier introuvable. Il a peut-être été déplacé ou supprimé.';
@override
String get fileAccessDenied =>
'Impossible d\'accéder au fichier. Vérifiez les autorisations.';
@override
String get fileTooLarge =>
'Le fichier est trop volumineux. Choisissez un fichier plus petit.';
@override
String get fileGenericError =>
'Problème avec le fichier. Essayez un autre fichier.';
@override
String get permissionCameraRequired =>
'L\'autorisation de la caméra est nécessaire. Activez-la dans les paramètres.';
@override
String get permissionStorageRequired =>
'L\'autorisation de stockage est nécessaire. Activez-la dans les paramètres.';
@override
String get permissionMicrophoneRequired =>
'L\'autorisation du microphone est nécessaire. Activez-la dans les paramètres.';
@override
String get permissionGenericError =>
'Autorisation requise. Vérifiez les autorisations de l\'application dans les paramètres.';
@override
String get actionRetryRequest => 'Réessayez la requête.';
@override
String get actionVerifyConnection => 'Vérifiez votre connexion Internet.';
@override
String get actionRetryOperation => 'Réessayez l\'opération.';
@override
String get actionRetryAfterDelay => 'Attendez un instant puis réessayez.';
@override
String get actionSignInToAccount => 'Connectez-vous à votre compte.';
@override
String get actionSelectAnotherFile => 'Sélectionnez un autre fichier.';
@override
String get actionOpenAppSettings =>
'Ouvrez les paramètres de l\'application pour accorder les autorisations.';
@override
String get actionRetryAfterPermission =>
'Réessayez après avoir accordé l\'autorisation.';
@override
String get actionReturnToPrevious => 'Revenir à l\'écran précédent.';
@override
String get display => 'Affichage';
@@ -951,10 +1133,6 @@ class AppLocalizationsFr extends AppLocalizations {
@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.';
@override
String get mode => 'Mode';
@@ -971,12 +1149,4 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get transportModeWsInfo =>
'Moins de surcharge, mais peut échouer derrière des proxys/firewalls stricts.';
@override
String get websocketConnectionError =>
'Impossible d\'établir une connexion en temps réel. Veuillez vérifier votre réseau et la configuration du serveur.';
@override
String get websocketReconnectFailed =>
'Échec de la connexion en temps réel. Le streaming pourrait ne pas fonctionner correctement.';
}

View File

@@ -11,9 +11,6 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get appTitle => 'Conduit';
@override
String get initializationFailed => 'Inizializzazione non riuscita';
@override
String get retry => 'Riprova';
@@ -39,10 +36,6 @@ class AppLocalizationsIt extends AppLocalizations {
String get connectionIssueSubtitle =>
'Riconnettiti per continuare oppure esci per scegliere un server diverso.';
@override
String get stillOfflineMessage =>
'Non riusciamo ancora a raggiungere il server. Controlla la connessione e riprova.';
@override
String get account => 'Account';
@@ -88,6 +81,12 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get availableModels => 'Modelli disponibili';
@override
String get modelCapabilityMultimodal => 'Multimodale';
@override
String get modelCapabilityReasoning => 'Ragionamento';
@override
String get noResults => 'Nessun risultato';
@@ -97,100 +96,53 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get errorMessage => 'Qualcosa è andato storto. Riprova.';
@override
String get loginButton => 'Accedi';
@override
String get menuItem => 'Impostazioni';
@override
String dynamicContentWithPlaceholder(String name) {
return 'Benvenuto, $name!';
}
@override
String itemsCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count elementi',
one: '1 elemento',
zero: 'Nessun elemento',
);
return '$_temp0';
}
@override
String get closeButtonSemantic => 'Chiudi';
@override
String get loadingContent => 'Caricamento contenuto';
@override
String get loadingShort => 'Caricamento';
@override
String loadingAnnouncement(String message) {
return 'Caricamento: $message';
}
@override
String errorAnnouncement(String error) {
return 'Errore: $error';
}
@override
String errorAnnouncementWithSuggestion(String error, String suggestion) {
return 'Errore: $error. $suggestion';
}
@override
String successAnnouncement(String message) {
return 'Operazione riuscita: $message';
}
@override
String get noItems => 'Nessun elemento';
@override
String get noItemsToDisplay => 'Nessun elemento da visualizzare';
@override
String get loadMore => 'Carica altro';
@override
String get workspace => 'Spazio di lavoro';
@override
String get recentFiles => 'File recenti';
@override
String get knowledgeBase => 'Base di conoscenza';
@override
String get noFilesYet => 'Ancora nessun file';
@override
String get uploadDocsPrompt =>
'Carica documenti da usare nelle conversazioni con Conduit';
@override
String get uploadFirstFile => 'Carica il tuo primo file';
@override
String get attachments => 'Allegati';
@override
String get knowledgeBaseEmpty => 'La base di conoscenza è vuota';
@override
String get createCollectionsPrompt =>
'Crea raccolte di documenti correlati per un rapido riferimento';
@override
String get chooseSourcePhoto => 'Scegli origine';
@override
String get takePhoto => 'Scatta una foto';
@override
String get chooseFromGallery => 'Scegli dalle foto';
@override
String get document => 'Documento';
@override
String get documentHint => 'File PDF, Word o di testo';
@override
String get uploadFileTitle => 'Carica file';
@override
String fileUploadComingSoon(String type) {
return 'Il caricamento file per $type arriverà presto!';
}
@override
String get kbCreationComingSoon =>
'La creazione della base di conoscenza arriverà presto!';
@override
String get backToServerSetup => 'Torna alla configurazione del server';
@@ -399,9 +351,6 @@ class AppLocalizationsIt extends AppLocalizations {
String get onboardQuickBullet2 =>
'Avvia Nuova chat o gestisci i modelli dalla barra';
@override
String get addAttachment => 'Aggiungi allegato';
@override
String get attachmentLabel => 'Allegato';
@@ -441,6 +390,46 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get voiceActionStart => 'Avvia';
@override
String get voiceCallTitle => 'Chiamata vocale';
@override
String get voiceCallPause => 'Pausa';
@override
String get voiceCallResume => 'Riprendi';
@override
String get voiceCallStop => 'Stop';
@override
String get voiceCallEnd => 'Termina chiamata';
@override
String get voiceCallReady => 'Pronto';
@override
String get voiceCallConnecting => 'Connessione...';
@override
String get voiceCallListening => 'In ascolto';
@override
String get voiceCallPaused => 'In pausa';
@override
String get voiceCallProcessing => 'Elaborazione...';
@override
String get voiceCallSpeaking => 'Sta parlando';
@override
String get voiceCallDisconnected => 'Disconnesso';
@override
String get voiceCallErrorHelp =>
'Controlla:\n• Sono state concesse le autorizzazioni del microfono\n• Il riconoscimento vocale è disponibile sul dispositivo\n• Sei connesso al server';
@override
String get messageInputLabel => 'Input messaggio';
@@ -465,6 +454,9 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get file => 'File';
@override
String get chooseDifferentFile => 'Scegli un altro file';
@override
String get photo => 'Foto';
@@ -499,17 +491,12 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get emptyImageData => 'Dati immagine vuoti';
@override
String get featureRequiresInternet =>
'Questa funzione richiede una connessione Internet';
@override
String get messagesWillSendWhenOnline =>
'I messaggi verranno inviati quando tornerai online';
@override
String get confirm => 'Conferma';
@override
String get continueAction => 'Continua';
@override
String get cancel => 'Annulla';
@@ -517,10 +504,13 @@ class AppLocalizationsIt extends AppLocalizations {
String get ok => 'OK';
@override
String get inputField => 'Campo di input';
String get previousLabel => 'Precedente';
@override
String get captureDocumentOrImage => 'Acquisisci un documento o un\'immagine';
String get nextLabel => 'Successivo';
@override
String get inputField => 'Campo di input';
@override
String get checkConnection => 'Controlla connessione';
@@ -528,15 +518,31 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get openSettings => 'Apri impostazioni';
@override
String get chooseDifferentFile => 'Scegli un altro file';
@override
String get goBack => 'Indietro';
@override
String get technicalDetails => 'Dettagli tecnici';
@override
String requiredFieldLabel(String label) {
return '$label *';
}
@override
String get requiredFieldHelper => 'Campo obbligatorio';
@override
String get switchOnLabel => 'Attivo';
@override
String get switchOffLabel => 'Disattivo';
@override
String dialogSemanticLabel(String title) {
return 'Dialogo: $title';
}
@override
String get save => 'Salva';
@@ -564,26 +570,15 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get clear => 'Pulisci';
@override
String get searchHint => 'Cerca...';
@override
String get searchConversations => 'Cerca conversazioni...';
@override
String get create => 'Crea';
@override
String get folderCreated => 'Cartella creata';
@override
String get failedToCreateFolder => 'Impossibile creare la cartella';
@override
String movedChatToFolder(String title, String folder) {
return '\"$title\" spostata in \"$folder\"';
}
@override
String get failedToMoveChat => 'Impossibile spostare la chat';
@@ -815,9 +810,6 @@ class AppLocalizationsIt extends AppLocalizations {
String get maxHeadersReachedDetail =>
'Massimo 10 header personalizzati consentiti. Rimuovine alcuni per aggiungerne altri.';
@override
String get editMessage => 'Modifica messaggio';
@override
String get noModelsAvailable => 'Nessun modello disponibile';
@@ -833,8 +825,39 @@ class AppLocalizationsIt extends AppLocalizations {
String get themePalette => 'Palette di colori';
@override
String get themePaletteDescription =>
'Scegli i colori di accento usati per pulsanti, schede e bolle di chat.';
String get themePaletteConduitLabel => 'Conduit';
@override
String get themePaletteConduitDescription =>
'Tema neutro e pulito progettato per Conduit.';
@override
String get themePaletteClaudeLabel => 'Claude';
@override
String get themePaletteClaudeDescription =>
'Palette calda e tattile ispirata al client web Claude.';
@override
String get themePaletteT3ChatLabel => 'T3 Chat';
@override
String get themePaletteT3ChatDescription =>
'Sfumature vivaci ispirate al brand T3 Stack.';
@override
String get themePaletteCatppuccinLabel => 'Catppuccin';
@override
String get themePaletteCatppuccinDescription =>
'Palette morbida di tonalità pastello.';
@override
String get themePaletteTangerineLabel => 'Tangerine';
@override
String get themePaletteTangerineDescription =>
'Palette calda arancione e ardesia.';
@override
String get themeLight => 'Chiaro';
@@ -880,6 +903,22 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get quickActionsDescription => 'Scorciatoie nella chat';
@override
String quickActionsSelectedCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count azioni selezionate',
one: '$count azione selezionata',
zero: 'Nessuna azione selezionata',
);
return '$_temp0';
}
@override
String get autoSelectDescription =>
'Lascia che l\'app scelga il modello migliore';
@override
String get chatSettings => 'Chat';
@@ -890,6 +929,15 @@ class AppLocalizationsIt extends AppLocalizations {
String get sendOnEnterDescription =>
'Invio invia (tastiera software). Cmd/Ctrl+Invio disponibile';
@override
String get ttsEngineLabel => 'Motore';
@override
String get ttsEngineDevice => 'Sul dispositivo';
@override
String get ttsEngineServer => 'Server';
@override
String get ttsSettings => 'Sintesi vocale';
@@ -931,6 +979,135 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get error => 'Errore';
@override
String errorWithMessage(String message) {
return 'Errore: $message';
}
@override
String get networkTimeoutError =>
'Connessione scaduta. Controlla la tua connessione Internet e riprova.';
@override
String get networkUnreachableError =>
'Impossibile raggiungere il server. Controlla l\'URL del server e la connessione Internet.';
@override
String get networkServerNotResponding =>
'Il server non risponde. Verifica che sia attivo e raggiungibile.';
@override
String get networkGenericError =>
'Problema di connessione di rete. Controlla la connessione Internet.';
@override
String get serverError500 =>
'Il server sta avendo problemi. Di solito è temporaneo.';
@override
String get serverErrorUnavailable =>
'Il server è temporaneamente non disponibile. Riprova tra poco.';
@override
String get serverErrorTimeout =>
'Il server ha impiegato troppo tempo a rispondere. Riprova.';
@override
String get serverErrorGeneric =>
'Il server è in difficoltà. Riprova più tardi.';
@override
String get authSessionExpired => 'La sessione è scaduta. Accedi di nuovo.';
@override
String get authForbidden =>
'Non hai l\'autorizzazione per eseguire questa azione.';
@override
String get authInvalidToken =>
'Il token di autenticazione non è valido. Accedi di nuovo.';
@override
String get authGenericError => 'Problema di autenticazione. Accedi di nuovo.';
@override
String get validationInvalidEmail => 'Inserisci un indirizzo email valido.';
@override
String get validationWeakPassword =>
'La password non soddisfa i requisiti. Controllala e riprova.';
@override
String get validationMissingRequired => 'Compila tutti i campi obbligatori.';
@override
String get validationFormatError =>
'Alcune informazioni non sono nel formato corretto. Controllale e riprova.';
@override
String get validationGenericError => 'Controlla i dati inseriti e riprova.';
@override
String get fileNotFound =>
'File non trovato. Potrebbe essere stato spostato o eliminato.';
@override
String get fileAccessDenied =>
'Impossibile accedere al file. Controlla i permessi.';
@override
String get fileTooLarge =>
'Il file è troppo grande. Scegline uno più piccolo.';
@override
String get fileGenericError =>
'Problema con il file. Prova con un file diverso.';
@override
String get permissionCameraRequired =>
'È necessario il permesso della fotocamera. Attivalo nelle impostazioni.';
@override
String get permissionStorageRequired =>
'È necessario il permesso di archiviazione. Attivalo nelle impostazioni.';
@override
String get permissionMicrophoneRequired =>
'È necessario il permesso del microfono. Attivalo nelle impostazioni.';
@override
String get permissionGenericError =>
'È necessaria un\'autorizzazione. Controlla i permessi dell\'app nelle impostazioni.';
@override
String get actionRetryRequest => 'Riprova la richiesta.';
@override
String get actionVerifyConnection => 'Verifica la connessione a Internet.';
@override
String get actionRetryOperation => 'Riprova l\'operazione.';
@override
String get actionRetryAfterDelay => 'Attendi un momento e riprova.';
@override
String get actionSignInToAccount => 'Accedi al tuo account.';
@override
String get actionSelectAnotherFile => 'Seleziona un altro file.';
@override
String get actionOpenAppSettings =>
'Apri le impostazioni dell\'app per concedere i permessi.';
@override
String get actionRetryAfterPermission =>
'Riprova dopo aver concesso il permesso.';
@override
String get actionReturnToPrevious => 'Torna alla schermata precedente.';
@override
String get display => 'Schermo';
@@ -940,10 +1117,6 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get transportMode => 'Modalità di trasporto';
@override
String get transportModeDescription =>
'Scegli come l\'app si connette per gli aggiornamenti in tempo reale.';
@override
String get mode => 'Modalità';
@@ -960,12 +1133,4 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get transportModeWsInfo =>
'Minore overhead, ma può fallire dietro proxy/firewall restrittivi.';
@override
String get websocketConnectionError =>
'Impossibile stabilire una connessione in tempo reale. Si prega di controllare la rete e la configurazione del server.';
@override
String get websocketReconnectFailed =>
'Connessione in tempo reale fallita. Lo streaming potrebbe non funzionare correttamente.';
}

View File

@@ -1,7 +1,6 @@
{
"@@locale": "nl",
"appTitle": "Conduit",
"initializationFailed": "Initialisatie mislukt",
"retry": "Opnieuw proberen",
"back": "Terug",
"you": "Jij",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Ondertitel die beschikbare acties uitlegt wanneer de server niet bereikbaar is"
},
"stillOfflineMessage": "We kunnen de server nog steeds niet bereiken. Controleer je verbinding en probeer het opnieuw.",
"@stillOfflineMessage": {
"description": "Statusbericht na een herhaalde poging wanneer de verbinding niet is hersteld"
},
"account": "Account",
"supportConduit": "Ondersteun Conduit",
"supportConduitSubtitle": "Houd Conduit onafhankelijk door doorlopende ontwikkeling te financieren.",
@@ -37,32 +32,14 @@
"noResults": "Geen resultaten",
"searchModels": "Modellen zoeken...",
"errorMessage": "Er is iets misgegaan. Probeer het opnieuw.",
"loginButton": "Inloggen",
"menuItem": "Instellingen",
"dynamicContentWithPlaceholder": "Welkom, {name}!",
"itemsCount": "{count, plural, =0{Geen items} one{1 item} other{{count} items}}",
"closeButtonSemantic": "Sluiten",
"loadingContent": "Inhoud laden",
"noItems": "Geen items",
"noItemsToDisplay": "Geen items om weer te geven",
"loadMore": "Meer laden",
"workspace": "Werkruimte",
"recentFiles": "Recente bestanden",
"knowledgeBase": "Kennisbank",
"noFilesYet": "Nog geen bestanden",
"uploadDocsPrompt": "Upload documenten om te gebruiken in je gesprekken met Conduit",
"uploadFirstFile": "Upload je eerste bestand",
"attachments": "Bijlagen",
"knowledgeBaseEmpty": "Kennisbank is leeg",
"createCollectionsPrompt": "Maak verzamelingen van gerelateerde documenten voor eenvoudige verwijzing",
"chooseSourcePhoto": "Kies je bron",
"takePhoto": "Foto maken",
"chooseFromGallery": "Kies uit je foto's",
"document": "Document",
"documentHint": "PDF, Word of tekstbestand",
"uploadFileTitle": "Bestand uploaden",
"fileUploadComingSoon": "Bestand uploaden voor {type} komt binnenkort!",
"kbCreationComingSoon": "Kennisbank aanmaken komt binnenkort!",
"backToServerSetup": "Terug naar serverinstelling",
"connectedToServer": "Verbonden met server",
"signIn": "Inloggen",
@@ -125,7 +102,6 @@
"onboardQuickSubtitle": "Open het menu om te schakelen tussen Chats, Werkruimte en Profiel.",
"onboardQuickBullet1": "Tik op het menu voor toegang tot Chats, Werkruimte, Profiel",
"onboardQuickBullet2": "Start Nieuwe chat of beheer modellen vanuit de bovenbalk",
"addAttachment": "Bijlage toevoegen",
"attachmentLabel": "Bijlage",
"tools": "Hulpmiddelen",
"voiceInput": "Spraakinvoer",
@@ -157,16 +133,12 @@
"failedToDecodeImage": "Kan afbeelding niet decoderen",
"invalidImageFormat": "Ongeldig afbeeldingsformaat",
"emptyImageData": "Lege afbeeldingsgegevens",
"featureRequiresInternet": "Deze functie vereist een internetverbinding",
"messagesWillSendWhenOnline": "Berichten worden verzonden wanneer je weer online bent",
"confirm": "Bevestigen",
"cancel": "Annuleren",
"ok": "OK",
"inputField": "Invoerveld",
"captureDocumentOrImage": "Document of afbeelding vastleggen",
"checkConnection": "Verbinding controleren",
"openSettings": "Instellingen openen",
"chooseDifferentFile": "Ander bestand kiezen",
"goBack": "Terug",
"technicalDetails": "Technische details",
"save": "Opslaan",
@@ -178,18 +150,9 @@
"newChat": "Nieuwe chat",
"more": "Meer",
"clear": "Wissen",
"searchHint": "Zoeken...",
"searchConversations": "Gesprekken zoeken...",
"create": "Aanmaken",
"folderCreated": "Map aangemaakt",
"failedToCreateFolder": "Kan map niet aanmaken",
"movedChatToFolder": "'{title}' verplaatst naar '{folder}'",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "Kan chat niet verplaatsen",
"failedToLoadChats": "Kan chats niet laden",
"failedToUpdatePin": "Kan vastpinning niet bijwerken",
@@ -219,13 +182,17 @@
"deleteMessagesMessage": "{count} berichten verwijderen?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Route niet gevonden: {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Chat verwijderen",
@@ -271,29 +238,55 @@
"headerNameTooLong": "Header-naam te lang (max 64 tekens)",
"headerNameInvalidChars": "Ongeldige header-naam. Gebruik alleen letters, cijfers en deze symbolen: !#$&-^_`|~",
"headerNameReserved": "Kan gereserveerde header '{key}' niet overschrijven",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "Header-waarde mag niet leeg zijn",
"headerValueTooLong": "Header-waarde te lang (max 1024 tekens)",
"headerValueInvalidChars": "Header-waarde bevat ongeldige tekens. Gebruik alleen afdrukbare ASCII.",
"headerValueUnsafe": "Header-waarde lijkt mogelijk onveilige inhoud te bevatten",
"headerAlreadyExists": "Header '{key}' bestaat al. Verwijder deze eerst om bij te werken.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Maximaal 10 aangepaste headers toegestaan. Verwijder er enkele om meer toe te voegen.",
"editMessage": "Bericht bewerken",
"noModelsAvailable": "Geen modellen beschikbaar",
"followingSystem": "Volgt systeem: {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Donker",
"themePalette": "Accentpalet",
"@themePalette": {"description": "Titel voor het selecteren van het app-kleurenpalet."},
"themePaletteDescription": "Kies de accentkleuren voor knoppen, kaarten en chatballonnen.",
"@themePaletteDescription": {"description": "Hulptekst die de paletselectie uitlegt."},
"@themePalette": {
"description": "Titel voor het selecteren van het app-kleurenpalet."
},
"themeLight": "Licht",
"currentlyUsingDarkTheme": "Momenteel donker thema in gebruik",
"currentlyUsingLightTheme": "Momenteel licht thema in gebruik",
"aboutConduit": "Over Conduit",
"versionLabel": "Versie: {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "GitHub-repository",
"unableToLoadAppInfo": "Kan app-info niet laden",
"thinking": "Denken...",
@@ -301,7 +294,12 @@
"thoughtForDuration": "Dacht {duration}",
"@thoughtForDuration": {
"description": "Toont hoe lang de assistent dacht voordat hij antwoordde.",
"placeholders": {"duration": {"type": "String", "example": "3s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3s"
}
}
},
"appCustomization": "Aanpassing",
"appCustomizationSubtitle": "Thema, taal, stem en quickpills",
@@ -325,12 +323,413 @@
"display": "Weergave",
"realtime": "Realtime",
"transportMode": "Transportmodus",
"transportModeDescription": "Kies hoe de app verbindt voor realtime updates.",
"mode": "Modus",
"transportModePolling": "Polling-fallback",
"transportModeWs": "Alleen WebSocket",
"transportModePollingInfo": "Valt terug op HTTP-polling wanneer WebSocket geblokkeerd is. Upgrade naar WebSocket zodra dat kan.",
"transportModeWsInfo": "Lagere overhead, maar kan mislukken achter strikte proxies/firewalls.",
"websocketConnectionError": "Kan geen realtime verbinding maken. Controleer uw netwerk en serverconfiguratie.",
"websocketReconnectFailed": "Realtime verbinding mislukt. Streaming werkt mogelijk niet goed."
"quickActionsSelectedCount": "{count, plural, =0{Geen acties geselecteerd} one{{count} actie geselecteerd} other{{count} acties geselecteerd}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Laat de app het beste model kiezen",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Engine",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "Op het apparaat",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Server",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Multimodaal",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Redeneren",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Spraakoproep",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Pauze",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Hervatten",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Stoppen",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Oproep beëindigen",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Ander bestand kiezen",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Fout: {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "De verbinding is verlopen. Controleer je internetverbinding en probeer het opnieuw.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "Server niet bereikbaar. Controleer de server-URL en je internetverbinding.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "Server reageert niet. Controleer of de server actief en bereikbaar is.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Netwerkprobleem. Controleer je internetverbinding.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "De server heeft problemen. Dit is meestal tijdelijk.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "Server tijdelijk niet beschikbaar. Probeer het zo weer.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "De server deed te lang over een antwoord. Probeer het opnieuw.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "De server ondervindt problemen. Probeer het later opnieuw.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "Je sessie is verlopen. Log opnieuw in.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "Je hebt geen toestemming voor deze actie.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "Authenticatietoken is ongeldig. Log opnieuw in.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Authenticatieprobleem. Log opnieuw in.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Voer een geldig e-mailadres in.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "Het wachtwoord voldoet niet aan de vereisten. Controleer het en probeer opnieuw.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Vul alle verplichte velden in.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Sommige informatie heeft het verkeerde formaat. Controleer en probeer opnieuw.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Controleer je invoer en probeer opnieuw.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "Bestand niet gevonden. Het is mogelijk verplaatst of verwijderd.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "Kan geen toegang krijgen tot het bestand. Controleer de rechten.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "Het bestand is te groot. Kies een kleiner bestand.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Probleem met het bestand. Probeer een ander bestand.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "Cameratoegang is vereist. Schakel dit in via de instellingen.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "Opslagtoegang is vereist. Schakel dit in via de instellingen.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "Microfoontoegang is vereist. Schakel dit in via de instellingen.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "Toestemming vereist. Controleer de app-machtigingen in de instellingen.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Probeer de aanvraag opnieuw.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Controleer je internetverbinding.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Probeer de actie opnieuw.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Wacht even en probeer het opnieuw.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Log in op je account.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Kies een ander bestand.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Open de app-instellingen om toestemming te geven.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Probeer opnieuw nadat je toestemming hebt gegeven.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Keer terug naar het vorige scherm.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Doorgaan",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Laden",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Laden: {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Fout: {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Fout: {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Succes: {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Verplicht veld",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Aan",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Uit",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Dialoog: {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Vorige",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Volgende",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Strak neutraal thema ontworpen voor Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Warm, tactiel palet geïnspireerd op de Claude-webclient.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Speelse verlopen geïnspireerd op het T3 Stack-merk.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Zacht pastelkleurig palet.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Warm oranje-en-leisteenpalet.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Gereed",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Verbinding maken...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "Luistert",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "Gepauzeerd",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Denkt na...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Spreekt",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Verbinding verbroken",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Controleer het volgende:\n• Microfoonmachtigingen zijn toegestaan\n• Spraakherkenning is beschikbaar op je apparaat\n• Je bent verbonden met de server",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -1,7 +1,6 @@
{
"@@locale": "ru",
"appTitle": "Conduit",
"initializationFailed": "Ошибка инициализации",
"retry": "Повторить",
"back": "Назад",
"you": "Вы",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "Подзаголовок с доступными действиями при недоступности сервера"
},
"stillOfflineMessage": "Мы все еще не можем подключиться к серверу. Проверьте соединение и повторите попытку.",
"@stillOfflineMessage": {
"description": "Сообщение после повторной попытки, когда соединение не восстановлено"
},
"account": "Аккаунт",
"supportConduit": "Поддержать Conduit",
"supportConduitSubtitle": "Сохраните независимость Conduit, финансируя разработку.",
@@ -37,32 +32,14 @@
"noResults": "Нет результатов",
"searchModels": "Поиск моделей...",
"errorMessage": "Что-то пошло не так. Пожалуйста, попробуйте еще раз.",
"loginButton": "Войти",
"menuItem": "Настройки",
"dynamicContentWithPlaceholder": "Добро пожаловать, {name}!",
"itemsCount": "{count, plural, =0{Нет элементов} one{{count} элемент} few{{count} элемента} other{{count} элементов}}",
"closeButtonSemantic": "Закрыть",
"loadingContent": "Загрузка содержимого",
"noItems": "Нет элементов",
"noItemsToDisplay": "Нет элементов для отображения",
"loadMore": "Загрузить еще",
"workspace": "Рабочее пространство",
"recentFiles": "Недавние файлы",
"knowledgeBase": "База знаний",
"noFilesYet": "Пока нет файлов",
"uploadDocsPrompt": "Загрузите документы для использования в разговорах с Conduit",
"uploadFirstFile": "Загрузить первый файл",
"attachments": "Вложения",
"knowledgeBaseEmpty": "База знаний пуста",
"createCollectionsPrompt": "Создайте коллекции связанных документов для удобной ссылки",
"chooseSourcePhoto": "Выберите источник",
"takePhoto": "Сделать фото",
"chooseFromGallery": "Выбрать из галереи",
"document": "Документ",
"documentHint": "PDF, Word или текстовый файл",
"uploadFileTitle": "Загрузить файл",
"fileUploadComingSoon": "Загрузка файлов для {type} скоро появится!",
"kbCreationComingSoon": "Создание базы знаний скоро появится!",
"backToServerSetup": "Вернуться к настройке сервера",
"connectedToServer": "Подключено к серверу",
"signIn": "Войти",
@@ -125,7 +102,6 @@
"onboardQuickSubtitle": "Откройте меню для переключения между чатами, рабочим пространством и профилем.",
"onboardQuickBullet1": "Нажмите на меню для доступа к чатам, рабочему пространству, профилю",
"onboardQuickBullet2": "Начните новый чат или управляйте моделями из верхней панели",
"addAttachment": "Добавить вложение",
"attachmentLabel": "Вложение",
"tools": "Инструменты",
"voiceInput": "Голосовой ввод",
@@ -157,16 +133,12 @@
"failedToDecodeImage": "Не удалось декодировать изображение",
"invalidImageFormat": "Неверный формат изображения",
"emptyImageData": "Пустые данные изображения",
"featureRequiresInternet": "Эта функция требует подключения к интернету",
"messagesWillSendWhenOnline": "Сообщения будут отправлены, когда вы снова будете онлайн",
"confirm": "Подтвердить",
"cancel": "Отмена",
"ok": "OK",
"inputField": "Поле ввода",
"captureDocumentOrImage": "Сфотографировать документ или изображение",
"checkConnection": "Проверить соединение",
"openSettings": "Открыть настройки",
"chooseDifferentFile": "Выбрать другой файл",
"goBack": "Назад",
"technicalDetails": "Технические детали",
"save": "Сохранить",
@@ -178,18 +150,9 @@
"newChat": "Новый чат",
"more": "Еще",
"clear": "Очистить",
"searchHint": "Поиск...",
"searchConversations": "Поиск разговоров...",
"create": "Создать",
"folderCreated": "Папка создана",
"failedToCreateFolder": "Не удалось создать папку",
"movedChatToFolder": "Перемещено «{title}» в «{folder}»",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "Не удалось переместить чат",
"failedToLoadChats": "Не удалось загрузить чаты",
"failedToUpdatePin": "Не удалось обновить закрепление",
@@ -219,13 +182,17 @@
"deleteMessagesMessage": "Удалить {count, plural, one{{count} сообщение} few{{count} сообщения} other{{count} сообщений}}?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "Маршрут не найден: {routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "Удалить чат",
@@ -271,29 +238,55 @@
"headerNameTooLong": "Имя заголовка слишком длинное (максимум 64 символа)",
"headerNameInvalidChars": "Недопустимое имя заголовка. Используйте только буквы, цифры и эти символы: !#$&-^_`|~",
"headerNameReserved": "Невозможно переопределить зарезервированный заголовок «{key}»",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "Значение заголовка не может быть пустым",
"headerValueTooLong": "Значение заголовка слишком длинное (максимум 1024 символа)",
"headerValueInvalidChars": "Значение заголовка содержит недопустимые символы. Используйте только печатаемые ASCII.",
"headerValueUnsafe": "Значение заголовка содержит потенциально небезопасное содержимое",
"headerAlreadyExists": "Заголовок «{key}» уже существует. Сначала удалите его для обновления.",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "Разрешено максимум 10 пользовательских заголовков. Удалите некоторые, чтобы добавить больше.",
"editMessage": "Редактировать сообщение",
"noModelsAvailable": "Нет доступных моделей",
"followingSystem": "Следует за системой: {theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "Темная",
"themePalette": "Цветовая палитра",
"@themePalette": {"description": "Заголовок для выбора цветовой палитры приложения."},
"themePaletteDescription": "Выберите акцентные цвета для кнопок, карточек и пузырьков чата.",
"@themePaletteDescription": {"description": "Вспомогательный текст, объясняющий выбор палитры."},
"@themePalette": {
"description": "Заголовок для выбора цветовой палитры приложения."
},
"themeLight": "Светлая",
"currentlyUsingDarkTheme": "Используется темная тема",
"currentlyUsingLightTheme": "Используется светлая тема",
"aboutConduit": "О Conduit",
"versionLabel": "Версия: {version} ({build})",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "Репозиторий GitHub",
"unableToLoadAppInfo": "Не удалось загрузить информацию о приложении",
"thinking": "Думаю...",
@@ -301,7 +294,12 @@
"thoughtForDuration": "Думал {duration}",
"@thoughtForDuration": {
"description": "Показывает, сколько времени ассистент думал перед ответом.",
"placeholders": {"duration": {"type": "String", "example": "3с"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3с"
}
}
},
"appCustomization": "Настройка",
"appCustomizationSubtitle": "Тема, язык, голос и quickpills",
@@ -325,12 +323,413 @@
"display": "Отображение",
"realtime": "Реальное время",
"transportMode": "Режим транспорта",
"transportModeDescription": "Выберите, как приложение подключается для обновлений в реальном времени.",
"mode": "Режим",
"transportModePolling": "Опрос (резерв)",
"transportModeWs": "Только WebSocket",
"transportModePollingInfo": "Переходит на HTTP-опрос, если WebSocket заблокирован. Возвращается к WebSocket, когда это возможно.",
"transportModeWsInfo": "Меньше накладных расходов, но может не работать за строгими прокси/брандмауэрами.",
"websocketConnectionError": "Не удалось установить соединение в реальном времени. Пожалуйста, проверьте сеть и конфигурацию сервера.",
"websocketReconnectFailed": "Сбой соединения в реальном времени. Потоковая передача может работать неправильно."
"quickActionsSelectedCount": "{count, plural, =0{Действия не выбраны} one{{count} действие выбрано} few{{count} действия выбраны} many{{count} действий выбрано} other{{count} действий выбрано}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "Позвольте приложению выбрать лучшую модель",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "Движок",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "На устройстве",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "Сервер",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "Мультимодальность",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "Рассуждения",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "Голосовой звонок",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "Пауза",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "Продолжить",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "Остановить",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "Завершить звонок",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "Выбрать другой файл",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "Ошибка: {message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "Время соединения истекло. Проверьте подключение к интернету и повторите попытку.",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "Не удаётся связаться с сервером. Проверьте URL сервера и подключение к интернету.",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "Сервер не отвечает. Убедитесь, что он запущен и доступен.",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "Проблема с подключением. Проверьте подключение к интернету.",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "На сервере возникли проблемы. Обычно это временно.",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "Сервер временно недоступен. Повторите попытку чуть позже.",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "Сервер слишком долго отвечает. Повторите попытку.",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "Сервер испытывает трудности. Повторите попытку позже.",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "Сессия истекла. Выполните вход снова.",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "У вас нет прав для выполнения этого действия.",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "Токен аутентификации недействителен. Выполните вход снова.",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "Проблема с аутентификацией. Выполните вход снова.",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "Введите корректный адрес электронной почты.",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "Пароль не соответствует требованиям. Проверьте его и повторите попытку.",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "Заполните все обязательные поля.",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "Некоторые данные указаны в неверном формате. Проверьте и повторите попытку.",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "Проверьте введённые данные и повторите попытку.",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "Файл не найден. Возможно, он был перемещён или удалён.",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "Нет доступа к файлу. Проверьте разрешения.",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "Файл слишком большой. Выберите файл меньшего размера.",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "Проблема с файлом. Попробуйте другой файл.",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "Требуется доступ к камере. Включите его в настройках.",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "Требуется доступ к хранилищу. Включите его в настройках.",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "Требуется доступ к микрофону. Включите его в настройках.",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "Требуется разрешение. Проверьте разрешения приложения в настройках.",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "Повторите запрос.",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "Проверьте подключение к интернету.",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "Повторите операцию.",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "Подождите немного и попробуйте снова.",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "Войдите в свою учётную запись.",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "Выберите другой файл.",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "Откройте настройки приложения, чтобы предоставить разрешения.",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "Повторите попытку после предоставления разрешения.",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "Вернуться на предыдущий экран.",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "Продолжить",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "Загрузка",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "Загрузка: {message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "Ошибка: {error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "Ошибка: {error}. {suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "Успешно: {message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "Обязательное поле",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "Вкл.",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "Выкл.",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "Диалог: {title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "Назад",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "Далее",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "Нейтральная чистая тема, созданная для Conduit.",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "Тёплая тактильная палитра из веб-клиента Claude.",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "Игривые градиенты, вдохновлённые брендом T3 Stack.",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "Мягкая пастельная палитра.",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "Тёплая палитра оранжевых и сланцевых оттенков.",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "Готово",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "Подключение...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "Слушает",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "Пауза",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "Обрабатывает...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "Говорит",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "Отключено",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "Проверьте:\n• Разрешение на микрофон предоставлено\n• Распознавание речи доступно на устройстве\n• Есть подключение к серверу",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -1,7 +1,6 @@
{
"@@locale": "zh",
"appTitle": "Conduit",
"initializationFailed": "初始化失败",
"retry": "重试",
"back": "返回",
"you": "你",
@@ -16,10 +15,6 @@
"@connectionIssueSubtitle": {
"description": "当无法访问服务器时解释可用操作的副标题"
},
"stillOfflineMessage": "我们仍然无法访问服务器。请仔细检查您的连接并重试。",
"@stillOfflineMessage": {
"description": "重试后连接未恢复时的状态消息"
},
"account": "账户",
"supportConduit": "支持 Conduit",
"supportConduitSubtitle": "通过资助持续开发来保持 Conduit 的独立性。",
@@ -37,32 +32,14 @@
"noResults": "无结果",
"searchModels": "搜索模型...",
"errorMessage": "出了点问题。请重试。",
"loginButton": "登录",
"menuItem": "设置",
"dynamicContentWithPlaceholder": "欢迎,{name}",
"itemsCount": "{count, plural, =0{无项目} other{{count} 个项目}}",
"closeButtonSemantic": "关闭",
"loadingContent": "加载内容中",
"noItems": "无项目",
"noItemsToDisplay": "无可显示的项目",
"loadMore": "加载更多",
"workspace": "工作区",
"recentFiles": "最近文件",
"knowledgeBase": "知识库",
"noFilesYet": "尚无文件",
"uploadDocsPrompt": "上传文档以在您与 Conduit 的对话中引用",
"uploadFirstFile": "上传您的第一个文件",
"attachments": "附件",
"knowledgeBaseEmpty": "知识库为空",
"createCollectionsPrompt": "创建相关文档集合以便于引用",
"chooseSourcePhoto": "选择来源",
"takePhoto": "拍照",
"chooseFromGallery": "从相册中选择",
"document": "文档",
"documentHint": "PDF、Word 或文本文件",
"uploadFileTitle": "上传文件",
"fileUploadComingSoon": "{type} 的文件上传即将推出!",
"kbCreationComingSoon": "知识库创建即将推出!",
"backToServerSetup": "返回服务器设置",
"connectedToServer": "已连接到服务器",
"signIn": "登录",
@@ -125,7 +102,6 @@
"onboardQuickSubtitle": "打开菜单在对话、工作区和个人资料之间切换。",
"onboardQuickBullet1": "点击菜单访问对话、工作区、个人资料",
"onboardQuickBullet2": "从顶部栏开始新对话或管理模型",
"addAttachment": "添加附件",
"attachmentLabel": "附件",
"tools": "工具",
"voiceInput": "语音输入",
@@ -157,16 +133,12 @@
"failedToDecodeImage": "无法解码图像",
"invalidImageFormat": "无效的图像格式",
"emptyImageData": "空图像数据",
"featureRequiresInternet": "此功能需要互联网连接",
"messagesWillSendWhenOnline": "当您重新上线时将发送消息",
"confirm": "确认",
"cancel": "取消",
"ok": "确定",
"inputField": "输入字段",
"captureDocumentOrImage": "捕获文档或图像",
"checkConnection": "检查连接",
"openSettings": "打开设置",
"chooseDifferentFile": "选择其他文件",
"goBack": "返回",
"technicalDetails": "技术详情",
"save": "保存",
@@ -178,18 +150,9 @@
"newChat": "新对话",
"more": "更多",
"clear": "清除",
"searchHint": "搜索...",
"searchConversations": "搜索对话...",
"create": "创建",
"folderCreated": "文件夹已创建",
"failedToCreateFolder": "无法创建文件夹",
"movedChatToFolder": "已将「{title}」移至「{folder}」",
"@movedChatToFolder": {
"placeholders": {
"title": {"type": "String"},
"folder": {"type": "String"}
}
},
"failedToMoveChat": "无法移动对话",
"failedToLoadChats": "无法加载对话",
"failedToUpdatePin": "无法更新置顶",
@@ -219,13 +182,17 @@
"deleteMessagesMessage": "删除 {count} 条消息?",
"@deleteMessagesMessage": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"routeNotFound": "未找到路由:{routeName}",
"@routeNotFound": {
"placeholders": {
"routeName": {"type": "String"}
"routeName": {
"type": "String"
}
}
},
"deleteChatTitle": "删除对话",
@@ -271,29 +238,55 @@
"headerNameTooLong": "标头名称太长(最多 64 个字符)",
"headerNameInvalidChars": "无效的标头名称。仅使用字母、数字和这些符号:!#$&-^_`|~",
"headerNameReserved": "无法覆盖保留的标头「{key}」",
"@headerNameReserved": {"placeholders": {"key": {"type": "String"}}},
"@headerNameReserved": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"headerValueEmpty": "标头值不能为空",
"headerValueTooLong": "标头值太长(最多 1024 个字符)",
"headerValueInvalidChars": "标头值包含无效字符。仅使用可打印的 ASCII。",
"headerValueUnsafe": "标头值似乎包含潜在的不安全内容",
"headerAlreadyExists": "标头「{key}」已存在。首先删除它以更新。",
"@headerAlreadyExists": {"placeholders": {"key": {"type": "String"}}},
"@headerAlreadyExists": {
"placeholders": {
"key": {
"type": "String"
}
}
},
"maxHeadersReachedDetail": "最多允许 10 个自定义标头。删除一些以添加更多。",
"editMessage": "编辑消息",
"noModelsAvailable": "无可用模型",
"followingSystem": "跟随系统:{theme}",
"@followingSystem": {"placeholders": {"theme": {"type": "String"}}},
"@followingSystem": {
"placeholders": {
"theme": {
"type": "String"
}
}
},
"themeDark": "深色",
"themePalette": "强调色调色板",
"@themePalette": {"description": "选择应用颜色调色板的标题。"},
"themePaletteDescription": "选择用于按钮、卡片和对话气泡的强调色。",
"@themePaletteDescription": {"description": "解释调色板选择的帮助文本。"},
"@themePalette": {
"description": "选择应用颜色调色板的标题。"
},
"themeLight": "浅色",
"currentlyUsingDarkTheme": "当前使用深色主题",
"currentlyUsingLightTheme": "当前使用浅色主题",
"aboutConduit": "关于 Conduit",
"versionLabel": "版本:{version}{build}",
"@versionLabel": {"placeholders": {"version": {"type": "String"}, "build": {"type": "String"}}},
"@versionLabel": {
"placeholders": {
"version": {
"type": "String"
},
"build": {
"type": "String"
}
}
},
"githubRepository": "GitHub 仓库",
"unableToLoadAppInfo": "无法加载应用信息",
"thinking": "思考中...",
@@ -301,7 +294,12 @@
"thoughtForDuration": "思考了 {duration}",
"@thoughtForDuration": {
"description": "显示助手在回复前思考了多长时间。",
"placeholders": {"duration": {"type": "String", "example": "3s"}}
"placeholders": {
"duration": {
"type": "String",
"example": "3s"
}
}
},
"appCustomization": "自定义",
"appCustomizationSubtitle": "主题、语言、语音和 quickpills",
@@ -325,12 +323,413 @@
"display": "显示",
"realtime": "实时",
"transportMode": "传输模式",
"transportModeDescription": "选择应用如何连接以进行实时更新。",
"mode": "模式",
"transportModePolling": "轮询回退",
"transportModeWs": "仅 WebSocket",
"transportModePollingInfo": "当 WebSocket 被阻止时改用 HTTP 轮询,在条件允许时切换回 WebSocket。",
"transportModeWsInfo": "开销较低,但可能在严格的代理/防火墙后失败。",
"websocketConnectionError": "无法建立实时连接。请检查您的网络和服务器配置。",
"websocketReconnectFailed": "实时连接失败。流式传输可能无法正常工作。"
"quickActionsSelectedCount": "{count, plural, =0{未选择操作} other{已选择{count}个操作}}",
"@quickActionsSelectedCount": {
"description": "Subtitle indicating how many quick actions are selected.",
"placeholders": {
"count": {
"type": "int",
"example": "2"
}
}
},
"autoSelectDescription": "让应用自动选择最佳模型",
"@autoSelectDescription": {
"description": "Explains what the auto-select model setting does."
},
"ttsEngineLabel": "引擎",
"@ttsEngineLabel": {
"description": "Label for selecting the text-to-speech engine."
},
"ttsEngineDevice": "本机",
"@ttsEngineDevice": {
"description": "Chip label for using on-device text-to-speech."
},
"ttsEngineServer": "服务器",
"@ttsEngineServer": {
"description": "Chip label for using server-side text-to-speech."
},
"modelCapabilityMultimodal": "多模态",
"@modelCapabilityMultimodal": {
"description": "Capability chip label for models that support multimodal input."
},
"modelCapabilityReasoning": "推理",
"@modelCapabilityReasoning": {
"description": "Capability chip label for models that support reasoning features."
},
"voiceCallTitle": "语音通话",
"@voiceCallTitle": {
"description": "Title displayed on the voice call screen."
},
"voiceCallPause": "暂停",
"@voiceCallPause": {
"description": "Button label to pause a voice call."
},
"voiceCallResume": "继续",
"@voiceCallResume": {
"description": "Button label to resume a paused voice call."
},
"voiceCallStop": "停止",
"@voiceCallStop": {
"description": "Button label to stop the active voice call."
},
"voiceCallEnd": "结束通话",
"@voiceCallEnd": {
"description": "Button label to end the voice call session."
},
"chooseDifferentFile": "选择其他文件",
"@chooseDifferentFile": {
"description": "Action label prompting the user to pick another file."
},
"errorWithMessage": "错误:{message}",
"@errorWithMessage": {
"description": "Error label with appended message text.",
"placeholders": {
"message": {
"type": "String",
"example": "Network timeout"
}
}
},
"networkTimeoutError": "连接超时。请检查网络后重试。",
"@networkTimeoutError": {
"description": "User-facing message when a network request times out."
},
"networkUnreachableError": "无法连接服务器。请检查服务器地址和网络。",
"@networkUnreachableError": {
"description": "User-facing message when the server cannot be reached."
},
"networkServerNotResponding": "服务器没有响应。请确认服务器正在运行且可访问。",
"@networkServerNotResponding": {
"description": "User-facing message when the server does not respond to a request."
},
"networkGenericError": "网络连接出现问题。请检查网络连接。",
"@networkGenericError": {
"description": "Fallback message for generic network errors."
},
"serverError500": "服务器出现问题,通常是暂时的。",
"@serverError500": {
"description": "Message when a 500 error is encountered."
},
"serverErrorUnavailable": "服务器暂时不可用。请稍后再试。",
"@serverErrorUnavailable": {
"description": "Message when a 502/503 error is encountered."
},
"serverErrorTimeout": "服务器响应超时。请重试。",
"@serverErrorTimeout": {
"description": "Message when the server times out."
},
"serverErrorGeneric": "服务器出现故障。请稍后再试。",
"@serverErrorGeneric": {
"description": "Fallback server error message."
},
"authSessionExpired": "会话已过期,请重新登录。",
"@authSessionExpired": {
"description": "Message when an authentication session expires."
},
"authForbidden": "您没有执行此操作的权限。",
"@authForbidden": {
"description": "Message when the user lacks required permissions."
},
"authInvalidToken": "认证令牌无效,请重新登录。",
"@authInvalidToken": {
"description": "Message when the authentication token is invalid."
},
"authGenericError": "认证出现问题,请重新登录。",
"@authGenericError": {
"description": "Fallback authentication error message."
},
"validationInvalidEmail": "请输入有效的邮箱地址。",
"@validationInvalidEmail": {
"description": "Validation message for invalid email input."
},
"validationWeakPassword": "密码不符合要求,请检查后重试。",
"@validationWeakPassword": {
"description": "Validation message for weak passwords."
},
"validationMissingRequired": "请填写所有必填项。",
"@validationMissingRequired": {
"description": "Validation message when required fields are missing."
},
"validationFormatError": "部分信息格式不正确,请检查后重试。",
"@validationFormatError": {
"description": "Validation message for generic formatting issues."
},
"validationGenericError": "请检查输入内容并重试。",
"@validationGenericError": {
"description": "Fallback validation message."
},
"fileNotFound": "未找到文件,可能已移动或删除。",
"@fileNotFound": {
"description": "Message when a file cannot be located."
},
"fileAccessDenied": "无法访问文件,请检查权限。",
"@fileAccessDenied": {
"description": "Message when file access is denied."
},
"fileTooLarge": "文件过大,请选择较小的文件。",
"@fileTooLarge": {
"description": "Message when a file exceeds size limits."
},
"fileGenericError": "文件出现问题,请尝试其他文件。",
"@fileGenericError": {
"description": "Fallback file error message."
},
"permissionCameraRequired": "需要相机权限,请在设置中开启。",
"@permissionCameraRequired": {
"description": "Message when camera permission is missing."
},
"permissionStorageRequired": "需要存储权限,请在设置中开启。",
"@permissionStorageRequired": {
"description": "Message when storage permission is missing."
},
"permissionMicrophoneRequired": "需要麦克风权限,请在设置中开启。",
"@permissionMicrophoneRequired": {
"description": "Message when microphone permission is missing."
},
"permissionGenericError": "需要权限,请在设置中检查应用权限。",
"@permissionGenericError": {
"description": "Fallback permission error message."
},
"actionRetryRequest": "请再次尝试该请求。",
"@actionRetryRequest": {
"description": "Description for retrying a failed request."
},
"actionVerifyConnection": "请检查网络连接。",
"@actionVerifyConnection": {
"description": "Description for checking internet connectivity."
},
"actionRetryOperation": "请重试此操作。",
"@actionRetryOperation": {
"description": "Description for retrying the same operation."
},
"actionRetryAfterDelay": "稍等片刻再试一次。",
"@actionRetryAfterDelay": {
"description": "Description suggesting a short delay before retrying."
},
"actionSignInToAccount": "登录到您的账户。",
"@actionSignInToAccount": {
"description": "Description for signing back into the app."
},
"actionSelectAnotherFile": "请选择其他文件。",
"@actionSelectAnotherFile": {
"description": "Description for choosing a different file."
},
"actionOpenAppSettings": "打开应用设置以授予权限。",
"@actionOpenAppSettings": {
"description": "Description for opening system or app settings."
},
"actionRetryAfterPermission": "授予权限后请重试。",
"@actionRetryAfterPermission": {
"description": "Description for retrying once permissions are granted."
},
"actionReturnToPrevious": "返回上一屏。",
"@actionReturnToPrevious": {
"description": "Description for navigating back to the prior screen."
},
"continueAction": "继续",
"@continueAction": {
"description": "Button label to continue an action or flow."
},
"loadingShort": "加载中",
"@loadingShort": {
"description": "Short loading label used for accessibility."
},
"loadingAnnouncement": "正在加载:{message}",
"@loadingAnnouncement": {
"description": "Screen reader announcement when loading a resource.",
"placeholders": {
"message": {
"type": "String",
"example": "Messages"
}
}
},
"errorAnnouncement": "错误:{error}",
"@errorAnnouncement": {
"description": "Screen reader announcement for an error.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
}
}
},
"errorAnnouncementWithSuggestion": "错误:{error}。{suggestion}",
"@errorAnnouncementWithSuggestion": {
"description": "Screen reader announcement for an error with a follow-up suggestion.",
"placeholders": {
"error": {
"type": "String",
"example": "Network timeout"
},
"suggestion": {
"type": "String",
"example": "Please try again later."
}
}
},
"successAnnouncement": "成功:{message}",
"@successAnnouncement": {
"description": "Screen reader announcement for successful actions.",
"placeholders": {
"message": {
"type": "String",
"example": "Profile updated"
}
}
},
"requiredFieldLabel": "{label} *",
"@requiredFieldLabel": {
"description": "Label text indicating a required field.",
"placeholders": {
"label": {
"type": "String",
"example": "Email"
}
}
},
"requiredFieldHelper": "必填项",
"@requiredFieldHelper": {
"description": "Helper text indicating that the field is required."
},
"switchOnLabel": "开启",
"@switchOnLabel": {
"description": "Semantic label when a switch is enabled."
},
"switchOffLabel": "关闭",
"@switchOffLabel": {
"description": "Semantic label when a switch is disabled."
},
"dialogSemanticLabel": "对话框:{title}",
"@dialogSemanticLabel": {
"description": "Semantic label describing the dialog title.",
"placeholders": {
"title": {
"type": "String",
"example": "Settings"
}
}
},
"previousLabel": "上一步",
"@previousLabel": {
"description": "Label for navigating to the previous item."
},
"nextLabel": "下一步",
"@nextLabel": {
"description": "Label for navigating to the next item."
},
"themePaletteConduitLabel": "Conduit",
"@themePaletteConduitLabel": {
"description": "Palette name for the default Conduit theme."
},
"themePaletteConduitDescription": "为 Conduit 设计的简洁中性色主题。",
"@themePaletteConduitDescription": {
"description": "Description of the Conduit palette."
},
"themePaletteClaudeLabel": "Claude",
"@themePaletteClaudeLabel": {
"description": "Palette name inspired by the Claude web client."
},
"themePaletteClaudeDescription": "源自 Claude 网页端的温暖触感配色。",
"@themePaletteClaudeDescription": {
"description": "Description of the Claude palette."
},
"themePaletteT3ChatLabel": "T3 Chat",
"@themePaletteT3ChatLabel": {
"description": "Palette name inspired by the T3 Stack brand."
},
"themePaletteT3ChatDescription": "灵感来自 T3 Stack 品牌的活泼渐变。",
"@themePaletteT3ChatDescription": {
"description": "Description of the T3 Chat palette."
},
"themePaletteCatppuccinLabel": "Catppuccin",
"@themePaletteCatppuccinLabel": {
"description": "Palette name for Catppuccin colors."
},
"themePaletteCatppuccinDescription": "柔和的马卡龙色调。",
"@themePaletteCatppuccinDescription": {
"description": "Description of the Catppuccin palette."
},
"themePaletteTangerineLabel": "Tangerine",
"@themePaletteTangerineLabel": {
"description": "Palette name for Tangerine colors."
},
"themePaletteTangerineDescription": "温暖的橙色与石板色调。",
"@themePaletteTangerineDescription": {
"description": "Description of the Tangerine palette."
},
"@onboardStartTitle": {
"description": "Onboarding card: start chatting title.",
"placeholders": {
"username": {
"type": "String",
"example": "Alex"
}
}
},
"@notAnImageFile": {
"description": "Error when a referenced file is not an image.",
"placeholders": {
"fileName": {
"type": "String",
"example": "image.txt"
}
}
},
"@failedToLoadImage": {
"description": "Error including the underlying reason when image loading fails.",
"placeholders": {
"error": {
"type": "String",
"example": "Network error"
}
}
},
"@ttsVoicesForLanguage": {
"description": "Section header for voices matching the app language",
"placeholders": {
"language": {
"type": "String",
"example": "EN"
}
}
},
"voiceCallReady": "已就绪",
"@voiceCallReady": {
"description": "Status label shown when the voice call is ready to start."
},
"voiceCallConnecting": "正在连接...",
"@voiceCallConnecting": {
"description": "Status label shown while the voice call is connecting."
},
"voiceCallListening": "正在聆听",
"@voiceCallListening": {
"description": "Status label shown while the call is listening for input."
},
"voiceCallPaused": "已暂停",
"@voiceCallPaused": {
"description": "Status label shown when the call is paused."
},
"voiceCallProcessing": "正在思考...",
"@voiceCallProcessing": {
"description": "Status label shown while the call processes a response."
},
"voiceCallSpeaking": "正在讲话",
"@voiceCallSpeaking": {
"description": "Status label shown while the assistant is speaking."
},
"voiceCallDisconnected": "已断开",
"@voiceCallDisconnected": {
"description": "Status label shown when the voice call has ended or disconnected."
},
"voiceCallErrorHelp": "请检查:\n• 已授予麦克风权限\n• 设备支持语音识别\n• 已连接到服务器",
"@voiceCallErrorHelp": {
"description": "Guidance shown when the voice call encounters an error."
}
}

View File

@@ -1,3 +1,4 @@
import 'package:conduit/l10n/app_localizations.dart';
import 'package:flutter/material.dart';
/// Represents a single tweakcn theme variant (light or dark) and exposes the
@@ -88,16 +89,16 @@ class TweakcnThemeVariant {
class TweakcnThemeDefinition {
const TweakcnThemeDefinition({
required this.id,
required this.label,
required this.description,
required this.labelBuilder,
required this.descriptionBuilder,
required this.light,
required this.dark,
required this.preview,
});
final String id;
final String label;
final String description;
final String Function(AppLocalizations) labelBuilder;
final String Function(AppLocalizations) descriptionBuilder;
final TweakcnThemeVariant light;
final TweakcnThemeVariant dark;
final List<Color> preview;
@@ -105,6 +106,10 @@ class TweakcnThemeDefinition {
TweakcnThemeVariant variantFor(Brightness brightness) {
return brightness == Brightness.dark ? dark : light;
}
String label(AppLocalizations l10n) => labelBuilder(l10n);
String description(AppLocalizations l10n) => descriptionBuilder(l10n);
}
Color mix(Color a, Color b, double amount) {
@@ -771,8 +776,8 @@ class TweakcnThemes {
static final TweakcnThemeDefinition claude = TweakcnThemeDefinition(
id: 'claude',
label: 'Claude',
description: 'Warm, tactile palette lifted from the Claude web client.',
labelBuilder: (l10n) => l10n.themePaletteClaudeLabel,
descriptionBuilder: (l10n) => l10n.themePaletteClaudeDescription,
light: _claudeLight,
dark: _claudeDark,
preview: const <Color>[
@@ -784,8 +789,8 @@ class TweakcnThemes {
static final TweakcnThemeDefinition t3Chat = TweakcnThemeDefinition(
id: 't3_chat',
label: 'T3 Chat',
description: 'Playful gradients inspired by the T3 Stack brand.',
labelBuilder: (l10n) => l10n.themePaletteT3ChatLabel,
descriptionBuilder: (l10n) => l10n.themePaletteT3ChatDescription,
light: _t3ChatLight,
dark: _t3ChatDark,
preview: const <Color>[
@@ -797,8 +802,8 @@ class TweakcnThemes {
static final TweakcnThemeDefinition conduit = TweakcnThemeDefinition(
id: 'conduit',
label: 'Conduit',
description: 'Clean neutral theme designed for Conduit.',
labelBuilder: (l10n) => l10n.themePaletteConduitLabel,
descriptionBuilder: (l10n) => l10n.themePaletteConduitDescription,
light: _conduitLight,
dark: _conduitDark,
preview: const <Color>[
@@ -810,8 +815,8 @@ class TweakcnThemes {
static final TweakcnThemeDefinition catppuccin = TweakcnThemeDefinition(
id: 'catppuccin',
label: 'Catppuccin',
description: 'Soft pastel palette.',
labelBuilder: (l10n) => l10n.themePaletteCatppuccinLabel,
descriptionBuilder: (l10n) => l10n.themePaletteCatppuccinDescription,
light: _catppuccinLight,
dark: _catppuccinDark,
preview: const <Color>[
@@ -823,8 +828,8 @@ class TweakcnThemes {
static final TweakcnThemeDefinition tangerine = TweakcnThemeDefinition(
id: 'tangerine',
label: 'Tangerine',
description: 'Warm orange-and-slate palette.',
labelBuilder: (l10n) => l10n.themePaletteTangerineLabel,
descriptionBuilder: (l10n) => l10n.themePaletteTangerineDescription,
light: _tangerineLight,
dark: _tangerineDark,
preview: const <Color>[

View File

@@ -71,7 +71,7 @@ Future<void> main(List<String> args) async {
}
// Unused keys (best-effort) — WARNINGS only
final usedKeys = await _scanUsedLocalizationKeys();
final usedKeys = await _scanUsedLocalizationKeys(baseKeys);
final unused = baseKeys.difference(usedKeys);
if (unused.isNotEmpty) {
warnings.add('Unused keys in EN (best-effort): ${unused.toList()..sort()}');
@@ -120,22 +120,34 @@ Map<String, Set<String>> _placeholdersMap(Map<String, dynamic> m) {
// Duplicate detection intentionally omitted (see note above).
Future<Set<String>> _scanUsedLocalizationKeys() async {
final libDir = Directory('lib');
Future<Set<String>> _scanUsedLocalizationKeys(Set<String> baseKeys) async {
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);
Future<bool> keyIsUsed(String key) async {
final result = await Process.run('rg', [
'--fixed-strings',
'--quiet',
'--glob=*.dart',
'--glob=!lib/l10n/app_localizations*.dart',
key,
'lib',
]);
if (result.exitCode == 0) {
return true;
}
if (result.exitCode > 1) {
stderr.writeln(
'warning: failed to search for key "$key": ${result.stderr}'.trim(),
);
}
return false;
}
for (final key in baseKeys) {
if (await keyIsUsed(key)) {
used.add(key);
}
}
return used;
}