Zenith/lib/room.dart

120 lines
3.5 KiB
Dart
Raw Normal View History

2023-12-28 22:31:18 +00:00
import 'dart:async';
2023-12-29 23:41:40 +00:00
import 'dart:io';
2023-12-28 22:31:18 +00:00
2023-12-29 23:41:40 +00:00
import 'package:file_picker/file_picker.dart';
2023-12-28 21:40:09 +00:00
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<RoomPage> createState() => _RoomPageState();
}
class _RoomPageState extends State<RoomPage> {
Timeline? timeline;
2023-12-28 22:31:18 +00:00
final chatController = TextEditingController();
StreamSubscription? updateListener;
2023-12-28 21:40:09 +00:00
void updateTimeline() async {
2023-12-28 22:31:18 +00:00
final newTimeline =
await widget.room.getTimeline(eventContextId: widget.room.fullyRead);
2023-12-28 21:40:09 +00:00
setState(() {
timeline = newTimeline;
});
}
@override
void initState() {
super.initState();
updateTimeline();
2023-12-28 22:31:18 +00:00
updateListener = widget.room.onUpdate.stream.listen((event) {
2023-12-28 21:40:09 +00:00
updateTimeline();
});
}
2023-12-29 23:41:40 +00:00
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);
}
2023-12-28 21:40:09 +00:00
@override
void dispose() {
super.dispose();
2023-12-28 22:31:18 +00:00
updateListener?.cancel();
2023-12-28 21:40:09 +00:00
}
void sendMessage() {}
2023-12-29 04:19:40 +00:00
List<Event>? get messages => timeline?.events
.where((element) => element.type == EventTypes.Message)
.toList();
2023-12-28 22:31:18 +00:00
List<Widget> getChildren() {
if (timeline == null) return [const CircularProgressIndicator()];
return [
Expanded(
child: ListView.builder(
2023-12-29 04:19:40 +00:00
itemCount: messages?.length,
2023-12-28 22:31:18 +00:00
reverse: true,
itemBuilder: (context, index) => ListTile(
2023-12-29 04:19:40 +00:00
title: Text(messages![index]
.senderFromMemoryOrFallback
.displayName
2023-12-29 04:10:47 +00:00
.toString()),
2023-12-29 04:19:40 +00:00
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,
2023-12-28 22:31:18 +00:00
)),
),
TextFormField(
controller: chatController,
2023-12-29 23:47:48 +00:00
textInputAction: TextInputAction.send,
2023-12-28 22:31:18 +00:00
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 = '';
},
),
];
}
2023-12-28 21:40:09 +00:00
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
2023-12-29 23:47:48 +00:00
title: Text(widget.room
.getLocalizedDisplayname()
.replaceFirst(RegExp("Group with "), "")),
2023-12-29 23:41:40 +00:00
actions: [
IconButton(onPressed: setAvatar, icon: const Icon(Icons.image))
],
2023-12-28 21:40:09 +00:00
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
2023-12-28 22:31:18 +00:00
children: getChildren(),
2023-12-28 21:40:09 +00:00
)),
);
}
}