diff --git a/lib/src/visual/views/chats/chat_messages_components/entries/chat_audio_entry.dart b/lib/src/visual/views/chats/chat_messages_components/entries/chat_audio_entry.dart index 349ace0f..a29455a6 100644 --- a/lib/src/visual/views/chats/chat_messages_components/entries/chat_audio_entry.dart +++ b/lib/src/visual/views/chats/chat_messages_components/entries/chat_audio_entry.dart @@ -31,34 +31,27 @@ class ChatAudioEntry extends StatelessWidget { return Container(); // media file was purged } - return LayoutBuilder( - 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; + final showTime = info.displayTime || message.modifiedAt != null; - return Container( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width * 0.8, - minWidth: 250, - ), - padding: info.padding, - decoration: BoxDecoration( - color: info.color, - borderRadius: borderRadius, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (info.displayUserName != '') - Text( + return IntrinsicWidth( + child: Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.8, + minWidth: 280, + ), + padding: info.padding, + decoration: BoxDecoration( + color: info.color, + borderRadius: borderRadius, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (info.displayUserName != '') + Padding( + padding: const EdgeInsets.only(bottom: 2), + child: Text( info.displayUserName, textAlign: TextAlign.left, style: const TextStyle( @@ -66,42 +59,37 @@ class ChatAudioEntry extends StatelessWidget { fontWeight: FontWeight.bold, ), ), - Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (isExpanded && info.text != '') - Expanded( - child: BetterText( - text: info.text, - textColor: info.textColor, - ), - ) - else if (info.text != '') ...[ - BetterText(text: info.text, textColor: info.textColor), - SizedBox(width: spacerWidth), - ] else ...[ - if (mediaService.mediaFile.downloadState == - DownloadState.ready || - mediaService.mediaFile.downloadState == null) - mediaService.tempPath.existsSync() - ? InChatAudioPlayer( - path: mediaService.tempPath.path, - message: message, - ) - : Container() - else - MessageSendStateIcon([message], [mediaService.mediaFile]), - SizedBox(width: spacerWidth), - ], - if (info.displayTime || message.modifiedAt != null) - FriendlyMessageTime(message: message), - ], ), - ], - ), - ); - }, + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (info.text != '') + Expanded( + child: BetterText( + text: info.text, + textColor: info.textColor, + ), + ) + else + Expanded( + child: mediaService.mediaFile.downloadState == + DownloadState.ready || + mediaService.mediaFile.downloadState == null + ? (mediaService.tempPath.existsSync() + ? InChatAudioPlayer( + path: mediaService.tempPath.path, + message: message, + ) + : Container()) + : MessageSendStateIcon([message], [mediaService.mediaFile]), + ), + if (showTime) FriendlyMessageTime(message: message), + ], + ), + ], + ), + ), ); } } diff --git a/lib/src/visual/views/chats/chat_messages_components/entries/chat_text_entry.dart b/lib/src/visual/views/chats/chat_messages_components/entries/chat_text_entry.dart index 67d0a1a5..694f3581 100644 --- a/lib/src/visual/views/chats/chat_messages_components/entries/chat_text_entry.dart +++ b/lib/src/visual/views/chats/chat_messages_components/entries/chat_text_entry.dart @@ -34,34 +34,27 @@ class ChatTextEntry extends StatelessWidget { ); } - return LayoutBuilder( - 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; + final showTime = info.displayTime || message.modifiedAt != null; - return Container( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width * 0.8, - minWidth: info.minWidth, - ), - padding: info.padding, - decoration: BoxDecoration( - color: info.color, - borderRadius: borderRadius, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (info.displayUserName != '') - Text( + return IntrinsicWidth( + child: Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.8, + minWidth: info.minWidth, + ), + padding: info.padding, + decoration: BoxDecoration( + color: info.color, + borderRadius: borderRadius, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (info.displayUserName != '') + Padding( + padding: const EdgeInsets.only(bottom: 2), + child: Text( info.displayUserName, textAlign: TextAlign.left, style: const TextStyle( @@ -69,31 +62,23 @@ class ChatTextEntry extends StatelessWidget { fontWeight: FontWeight.bold, ), ), - Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (isExpanded) - Expanded( - child: BetterText( - text: info.text, - textColor: info.textColor, - ), - ) - else ...[ - BetterText(text: info.text, textColor: info.textColor), - SizedBox( - width: spacerWidth, - ), - ], - if (info.displayTime || message.modifiedAt != null) - FriendlyMessageTime(message: message), - ], ), - ], - ), - ); - }, + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: BetterText( + text: info.text, + textColor: info.textColor, + ), + ), + if (showTime) FriendlyMessageTime(message: message), + ], + ), + ], + ), + ), ); } } diff --git a/lib/src/visual/views/chats/chat_messages_components/response_container.dart b/lib/src/visual/views/chats/chat_messages_components/response_container.dart index 9508dc7d..771cb931 100644 --- a/lib/src/visual/views/chats/chat_messages_components/response_container.dart +++ b/lib/src/visual/views/chats/chat_messages_components/response_container.dart @@ -9,7 +9,7 @@ import 'package:twonly/src/services/mediafiles/mediafile.service.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/visual/views/chats/chat_messages.view.dart'; -class ResponseContainer extends StatefulWidget { +class ResponseContainer extends StatelessWidget { const ResponseContainer({ required this.msg, required this.group, @@ -27,86 +27,55 @@ class ResponseContainer extends StatefulWidget { final BorderRadius borderRadius; final void Function(String)? scrollToMessage; - @override - State createState() => _ResponseContainerState(); -} - -class _ResponseContainerState extends State { - 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 Widget build(BuildContext context) { - if (widget.msg.quotesMessageId == null) { - if (widget.child == null) { + if (msg.quotesMessageId == null) { + if (child == null) { return Container(); } - return widget.child!; + return child!; } return GestureDetector( - onTap: widget.scrollToMessage == null + onTap: scrollToMessage == null ? null - : () => widget.scrollToMessage!(widget.msg.quotesMessageId!), + : () => scrollToMessage!(msg.quotesMessageId!), child: Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.8, ), decoration: BoxDecoration( - color: getMessageColor(widget.msg.senderId != null), - borderRadius: widget.borderRadius, + color: getMessageColor(msg.senderId != null), + borderRadius: borderRadius, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - key: _preview, - padding: const EdgeInsets.only(top: 4, right: 4, left: 4), - child: Container( - width: minWidth, - decoration: BoxDecoration( - color: context.color.surface.withAlpha(150), - borderRadius: const BorderRadius.only( - topRight: Radius.circular(8), - topLeft: Radius.circular(8), - bottomLeft: Radius.circular(4), - bottomRight: Radius.circular(4), + child: IntrinsicWidth( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.only(top: 4, right: 4, left: 4), + child: Container( + decoration: BoxDecoration( + color: context.color.surface.withAlpha(150), + borderRadius: const BorderRadius.only( + topRight: Radius.circular(8), + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(4), + bottomRight: Radius.circular(4), + ), + ), + child: ResponsePreview( + group: group, + messageId: msg.quotesMessageId, + showBorder: false, + showLeftBorder: false, + colorUsername: false, ), ), - child: ResponsePreview( - group: widget.group, - messageId: widget.msg.quotesMessageId, - showBorder: false, - ), ), - ), - SizedBox( - key: _message, - width: minWidth, - child: widget.child, - ), - ], + if (child != null) child!, + ], + ), ), ), ); @@ -119,6 +88,8 @@ class ResponsePreview extends StatefulWidget { required this.showBorder, this.message, this.messageId, + this.showLeftBorder = true, + this.colorUsername = false, super.key, }); @@ -126,6 +97,8 @@ class ResponsePreview extends StatefulWidget { final String? messageId; final Group group; final bool showBorder; + final bool showLeftBorder; + final bool colorUsername; @override State createState() => _ResponsePreviewState(); @@ -212,80 +185,85 @@ class _ResponsePreviewState extends State { if (_message!.senderId == null) { _username = context.lang.you; - // _username = _message!.senderId.toString(); } 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), - ], + final hasImage = + _message != null && + _message!.mediaStored && + _mediaService != null && + _mediaService!.mediaFile.type != MediaType.audio; + + Widget? imageWidget; + if (hasImage) { + final isVideo = _mediaService!.mediaFile.type == MediaType.video; + final pathToCheck = isVideo + ? _mediaService!.thumbnailPath + : _mediaService!.storedPath; + if (pathToCheck.existsSync() && pathToCheck.lengthSync() > 0) { + imageWidget = Container( + height: 40, + width: 40, + margin: const EdgeInsets.only(left: 8), + child: ClipRRect( + borderRadius: BorderRadius.circular(4), + child: Image.file( + pathToCheck, + fit: BoxFit.cover, + ), ), ); } } return Container( - padding: const EdgeInsets.only(left: 10), - width: 200, - decoration: BoxDecoration( - border: Border( - left: BorderSide( - color: color, - width: 2, - ), - ), + 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: const TextStyle(fontWeight: FontWeight.bold), + style: TextStyle( + fontWeight: FontWeight.bold, + color: widget.colorUsername ? color : null, + ), ), - if (subtitle != null) Text(subtitle), + if (subtitle != null) + Text( + subtitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), ], ), ), - if (_mediaService != null && - _mediaService!.mediaFile.type != MediaType.audio) - () { - final isVideo = _mediaService!.mediaFile.type == MediaType.video; - final pathToCheck = isVideo - ? _mediaService!.thumbnailPath - : _mediaService!.storedPath; - if (pathToCheck.existsSync() && pathToCheck.lengthSync() > 0) { - return SizedBox( - height: widget.showBorder ? 100 : 210, - child: Image.file(pathToCheck), - ); - } - return const SizedBox.shrink(); - }(), + if (imageWidget != null) imageWidget, ], ), );