Files
stadtbote-app/lib/content_views/messages_page.dart
T
2024-08-08 09:58:41 +02:00

200 lines
6.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:isar/isar.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/message.dart' as sbmessage;
import 'package:stadtbote/model/message.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/message_service.dart';
import 'package:stadtbote/tools/messages/publish_payload_message.dart';
import '../tools/util.dart';
class MessagesPage extends ContentViewWidget {
const MessagesPage({super.key});
@override
State<MessagesPage> createState() => _MessagesPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Nachrichten',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
rightButtonEnabled: true,
rightButtonVisible: true,
rightButtonImage: Util.fetchFutureIcon(const Icon(Icons.help_outline, size: 20.0, color: Colors.white)),
rightButtonOnPressed: () async {
await Util.startBrowser('https://app.assecutor.de/help/sb/app/context/003/index.html');
});
}
}
class _MessagesPageState extends State<MessagesPage> {
bool _initCompleted = false;
late String _sid;
late final List<types.Message> _messages = [];
final _user = const types.User(
id: '82091008-a484-4a89-ae75-a22bf8d6f3ac',
);
final _central = const types.User(
id: '82091008-a484-4a89-ae75-a22bf8d6f3ad',
);
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 0), () async {
var status = await MyApp.isarInstance.sessionStatus.where().findFirst();
_sid = status != null ? status.sid : 'Unbekannt';
await _fetchMessages();
_initCompleted = true;
setState(() {});
});
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
return Stack(
children: [
Chat(
messages: _messages,
textMessageOptions:const TextMessageOptions(isTextSelectable:false),
onSendPressed: _handleSendPressed,
showUserAvatars: false,
showUserNames: false,
user: _user,
onMessageTap: (context, message) => {
_showDeleteMessageDialog(context, message)
},
),
],
);
}
void _handleSendPressed(types.PartialText text) async {
var now = DateTime.now();
var message = sbmessage.Message();
message.text = text.text;
message.from = _sid;
message.subj = '';
message.time = now.toUtc().toIso8601String();
message.read = true;
message.id = await sbmessage.Message.getNextId();
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.messages.put(message);
});
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "message", message: message.toJson(), qos: MqttQos.exactlyOnce));
_messages.insert(0, types.TextMessage(
author: _user,
createdAt: now.millisecondsSinceEpoch,
id: message.id.toString(),
text: text.text,
));
setState(() {});
}
Future<void> _fetchMessages() async {
_messages.clear();
var messages = await MyApp.isarInstance.messages.where().findAll();
for (var message in messages) {
_messages.add(types.TextMessage(
author: message.from == _sid ? _user : _central,
createdAt: DateTime.parse(message.time).toLocal().millisecondsSinceEpoch,
id: message.id.toString(),
text: "${message.subj}\n${message.text}",
));
_messages.sort((a, b) => b.createdAt! > a.createdAt! ? 1 : 0);
message.read = true;
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.messages.put(message);
});
}
setState(() {});
}
_showDeleteMessageDialog(BuildContext context, types.Message message) async {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
contentPadding: EdgeInsets.zero,
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return SizedBox(
key: GlobalKey(),
height: 120,
width: MediaQuery
.of(context)
.size
.width * 1.2,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
padding: const EdgeInsets.all(5),
child: Column(
children: [
const Text('Soll die Nachricht gelöscht werden?'),
const SizedBox(height: 20),
Row(children: [
Expanded(
child: getDefaultButton('Nein', () => {Navigator.of(context).pop()}),
),
const SizedBox(width: 20),
Expanded(
child: getDefaultButton('Ja', () async => {
await MyApp.isarInstance.writeTxn(() async => { await MyApp.isarInstance.messages.delete(int.parse(message.id))}),
_fetchMessages(),
setState(() {}),
Navigator.of(MyApp.appNavigatorKey.currentContext!).pop()
}),
)
])
],
),
),
)
);
})
);
});
}
}