import 'package:flutter/material.dart'; import '../api.dart'; import '../main.dart'; /// Read-only chat view. Sending a message is a WebSocket-only path on the /// backend (`chat:send`); wiring that up is a follow-up. class ChatScreen extends StatefulWidget { const ChatScreen({super.key, required this.kcId}); final String kcId; @override State createState() => _ChatScreenState(); } class _ChatScreenState extends State { Future>? _future; @override void didChangeDependencies() { super.didChangeDependencies(); _future ??= AppScope.of(context).api.channels(widget.kcId); } static const _typeLabels = { 'GEMEINDE_GRUPPE': 'Gemeinde-Gruppe', 'DIREKT': 'Direktnachricht', 'LT_UEBERGREIFEND': 'Leitungsteam', 'BROADCAST': 'Ankündigungen', }; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Chat')), body: FutureBuilder>( future: _future, builder: (context, snap) { if (snap.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center( child: Padding( padding: const EdgeInsets.all(24), child: Text('${snap.error}', textAlign: TextAlign.center), ), ); } final channels = snap.data!; if (channels.isEmpty) { return const Center(child: Text('Keine Kanäle sichtbar.')); } return ListView( children: [ for (final c in channels) ListTile( leading: const Icon(Icons.tag), title: Text(_typeLabels[c.type] ?? c.type), subtitle: Text(c.id), onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => _ChannelMessages( channelId: c.id, title: _typeLabels[c.type] ?? c.type, ), ), ), ), ], ); }, ), ); } } class _ChannelMessages extends StatefulWidget { const _ChannelMessages({required this.channelId, required this.title}); final String channelId; final String title; @override State<_ChannelMessages> createState() => _ChannelMessagesState(); } class _ChannelMessagesState extends State<_ChannelMessages> { Future>? _future; @override void didChangeDependencies() { super.didChangeDependencies(); _future ??= AppScope.of(context).api.messages(widget.channelId); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: FutureBuilder>( future: _future, builder: (context, snap) { if (snap.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center( child: Padding( padding: const EdgeInsets.all(24), child: Text('${snap.error}', textAlign: TextAlign.center), ), ); } final messages = snap.data!; if (messages.isEmpty) { return const Center(child: Text('Noch keine Nachrichten.')); } return ListView.builder( padding: const EdgeInsets.all(12), itemCount: messages.length, itemBuilder: (context, i) { final m = messages[i]; return Align( alignment: Alignment.centerLeft, child: Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(10), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(m.body), const SizedBox(height: 2), Text( m.createdAt, style: Theme.of(context).textTheme.labelSmall, ), ], ), ), ); }, ); }, ), bottomNavigationBar: const Padding( padding: EdgeInsets.all(12), child: Text( 'Senden folgt (WebSocket) — aktuell nur Lesen.', textAlign: TextAlign.center, style: TextStyle(fontSize: 12), ), ), ); } }