import 'dart:async'; import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; class RoomPage extends StatefulWidget { const RoomPage({super.key, required this.room}); final Room room; @override State createState() => _RoomPageState(); } class _RoomPageState extends State { Timeline? timeline; final chatController = TextEditingController(); StreamSubscription? updateListener; void updateTimeline() async { final newTimeline = await widget.room.getTimeline(eventContextId: widget.room.fullyRead); setState(() { timeline = newTimeline; }); } @override void initState() { super.initState(); updateTimeline(); updateListener = widget.room.onUpdate.stream.listen((event) { updateTimeline(); }); } void setAvatar() async { final participants = widget.room.getParticipants(); final picked = await FilePicker.platform.pickFiles(type: FileType.image); if (picked == null) return; final file = File(picked.files.single.path!); final bytes = await file.readAsBytes(); final uri = await widget.room.client.uploadContent(bytes); await widget.room.client.setAvatarUrl(participants[0].id, uri); } @override void dispose() { super.dispose(); updateListener?.cancel(); } void sendMessage() {} List? get messages => timeline?.events .where((element) => element.type == EventTypes.Message) .toList(); List getChildren() { if (timeline == null) return [const CircularProgressIndicator()]; return [ Expanded( child: ListView.builder( itemCount: messages?.length, reverse: true, itemBuilder: (context, index) => ListTile( title: Text(messages![index] .senderFromMemoryOrFallback .displayName .toString()), subtitle: Text(messages![index].body), leading: messages![index].senderFromMemoryOrFallback.avatarUrl != null ? CircleAvatar( foregroundImage: NetworkImage(messages![index] .senderFromMemoryOrFallback .avatarUrl! .getThumbnail(widget.room.client, width: 50, height: 50) .toString())) : null, )), ), TextFormField( controller: chatController, decoration: const InputDecoration(hintText: 'Message'), onFieldSubmitted: (value) async { print("Sending text event $value to room ${widget.room.id}..."); await widget.room.sendTextEvent(value); chatController.text = ''; }, ), ]; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.room.getLocalizedDisplayname()), actions: [ IconButton(onPressed: setAvatar, icon: const Icon(Icons.image)) ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: getChildren(), )), floatingActionButton: FloatingActionButton( onPressed: sendMessage, tooltip: 'Send message', child: const Icon(Icons.send), ), ); } }