imprroved
This commit is contained in:
parent
e2fc81ba0e
commit
2aa6d13a71
@ -582,7 +582,6 @@ Widget build(BuildContext context) {
|
||||
children: [
|
||||
_quickActions(),
|
||||
MySpacing.height(20),
|
||||
_sectionTitle('Modules'),
|
||||
_dashboardModules(),
|
||||
MySpacing.height(20),
|
||||
_sectionTitle('Reports & Analytics'),
|
||||
|
||||
@ -56,6 +56,13 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
parent: _animController,
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
|
||||
// Add initial welcome message
|
||||
_chatHistory.add({
|
||||
'sender': 'ai',
|
||||
'message':
|
||||
'Hello! I am your AI assistant. How can I help you today? You can ask general questions or use the chart button below to analyze your monthly expenses.',
|
||||
});
|
||||
}
|
||||
|
||||
// Scroll helper
|
||||
@ -152,6 +159,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
final placeholderIndex = _chatHistory.length - 1;
|
||||
|
||||
try {
|
||||
// NOTE: Assuming GeminiService.generateText handles the API call
|
||||
final result = await GeminiService.generateText(promptText);
|
||||
if (placeholderIndex >= 0 &&
|
||||
_chatHistory.length > placeholderIndex) {
|
||||
@ -191,11 +199,16 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
|
||||
try {
|
||||
await widget.dashboardController.fetchMonthlyExpenses();
|
||||
// NOTE: Assuming monthlyExpenseList contains a list of objects that have a .toJson() method
|
||||
final rawDataList = widget.dashboardController.monthlyExpenseList;
|
||||
|
||||
if (rawDataList.isEmpty) {
|
||||
_error.value = "No monthly expense data found for analysis.";
|
||||
_chatHistory.removeAt(placeholderIndex);
|
||||
if (placeholderIndex >= 0 &&
|
||||
_chatHistory.length > placeholderIndex) {
|
||||
_chatHistory.removeAt(placeholderIndex);
|
||||
}
|
||||
_isAnalyzingData.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -435,7 +448,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
),
|
||||
onSubmitted: (_) =>
|
||||
_handlePromptSubmission(),
|
||||
enabled: !_isAnalyzingData.value,
|
||||
enabled: !_isAnalyzingData.value && !_isLoading.value,
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
@ -449,7 +462,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
.isEmpty)
|
||||
? null
|
||||
: _handlePromptSubmission,
|
||||
icon: _isLoading.value
|
||||
icon: _isLoading.value && _promptController.text.trim().isNotEmpty // Show loading only for text submission
|
||||
? SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
@ -493,17 +506,21 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
onPressed: _toggleOpen,
|
||||
heroTag: 'gemini_fab',
|
||||
backgroundColor: contentTheme.primary,
|
||||
icon: const Icon(LucideIcons.bot),
|
||||
icon: const Icon(LucideIcons.bot, color: Colors.white),
|
||||
label: const Text(
|
||||
'Ask Me Anything',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Dim background when open
|
||||
// Dim background when open - Full screen scrim
|
||||
Widget _buildScrim() {
|
||||
return Obx(
|
||||
() => _isOpen.value
|
||||
@ -511,8 +528,11 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
opacity: _opacityAnimation,
|
||||
child: GestureDetector(
|
||||
onTap: _toggleOpen,
|
||||
child: Container(
|
||||
color: Colors.black.withOpacity(0.25),
|
||||
// Use Positioned.fill to guarantee it covers the entire Stack
|
||||
child: const Positioned.fill(
|
||||
child: ColoredBox(
|
||||
color: Colors.black38, // Use Colors.black38 for 38% opacity, slightly stronger than 0.25
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -522,19 +542,25 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
// Scrim behind panel
|
||||
_buildScrim(),
|
||||
// Panel
|
||||
_buildFloatingPanel(context),
|
||||
// FAB
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: _buildFab(),
|
||||
),
|
||||
],
|
||||
// Wrap the Stack in SizedBox.expand to force the widget to take the full space
|
||||
// of its parent, which is typically the whole screen area in a dashboard.
|
||||
return SizedBox.expand(
|
||||
child: Stack(
|
||||
children: [
|
||||
// 1. Scrim (Background layer when open) - Now using Positioned.fill for reliability
|
||||
_buildScrim(),
|
||||
|
||||
// 2. Panel (Middle layer when open)
|
||||
_buildFloatingPanel(context),
|
||||
|
||||
// 3. FAB (Top layer when closed)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: _buildFab(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -545,4 +571,4 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
|
||||
_animController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user