fix: default model edge cases

This commit is contained in:
cogwheel0
2025-08-17 17:43:19 +05:30
parent cf449fb796
commit 7b598d7c04
14 changed files with 90 additions and 429 deletions

View File

@@ -139,7 +139,7 @@ class VoiceInputService {
path: filePath,
);
// ignore: avoid_print
print('DEBUG: VoiceInputService recording started at: ' + filePath);
print('DEBUG: VoiceInputService recording started at: $filePath');
// Drive intensity from amplitude stream and detect silence
// Consider amplitude less than threshold as silence; stop after ~3s of continuous silence
@@ -183,7 +183,7 @@ class VoiceInputService {
return;
}
// ignore: avoid_print
print('DEBUG: VoiceInputService recording saved: ' + path);
print('DEBUG: VoiceInputService recording saved: $path');
// Hand off recorded file path to listeners as a special token; UI layer will upload for transcription
_textStreamController?.add('[[AUDIO_FILE_PATH]]:$path');
} catch (e) {

View File

@@ -109,7 +109,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
// Try to use the default model provider
try {
final model = await ref.read(defaultModelProvider.future);
final Model? model = await ref.read(defaultModelProvider.future);
if (model != null) {
debugPrint('DEBUG: Model auto-selected via provider: ${model.name}');
}
@@ -2170,7 +2170,7 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
if (text.startsWith('[[AUDIO_FILE_PATH]]:')) {
final filePath = text.split(':').skip(1).join(':');
debugPrint(
'DEBUG: VoiceInputSheet received audio file path: ' + filePath,
'DEBUG: VoiceInputSheet received audio file path: $filePath',
);
_transcribeRecordedFile(filePath);
} else {
@@ -2237,7 +2237,7 @@ class _VoiceInputSheetState extends ConsumerState<_VoiceInputSheet> {
language: language,
);
debugPrint(
'DEBUG: Transcription received: ' + (text.isEmpty ? '[empty]' : text),
'DEBUG: Transcription received: ${text.isEmpty ? '[empty]' : text}',
);
if (!mounted) return;
setState(() {

View File

@@ -199,6 +199,7 @@ class _ModelSelectorPageState extends ConsumerState<ModelSelectorPage> {
onTap: () {
ref.read(selectedModelProvider.notifier).state =
model;
ref.read(isManualModelSelectionProvider.notifier).state = true;
Navigator.pop(context);
},
),

View File

@@ -839,19 +839,19 @@ class MoreOptionsSheet extends ConsumerWidget {
}
}
void _showDeleteConfirmation(BuildContext context, WidgetRef ref) {
ThemedDialogs.confirm(
void _showDeleteConfirmation(BuildContext context, WidgetRef ref) async {
final confirmed = await ThemedDialogs.confirm(
context,
title: 'Delete Messages',
message:
'Are you sure you want to delete ${messages.length} message${messages.length == 1 ? '' : 's'}? This action cannot be undone.',
confirmText: 'Delete',
isDestructive: true,
).then((confirmed) {
if (confirmed == true) {
_deleteMessages(context, ref);
}
});
);
if (confirmed == true && context.mounted) {
_deleteMessages(context, ref);
}
}
void _deleteMessages(BuildContext context, WidgetRef ref) async {

View File

@@ -274,16 +274,16 @@ class _ChatsListPageState extends ConsumerState<ChatsListPage>
.toList();
// Debug logging
print('🔍 DEBUG: Total conversations: ${uniqueConversations.length} (filtered: ${filteredConversations.length}, original: ${conversations.length})');
print('🔍 DEBUG: Pinned: ${pinnedConversations.length}');
print('🔍 DEBUG: Regular: ${regularConversations.length}');
print('🔍 DEBUG: Folder: ${folderConversations.length}');
print('🔍 DEBUG: Archived: ${archivedConversations.length}');
debugPrint('DEBUG: Total conversations: ${uniqueConversations.length} (filtered: ${filteredConversations.length}, original: ${conversations.length})');
debugPrint('DEBUG: Pinned: ${pinnedConversations.length}');
debugPrint('DEBUG: Regular: ${regularConversations.length}');
debugPrint('DEBUG: Folder: ${folderConversations.length}');
debugPrint('DEBUG: Archived: ${archivedConversations.length}');
// Check first few conversations for folder IDs
for (int i = 0; i < uniqueConversations.take(5).length; i++) {
final conv = uniqueConversations[i];
print('🔍 DEBUG: Conv ${i}: id=${conv.id.substring(0, 8)}, folderId=${conv.folderId}, pinned=${conv.pinned}, archived=${conv.archived}');
debugPrint('DEBUG: Conv $i: id=${conv.id.substring(0, 8)}, folderId=${conv.folderId}, pinned=${conv.pinned}, archived=${conv.archived}');
}
return ListView(
@@ -336,7 +336,7 @@ class _ChatsListPageState extends ConsumerState<ChatsListPage>
}).toList();
},
loading: () => [const SizedBox.shrink()],
error: (_, __) => [const SizedBox.shrink()],
error: (_, stackTrace) => [const SizedBox.shrink()],
),
],
@@ -1246,6 +1246,13 @@ class _ChatsListPageState extends ConsumerState<ChatsListPage>
}
Future<void> _createFolderFromDialog(String name, BuildContext dialogContext) async {
// Store theme values and messenger before async operation
final theme = context.conduitTheme;
final textInverseColor = theme.textInverse;
final successColor = theme.success;
final errorColor = theme.error;
final messenger = ScaffoldMessenger.of(context);
try {
final api = ref.read(apiServiceProvider);
if (api == null) throw Exception('No API service available');
@@ -1253,31 +1260,33 @@ class _ChatsListPageState extends ConsumerState<ChatsListPage>
await api.createFolder(name: name);
ref.invalidate(foldersProvider);
if (mounted) {
if (mounted && dialogContext.mounted) {
Navigator.pop(dialogContext);
ScaffoldMessenger.of(context).showSnackBar(
}
if (context.mounted) {
messenger.showSnackBar(
SnackBar(
content: Text(
'Folder "$name" created',
style: AppTypography.bodyMediumStyle.copyWith(
color: context.conduitTheme.textInverse,
color: textInverseColor,
),
),
backgroundColor: context.conduitTheme.success,
backgroundColor: successColor,
),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
if (context.mounted) {
messenger.showSnackBar(
SnackBar(
content: Text(
'Failed to create folder: $e',
style: AppTypography.bodyMediumStyle.copyWith(
color: context.conduitTheme.textInverse,
color: textInverseColor,
),
),
backgroundColor: context.conduitTheme.error,
backgroundColor: errorColor,
),
);
}

View File

@@ -647,8 +647,12 @@ class ProfilePage extends ConsumerWidget {
),
);
if (result is String || result == null) {
await ref.read(appSettingsProvider.notifier).setDefaultModel(result);
// result is non-null only when Save button is pressed
// null means the sheet was dismissed without saving
if (result != null) {
// Handle special case: 'auto-select' should be stored as null
final modelIdToSave = result == 'auto-select' ? null : result;
await ref.read(appSettingsProvider.notifier).setDefaultModel(modelIdToSave);
}
}
@@ -720,7 +724,8 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
@override
void initState() {
super.initState();
_selectedModelId = widget.currentDefaultModelId;
// If no default model is set (null), default to auto-select
_selectedModelId = widget.currentDefaultModelId ?? 'auto-select';
// Add auto-select as first item
_filteredModels = [
const Model(id: 'auto-select', name: 'Auto-select'),
@@ -812,7 +817,7 @@ class _DefaultModelBottomSheetState extends ConsumerState<_DefaultModelBottomShe
),
),
TextButton(
onPressed: () => Navigator.pop(context, _selectedModelId == 'auto-select' ? null : _selectedModelId),
onPressed: () => Navigator.pop(context, _selectedModelId),
child: Text(
'Save',
style: context.conduitTheme.bodyMedium?.copyWith(