From f65cf33c5986e0c837fda0329d730b3d9706d3c9 Mon Sep 17 00:00:00 2001 From: cogwheel0 <172976095+cogwheel0@users.noreply.github.com> Date: Thu, 28 Aug 2025 23:05:27 +0530 Subject: [PATCH] fix: range error on chat drawer --- lib/core/providers/app_providers.dart | 15 +++- lib/core/services/api_service.dart | 21 +++-- .../navigation/widgets/chats_drawer.dart | 84 +++++++++++-------- vendor/open-webui | 1 + 4 files changed, 75 insertions(+), 46 deletions(-) create mode 160000 vendor/open-webui diff --git a/lib/core/providers/app_providers.dart b/lib/core/providers/app_providers.dart index 1ca0988..ab6ac4c 100644 --- a/lib/core/providers/app_providers.dart +++ b/lib/core/providers/app_providers.dart @@ -442,8 +442,11 @@ final conversationsProvider = FutureProvider>((ref) async { conversationMap[conversation.id] = conversation.copyWith( folderId: folderIdToUse, ); + final _idPreview = conversation.id.length > 8 + ? conversation.id.substring(0, 8) + : conversation.id; foundation.debugPrint( - 'DEBUG: Updated conversation ${conversation.id.substring(0, 8)} with folderId: $folderIdToUse (explicit: ${explicitFolderId != null})', + 'DEBUG: Updated conversation $_idPreview with folderId: $folderIdToUse (explicit: ${explicitFolderId != null})', ); } else { conversationMap[conversation.id] = conversation; @@ -505,8 +508,11 @@ final conversationsProvider = FutureProvider>((ref) async { // Use map to prevent duplicates - this will overwrite if ID already exists conversationMap[toAdd.id] = toAdd; existingIds.add(toAdd.id); + final _idPreview = toAdd.id.length > 8 + ? toAdd.id.substring(0, 8) + : toAdd.id; foundation.debugPrint( - 'DEBUG: Added missing conversation from folder fetch: ${toAdd.id.substring(0, 8)} -> folder ${folder.id}', + 'DEBUG: Added missing conversation from folder fetch: $_idPreview -> folder ${folder.id}', ); } else { // Create a minimal placeholder if not returned by folder API @@ -521,8 +527,11 @@ final conversationsProvider = FutureProvider>((ref) async { // Use map to prevent duplicates conversationMap[convId] = placeholder; existingIds.add(convId); + final _idPreview = convId.length > 8 + ? convId.substring(0, 8) + : convId; foundation.debugPrint( - 'DEBUG: Added placeholder conversation for missing ID: ${convId.substring(0, 8)} -> folder ${folder.id}', + 'DEBUG: Added placeholder conversation for missing ID: $_idPreview -> folder ${folder.id}', ); } } diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index 41f9921..cda3e0a 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -417,9 +417,11 @@ class ApiService { debugPrint( '🔍 DEBUG: Sample chat data fields: ${chatData.keys.toList()}', ); - debugPrint( - '🔍 DEBUG: Sample chat data: ${chatData.toString().substring(0, 200)}...', - ); + final _sampleStr = chatData.toString(); + final _preview = _sampleStr.length > 200 + ? _sampleStr.substring(0, 200) + : _sampleStr; + debugPrint('🔍 DEBUG: Sample chat data: $_preview...'); } final conversation = _parseOpenWebUIChat(chatData); @@ -498,9 +500,8 @@ class ApiService { // Debug logging for folder assignment if (folderId != null) { - debugPrint( - '🔍 DEBUG: Conversation ${id.substring(0, 8)} has folderId: $folderId', - ); + final _idPreview = id.length > 8 ? id.substring(0, 8) : id; + debugPrint('🔍 DEBUG: Conversation $_idPreview has folderId: $folderId'); } debugPrint( @@ -3020,9 +3021,11 @@ class ApiService { } else if (response.data is Map) { DebugLogger.log(' Object keys: ${(response.data as Map).keys}'); } - DebugLogger.log( - ' Sample data: ${response.data.toString().substring(0, 200)}...', - ); + final _dataStr = response.data.toString(); + final _dataPreview = _dataStr.length > 200 + ? _dataStr.substring(0, 200) + : _dataStr; + DebugLogger.log(' Sample data: $_dataPreview...'); } catch (e) { debugPrint('❌ $endpoint - Error: $e'); } diff --git a/lib/features/navigation/widgets/chats_drawer.dart b/lib/features/navigation/widgets/chats_drawer.dart index 9405144..6efd9fe 100644 --- a/lib/features/navigation/widgets/chats_drawer.dart +++ b/lib/features/navigation/widgets/chats_drawer.dart @@ -198,23 +198,32 @@ class _ChatsDrawerState extends ConsumerState { // Build sections final pinned = list.where((c) => c.pinned == true).toList(); - final regular = list - .where( - (c) => - c.pinned != true && - c.archived != true && - (c.folderId == null || c.folderId!.isEmpty), - ) - .toList(); - final foldered = list - .where( - (c) => - c.pinned != true && - c.archived != true && - c.folderId != null && - c.folderId!.isNotEmpty, - ) - .toList(); + + // Determine which folder IDs actually exist from the API + final foldersState = ref.watch(foldersProvider); + final availableFolderIds = foldersState.maybeWhen( + data: (folders) => folders.map((f) => f.id).toSet(), + orElse: () => {}, + ); + + // Conversations that reference a non-existent/unknown folder should not disappear. + // Treat those as regular until the folders list is available and contains the ID. + final regular = list.where((c) { + final hasFolder = (c.folderId != null && c.folderId!.isNotEmpty); + final folderKnown = hasFolder && availableFolderIds.contains(c.folderId); + return c.pinned != true && + c.archived != true && + (!hasFolder || !folderKnown); + }).toList(); + + final foldered = list.where((c) { + final hasFolder = (c.folderId != null && c.folderId!.isNotEmpty); + return c.pinned != true && + c.archived != true && + hasFolder && + availableFolderIds.contains(c.folderId); + }).toList(); + final archived = list.where((c) => c.archived == true).toList(); return Scrollbar( @@ -342,23 +351,30 @@ class _ChatsDrawerState extends ConsumerState { } final pinned = list.where((c) => c.pinned == true).toList(); - final regular = list - .where( - (c) => - c.pinned != true && - c.archived != true && - (c.folderId == null || c.folderId!.isEmpty), - ) - .toList(); - final foldered = list - .where( - (c) => - c.pinned != true && - c.archived != true && - c.folderId != null && - c.folderId!.isNotEmpty, - ) - .toList(); + + // For search results, apply the same folder safety logic + final foldersState = ref.watch(foldersProvider); + final availableFolderIds = foldersState.maybeWhen( + data: (folders) => folders.map((f) => f.id).toSet(), + orElse: () => {}, + ); + + final regular = list.where((c) { + final hasFolder = (c.folderId != null && c.folderId!.isNotEmpty); + final folderKnown = hasFolder && availableFolderIds.contains(c.folderId); + return c.pinned != true && + c.archived != true && + (!hasFolder || !folderKnown); + }).toList(); + + final foldered = list.where((c) { + final hasFolder = (c.folderId != null && c.folderId!.isNotEmpty); + return c.pinned != true && + c.archived != true && + hasFolder && + availableFolderIds.contains(c.folderId); + }).toList(); + final archived = list.where((c) => c.archived == true).toList(); return Scrollbar( diff --git a/vendor/open-webui b/vendor/open-webui new file mode 160000 index 0000000..2407d9b --- /dev/null +++ b/vendor/open-webui @@ -0,0 +1 @@ +Subproject commit 2407d9b905978d68619bdce4021e424046ec8df9