@@ -20,13 +20,15 @@ import '../../../config/app_config.dart';
2020import '../../../utils/event_checkbox_extension.dart' ;
2121import '../../../utils/platform_infos.dart' ;
2222import '../../../utils/url_launcher.dart' ;
23+ import '../../../utils/url_preview_service.dart' ;
2324import 'audio_player.dart' ;
2425import 'call_notify_event.dart' ;
2526import 'cute_events.dart' ;
2627import 'html_message.dart' ;
2728import 'image_bubble.dart' ;
2829import 'map_bubble.dart' ;
2930import 'message_download_content.dart' ;
31+ import 'url_preview.dart' ;
3032
3133class MessageContent extends StatelessWidget {
3234 final Event event;
@@ -285,51 +287,66 @@ class MessageContent extends StatelessWidget {
285287 final bigEmotes =
286288 ! event.isRichMessage && bigEmojis.contains (event.body);
287289
290+ final urls = UrlPreviewService .extractUrls (event.body);
291+
288292 return Padding (
289293 padding: const EdgeInsets .symmetric (horizontal: 12 , vertical: 8 ),
290- child: Stack (
294+ child: Column (
295+ crossAxisAlignment: CrossAxisAlignment .start,
296+ mainAxisSize: MainAxisSize .min,
291297 children: [
292- HtmlMessage (
293- html: html,
294- textColor: textColor,
295- room: event.room,
296- fontSize: AppSettings .fontSizeFactor.value * AppConfig .messageFontSize * (bigEmotes ? 5 : 1 ),
297- limitHeight: ! selected,
298- linkStyle: TextStyle (
299- color: linkColor,
300- fontSize: AppSettings .fontSizeFactor.value * AppConfig .messageFontSize,
301- decoration: TextDecoration .underline,
302- decorationColor: linkColor,
303- ),
304- onOpen: (url) => UrlLauncher (context, url.url).launchUrl (),
305- eventId: event.eventId,
306- checkboxCheckedEvents: event.aggregatedEvents (
307- timeline,
308- EventCheckboxRoomExtension .relationshipType,
309- ),
310- trailingWidget: SizedBox (
311- width: isReplied
312- ? double .infinity
313- : messageStatus == null
314- ? 46
315- : 60 ,
316- height: 14 ,
317- ),
318- ),
298+ Stack (
299+ children: [
300+ HtmlMessage (
301+ html: html,
302+ textColor: textColor,
303+ room: event.room,
304+ fontSize: AppSettings .fontSizeFactor.value * AppConfig .messageFontSize * (bigEmotes ? 5 : 1 ),
305+ limitHeight: ! selected,
306+ linkStyle: TextStyle (
307+ color: linkColor,
308+ fontSize: AppSettings .fontSizeFactor.value * AppConfig .messageFontSize,
309+ decoration: TextDecoration .underline,
310+ decorationColor: linkColor,
311+ ),
312+ onOpen: (url) => UrlLauncher (context, url.url).launchUrl (),
313+ eventId: event.eventId,
314+ checkboxCheckedEvents: event.aggregatedEvents (
315+ timeline,
316+ EventCheckboxRoomExtension .relationshipType,
317+ ),
318+ trailingWidget: SizedBox (
319+ width: isReplied
320+ ? double .infinity
321+ : messageStatus == null
322+ ? 46
323+ : 60 ,
324+ height: 14 ,
325+ ),
326+ ),
319327
320- // Time - always in the lower right corner
321- Positioned (
322- right: 0 ,
323- bottom: 0 ,
324- child: Row (
325- mainAxisSize: MainAxisSize .min,
326- children: [
327- Text (formattedTime, style: TextStyle (color: textColor, fontSize: 12 )),
328- if (messageStatus != null ) const SizedBox (width: 3 ),
329- if (messageStatus != null ) MessageStatusWidget (status: messageStatus, iconColor: textColor),
330- ],
331- ),
328+ // Time - always in the lower right corner
329+ Positioned (
330+ right: 0 ,
331+ bottom: 0 ,
332+ child: Row (
333+ mainAxisSize: MainAxisSize .min,
334+ children: [
335+ Text (formattedTime, style: TextStyle (color: textColor, fontSize: 12 )),
336+ if (messageStatus != null ) const SizedBox (width: 3 ),
337+ if (messageStatus != null ) MessageStatusWidget (status: messageStatus, iconColor: textColor),
338+ ],
339+ ),
340+ ),
341+ ],
332342 ),
343+ if (urls.isNotEmpty)
344+ UrlPreviewWidget (
345+ key: ValueKey ('preview_${event .eventId }_${urls .first }' ),
346+ url: urls.first,
347+ textColor: textColor,
348+ linkColor: linkColor,
349+ ),
333350 ],
334351 ),
335352 );
0 commit comments