Initial commit
This commit is contained in:
109
lib/presentation/chat/chat_controller.dart
Normal file
109
lib/presentation/chat/chat_controller.dart
Normal file
@@ -0,0 +1,109 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:trainhub_flutter/injection.dart';
|
||||
import 'package:trainhub_flutter/domain/repositories/chat_repository.dart';
|
||||
import 'package:trainhub_flutter/presentation/chat/chat_state.dart';
|
||||
|
||||
part 'chat_controller.g.dart';
|
||||
|
||||
@riverpod
|
||||
class ChatController extends _$ChatController {
|
||||
late final ChatRepository _repo;
|
||||
|
||||
@override
|
||||
Future<ChatState> build() async {
|
||||
_repo = getIt<ChatRepository>();
|
||||
final sessions = await _repo.getAllSessions();
|
||||
return ChatState(sessions: sessions);
|
||||
}
|
||||
|
||||
Future<void> createSession() async {
|
||||
final session = await _repo.createSession();
|
||||
final sessions = await _repo.getAllSessions();
|
||||
state = AsyncValue.data(
|
||||
ChatState(sessions: sessions, activeSession: session),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> loadSession(String id) async {
|
||||
final session = await _repo.getSession(id);
|
||||
if (session == null) return;
|
||||
final messages = await _repo.getMessages(id);
|
||||
final current = state.valueOrNull ?? const ChatState();
|
||||
state = AsyncValue.data(
|
||||
current.copyWith(activeSession: session, messages: messages),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteSession(String id) async {
|
||||
await _repo.deleteSession(id);
|
||||
final sessions = await _repo.getAllSessions();
|
||||
final current = state.valueOrNull ?? const ChatState();
|
||||
state = AsyncValue.data(
|
||||
current.copyWith(
|
||||
sessions: sessions,
|
||||
activeSession:
|
||||
current.activeSession?.id == id ? null : current.activeSession,
|
||||
messages: current.activeSession?.id == id ? [] : current.messages,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
final current = state.valueOrNull;
|
||||
if (current == null) return;
|
||||
String sessionId;
|
||||
if (current.activeSession == null) {
|
||||
final session = await _repo.createSession();
|
||||
sessionId = session.id;
|
||||
final sessions = await _repo.getAllSessions();
|
||||
state = AsyncValue.data(
|
||||
current.copyWith(sessions: sessions, activeSession: session),
|
||||
);
|
||||
} else {
|
||||
sessionId = current.activeSession!.id;
|
||||
}
|
||||
await _repo.addMessage(
|
||||
sessionId: sessionId,
|
||||
role: 'user',
|
||||
content: content,
|
||||
);
|
||||
final messagesAfterUser = await _repo.getMessages(sessionId);
|
||||
state = AsyncValue.data(
|
||||
state.valueOrNull!.copyWith(messages: messagesAfterUser, isTyping: true),
|
||||
);
|
||||
await Future<void>.delayed(const Duration(seconds: 1));
|
||||
final String response = _getMockResponse(content);
|
||||
await _repo.addMessage(
|
||||
sessionId: sessionId,
|
||||
role: 'assistant',
|
||||
content: response,
|
||||
);
|
||||
final messagesAfterAi = await _repo.getMessages(sessionId);
|
||||
if (messagesAfterAi.length <= 2) {
|
||||
final title = content.length > 30
|
||||
? '${content.substring(0, 30)}...'
|
||||
: content;
|
||||
await _repo.updateSessionTitle(sessionId, title);
|
||||
}
|
||||
final sessions = await _repo.getAllSessions();
|
||||
state = AsyncValue.data(
|
||||
state.valueOrNull!.copyWith(
|
||||
messages: messagesAfterAi,
|
||||
isTyping: false,
|
||||
sessions: sessions,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _getMockResponse(String input) {
|
||||
final String lower = input.toLowerCase();
|
||||
if (lower.contains('plan') || lower.contains('program')) {
|
||||
return "I can help you design a training plan! What are your goals? Strength, hypertrophy, or endurance?";
|
||||
} else if (lower.contains('squat') || lower.contains('bench')) {
|
||||
return "Compound movements are great. Remember to maintain proper form. For squats, keep your chest up and knees tracking over toes.";
|
||||
} else if (lower.contains('nutrition') || lower.contains('eat')) {
|
||||
return "Nutrition is key. Aim for 1.6-2.2g of protein per kg of bodyweight if you're training hard.";
|
||||
}
|
||||
return "I'm your AI training assistant. How can I help you today?";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user