From 8cd99236905a4b300aa122e9a8263dea6ec45c44 Mon Sep 17 00:00:00 2001 From: Udhay-Adithya Date: Fri, 26 Sep 2025 23:49:17 +0530 Subject: [PATCH] feat: integrate chat state management for dynamic navigation in dashbot --- lib/dashbot/dashbot_dashboard.dart | 78 +++++++++++++++++++----------- lib/dashbot/dashbot_tab.dart | 69 +++++++++++++++++--------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/lib/dashbot/dashbot_dashboard.dart b/lib/dashbot/dashbot_dashboard.dart index e4a42228..f18b1579 100644 --- a/lib/dashbot/dashbot_dashboard.dart +++ b/lib/dashbot/dashbot_dashboard.dart @@ -9,6 +9,8 @@ import 'core/routes/dashbot_router.dart'; import 'core/routes/dashbot_routes.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +// Removed navigation persistence provider. +import 'features/chat/viewmodel/chat_viewmodel.dart'; class DashbotWindow extends ConsumerWidget { final VoidCallback onClose; @@ -24,6 +26,7 @@ class DashbotWindow extends ConsumerWidget { final windowNotifier = ref.read(dashbotWindowNotifierProvider.notifier); final settings = ref.watch(settingsProvider); final currentRequest = ref.watch(selectedRequestModelProvider); + final chatState = ref.watch(chatViewmodelProvider); // Close the overlay when the window is not popped anymore ref.listen( @@ -35,32 +38,43 @@ class DashbotWindow extends ConsumerWidget { }, ); - // Listen to changes in response status and navigate accordingly - ref.listen( - selectedRequestModelProvider - .select((request) => request?.httpResponseModel?.statusCode != null), - (prev, hasResponse) { - if (prev == hasResponse) return; + void _maybeNavigate() { + final req = ref.read(selectedRequestModelProvider); + final hasResponse = (req?.httpResponseModel?.statusCode != null) || + (req?.responseStatus != null); + final requestId = req?.id ?? 'global'; + final messages = chatState.chatSessions[requestId] ?? const []; + final isChatActive = messages.isNotEmpty; + final navigator = _dashbotNavigatorKey.currentState; + if (navigator == null) return; + final canPop = navigator.canPop(); - final currentRoute = - _dashbotNavigatorKey.currentState?.widget.initialRoute; - final canPop = _dashbotNavigatorKey.currentState?.canPop() ?? false; + final desired = isChatActive + ? DashbotRoutes.dashbotChat + : hasResponse + ? DashbotRoutes.dashbotHome + : DashbotRoutes.dashbotDefault; + bool isOn(String r) { + Route? top; + navigator.popUntil((route) { + top = route; + return true; + }); + return top?.settings.name == r; + } - if (hasResponse) { - // Response available - navigate to home if not already there - if (currentRoute == DashbotRoutes.dashbotDefault && !canPop) { - _dashbotNavigatorKey.currentState - ?.pushNamed(DashbotRoutes.dashbotHome); - } - } else { - // No response - navigate back to default if we're in home - if (canPop) { - _dashbotNavigatorKey.currentState - ?.popUntil((route) => route.isFirst); - } - } - }, - ); + if (isOn(desired)) return; + if (desired == DashbotRoutes.dashbotDefault && canPop) { + navigator.popUntil((route) => route.isFirst); + return; + } + if (desired != DashbotRoutes.dashbotDefault) { + navigator.pushNamed(desired); + } + } + + ref.listen(chatViewmodelProvider, (_, __) => _maybeNavigate()); + ref.listen(selectedRequestModelProvider, (_, __) => _maybeNavigate()); return Stack( children: [ @@ -174,11 +188,17 @@ class DashbotWindow extends ConsumerWidget { Expanded( child: Navigator( key: _dashbotNavigatorKey, - initialRoute: (currentRequest - ?.httpResponseModel?.statusCode != - null) - ? DashbotRoutes.dashbotHome - : DashbotRoutes.dashbotDefault, + initialRoute: (chatState + .chatSessions[ + (currentRequest?.id ?? 'global')] + ?.isNotEmpty ?? + false) + ? DashbotRoutes.dashbotChat + : (currentRequest + ?.httpResponseModel?.statusCode != + null) + ? DashbotRoutes.dashbotHome + : DashbotRoutes.dashbotDefault, onGenerateRoute: generateRoute, ), ), diff --git a/lib/dashbot/dashbot_tab.dart b/lib/dashbot/dashbot_tab.dart index d7e8b832..634af42c 100644 --- a/lib/dashbot/dashbot_tab.dart +++ b/lib/dashbot/dashbot_tab.dart @@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'core/providers/dashbot_window_notifier.dart'; import 'core/utils/show_dashbot.dart'; import 'package:apidash/consts.dart'; +import 'features/chat/viewmodel/chat_viewmodel.dart'; class DashbotTab extends ConsumerStatefulWidget { const DashbotTab({super.key}); @@ -26,31 +27,46 @@ class _DashbotTabState extends ConsumerState Widget build(BuildContext context) { super.build(context); final currentRequest = ref.watch(selectedRequestModelProvider); + final chatState = ref.watch(chatViewmodelProvider); - // Listen to changes in response status and navigate accordingly - ref.listen( - selectedRequestModelProvider.select((request) => - request?.httpResponseModel?.statusCode != null || - request?.responseStatus != null), - (prev, hasResponse) { - if (prev == hasResponse) return; + void maybeNavigate() { + final req = ref.read(selectedRequestModelProvider); + final hasResponse = (req?.httpResponseModel?.statusCode != null) || + (req?.responseStatus != null); + final requestId = req?.id ?? 'global'; + final messages = chatState.chatSessions[requestId] ?? const []; + final isChatActive = messages.isNotEmpty; + final navigator = _navKey.currentState; + if (navigator == null) return; + final canPop = navigator.canPop(); - final currentRoute = _navKey.currentState?.widget.initialRoute; - final canPop = _navKey.currentState?.canPop() ?? false; + final desired = isChatActive + ? DashbotRoutes.dashbotChat + : hasResponse + ? DashbotRoutes.dashbotHome + : DashbotRoutes.dashbotDefault; - if (hasResponse) { - // Response available - navigate to home if not already there - if (currentRoute == DashbotRoutes.dashbotDefault && !canPop) { - _navKey.currentState?.pushNamed(DashbotRoutes.dashbotHome); - } - } else { - // No response - navigate back to default if we're in home - if (canPop) { - _navKey.currentState?.popUntil((route) => route.isFirst); - } - } - }, - ); + bool isOn(String r) { + Route? top; + navigator.popUntil((route) { + top = route; + return true; + }); + return top?.settings.name == r; + } + + if (isOn(desired)) return; + if (desired == DashbotRoutes.dashbotDefault && canPop) { + navigator.popUntil((route) => route.isFirst); + return; + } + if (desired != DashbotRoutes.dashbotDefault) { + navigator.pushNamed(desired); + } + } + + ref.listen(chatViewmodelProvider, (_, __) => maybeNavigate()); + ref.listen(selectedRequestModelProvider, (_, __) => maybeNavigate()); return PopScope( canPop: true, @@ -119,8 +135,13 @@ class _DashbotTabState extends ConsumerState Expanded( child: Navigator( key: _navKey, - initialRoute: - (currentRequest?.httpResponseModel?.statusCode != null || + initialRoute: (chatState + .chatSessions[(currentRequest?.id ?? 'global')] + ?.isNotEmpty ?? + false) + ? DashbotRoutes.dashbotChat + : (currentRequest?.httpResponseModel?.statusCode != + null || currentRequest?.responseStatus != null) ? DashbotRoutes.dashbotHome : DashbotRoutes.dashbotDefault,