feat: enhance localization support with additional strings and improved structure
This commit is contained in:
@@ -4,6 +4,13 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleLocalizations</key>
|
||||||
|
<array>
|
||||||
|
<string>en</string>
|
||||||
|
<string>de</string>
|
||||||
|
<string>fr</string>
|
||||||
|
<string>it</string>
|
||||||
|
</array>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Conduit</string>
|
<string>Conduit</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:conduit/l10n/app_localizations.dart';
|
||||||
import '../../shared/theme/theme_extensions.dart';
|
import '../../shared/theme/theme_extensions.dart';
|
||||||
|
|
||||||
/// User-friendly error messages and recovery actions
|
/// User-friendly error messages and recovery actions
|
||||||
@@ -438,7 +439,7 @@ class ErrorCard extends StatelessWidget {
|
|||||||
if (showDetails && technicalDetails != null) ...[
|
if (showDetails && technicalDetails != null) ...[
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
ExpansionTile(
|
ExpansionTile(
|
||||||
title: const Text('Technical Details'),
|
title: Text(AppLocalizations.of(context)!.technicalDetails),
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
@@ -517,7 +518,7 @@ class ErrorDialog extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Icon(Icons.error_outline, color: Theme.of(context).colorScheme.error),
|
Icon(Icons.error_outline, color: Theme.of(context).colorScheme.error),
|
||||||
const SizedBox(width: Spacing.sm + Spacing.xs),
|
const SizedBox(width: Spacing.sm + Spacing.xs),
|
||||||
const Text('Error'),
|
Text(AppLocalizations.of(context)!.errorMessage),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
content: Column(
|
content: Column(
|
||||||
@@ -528,7 +529,7 @@ class ErrorDialog extends StatelessWidget {
|
|||||||
if (showDetails && technicalDetails != null) ...[
|
if (showDetails && technicalDetails != null) ...[
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
ExpansionTile(
|
ExpansionTile(
|
||||||
title: const Text('Technical Details'),
|
title: Text(AppLocalizations.of(context)!.technicalDetails),
|
||||||
children: [
|
children: [
|
||||||
SelectableText(
|
SelectableText(
|
||||||
technicalDetails!,
|
technicalDetails!,
|
||||||
@@ -545,7 +546,7 @@ class ErrorDialog extends StatelessWidget {
|
|||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: const Text('Cancel'),
|
child: Text(AppLocalizations.of(context)!.cancel),
|
||||||
),
|
),
|
||||||
if (actions.isNotEmpty)
|
if (actions.isNotEmpty)
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
|
|||||||
@@ -243,7 +243,9 @@ class AsyncErrorBoundary extends ConsumerWidget {
|
|||||||
(context as Element).markNeedsBuild();
|
(context as Element).markNeedsBuild();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.refresh),
|
icon: const Icon(Icons.refresh),
|
||||||
label: Text(AppLocalizations.of(context)!.retry),
|
label: Text(
|
||||||
|
AppLocalizations.of(context)?.retry ?? 'Retry',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:conduit/l10n/app_localizations.dart';
|
||||||
import '../../../core/widgets/error_boundary.dart';
|
import '../../../core/widgets/error_boundary.dart';
|
||||||
import '../../../shared/widgets/optimized_list.dart';
|
import '../../../shared/widgets/optimized_list.dart';
|
||||||
import '../../../shared/theme/theme_extensions.dart';
|
import '../../../shared/theme/theme_extensions.dart';
|
||||||
@@ -805,7 +806,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
|||||||
style: TextStyle(color: context.conduitTheme.textPrimary),
|
style: TextStyle(color: context.conduitTheme.textPrimary),
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Enter your message',
|
hintText: AppLocalizations.of(context)!.messageHintText,
|
||||||
hintStyle: TextStyle(color: context.conduitTheme.inputPlaceholder),
|
hintStyle: TextStyle(color: context.conduitTheme.inputPlaceholder),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: context.conduitTheme.inputBorder),
|
borderSide: BorderSide(color: context.conduitTheme.inputBorder),
|
||||||
@@ -831,7 +832,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
|||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
foregroundColor: context.conduitTheme.buttonPrimary,
|
foregroundColor: context.conduitTheme.buttonPrimary,
|
||||||
),
|
),
|
||||||
child: const Text('Save'),
|
child: Text(AppLocalizations.of(context)!.save),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -911,7 +912,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
|||||||
const SizedBox(height: Spacing.xl),
|
const SizedBox(height: Spacing.xl),
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
'Start a conversation',
|
AppLocalizations.of(context)!.onboardStartTitle,
|
||||||
style: theme.textTheme.headlineSmall?.copyWith(
|
style: theme.textTheme.headlineSmall?.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: context.conduitTheme.textPrimary,
|
color: context.conduitTheme.textPrimary,
|
||||||
@@ -921,7 +922,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
|||||||
const SizedBox(height: Spacing.sm),
|
const SizedBox(height: Spacing.sm),
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
'Type below to begin',
|
AppLocalizations.of(context)!.typeBelowToBegin,
|
||||||
style: theme.textTheme.bodyLarge?.copyWith(
|
style: theme.textTheme.bodyLarge?.copyWith(
|
||||||
color: context.conduitTheme.textSecondary,
|
color: context.conduitTheme.textSecondary,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -1221,7 +1222,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
|||||||
size: IconSize.appBar,
|
size: IconSize.appBar,
|
||||||
),
|
),
|
||||||
onPressed: _handleNewChat,
|
onPressed: _handleNewChat,
|
||||||
tooltip: 'New Chat',
|
tooltip: AppLocalizations.of(context)!.newChat,
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
IconButton(
|
IconButton(
|
||||||
@@ -1530,7 +1531,7 @@ class _ModelSelectorSheetState extends ConsumerState<_ModelSelectorSheet> {
|
|||||||
controller: _searchController,
|
controller: _searchController,
|
||||||
style: TextStyle(color: context.conduitTheme.textPrimary),
|
style: TextStyle(color: context.conduitTheme.textPrimary),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search...',
|
hintText: AppLocalizations.of(context)!.searchModels,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
color: context.conduitTheme.inputPlaceholder,
|
color: context.conduitTheme.inputPlaceholder,
|
||||||
),
|
),
|
||||||
@@ -2235,7 +2236,9 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
|
|||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.xmark
|
? CupertinoIcons.xmark
|
||||||
: Icons.close,
|
: Icons.close,
|
||||||
tooltip: 'Close',
|
tooltip: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.closeButtonSemantic,
|
||||||
isCompact: true,
|
isCompact: true,
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
@@ -2475,7 +2478,9 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
|
|||||||
ConduitIconButton(
|
ConduitIconButton(
|
||||||
icon: Icons.close,
|
icon: Icons.close,
|
||||||
isCompact: true,
|
isCompact: true,
|
||||||
tooltip: 'Clear',
|
tooltip: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.clear,
|
||||||
onPressed:
|
onPressed:
|
||||||
_recognizedText.isNotEmpty &&
|
_recognizedText.isNotEmpty &&
|
||||||
!_isTranscribing
|
!_isTranscribing
|
||||||
|
|||||||
@@ -393,7 +393,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.search
|
? CupertinoIcons.search
|
||||||
: Icons.search,
|
: Icons.search,
|
||||||
label: 'Web',
|
label: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.web,
|
||||||
isActive: webSearchEnabled,
|
isActive: webSearchEnabled,
|
||||||
onTap: widget.enabled
|
onTap: widget.enabled
|
||||||
? () {
|
? () {
|
||||||
@@ -413,7 +415,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.photo
|
? CupertinoIcons.photo
|
||||||
: Icons.image,
|
: Icons.image,
|
||||||
label: 'Image Gen',
|
label: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.imageGen,
|
||||||
isActive: imageGenEnabled,
|
isActive: imageGenEnabled,
|
||||||
onTap: widget.enabled
|
onTap: widget.enabled
|
||||||
? () {
|
? () {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:io' show File, Platform;
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:conduit/l10n/app_localizations.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import '../../../core/providers/app_providers.dart';
|
import '../../../core/providers/app_providers.dart';
|
||||||
@@ -353,12 +354,12 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
_isTranscribing
|
_isTranscribing
|
||||||
? 'Transcribing…'
|
? AppLocalizations.of(context)!.transcribing
|
||||||
: _isListening
|
: _isListening
|
||||||
? (_voiceService.hasLocalStt
|
? (_voiceService.hasLocalStt
|
||||||
? 'Listening…'
|
? AppLocalizations.of(context)!.listening
|
||||||
: 'Recording…')
|
: AppLocalizations.of(context)!.recording)
|
||||||
: 'Voice',
|
: AppLocalizations.of(context)!.voiceInput,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: AppTypography.headlineMedium,
|
fontSize: AppTypography.headlineMedium,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -426,7 +427,9 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.xmark
|
? CupertinoIcons.xmark
|
||||||
: Icons.close,
|
: Icons.close,
|
||||||
tooltip: 'Close',
|
tooltip: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.closeButtonSemantic,
|
||||||
isCompact: true,
|
isCompact: true,
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
@@ -456,11 +459,16 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
activeColor: context.conduitTheme.buttonPrimary,
|
activeColor: context.conduitTheme.buttonPrimary,
|
||||||
),
|
),
|
||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Text(
|
Flexible(
|
||||||
'Hold to talk',
|
child: Text(
|
||||||
style: TextStyle(color: context.conduitTheme.textSecondary),
|
AppLocalizations.of(context)!.holdToTalk,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: context.conduitTheme.textSecondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const SizedBox(width: Spacing.sm),
|
||||||
ps.PlatformService.getPlatformSwitch(
|
ps.PlatformService.getPlatformSwitch(
|
||||||
value: _autoSendFinal,
|
value: _autoSendFinal,
|
||||||
onChanged: (v) async {
|
onChanged: (v) async {
|
||||||
@@ -472,9 +480,14 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
activeColor: context.conduitTheme.buttonPrimary,
|
activeColor: context.conduitTheme.buttonPrimary,
|
||||||
),
|
),
|
||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Text(
|
Flexible(
|
||||||
'Auto-send',
|
child: Text(
|
||||||
style: TextStyle(color: context.conduitTheme.textSecondary),
|
AppLocalizations.of(context)!.autoSend,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: context.conduitTheme.textSecondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -521,8 +534,10 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
child: Semantics(
|
child: Semantics(
|
||||||
button: true,
|
button: true,
|
||||||
label: _isListening
|
label: _isListening
|
||||||
? 'Stop listening'
|
? AppLocalizations.of(context)!.stopListening
|
||||||
: 'Start listening',
|
: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.startListening,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -617,7 +632,9 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Transcript',
|
AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.transcript,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: AppTypography.labelSmall,
|
fontSize: AppTypography.labelSmall,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -630,7 +647,9 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
ConduitIconButton(
|
ConduitIconButton(
|
||||||
icon: Icons.close,
|
icon: Icons.close,
|
||||||
isCompact: true,
|
isCompact: true,
|
||||||
tooltip: 'Clear',
|
tooltip: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.clear,
|
||||||
onPressed:
|
onPressed:
|
||||||
_recognizedText.isNotEmpty &&
|
_recognizedText.isNotEmpty &&
|
||||||
!_isTranscribing
|
!_isTranscribing
|
||||||
@@ -656,18 +675,13 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Text(
|
Text(
|
||||||
'Transcribing…',
|
AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.transcribing,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: isUltra
|
fontSize: isUltra
|
||||||
? AppTypography.bodySmall
|
? 12
|
||||||
: (isCompact
|
: (isCompact ? 12 : 13),
|
||||||
? AppTypography
|
|
||||||
.bodyMedium
|
|
||||||
: AppTypography
|
|
||||||
.bodyLarge),
|
|
||||||
color: context
|
|
||||||
.conduitTheme
|
|
||||||
.textSecondary,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -680,9 +694,15 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
_recognizedText.isEmpty
|
_recognizedText.isEmpty
|
||||||
? (_isListening
|
? (_isListening
|
||||||
? (_voiceService.hasLocalStt
|
? (_voiceService.hasLocalStt
|
||||||
? 'Speak now…'
|
? AppLocalizations.of(
|
||||||
: 'Recording…')
|
context,
|
||||||
: 'Tap Start to begin')
|
)!.speakNow
|
||||||
|
: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.recording)
|
||||||
|
: AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.typeBelowToBegin)
|
||||||
: _recognizedText,
|
: _recognizedText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: isUltra
|
fontSize: isUltra
|
||||||
@@ -731,7 +751,9 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ConduitButton(
|
child: ConduitButton(
|
||||||
text: _isListening ? 'Stop' : 'Start',
|
text: _isListening
|
||||||
|
? AppLocalizations.of(context)!.stop
|
||||||
|
: AppLocalizations.of(context)!.start,
|
||||||
isSecondary: true,
|
isSecondary: true,
|
||||||
isCompact: isCompact,
|
isCompact: isCompact,
|
||||||
onPressed: _isListening
|
onPressed: _isListening
|
||||||
@@ -742,7 +764,7 @@ class _VoiceInputSheetState extends ConsumerState<VoiceInputSheet> {
|
|||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ConduitButton(
|
child: ConduitButton(
|
||||||
text: 'Send',
|
text: AppLocalizations.of(context)!.send,
|
||||||
isCompact: isCompact,
|
isCompact: isCompact,
|
||||||
onPressed: _recognizedText.isNotEmpty ? _sendText : null,
|
onPressed: _recognizedText.isNotEmpty ? _sendText : null,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
|
|
||||||
// UI state providers for sections
|
// UI state providers for sections
|
||||||
static final _showArchivedProvider = StateProvider<bool>((ref) => false);
|
static final _showArchivedProvider = StateProvider<bool>((ref) => false);
|
||||||
static final _expandedFoldersProvider =
|
static final _expandedFoldersProvider = StateProvider<Map<String, bool>>(
|
||||||
StateProvider<Map<String, bool>>((ref) => {});
|
(ref) => {},
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@@ -96,7 +97,7 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
children: [
|
children: [
|
||||||
// Centered title (no leading icon)
|
// Centered title (no leading icon)
|
||||||
Text(
|
Text(
|
||||||
'Chats',
|
AppLocalizations.of(context)!.chats,
|
||||||
style: AppTypography.headlineSmallStyle.copyWith(
|
style: AppTypography.headlineSmallStyle.copyWith(
|
||||||
color: theme.textPrimary,
|
color: theme.textPrimary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -214,17 +215,21 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
// Build sections
|
// Build sections
|
||||||
final pinned = list.where((c) => c.pinned == true).toList();
|
final pinned = list.where((c) => c.pinned == true).toList();
|
||||||
final regular = list
|
final regular = list
|
||||||
.where((c) =>
|
.where(
|
||||||
c.pinned != true &&
|
(c) =>
|
||||||
c.archived != true &&
|
c.pinned != true &&
|
||||||
(c.folderId == null || c.folderId!.isEmpty))
|
c.archived != true &&
|
||||||
|
(c.folderId == null || c.folderId!.isEmpty),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final foldered = list
|
final foldered = list
|
||||||
.where((c) =>
|
.where(
|
||||||
c.pinned != true &&
|
(c) =>
|
||||||
c.archived != true &&
|
c.pinned != true &&
|
||||||
c.folderId != null &&
|
c.archived != true &&
|
||||||
c.folderId!.isNotEmpty)
|
c.folderId != null &&
|
||||||
|
c.folderId!.isNotEmpty,
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final archived = list.where((c) => c.archived == true).toList();
|
final archived = list.where((c) => c.archived == true).toList();
|
||||||
|
|
||||||
@@ -237,7 +242,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
if (pinned.isNotEmpty) ...[
|
if (pinned.isNotEmpty) ...[
|
||||||
_buildSectionHeader('Pinned', pinned.length),
|
_buildSectionHeader(
|
||||||
|
AppLocalizations.of(context)!.pinned,
|
||||||
|
pinned.length,
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.xs),
|
const SizedBox(height: Spacing.xs),
|
||||||
...pinned.map((conv) => _buildTileFor(conv)),
|
...pinned.map((conv) => _buildTileFor(conv)),
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
@@ -250,40 +258,53 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
_buildUnfileDropTarget(),
|
_buildUnfileDropTarget(),
|
||||||
const SizedBox(height: Spacing.sm),
|
const SizedBox(height: Spacing.sm),
|
||||||
],
|
],
|
||||||
...ref.watch(foldersProvider).when(
|
...ref
|
||||||
data: (folders) {
|
.watch(foldersProvider)
|
||||||
final grouped = <String, List<dynamic>>{};
|
.when(
|
||||||
for (final c in foldered) {
|
data: (folders) {
|
||||||
final id = c.folderId!;
|
final grouped = <String, List<dynamic>>{};
|
||||||
grouped.putIfAbsent(id, () => []).add(c);
|
for (final c in foldered) {
|
||||||
}
|
final id = c.folderId!;
|
||||||
|
grouped.putIfAbsent(id, () => []).add(c);
|
||||||
|
}
|
||||||
|
|
||||||
// Show all folders (including empty)
|
// Show all folders (including empty)
|
||||||
final sections = folders.map((folder) {
|
final sections = folders.map((folder) {
|
||||||
final expandedMap = ref.watch(_expandedFoldersProvider);
|
final expandedMap = ref.watch(_expandedFoldersProvider);
|
||||||
final isExpanded = expandedMap[folder.id] ?? false;
|
final isExpanded = expandedMap[folder.id] ?? false;
|
||||||
final convs = grouped[folder.id] ?? const <dynamic>[];
|
final convs = grouped[folder.id] ?? const <dynamic>[];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
_buildFolderHeader(folder.id, folder.name, convs.length),
|
_buildFolderHeader(
|
||||||
if (isExpanded && convs.isNotEmpty) ...[
|
folder.id,
|
||||||
const SizedBox(height: Spacing.xs),
|
folder.name,
|
||||||
...convs.map((c) => _buildTileFor(c, inFolder: true)),
|
convs.length,
|
||||||
const SizedBox(height: Spacing.sm),
|
),
|
||||||
],
|
if (isExpanded && convs.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: Spacing.xs),
|
||||||
|
...convs.map(
|
||||||
|
(c) => _buildTileFor(c, inFolder: true),
|
||||||
|
),
|
||||||
|
const SizedBox(height: Spacing.sm),
|
||||||
],
|
],
|
||||||
);
|
],
|
||||||
}).toList();
|
);
|
||||||
return sections.isEmpty ? [const SizedBox.shrink()] : sections;
|
}).toList();
|
||||||
},
|
return sections.isEmpty
|
||||||
loading: () => [const SizedBox.shrink()],
|
? [const SizedBox.shrink()]
|
||||||
error: (e, st) => [const SizedBox.shrink()],
|
: sections;
|
||||||
),
|
},
|
||||||
|
loading: () => [const SizedBox.shrink()],
|
||||||
|
error: (e, st) => [const SizedBox.shrink()],
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
|
|
||||||
if (regular.isNotEmpty) ...[
|
if (regular.isNotEmpty) ...[
|
||||||
_buildSectionHeader(AppLocalizations.of(context)!.recent, regular.length),
|
_buildSectionHeader(
|
||||||
|
AppLocalizations.of(context)!.recent,
|
||||||
|
regular.length,
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.xs),
|
const SizedBox(height: Spacing.xs),
|
||||||
...regular.map(_buildTileFor),
|
...regular.map(_buildTileFor),
|
||||||
],
|
],
|
||||||
@@ -295,7 +316,8 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
|
loading: () =>
|
||||||
|
const Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
|
||||||
error: (e, _) => Center(
|
error: (e, _) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(Spacing.md),
|
padding: const EdgeInsets.all(Spacing.md),
|
||||||
@@ -330,17 +352,21 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
|
|
||||||
final pinned = list.where((c) => c.pinned == true).toList();
|
final pinned = list.where((c) => c.pinned == true).toList();
|
||||||
final regular = list
|
final regular = list
|
||||||
.where((c) =>
|
.where(
|
||||||
c.pinned != true &&
|
(c) =>
|
||||||
c.archived != true &&
|
c.pinned != true &&
|
||||||
(c.folderId == null || c.folderId!.isEmpty))
|
c.archived != true &&
|
||||||
|
(c.folderId == null || c.folderId!.isEmpty),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final foldered = list
|
final foldered = list
|
||||||
.where((c) =>
|
.where(
|
||||||
c.pinned != true &&
|
(c) =>
|
||||||
c.archived != true &&
|
c.pinned != true &&
|
||||||
c.folderId != null &&
|
c.archived != true &&
|
||||||
c.folderId!.isNotEmpty)
|
c.folderId != null &&
|
||||||
|
c.folderId!.isNotEmpty,
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final archived = list.where((c) => c.archived == true).toList();
|
final archived = list.where((c) => c.archived == true).toList();
|
||||||
|
|
||||||
@@ -355,7 +381,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
_buildSectionHeader('Results', list.length),
|
_buildSectionHeader('Results', list.length),
|
||||||
const SizedBox(height: Spacing.xs),
|
const SizedBox(height: Spacing.xs),
|
||||||
if (pinned.isNotEmpty) ...[
|
if (pinned.isNotEmpty) ...[
|
||||||
_buildSectionHeader('Pinned', pinned.length),
|
_buildSectionHeader(
|
||||||
|
AppLocalizations.of(context)!.pinned,
|
||||||
|
pinned.length,
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.xs),
|
const SizedBox(height: Spacing.xs),
|
||||||
...pinned.map((conv) => _buildTileFor(conv)),
|
...pinned.map((conv) => _buildTileFor(conv)),
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
@@ -367,7 +396,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
_buildUnfileDropTarget(),
|
_buildUnfileDropTarget(),
|
||||||
const SizedBox(height: Spacing.sm),
|
const SizedBox(height: Spacing.sm),
|
||||||
],
|
],
|
||||||
...ref.watch(foldersProvider).when(
|
...ref
|
||||||
|
.watch(foldersProvider)
|
||||||
|
.when(
|
||||||
data: (folders) {
|
data: (folders) {
|
||||||
final grouped = <String, List<dynamic>>{};
|
final grouped = <String, List<dynamic>>{};
|
||||||
for (final c in foldered) {
|
for (final c in foldered) {
|
||||||
@@ -375,30 +406,41 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
grouped.putIfAbsent(id, () => []).add(c);
|
grouped.putIfAbsent(id, () => []).add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
final sections = folders.map((folder) {
|
final sections = folders.map((folder) {
|
||||||
final expandedMap = ref.watch(_expandedFoldersProvider);
|
final expandedMap = ref.watch(_expandedFoldersProvider);
|
||||||
final isExpanded = expandedMap[folder.id] ?? false;
|
final isExpanded = expandedMap[folder.id] ?? false;
|
||||||
final convs = grouped[folder.id] ?? const <dynamic>[];
|
final convs = grouped[folder.id] ?? const <dynamic>[];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
_buildFolderHeader(folder.id, folder.name, convs.length),
|
_buildFolderHeader(
|
||||||
if (isExpanded && convs.isNotEmpty) ...[
|
folder.id,
|
||||||
const SizedBox(height: Spacing.xs),
|
folder.name,
|
||||||
...convs.map((c) => _buildTileFor(c, inFolder: true)),
|
convs.length,
|
||||||
const SizedBox(height: Spacing.sm),
|
),
|
||||||
],
|
if (isExpanded && convs.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: Spacing.xs),
|
||||||
|
...convs.map(
|
||||||
|
(c) => _buildTileFor(c, inFolder: true),
|
||||||
|
),
|
||||||
|
const SizedBox(height: Spacing.sm),
|
||||||
],
|
],
|
||||||
);
|
],
|
||||||
}).toList();
|
);
|
||||||
return sections.isEmpty ? [const SizedBox.shrink()] : sections;
|
}).toList();
|
||||||
},
|
return sections.isEmpty
|
||||||
loading: () => [const SizedBox.shrink()],
|
? [const SizedBox.shrink()]
|
||||||
error: (e, st) => [const SizedBox.shrink()],
|
: sections;
|
||||||
),
|
},
|
||||||
|
loading: () => [const SizedBox.shrink()],
|
||||||
|
error: (e, st) => [const SizedBox.shrink()],
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.md),
|
const SizedBox(height: Spacing.md),
|
||||||
if (regular.isNotEmpty) ...[
|
if (regular.isNotEmpty) ...[
|
||||||
_buildSectionHeader(AppLocalizations.of(context)!.recent, regular.length),
|
_buildSectionHeader(
|
||||||
|
AppLocalizations.of(context)!.recent,
|
||||||
|
regular.length,
|
||||||
|
),
|
||||||
const SizedBox(height: Spacing.xs),
|
const SizedBox(height: Spacing.xs),
|
||||||
...regular.map(_buildTileFor),
|
...regular.map(_buildTileFor),
|
||||||
],
|
],
|
||||||
@@ -409,7 +451,8 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
|
loading: () =>
|
||||||
|
const Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
|
||||||
error: (e, _) => Center(
|
error: (e, _) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(Spacing.md),
|
padding: const EdgeInsets.all(Spacing.md),
|
||||||
@@ -442,7 +485,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: theme.surfaceBackground.withValues(alpha: 0.6),
|
color: theme.surfaceBackground.withValues(alpha: 0.6),
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.xs),
|
borderRadius: BorderRadius.circular(AppBorderRadius.xs),
|
||||||
border: Border.all(color: theme.dividerColor, width: BorderWidth.thin),
|
border: Border.all(
|
||||||
|
color: theme.dividerColor,
|
||||||
|
width: BorderWidth.thin,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'$count',
|
'$count',
|
||||||
@@ -461,7 +507,7 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Folders',
|
AppLocalizations.of(context)!.folders,
|
||||||
style: AppTypography.bodySmallStyle.copyWith(
|
style: AppTypography.bodySmallStyle.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: theme.textSecondary,
|
color: theme.textSecondary,
|
||||||
@@ -473,7 +519,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
tooltip: AppLocalizations.of(context)!.newFolder,
|
tooltip: AppLocalizations.of(context)!.newFolder,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Platform.isIOS ? CupertinoIcons.folder_badge_plus : Icons.create_new_folder_outlined,
|
Platform.isIOS
|
||||||
|
? CupertinoIcons.folder_badge_plus
|
||||||
|
: Icons.create_new_folder_outlined,
|
||||||
color: theme.iconPrimary,
|
color: theme.iconPrimary,
|
||||||
),
|
),
|
||||||
onPressed: _promptCreateFolder,
|
onPressed: _promptCreateFolder,
|
||||||
@@ -489,7 +537,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (ctx) => AlertDialog(
|
builder: (ctx) => AlertDialog(
|
||||||
backgroundColor: theme.surfaceBackground,
|
backgroundColor: theme.surfaceBackground,
|
||||||
title: Text(AppLocalizations.of(context)!.newFolder, style: TextStyle(color: theme.textPrimary)),
|
title: Text(
|
||||||
|
AppLocalizations.of(context)!.newFolder,
|
||||||
|
style: TextStyle(color: theme.textPrimary),
|
||||||
|
),
|
||||||
content: TextField(
|
content: TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@@ -497,8 +548,12 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: AppLocalizations.of(context)!.folderName,
|
hintText: AppLocalizations.of(context)!.folderName,
|
||||||
hintStyle: TextStyle(color: theme.inputPlaceholder),
|
hintStyle: TextStyle(color: theme.inputPlaceholder),
|
||||||
enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: theme.inputBorder)),
|
enabledBorder: UnderlineInputBorder(
|
||||||
focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: theme.buttonPrimary)),
|
borderSide: BorderSide(color: theme.inputBorder),
|
||||||
|
),
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: theme.buttonPrimary),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onSubmitted: (v) => Navigator.pop(ctx, controller.text.trim()),
|
onSubmitted: (v) => Navigator.pop(ctx, controller.text.trim()),
|
||||||
),
|
),
|
||||||
@@ -527,7 +582,11 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
UiUtils.showMessage(context, AppLocalizations.of(context)!.folderCreated);
|
UiUtils.showMessage(context, AppLocalizations.of(context)!.folderCreated);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
UiUtils.showMessage(context, AppLocalizations.of(context)!.failedToCreateFolder, isError: true);
|
UiUtils.showMessage(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context)!.failedToCreateFolder,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,12 +616,18 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
if (mounted) {
|
if (mounted) {
|
||||||
UiUtils.showMessage(
|
UiUtils.showMessage(
|
||||||
context,
|
context,
|
||||||
AppLocalizations.of(context)!.movedChatToFolder(details.data.title, name),
|
AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
)!.movedChatToFolder(details.data.title, name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
UiUtils.showMessage(context, AppLocalizations.of(context)!.failedToMoveChat, isError: true);
|
UiUtils.showMessage(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context)!.failedToMoveChat,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -596,8 +661,12 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
isExpanded
|
isExpanded
|
||||||
? (Platform.isIOS ? CupertinoIcons.folder_open : Icons.folder_open)
|
? (Platform.isIOS
|
||||||
: (Platform.isIOS ? CupertinoIcons.folder : Icons.folder),
|
? CupertinoIcons.folder_open
|
||||||
|
: Icons.folder_open)
|
||||||
|
: (Platform.isIOS
|
||||||
|
? CupertinoIcons.folder
|
||||||
|
: Icons.folder),
|
||||||
color: theme.iconPrimary,
|
color: theme.iconPrimary,
|
||||||
),
|
),
|
||||||
const SizedBox(width: Spacing.sm),
|
const SizedBox(width: Spacing.sm),
|
||||||
@@ -619,10 +688,14 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Icon(
|
Icon(
|
||||||
isExpanded
|
isExpanded
|
||||||
? (Platform.isIOS ? CupertinoIcons.chevron_up : Icons.expand_less)
|
? (Platform.isIOS
|
||||||
: (Platform.isIOS ? CupertinoIcons.chevron_down : Icons.expand_more),
|
? CupertinoIcons.chevron_up
|
||||||
|
: Icons.expand_less)
|
||||||
|
: (Platform.isIOS
|
||||||
|
? CupertinoIcons.chevron_down
|
||||||
|
: Icons.expand_more),
|
||||||
color: theme.iconSecondary,
|
color: theme.iconSecondary,
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -654,11 +727,18 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
ref.invalidate(conversationsProvider);
|
ref.invalidate(conversationsProvider);
|
||||||
ref.invalidate(foldersProvider);
|
ref.invalidate(foldersProvider);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
UiUtils.showMessage(context, 'Removed "${details.data.title}" from folder');
|
UiUtils.showMessage(
|
||||||
|
context,
|
||||||
|
'Removed "${details.data.title}" from folder',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
UiUtils.showMessage(context, AppLocalizations.of(context)!.failedToMoveChat, isError: true);
|
UiUtils.showMessage(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context)!.failedToMoveChat,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -713,7 +793,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
title: title,
|
title: title,
|
||||||
pinned: conv.pinned == true,
|
pinned: conv.pinned == true,
|
||||||
selected: isActive,
|
selected: isActive,
|
||||||
onTap: _isLoadingConversation ? null : () => _selectConversation(context, conv.id),
|
onTap: _isLoadingConversation
|
||||||
|
? null
|
||||||
|
: () => _selectConversation(context, conv.id),
|
||||||
// Remove long-press context menu to avoid conflict with drag gesture
|
// Remove long-press context menu to avoid conflict with drag gesture
|
||||||
onLongPress: null,
|
onLongPress: null,
|
||||||
onMorePressed: () {
|
onMorePressed: () {
|
||||||
@@ -723,7 +805,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(bottom: Spacing.xs, left: inFolder ? Spacing.md : 0),
|
padding: EdgeInsets.only(
|
||||||
|
bottom: Spacing.xs,
|
||||||
|
left: inFolder ? Spacing.md : 0,
|
||||||
|
),
|
||||||
child: LongPressDraggable<_DragConversationData>(
|
child: LongPressDraggable<_DragConversationData>(
|
||||||
data: _DragConversationData(id: conv.id, title: title),
|
data: _DragConversationData(id: conv.id, title: title),
|
||||||
dragAnchorStrategy: pointerDragAnchorStrategy,
|
dragAnchorStrategy: pointerDragAnchorStrategy,
|
||||||
@@ -768,7 +853,8 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
),
|
),
|
||||||
onDragStarted: () {
|
onDragStarted: () {
|
||||||
HapticFeedback.lightImpact();
|
HapticFeedback.lightImpact();
|
||||||
final hasFolder = (conv.folderId != null && (conv.folderId as String).isNotEmpty);
|
final hasFolder =
|
||||||
|
(conv.folderId != null && (conv.folderId as String).isNotEmpty);
|
||||||
setState(() {
|
setState(() {
|
||||||
_isDragging = true;
|
_isDragging = true;
|
||||||
_draggingHasFolder = hasFolder;
|
_draggingHasFolder = hasFolder;
|
||||||
@@ -794,12 +880,14 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
color: theme.surfaceBackground.withValues(alpha: 0.05),
|
color: theme.surfaceBackground.withValues(alpha: 0.05),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
side: BorderSide(color: theme.dividerColor, width: BorderWidth.regular),
|
side: BorderSide(
|
||||||
|
color: theme.dividerColor,
|
||||||
|
width: BorderWidth.regular,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
onTap: () =>
|
onTap: () => ref.read(_showArchivedProvider.notifier).state = !show,
|
||||||
ref.read(_showArchivedProvider.notifier).state = !show,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: Spacing.md,
|
horizontal: Spacing.md,
|
||||||
@@ -816,7 +904,7 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
const SizedBox(width: Spacing.sm),
|
const SizedBox(width: Spacing.sm),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Archived',
|
AppLocalizations.of(context)!.archived,
|
||||||
style: AppTypography.bodyLargeStyle.copyWith(
|
style: AppTypography.bodyLargeStyle.copyWith(
|
||||||
color: theme.textPrimary,
|
color: theme.textPrimary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -833,11 +921,11 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
Icon(
|
Icon(
|
||||||
show
|
show
|
||||||
? (Platform.isIOS
|
? (Platform.isIOS
|
||||||
? CupertinoIcons.chevron_up
|
? CupertinoIcons.chevron_up
|
||||||
: Icons.expand_less)
|
: Icons.expand_less)
|
||||||
: (Platform.isIOS
|
: (Platform.isIOS
|
||||||
? CupertinoIcons.chevron_down
|
? CupertinoIcons.chevron_down
|
||||||
: Icons.expand_more),
|
: Icons.expand_more),
|
||||||
color: theme.iconSecondary,
|
color: theme.iconSecondary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -867,9 +955,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
ref.read(activeConversationProvider.notifier).state = full;
|
ref.read(activeConversationProvider.notifier).state = full;
|
||||||
} else {
|
} else {
|
||||||
// Fallback: let ChatPage handle if API missing
|
// Fallback: let ChatPage handle if API missing
|
||||||
ref.read(activeConversationProvider.notifier).state =
|
ref.read(activeConversationProvider.notifier).state = (await ref.read(
|
||||||
(await ref.read(conversationsProvider.future))
|
conversationsProvider.future,
|
||||||
.firstWhere((c) => c.id == id);
|
)).firstWhere((c) => c.id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear global loading before closing drawer
|
// Clear global loading before closing drawer
|
||||||
@@ -890,7 +978,12 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
return SafeArea(
|
return SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(Spacing.sm, 0, Spacing.sm, Spacing.sm),
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
Spacing.sm,
|
||||||
|
0,
|
||||||
|
Spacing.sm,
|
||||||
|
Spacing.sm,
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -901,7 +994,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: theme.surfaceBackground.withValues(alpha: 0.04),
|
color: theme.surfaceBackground.withValues(alpha: 0.04),
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
border: Border.all(color: theme.dividerColor, width: BorderWidth.regular),
|
border: Border.all(
|
||||||
|
color: theme.dividerColor,
|
||||||
|
width: BorderWidth.regular,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -910,12 +1006,20 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
height: IconSize.avatar,
|
height: IconSize.avatar,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: theme.buttonPrimary.withValues(alpha: 0.15),
|
color: theme.buttonPrimary.withValues(alpha: 0.15),
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.avatar),
|
borderRadius: BorderRadius.circular(
|
||||||
border: Border.all(color: theme.buttonPrimary.withValues(alpha: 0.35), width: BorderWidth.thin),
|
AppBorderRadius.avatar,
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
color: theme.buttonPrimary.withValues(alpha: 0.35),
|
||||||
|
width: BorderWidth.thin,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
(user.name ?? user.username ?? 'U').toString().substring(0, 1).toUpperCase(),
|
(user.name ?? user.username ?? 'U')
|
||||||
|
.toString()
|
||||||
|
.substring(0, 1)
|
||||||
|
.toUpperCase(),
|
||||||
style: AppTypography.bodyLargeStyle.copyWith(
|
style: AppTypography.bodyLargeStyle.copyWith(
|
||||||
color: theme.buttonPrimary,
|
color: theme.buttonPrimary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -949,11 +1053,13 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).maybePop();
|
Navigator.of(context).maybePop();
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (_) => const ProfilePage()),
|
MaterialPageRoute(
|
||||||
|
builder: (_) => const ProfilePage(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(AppLocalizations.of(context)!.manage),
|
child: Text(AppLocalizations.of(context)!.manage),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -974,7 +1080,9 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
context: context,
|
context: context,
|
||||||
backgroundColor: theme.surfaceBackground,
|
backgroundColor: theme.surfaceBackground,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(AppBorderRadius.lg)),
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.circular(AppBorderRadius.lg),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
builder: (sheetContext) {
|
builder: (sheetContext) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
@@ -984,8 +1092,12 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
isPinned
|
isPinned
|
||||||
? (Platform.isIOS ? CupertinoIcons.pin_slash : Icons.push_pin_outlined)
|
? (Platform.isIOS
|
||||||
: (Platform.isIOS ? CupertinoIcons.pin_fill : Icons.push_pin_rounded),
|
? CupertinoIcons.pin_slash
|
||||||
|
: Icons.push_pin_outlined)
|
||||||
|
: (Platform.isIOS
|
||||||
|
? CupertinoIcons.pin_fill
|
||||||
|
: Icons.push_pin_rounded),
|
||||||
color: theme.iconPrimary,
|
color: theme.iconPrimary,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -1001,15 +1113,23 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
await chat.pinConversation(ref, conv.id, !isPinned);
|
await chat.pinConversation(ref, conv.id, !isPinned);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
UiUtils.showMessage(this.context, AppLocalizations.of(context)!.failedToUpdatePin, isError: true);
|
UiUtils.showMessage(
|
||||||
|
this.context,
|
||||||
|
AppLocalizations.of(context)!.failedToUpdatePin,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
isArchived
|
isArchived
|
||||||
? (Platform.isIOS ? CupertinoIcons.archivebox_fill : Icons.unarchive_rounded)
|
? (Platform.isIOS
|
||||||
: (Platform.isIOS ? CupertinoIcons.archivebox : Icons.archive_rounded),
|
? CupertinoIcons.archivebox_fill
|
||||||
|
: Icons.unarchive_rounded)
|
||||||
|
: (Platform.isIOS
|
||||||
|
? CupertinoIcons.archivebox
|
||||||
|
: Icons.archive_rounded),
|
||||||
color: theme.iconPrimary,
|
color: theme.iconPrimary,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -1025,7 +1145,11 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
await chat.archiveConversation(ref, conv.id, !isArchived);
|
await chat.archiveConversation(ref, conv.id, !isArchived);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
UiUtils.showMessage(this.context, AppLocalizations.of(context)!.failedToUpdateArchive, isError: true);
|
UiUtils.showMessage(
|
||||||
|
this.context,
|
||||||
|
AppLocalizations.of(context)!.failedToUpdateArchive,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1034,7 +1158,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
Platform.isIOS ? CupertinoIcons.pencil : Icons.edit_rounded,
|
Platform.isIOS ? CupertinoIcons.pencil : Icons.edit_rounded,
|
||||||
color: theme.iconPrimary,
|
color: theme.iconPrimary,
|
||||||
),
|
),
|
||||||
title: Text(AppLocalizations.of(context)!.rename, style: TextStyle(color: theme.textPrimary)),
|
title: Text(
|
||||||
|
AppLocalizations.of(context)!.rename,
|
||||||
|
style: TextStyle(color: theme.textPrimary),
|
||||||
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
HapticFeedback.selectionClick();
|
HapticFeedback.selectionClick();
|
||||||
Navigator.pop(sheetContext);
|
Navigator.pop(sheetContext);
|
||||||
@@ -1047,7 +1174,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
Platform.isIOS ? CupertinoIcons.delete : Icons.delete_rounded,
|
Platform.isIOS ? CupertinoIcons.delete : Icons.delete_rounded,
|
||||||
color: theme.error,
|
color: theme.error,
|
||||||
),
|
),
|
||||||
title: Text(AppLocalizations.of(context)!.delete, style: TextStyle(color: theme.error)),
|
title: Text(
|
||||||
|
AppLocalizations.of(context)!.delete,
|
||||||
|
style: TextStyle(color: theme.error),
|
||||||
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
HapticFeedback.mediumImpact();
|
HapticFeedback.mediumImpact();
|
||||||
Navigator.pop(sheetContext);
|
Navigator.pop(sheetContext);
|
||||||
@@ -1074,7 +1204,10 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
builder: (dialogContext) {
|
builder: (dialogContext) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: theme.surfaceBackground,
|
backgroundColor: theme.surfaceBackground,
|
||||||
title: Text(AppLocalizations.of(context)!.renameChat, style: TextStyle(color: theme.textPrimary)),
|
title: Text(
|
||||||
|
AppLocalizations.of(context)!.renameChat,
|
||||||
|
style: TextStyle(color: theme.textPrimary),
|
||||||
|
),
|
||||||
content: TextField(
|
content: TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@@ -1121,12 +1254,17 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
ref.invalidate(conversationsProvider);
|
ref.invalidate(conversationsProvider);
|
||||||
final active = ref.read(activeConversationProvider);
|
final active = ref.read(activeConversationProvider);
|
||||||
if (active?.id == conversationId) {
|
if (active?.id == conversationId) {
|
||||||
ref.read(activeConversationProvider.notifier).state =
|
ref.read(activeConversationProvider.notifier).state = active!.copyWith(
|
||||||
active!.copyWith(title: newName);
|
title: newName,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
UiUtils.showMessage(this.context, AppLocalizations.of(context)!.failedToRenameChat, isError: true);
|
UiUtils.showMessage(
|
||||||
|
this.context,
|
||||||
|
AppLocalizations.of(context)!.failedToRenameChat,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1157,7 +1295,11 @@ class _ChatsDrawerState extends ConsumerState<ChatsDrawer> {
|
|||||||
ref.invalidate(conversationsProvider);
|
ref.invalidate(conversationsProvider);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
UiUtils.showMessage(this.context, AppLocalizations.of(context)!.failedToDeleteChat, isError: true);
|
UiUtils.showMessage(
|
||||||
|
this.context,
|
||||||
|
AppLocalizations.of(context)!.failedToDeleteChat,
|
||||||
|
isError: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1195,7 +1337,9 @@ class _ConversationTile extends StatelessWidget {
|
|||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: selected ? theme.buttonPrimary.withValues(alpha: 0.5) : theme.dividerColor,
|
color: selected
|
||||||
|
? theme.buttonPrimary.withValues(alpha: 0.5)
|
||||||
|
: theme.dividerColor,
|
||||||
width: BorderWidth.regular,
|
width: BorderWidth.regular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1226,9 +1370,14 @@ class _ConversationTile extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
|
constraints: const BoxConstraints(
|
||||||
|
minWidth: 36,
|
||||||
|
minHeight: 36,
|
||||||
|
),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Platform.isIOS ? CupertinoIcons.ellipsis : Icons.more_vert_rounded,
|
Platform.isIOS
|
||||||
|
? CupertinoIcons.ellipsis
|
||||||
|
: Icons.more_vert_rounded,
|
||||||
color: theme.iconSecondary,
|
color: theme.iconSecondary,
|
||||||
size: IconSize.md,
|
size: IconSize.md,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: ImprovedLoadingState(message: AppLocalizations.of(context)!.loadingProfile),
|
child: ImprovedLoadingState(
|
||||||
|
message: AppLocalizations.of(context)!.loadingProfile,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Scaffold(
|
error: (error, stack) => Scaffold(
|
||||||
@@ -311,17 +313,16 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
Widget _buildDefaultModelTile(BuildContext context, WidgetRef ref) {
|
Widget _buildDefaultModelTile(BuildContext context, WidgetRef ref) {
|
||||||
final settings = ref.watch(appSettingsProvider);
|
final settings = ref.watch(appSettingsProvider);
|
||||||
final modelsAsync = ref.watch(modelsProvider);
|
final modelsAsync = ref.watch(modelsProvider);
|
||||||
|
|
||||||
return modelsAsync.when(
|
return modelsAsync.when(
|
||||||
data: (models) {
|
data: (models) {
|
||||||
final currentModel = models.firstWhere(
|
final currentModel = models.firstWhere(
|
||||||
(m) => m.id == settings.defaultModel,
|
(m) => m.id == settings.defaultModel,
|
||||||
orElse: () => models.isNotEmpty ? models.first : const Model(
|
orElse: () => models.isNotEmpty
|
||||||
id: 'none',
|
? models.first
|
||||||
name: 'No models available',
|
: const Model(id: 'none', name: 'No models available'),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
horizontal: Spacing.listItemPadding,
|
horizontal: Spacing.listItemPadding,
|
||||||
@@ -352,7 +353,9 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
settings.defaultModel != null ? currentModel.name : AppLocalizations.of(context)!.autoSelect,
|
settings.defaultModel != null
|
||||||
|
? currentModel.name
|
||||||
|
: AppLocalizations.of(context)!.autoSelect,
|
||||||
style: context.conduitTheme.bodySmall?.copyWith(
|
style: context.conduitTheme.bodySmall?.copyWith(
|
||||||
color: context.conduitTheme.textSecondary,
|
color: context.conduitTheme.textSecondary,
|
||||||
),
|
),
|
||||||
@@ -484,7 +487,7 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context)!.menuItem,
|
AppLocalizations.of(context)!.appLanguage,
|
||||||
style: context.conduitTheme.bodyLarge?.copyWith(
|
style: context.conduitTheme.bodyLarge?.copyWith(
|
||||||
color: context.conduitTheme.textPrimary,
|
color: context.conduitTheme.textPrimary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -600,7 +603,7 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'Dark Mode',
|
AppLocalizations.of(context)!.darkMode,
|
||||||
style: context.conduitTheme.bodyLarge?.copyWith(
|
style: context.conduitTheme.bodyLarge?.copyWith(
|
||||||
color: context.conduitTheme.textPrimary,
|
color: context.conduitTheme.textPrimary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -720,7 +723,11 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showModelSelector(BuildContext context, WidgetRef ref, List<Model> models) async {
|
Future<void> _showModelSelector(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
List<Model> models,
|
||||||
|
) async {
|
||||||
final result = await showModalBottomSheet<String?>(
|
final result = await showModalBottomSheet<String?>(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
@@ -730,13 +737,15 @@ class ProfilePage extends ConsumerWidget {
|
|||||||
currentDefaultModelId: ref.read(appSettingsProvider).defaultModel,
|
currentDefaultModelId: ref.read(appSettingsProvider).defaultModel,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// result is non-null only when Save button is pressed
|
// result is non-null only when Save button is pressed
|
||||||
// null means the sheet was dismissed without saving
|
// null means the sheet was dismissed without saving
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
// Handle special case: 'auto-select' should be stored as null
|
// Handle special case: 'auto-select' should be stored as null
|
||||||
final modelIdToSave = result == 'auto-select' ? null : result;
|
final modelIdToSave = result == 'auto-select' ? null : result;
|
||||||
await ref.read(appSettingsProvider.notifier).setDefaultModel(modelIdToSave);
|
await ref
|
||||||
|
.read(appSettingsProvider.notifier)
|
||||||
|
.setDefaultModel(modelIdToSave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,10 +774,12 @@ class _DefaultModelBottomSheet extends ConsumerStatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<_DefaultModelBottomSheet> createState() => _DefaultModelBottomSheetState();
|
ConsumerState<_DefaultModelBottomSheet> createState() =>
|
||||||
|
_DefaultModelBottomSheetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomSheet> {
|
class _DefaultModelBottomSheetState
|
||||||
|
extends ConsumerState<_DefaultModelBottomSheet> {
|
||||||
final TextEditingController _searchController = TextEditingController();
|
final TextEditingController _searchController = TextEditingController();
|
||||||
String _searchQuery = '';
|
String _searchQuery = '';
|
||||||
List<Model> _filteredModels = [];
|
List<Model> _filteredModels = [];
|
||||||
@@ -833,7 +844,7 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
const Model(id: 'auto-select', name: 'Auto-select'),
|
const Model(id: 'auto-select', name: 'Auto-select'),
|
||||||
...widget.models,
|
...widget.models,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (_searchQuery.isNotEmpty) {
|
if (_searchQuery.isNotEmpty) {
|
||||||
_filteredModels = allModels.where((model) {
|
_filteredModels = allModels.where((model) {
|
||||||
return model.name.toLowerCase().contains(_searchQuery) ||
|
return model.name.toLowerCase().contains(_searchQuery) ||
|
||||||
@@ -896,18 +907,24 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
filled: true,
|
filled: true,
|
||||||
fillColor: context.conduitTheme.inputBackground,
|
fillColor: context.conduitTheme.inputBackground,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(
|
||||||
|
AppBorderRadius.md,
|
||||||
|
),
|
||||||
borderSide: BorderSide.none,
|
borderSide: BorderSide.none,
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(
|
||||||
|
AppBorderRadius.md,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: context.conduitTheme.inputBorder,
|
color: context.conduitTheme.inputBorder,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(
|
||||||
|
AppBorderRadius.md,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: context.conduitTheme.buttonPrimary,
|
color: context.conduitTheme.buttonPrimary,
|
||||||
width: 1,
|
width: 1,
|
||||||
@@ -937,10 +954,16 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
),
|
),
|
||||||
const SizedBox(width: Spacing.xs),
|
const SizedBox(width: Spacing.xs),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6,
|
||||||
|
vertical: 2,
|
||||||
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.conduitTheme.surfaceBackground.withValues(alpha: 0.6),
|
color: context.conduitTheme.surfaceBackground
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.xs),
|
.withValues(alpha: 0.6),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
AppBorderRadius.xs,
|
||||||
|
),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: context.conduitTheme.dividerColor,
|
color: context.conduitTheme.dividerColor,
|
||||||
width: BorderWidth.thin,
|
width: BorderWidth.thin,
|
||||||
@@ -993,8 +1016,9 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final model = _filteredModels[index];
|
final model = _filteredModels[index];
|
||||||
final isAutoSelect = model.id == 'auto-select';
|
final isAutoSelect = model.id == 'auto-select';
|
||||||
final isSelected = isAutoSelect
|
final isSelected = isAutoSelect
|
||||||
? _selectedModelId == null || _selectedModelId == 'auto-select'
|
? _selectedModelId == null ||
|
||||||
|
_selectedModelId == 'auto-select'
|
||||||
: _selectedModelId == model.id;
|
: _selectedModelId == model.id;
|
||||||
|
|
||||||
return _buildModelListTile(
|
return _buildModelListTile(
|
||||||
@@ -1003,8 +1027,9 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
isAutoSelect: isAutoSelect,
|
isAutoSelect: isAutoSelect,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
HapticFeedback.lightImpact();
|
HapticFeedback.lightImpact();
|
||||||
final selectedId =
|
final selectedId = isAutoSelect
|
||||||
isAutoSelect ? 'auto-select' : model.id;
|
? 'auto-select'
|
||||||
|
: model.id;
|
||||||
// Return selection immediately; caller handles persisting
|
// Return selection immediately; caller handles persisting
|
||||||
Navigator.pop(context, selectedId);
|
Navigator.pop(context, selectedId);
|
||||||
},
|
},
|
||||||
@@ -1070,13 +1095,19 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.conduitTheme.buttonPrimary.withValues(alpha: 0.15),
|
color: context.conduitTheme.buttonPrimary.withValues(
|
||||||
|
alpha: 0.15,
|
||||||
|
),
|
||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
isAutoSelect
|
isAutoSelect
|
||||||
? (Platform.isIOS ? CupertinoIcons.wand_stars : Icons.auto_awesome)
|
? (Platform.isIOS
|
||||||
: (Platform.isIOS ? CupertinoIcons.cube : Icons.psychology),
|
? CupertinoIcons.wand_stars
|
||||||
|
: Icons.auto_awesome)
|
||||||
|
: (Platform.isIOS
|
||||||
|
? CupertinoIcons.cube
|
||||||
|
: Icons.psychology),
|
||||||
color: context.conduitTheme.buttonPrimary,
|
color: context.conduitTheme.buttonPrimary,
|
||||||
size: 16,
|
size: 16,
|
||||||
),
|
),
|
||||||
@@ -1087,7 +1118,9 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
isAutoSelect ? AppLocalizations.of(context)!.autoSelect : model.name,
|
isAutoSelect
|
||||||
|
? AppLocalizations.of(context)!.autoSelect
|
||||||
|
: model.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: context.conduitTheme.textPrimary,
|
color: context.conduitTheme.textPrimary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -1143,13 +1176,17 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
|
|||||||
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
borderRadius: BorderRadius.circular(AppBorderRadius.md),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? context.conduitTheme.buttonPrimary.withValues(alpha: 0.6)
|
? context.conduitTheme.buttonPrimary.withValues(
|
||||||
|
alpha: 0.6,
|
||||||
|
)
|
||||||
: context.conduitTheme.dividerColor,
|
: context.conduitTheme.dividerColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
isSelected
|
isSelected
|
||||||
? (Platform.isIOS ? CupertinoIcons.check_mark : Icons.check)
|
? (Platform.isIOS
|
||||||
|
? CupertinoIcons.check_mark
|
||||||
|
: Icons.check)
|
||||||
: (Platform.isIOS ? CupertinoIcons.add : Icons.add),
|
: (Platform.isIOS ? CupertinoIcons.add : Icons.add),
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? context.conduitTheme.textInverse
|
? context.conduitTheme.textInverse
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:conduit/l10n/app_localizations.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -59,9 +60,10 @@ class _UnifiedToolsModalState extends ConsumerState<UnifiedToolsModal> {
|
|||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
_buildFeatureTile(
|
_buildFeatureTile(
|
||||||
title: 'Web Search',
|
title: AppLocalizations.of(context)!.webSearch,
|
||||||
description:
|
description: AppLocalizations.of(
|
||||||
'Let the assistant search the internet while answering.',
|
context,
|
||||||
|
)!.webSearchDescription,
|
||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.search
|
? CupertinoIcons.search
|
||||||
: Icons.search,
|
: Icons.search,
|
||||||
@@ -74,9 +76,10 @@ class _UnifiedToolsModalState extends ConsumerState<UnifiedToolsModal> {
|
|||||||
),
|
),
|
||||||
if (imageGenAvailable)
|
if (imageGenAvailable)
|
||||||
_buildFeatureTile(
|
_buildFeatureTile(
|
||||||
title: 'Image Generation',
|
title: AppLocalizations.of(context)!.imageGeneration,
|
||||||
description:
|
description: AppLocalizations.of(
|
||||||
'Generate images from your prompt and attach them.',
|
context,
|
||||||
|
)!.imageGenerationDescription,
|
||||||
icon: Platform.isIOS
|
icon: Platform.isIOS
|
||||||
? CupertinoIcons.photo
|
? CupertinoIcons.photo
|
||||||
: Icons.image,
|
: Icons.image,
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ import 'app_localizations_it.dart';
|
|||||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||||
/// property.
|
/// property.
|
||||||
abstract class AppLocalizations {
|
abstract class AppLocalizations {
|
||||||
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
AppLocalizations(String locale)
|
||||||
|
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||||
|
|
||||||
final String localeName;
|
final String localeName;
|
||||||
|
|
||||||
@@ -72,7 +73,8 @@ abstract class AppLocalizations {
|
|||||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
|
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||||
|
_AppLocalizationsDelegate();
|
||||||
|
|
||||||
/// A list of this localizations delegate along with the default localizations
|
/// A list of this localizations delegate along with the default localizations
|
||||||
/// delegates.
|
/// delegates.
|
||||||
@@ -84,19 +86,20 @@ abstract class AppLocalizations {
|
|||||||
/// Additional delegates can be added by appending to this list in
|
/// Additional delegates can be added by appending to this list in
|
||||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||||
/// of delegates is preferred or required.
|
/// of delegates is preferred or required.
|
||||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
|
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||||
delegate,
|
<LocalizationsDelegate<dynamic>>[
|
||||||
GlobalMaterialLocalizations.delegate,
|
delegate,
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
];
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
];
|
||||||
|
|
||||||
/// A list of this localizations delegate's supported locales.
|
/// A list of this localizations delegate's supported locales.
|
||||||
static const List<Locale> supportedLocales = <Locale>[
|
static const List<Locale> supportedLocales = <Locale>[
|
||||||
Locale('de'),
|
Locale('de'),
|
||||||
Locale('en'),
|
Locale('en'),
|
||||||
Locale('fr'),
|
Locale('fr'),
|
||||||
Locale('it')
|
Locale('it'),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// No description provided for @appTitle.
|
/// No description provided for @appTitle.
|
||||||
@@ -1190,9 +1193,154 @@ abstract class AppLocalizations {
|
|||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'Conduit information and links'**
|
/// **'Conduit information and links'**
|
||||||
String get aboutAppSubtitle;
|
String get aboutAppSubtitle;
|
||||||
|
|
||||||
|
/// No description provided for @appLanguage.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'App language'**
|
||||||
|
String get appLanguage;
|
||||||
|
|
||||||
|
/// No description provided for @typeBelowToBegin.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Type below to begin'**
|
||||||
|
String get typeBelowToBegin;
|
||||||
|
|
||||||
|
/// No description provided for @listening.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Listening…'**
|
||||||
|
String get listening;
|
||||||
|
|
||||||
|
/// No description provided for @recording.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Recording…'**
|
||||||
|
String get recording;
|
||||||
|
|
||||||
|
/// No description provided for @transcribing.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Transcribing…'**
|
||||||
|
String get transcribing;
|
||||||
|
|
||||||
|
/// No description provided for @speakNow.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Speak now…'**
|
||||||
|
String get speakNow;
|
||||||
|
|
||||||
|
/// No description provided for @chats.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Chats'**
|
||||||
|
String get chats;
|
||||||
|
|
||||||
|
/// No description provided for @darkMode.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Dark Mode'**
|
||||||
|
String get darkMode;
|
||||||
|
|
||||||
|
/// No description provided for @transcript.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Transcript'**
|
||||||
|
String get transcript;
|
||||||
|
|
||||||
|
/// No description provided for @pinned.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Pinned'**
|
||||||
|
String get pinned;
|
||||||
|
|
||||||
|
/// No description provided for @folders.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Folders'**
|
||||||
|
String get folders;
|
||||||
|
|
||||||
|
/// No description provided for @archived.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Archived'**
|
||||||
|
String get archived;
|
||||||
|
|
||||||
|
/// No description provided for @holdToTalk.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Hold to talk'**
|
||||||
|
String get holdToTalk;
|
||||||
|
|
||||||
|
/// No description provided for @autoSend.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Auto-send'**
|
||||||
|
String get autoSend;
|
||||||
|
|
||||||
|
/// No description provided for @stopListening.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Stop listening'**
|
||||||
|
String get stopListening;
|
||||||
|
|
||||||
|
/// No description provided for @startListening.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Start listening'**
|
||||||
|
String get startListening;
|
||||||
|
|
||||||
|
/// No description provided for @start.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Start'**
|
||||||
|
String get start;
|
||||||
|
|
||||||
|
/// No description provided for @stop.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Stop'**
|
||||||
|
String get stop;
|
||||||
|
|
||||||
|
/// No description provided for @web.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Web'**
|
||||||
|
String get web;
|
||||||
|
|
||||||
|
/// No description provided for @imageGen.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Image Gen'**
|
||||||
|
String get imageGen;
|
||||||
|
|
||||||
|
/// No description provided for @webSearch.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Web Search'**
|
||||||
|
String get webSearch;
|
||||||
|
|
||||||
|
/// No description provided for @webSearchDescription.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Let the assistant search the internet while answering.'**
|
||||||
|
String get webSearchDescription;
|
||||||
|
|
||||||
|
/// No description provided for @imageGeneration.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Image Generation'**
|
||||||
|
String get imageGeneration;
|
||||||
|
|
||||||
|
/// No description provided for @imageGenerationDescription.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Generate images from your prompt and attach them.'**
|
||||||
|
String get imageGenerationDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
class _AppLocalizationsDelegate
|
||||||
|
extends LocalizationsDelegate<AppLocalizations> {
|
||||||
const _AppLocalizationsDelegate();
|
const _AppLocalizationsDelegate();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1201,27 +1349,30 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSupported(Locale locale) => <String>['de', 'en', 'fr', 'it'].contains(locale.languageCode);
|
bool isSupported(Locale locale) =>
|
||||||
|
<String>['de', 'en', 'fr', 'it'].contains(locale.languageCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||||
|
|
||||||
|
|
||||||
// Lookup logic when only language code is specified.
|
// Lookup logic when only language code is specified.
|
||||||
switch (locale.languageCode) {
|
switch (locale.languageCode) {
|
||||||
case 'de': return AppLocalizationsDe();
|
case 'de':
|
||||||
case 'en': return AppLocalizationsEn();
|
return AppLocalizationsDe();
|
||||||
case 'fr': return AppLocalizationsFr();
|
case 'en':
|
||||||
case 'it': return AppLocalizationsIt();
|
return AppLocalizationsEn();
|
||||||
|
case 'fr':
|
||||||
|
return AppLocalizationsFr();
|
||||||
|
case 'it':
|
||||||
|
return AppLocalizationsIt();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw FlutterError(
|
throw FlutterError(
|
||||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||||
'an issue with the localizations generation tool. Please file an issue '
|
'an issue with the localizations generation tool. Please file an issue '
|
||||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||||
'that was used.'
|
'that was used.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get unableToLoadProfile => 'Profil konnte nicht geladen werden';
|
String get unableToLoadProfile => 'Profil konnte nicht geladen werden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get pleaseCheckConnection => 'Bitte überprüfe deine Verbindung und versuche es erneut';
|
String get pleaseCheckConnection =>
|
||||||
|
'Bitte überprüfe deine Verbindung und versuche es erneut';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get account => 'Konto';
|
String get account => 'Konto';
|
||||||
@@ -63,7 +64,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get searchModels => 'Modelle suchen...';
|
String get searchModels => 'Modelle suchen...';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get errorMessage => 'Etwas ist schief gelaufen. Bitte versuche es erneut.';
|
String get errorMessage =>
|
||||||
|
'Etwas ist schief gelaufen. Bitte versuche es erneut.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get loginButton => 'Anmelden';
|
String get loginButton => 'Anmelden';
|
||||||
@@ -116,7 +118,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get noFilesYet => 'Noch keine Dateien';
|
String get noFilesYet => 'Noch keine Dateien';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadDocsPrompt => 'Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden';
|
String get uploadDocsPrompt =>
|
||||||
|
'Lade Dokumente hoch, um sie in deinen Unterhaltungen mit Conduit zu verwenden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadFirstFile => 'Erste Datei hochladen';
|
String get uploadFirstFile => 'Erste Datei hochladen';
|
||||||
@@ -125,7 +128,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get knowledgeBaseEmpty => 'Wissensdatenbank ist leer';
|
String get knowledgeBaseEmpty => 'Wissensdatenbank ist leer';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get createCollectionsPrompt => 'Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz';
|
String get createCollectionsPrompt =>
|
||||||
|
'Erstelle Sammlungen verwandter Dokumente zur einfachen Referenz';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get chooseSourcePhoto => 'Quelle auswählen';
|
String get chooseSourcePhoto => 'Quelle auswählen';
|
||||||
@@ -151,7 +155,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kbCreationComingSoon => 'Erstellung der Wissensdatenbank kommt bald!';
|
String get kbCreationComingSoon =>
|
||||||
|
'Erstellung der Wissensdatenbank kommt bald!';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get backToServerSetup => 'Zur Servereinrichtung zurück';
|
String get backToServerSetup => 'Zur Servereinrichtung zurück';
|
||||||
@@ -163,7 +168,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get signIn => 'Anmelden';
|
String get signIn => 'Anmelden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterCredentials => 'Gib deine Anmeldedaten ein, um auf deine KI-Unterhaltungen zuzugreifen';
|
String get enterCredentials =>
|
||||||
|
'Gib deine Anmeldedaten ein, um auf deine KI-Unterhaltungen zuzugreifen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get credentials => 'Zugangsdaten';
|
String get credentials => 'Zugangsdaten';
|
||||||
@@ -184,7 +190,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get connectToServer => 'Mit Server verbinden';
|
String get connectToServer => 'Mit Server verbinden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerAddress => 'Gib die Adresse deines Open-WebUI-Servers ein, um zu beginnen';
|
String get enterServerAddress =>
|
||||||
|
'Gib die Adresse deines Open-WebUI-Servers ein, um zu beginnen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrl => 'Server-URL';
|
String get serverUrl => 'Server-URL';
|
||||||
@@ -193,7 +200,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get serverUrlHint => 'https://dein-server.com';
|
String get serverUrlHint => 'https://dein-server.com';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerUrlSemantic => 'Gib deine Server-URL oder IP-Adresse ein';
|
String get enterServerUrlSemantic =>
|
||||||
|
'Gib deine Server-URL oder IP-Adresse ein';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get headerName => 'Header-Name';
|
String get headerName => 'Header-Name';
|
||||||
@@ -223,7 +231,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get demoModeActive => 'Demo-Modus aktiv';
|
String get demoModeActive => 'Demo-Modus aktiv';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skipServerSetupTryDemo => 'Servereinrichtung überspringen und Demo testen';
|
String get skipServerSetupTryDemo =>
|
||||||
|
'Servereinrichtung überspringen und Demo testen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterDemo => 'Demo starten';
|
String get enterDemo => 'Demo starten';
|
||||||
@@ -232,7 +241,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get demoBadge => 'Demo';
|
String get demoBadge => 'Demo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverNotOpenWebUI => 'Dies scheint kein Open-WebUI-Server zu sein.';
|
String get serverNotOpenWebUI =>
|
||||||
|
'Dies scheint kein Open-WebUI-Server zu sein.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrlEmpty => 'Server-URL darf nicht leer sein';
|
String get serverUrlEmpty => 'Server-URL darf nicht leer sein';
|
||||||
@@ -241,10 +251,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get invalidUrlFormat => 'Ungültiges URL-Format. Bitte Eingabe prüfen.';
|
String get invalidUrlFormat => 'Ungültiges URL-Format. Bitte Eingabe prüfen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onlyHttpHttps => 'Nur HTTP- und HTTPS-Protokolle werden unterstützt.';
|
String get onlyHttpHttps =>
|
||||||
|
'Nur HTTP- und HTTPS-Protokolle werden unterstützt.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverAddressRequired => 'Serveradresse erforderlich (z. B. 192.168.1.10 oder example.com).';
|
String get serverAddressRequired =>
|
||||||
|
'Serveradresse erforderlich (z. B. 192.168.1.10 oder example.com).';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get portRange => 'Port muss zwischen 1 und 65535 liegen.';
|
String get portRange => 'Port muss zwischen 1 und 65535 liegen.';
|
||||||
@@ -253,13 +265,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get invalidIpFormat => 'Ungültiges IP-Format. Beispiel: 192.168.1.10.';
|
String get invalidIpFormat => 'Ungültiges IP-Format. Beispiel: 192.168.1.10.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get couldNotConnectGeneric => 'Verbindung fehlgeschlagen. Adresse prüfen und erneut versuchen.';
|
String get couldNotConnectGeneric =>
|
||||||
|
'Verbindung fehlgeschlagen. Adresse prüfen und erneut versuchen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get weCouldntReachServer => 'Server nicht erreichbar. Verbindung und Serverstatus prüfen.';
|
String get weCouldntReachServer =>
|
||||||
|
'Server nicht erreichbar. Verbindung und Serverstatus prüfen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get connectionTimedOut => 'Zeitüberschreitung. Server eventuell ausgelastet oder blockiert.';
|
String get connectionTimedOut =>
|
||||||
|
'Zeitüberschreitung. Server eventuell ausgelastet oder blockiert.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useHttpOrHttpsOnly => 'Nur http:// oder https:// verwenden.';
|
String get useHttpOrHttpsOnly => 'Nur http:// oder https:// verwenden.';
|
||||||
@@ -268,19 +283,23 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get loginFailed => 'Anmeldung fehlgeschlagen';
|
String get loginFailed => 'Anmeldung fehlgeschlagen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidCredentials => 'Ungültiger Benutzername oder Passwort. Bitte erneut versuchen.';
|
String get invalidCredentials =>
|
||||||
|
'Ungültiger Benutzername oder Passwort. Bitte erneut versuchen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverRedirectingHttps => 'Server leitet um. HTTPS-Konfiguration prüfen.';
|
String get serverRedirectingHttps =>
|
||||||
|
'Server leitet um. HTTPS-Konfiguration prüfen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get unableToConnectServer => 'Verbindung zum Server nicht möglich. Bitte Verbindung prüfen.';
|
String get unableToConnectServer =>
|
||||||
|
'Verbindung zum Server nicht möglich. Bitte Verbindung prüfen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get requestTimedOut => 'Zeitüberschreitung. Bitte erneut versuchen.';
|
String get requestTimedOut => 'Zeitüberschreitung. Bitte erneut versuchen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get genericSignInFailed => 'Anmeldung nicht möglich. Zugangsdaten und Server prüfen.';
|
String get genericSignInFailed =>
|
||||||
|
'Anmeldung nicht möglich. Zugangsdaten und Server prüfen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skip => 'Überspringen';
|
String get skip => 'Überspringen';
|
||||||
@@ -295,7 +314,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get onboardStartTitle => 'Unterhaltung starten';
|
String get onboardStartTitle => 'Unterhaltung starten';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartSubtitle => 'Wähle ein Modell und tippe los. Tippe jederzeit auf Neuer Chat.';
|
String get onboardStartSubtitle =>
|
||||||
|
'Wähle ein Modell und tippe los. Tippe jederzeit auf Neuer Chat.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet1 => 'Modellname oben antippen, um zu wechseln';
|
String get onboardStartBullet1 => 'Modellname oben antippen, um zu wechseln';
|
||||||
@@ -307,7 +327,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get onboardAttachTitle => 'Kontext anhängen';
|
String get onboardAttachTitle => 'Kontext anhängen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachSubtitle => 'Antworten mit Dateien oder Bildern untermauern.';
|
String get onboardAttachSubtitle =>
|
||||||
|
'Antworten mit Dateien oder Bildern untermauern.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachBullet1 => 'Dateien: PDFs, Dokumente, Datensätze';
|
String get onboardAttachBullet1 => 'Dateien: PDFs, Dokumente, Datensätze';
|
||||||
@@ -325,19 +346,23 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get onboardSpeakBullet1 => 'Jederzeit stoppen; Text bleibt erhalten';
|
String get onboardSpeakBullet1 => 'Jederzeit stoppen; Text bleibt erhalten';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet2 => 'Ideal für kurze Notizen oder lange Prompts';
|
String get onboardSpeakBullet2 =>
|
||||||
|
'Ideal für kurze Notizen oder lange Prompts';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickTitle => 'Schnellaktionen';
|
String get onboardQuickTitle => 'Schnellaktionen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickSubtitle => 'Links oben das Menü für Chats und Navigation öffnen.';
|
String get onboardQuickSubtitle =>
|
||||||
|
'Links oben das Menü für Chats und Navigation öffnen.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet1 => 'Menü tippen, um Chats und Navigation zu öffnen';
|
String get onboardQuickBullet1 =>
|
||||||
|
'Menü tippen, um Chats und Navigation zu öffnen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet2 => 'Schnell zu Neuer Chat, Dateien oder Profil springen';
|
String get onboardQuickBullet2 =>
|
||||||
|
'Schnell zu Neuer Chat, Dateien oder Profil springen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get addAttachment => 'Anhang hinzufügen';
|
String get addAttachment => 'Anhang hinzufügen';
|
||||||
@@ -404,13 +429,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get emptyImageData => 'Leere Bilddaten';
|
String get emptyImageData => 'Leere Bilddaten';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get offlineBanner => 'Du bist offline. Einige Funktionen sind eingeschränkt.';
|
String get offlineBanner =>
|
||||||
|
'Du bist offline. Einige Funktionen sind eingeschränkt.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get featureRequiresInternet => 'Diese Funktion erfordert eine Internetverbindung';
|
String get featureRequiresInternet =>
|
||||||
|
'Diese Funktion erfordert eine Internetverbindung';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get messagesWillSendWhenOnline => 'Nachrichten werden gesendet, sobald du wieder online bist';
|
String get messagesWillSendWhenOnline =>
|
||||||
|
'Nachrichten werden gesendet, sobald du wieder online bist';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get confirm => 'Bestätigen';
|
String get confirm => 'Bestätigen';
|
||||||
@@ -576,4 +604,78 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get aboutAppSubtitle => 'Conduit Informationen und Links';
|
String get aboutAppSubtitle => 'Conduit Informationen und Links';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appLanguage => 'App-Sprache';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get typeBelowToBegin => 'Unten tippen, um zu beginnen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get listening => 'Zuhören…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get recording => 'Aufnahme…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcribing => 'Transkription…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get speakNow => 'Jetzt sprechen…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chats => 'Chats';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get darkMode => 'Dunkler Modus';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcript => 'Transkript';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pinned => 'Angeheftet';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get folders => 'Ordner';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get archived => 'Archiviert';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get holdToTalk => 'Zum Sprechen halten';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSend => 'Automatisch senden';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stopListening => 'Zuhören stoppen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get startListening => 'Zuhören starten';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get start => 'Start';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stop => 'Stopp';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get web => 'Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGen => 'Bild-Gen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearch => 'Websuche';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearchDescription =>
|
||||||
|
'Lassen Sie den Assistenten beim Antworten im Internet suchen.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGeneration => 'Bilderzeugung';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGenerationDescription =>
|
||||||
|
'Bilder aus Ihrer Eingabe generieren und anhängen.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get unableToLoadProfile => 'Unable to load profile';
|
String get unableToLoadProfile => 'Unable to load profile';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get pleaseCheckConnection => 'Please check your connection and try again';
|
String get pleaseCheckConnection =>
|
||||||
|
'Please check your connection and try again';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get account => 'Account';
|
String get account => 'Account';
|
||||||
@@ -116,7 +117,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get noFilesYet => 'No files yet';
|
String get noFilesYet => 'No files yet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadDocsPrompt => 'Upload documents to reference in your conversations with Conduit';
|
String get uploadDocsPrompt =>
|
||||||
|
'Upload documents to reference in your conversations with Conduit';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadFirstFile => 'Upload your first file';
|
String get uploadFirstFile => 'Upload your first file';
|
||||||
@@ -125,7 +127,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get knowledgeBaseEmpty => 'Knowledge base is empty';
|
String get knowledgeBaseEmpty => 'Knowledge base is empty';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get createCollectionsPrompt => 'Create collections of related documents for easy reference';
|
String get createCollectionsPrompt =>
|
||||||
|
'Create collections of related documents for easy reference';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get chooseSourcePhoto => 'Choose your source';
|
String get chooseSourcePhoto => 'Choose your source';
|
||||||
@@ -163,7 +166,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get signIn => 'Sign In';
|
String get signIn => 'Sign In';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterCredentials => 'Enter your credentials to access your AI conversations';
|
String get enterCredentials =>
|
||||||
|
'Enter your credentials to access your AI conversations';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get credentials => 'Credentials';
|
String get credentials => 'Credentials';
|
||||||
@@ -184,7 +188,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get connectToServer => 'Connect to Server';
|
String get connectToServer => 'Connect to Server';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerAddress => 'Enter your Open-WebUI server address to get started';
|
String get enterServerAddress =>
|
||||||
|
'Enter your Open-WebUI server address to get started';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrl => 'Server URL';
|
String get serverUrl => 'Server URL';
|
||||||
@@ -232,7 +237,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get demoBadge => 'Demo';
|
String get demoBadge => 'Demo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverNotOpenWebUI => 'This does not appear to be an Open-WebUI server.';
|
String get serverNotOpenWebUI =>
|
||||||
|
'This does not appear to be an Open-WebUI server.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrlEmpty => 'Server URL cannot be empty';
|
String get serverUrlEmpty => 'Server URL cannot be empty';
|
||||||
@@ -244,22 +250,27 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get onlyHttpHttps => 'Only HTTP and HTTPS protocols are supported.';
|
String get onlyHttpHttps => 'Only HTTP and HTTPS protocols are supported.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverAddressRequired => 'Server address is required (e.g., 192.168.1.10 or example.com).';
|
String get serverAddressRequired =>
|
||||||
|
'Server address is required (e.g., 192.168.1.10 or example.com).';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get portRange => 'Port must be between 1 and 65535.';
|
String get portRange => 'Port must be between 1 and 65535.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidIpFormat => 'Invalid IP address format. Use format like 192.168.1.10.';
|
String get invalidIpFormat =>
|
||||||
|
'Invalid IP address format. Use format like 192.168.1.10.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get couldNotConnectGeneric => 'Couldn\'t connect. Double-check the address and try again.';
|
String get couldNotConnectGeneric =>
|
||||||
|
'Couldn\'t connect. Double-check the address and try again.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get weCouldntReachServer => 'We couldn\'t reach the server. Check your connection and that the server is running.';
|
String get weCouldntReachServer =>
|
||||||
|
'We couldn\'t reach the server. Check your connection and that the server is running.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get connectionTimedOut => 'Connection timed out. The server might be busy or blocked by a firewall.';
|
String get connectionTimedOut =>
|
||||||
|
'Connection timed out. The server might be busy or blocked by a firewall.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useHttpOrHttpsOnly => 'Use http:// or https:// only.';
|
String get useHttpOrHttpsOnly => 'Use http:// or https:// only.';
|
||||||
@@ -268,19 +279,23 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get loginFailed => 'Login failed';
|
String get loginFailed => 'Login failed';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidCredentials => 'Invalid username or password. Please try again.';
|
String get invalidCredentials =>
|
||||||
|
'Invalid username or password. Please try again.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverRedirectingHttps => 'The server is redirecting requests. Check your server\'s HTTPS configuration.';
|
String get serverRedirectingHttps =>
|
||||||
|
'The server is redirecting requests. Check your server\'s HTTPS configuration.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get unableToConnectServer => 'Unable to connect to server. Please check your connection.';
|
String get unableToConnectServer =>
|
||||||
|
'Unable to connect to server. Please check your connection.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get requestTimedOut => 'The request timed out. Please try again.';
|
String get requestTimedOut => 'The request timed out. Please try again.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get genericSignInFailed => 'We couldn\'t sign you in. Check your credentials and server settings.';
|
String get genericSignInFailed =>
|
||||||
|
'We couldn\'t sign you in. Check your credentials and server settings.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skip => 'Skip';
|
String get skip => 'Skip';
|
||||||
@@ -295,10 +310,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get onboardStartTitle => 'Start a conversation';
|
String get onboardStartTitle => 'Start a conversation';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartSubtitle => 'Choose a model, then type below to begin. Tap New Chat anytime.';
|
String get onboardStartSubtitle =>
|
||||||
|
'Choose a model, then type below to begin. Tap New Chat anytime.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet1 => 'Tap the model name in the top bar to switch models';
|
String get onboardStartBullet1 =>
|
||||||
|
'Tap the model name in the top bar to switch models';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet2 => 'Use New Chat to reset context';
|
String get onboardStartBullet2 => 'Use New Chat to reset context';
|
||||||
@@ -307,7 +324,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get onboardAttachTitle => 'Attach context';
|
String get onboardAttachTitle => 'Attach context';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachSubtitle => 'Ground responses by adding files or images.';
|
String get onboardAttachSubtitle =>
|
||||||
|
'Ground responses by adding files or images.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachBullet1 => 'Files: PDFs, docs, datasets';
|
String get onboardAttachBullet1 => 'Files: PDFs, docs, datasets';
|
||||||
@@ -319,7 +337,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get onboardSpeakTitle => 'Speak naturally';
|
String get onboardSpeakTitle => 'Speak naturally';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakSubtitle => 'Tap the mic to dictate with live waveform feedback.';
|
String get onboardSpeakSubtitle =>
|
||||||
|
'Tap the mic to dictate with live waveform feedback.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet1 => 'Stop anytime; partial text is preserved';
|
String get onboardSpeakBullet1 => 'Stop anytime; partial text is preserved';
|
||||||
@@ -331,13 +350,16 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get onboardQuickTitle => 'Quick actions';
|
String get onboardQuickTitle => 'Quick actions';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickSubtitle => 'Use the top‑left menu to open the chats list and navigation.';
|
String get onboardQuickSubtitle =>
|
||||||
|
'Use the top‑left menu to open the chats list and navigation.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet1 => 'Tap the menu to open the chats list and navigation';
|
String get onboardQuickBullet1 =>
|
||||||
|
'Tap the menu to open the chats list and navigation';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet2 => 'Jump instantly to New Chat, Files, or Profile';
|
String get onboardQuickBullet2 =>
|
||||||
|
'Jump instantly to New Chat, Files, or Profile';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get addAttachment => 'Add attachment';
|
String get addAttachment => 'Add attachment';
|
||||||
@@ -407,10 +429,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get offlineBanner => 'You\'re offline. Some features may be limited.';
|
String get offlineBanner => 'You\'re offline. Some features may be limited.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get featureRequiresInternet => 'This feature requires an internet connection';
|
String get featureRequiresInternet =>
|
||||||
|
'This feature requires an internet connection';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get messagesWillSendWhenOnline => 'Messages will be sent when you\'re back online';
|
String get messagesWillSendWhenOnline =>
|
||||||
|
'Messages will be sent when you\'re back online';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get confirm => 'Confirm';
|
String get confirm => 'Confirm';
|
||||||
@@ -576,4 +600,78 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get aboutAppSubtitle => 'Conduit information and links';
|
String get aboutAppSubtitle => 'Conduit information and links';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appLanguage => 'App language';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get typeBelowToBegin => 'Type below to begin';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get listening => 'Listening…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get recording => 'Recording…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcribing => 'Transcribing…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get speakNow => 'Speak now…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chats => 'Chats';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get darkMode => 'Dark Mode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcript => 'Transcript';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pinned => 'Pinned';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get folders => 'Folders';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get archived => 'Archived';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get holdToTalk => 'Hold to talk';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSend => 'Auto-send';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stopListening => 'Stop listening';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get startListening => 'Start listening';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get start => 'Start';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stop => 'Stop';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get web => 'Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGen => 'Image Gen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearch => 'Web Search';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearchDescription =>
|
||||||
|
'Let the assistant search the internet while answering.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGeneration => 'Image Generation';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGenerationDescription =>
|
||||||
|
'Generate images from your prompt and attach them.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get unableToLoadProfile => 'Impossible de charger le profil';
|
String get unableToLoadProfile => 'Impossible de charger le profil';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get pleaseCheckConnection => 'Veuillez vérifier votre connexion et réessayer';
|
String get pleaseCheckConnection =>
|
||||||
|
'Veuillez vérifier votre connexion et réessayer';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get account => 'Compte';
|
String get account => 'Compte';
|
||||||
@@ -116,7 +117,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get noFilesYet => 'Pas encore de fichiers';
|
String get noFilesYet => 'Pas encore de fichiers';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadDocsPrompt => 'Importez des documents à utiliser dans vos conversations avec Conduit';
|
String get uploadDocsPrompt =>
|
||||||
|
'Importez des documents à utiliser dans vos conversations avec Conduit';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadFirstFile => 'Importer votre premier fichier';
|
String get uploadFirstFile => 'Importer votre premier fichier';
|
||||||
@@ -125,7 +127,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get knowledgeBaseEmpty => 'La base de connaissances est vide';
|
String get knowledgeBaseEmpty => 'La base de connaissances est vide';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get createCollectionsPrompt => 'Créez des collections de documents liés pour une référence facile';
|
String get createCollectionsPrompt =>
|
||||||
|
'Créez des collections de documents liés pour une référence facile';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get chooseSourcePhoto => 'Choisir la source';
|
String get chooseSourcePhoto => 'Choisir la source';
|
||||||
@@ -151,7 +154,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kbCreationComingSoon => 'La création de la base de connaissances arrive bientôt !';
|
String get kbCreationComingSoon =>
|
||||||
|
'La création de la base de connaissances arrive bientôt !';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get backToServerSetup => 'Retour à la configuration du serveur';
|
String get backToServerSetup => 'Retour à la configuration du serveur';
|
||||||
@@ -163,7 +167,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get signIn => 'Se connecter';
|
String get signIn => 'Se connecter';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterCredentials => 'Entrez vos identifiants pour accéder à vos conversations IA';
|
String get enterCredentials =>
|
||||||
|
'Entrez vos identifiants pour accéder à vos conversations IA';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get credentials => 'Identifiants';
|
String get credentials => 'Identifiants';
|
||||||
@@ -184,7 +189,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get connectToServer => 'Se connecter au serveur';
|
String get connectToServer => 'Se connecter au serveur';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerAddress => 'Saisissez l\'adresse de votre serveur Open-WebUI pour commencer';
|
String get enterServerAddress =>
|
||||||
|
'Saisissez l\'adresse de votre serveur Open-WebUI pour commencer';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrl => 'URL du serveur';
|
String get serverUrl => 'URL du serveur';
|
||||||
@@ -193,7 +199,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get serverUrlHint => 'https://votre-serveur.com';
|
String get serverUrlHint => 'https://votre-serveur.com';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerUrlSemantic => 'Saisissez l\'URL ou l\'adresse IP de votre serveur';
|
String get enterServerUrlSemantic =>
|
||||||
|
'Saisissez l\'URL ou l\'adresse IP de votre serveur';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get headerName => 'Nom de l\'en-tête';
|
String get headerName => 'Nom de l\'en-tête';
|
||||||
@@ -223,7 +230,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get demoModeActive => 'Mode démo activé';
|
String get demoModeActive => 'Mode démo activé';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skipServerSetupTryDemo => 'Ignorer la configuration et essayer la démo';
|
String get skipServerSetupTryDemo =>
|
||||||
|
'Ignorer la configuration et essayer la démo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterDemo => 'Entrer en démo';
|
String get enterDemo => 'Entrer en démo';
|
||||||
@@ -232,34 +240,42 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get demoBadge => 'Démo';
|
String get demoBadge => 'Démo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverNotOpenWebUI => 'Ceci ne semble pas être un serveur Open-WebUI.';
|
String get serverNotOpenWebUI =>
|
||||||
|
'Ceci ne semble pas être un serveur Open-WebUI.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrlEmpty => 'L\'URL du serveur ne peut pas être vide';
|
String get serverUrlEmpty => 'L\'URL du serveur ne peut pas être vide';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidUrlFormat => 'Format d\'URL invalide. Veuillez vérifier votre saisie.';
|
String get invalidUrlFormat =>
|
||||||
|
'Format d\'URL invalide. Veuillez vérifier votre saisie.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onlyHttpHttps => 'Seuls les protocoles HTTP et HTTPS sont pris en charge.';
|
String get onlyHttpHttps =>
|
||||||
|
'Seuls les protocoles HTTP et HTTPS sont pris en charge.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverAddressRequired => 'Adresse du serveur requise (ex. 192.168.1.10 ou example.com).';
|
String get serverAddressRequired =>
|
||||||
|
'Adresse du serveur requise (ex. 192.168.1.10 ou example.com).';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get portRange => 'Le port doit être compris entre 1 et 65535.';
|
String get portRange => 'Le port doit être compris entre 1 et 65535.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidIpFormat => 'Format d\'IP invalide. Exemple : 192.168.1.10.';
|
String get invalidIpFormat =>
|
||||||
|
'Format d\'IP invalide. Exemple : 192.168.1.10.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get couldNotConnectGeneric => 'Connexion impossible. Vérifiez l\'adresse et réessayez.';
|
String get couldNotConnectGeneric =>
|
||||||
|
'Connexion impossible. Vérifiez l\'adresse et réessayez.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get weCouldntReachServer => 'Impossible d\'atteindre le serveur. Vérifiez la connexion et l\'état du serveur.';
|
String get weCouldntReachServer =>
|
||||||
|
'Impossible d\'atteindre le serveur. Vérifiez la connexion et l\'état du serveur.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get connectionTimedOut => 'Délai d\'attente dépassé. Le serveur est peut-être occupé ou bloqué.';
|
String get connectionTimedOut =>
|
||||||
|
'Délai d\'attente dépassé. Le serveur est peut-être occupé ou bloqué.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useHttpOrHttpsOnly => 'Utilisez uniquement http:// ou https://.';
|
String get useHttpOrHttpsOnly => 'Utilisez uniquement http:// ou https://.';
|
||||||
@@ -268,19 +284,23 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get loginFailed => 'Échec de la connexion';
|
String get loginFailed => 'Échec de la connexion';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidCredentials => 'Nom d\'utilisateur ou mot de passe invalide. Réessayez.';
|
String get invalidCredentials =>
|
||||||
|
'Nom d\'utilisateur ou mot de passe invalide. Réessayez.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverRedirectingHttps => 'Le serveur redirige les requêtes. Vérifiez la configuration HTTPS.';
|
String get serverRedirectingHttps =>
|
||||||
|
'Le serveur redirige les requêtes. Vérifiez la configuration HTTPS.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get unableToConnectServer => 'Impossible de se connecter au serveur. Vérifiez votre connexion.';
|
String get unableToConnectServer =>
|
||||||
|
'Impossible de se connecter au serveur. Vérifiez votre connexion.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get requestTimedOut => 'Délai d\'attente dépassé. Réessayez.';
|
String get requestTimedOut => 'Délai d\'attente dépassé. Réessayez.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get genericSignInFailed => 'Connexion impossible. Vérifiez vos identifiants et le serveur.';
|
String get genericSignInFailed =>
|
||||||
|
'Connexion impossible. Vérifiez vos identifiants et le serveur.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skip => 'Ignorer';
|
String get skip => 'Ignorer';
|
||||||
@@ -295,22 +315,27 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get onboardStartTitle => 'Commencer une conversation';
|
String get onboardStartTitle => 'Commencer une conversation';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartSubtitle => 'Choisissez un modèle puis commencez à écrire. Touchez Nouveau chat à tout moment.';
|
String get onboardStartSubtitle =>
|
||||||
|
'Choisissez un modèle puis commencez à écrire. Touchez Nouveau chat à tout moment.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet1 => 'Touchez le nom du modèle en haut pour changer';
|
String get onboardStartBullet1 =>
|
||||||
|
'Touchez le nom du modèle en haut pour changer';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet2 => 'Utilisez Nouveau chat pour réinitialiser le contexte';
|
String get onboardStartBullet2 =>
|
||||||
|
'Utilisez Nouveau chat pour réinitialiser le contexte';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachTitle => 'Ajouter du contexte';
|
String get onboardAttachTitle => 'Ajouter du contexte';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachSubtitle => 'Améliorez les réponses en ajoutant des fichiers ou des images.';
|
String get onboardAttachSubtitle =>
|
||||||
|
'Améliorez les réponses en ajoutant des fichiers ou des images.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachBullet1 => 'Fichiers : PDF, documents, jeux de données';
|
String get onboardAttachBullet1 =>
|
||||||
|
'Fichiers : PDF, documents, jeux de données';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachBullet2 => 'Images : photos ou captures d\'écran';
|
String get onboardAttachBullet2 => 'Images : photos ou captures d\'écran';
|
||||||
@@ -319,25 +344,31 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get onboardSpeakTitle => 'Parlez naturellement';
|
String get onboardSpeakTitle => 'Parlez naturellement';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakSubtitle => 'Touchez le micro pour dicter avec retour visuel.';
|
String get onboardSpeakSubtitle =>
|
||||||
|
'Touchez le micro pour dicter avec retour visuel.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet1 => 'Arrêtez à tout moment ; le texte partiel est conservé';
|
String get onboardSpeakBullet1 =>
|
||||||
|
'Arrêtez à tout moment ; le texte partiel est conservé';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet2 => 'Idéal pour des notes rapides ou de longs prompts';
|
String get onboardSpeakBullet2 =>
|
||||||
|
'Idéal pour des notes rapides ou de longs prompts';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickTitle => 'Actions rapides';
|
String get onboardQuickTitle => 'Actions rapides';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickSubtitle => 'Utilisez le menu en haut à gauche pour ouvrir la liste des chats et la navigation.';
|
String get onboardQuickSubtitle =>
|
||||||
|
'Utilisez le menu en haut à gauche pour ouvrir la liste des chats et la navigation.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet1 => 'Touchez le menu pour ouvrir les chats et la navigation';
|
String get onboardQuickBullet1 =>
|
||||||
|
'Touchez le menu pour ouvrir les chats et la navigation';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet2 => 'Accédez rapidement à Nouveau chat, Fichiers ou Profil';
|
String get onboardQuickBullet2 =>
|
||||||
|
'Accédez rapidement à Nouveau chat, Fichiers ou Profil';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get addAttachment => 'Ajouter une pièce jointe';
|
String get addAttachment => 'Ajouter une pièce jointe';
|
||||||
@@ -404,13 +435,16 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get emptyImageData => 'Données d\'image vides';
|
String get emptyImageData => 'Données d\'image vides';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get offlineBanner => 'Vous êtes hors ligne. Certaines fonctions peuvent être limitées.';
|
String get offlineBanner =>
|
||||||
|
'Vous êtes hors ligne. Certaines fonctions peuvent être limitées.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get featureRequiresInternet => 'Cette fonctionnalité nécessite une connexion Internet';
|
String get featureRequiresInternet =>
|
||||||
|
'Cette fonctionnalité nécessite une connexion Internet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get messagesWillSendWhenOnline => 'Les messages seront envoyés lorsque vous serez de nouveau en ligne';
|
String get messagesWillSendWhenOnline =>
|
||||||
|
'Les messages seront envoyés lorsque vous serez de nouveau en ligne';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get confirm => 'Confirmer';
|
String get confirm => 'Confirmer';
|
||||||
@@ -576,4 +610,78 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get aboutAppSubtitle => 'Informations et liens Conduit';
|
String get aboutAppSubtitle => 'Informations et liens Conduit';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appLanguage => 'Langue de l\'app';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get typeBelowToBegin => 'Tapez ci-dessous pour commencer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get listening => 'Écoute…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get recording => 'Enregistrement…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcribing => 'Transcription…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get speakNow => 'Parlez maintenant…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chats => 'Discussions';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get darkMode => 'Mode sombre';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcript => 'Transcription';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pinned => 'Épinglés';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get folders => 'Dossiers';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get archived => 'Archivés';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get holdToTalk => 'Maintenir pour parler';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSend => 'Envoi auto';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stopListening => 'Arrêter l\'écoute';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get startListening => 'Commencer l\'écoute';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get start => 'Démarrer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stop => 'Arrêter';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get web => 'Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGen => 'Gén. image';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearch => 'Recherche Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearchDescription =>
|
||||||
|
'Laissez l\'assistant rechercher sur Internet pendant la réponse.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGeneration => 'Génération d\'images';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGenerationDescription =>
|
||||||
|
'Générez des images à partir de votre prompt et joignez-les.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get noFilesYet => 'Ancora nessun file';
|
String get noFilesYet => 'Ancora nessun file';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadDocsPrompt => 'Carica documenti da usare nelle conversazioni con Conduit';
|
String get uploadDocsPrompt =>
|
||||||
|
'Carica documenti da usare nelle conversazioni con Conduit';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get uploadFirstFile => 'Carica il tuo primo file';
|
String get uploadFirstFile => 'Carica il tuo primo file';
|
||||||
@@ -125,7 +126,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get knowledgeBaseEmpty => 'La base di conoscenza è vuota';
|
String get knowledgeBaseEmpty => 'La base di conoscenza è vuota';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get createCollectionsPrompt => 'Crea raccolte di documenti correlati per un rapido riferimento';
|
String get createCollectionsPrompt =>
|
||||||
|
'Crea raccolte di documenti correlati per un rapido riferimento';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get chooseSourcePhoto => 'Scegli origine';
|
String get chooseSourcePhoto => 'Scegli origine';
|
||||||
@@ -151,7 +153,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kbCreationComingSoon => 'La creazione della base di conoscenza arriverà presto!';
|
String get kbCreationComingSoon =>
|
||||||
|
'La creazione della base di conoscenza arriverà presto!';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get backToServerSetup => 'Torna alla configurazione del server';
|
String get backToServerSetup => 'Torna alla configurazione del server';
|
||||||
@@ -163,7 +166,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get signIn => 'Accedi';
|
String get signIn => 'Accedi';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterCredentials => 'Inserisci le credenziali per accedere alle conversazioni IA';
|
String get enterCredentials =>
|
||||||
|
'Inserisci le credenziali per accedere alle conversazioni IA';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get credentials => 'Credenziali';
|
String get credentials => 'Credenziali';
|
||||||
@@ -184,7 +188,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get connectToServer => 'Connetti al server';
|
String get connectToServer => 'Connetti al server';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerAddress => 'Inserisci l\'indirizzo del server Open-WebUI per iniziare';
|
String get enterServerAddress =>
|
||||||
|
'Inserisci l\'indirizzo del server Open-WebUI per iniziare';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverUrl => 'URL del server';
|
String get serverUrl => 'URL del server';
|
||||||
@@ -193,7 +198,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get serverUrlHint => 'https://tuo-server.com';
|
String get serverUrlHint => 'https://tuo-server.com';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterServerUrlSemantic => 'Inserisci l\'URL o l\'indirizzo IP del server';
|
String get enterServerUrlSemantic =>
|
||||||
|
'Inserisci l\'URL o l\'indirizzo IP del server';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get headerName => 'Nome header';
|
String get headerName => 'Nome header';
|
||||||
@@ -223,7 +229,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get demoModeActive => 'Modalità demo attiva';
|
String get demoModeActive => 'Modalità demo attiva';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skipServerSetupTryDemo => 'Salta configurazione server e prova la demo';
|
String get skipServerSetupTryDemo =>
|
||||||
|
'Salta configurazione server e prova la demo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enterDemo => 'Entra in demo';
|
String get enterDemo => 'Entra in demo';
|
||||||
@@ -244,7 +251,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get onlyHttpHttps => 'Sono supportati solo i protocolli HTTP e HTTPS.';
|
String get onlyHttpHttps => 'Sono supportati solo i protocolli HTTP e HTTPS.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverAddressRequired => 'Indirizzo server richiesto (es. 192.168.1.10 o example.com).';
|
String get serverAddressRequired =>
|
||||||
|
'Indirizzo server richiesto (es. 192.168.1.10 o example.com).';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get portRange => 'La porta deve essere tra 1 e 65535.';
|
String get portRange => 'La porta deve essere tra 1 e 65535.';
|
||||||
@@ -253,13 +261,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get invalidIpFormat => 'Formato IP non valido. Esempio: 192.168.1.10.';
|
String get invalidIpFormat => 'Formato IP non valido. Esempio: 192.168.1.10.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get couldNotConnectGeneric => 'Impossibile connettersi. Verifica l\'indirizzo e riprova.';
|
String get couldNotConnectGeneric =>
|
||||||
|
'Impossibile connettersi. Verifica l\'indirizzo e riprova.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get weCouldntReachServer => 'Impossibile raggiungere il server. Verifica connessione e stato del server.';
|
String get weCouldntReachServer =>
|
||||||
|
'Impossibile raggiungere il server. Verifica connessione e stato del server.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get connectionTimedOut => 'Tempo scaduto. Il server potrebbe essere occupato o bloccato.';
|
String get connectionTimedOut =>
|
||||||
|
'Tempo scaduto. Il server potrebbe essere occupato o bloccato.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useHttpOrHttpsOnly => 'Usa solo http:// o https://.';
|
String get useHttpOrHttpsOnly => 'Usa solo http:// o https://.';
|
||||||
@@ -268,19 +279,23 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get loginFailed => 'Accesso non riuscito';
|
String get loginFailed => 'Accesso non riuscito';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidCredentials => 'Nome utente o password non validi. Riprova.';
|
String get invalidCredentials =>
|
||||||
|
'Nome utente o password non validi. Riprova.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get serverRedirectingHttps => 'Il server sta reindirizzando. Controlla la configurazione HTTPS.';
|
String get serverRedirectingHttps =>
|
||||||
|
'Il server sta reindirizzando. Controlla la configurazione HTTPS.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get unableToConnectServer => 'Impossibile connettersi al server. Controlla la connessione.';
|
String get unableToConnectServer =>
|
||||||
|
'Impossibile connettersi al server. Controlla la connessione.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get requestTimedOut => 'Richiesta scaduta. Riprova.';
|
String get requestTimedOut => 'Richiesta scaduta. Riprova.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get genericSignInFailed => 'Impossibile accedere. Controlla credenziali e server.';
|
String get genericSignInFailed =>
|
||||||
|
'Impossibile accedere. Controlla credenziali e server.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get skip => 'Salta';
|
String get skip => 'Salta';
|
||||||
@@ -295,10 +310,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get onboardStartTitle => 'Inizia una conversazione';
|
String get onboardStartTitle => 'Inizia una conversazione';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartSubtitle => 'Scegli un modello e inizia a scrivere. Tocca Nuova chat in qualsiasi momento.';
|
String get onboardStartSubtitle =>
|
||||||
|
'Scegli un modello e inizia a scrivere. Tocca Nuova chat in qualsiasi momento.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet1 => 'Tocca il nome del modello in alto per cambiare';
|
String get onboardStartBullet1 =>
|
||||||
|
'Tocca il nome del modello in alto per cambiare';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardStartBullet2 => 'Usa Nuova chat per azzerare il contesto';
|
String get onboardStartBullet2 => 'Usa Nuova chat per azzerare il contesto';
|
||||||
@@ -307,7 +324,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get onboardAttachTitle => 'Aggiungi contesto';
|
String get onboardAttachTitle => 'Aggiungi contesto';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachSubtitle => 'Migliora le risposte aggiungendo file o immagini.';
|
String get onboardAttachSubtitle =>
|
||||||
|
'Migliora le risposte aggiungendo file o immagini.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardAttachBullet1 => 'File: PDF, documenti, dataset';
|
String get onboardAttachBullet1 => 'File: PDF, documenti, dataset';
|
||||||
@@ -319,10 +337,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get onboardSpeakTitle => 'Parla in modo naturale';
|
String get onboardSpeakTitle => 'Parla in modo naturale';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakSubtitle => 'Tocca il microfono per dettare con feedback visivo.';
|
String get onboardSpeakSubtitle =>
|
||||||
|
'Tocca il microfono per dettare con feedback visivo.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet1 => 'Interrompi in qualsiasi momento; il testo parziale viene mantenuto';
|
String get onboardSpeakBullet1 =>
|
||||||
|
'Interrompi in qualsiasi momento; il testo parziale viene mantenuto';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardSpeakBullet2 => 'Ottimo per note rapide o prompt lunghi';
|
String get onboardSpeakBullet2 => 'Ottimo per note rapide o prompt lunghi';
|
||||||
@@ -331,10 +351,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get onboardQuickTitle => 'Azioni rapide';
|
String get onboardQuickTitle => 'Azioni rapide';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickSubtitle => 'Usa il menu in alto a sinistra per aprire l\'elenco chat e la navigazione.';
|
String get onboardQuickSubtitle =>
|
||||||
|
'Usa il menu in alto a sinistra per aprire l\'elenco chat e la navigazione.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet1 => 'Tocca il menu per aprire chat e navigazione';
|
String get onboardQuickBullet1 =>
|
||||||
|
'Tocca il menu per aprire chat e navigazione';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get onboardQuickBullet2 => 'Vai subito a Nuova chat, File o Profilo';
|
String get onboardQuickBullet2 => 'Vai subito a Nuova chat, File o Profilo';
|
||||||
@@ -404,13 +426,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get emptyImageData => 'Dati immagine vuoti';
|
String get emptyImageData => 'Dati immagine vuoti';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get offlineBanner => 'Sei offline. Alcune funzioni potrebbero essere limitate.';
|
String get offlineBanner =>
|
||||||
|
'Sei offline. Alcune funzioni potrebbero essere limitate.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get featureRequiresInternet => 'Questa funzione richiede una connessione Internet';
|
String get featureRequiresInternet =>
|
||||||
|
'Questa funzione richiede una connessione Internet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get messagesWillSendWhenOnline => 'I messaggi verranno inviati quando tornerai online';
|
String get messagesWillSendWhenOnline =>
|
||||||
|
'I messaggi verranno inviati quando tornerai online';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get confirm => 'Conferma';
|
String get confirm => 'Conferma';
|
||||||
@@ -569,11 +594,86 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
String get deleteChatTitle => 'Elimina chat';
|
String get deleteChatTitle => 'Elimina chat';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteChatMessage => 'Questa chat verrà eliminata definitivamente.';
|
String get deleteChatMessage =>
|
||||||
|
'Questa chat verrà eliminata definitivamente.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get aboutApp => 'Informazioni sull\'app';
|
String get aboutApp => 'Informazioni sull\'app';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get aboutAppSubtitle => 'Informazioni e link di Conduit';
|
String get aboutAppSubtitle => 'Informazioni e link di Conduit';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appLanguage => 'Lingua dell\'app';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get typeBelowToBegin => 'Scrivi qui sotto per iniziare';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get listening => 'In ascolto…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get recording => 'Registrazione…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcribing => 'Trascrizione…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get speakNow => 'Parla ora…';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chats => 'Chat';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get darkMode => 'Tema scuro';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get transcript => 'Trascrizione';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pinned => 'In evidenza';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get folders => 'Cartelle';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get archived => 'Archiviati';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get holdToTalk => 'Tieni premuto per parlare';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSend => 'Invio automatico';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stopListening => 'Interrompi ascolto';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get startListening => 'Avvia ascolto';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get start => 'Avvia';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get stop => 'Stop';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get web => 'Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGen => 'Gen. immagini';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearch => 'Ricerca Web';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get webSearchDescription =>
|
||||||
|
'Lascia che l\'assistente cerchi sul web mentre risponde.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGeneration => 'Generazione immagini';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get imageGenerationDescription =>
|
||||||
|
'Genera immagini dal prompt e allegale.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import 'core/auth/auth_state_manager.dart';
|
|||||||
import 'core/utils/debug_logger.dart';
|
import 'core/utils/debug_logger.dart';
|
||||||
|
|
||||||
import 'features/onboarding/views/onboarding_sheet.dart';
|
import 'features/onboarding/views/onboarding_sheet.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
||||||
import 'package:conduit/l10n/app_localizations.dart';
|
import 'package:conduit/l10n/app_localizations.dart';
|
||||||
import 'features/chat/views/chat_page.dart';
|
import 'features/chat/views/chat_page.dart';
|
||||||
import 'features/navigation/views/splash_launcher_page.dart';
|
import 'features/navigation/views/splash_launcher_page.dart';
|
||||||
@@ -101,25 +100,19 @@ class _ConduitAppState extends ConsumerState<ConduitApp> {
|
|||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
navigatorKey: NavigationService.navigatorKey,
|
navigatorKey: NavigationService.navigatorKey,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
AppLocalizations.delegate,
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
GlobalMaterialLocalizations.delegate,
|
localeListResolutionCallback: (deviceLocales, supported) {
|
||||||
GlobalWidgetsLocalizations.delegate,
|
|
||||||
GlobalCupertinoLocalizations.delegate,
|
|
||||||
],
|
|
||||||
supportedLocales: const [
|
|
||||||
Locale('en'),
|
|
||||||
Locale('de'),
|
|
||||||
Locale('fr'),
|
|
||||||
Locale('it'),
|
|
||||||
],
|
|
||||||
localeResolutionCallback: (deviceLocale, supported) {
|
|
||||||
if (locale != null) return locale; // User override wins
|
if (locale != null) return locale; // User override wins
|
||||||
if (deviceLocale == null) return const Locale('en');
|
if (deviceLocales == null || deviceLocales.isEmpty) {
|
||||||
for (final loc in supported) {
|
return supported.first;
|
||||||
if (loc.languageCode == deviceLocale.languageCode) return loc;
|
|
||||||
}
|
}
|
||||||
return const Locale('en');
|
for (final device in deviceLocales) {
|
||||||
|
for (final loc in supported) {
|
||||||
|
if (loc.languageCode == device.languageCode) return loc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return supported.first;
|
||||||
},
|
},
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
// Keep a subtle fade for navigation transitions only
|
// Keep a subtle fade for navigation transitions only
|
||||||
@@ -184,7 +177,8 @@ class _ConduitAppState extends ConsumerState<ConduitApp> {
|
|||||||
|
|
||||||
if (authNavState == AuthNavigationState.error) {
|
if (authNavState == AuthNavigationState.error) {
|
||||||
return _buildErrorState(
|
return _buildErrorState(
|
||||||
ref.watch(authErrorProvider3) ?? AppLocalizations.of(context)!.errorMessage,
|
ref.watch(authErrorProvider3) ??
|
||||||
|
AppLocalizations.of(context)!.errorMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +193,9 @@ class _ConduitAppState extends ConsumerState<ConduitApp> {
|
|||||||
loading: () => _buildInitialLoadingSkeleton(context),
|
loading: () => _buildInitialLoadingSkeleton(context),
|
||||||
error: (error, stackTrace) {
|
error: (error, stackTrace) {
|
||||||
DebugLogger.error('Server provider error', error);
|
DebugLogger.error('Server provider error', error);
|
||||||
return _buildErrorState(AppLocalizations.of(context)!.unableToConnectServer);
|
return _buildErrorState(
|
||||||
|
AppLocalizations.of(context)!.unableToConnectServer,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user