Implement View Replies
This commit is contained in:
parent
62ea8278f3
commit
814e6df6f6
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "cy",
|
"@@locale": "cy",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "da",
|
"@@locale": "da",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "de",
|
"@@locale": "de",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "el",
|
"@@locale": "el",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "es",
|
"@@locale": "es",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "fr",
|
"@@locale": "fr",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "it",
|
"@@locale": "it",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "lb",
|
"@@locale": "lb",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "no",
|
"@@locale": "no",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "pl",
|
"@@locale": "pl",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "pt",
|
"@@locale": "pt",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "ro",
|
"@@locale": "ro",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "ru",
|
"@@locale": "ru",
|
||||||
"@@last_modified": "2022-07-06T20:42:11+02:00",
|
"@@last_modified": "2022-07-07T21:07:20+02:00",
|
||||||
|
"headingReplies": "Replies",
|
||||||
|
"viewReplies": "View replies to this message",
|
||||||
"restartFileShare": "Start Sharing File",
|
"restartFileShare": "Start Sharing File",
|
||||||
"stopSharingFile": "Stop Sharing File",
|
"stopSharingFile": "Stop Sharing File",
|
||||||
"manageSharedFiles": "Manage Shared Files",
|
"manageSharedFiles": "Manage Shared Files",
|
||||||
|
|
|
@ -201,6 +201,42 @@ class ByContentHash implements CacheHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Message> getReplies(MessageCache cache, int messageIdentifier) {
|
||||||
|
List<Message> replies = List.empty(growable: true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
MessageInfo original = cache.cache[messageIdentifier]!;
|
||||||
|
String hash = original.metadata.contenthash;
|
||||||
|
|
||||||
|
cache.cache.forEach((key, messageInfo) {
|
||||||
|
// only bother searching for identifiers that came *after*
|
||||||
|
if (key > messageIdentifier) {
|
||||||
|
try {
|
||||||
|
dynamic message = jsonDecode(messageInfo.wrapper);
|
||||||
|
var content = message['d'] as dynamic;
|
||||||
|
dynamic qmessage = jsonDecode(content);
|
||||||
|
if (qmessage["body"] == null || qmessage["quotedHash"] == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (qmessage["quotedHash"] == hash) {
|
||||||
|
replies.add(compileOverlay(messageInfo));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
EnvironmentConfig.debugLog("message handler exception on get from cache: $e");
|
||||||
|
}
|
||||||
|
|
||||||
|
replies.sort((a, b) {
|
||||||
|
return a.getMetadata().messageID.compareTo(b.getMetadata().messageID);
|
||||||
|
});
|
||||||
|
|
||||||
|
return replies;
|
||||||
|
}
|
||||||
|
|
||||||
Future<Message> messageHandler(BuildContext context, String profileOnion, int conversationIdentifier, CacheHandler cacheHandler) async {
|
Future<Message> messageHandler(BuildContext context, String profileOnion, int conversationIdentifier, CacheHandler cacheHandler) async {
|
||||||
var malformedMetadata = MessageMetadata(profileOnion, conversationIdentifier, 0, DateTime.now(), "", "", "", <String, String>{}, false, true, false, "");
|
var malformedMetadata = MessageMetadata(profileOnion, conversationIdentifier, 0, DateTime.now(), "", "", "", <String, String>{}, false, true, false, "");
|
||||||
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
|
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
|
||||||
|
|
|
@ -36,7 +36,6 @@ class QuotedMessage extends Message {
|
||||||
var content = message["body"];
|
var content = message["body"];
|
||||||
return Text(
|
return Text(
|
||||||
content,
|
content,
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return MalformedBubble();
|
return MalformedBubble();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cwtch/models/contact.dart';
|
||||||
import 'package:cwtch/models/message.dart';
|
import 'package:cwtch/models/message.dart';
|
||||||
import 'package:cwtch/models/profile.dart';
|
import 'package:cwtch/models/profile.dart';
|
||||||
import 'package:cwtch/views/contactsview.dart';
|
import 'package:cwtch/views/contactsview.dart';
|
||||||
|
import 'package:cwtch/widgets/staticmessagebubble.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cwtch/widgets/profileimage.dart';
|
import 'package:cwtch/widgets/profileimage.dart';
|
||||||
import 'package:flutter/physics.dart';
|
import 'package:flutter/physics.dart';
|
||||||
|
@ -15,6 +16,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
|
import '../models/messagecache.dart';
|
||||||
import '../settings.dart';
|
import '../settings.dart';
|
||||||
|
|
||||||
class MessageRow extends StatefulWidget {
|
class MessageRow extends StatefulWidget {
|
||||||
|
@ -74,7 +76,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget wdgIcons = Platform.isAndroid
|
Widget wdgReply = Platform.isAndroid
|
||||||
? SizedBox.shrink()
|
? SizedBox.shrink()
|
||||||
: Visibility(
|
: Visibility(
|
||||||
visible: EnvironmentConfig.TEST_MODE || Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageID,
|
visible: EnvironmentConfig.TEST_MODE || Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageID,
|
||||||
|
@ -90,13 +92,37 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.reply, color: Provider.of<Settings>(context).theme.dropShadowColor)));
|
icon: Icon(Icons.reply, color: Provider.of<Settings>(context).theme.dropShadowColor)));
|
||||||
|
|
||||||
|
var settings = Provider.of<Settings>(context);
|
||||||
|
var pis = Provider.of<ProfileInfoState>(context);
|
||||||
|
var cis = Provider.of<ContactInfoState>(context);
|
||||||
|
var borderColor = Provider.of<Settings>(context).theme.portraitOnlineBorderColor;
|
||||||
|
var messageID = Provider.of<MessageMetadata>(context).messageID;
|
||||||
|
var cache = Provider.of<ContactInfoState>(context).messageCache;
|
||||||
|
|
||||||
|
Widget wdgSeeReplies = Platform.isAndroid
|
||||||
|
? SizedBox.shrink()
|
||||||
|
: Visibility(
|
||||||
|
visible: EnvironmentConfig.TEST_MODE || Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageID,
|
||||||
|
maintainSize: true,
|
||||||
|
maintainAnimation: true,
|
||||||
|
maintainState: true,
|
||||||
|
maintainInteractivity: false,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: AppLocalizations.of(context)!.viewReplies,
|
||||||
|
splashRadius: Material.defaultSplashRadius / 2,
|
||||||
|
onPressed: () {
|
||||||
|
modalShowReplies(context, AppLocalizations.of(context)!.headingReplies, settings, pis, cis, borderColor, cache, messageID);
|
||||||
|
},
|
||||||
|
icon: Icon(Icons.message_rounded, color: Provider.of<Settings>(context).theme.dropShadowColor)));
|
||||||
|
|
||||||
Widget wdgSpacer = Flexible(flex: 1, child: SizedBox(width: Platform.isAndroid ? 20 : 60, height: 10));
|
Widget wdgSpacer = Flexible(flex: 1, child: SizedBox(width: Platform.isAndroid ? 20 : 60, height: 10));
|
||||||
var widgetRow = <Widget>[];
|
var widgetRow = <Widget>[];
|
||||||
|
|
||||||
if (fromMe) {
|
if (fromMe) {
|
||||||
widgetRow = <Widget>[
|
widgetRow = <Widget>[
|
||||||
wdgSpacer,
|
wdgSpacer,
|
||||||
wdgIcons,
|
wdgSeeReplies,
|
||||||
|
wdgReply,
|
||||||
actualMessage,
|
actualMessage,
|
||||||
];
|
];
|
||||||
} else if (isBlocked && !showBlockedMessage) {
|
} else if (isBlocked && !showBlockedMessage) {
|
||||||
|
@ -143,7 +169,8 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
||||||
});
|
});
|
||||||
})),
|
})),
|
||||||
]))),
|
]))),
|
||||||
wdgIcons,
|
wdgReply,
|
||||||
|
wdgSeeReplies,
|
||||||
wdgSpacer,
|
wdgSpacer,
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
|
@ -179,7 +206,8 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
||||||
widgetRow = <Widget>[
|
widgetRow = <Widget>[
|
||||||
wdgPortrait,
|
wdgPortrait,
|
||||||
actualMessage,
|
actualMessage,
|
||||||
wdgIcons,
|
wdgReply,
|
||||||
|
wdgSeeReplies,
|
||||||
wdgSpacer,
|
wdgSpacer,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -332,3 +360,80 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void modalShowReplies(BuildContext ctx, String replyHeader, Settings settings, ProfileInfoState profile, ContactInfoState cis, Color borderColor, MessageCache cache, int messageID,
|
||||||
|
{bool showImage = true}) {
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: ctx,
|
||||||
|
builder: (BuildContext bcontext) {
|
||||||
|
List<Message> replies = getReplies(cache, messageID);
|
||||||
|
|
||||||
|
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||||
|
var replyWidgets = replies.map((e) {
|
||||||
|
var fromMe = e.getMetadata().senderHandle == profile.onion;
|
||||||
|
|
||||||
|
var bubble = StaticMessageBubble(profile, settings, e.getMetadata(), Row(children: [Flexible(child: e.getPreviewWidget(context))]));
|
||||||
|
|
||||||
|
String imagePath = e.getMetadata().senderImage!;
|
||||||
|
var sender = profile.contactList.findContact(e.getMetadata().senderHandle);
|
||||||
|
if (sender != null) {
|
||||||
|
imagePath = showImage ? sender.imagePath : sender.defaultImagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromMe) {
|
||||||
|
imagePath = profile.imagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
var image = Padding(
|
||||||
|
padding: EdgeInsets.all(4.0),
|
||||||
|
child: ProfileImage(
|
||||||
|
imagePath: imagePath,
|
||||||
|
diameter: 48.0,
|
||||||
|
border: borderColor,
|
||||||
|
badgeTextColor: Colors.red,
|
||||||
|
badgeColor: Colors.red,
|
||||||
|
));
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [image, Flexible(child: bubble)],
|
||||||
|
));
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
var withHeader = replyWidgets;
|
||||||
|
|
||||||
|
var original = StaticMessageBubble(profile, settings, cache.cache[messageID]!.metadata, Row(children: [Flexible(child: compileOverlay(cache.cache[messageID]!).getPreviewWidget(context))]));
|
||||||
|
|
||||||
|
withHeader.insert(0,
|
||||||
|
Padding(padding: EdgeInsets.fromLTRB(10.0, 10.0, 2.0, 15.0), child: Center(child: original)));
|
||||||
|
|
||||||
|
|
||||||
|
withHeader.insert(1,
|
||||||
|
Padding(padding: EdgeInsets.fromLTRB(10.0, 10.0, 2.0, 15.0),
|
||||||
|
child: Divider(
|
||||||
|
color: settings.theme.mainTextColor,
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
withHeader.insert(2,
|
||||||
|
Padding(padding: EdgeInsets.fromLTRB(10.0, 10.0, 2.0, 15.0), child: Text(replyHeader, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold))));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return Scrollbar(
|
||||||
|
isAlwaysShown: true,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minHeight: viewportConstraints.maxHeight,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: withHeader,
|
||||||
|
))));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:cwtch/models/contact.dart';
|
||||||
|
import 'package:cwtch/models/message.dart';
|
||||||
|
import 'package:cwtch/models/profile.dart';
|
||||||
|
import 'package:cwtch/widgets/malformedbubble.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../settings.dart';
|
||||||
|
import 'messagebubbledecorations.dart';
|
||||||
|
|
||||||
|
class StaticMessageBubble extends StatefulWidget {
|
||||||
|
final ProfileInfoState profile;
|
||||||
|
final Settings settings;
|
||||||
|
final MessageMetadata metadata;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
StaticMessageBubble(this.profile, this.settings, this.metadata, this.child);
|
||||||
|
|
||||||
|
@override
|
||||||
|
StaticMessageBubbleState createState() => StaticMessageBubbleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class StaticMessageBubbleState extends State<StaticMessageBubble> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var fromMe = widget.metadata.senderHandle == widget.profile.onion;
|
||||||
|
var borderRadiousEh = 15.0;
|
||||||
|
DateTime messageDate = widget.metadata.timestamp;
|
||||||
|
|
||||||
|
// If the sender is not us, then we want to give them a nickname...
|
||||||
|
var senderDisplayStr = "";
|
||||||
|
if (!fromMe) {
|
||||||
|
ContactInfoState? contact = widget.profile.contactList.findContact(widget.metadata.senderHandle);
|
||||||
|
if (contact != null) {
|
||||||
|
senderDisplayStr = contact.nickname;
|
||||||
|
} else {
|
||||||
|
senderDisplayStr = widget.metadata.senderHandle;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
senderDisplayStr = widget.profile.nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wdgSender = SelectableText(senderDisplayStr, style: TextStyle(fontSize: 9.0, color: fromMe ? widget.settings.theme.messageFromMeTextColor : widget.settings.theme.messageFromOtherTextColor));
|
||||||
|
|
||||||
|
var wdgDecorations = MessageBubbleDecoration(ackd: widget.metadata.ackd, errored: widget.metadata.error, fromMe: fromMe, messageDate: messageDate);
|
||||||
|
|
||||||
|
var error = widget.metadata.error;
|
||||||
|
|
||||||
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
|
//print(constraints.toString()+", "+constraints.maxWidth.toString());
|
||||||
|
return RepaintBoundary(
|
||||||
|
child: Container(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: error ? malformedColor : (fromMe ? widget.settings.theme.messageFromMeBackgroundColor : widget.settings.theme.messageFromOtherBackgroundColor),
|
||||||
|
border: Border.all(color: error ? malformedColor : (fromMe ? widget.settings.theme.messageFromMeBackgroundColor : widget.settings.theme.messageFromOtherBackgroundColor), width: 1),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(borderRadiousEh),
|
||||||
|
topRight: Radius.circular(borderRadiousEh),
|
||||||
|
bottomLeft: Radius.zero,
|
||||||
|
bottomRight: Radius.circular(borderRadiousEh),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(9.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [wdgSender, widget.child, wdgDecorations])))));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue