diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index c44323d..6592a2a 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:ht_auth_api/ht_auth_api.dart'; @@ -16,7 +15,9 @@ import 'package:ht_main/app/config/config.dart' as app_config; import 'package:ht_main/app/services/demo_data_migration_service.dart'; import 'package:ht_main/bloc_observer.dart'; import 'package:ht_shared/ht_shared.dart'; +import 'package:ht_ui_kit/ht_ui_kit.dart'; import 'package:logging/logging.dart'; +import 'package:timeago/timeago.dart' as timeago; Future bootstrap( app_config.AppConfig appConfig, @@ -25,6 +26,9 @@ Future bootstrap( WidgetsFlutterBinding.ensureInitialized(); Bloc.observer = const AppBlocObserver(); + timeago.setLocaleMessages('en', EnTimeagoMessages()); + timeago.setLocaleMessages('ar', ArTimeagoMessages()); + final logger = Logger('bootstrap'); final kvStorage = await HtKvStorageSharedPreferences.getInstance(); diff --git a/lib/headlines-search/view/headlines_search_page.dart b/lib/headlines-search/view/headlines_search_page.dart index 6c7f221..1e3cc12 100644 --- a/lib/headlines-search/view/headlines_search_page.dart +++ b/lib/headlines-search/view/headlines_search_page.dart @@ -9,6 +9,7 @@ import 'package:ht_main/app/bloc/app_bloc.dart'; import 'package:ht_main/headlines-search/bloc/headlines_search_bloc.dart'; // import 'package:ht_main/headlines-search/widgets/country_item_widget.dart'; import 'package:ht_main/headlines-search/widgets/source_item_widget.dart'; +import 'package:ht_main/headlines-search/widgets/topic_item_widget.dart'; import 'package:ht_main/l10n/l10n.dart'; import 'package:ht_main/router/routes.dart'; import 'package:ht_main/shared/extensions/content_type_extensions.dart'; @@ -332,8 +333,7 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> { } return tile; } else if (feedItem is Topic) { - // TODO(user): Create a TopicItemWidget similar to CategoryItemWidget - return ListTile(title: Text(feedItem.name)); + return TopicItemWidget(topic: feedItem); } else if (feedItem is Source) { return SourceItemWidget(source: feedItem); } else if (feedItem is Ad) { diff --git a/lib/headlines-search/widgets/topic_item_widget.dart b/lib/headlines-search/widgets/topic_item_widget.dart new file mode 100644 index 0000000..4376985 --- /dev/null +++ b/lib/headlines-search/widgets/topic_item_widget.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:ht_main/entity_details/view/entity_details_page.dart'; +import 'package:ht_main/router/routes.dart'; +import 'package:ht_shared/ht_shared.dart'; + +/// A simple widget to display a Topic search result. +class TopicItemWidget extends StatelessWidget { + const TopicItemWidget({required this.topic, super.key}); + + final Topic topic; + + @override + Widget build(BuildContext context) { + return ListTile( + title: Text(topic.name), + subtitle: topic.description.isNotEmpty + ? Text( + topic.description, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ) + : null, + onTap: () { + context.push( + Routes.topicDetails, + extra: EntityDetailsPageArguments(entity: topic), + ); + }, + ); + } +} diff --git a/lib/shared/widgets/headline_tile_image_start.dart b/lib/shared/widgets/headline_tile_image_start.dart index 45a0853..6b9de30 100644 --- a/lib/shared/widgets/headline_tile_image_start.dart +++ b/lib/shared/widgets/headline_tile_image_start.dart @@ -4,6 +4,7 @@ import 'package:ht_main/entity_details/view/entity_details_page.dart'; import 'package:ht_main/router/routes.dart'; import 'package:ht_shared/ht_shared.dart'; import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:timeago/timeago.dart' as timeago; /// {@template headline_tile_image_start} /// A shared widget to display a headline item with a small image at the start. @@ -136,8 +137,7 @@ class _HeadlineMetadataRow extends StatelessWidget { @override Widget build(BuildContext context) { - // TODO(anyone): Use a proper timeago library. - final formattedDate = headline.createdAt.toString(); + final formattedDate = timeago.format(headline.createdAt); // Use bodySmall for a reasonable base size, with muted accent color final metadataTextStyle = textTheme.bodySmall?.copyWith( diff --git a/lib/shared/widgets/headline_tile_image_top.dart b/lib/shared/widgets/headline_tile_image_top.dart index 440de32..6ae541e 100644 --- a/lib/shared/widgets/headline_tile_image_top.dart +++ b/lib/shared/widgets/headline_tile_image_top.dart @@ -4,6 +4,7 @@ import 'package:ht_main/entity_details/view/entity_details_page.dart'; import 'package:ht_main/router/routes.dart'; import 'package:ht_shared/ht_shared.dart'; import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:timeago/timeago.dart' as timeago; /// {@template headline_tile_image_top} /// A shared widget to display a headline item with a large image at the top. @@ -147,8 +148,7 @@ class _HeadlineMetadataRow extends StatelessWidget { @override Widget build(BuildContext context) { - // TODO(anyone): Use a proper timeago library. - final formattedDate = headline.createdAt.toString(); + final formattedDate = timeago.format(headline.createdAt); // Use bodySmall for a reasonable base size, with muted accent color final metadataTextStyle = textTheme.bodySmall?.copyWith( diff --git a/lib/shared/widgets/headline_tile_text_only.dart b/lib/shared/widgets/headline_tile_text_only.dart index 3bc4c0e..a895095 100644 --- a/lib/shared/widgets/headline_tile_text_only.dart +++ b/lib/shared/widgets/headline_tile_text_only.dart @@ -4,6 +4,7 @@ import 'package:ht_main/entity_details/view/entity_details_page.dart'; import 'package:ht_main/router/routes.dart'; import 'package:ht_shared/ht_shared.dart'; import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:timeago/timeago.dart' as timeago; /// {@template headline_tile_text_only} /// A widget to display a headline item with text only. @@ -108,8 +109,7 @@ class _HeadlineMetadataRow extends StatelessWidget { @override Widget build(BuildContext context) { - // TODO(anyone): Use a proper timeago library. - final formattedDate = headline.createdAt.toString(); + final formattedDate = timeago.format(headline.createdAt); // Use bodySmall for a reasonable base size, with muted accent color final metadataTextStyle = textTheme.bodySmall?.copyWith( diff --git a/pubspec.lock b/pubspec.lock index a0790ec..0975732 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -416,7 +416,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: abef81e5294d70ace82d3e87f1efc94fca6a8445 + resolved-ref: "7945773edb4251d294071820c4ce1b6332f032ec" url: "https://github.com/headlines-toolkit/ht-data-inmemory.git" source: git version: "0.0.0"