mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
feat: integrate chat state management for dynamic navigation in dashbot
This commit is contained in:
@@ -9,6 +9,8 @@ import 'core/routes/dashbot_router.dart';
|
|||||||
import 'core/routes/dashbot_routes.dart';
|
import 'core/routes/dashbot_routes.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
// Removed navigation persistence provider.
|
||||||
|
import 'features/chat/viewmodel/chat_viewmodel.dart';
|
||||||
|
|
||||||
class DashbotWindow extends ConsumerWidget {
|
class DashbotWindow extends ConsumerWidget {
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
@@ -24,6 +26,7 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
final windowNotifier = ref.read(dashbotWindowNotifierProvider.notifier);
|
final windowNotifier = ref.read(dashbotWindowNotifierProvider.notifier);
|
||||||
final settings = ref.watch(settingsProvider);
|
final settings = ref.watch(settingsProvider);
|
||||||
final currentRequest = ref.watch(selectedRequestModelProvider);
|
final currentRequest = ref.watch(selectedRequestModelProvider);
|
||||||
|
final chatState = ref.watch(chatViewmodelProvider);
|
||||||
|
|
||||||
// Close the overlay when the window is not popped anymore
|
// Close the overlay when the window is not popped anymore
|
||||||
ref.listen(
|
ref.listen(
|
||||||
@@ -35,32 +38,43 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Listen to changes in response status and navigate accordingly
|
void _maybeNavigate() {
|
||||||
ref.listen(
|
final req = ref.read(selectedRequestModelProvider);
|
||||||
selectedRequestModelProvider
|
final hasResponse = (req?.httpResponseModel?.statusCode != null) ||
|
||||||
.select((request) => request?.httpResponseModel?.statusCode != null),
|
(req?.responseStatus != null);
|
||||||
(prev, hasResponse) {
|
final requestId = req?.id ?? 'global';
|
||||||
if (prev == hasResponse) return;
|
final messages = chatState.chatSessions[requestId] ?? const [];
|
||||||
|
final isChatActive = messages.isNotEmpty;
|
||||||
|
final navigator = _dashbotNavigatorKey.currentState;
|
||||||
|
if (navigator == null) return;
|
||||||
|
final canPop = navigator.canPop();
|
||||||
|
|
||||||
final currentRoute =
|
final desired = isChatActive
|
||||||
_dashbotNavigatorKey.currentState?.widget.initialRoute;
|
? DashbotRoutes.dashbotChat
|
||||||
final canPop = _dashbotNavigatorKey.currentState?.canPop() ?? false;
|
: 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) {
|
if (isOn(desired)) return;
|
||||||
// Response available - navigate to home if not already there
|
if (desired == DashbotRoutes.dashbotDefault && canPop) {
|
||||||
if (currentRoute == DashbotRoutes.dashbotDefault && !canPop) {
|
navigator.popUntil((route) => route.isFirst);
|
||||||
_dashbotNavigatorKey.currentState
|
return;
|
||||||
?.pushNamed(DashbotRoutes.dashbotHome);
|
}
|
||||||
}
|
if (desired != DashbotRoutes.dashbotDefault) {
|
||||||
} else {
|
navigator.pushNamed(desired);
|
||||||
// No response - navigate back to default if we're in home
|
}
|
||||||
if (canPop) {
|
}
|
||||||
_dashbotNavigatorKey.currentState
|
|
||||||
?.popUntil((route) => route.isFirst);
|
ref.listen(chatViewmodelProvider, (_, __) => _maybeNavigate());
|
||||||
}
|
ref.listen(selectedRequestModelProvider, (_, __) => _maybeNavigate());
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@@ -174,11 +188,17 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Navigator(
|
child: Navigator(
|
||||||
key: _dashbotNavigatorKey,
|
key: _dashbotNavigatorKey,
|
||||||
initialRoute: (currentRequest
|
initialRoute: (chatState
|
||||||
?.httpResponseModel?.statusCode !=
|
.chatSessions[
|
||||||
null)
|
(currentRequest?.id ?? 'global')]
|
||||||
? DashbotRoutes.dashbotHome
|
?.isNotEmpty ??
|
||||||
: DashbotRoutes.dashbotDefault,
|
false)
|
||||||
|
? DashbotRoutes.dashbotChat
|
||||||
|
: (currentRequest
|
||||||
|
?.httpResponseModel?.statusCode !=
|
||||||
|
null)
|
||||||
|
? DashbotRoutes.dashbotHome
|
||||||
|
: DashbotRoutes.dashbotDefault,
|
||||||
onGenerateRoute: generateRoute,
|
onGenerateRoute: generateRoute,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'core/providers/dashbot_window_notifier.dart';
|
import 'core/providers/dashbot_window_notifier.dart';
|
||||||
import 'core/utils/show_dashbot.dart';
|
import 'core/utils/show_dashbot.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
import 'features/chat/viewmodel/chat_viewmodel.dart';
|
||||||
|
|
||||||
class DashbotTab extends ConsumerStatefulWidget {
|
class DashbotTab extends ConsumerStatefulWidget {
|
||||||
const DashbotTab({super.key});
|
const DashbotTab({super.key});
|
||||||
@@ -26,31 +27,46 @@ class _DashbotTabState extends ConsumerState<DashbotTab>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
final currentRequest = ref.watch(selectedRequestModelProvider);
|
final currentRequest = ref.watch(selectedRequestModelProvider);
|
||||||
|
final chatState = ref.watch(chatViewmodelProvider);
|
||||||
|
|
||||||
// Listen to changes in response status and navigate accordingly
|
void maybeNavigate() {
|
||||||
ref.listen(
|
final req = ref.read(selectedRequestModelProvider);
|
||||||
selectedRequestModelProvider.select((request) =>
|
final hasResponse = (req?.httpResponseModel?.statusCode != null) ||
|
||||||
request?.httpResponseModel?.statusCode != null ||
|
(req?.responseStatus != null);
|
||||||
request?.responseStatus != null),
|
final requestId = req?.id ?? 'global';
|
||||||
(prev, hasResponse) {
|
final messages = chatState.chatSessions[requestId] ?? const [];
|
||||||
if (prev == hasResponse) return;
|
final isChatActive = messages.isNotEmpty;
|
||||||
|
final navigator = _navKey.currentState;
|
||||||
|
if (navigator == null) return;
|
||||||
|
final canPop = navigator.canPop();
|
||||||
|
|
||||||
final currentRoute = _navKey.currentState?.widget.initialRoute;
|
final desired = isChatActive
|
||||||
final canPop = _navKey.currentState?.canPop() ?? false;
|
? DashbotRoutes.dashbotChat
|
||||||
|
: hasResponse
|
||||||
|
? DashbotRoutes.dashbotHome
|
||||||
|
: DashbotRoutes.dashbotDefault;
|
||||||
|
|
||||||
if (hasResponse) {
|
bool isOn(String r) {
|
||||||
// Response available - navigate to home if not already there
|
Route? top;
|
||||||
if (currentRoute == DashbotRoutes.dashbotDefault && !canPop) {
|
navigator.popUntil((route) {
|
||||||
_navKey.currentState?.pushNamed(DashbotRoutes.dashbotHome);
|
top = route;
|
||||||
}
|
return true;
|
||||||
} else {
|
});
|
||||||
// No response - navigate back to default if we're in home
|
return top?.settings.name == r;
|
||||||
if (canPop) {
|
}
|
||||||
_navKey.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 PopScope(
|
return PopScope(
|
||||||
canPop: true,
|
canPop: true,
|
||||||
@@ -119,8 +135,13 @@ class _DashbotTabState extends ConsumerState<DashbotTab>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Navigator(
|
child: Navigator(
|
||||||
key: _navKey,
|
key: _navKey,
|
||||||
initialRoute:
|
initialRoute: (chatState
|
||||||
(currentRequest?.httpResponseModel?.statusCode != null ||
|
.chatSessions[(currentRequest?.id ?? 'global')]
|
||||||
|
?.isNotEmpty ??
|
||||||
|
false)
|
||||||
|
? DashbotRoutes.dashbotChat
|
||||||
|
: (currentRequest?.httpResponseModel?.statusCode !=
|
||||||
|
null ||
|
||||||
currentRequest?.responseStatus != null)
|
currentRequest?.responseStatus != null)
|
||||||
? DashbotRoutes.dashbotHome
|
? DashbotRoutes.dashbotHome
|
||||||
: DashbotRoutes.dashbotDefault,
|
: DashbotRoutes.dashbotDefault,
|
||||||
|
|||||||
Reference in New Issue
Block a user