From b43b43411cf2a06bbb4af0761d8acf2807718945 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Mon, 22 May 2023 09:30:03 -0600 Subject: Auto scroll to bottom --- lib/screens/chat_screen.dart | 11 ++++++ lib/widgets/chat_bubble.dart | 81 +++++++++++++++++++++++--------------------- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index d3d71ad..bd0d5d7 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -22,6 +22,8 @@ class _ChatScreenState extends State { final Auth _auth = Auth(); final Database _db = Database(); + final ScrollController _scroll = ScrollController(); + @override Widget build(BuildContext context) { List arguments = @@ -64,8 +66,17 @@ class _ChatScreenState extends State { stream: _db.getMessagesByGroupId(group!.id!), builder: (context, snapshot) { if (snapshot.hasData) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (_scroll.hasClients) { + _scroll.animateTo(_scroll.position.maxScrollExtent, + duration: const Duration(milliseconds: 500), + curve: Curves.fastOutSlowIn); + } + }); + List msgs = snapshot.data!; return ListView.builder( + controller: _scroll, padding: const EdgeInsets.only(bottom: 80.0), itemCount: snapshot.data!.length, itemBuilder: (context, index) => ChatBubble( diff --git a/lib/widgets/chat_bubble.dart b/lib/widgets/chat_bubble.dart index 1459da5..ba90f6b 100644 --- a/lib/widgets/chat_bubble.dart +++ b/lib/widgets/chat_bubble.dart @@ -3,6 +3,7 @@ import 'package:custom_clippers/custom_clippers.dart'; import 'package:flutter/material.dart'; import 'package:linkchat/models/message.dart'; import 'package:url_launcher/link.dart'; +import 'package:url_launcher/url_launcher.dart'; enum ChatBubbleAlignment { start, end } @@ -122,45 +123,47 @@ class LinkPreview extends StatelessWidget { padding: const EdgeInsets.only(bottom: 8.0), child: Card( clipBehavior: Clip.antiAliasWithSaveLayer, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - message.linkPhotoURL != null - // ? FadeInImage( - // placeholder: const AssetImage('assets/loading.gif'), - // image: NetworkImage(message.linkPhotoURL!), - // imageErrorBuilder: (context, error, stackTrace) => - // const SizedBox.shrink(), - // fit: BoxFit.fill, - // ) - ? CachedNetworkImage( - imageUrl: message.linkPhotoURL!, - placeholder: (context, url) => - Image.asset('assets/loading.gif'), - errorWidget: (context, url, error) => - const SizedBox.shrink(), - ) - : const SizedBox.shrink(), - message.linkTitle != null - ? Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - message.linkTitle!, - style: Theme.of(context) - .textTheme - .bodyLarge! - .copyWith(fontWeight: FontWeight.bold), - ), - ) - : const SizedBox.shrink(), - message.linkDescription != null - ? Padding( - padding: - const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), - child: Text(message.linkDescription!), - ) - : const SizedBox.shrink(), - ], + semanticContainer: true, + child: InkWell( + onTap: () { + launchUrl( + Uri.parse(message.messageText), + mode: LaunchMode.externalApplication, + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + message.linkPhotoURL != null + ? CachedNetworkImage( + imageUrl: message.linkPhotoURL!, + placeholder: (context, url) => + Image.asset('assets/loading.gif'), + errorWidget: (context, url, error) => + const SizedBox.shrink(), + ) + : const SizedBox.shrink(), + message.linkTitle != null + ? Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + message.linkTitle!, + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.bold), + ), + ) + : const SizedBox.shrink(), + message.linkDescription != null + ? Padding( + padding: + const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), + child: Text(message.linkDescription!), + ) + : const SizedBox.shrink(), + ], + ), ), ), ) -- cgit v1.2.3