Files
voidea/flutter/lib/features/voice/screens/voice_sessions_screen.dart

90 lines
3.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import '../../../core/api/client.dart';
import '../../../core/api/endpoints.dart';
import '../../../models/voice.dart';
import '../../../widgets/loading_indicator.dart';
import '../../../widgets/empty_state.dart';
import '../../../core/theme/app_theme.dart';
class VoiceSessionsScreen extends ConsumerStatefulWidget {
const VoiceSessionsScreen({super.key});
@override
ConsumerState<VoiceSessionsScreen> createState() =>
_VoiceSessionsScreenState();
}
class _VoiceSessionsScreenState extends ConsumerState<VoiceSessionsScreen> {
List<VoiceSession> _sessions = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadSessions();
}
Future<void> _loadSessions() async {
setState(() => _isLoading = true);
try {
final api = ref.read(apiClientProvider);
final response = await api.get(Endpoints.voiceSessions);
final list = (response.data as List<dynamic>)
.map((e) => VoiceSession.fromJson(e as Map<String, dynamic>))
.toList();
if (mounted) setState(() => _sessions = list);
} catch (_) {}
if (mounted) setState(() => _isLoading = false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('История сессий')),
body: _isLoading
? const LoadingIndicator()
: _sessions.isEmpty
? const EmptyState(
icon: Icons.history,
title: 'Нет сессий',
subtitle: 'Начните голосовой ввод',
)
: RefreshIndicator(
onRefresh: _loadSessions,
child: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: _sessions.length,
itemBuilder: (_, i) {
final session = _sessions[i];
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
leading: CircleAvatar(
backgroundColor:
VoIdeaColors.primary.withOpacity(0.1),
child: const Icon(Icons.mic,
color: VoIdeaColors.primary),
),
title: Text(
session.title ?? 'Сессия ${i + 1}'),
subtitle: Text(
'${session.messageCount} сообщений · ${DateFormat('d MMM').format(session.createdAt)}',
style: const TextStyle(fontSize: 12),
),
trailing: Chip(
label: Text(
session.status,
style: const TextStyle(fontSize: 11),
),
),
),
);
},
),
),
);
}
}