mirror of
https://github.com/Dvorinka/1356.git
synced 2026-06-05 04:22:55 +00:00
small fix, don't worry about it
This commit is contained in:
@@ -27,7 +27,7 @@ class AIChatState {
|
||||
this.isRecording = false,
|
||||
this.error,
|
||||
this.currentTranscription,
|
||||
this.privacyModeEnabled = true,
|
||||
this.privacyModeEnabled = false,
|
||||
});
|
||||
|
||||
AIChatState copyWith({
|
||||
@@ -153,6 +153,13 @@ class AIChatController extends StateNotifier<AIChatState> {
|
||||
buffer.writeln(
|
||||
'User privacy mode is DISABLED. Use the following personal context to personalise your coaching:');
|
||||
buffer.writeln('Username: ${user.username}.');
|
||||
|
||||
if (user.heightCm != null) {
|
||||
buffer.writeln('Height: ${user.heightCm!.toStringAsFixed(1)} cm.');
|
||||
}
|
||||
if (user.weightKg != null) {
|
||||
buffer.writeln('Weight: ${user.weightKg!.toStringAsFixed(1)} kg.');
|
||||
}
|
||||
|
||||
if (countdownSummary != null) {
|
||||
buffer.writeln(countdownSummary);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import '../application/ai_chat_controller.dart';
|
||||
|
||||
class AIChatScreen extends ConsumerStatefulWidget {
|
||||
@@ -64,7 +65,7 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
Expanded(
|
||||
child: state.messages.isEmpty
|
||||
? _buildEmptyState(context)
|
||||
: _buildMessagesList(state.messages),
|
||||
: _buildMessagesList(state.messages, state.isLoading),
|
||||
),
|
||||
|
||||
// Error message
|
||||
@@ -87,7 +88,7 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface
|
||||
.withValues(alpha:0.7),
|
||||
.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -128,7 +129,7 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
Text(
|
||||
'Ask for goal inspiration, motivation, or life advice',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha:0.7),
|
||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -174,12 +175,16 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMessagesList(List messages) {
|
||||
Widget _buildMessagesList(List messages, bool isLoading) {
|
||||
return ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: messages.length,
|
||||
itemCount: messages.length + (isLoading ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (index == messages.length && isLoading) {
|
||||
return _buildLoadingIndicator();
|
||||
}
|
||||
|
||||
final message = messages[index];
|
||||
final isUser = message.role == 'user';
|
||||
|
||||
@@ -218,14 +223,29 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
message.content,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: isUser
|
||||
? Theme.of(context).colorScheme.onPrimary
|
||||
: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
child: isUser
|
||||
? Text(
|
||||
message.content,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
)
|
||||
: MarkdownBody(
|
||||
data: message.content,
|
||||
styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
|
||||
p: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
code: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
codeblockDecoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isUser) ...[
|
||||
@@ -245,6 +265,59 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLoadingIndicator() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 16,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
child: Icon(
|
||||
Icons.psychology,
|
||||
size: 20,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * 0.75,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'AI is thinking...',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildErrorMessage(String error, controller) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(16),
|
||||
@@ -317,7 +390,7 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).shadowColor.withValues(alpha:0.1),
|
||||
color: Theme.of(context).shadowColor.withValues(alpha: 0.1),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
@@ -362,8 +435,8 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: state.isRecording
|
||||
? Theme.of(context).colorScheme.error.withValues(alpha:0.12)
|
||||
: Theme.of(context).colorScheme.primary.withValues(alpha:0.08),
|
||||
? Theme.of(context).colorScheme.error.withValues(alpha: 0.12)
|
||||
: Theme.of(context).colorScheme.primary.withValues(alpha: 0.08),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: state.isRecording
|
||||
@@ -429,7 +502,7 @@ class _AIChatScreenState extends ConsumerState<AIChatScreen> {
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
.withValues(alpha:state.isLoading ||
|
||||
.withValues(alpha: state.isLoading ||
|
||||
_textController.text.trim().isEmpty
|
||||
? 0.06
|
||||
: 0.12),
|
||||
|
||||
Reference in New Issue
Block a user