From e0aa489478399182f4569026139656f52da56188 Mon Sep 17 00:00:00 2001 From: Marcin Wojnarowski Date: Wed, 3 Nov 2021 22:50:03 +0100 Subject: [PATCH] Fix/overflows (#278) * Fix overflow issues * Add changelog entry * Fix uneven paddings * Fix avatar padding * Better cover the background image * Add changelog entry --- CHANGELOG.md | 5 + lib/pages/community.dart | 149 +++++++++---------- lib/pages/profile_tab.dart | 12 +- lib/widgets/avatar.dart | 27 +++- lib/widgets/post/post_info_section.dart | 188 ++++++++++++------------ lib/widgets/user_profile.dart | 104 ++++++------- 6 files changed, 248 insertions(+), 237 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5d2be..d2a48ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ - Fixed a bug where post would go out of sync with full version of the post - Fixed a bug where making a comment selectable would not always result in making the comment selectable - Full post will now open no matter where you press on the post card +- Fixed overflows in various places + +### Changed + +- User banner photo now fits better on user profile ## v0.6.0 - 2021-09-06 diff --git a/lib/pages/community.dart b/lib/pages/community.dart index f441382..76d4419 100644 --- a/lib/pages/community.dart +++ b/lib/pages/community.dart @@ -266,98 +266,93 @@ class _CommunityOverview extends StatelessWidget { ) : null; - return Stack(children: [ - if (community.community.banner != null) - FullscreenableImage( - url: community.community.banner!, - child: CachedNetworkImage( - imageUrl: community.community.banner!, - errorBuilder: (_, ___) => const SizedBox.shrink(), + return Stack( + children: [ + if (community.community.banner != null) + FullscreenableImage( + url: community.community.banner!, + child: CachedNetworkImage( + imageUrl: community.community.banner!, + errorBuilder: (_, ___) => const SizedBox.shrink(), + ), ), - ), - SafeArea( - child: Padding( - padding: const EdgeInsets.only(top: 45), - child: Column(children: [ - if (icon != null) icon, - // NAME - Center( - child: Padding( - padding: const EdgeInsets.only(top: 10), - child: RichText( - overflow: TextOverflow.ellipsis, // TODO: fix overflowing - text: TextSpan( - style: - theme.textTheme.subtitle1?.copyWith(shadows: [shadow]), - children: [ - const TextSpan( - text: '!', - style: TextStyle(fontWeight: FontWeight.w200)), - TextSpan( - text: community.community.name, - style: const TextStyle(fontWeight: FontWeight.w600)), - const TextSpan( - text: '@', - style: TextStyle(fontWeight: FontWeight.w200)), - TextSpan( - text: community.community.originInstanceHost, - style: const TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToInstance( - context, community.community.originInstanceHost), - ), - ], - ), + SafeArea( + child: Column( + children: [ + const SizedBox(height: 45), + if (icon != null) icon, + const SizedBox(height: 10), + // NAME + RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: theme.textTheme.subtitle1?.copyWith(shadows: [shadow]), + children: [ + const TextSpan( + text: '!', + style: TextStyle(fontWeight: FontWeight.w200), + ), + TextSpan( + text: community.community.name, + style: const TextStyle(fontWeight: FontWeight.w600), + ), + const TextSpan( + text: '@', + style: TextStyle(fontWeight: FontWeight.w200), + ), + TextSpan( + text: community.community.originInstanceHost, + style: const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToInstance( + context, + community.community.originInstanceHost, + ), + ), + ], ), ), - ), - // TITLE/MOTTO - Center( - child: Padding( - padding: const EdgeInsets.only(top: 8, left: 20, right: 20), + // TITLE/MOTTO + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), child: Text( community.community.title, textAlign: TextAlign.center, - style: - TextStyle(fontWeight: FontWeight.w300, shadows: [shadow]), + style: TextStyle( + fontWeight: FontWeight.w300, + shadows: [shadow], + ), ), ), - ), - Padding( - padding: const EdgeInsets.only(top: 20), - child: Stack( + const SizedBox(height: 20), + Stack( + alignment: Alignment.center, children: [ // INFO ICONS - Padding( - padding: const EdgeInsets.only(top: 5), - child: Row( - children: [ - const Spacer(), - const Padding( - padding: EdgeInsets.only(right: 3), - child: Icon(Icons.people, size: 20), - ), - Text(compactNumber(community.counts.subscribers)), - const Spacer(flex: 4), - const Padding( - padding: EdgeInsets.only(right: 3), - child: Icon(Icons.record_voice_over, size: 20), - ), - Text(onlineUsers == null - ? 'xx' - : compactNumber(onlineUsers!)), - const Spacer(), - ], - ), + Row( + children: [ + const Spacer(), + const Icon(Icons.people, size: 20), + const SizedBox(width: 3), + Text(compactNumber(community.counts.subscribers)), + const Spacer(flex: 4), + const Icon(Icons.record_voice_over, size: 20), + const SizedBox(width: 3), + Text(onlineUsers == null + ? 'xx' + : compactNumber(onlineUsers!)), + const Spacer(), + ], ), _FollowButton(community), ], ), - ), - ]), + ], + ), ), - ), - ]); + ], + ); } } diff --git a/lib/pages/profile_tab.dart b/lib/pages/profile_tab.dart index ce10411..d7f9555 100644 --- a/lib/pages/profile_tab.dart +++ b/lib/pages/profile_tab.dart @@ -76,11 +76,13 @@ class UserProfileTab extends HookWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - // TODO: fix overflow issues - displayValue, - style: theme.appBarTheme.titleTextStyle, - overflow: TextOverflow.fade, + Flexible( + child: Text( + displayValue, + style: theme.appBarTheme.titleTextStyle, + overflow: TextOverflow.fade, + softWrap: false, + ), ), const Icon(Icons.expand_more), ], diff --git a/lib/widgets/avatar.dart b/lib/widgets/avatar.dart index 21ad949..0499810 100644 --- a/lib/widgets/avatar.dart +++ b/lib/widgets/avatar.dart @@ -15,11 +15,17 @@ class Avatar extends HookWidget { this.radius = 25, this.noBlank = false, this.alwaysShow = false, + this.padding = EdgeInsets.zero, + this.onTap, }) : super(key: key); final String? url; final double radius; final bool noBlank; + final VoidCallback? onTap; + + /// padding is applied unless blank widget is returned + final EdgeInsetsGeometry padding; /// Overrides the `showAvatars` setting final bool alwaysShow; @@ -44,13 +50,20 @@ class Avatar extends HookWidget { return blankWidget; } - return ClipOval( - child: CachedNetworkImage( - height: radius * 2, - width: radius * 2, - imageUrl: imageUrl, - fit: BoxFit.cover, - errorBuilder: (_, __) => blankWidget, + return Padding( + padding: padding, + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(radius), + child: ClipOval( + child: CachedNetworkImage( + height: radius * 2, + width: radius * 2, + imageUrl: imageUrl, + fit: BoxFit.cover, + errorBuilder: (_, __) => blankWidget, + ), + ), ), ); } diff --git a/lib/widgets/post/post_info_section.dart b/lib/widgets/post/post_info_section.dart index c543da1..2da9ea4 100644 --- a/lib/widgets/post/post_info_section.dart +++ b/lib/widgets/post/post_info_section.dart @@ -23,105 +23,107 @@ class PostInfoSection extends StatelessWidget { final instanceHost = store.postView.instanceHost; final theme = Theme.of(context); - return Column( - children: [ - Padding( - padding: const EdgeInsets.all(10), - child: Row( - children: [ - if (post.community.icon != null) - Padding( - padding: const EdgeInsets.only(right: 10), - child: InkWell( - borderRadius: BorderRadius.circular(20), - onTap: () => goToCommunity.byId( - context, instanceHost, post.community.id), - child: Avatar( - url: post.community.icon, - noBlank: true, - radius: 20, + return Padding( + padding: const EdgeInsets.all(10), + child: Row( + children: [ + Avatar( + url: post.community.icon, + padding: const EdgeInsets.only(right: 10), + onTap: () => + goToCommunity.byId(context, instanceHost, post.community.id), + noBlank: true, + radius: 20, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + overflow: TextOverflow.fade, + softWrap: false, + text: TextSpan( + style: TextStyle( + fontSize: 15, + color: theme.textTheme.bodyText1?.color, ), + children: [ + const TextSpan( + text: '!', + style: TextStyle(fontWeight: FontWeight.w300), + ), + TextSpan( + text: post.community.name, + style: const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToCommunity.byId( + context, + instanceHost, + post.community.id, + ), + ), + const TextSpan( + text: '@', + style: TextStyle(fontWeight: FontWeight.w300), + ), + TextSpan( + text: post.post.originInstanceHost, + style: const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToInstance( + context, + post.post.originInstanceHost, + ), + ), + ], ), ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - RichText( - overflow: TextOverflow.ellipsis, // TODO: fix overflowing - text: TextSpan( - style: TextStyle( - fontSize: 15, - color: theme.textTheme.bodyText1?.color), - children: [ - const TextSpan( - text: '!', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.community.name, - style: - const TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToCommunity.byId( - context, instanceHost, post.community.id)), - const TextSpan( - text: '@', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.post.originInstanceHost, - style: - const TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToInstance( - context, post.post.originInstanceHost)), - ], + RichText( + overflow: TextOverflow.fade, + softWrap: false, + text: TextSpan( + style: TextStyle( + fontSize: 13, + color: theme.textTheme.bodyText1?.color, ), + children: [ + TextSpan( + text: L10n.of(context)!.by, + style: const TextStyle(fontWeight: FontWeight.w300), + ), + TextSpan( + text: ' ${post.creator.originPreferredName}', + style: const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToUser.fromPersonSafe( + context, + post.creator, + ), + ), + TextSpan(text: ' 路 ${post.post.published.fancyShort}'), + if (post.post.locked) const TextSpan(text: ' 路 馃敀'), + if (post.post.stickied) const TextSpan(text: ' 路 馃搶'), + if (post.post.nsfw) const TextSpan(text: ' 路 '), + if (post.post.nsfw) + TextSpan( + text: L10n.of(context)!.nsfw, + style: const TextStyle(color: Colors.red), + ), + if (store.urlDomain != null) + TextSpan(text: ' 路 ${store.urlDomain}'), + if (post.post.removed) + const TextSpan(text: ' 路 REMOVED'), + if (post.post.deleted) + const TextSpan(text: ' 路 DELETED'), + ], ), - RichText( - overflow: TextOverflow.ellipsis, - text: TextSpan( - style: TextStyle( - fontSize: 13, - color: theme.textTheme.bodyText1?.color), - children: [ - TextSpan( - text: L10n.of(context)!.by, - style: const TextStyle(fontWeight: FontWeight.w300), - ), - TextSpan( - text: ' ${post.creator.originPreferredName}', - style: const TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToUser.fromPersonSafe( - context, - post.creator, - ), - ), - TextSpan( - text: ' 路 ${post.post.published.fancyShort}'), - if (post.post.locked) const TextSpan(text: ' 路 馃敀'), - if (post.post.stickied) const TextSpan(text: ' 路 馃搶'), - if (post.post.nsfw) const TextSpan(text: ' 路 '), - if (post.post.nsfw) - TextSpan( - text: L10n.of(context)!.nsfw, - style: const TextStyle(color: Colors.red)), - if (store.urlDomain != null) - TextSpan(text: ' 路 ${store.urlDomain}'), - if (post.post.removed) - const TextSpan(text: ' 路 REMOVED'), - if (post.post.deleted) - const TextSpan(text: ' 路 DELETED'), - ], - ), - ) - ], - ), - const Spacer(), - if (!fullPost) const PostMoreMenuButton(), - ], + ) + ], + ), ), - ), - ], + if (!fullPost) const PostMoreMenuButton(), + ], + ), ); }); } diff --git a/lib/widgets/user_profile.dart b/lib/widgets/user_profile.dart index ddcaf9c..555528d 100644 --- a/lib/widgets/user_profile.dart +++ b/lib/widgets/user_profile.dart @@ -140,49 +140,47 @@ class _UserOverview extends HookWidget { textColorBasedOnBackground(theme.colorScheme.secondary); return Stack( + fit: StackFit.expand, children: [ if (userView.person.banner != null) - // TODO: for some reason doesnt react to presses - FullscreenableImage( - url: userView.person.banner!, - child: CachedNetworkImage( - imageUrl: userView.person.banner!, - errorBuilder: (_, ___) => const SizedBox.shrink(), + Align( + alignment: Alignment.topCenter, + child: FullscreenableImage( + url: userView.person.banner!, + child: CachedNetworkImage( + fit: BoxFit.cover, + height: MediaQuery.of(context).padding.top + 100, + width: double.infinity, + imageUrl: userView.person.banner!, + errorBuilder: (_, ___) => const SizedBox.shrink(), + ), ), ) else - Container( - width: double.infinity, - height: 200, - color: theme.colorScheme.secondary, - ), - Container( - height: 200, - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: FractionalOffset.topCenter, - end: FractionalOffset.bottomCenter, - colors: [ - Colors.black26, - Colors.transparent, - ], + ColoredBox(color: theme.colorScheme.secondary), + const IgnorePointer( + child: DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: FractionalOffset.topCenter, + end: FractionalOffset.bottomCenter, + colors: [ + Colors.black26, + Colors.transparent, + ], + ), ), ), ), SafeArea( child: Padding( padding: const EdgeInsets.only(top: 60), - child: SizedBox( - width: double.infinity, - height: double.infinity, - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topRight: Radius.circular(40), - topLeft: Radius.circular(40), - ), - color: theme.cardColor, + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: const BorderRadius.vertical( + top: Radius.circular(40), ), + color: theme.cardColor, ), ), ), @@ -191,25 +189,23 @@ class _UserOverview extends HookWidget { child: Column( children: [ if (userView.person.avatar != null) - SizedBox( + Container( width: 80, height: 80, - child: Container( - decoration: BoxDecoration( - boxShadow: const [ - BoxShadow(blurRadius: 6, color: Colors.black54) - ], - borderRadius: const BorderRadius.all(Radius.circular(15)), - border: Border.all(color: Colors.white, width: 3), - ), - child: ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(12)), - child: FullscreenableImage( - url: userView.person.avatar!, - child: CachedNetworkImage( - imageUrl: userView.person.avatar!, - errorBuilder: (_, ___) => const SizedBox.shrink(), - ), + decoration: BoxDecoration( + boxShadow: const [ + BoxShadow(blurRadius: 6, color: Colors.black54) + ], + borderRadius: const BorderRadius.all(Radius.circular(15)), + border: Border.all(color: Colors.white, width: 3), + ), + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(12)), + child: FullscreenableImage( + url: userView.person.avatar!, + child: CachedNetworkImage( + imageUrl: userView.person.avatar!, + errorBuilder: (_, ___) => const SizedBox.shrink(), ), ), ), @@ -292,13 +288,11 @@ class _UserOverview extends HookWidget { Icons.cake, size: 13, ), - Padding( - padding: const EdgeInsets.only(left: 4), - child: Text( - DateFormat('MMM dd, yyyy') - .format(userView.person.published), - style: theme.textTheme.bodyText1, - ), + const SizedBox(width: 4), + Text( + DateFormat('MMM dd, yyyy') + .format(userView.person.published), + style: theme.textTheme.bodyText1, ), ], ),