200 lines
6.3 KiB
Dart
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);
|
|
});
|
|
|
|
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(context).pop()
|
|
}),
|
|
)
|
|
])
|
|
],
|
|
),
|
|
),
|
|
)
|
|
);
|
|
})
|
|
);
|
|
});
|
|
}
|
|
}
|