mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 10:49:49 +08:00
feat: create a dedicated provider for dashbot navigation
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import 'package:apidash/providers/providers.dart';
|
||||||
|
|
||||||
|
import '../routes/dashbot_routes.dart';
|
||||||
|
import '../utils/dashbot_route_utils.dart';
|
||||||
|
|
||||||
|
/// A Notifier that exposes the current Dashbot active route.
|
||||||
|
///
|
||||||
|
/// Behavior:
|
||||||
|
/// - Default state is computed from the currently selected request using
|
||||||
|
/// [computeDashbotBaseRoute].
|
||||||
|
/// - Automatically updates when the selected request changes, *unless* the
|
||||||
|
/// route has been manually set to Chat (Chat acts as a user override).
|
||||||
|
/// - Public method [goToChat] pins the route to Chat.
|
||||||
|
/// - Public method [resetToBaseRoute] recalculates from the current request
|
||||||
|
/// (used after clearing chat, etc.).
|
||||||
|
class DashbotActiveRouteNotifier extends Notifier<String> {
|
||||||
|
bool _chatPinned = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String build() {
|
||||||
|
// Watch current request for automatic base route computation.
|
||||||
|
final req = ref.watch(selectedRequestModelProvider);
|
||||||
|
ref.keepAlive();
|
||||||
|
|
||||||
|
// If chat is pinned we always stay on chat regardless of request changes.
|
||||||
|
if (_chatPinned) {
|
||||||
|
return DashbotRoutes.dashbotChat;
|
||||||
|
}
|
||||||
|
// Otherwise compute the base route from the current request.
|
||||||
|
return computeDashbotBaseRoute(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToChat() {
|
||||||
|
if (state == DashbotRoutes.dashbotChat) return;
|
||||||
|
_chatPinned = true;
|
||||||
|
state = DashbotRoutes.dashbotChat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetToBaseRoute() {
|
||||||
|
_chatPinned = false;
|
||||||
|
final req = ref.read(selectedRequestModelProvider);
|
||||||
|
final target = computeDashbotBaseRoute(req);
|
||||||
|
state = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Force set a specific route (used rarely; prefers semantic helpers).
|
||||||
|
void setRoute(String route) {
|
||||||
|
if (route == DashbotRoutes.dashbotChat) {
|
||||||
|
goToChat();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_chatPinned = false;
|
||||||
|
state = route;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final dashbotActiveRouteProvider =
|
||||||
|
NotifierProvider<DashbotActiveRouteNotifier, String>(
|
||||||
|
() => DashbotActiveRouteNotifier(),
|
||||||
|
name: 'dashbotActiveRouteProvider',
|
||||||
|
);
|
||||||
22
lib/dashbot/core/utils/dashbot_route_utils.dart
Normal file
22
lib/dashbot/core/utils/dashbot_route_utils.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:apidash/models/models.dart';
|
||||||
|
|
||||||
|
import '../routes/dashbot_routes.dart';
|
||||||
|
|
||||||
|
/// Computes the base Dashbot route for a given request based on whether a
|
||||||
|
/// response exists.
|
||||||
|
/// - Returns [DashbotRoutes.dashbotHome] if the request has a response (either
|
||||||
|
/// statusCode or responseStatus present).
|
||||||
|
/// - Otherwise returns [DashbotRoutes.dashbotDefault].
|
||||||
|
String computeDashbotBaseRoute(RequestModel? req) {
|
||||||
|
final hasResponse = (req?.httpResponseModel?.statusCode != null) ||
|
||||||
|
(req?.responseStatus != null);
|
||||||
|
return hasResponse ? DashbotRoutes.dashbotHome : DashbotRoutes.dashbotDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the route that should be shown for [req] differs from the
|
||||||
|
/// currently active [currentRoute].
|
||||||
|
/// This helper is pure and does not perform any side effects.
|
||||||
|
bool needsDashbotRouteChange(RequestModel? req, String currentRoute) {
|
||||||
|
final target = computeDashbotBaseRoute(req);
|
||||||
|
return target != currentRoute;
|
||||||
|
}
|
||||||
@@ -9,8 +9,7 @@ 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 'core/providers/dashbot_active_route_provider.dart';
|
||||||
import 'features/chat/viewmodel/chat_viewmodel.dart';
|
|
||||||
|
|
||||||
class DashbotWindow extends ConsumerWidget {
|
class DashbotWindow extends ConsumerWidget {
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
@@ -25,8 +24,7 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
final windowState = ref.watch(dashbotWindowNotifierProvider);
|
final windowState = ref.watch(dashbotWindowNotifierProvider);
|
||||||
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 activeRoute = ref.watch(dashbotActiveRouteProvider);
|
||||||
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(
|
||||||
@@ -38,43 +36,26 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
void _maybeNavigate() {
|
void navigateTo(String route) {
|
||||||
final req = ref.read(selectedRequestModelProvider);
|
final nav = _dashbotNavigatorKey.currentState;
|
||||||
final hasResponse = (req?.httpResponseModel?.statusCode != null) ||
|
if (nav == null) return;
|
||||||
(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 desired = isChatActive
|
|
||||||
? DashbotRoutes.dashbotChat
|
|
||||||
: hasResponse
|
|
||||||
? DashbotRoutes.dashbotHome
|
|
||||||
: DashbotRoutes.dashbotDefault;
|
|
||||||
bool isOn(String r) {
|
|
||||||
Route? top;
|
Route? top;
|
||||||
navigator.popUntil((route) {
|
nav.popUntil((r) {
|
||||||
top = route;
|
top = r;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return top?.settings.name == r;
|
if (top?.settings.name == route) return;
|
||||||
}
|
if (route == DashbotRoutes.dashbotDefault) {
|
||||||
|
nav.popUntil((r) => r.isFirst);
|
||||||
if (isOn(desired)) return;
|
} else {
|
||||||
if (desired == DashbotRoutes.dashbotDefault && canPop) {
|
nav.pushNamed(route);
|
||||||
navigator.popUntil((route) => route.isFirst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (desired != DashbotRoutes.dashbotDefault) {
|
|
||||||
navigator.pushNamed(desired);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.listen(chatViewmodelProvider, (_, __) => _maybeNavigate());
|
ref.listen<String>(dashbotActiveRouteProvider, (prev, next) {
|
||||||
ref.listen(selectedRequestModelProvider, (_, __) => _maybeNavigate());
|
if (prev == next || next.isEmpty) return;
|
||||||
|
navigateTo(next);
|
||||||
|
});
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@@ -188,17 +169,7 @@ class DashbotWindow extends ConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Navigator(
|
child: Navigator(
|
||||||
key: _dashbotNavigatorKey,
|
key: _dashbotNavigatorKey,
|
||||||
initialRoute: (chatState
|
initialRoute: activeRoute,
|
||||||
.chatSessions[
|
|
||||||
(currentRequest?.id ?? 'global')]
|
|
||||||
?.isNotEmpty ??
|
|
||||||
false)
|
|
||||||
? DashbotRoutes.dashbotChat
|
|
||||||
: (currentRequest
|
|
||||||
?.httpResponseModel?.statusCode !=
|
|
||||||
null)
|
|
||||||
? DashbotRoutes.dashbotHome
|
|
||||||
: DashbotRoutes.dashbotDefault,
|
|
||||||
onGenerateRoute: generateRoute,
|
onGenerateRoute: generateRoute,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'package:apidash/providers/providers.dart';
|
|
||||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||||
import 'core/routes/dashbot_router.dart';
|
import 'core/routes/dashbot_router.dart';
|
||||||
import 'core/routes/dashbot_routes.dart';
|
import 'core/routes/dashbot_routes.dart';
|
||||||
@@ -7,7 +6,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';
|
import 'core/providers/dashbot_active_route_provider.dart';
|
||||||
|
|
||||||
class DashbotTab extends ConsumerStatefulWidget {
|
class DashbotTab extends ConsumerStatefulWidget {
|
||||||
const DashbotTab({super.key});
|
const DashbotTab({super.key});
|
||||||
@@ -26,47 +25,31 @@ class _DashbotTabState extends ConsumerState<DashbotTab>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
final currentRequest = ref.watch(selectedRequestModelProvider);
|
final activeRoute = ref.watch(dashbotActiveRouteProvider);
|
||||||
final chatState = ref.watch(chatViewmodelProvider);
|
|
||||||
|
|
||||||
void maybeNavigate() {
|
void navigateTo(String route) {
|
||||||
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;
|
final navigator = _navKey.currentState;
|
||||||
if (navigator == null) return;
|
if (navigator == null) return;
|
||||||
final canPop = navigator.canPop();
|
// Determine current top
|
||||||
|
|
||||||
final desired = isChatActive
|
|
||||||
? DashbotRoutes.dashbotChat
|
|
||||||
: hasResponse
|
|
||||||
? DashbotRoutes.dashbotHome
|
|
||||||
: DashbotRoutes.dashbotDefault;
|
|
||||||
|
|
||||||
bool isOn(String r) {
|
|
||||||
Route? top;
|
Route? top;
|
||||||
navigator.popUntil((route) {
|
navigator.popUntil((r) {
|
||||||
top = route;
|
top = r;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return top?.settings.name == r;
|
final topName = top?.settings.name;
|
||||||
}
|
if (topName == route) return; // already there
|
||||||
|
if (route == DashbotRoutes.dashbotDefault) {
|
||||||
if (isOn(desired)) return;
|
navigator.popUntil((r) => r.isFirst);
|
||||||
if (desired == DashbotRoutes.dashbotDefault && canPop) {
|
} else {
|
||||||
navigator.popUntil((route) => route.isFirst);
|
navigator.pushNamed(route);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (desired != DashbotRoutes.dashbotDefault) {
|
|
||||||
navigator.pushNamed(desired);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.listen(chatViewmodelProvider, (_, __) => maybeNavigate());
|
// React to route provider changes.
|
||||||
ref.listen(selectedRequestModelProvider, (_, __) => maybeNavigate());
|
ref.listen<String>(dashbotActiveRouteProvider, (prev, next) {
|
||||||
|
if (prev == next || next.isEmpty) return;
|
||||||
|
navigateTo(next);
|
||||||
|
});
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: true,
|
canPop: true,
|
||||||
@@ -135,16 +118,7 @@ class _DashbotTabState extends ConsumerState<DashbotTab>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Navigator(
|
child: Navigator(
|
||||||
key: _navKey,
|
key: _navKey,
|
||||||
initialRoute: (chatState
|
initialRoute: activeRoute,
|
||||||
.chatSessions[(currentRequest?.id ?? 'global')]
|
|
||||||
?.isNotEmpty ??
|
|
||||||
false)
|
|
||||||
? DashbotRoutes.dashbotChat
|
|
||||||
: (currentRequest?.httpResponseModel?.statusCode !=
|
|
||||||
null ||
|
|
||||||
currentRequest?.responseStatus != null)
|
|
||||||
? DashbotRoutes.dashbotHome
|
|
||||||
: DashbotRoutes.dashbotDefault,
|
|
||||||
onGenerateRoute: generateRoute,
|
onGenerateRoute: generateRoute,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:apidash/dashbot/features/chat/view/widgets/dashbot_task_buttons.dart';
|
import 'package:apidash/dashbot/features/chat/view/widgets/dashbot_task_buttons.dart';
|
||||||
|
import 'package:apidash/providers/providers.dart';
|
||||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||||
|
|
||||||
import '../../../../core/constants/constants.dart';
|
import '../../../../core/constants/constants.dart';
|
||||||
@@ -66,6 +67,7 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
|||||||
_scrollToBottom();
|
_scrollToBottom();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ref.watch(selectedRequestModelProvider.select((value) => value?.id));
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Column(
|
body: Column(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import '../models/chat_action.dart';
|
|||||||
import '../models/chat_state.dart';
|
import '../models/chat_state.dart';
|
||||||
import '../repository/chat_remote_repository.dart';
|
import '../repository/chat_remote_repository.dart';
|
||||||
import '../providers/service_providers.dart';
|
import '../providers/service_providers.dart';
|
||||||
|
import '../../../core/providers/dashbot_active_route_provider.dart';
|
||||||
|
|
||||||
class ChatViewmodel extends StateNotifier<ChatState> {
|
class ChatViewmodel extends StateNotifier<ChatState> {
|
||||||
ChatViewmodel(this._ref) : super(const ChatState());
|
ChatViewmodel(this._ref) : super(const ChatState());
|
||||||
@@ -270,6 +271,8 @@ class ChatViewmodel extends StateNotifier<ChatState> {
|
|||||||
isGenerating: false,
|
isGenerating: false,
|
||||||
currentStreamingResponse: '',
|
currentStreamingResponse: '',
|
||||||
);
|
);
|
||||||
|
// Reset to base route (unpins chat) after clearing messages.
|
||||||
|
_ref.read(dashbotActiveRouteProvider.notifier).resetToBaseRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sendTaskMessage(ChatMessageType type) async {
|
Future<void> sendTaskMessage(ChatMessageType type) async {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import '../../../../core/utils/dashbot_icons.dart';
|
|||||||
import '../../../../core/providers/dashbot_window_notifier.dart';
|
import '../../../../core/providers/dashbot_window_notifier.dart';
|
||||||
|
|
||||||
import '../../../../core/routes/dashbot_routes.dart';
|
import '../../../../core/routes/dashbot_routes.dart';
|
||||||
|
import '../../../../core/providers/dashbot_active_route_provider.dart';
|
||||||
import 'package:apidash_design_system/tokens/measurements.dart';
|
import 'package:apidash_design_system/tokens/measurements.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';
|
||||||
@@ -46,15 +47,15 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "🤖 Chat with Dashbot",
|
label: "🤖 Chat with Dashbot",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pushNamed(
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
DashbotRoutes.dashbotChat,
|
Navigator.of(context).pushNamed(DashbotRoutes.dashbotChat);
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "🔎 Explain me this response",
|
label: "🔎 Explain me this response",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.explainResponse,
|
arguments: ChatMessageType.explainResponse,
|
||||||
@@ -64,6 +65,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "🐞 Help me debug this error",
|
label: "🐞 Help me debug this error",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.debugError,
|
arguments: ChatMessageType.debugError,
|
||||||
@@ -73,6 +75,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "📄 Generate documentation",
|
label: "📄 Generate documentation",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.generateDoc,
|
arguments: ChatMessageType.generateDoc,
|
||||||
@@ -82,6 +85,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "📝 Generate Tests",
|
label: "📝 Generate Tests",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.generateTest,
|
arguments: ChatMessageType.generateTest,
|
||||||
@@ -91,6 +95,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "🧩 Generate Code",
|
label: "🧩 Generate Code",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.generateCode,
|
arguments: ChatMessageType.generateCode,
|
||||||
@@ -100,6 +105,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "📥 Import cURL",
|
label: "📥 Import cURL",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.importCurl,
|
arguments: ChatMessageType.importCurl,
|
||||||
@@ -109,6 +115,7 @@ class _DashbotHomePageState extends ConsumerState<DashbotHomePage> {
|
|||||||
HomeScreenTaskButton(
|
HomeScreenTaskButton(
|
||||||
label: "📄 Import OpenAPI",
|
label: "📄 Import OpenAPI",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.read(dashbotActiveRouteProvider.notifier).goToChat();
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
DashbotRoutes.dashbotChat,
|
DashbotRoutes.dashbotChat,
|
||||||
arguments: ChatMessageType.importOpenApi,
|
arguments: ChatMessageType.importOpenApi,
|
||||||
|
|||||||
Reference in New Issue
Block a user