mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-06-15 13:14:07 +00:00
fix the response view
This commit is contained in:
parent
b49b9cf452
commit
f66e1f17bf
3 changed files with 180 additions and 229 deletions
|
|
@ -31,23 +31,13 @@ class ChatAudioEntry extends StatelessWidget {
|
||||||
return Container(); // media file was purged
|
return Container(); // media file was purged
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayoutBuilder(
|
final showTime = info.displayTime || message.modifiedAt != null;
|
||||||
builder: (context, constraints) {
|
|
||||||
final textWidth = measureTextWidth(info.text);
|
|
||||||
const timeWidth = 60.0;
|
|
||||||
final isExpanded =
|
|
||||||
info.expanded ||
|
|
||||||
(textWidth + timeWidth + 20 > constraints.maxWidth);
|
|
||||||
final effectiveSpacerWidth =
|
|
||||||
constraints.minWidth - textWidth - timeWidth;
|
|
||||||
final spacerWidth = effectiveSpacerWidth > 0
|
|
||||||
? effectiveSpacerWidth
|
|
||||||
: 0.0;
|
|
||||||
|
|
||||||
return Container(
|
return IntrinsicWidth(
|
||||||
|
child: Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
||||||
minWidth: 250,
|
minWidth: 280,
|
||||||
),
|
),
|
||||||
padding: info.padding,
|
padding: info.padding,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -56,9 +46,12 @@ class ChatAudioEntry extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (info.displayUserName != '')
|
if (info.displayUserName != '')
|
||||||
Text(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 2),
|
||||||
|
child: Text(
|
||||||
info.displayUserName,
|
info.displayUserName,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
|
@ -66,42 +59,37 @@ class ChatAudioEntry extends StatelessWidget {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
if (isExpanded && info.text != '')
|
if (info.text != '')
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BetterText(
|
child: BetterText(
|
||||||
text: info.text,
|
text: info.text,
|
||||||
textColor: info.textColor,
|
textColor: info.textColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else if (info.text != '') ...[
|
else
|
||||||
BetterText(text: info.text, textColor: info.textColor),
|
Expanded(
|
||||||
SizedBox(width: spacerWidth),
|
child: mediaService.mediaFile.downloadState ==
|
||||||
] else ...[
|
|
||||||
if (mediaService.mediaFile.downloadState ==
|
|
||||||
DownloadState.ready ||
|
DownloadState.ready ||
|
||||||
mediaService.mediaFile.downloadState == null)
|
mediaService.mediaFile.downloadState == null
|
||||||
mediaService.tempPath.existsSync()
|
? (mediaService.tempPath.existsSync()
|
||||||
? InChatAudioPlayer(
|
? InChatAudioPlayer(
|
||||||
path: mediaService.tempPath.path,
|
path: mediaService.tempPath.path,
|
||||||
message: message,
|
message: message,
|
||||||
)
|
)
|
||||||
: Container()
|
: Container())
|
||||||
else
|
: MessageSendStateIcon([message], [mediaService.mediaFile]),
|
||||||
MessageSendStateIcon([message], [mediaService.mediaFile]),
|
),
|
||||||
SizedBox(width: spacerWidth),
|
if (showTime) FriendlyMessageTime(message: message),
|
||||||
],
|
|
||||||
if (info.displayTime || message.modifiedAt != null)
|
|
||||||
FriendlyMessageTime(message: message),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,20 +34,10 @@ class ChatTextEntry extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayoutBuilder(
|
final showTime = info.displayTime || message.modifiedAt != null;
|
||||||
builder: (context, constraints) {
|
|
||||||
final textWidth = measureTextWidth(info.text);
|
|
||||||
const timeWidth = 60.0;
|
|
||||||
final isExpanded =
|
|
||||||
info.expanded ||
|
|
||||||
(textWidth + timeWidth + 20 > constraints.maxWidth);
|
|
||||||
final effectiveSpacerWidth =
|
|
||||||
constraints.minWidth - textWidth - timeWidth;
|
|
||||||
final spacerWidth = effectiveSpacerWidth > 0
|
|
||||||
? effectiveSpacerWidth
|
|
||||||
: 0.0;
|
|
||||||
|
|
||||||
return Container(
|
return IntrinsicWidth(
|
||||||
|
child: Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
||||||
minWidth: info.minWidth,
|
minWidth: info.minWidth,
|
||||||
|
|
@ -59,9 +49,12 @@ class ChatTextEntry extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (info.displayUserName != '')
|
if (info.displayUserName != '')
|
||||||
Text(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 2),
|
||||||
|
child: Text(
|
||||||
info.displayUserName,
|
info.displayUserName,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
|
@ -69,31 +62,23 @@ class ChatTextEntry extends StatelessWidget {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
if (isExpanded)
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BetterText(
|
child: BetterText(
|
||||||
text: info.text,
|
text: info.text,
|
||||||
textColor: info.textColor,
|
textColor: info.textColor,
|
||||||
),
|
),
|
||||||
)
|
|
||||||
else ...[
|
|
||||||
BetterText(text: info.text, textColor: info.textColor),
|
|
||||||
SizedBox(
|
|
||||||
width: spacerWidth,
|
|
||||||
),
|
),
|
||||||
],
|
if (showTime) FriendlyMessageTime(message: message),
|
||||||
if (info.displayTime || message.modifiedAt != null)
|
|
||||||
FriendlyMessageTime(message: message),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/visual/views/chats/chat_messages.view.dart';
|
import 'package:twonly/src/visual/views/chats/chat_messages.view.dart';
|
||||||
|
|
||||||
class ResponseContainer extends StatefulWidget {
|
class ResponseContainer extends StatelessWidget {
|
||||||
const ResponseContainer({
|
const ResponseContainer({
|
||||||
required this.msg,
|
required this.msg,
|
||||||
required this.group,
|
required this.group,
|
||||||
|
|
@ -27,64 +27,34 @@ class ResponseContainer extends StatefulWidget {
|
||||||
final BorderRadius borderRadius;
|
final BorderRadius borderRadius;
|
||||||
final void Function(String)? scrollToMessage;
|
final void Function(String)? scrollToMessage;
|
||||||
|
|
||||||
@override
|
|
||||||
State<ResponseContainer> createState() => _ResponseContainerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ResponseContainerState extends State<ResponseContainer> {
|
|
||||||
double? minWidth;
|
|
||||||
final GlobalKey _message = GlobalKey();
|
|
||||||
final GlobalKey _preview = GlobalKey();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
final messageBox =
|
|
||||||
_message.currentContext?.findRenderObject() as RenderBox?;
|
|
||||||
final previewBox =
|
|
||||||
_preview.currentContext?.findRenderObject() as RenderBox?;
|
|
||||||
if (messageBox == null || previewBox == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
if (messageBox.size.width > previewBox.size.width) {
|
|
||||||
minWidth = messageBox.size.width;
|
|
||||||
} else {
|
|
||||||
minWidth = previewBox.size.width;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (widget.msg.quotesMessageId == null) {
|
if (msg.quotesMessageId == null) {
|
||||||
if (widget.child == null) {
|
if (child == null) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return widget.child!;
|
return child!;
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: widget.scrollToMessage == null
|
onTap: scrollToMessage == null
|
||||||
? null
|
? null
|
||||||
: () => widget.scrollToMessage!(widget.msg.quotesMessageId!),
|
: () => scrollToMessage!(msg.quotesMessageId!),
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: getMessageColor(widget.msg.senderId != null),
|
color: getMessageColor(msg.senderId != null),
|
||||||
borderRadius: widget.borderRadius,
|
borderRadius: borderRadius,
|
||||||
),
|
),
|
||||||
|
child: IntrinsicWidth(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
key: _preview,
|
|
||||||
padding: const EdgeInsets.only(top: 4, right: 4, left: 4),
|
padding: const EdgeInsets.only(top: 4, right: 4, left: 4),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: minWidth,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.color.surface.withAlpha(150),
|
color: context.color.surface.withAlpha(150),
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
|
|
@ -95,20 +65,19 @@ class _ResponseContainerState extends State<ResponseContainer> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ResponsePreview(
|
child: ResponsePreview(
|
||||||
group: widget.group,
|
group: group,
|
||||||
messageId: widget.msg.quotesMessageId,
|
messageId: msg.quotesMessageId,
|
||||||
showBorder: false,
|
showBorder: false,
|
||||||
|
showLeftBorder: false,
|
||||||
|
colorUsername: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
if (child != null) child!,
|
||||||
key: _message,
|
|
||||||
width: minWidth,
|
|
||||||
child: widget.child,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +88,8 @@ class ResponsePreview extends StatefulWidget {
|
||||||
required this.showBorder,
|
required this.showBorder,
|
||||||
this.message,
|
this.message,
|
||||||
this.messageId,
|
this.messageId,
|
||||||
|
this.showLeftBorder = true,
|
||||||
|
this.colorUsername = false,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -126,6 +97,8 @@ class ResponsePreview extends StatefulWidget {
|
||||||
final String? messageId;
|
final String? messageId;
|
||||||
final Group group;
|
final Group group;
|
||||||
final bool showBorder;
|
final bool showBorder;
|
||||||
|
final bool showLeftBorder;
|
||||||
|
final bool colorUsername;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ResponsePreview> createState() => _ResponsePreviewState();
|
State<ResponsePreview> createState() => _ResponsePreviewState();
|
||||||
|
|
@ -212,80 +185,85 @@ class _ResponsePreviewState extends State<ResponsePreview> {
|
||||||
|
|
||||||
if (_message!.senderId == null) {
|
if (_message!.senderId == null) {
|
||||||
_username = context.lang.you;
|
_username = context.lang.you;
|
||||||
// _username = _message!.senderId.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color = getMessageColor(_message!.senderId != null);
|
color = getMessageColor(_message!.senderId != null);
|
||||||
|
|
||||||
if (!_message!.mediaStored) {
|
|
||||||
return Container(
|
|
||||||
padding: widget.showBorder
|
|
||||||
? const EdgeInsets.only(left: 10, right: 10)
|
|
||||||
: const EdgeInsets.symmetric(horizontal: 5),
|
|
||||||
decoration: (widget.showBorder)
|
|
||||||
? BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
left: BorderSide(
|
|
||||||
color: color,
|
|
||||||
width: 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
_username,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
if (subtitle != null) Text(subtitle),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
final hasImage =
|
||||||
padding: const EdgeInsets.only(left: 10),
|
_message != null &&
|
||||||
width: 200,
|
_message!.mediaStored &&
|
||||||
decoration: BoxDecoration(
|
_mediaService != null &&
|
||||||
border: Border(
|
_mediaService!.mediaFile.type != MediaType.audio;
|
||||||
left: BorderSide(
|
|
||||||
color: color,
|
Widget? imageWidget;
|
||||||
width: 2,
|
if (hasImage) {
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
_username,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
if (subtitle != null) Text(subtitle),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_mediaService != null &&
|
|
||||||
_mediaService!.mediaFile.type != MediaType.audio)
|
|
||||||
() {
|
|
||||||
final isVideo = _mediaService!.mediaFile.type == MediaType.video;
|
final isVideo = _mediaService!.mediaFile.type == MediaType.video;
|
||||||
final pathToCheck = isVideo
|
final pathToCheck = isVideo
|
||||||
? _mediaService!.thumbnailPath
|
? _mediaService!.thumbnailPath
|
||||||
: _mediaService!.storedPath;
|
: _mediaService!.storedPath;
|
||||||
if (pathToCheck.existsSync() && pathToCheck.lengthSync() > 0) {
|
if (pathToCheck.existsSync() && pathToCheck.lengthSync() > 0) {
|
||||||
return SizedBox(
|
imageWidget = Container(
|
||||||
height: widget.showBorder ? 100 : 210,
|
height: 40,
|
||||||
child: Image.file(pathToCheck),
|
width: 40,
|
||||||
|
margin: const EdgeInsets.only(left: 8),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
child: Image.file(
|
||||||
|
pathToCheck,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return const SizedBox.shrink();
|
}
|
||||||
}(),
|
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: widget.showLeftBorder ? 8 : 4,
|
||||||
|
right: 6,
|
||||||
|
top: 4,
|
||||||
|
bottom: 4,
|
||||||
|
),
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minWidth: 60,
|
||||||
|
maxWidth: MediaQuery.of(context).size.width * 0.7,
|
||||||
|
),
|
||||||
|
decoration: widget.showLeftBorder
|
||||||
|
? BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
left: BorderSide(
|
||||||
|
color: color,
|
||||||
|
width: 2.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_username,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: widget.colorUsername ? color : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (subtitle != null)
|
||||||
|
Text(
|
||||||
|
subtitle,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (imageWidget != null) imageWidget,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue