diff --git a/lib/explore/widgets/articles_preview.dart b/lib/explore/widgets/articles_preview.dart index 7bf0825..3b311dc 100644 --- a/lib/explore/widgets/articles_preview.dart +++ b/lib/explore/widgets/articles_preview.dart @@ -31,7 +31,7 @@ class ArticlesPreview extends StatelessWidget { child: Text('Latest News'), ), SizedBox( - height: 350, + height: 300, child: articles.isNotEmpty ? ListView.builder( scrollDirection: Axis.horizontal, @@ -41,9 +41,8 @@ class ArticlesPreview extends StatelessWidget { width: 300, child: Padding( padding: const EdgeInsets.only(right: kListSpacing), - child: ArticleCard( + child: ArticleCard.preview( expandVertically: true, - previewMode: true, article: articles[index], ), ), diff --git a/lib/launches/widgets/launch_date_card.dart b/lib/launches/widgets/launch_date_card.dart index 3d619b8..fc4b796 100644 --- a/lib/launches/widgets/launch_date_card.dart +++ b/lib/launches/widgets/launch_date_card.dart @@ -29,17 +29,10 @@ class LaunchDateCard extends StatelessWidget { @override Widget build(BuildContext context) { - String? localMMMd; - String? localEEEE; - String? localHm; - String? utcTime; - - if (date != null) { - localMMMd = formatDate(date, dateFormat: DateFormat.MMMd()); - localEEEE = formatDate(date, dateFormat: DateFormat.EEEE()); - localHm = formatDate(date?.toLocal(), dateFormat: DateFormat.Hm()); - utcTime = formatDate(date?.toUtc(), dateFormat: DateFormat.Hm()); - } + final localMMMd = formatDate(date, dateFormat: DateFormat.MMMd()); + final localEEEE = formatDate(date, dateFormat: DateFormat.EEEE()); + final localHm = formatDate(date?.toLocal(), dateFormat: DateFormat.Hm()); + final utcTime = formatDate(date?.toUtc(), dateFormat: DateFormat.Hm()); return ExploreCard( trailing: LaunchStatus(status), diff --git a/lib/news/widgets/article_card.dart b/lib/news/widgets/article_card.dart index 0c424e8..4848102 100644 --- a/lib/news/widgets/article_card.dart +++ b/lib/news/widgets/article_card.dart @@ -1,8 +1,8 @@ // Flutter imports: import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; // Package imports: -import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import 'package:spaceflight_news_repository/spaceflight_news_repository.dart'; @@ -21,15 +21,40 @@ class ArticleCard extends StatelessWidget { required this.article, this.isSaved = false, this.expandVertically = false, - this.previewMode = false, super.key, - }); + }) : previewMode = false; + + const ArticleCard.preview({ + required this.article, + this.isSaved = false, + this.expandVertically = false, + super.key, + }) : previewMode = true; final Article article; final bool isSaved; final bool expandVertically; final bool previewMode; + Future launchUrlAndSetOverlayStyle( + Uri uri, + BuildContext context, + ) async { + WidgetsBinding.instance.renderView.automaticSystemUiAdjustment = false; + + final brightness = MediaQuery.of(context).platformBrightness; + + if (brightness == Brightness.light) { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); + } else { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light); + } + + await launchUrlString(article.url); + + WidgetsBinding.instance.renderView.automaticSystemUiAdjustment = true; + } + @override Widget build(BuildContext context) { if (previewMode) { @@ -60,15 +85,29 @@ class ArticleCard extends StatelessWidget { padding: const EdgeInsets.all(10), child: Column( children: [ - AutoSizeText( + Text( article.title, style: Theme.of(context).textTheme.titleMedium, - maxLines: 3, + overflow: TextOverflow.ellipsis, + maxLines: 2, ), const SizedBox(height: kListSpacing), - Flexible( - child: AutoSizeText( - '${article.summary.split(' ').take(25).join(' ')}...', + Expanded( + child: LayoutBuilder( + builder: (context, constraints) { + final maxLines = ((constraints.maxHeight - 10) / + Theme.of(context) + .textTheme + .bodyMedium! + .fontSize!) + .floor(); + + return Text( + article.summary, + overflow: TextOverflow.ellipsis, + maxLines: maxLines, + ); + }, ), ), ], @@ -81,61 +120,71 @@ class ArticleCard extends StatelessWidget { } else { return ExploreCard( expandVertically: expandVertically, - title: Text(article.newsSite), + title: Text( + article.newsSite, + ), trailing: Text( - '${formatDate( - article.publishedAt, - dateFormat: DateFormat.Hm(), - )} ${formatDate( - article.publishedAt, - dateFormat: DateFormat.yMMMd(), - )}', + formatDate( + article.publishedAt, + dateFormat: DateFormat.yMMMd(), + ) ?? + 'N/A', + style: TextStyle( + color: Theme.of(context).colorScheme.tertiary, + ), ), padding: EdgeInsets.zero, - onTap: () => launchUrlString(article.url), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + onTap: () => launchUrlAndSetOverlayStyle( + Uri.parse(article.url), + context, + ), + child: Row( children: [ - MissionImage( - fit: BoxFit.cover, - imageUrl: article.imageUrl, + SizedBox( + width: 100, + height: 100, + child: MissionImage( + fit: BoxFit.cover, + imageUrl: article.imageUrl, + ), ), - Padding( - padding: const EdgeInsets.all(10), - child: Column( - children: [ - Row( - children: [ - Expanded( - flex: 10, - child: Text( - article.title, - style: Theme.of(context).textTheme.titleMedium, + Flexible( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Text( + article.title, + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.titleMedium, + ), ), - ), - const Spacer(), - IconToggleButton( - icon: const Icon(Icons.bookmark_outline_rounded), - selectedIcon: const Icon(Icons.bookmark_rounded), - getDefaultStyle: enabledFilledTonalButtonStyle, - selected: isSaved, - onToggle: (isToggled) { - if (isToggled) { - context - .read() - .add(NewsArticleSaveRequested(article)); - } else { - context - .read() - .add(NewsArticleUnsaveRequested(article)); - } - }, - ), - ], - ), - const SizedBox(height: kListSpacing), - Text(article.summary), - ], + const SizedBox(width: kListSpacing), + IconToggleButton( + icon: const Icon(Icons.bookmark_outline_rounded), + selectedIcon: const Icon(Icons.bookmark_rounded), + getDefaultStyle: enabledFilledTonalButtonStyle, + selected: isSaved, + onToggle: (isToggled) { + if (isToggled) { + context + .read() + .add(NewsArticleSaveRequested(article)); + } else { + context + .read() + .add(NewsArticleUnsaveRequested(article)); + } + }, + ), + ], + ), + ], + ), ), ), ],