Solian/lib/widgets/chat/message_content.dart

112 lines
3.4 KiB
Dart
Raw Normal View History

2024-04-17 15:00:53 +00:00
import 'package:flutter/material.dart';
2024-05-12 12:15:12 +00:00
import 'package:flutter_animate/flutter_animate.dart';
2024-04-17 15:00:53 +00:00
import 'package:flutter_markdown/flutter_markdown.dart';
2024-05-12 12:15:12 +00:00
import 'package:provider/provider.dart';
2024-04-17 15:00:53 +00:00
import 'package:solian/models/message.dart';
2024-05-12 12:15:12 +00:00
import 'package:solian/providers/keypair.dart';
2024-04-17 15:00:53 +00:00
import 'package:url_launcher/url_launcher_string.dart';
2024-05-12 12:15:12 +00:00
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
2024-04-17 15:00:53 +00:00
2024-05-12 12:15:12 +00:00
class ChatMessageContent extends StatefulWidget {
2024-04-17 15:00:53 +00:00
final Message item;
const ChatMessageContent({super.key, required this.item});
2024-05-12 12:15:12 +00:00
@override
State<ChatMessageContent> createState() => _ChatMessageContentState();
}
class _ChatMessageContentState extends State<ChatMessageContent> {
2024-04-17 15:00:53 +00:00
@override
Widget build(BuildContext context) {
2024-05-12 12:15:12 +00:00
final feColor = Theme.of(context).colorScheme.onSurface.withOpacity(0.65);
final waitingKeyHint = Row(
children: [
Icon(Icons.key, color: feColor, size: 16),
const SizedBox(width: 4),
Expanded(
child: Text(
AppLocalizations.of(context)!.chatMessageUnableDecryptWaiting,
style: TextStyle(color: feColor),
),
),
],
);
final missingKeyHint = Row(
children: [
Icon(Icons.key_off_outlined, color: feColor, size: 16),
const SizedBox(width: 4),
Expanded(
child: Text(
AppLocalizations.of(context)!.chatMessageUnableDecryptMissing,
style: TextStyle(color: feColor),
),
),
],
);
if (widget.item.type == 'm.text') {
String? content;
switch (widget.item.decodedContent['algorithm']) {
case 'plain':
content = widget.item.decodedContent['value'];
case 'aes':
final keypair = context.watch<KeypairProvider>();
if (keypair.keys[widget.item.decodedContent['keypair_id']] == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (keypair.requestKey(
widget.item.decodedContent['keypair_id'],
widget.item.decodedContent['algorithm'],
widget.item.sender.account.externalId!,
)) {
}
});
} else {
content = keypair.decodeViaAESKey(
widget.item.decodedContent['keypair_id'],
widget.item.decodedContent['value'],
)!;
break;
}
if (keypair.requestingKeys.contains(widget.item.decodedContent['keypair_id'])) {
return waitingKeyHint.animate().swap(builder: (context, _) {
return missingKeyHint;
}, delay: 3000.ms);
}
}
if (content == null) {
return Row(
children: [
Icon(Icons.key_off, color: feColor, size: 16),
const SizedBox(width: 4),
Text(
AppLocalizations.of(context)!.chatMessageUnableDecryptUnsupported,
style: TextStyle(color: feColor),
),
],
);
}
return Markdown(
2024-05-12 12:15:12 +00:00
data: content,
shrinkWrap: true,
selectable: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
onTapLink: (text, href, title) async {
if (href == null) return;
await launchUrlString(
href,
mode: LaunchMode.externalApplication,
);
},
);
}
return Container();
2024-04-17 15:00:53 +00:00
}
}