From 88782e05931ebaf06c012b64e19dabed989fb58a Mon Sep 17 00:00:00 2001 From: matiasleyba Date: Thu, 28 Nov 2024 13:22:22 -0300 Subject: [PATCH 1/2] refactor: remove PostCategory --- flutter_news_example/api/lib/client.dart | 1 - .../src/data/in_memory_news_data_source.dart | 2 +- .../api/lib/src/data/static_news_data.dart | 196 ++++++++++-------- .../packages/news_blocks/lib/news_blocks.dart | 1 - .../lib/src/article_introduction_block.dart | 8 +- .../lib/src/article_introduction_block.g.dart | 15 +- .../news_blocks/lib/src/category.dart | 3 + .../news_blocks/lib/src/post_block.dart | 8 +- .../news_blocks/lib/src/post_category.dart | 20 -- .../lib/src/post_grid_group_block.dart | 8 +- .../lib/src/post_grid_group_block.g.dart | 15 +- .../lib/src/post_grid_tile_block.dart | 6 +- .../lib/src/post_grid_tile_block.g.dart | 15 +- .../news_blocks/lib/src/post_large_block.dart | 2 +- .../lib/src/post_large_block.g.dart | 15 +- .../lib/src/post_medium_block.dart | 2 +- .../lib/src/post_medium_block.g.dart | 15 +- .../news_blocks/lib/src/post_small_block.dart | 2 +- .../lib/src/post_small_block.g.dart | 15 +- .../lib/src/video_introduction_block.dart | 8 +- .../lib/src/video_introduction_block.g.dart | 16 +- .../src/article_introduction_block_test.dart | 3 +- .../news_blocks/test/src/news_block_test.dart | 26 ++- .../test/src/news_blocks_converter_test.dart | 3 +- .../news_blocks/test/src/post_block_test.dart | 2 +- .../test/src/post_grid_group_block_test.dart | 5 +- .../test/src/post_grid_tile_block_test.dart | 11 +- .../test/src/post_large_block_test.dart | 3 +- .../test/src/post_medium_block_test.dart | 3 +- .../test/src/post_small_block_test.dart | 3 +- .../test/src/trending_story_block_test.dart | 3 +- .../test/src/video_intro_block_test.dart | 3 +- .../test/src/data/news_data_source_test.dart | 2 +- flutter_news_example/lib/app/view/app.dart | 6 + .../lib/article/widgets/article_content.dart | 9 +- .../article/widgets/article_content_item.dart | 16 +- .../lib/categories/bloc/categories_bloc.dart | 13 +- .../categories/bloc/categories_bloc.g.dart | 42 ---- .../lib/categories/bloc/categories_state.dart | 16 +- .../lib/feed/widgets/category_feed_item.dart | 10 + .../lib/home/view/home_page.dart | 6 - .../lib/src/article_introduction.dart | 6 +- .../news_blocks_ui/lib/src/post_grid.dart | 5 + .../lib/src/post_large/post_large.dart | 6 +- .../lib/src/video_introduction.dart | 11 +- .../test/src/article_introduction_test.dart | 5 +- .../test/src/post_grid_test.dart | 22 +- .../test/src/post_large/post_large_test.dart | 17 +- .../src/post_medium/post_medium_test.dart | 8 +- .../test/src/post_small_test.dart | 9 +- .../test/src/section_header_test.dart | 6 +- .../test/src/trending_story_test.dart | 3 +- .../test/src/video_introduction_test.dart | 9 +- .../test/app/view/app_test.dart | 12 ++ .../widgets/article_content_item_test.dart | 10 +- .../article_trailing_content_test.dart | 3 +- .../categories/bloc/categories_bloc_test.dart | 13 -- .../feed/widgets/category_feed_item_test.dart | 42 ++-- .../test/helpers/pump_app.dart | 18 ++ 59 files changed, 386 insertions(+), 377 deletions(-) delete mode 100644 flutter_news_example/api/packages/news_blocks/lib/src/post_category.dart delete mode 100644 flutter_news_example/lib/categories/bloc/categories_bloc.g.dart diff --git a/flutter_news_example/api/lib/client.dart b/flutter_news_example/api/lib/client.dart index a903d478a..d8ff3ae39 100644 --- a/flutter_news_example/api/lib/client.dart +++ b/flutter_news_example/api/lib/client.dart @@ -9,7 +9,6 @@ export 'package:news_blocks/news_blocks.dart' ImageBlock, NewsBlock, NewsBlocksConverter, - PostCategory, PostGridGroupBlock, PostGridTileBlock, PostLargeBlock, diff --git a/flutter_news_example/api/lib/src/data/in_memory_news_data_source.dart b/flutter_news_example/api/lib/src/data/in_memory_news_data_source.dart index 8b7a7038d..94a6939ba 100644 --- a/flutter_news_example/api/lib/src/data/in_memory_news_data_source.dart +++ b/flutter_news_example/api/lib/src/data/in_memory_news_data_source.dart @@ -115,7 +115,7 @@ class InMemoryNewsDataSource implements NewsDataSource { } @override - Future> getCategories() async => _newsFeedData.keys.toList(); + Future> getCategories() async => _categories; @override Future getUser({required String userId}) async { diff --git a/flutter_news_example/api/lib/src/data/static_news_data.dart b/flutter_news_example/api/lib/src/data/static_news_data.dart index 4b2db6d2f..57bc29864 100644 --- a/flutter_news_example/api/lib/src/data/static_news_data.dart +++ b/flutter_news_example/api/lib/src/data/static_news_data.dart @@ -57,7 +57,7 @@ final popularArticles = [ NewsItem( post: PostSmallBlock( id: '5c47495a-608b-4e8b-a7f0-642a02594888', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'CNN', publishedAt: DateTime(2022, 3, 17), imageUrl: @@ -72,7 +72,7 @@ final popularArticles = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Sean Hollister', publishedAt: DateTime(2022, 3, 17), title: 'Boeing makes third attempt to launch its ' @@ -93,7 +93,7 @@ final relevantArticles = [ NewsItem( post: PostSmallBlock( id: '781b6a65-0357-45c7-8789-3ee890e43e0e', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'CNN', publishedAt: DateTime(2022, 5, 20), imageUrl: @@ -104,7 +104,7 @@ final relevantArticles = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Sandee LaMotte', publishedAt: DateTime(2022, 5, 20), title: 'What is monkeypox and its signs and symptoms?', @@ -131,7 +131,7 @@ final technologyLargeItems = [ NewsItem( post: PostLargeBlock( id: '499305f6-5096-4051-afda-824dcfc7df23', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Sean Hollister', publishedAt: DateTime(2022, 4, 19), imageUrl: @@ -144,7 +144,7 @@ final technologyLargeItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Sean Hollister', publishedAt: DateTime(2022, 4, 19), title: 'Nvidia and AMD GPUs are returning to shelves ' @@ -260,7 +260,7 @@ final technologyLargeItems = [ TrendingStoryBlock( content: PostSmallBlock( id: '5c47497a-608b-4e9b-a7f0-642a02594900', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Fall Guys', publishedAt: DateTime(2022, 3, 9), imageUrl: @@ -278,7 +278,7 @@ final technologyLargeItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Sean Hollister', publishedAt: DateTime(2022, 4, 19), title: 'Nvidia and AMD GPUs are returning to shelves ' @@ -299,7 +299,7 @@ final technologyLargeItems = [ relatedArticles: [ PostSmallBlock( id: '2224b86e-60d6-461a-a5d8-e8e71589669f', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'The Drive', publishedAt: DateTime(2022, 3, 17), imageUrl: @@ -319,7 +319,7 @@ final technologyLargeItems = [ NewsItem( post: PostLargeBlock( id: '7dd29642-2bbd-40ea-80af-99e4381bbabb', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Jasmine Hicks', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -332,7 +332,7 @@ final technologyLargeItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Jasmine Hicks', publishedAt: DateTime(2022, 6, 2), title: @@ -344,7 +344,7 @@ final technologyLargeItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Jasmine Hicks', publishedAt: DateTime(2022, 6, 2), title: @@ -364,7 +364,7 @@ final technologyMediumItems = [ NewsItem( post: PostMediumBlock( id: 'd62a154f-b69a-4e8c-87ee-a1bdfcec3cfa', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Victoria Song', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -380,7 +380,7 @@ final technologyMediumItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Victoria Song', publishedAt: DateTime(2022, 6, 2), title: @@ -391,7 +391,7 @@ final technologyMediumItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Victoria Song', publishedAt: DateTime(2022, 6, 2), title: @@ -411,7 +411,7 @@ final technologySmallItems = [ NewsItem( post: PostSmallBlock( id: '36f4a017-d099-4fce-8727-1d9ca6a0398c', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Tom Phillips', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -426,7 +426,7 @@ final technologySmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Tom Phillips', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -437,7 +437,7 @@ final technologySmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Tom Phillips', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -453,7 +453,7 @@ final technologySmallItems = [ NewsItem( post: PostSmallBlock( id: 'f903c34b-e4a7-4db1-8945-94f9fb7c7284', - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Mike Andronico', publishedAt: DateTime(2022, 6, 2), title: 'Walmart has a big PS5 restock today — ' @@ -468,7 +468,7 @@ final technologySmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Victoria Song', publishedAt: DateTime(2022, 6, 2), title: 'Walmart has a big PS5 restock today — ' @@ -478,7 +478,7 @@ final technologySmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: _technologyCategory.id, author: 'Victoria Song', publishedAt: DateTime(2022, 6, 2), title: 'Walmart has a big PS5 restock today — ' @@ -503,7 +503,7 @@ final sportsLargeItems = [ NewsItem( post: PostLargeBlock( id: 'e24e8c44-fcba-4312-92bc-4da4c83e1f4b', - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Peter Brody', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -519,7 +519,7 @@ final sportsLargeItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Peter Brody', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -530,7 +530,7 @@ final sportsLargeItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Peter Brody', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -550,7 +550,7 @@ final sportsMediumItems = [ NewsItem( post: PostMediumBlock( id: '82c49bf1-946d-4920-a801-302291f367b5', - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Tom Dierberger', publishedAt: DateTime(2022, 5, 5), imageUrl: @@ -568,7 +568,7 @@ final sportsMediumItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Tom Dierberger', publishedAt: DateTime(2022, 5, 22), imageUrl: @@ -579,7 +579,7 @@ final sportsMediumItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Tom Dierberger', publishedAt: DateTime(2022, 5, 22), imageUrl: @@ -591,7 +591,7 @@ final sportsMediumItems = [ relatedArticles: [ PostSmallBlock( id: 'b77f8854-7483-4353-ac91-5a8a10e576b0', - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Bleacher Report', publishedAt: DateTime(2022, 3, 17), imageUrl: @@ -616,7 +616,7 @@ final sportsSmallItems = [ NewsItem( post: PostSmallBlock( id: 'b1e70b22-b7a3-4b07-808d-3735fe7131af', - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Jasmyn Wimbish', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -631,7 +631,7 @@ final sportsSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Jasmyn Wimbish', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -642,7 +642,7 @@ final sportsSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Jasmyn Wimbish', publishedAt: DateTime(2022, 6, 3), imageUrl: @@ -658,7 +658,7 @@ final sportsSmallItems = [ NewsItem( post: PostSmallBlock( id: '7f03f6bf-011f-49cf-88b8-08c79a21745c', - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Adam Rowe', publishedAt: DateTime(2022, 6, 3), title: 'Five-Star International Recruit Tyrese Proctor will reclassify ' @@ -671,7 +671,7 @@ final sportsSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Adam Rowe', publishedAt: DateTime(2022, 6, 3), title: 'Five-Star International Recruit Tyrese Proctor will reclassify ' @@ -680,7 +680,7 @@ final sportsSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.sports, + categoryId: _sportsCategory.id, author: 'Adam Rowe', publishedAt: DateTime(2022, 6, 3), title: 'Five-Star International Recruit Tyrese Proctor will reclassify ' @@ -705,7 +705,7 @@ final healthLargeItems = [ NewsItem( post: PostLargeBlock( id: 'f237463b-f4d8-4b23-a468-d448a446b03b', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -720,7 +720,7 @@ final healthLargeItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -731,7 +731,7 @@ final healthLargeItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -751,7 +751,7 @@ final healthMediumItems = [ NewsItem( post: PostMediumBlock( id: '057d4de4-a7c5-4dc3-b231-33052bcea53d', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -768,7 +768,7 @@ final healthMediumItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -779,7 +779,7 @@ final healthMediumItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Neuroscience News', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -799,7 +799,7 @@ final healthSmallItems = [ NewsItem( post: PostSmallBlock( id: 'b1fc2ffc-eb02-42ce-af65-79702172a987', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Northwestern University', publishedAt: DateTime(2022, 5, 4), imageUrl: 'https://scitechdaily.com/images/Ear-Hearing-Concept.jpg', @@ -815,7 +815,7 @@ final healthSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Northwestern University', publishedAt: DateTime(2022, 5, 4), imageUrl: 'https://scitechdaily.com/images/Ear-Hearing-Concept.jpg', @@ -825,7 +825,7 @@ final healthSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Northwestern University', publishedAt: DateTime(2022, 5, 4), imageUrl: 'https://scitechdaily.com/images/Ear-Hearing-Concept.jpg', @@ -836,7 +836,7 @@ final healthSmallItems = [ relatedArticles: [ PostSmallBlock( id: '7a5661d7-32a3-4b05-9fe2-7bc5ff8ea904', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'New York Times', publishedAt: DateTime(2022, 3, 17), imageUrl: @@ -856,7 +856,7 @@ final healthSmallItems = [ NewsItem( post: PostSmallBlock( id: '67c36008-42f3-4ed3-9bcc-2c96acaa27d3', - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Gabby Landsverk', publishedAt: DateTime(2022, 6, 2), title: 'Keto and Mediterranean diets both help manage blood sugar, ' @@ -871,7 +871,7 @@ final healthSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Gabby Landsverk', publishedAt: DateTime(2022, 6, 2), title: 'Keto and Mediterranean diets both help manage blood sugar, ' @@ -880,7 +880,7 @@ final healthSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.health, + categoryId: _healthCategory.id, author: 'Gabby Landsverk', publishedAt: DateTime(2022, 6, 2), title: 'Keto and Mediterranean diets both help manage blood sugar, ' @@ -906,7 +906,7 @@ final scienceLargeItems = [ NewsItem( post: PostLargeBlock( id: 'f6e66eb4-add9-4181-bf1e-ce09c629287d', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Megan Marples and Ashley Strickland', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -921,7 +921,7 @@ final scienceLargeItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Megan Marples and Ashley Strickland', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -931,7 +931,7 @@ final scienceLargeItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Megan Marples and Ashley Strickland', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -950,7 +950,7 @@ final scienceMediumItems = [ NewsItem( post: PostMediumBlock( id: '506271f9-394e-48e4-a6d8-9d438f561532', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Jeff Foust', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -965,7 +965,7 @@ final scienceMediumItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Jeff Foust', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -975,7 +975,7 @@ final scienceMediumItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Jeff Foust', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -994,7 +994,7 @@ final scienceSmallItems = [ NewsItem( post: PostSmallBlock( id: '1273746e-900d-45d9-a4f3-acbb462de797', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Tomasz Nowakowski', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -1009,7 +1009,7 @@ final scienceSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Tomasz Nowakowski', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -1019,7 +1019,7 @@ final scienceSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Tomasz Nowakowski', publishedAt: DateTime(2022, 6, 2), imageUrl: @@ -1034,7 +1034,7 @@ final scienceSmallItems = [ NewsItem( post: PostSmallBlock( id: '52c74e71-36b3-45aa-bc06-f50b1d2631fa', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Phil Plait', publishedAt: DateTime(2022, 6, 2), title: 'Are supermassive black holes killing their host galaxies?', @@ -1046,7 +1046,7 @@ final scienceSmallItems = [ ), content: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Phil Plait', publishedAt: DateTime(2022, 6, 2), title: 'Are supermassive black holes killing their host galaxies?', @@ -1054,7 +1054,7 @@ final scienceSmallItems = [ ], contentPreview: [ ArticleIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Phil Plait', publishedAt: DateTime(2022, 6, 2), title: 'Are supermassive black holes killing their host galaxies?', @@ -1071,7 +1071,7 @@ final scienceVideoItems = [ NewsItem( post: PostGridTileBlock( id: '384a15ff-a50e-46d5-96a7-8864facdcc48', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Loren Grush', publishedAt: DateTime(2022, 5, 6), imageUrl: @@ -1083,18 +1083,18 @@ final scienceVideoItems = [ articleId: '384a15ff-a50e-46d5-96a7-8864facdcc48', ), ), - content: const [ + content: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'SpaceX successfully returns four astronauts from the ' 'International Space Station', videoUrl: 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', ), ], - contentPreview: const [ + contentPreview: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'SpaceX successfully returns four astronauts from the ' 'International Space Station', videoUrl: @@ -1104,7 +1104,7 @@ final scienceVideoItems = [ relatedArticles: [ PostSmallBlock( id: 'bfd5aa62-4c50-40c6-9aef-5511535c7b68', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'SciTechDaily', publishedAt: DateTime(2022, 3, 17), imageUrl: @@ -1126,7 +1126,7 @@ final scienceVideoItems = [ NewsItem( post: PostGridTileBlock( id: '13e448bb-cd26-4ae0-b138-4a67067f7a93', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'Daniel Strain', publishedAt: DateTime(2022, 5, 6), imageUrl: @@ -1138,18 +1138,18 @@ final scienceVideoItems = [ articleId: '13e448bb-cd26-4ae0-b138-4a67067f7a93', ), ), - content: const [ + content: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'A surging glow in a distant galaxy could change ' 'the way we look at black holes', videoUrl: 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', ), ], - contentPreview: const [ + contentPreview: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'A surging glow in a distant galaxy could change ' 'the way we look at black holes', videoUrl: @@ -1163,7 +1163,7 @@ final scienceVideoItems = [ NewsItem( post: PostGridTileBlock( id: '842e3193-86d2-4069-a7e6-f769faa6f970', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'SciTechDaily', publishedAt: DateTime(2022, 5, 5), imageUrl: @@ -1174,9 +1174,9 @@ final scienceVideoItems = [ articleId: '842e3193-86d2-4069-a7e6-f769faa6f970', ), ), - content: const [ + content: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'The Quest for an Ideal Quantum Bit: New Qubit Breakthrough Could ' 'Revolutionize Quantum Computing', @@ -1184,9 +1184,9 @@ final scienceVideoItems = [ 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', ), ], - contentPreview: const [ + contentPreview: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'The Quest for an Ideal Quantum Bit: New Qubit Breakthrough Could ' 'Revolutionize Quantum Computing', @@ -1201,7 +1201,7 @@ final scienceVideoItems = [ NewsItem( post: PostGridTileBlock( id: '1f79da6f-64cb-430a-b7b2-2318d23b719f', - category: PostCategory.science, + categoryId: _scienceCategory.id, author: 'SciTechDaily', publishedAt: DateTime(2022, 5, 4), imageUrl: 'https://scitechdaily.com/images/Black-Hole-Sonification.gif', @@ -1211,18 +1211,18 @@ final scienceVideoItems = [ articleId: '1f79da6f-64cb-430a-b7b2-2318d23b719f', ), ), - content: const [ + content: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'Hear What a Black Hole Sounds Like – New NASA Black Hole ' 'Sonifications With a Remix', videoUrl: 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', ), ], - contentPreview: const [ + contentPreview: [ VideoIntroductionBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, title: 'Hear What a Black Hole Sounds Like – New NASA Black Hole ' 'Sonifications With a Remix', videoUrl: @@ -1245,7 +1245,7 @@ final topNewsFeedBlocks = [ const SectionHeaderBlock( title: 'Technology', action: NavigateToFeedCategoryAction( - category: Category.technology, + category: _technologyCategory, ), ), technologyLargeItems.last.post, @@ -1254,11 +1254,11 @@ final topNewsFeedBlocks = [ const SectionHeaderBlock( title: 'Science Videos', action: NavigateToFeedCategoryAction( - category: Category.science, + category: _scienceCategory, ), ), PostGridGroupBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, tiles: [...scienceVideoItems.map((e) => e.post).cast()], ), const SpacerBlock(spacing: Spacing.large), @@ -1266,7 +1266,7 @@ final topNewsFeedBlocks = [ const SectionHeaderBlock( title: 'Sports', action: NavigateToFeedCategoryAction( - category: Category.sports, + category: _sportsCategory, ), ), sportsMediumItems.first.post, @@ -1276,7 +1276,7 @@ final topNewsFeedBlocks = [ const SectionHeaderBlock( title: 'Health', action: NavigateToFeedCategoryAction( - category: Category.health, + category: _healthCategory, ), ), healthSmallItems.first.post, @@ -1368,7 +1368,7 @@ final scienceFeedBlocks = [ const SpacerBlock(spacing: Spacing.small), const SectionHeaderBlock(title: 'Science Videos'), PostGridGroupBlock( - category: PostCategory.science, + categoryId: _scienceCategory.id, tiles: [...scienceVideoItems.map((e) => e.post).cast()], ), const SpacerBlock(spacing: Spacing.medium), @@ -1384,13 +1384,27 @@ List get _newsItems { } final _newsFeedData = { - Category.top: topNewsFeedBlocks.toFeed(), - Category.technology: technologyFeedBlocks.toFeed(), - Category.sports: sportsFeedBlocks.toFeed(), - Category.health: healthFeedBlocks.toFeed(), - Category.science: scienceFeedBlocks.toFeed(), + _topCategory: topNewsFeedBlocks.toFeed(), + _technologyCategory: technologyFeedBlocks.toFeed(), + _sportsCategory: sportsFeedBlocks.toFeed(), + _healthCategory: healthFeedBlocks.toFeed(), + _scienceCategory: scienceFeedBlocks.toFeed(), }; +const _topCategory = Category.top; +const _sportsCategory = Category.sports; +const _technologyCategory = Category.technology; +const _healthCategory = Category.health; +const _scienceCategory = Category.science; + +const _categories = [ + _topCategory, + _sportsCategory, + _technologyCategory, + _healthCategory, + _scienceCategory, +]; + extension on List { Feed toFeed() => Feed(blocks: this, totalBlocks: length); Article toArticle({required String title, required Uri url}) { diff --git a/flutter_news_example/api/packages/news_blocks/lib/news_blocks.dart b/flutter_news_example/api/packages/news_blocks/lib/news_blocks.dart index 81b3b8bfd..1ad20f897 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/news_blocks.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/news_blocks.dart @@ -18,7 +18,6 @@ export 'src/news_block.dart' show NewsBlock; export 'src/news_blocks_converter.dart' show NewsBlocksConverter; export 'src/newsletter_block.dart' show NewsletterBlock; export 'src/post_block.dart' show PostBlock, PostBlockActions; -export 'src/post_category.dart' show PostCategory; export 'src/post_grid_group_block.dart' show PostGridGroupBlock; export 'src/post_grid_tile_block.dart' show PostGridTileBlock, PostGridTileBlockExt; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.dart index 924b8df17..332010645 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.dart @@ -12,7 +12,7 @@ part 'article_introduction_block.g.dart'; class ArticleIntroductionBlock with EquatableMixin implements NewsBlock { /// {@macro article_introduction_block} const ArticleIntroductionBlock({ - required this.category, + required this.categoryId, required this.author, required this.publishedAt, required this.title, @@ -29,8 +29,8 @@ class ArticleIntroductionBlock with EquatableMixin implements NewsBlock { /// The article introduction block type identifier. static const identifier = '__article_introduction__'; - /// The category of the associated article. - final PostCategory category; + /// The category id of the associated article. + final String categoryId; /// The author of the associated article. final String author; @@ -58,7 +58,7 @@ class ArticleIntroductionBlock with EquatableMixin implements NewsBlock { @override List get props => [ type, - category, + categoryId, author, publishedAt, imageUrl, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.g.dart index 1bef118ba..603a384f0 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/article_introduction_block.g.dart @@ -15,8 +15,7 @@ ArticleIntroductionBlock _$ArticleIntroductionBlockFromJson( json, ($checkedConvert) { final val = ArticleIntroductionBlock( - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), author: $checkedConvert('author', (v) => v as String), publishedAt: $checkedConvert( 'published_at', (v) => DateTime.parse(v as String)), @@ -29,6 +28,7 @@ ArticleIntroductionBlock _$ArticleIntroductionBlockFromJson( return val; }, fieldKeyMap: const { + 'categoryId': 'category_id', 'publishedAt': 'published_at', 'imageUrl': 'image_url', 'isPremium': 'is_premium' @@ -38,7 +38,7 @@ ArticleIntroductionBlock _$ArticleIntroductionBlockFromJson( Map _$ArticleIntroductionBlockToJson( ArticleIntroductionBlock instance) { final val = { - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'author': instance.author, 'published_at': instance.publishedAt.toIso8601String(), }; @@ -55,12 +55,3 @@ Map _$ArticleIntroductionBlockToJson( val['type'] = instance.type; return val; } - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/category.dart b/flutter_news_example/api/packages/news_blocks/lib/src/category.dart index f17b2b18f..59afd6ce7 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/category.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/category.dart @@ -21,6 +21,9 @@ enum Category { /// News relating to technology. technology; + /// The id of the category. + String get id => name; + /// Returns a [Category] for the [categoryName]. static Category fromString(String categoryName) => Category.values.firstWhere((category) => category.name == categoryName); diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_block.dart index ec8853b91..ec110a6d7 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_block.dart @@ -8,7 +8,7 @@ abstract class PostBlock with EquatableMixin implements NewsBlock { /// {@macro post_block} const PostBlock({ required this.id, - required this.category, + required this.categoryId, required this.author, required this.publishedAt, required this.title, @@ -26,8 +26,8 @@ abstract class PostBlock with EquatableMixin implements NewsBlock { /// The identifier of this post. final String id; - /// The category of this post. - final PostCategory category; + /// The category id of this post. + final String categoryId; /// The author of this post. final String author; @@ -64,7 +64,7 @@ abstract class PostBlock with EquatableMixin implements NewsBlock { @override List get props => [ id, - category, + categoryId, author, publishedAt, imageUrl, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_category.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_category.dart deleted file mode 100644 index 3a0622d3e..000000000 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_category.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// The supported news post category types. -enum PostCategory { - /// News post relating to business. - business, - - /// News post relating to entertainment. - entertainment, - - /// News post relating to health. - health, - - /// News post relating to science. - science, - - /// News post relating to sports. - sports, - - /// News post relating to technology. - technology, -} diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.dart index c1b2e2aa4..90438fd96 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.dart @@ -12,7 +12,7 @@ part 'post_grid_group_block.g.dart'; class PostGridGroupBlock with EquatableMixin implements NewsBlock { /// {@macro post_grid_group_block} const PostGridGroupBlock({ - required this.category, + required this.categoryId, required this.tiles, this.type = PostGridGroupBlock.identifier, }); @@ -24,8 +24,8 @@ class PostGridGroupBlock with EquatableMixin implements NewsBlock { /// The post grid block type identifier. static const identifier = '__post_grid_group__'; - /// The category of this post grid group. - final PostCategory category; + /// The category id of this post grid group. + final String categoryId; /// The associated list of [PostGridTileBlock] tiles. @NewsBlocksConverter() @@ -38,5 +38,5 @@ class PostGridGroupBlock with EquatableMixin implements NewsBlock { Map toJson() => _$PostGridGroupBlockToJson(this); @override - List get props => [category, tiles, type]; + List get props => [categoryId, tiles, type]; } diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.g.dart index 341f8a018..415012e05 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_group_block.g.dart @@ -14,8 +14,7 @@ PostGridGroupBlock _$PostGridGroupBlockFromJson(Map json) => json, ($checkedConvert) { final val = PostGridGroupBlock( - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), tiles: $checkedConvert( 'tiles', (v) => (v as List) @@ -27,20 +26,12 @@ PostGridGroupBlock _$PostGridGroupBlockFromJson(Map json) => ); return val; }, + fieldKeyMap: const {'categoryId': 'category_id'}, ); Map _$PostGridGroupBlockToJson(PostGridGroupBlock instance) => { - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'tiles': instance.tiles.map((e) => e.toJson()).toList(), 'type': instance.type, }; - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.dart index 374dcb081..b014761ee 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.dart @@ -14,7 +14,7 @@ class PostGridTileBlock extends PostBlock { /// {@macro post_grid_tile_block} const PostGridTileBlock({ required super.id, - required super.category, + required super.categoryId, required super.author, required super.publishedAt, required String super.imageUrl, @@ -43,7 +43,7 @@ extension PostGridTileBlockExt on PostGridTileBlock { /// Converts [PostGridTileBlock] into a [PostLargeBlock] instance. PostLargeBlock toPostLargeBlock() => PostLargeBlock( id: id, - category: category, + categoryId: categoryId, author: author, publishedAt: publishedAt, imageUrl: imageUrl!, @@ -56,7 +56,7 @@ extension PostGridTileBlockExt on PostGridTileBlock { /// Converts [PostGridTileBlock] into a [PostMediumBlock] instance. PostMediumBlock toPostMediumBlock() => PostMediumBlock( id: id, - category: category, + categoryId: categoryId, author: author, publishedAt: publishedAt, imageUrl: imageUrl!, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.g.dart index e276806ad..627fc8c17 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_grid_tile_block.g.dart @@ -15,8 +15,7 @@ PostGridTileBlock _$PostGridTileBlockFromJson(Map json) => ($checkedConvert) { final val = PostGridTileBlock( id: $checkedConvert('id', (v) => v as String), - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), author: $checkedConvert('author', (v) => v as String), publishedAt: $checkedConvert( 'published_at', (v) => DateTime.parse(v as String)), @@ -34,6 +33,7 @@ PostGridTileBlock _$PostGridTileBlockFromJson(Map json) => return val; }, fieldKeyMap: const { + 'categoryId': 'category_id', 'publishedAt': 'published_at', 'imageUrl': 'image_url', 'isPremium': 'is_premium' @@ -43,7 +43,7 @@ PostGridTileBlock _$PostGridTileBlockFromJson(Map json) => Map _$PostGridTileBlockToJson(PostGridTileBlock instance) { final val = { 'id': instance.id, - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'author': instance.author, 'published_at': instance.publishedAt.toIso8601String(), }; @@ -62,12 +62,3 @@ Map _$PostGridTileBlockToJson(PostGridTileBlock instance) { val['type'] = instance.type; return val; } - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.dart index 18723bfdc..46fda8434 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.dart @@ -12,7 +12,7 @@ class PostLargeBlock extends PostBlock { /// {@macro post_large_block} const PostLargeBlock({ required super.id, - required super.category, + required super.categoryId, required super.author, required super.publishedAt, required String super.imageUrl, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.g.dart index 2c1338316..11c89ef09 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_large_block.g.dart @@ -15,8 +15,7 @@ PostLargeBlock _$PostLargeBlockFromJson(Map json) => ($checkedConvert) { final val = PostLargeBlock( id: $checkedConvert('id', (v) => v as String), - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), author: $checkedConvert('author', (v) => v as String), publishedAt: $checkedConvert( 'published_at', (v) => DateTime.parse(v as String)), @@ -36,6 +35,7 @@ PostLargeBlock _$PostLargeBlockFromJson(Map json) => return val; }, fieldKeyMap: const { + 'categoryId': 'category_id', 'publishedAt': 'published_at', 'imageUrl': 'image_url', 'isPremium': 'is_premium', @@ -46,7 +46,7 @@ PostLargeBlock _$PostLargeBlockFromJson(Map json) => Map _$PostLargeBlockToJson(PostLargeBlock instance) { final val = { 'id': instance.id, - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'author': instance.author, 'published_at': instance.publishedAt.toIso8601String(), }; @@ -66,12 +66,3 @@ Map _$PostLargeBlockToJson(PostLargeBlock instance) { val['type'] = instance.type; return val; } - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.dart index 797b244eb..c968cc93d 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.dart @@ -12,7 +12,7 @@ class PostMediumBlock extends PostBlock { /// {@macro post_medium_block} const PostMediumBlock({ required super.id, - required super.category, + required super.categoryId, required super.author, required super.publishedAt, required String super.imageUrl, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.g.dart index 5020ee2e7..404f1508c 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_medium_block.g.dart @@ -15,8 +15,7 @@ PostMediumBlock _$PostMediumBlockFromJson(Map json) => ($checkedConvert) { final val = PostMediumBlock( id: $checkedConvert('id', (v) => v as String), - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), author: $checkedConvert('author', (v) => v as String), publishedAt: $checkedConvert( 'published_at', (v) => DateTime.parse(v as String)), @@ -36,6 +35,7 @@ PostMediumBlock _$PostMediumBlockFromJson(Map json) => return val; }, fieldKeyMap: const { + 'categoryId': 'category_id', 'publishedAt': 'published_at', 'imageUrl': 'image_url', 'isPremium': 'is_premium', @@ -46,7 +46,7 @@ PostMediumBlock _$PostMediumBlockFromJson(Map json) => Map _$PostMediumBlockToJson(PostMediumBlock instance) { final val = { 'id': instance.id, - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'author': instance.author, 'published_at': instance.publishedAt.toIso8601String(), }; @@ -66,12 +66,3 @@ Map _$PostMediumBlockToJson(PostMediumBlock instance) { val['type'] = instance.type; return val; } - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.dart index 0bb7ddb09..003c3d525 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.dart @@ -12,7 +12,7 @@ class PostSmallBlock extends PostBlock { /// {@macro post_small_block} const PostSmallBlock({ required super.id, - required super.category, + required super.categoryId, required super.author, required super.publishedAt, required super.title, diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.g.dart index 778287260..5dabda748 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/post_small_block.g.dart @@ -15,8 +15,7 @@ PostSmallBlock _$PostSmallBlockFromJson(Map json) => ($checkedConvert) { final val = PostSmallBlock( id: $checkedConvert('id', (v) => v as String), - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), author: $checkedConvert('author', (v) => v as String), publishedAt: $checkedConvert( 'published_at', (v) => DateTime.parse(v as String)), @@ -34,6 +33,7 @@ PostSmallBlock _$PostSmallBlockFromJson(Map json) => return val; }, fieldKeyMap: const { + 'categoryId': 'category_id', 'publishedAt': 'published_at', 'imageUrl': 'image_url', 'isPremium': 'is_premium' @@ -43,7 +43,7 @@ PostSmallBlock _$PostSmallBlockFromJson(Map json) => Map _$PostSmallBlockToJson(PostSmallBlock instance) { final val = { 'id': instance.id, - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'author': instance.author, 'published_at': instance.publishedAt.toIso8601String(), }; @@ -62,12 +62,3 @@ Map _$PostSmallBlockToJson(PostSmallBlock instance) { val['type'] = instance.type; return val; } - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.dart b/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.dart index 8c95a1dff..cb3ca0afb 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.dart @@ -12,7 +12,7 @@ part 'video_introduction_block.g.dart'; class VideoIntroductionBlock with EquatableMixin implements NewsBlock { /// {@macro video_introduction_block} const VideoIntroductionBlock({ - required this.category, + required this.categoryId, required this.title, required this.videoUrl, this.type = VideoIntroductionBlock.identifier, @@ -26,8 +26,8 @@ class VideoIntroductionBlock with EquatableMixin implements NewsBlock { /// The video introduction block type identifier. static const identifier = '__video_introduction__'; - /// The category of the associated article. - final PostCategory category; + /// The category id of the associated article. + final String categoryId; /// The title of the associated article. final String title; @@ -42,5 +42,5 @@ class VideoIntroductionBlock with EquatableMixin implements NewsBlock { Map toJson() => _$VideoIntroductionBlockToJson(this); @override - List get props => [category, title, videoUrl, type]; + List get props => [categoryId, title, videoUrl, type]; } diff --git a/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.g.dart b/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.g.dart index a69ec2122..e8ddadfe5 100644 --- a/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.g.dart +++ b/flutter_news_example/api/packages/news_blocks/lib/src/video_introduction_block.g.dart @@ -15,8 +15,7 @@ VideoIntroductionBlock _$VideoIntroductionBlockFromJson( json, ($checkedConvert) { final val = VideoIntroductionBlock( - category: $checkedConvert( - 'category', (v) => $enumDecode(_$PostCategoryEnumMap, v)), + categoryId: $checkedConvert('category_id', (v) => v as String), title: $checkedConvert('title', (v) => v as String), videoUrl: $checkedConvert('video_url', (v) => v as String), type: $checkedConvert( @@ -24,23 +23,14 @@ VideoIntroductionBlock _$VideoIntroductionBlockFromJson( ); return val; }, - fieldKeyMap: const {'videoUrl': 'video_url'}, + fieldKeyMap: const {'categoryId': 'category_id', 'videoUrl': 'video_url'}, ); Map _$VideoIntroductionBlockToJson( VideoIntroductionBlock instance) => { - 'category': _$PostCategoryEnumMap[instance.category]!, + 'category_id': instance.categoryId, 'title': instance.title, 'video_url': instance.videoUrl, 'type': instance.type, }; - -const _$PostCategoryEnumMap = { - PostCategory.business: 'business', - PostCategory.entertainment: 'entertainment', - PostCategory.health: 'health', - PostCategory.science: 'science', - PostCategory.sports: 'sports', - PostCategory.technology: 'technology', -}; diff --git a/flutter_news_example/api/packages/news_blocks/test/src/article_introduction_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/article_introduction_block_test.dart index 3ac1d6e47..4643d1403 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/article_introduction_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/article_introduction_block_test.dart @@ -4,8 +4,9 @@ import 'package:test/test.dart'; void main() { group('ArticleIntroductionBlock', () { test('can be (de)serialized', () { + const category = Category.technology; final block = ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/news_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/news_block_test.dart index ee1ea57b2..d10bb7786 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/news_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/news_block_test.dart @@ -77,8 +77,9 @@ void main() { }); test('returns VideoIntroductionBlock', () { + const category = Category.technology; final block = VideoIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, title: 'title', videoUrl: 'videoUrl', ); @@ -86,8 +87,9 @@ void main() { }); test('returns ArticleIntroductionBlock', () { + const category = Category.technology; final block = ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -97,9 +99,10 @@ void main() { }); test('returns PostLargeBlock', () { + const category = Category.technology; final block = PostLargeBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -110,9 +113,10 @@ void main() { }); test('returns PostMediumBlock', () { + const category = Category.sports; final block = PostMediumBlock( id: 'id', - category: PostCategory.sports, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 10), imageUrl: 'imageUrl', @@ -123,9 +127,10 @@ void main() { }); test('returns PostSmallBlock', () { + const category = Category.health; final block = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', @@ -136,12 +141,13 @@ void main() { }); test('returns PostGridGroupBlock', () { + const category = Category.science; final block = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [ PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', @@ -154,9 +160,10 @@ void main() { }); test('returns PostGridTileBlock', () { + const category = Category.science; final block = PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', @@ -214,9 +221,10 @@ void main() { }); test('returns TrendingStoryBlock', () { + const category = Category.health; final content = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/news_blocks_converter_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/news_blocks_converter_test.dart index 7cb3e2ad8..0f6ed5540 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/news_blocks_converter_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/news_blocks_converter_test.dart @@ -7,13 +7,14 @@ void main() { group('NewsBlocksConverter', () { test('can (de)serialize List', () { final converter = NewsBlocksConverter(); + const category = Category.health; final newsBlocks = [ SectionHeaderBlock(title: 'title'), DividerHorizontalBlock(), SpacerBlock(spacing: Spacing.medium), PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_block_test.dart index 75bfcdc0d..da3731d8f 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_block_test.dart @@ -7,7 +7,7 @@ class CustomPostBlock extends PostBlock { CustomPostBlock({super.action}) : super( id: 'id', - category: PostCategory.technology, + categoryId: Category.health.id, author: 'author', publishedAt: DateTime(2022, 03, 09), title: 'title', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_grid_group_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_grid_group_block_test.dart index 7aa331852..abdfbcd5c 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_grid_group_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_grid_group_block_test.dart @@ -4,12 +4,13 @@ import 'package:test/test.dart'; void main() { group('PostGridGroupBlock', () { test('can be (de)serialized', () { + const category = Category.science; final block = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [ PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_grid_tile_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_grid_tile_block_test.dart index c94b8ecaa..478013aff 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_grid_tile_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_grid_tile_block_test.dart @@ -4,9 +4,10 @@ import 'package:test/test.dart'; void main() { group('PostGridTileBlock', () { test('can be (de)serialized', () { + const category = Category.science; final block = PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', @@ -18,7 +19,7 @@ void main() { group('PostGridTitleBlockExt', () { const id = 'id'; - const category = PostCategory.science; + const category = Category.science; const author = 'author'; final publishedAt = DateTime(2022, 3, 12); const imageUrl = 'imageUrl'; @@ -28,7 +29,7 @@ void main() { final gridTile = PostGridTileBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -40,7 +41,7 @@ void main() { test('toPostLargeBlock creates PostLargeBlock instance', () { final largeBlock = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -56,7 +57,7 @@ void main() { test('toPostMediumBlock creates PostMediumBlock instance', () { final mediumBlock = PostMediumBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_large_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_large_block_test.dart index 39275304d..66c42634e 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_large_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_large_block_test.dart @@ -4,9 +4,10 @@ import 'package:test/test.dart'; void main() { group('PostLargeBlock', () { test('can be (de)serialized', () { + const category = Category.technology; final block = PostLargeBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_medium_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_medium_block_test.dart index bfa71d3d2..380bbc9d7 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_medium_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_medium_block_test.dart @@ -4,9 +4,10 @@ import 'package:test/test.dart'; void main() { group('PostMediumBlock', () { test('can be (de)serialized', () { + const category = Category.sports; final block = PostMediumBlock( id: 'id', - category: PostCategory.sports, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 10), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/post_small_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/post_small_block_test.dart index 4c1d7f260..4fb2f4c47 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/post_small_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/post_small_block_test.dart @@ -5,9 +5,10 @@ import 'package:test/test.dart'; void main() { group('PostSmallBlock', () { test('can be (de)serialized', () { + const category = Category.health; final block = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/trending_story_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/trending_story_block_test.dart index e4d9a043f..012ec1b38 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/trending_story_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/trending_story_block_test.dart @@ -6,9 +6,10 @@ import 'package:test/test.dart'; void main() { group('TrendingStoryBlock', () { test('can be (de)serialized', () { + const category = Category.health; final content = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/api/packages/news_blocks/test/src/video_intro_block_test.dart b/flutter_news_example/api/packages/news_blocks/test/src/video_intro_block_test.dart index d1eaca521..e0394e7bd 100644 --- a/flutter_news_example/api/packages/news_blocks/test/src/video_intro_block_test.dart +++ b/flutter_news_example/api/packages/news_blocks/test/src/video_intro_block_test.dart @@ -6,8 +6,9 @@ import 'package:test/test.dart'; void main() { group('VideoIntroductionBlock', () { test('can be (de)serialized', () { + const category = Category.technology; final block = VideoIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, title: 'title', videoUrl: 'videoUrl', ); diff --git a/flutter_news_example/api/test/src/data/news_data_source_test.dart b/flutter_news_example/api/test/src/data/news_data_source_test.dart index b0e1cd547..a96aa3e60 100644 --- a/flutter_news_example/api/test/src/data/news_data_source_test.dart +++ b/flutter_news_example/api/test/src/data/news_data_source_test.dart @@ -299,8 +299,8 @@ void main() { newsDataSource.getCategories(), completion([ Category.top, - Category.technology, Category.sports, + Category.technology, Category.health, Category.science, ]), diff --git a/flutter_news_example/lib/app/view/app.dart b/flutter_news_example/lib/app/view/app.dart index a616294a6..ae4a17ef4 100644 --- a/flutter_news_example/lib/app/view/app.dart +++ b/flutter_news_example/lib/app/view/app.dart @@ -8,6 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_news_example/ads/ads.dart'; import 'package:flutter_news_example/analytics/analytics.dart'; import 'package:flutter_news_example/app/app.dart'; +import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/l10n/l10n.dart'; import 'package:flutter_news_example/login/login.dart' hide LoginEvent; import 'package:flutter_news_example/theme_selector/theme_selector.dart'; @@ -94,6 +95,11 @@ class App extends StatelessWidget { ..add(const LoadRewardedAdRequested()), lazy: false, ), + BlocProvider( + create: (context) => CategoriesBloc( + newsRepository: context.read(), + )..add(const CategoriesRequested()), + ), ], child: const AppView(), ), diff --git a/flutter_news_example/lib/article/widgets/article_content.dart b/flutter_news_example/lib/article/widgets/article_content.dart index 36bc8824a..12a40ecbd 100644 --- a/flutter_news_example/lib/article/widgets/article_content.dart +++ b/flutter_news_example/lib/article/widgets/article_content.dart @@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_news_example/ads/ads.dart'; import 'package:flutter_news_example/analytics/analytics.dart'; import 'package:flutter_news_example/article/article.dart'; +import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/l10n/l10n.dart'; import 'package:flutter_news_example/network_error/network_error.dart'; import 'package:flutter_news_example_api/client.dart'; @@ -15,11 +16,17 @@ class ArticleContent extends StatelessWidget { @override Widget build(BuildContext context) { final status = context.select((ArticleBloc bloc) => bloc.state.status); + final categoriesStatus = context.select( + (CategoriesBloc bloc) => bloc.state.status, + ); final hasMoreContent = context.select((ArticleBloc bloc) => bloc.state.hasMoreContent); - if (status == ArticleStatus.initial) { + /// Show loader while categories are loading as articles may need to consume + /// them + if (status == ArticleStatus.initial || + categoriesStatus == CategoriesStatus.initial) { return const ArticleContentLoaderItem( key: Key('articleContent_empty_loaderItem'), ); diff --git a/flutter_news_example/lib/article/widgets/article_content_item.dart b/flutter_news_example/lib/article/widgets/article_content_item.dart index db333e6b6..ea218f26c 100644 --- a/flutter_news_example/lib/article/widgets/article_content_item.dart +++ b/flutter_news_example/lib/article/widgets/article_content_item.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart' hide Image, Spacer; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_news_example/article/article.dart'; +import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/l10n/l10n.dart'; import 'package:flutter_news_example/newsletter/newsletter.dart'; import 'package:flutter_news_example/slideshow/slideshow.dart'; @@ -48,12 +50,24 @@ class ArticleContentItem extends StatelessWidget { } else if (newsBlock is TextParagraphBlock) { return TextParagraph(block: newsBlock); } else if (newsBlock is ArticleIntroductionBlock) { + final categoryName = context + .read() + .state + .getCategoryName(newsBlock.categoryId); return ArticleIntroduction( block: newsBlock, + categoryName: categoryName, premiumText: context.l10n.newsBlockPremiumText, ); } else if (newsBlock is VideoIntroductionBlock) { - return VideoIntroduction(block: newsBlock); + final categoryName = context + .read() + .state + .getCategoryName(newsBlock.categoryId); + return VideoIntroduction( + block: newsBlock, + categoryName: categoryName, + ); } else if (newsBlock is BannerAdBlock) { return BannerAd( block: newsBlock, diff --git a/flutter_news_example/lib/categories/bloc/categories_bloc.dart b/flutter_news_example/lib/categories/bloc/categories_bloc.dart index 105068d19..2c10c8ad2 100644 --- a/flutter_news_example/lib/categories/bloc/categories_bloc.dart +++ b/flutter_news_example/lib/categories/bloc/categories_bloc.dart @@ -2,15 +2,13 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; -import 'package:hydrated_bloc/hydrated_bloc.dart'; -import 'package:json_annotation/json_annotation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:news_repository/news_repository.dart'; part 'categories_event.dart'; part 'categories_state.dart'; -part 'categories_bloc.g.dart'; -class CategoriesBloc extends HydratedBloc { +class CategoriesBloc extends Bloc { CategoriesBloc({ required NewsRepository newsRepository, }) : _newsRepository = newsRepository, @@ -47,11 +45,4 @@ class CategoriesBloc extends HydratedBloc { Emitter emit, ) => emit(state.copyWith(selectedCategory: event.category)); - - @override - CategoriesState? fromJson(Map json) => - CategoriesState.fromJson(json); - - @override - Map? toJson(CategoriesState state) => state.toJson(); } diff --git a/flutter_news_example/lib/categories/bloc/categories_bloc.g.dart b/flutter_news_example/lib/categories/bloc/categories_bloc.g.dart deleted file mode 100644 index 684c8f19f..000000000 --- a/flutter_news_example/lib/categories/bloc/categories_bloc.g.dart +++ /dev/null @@ -1,42 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'categories_bloc.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -CategoriesState _$CategoriesStateFromJson(Map json) => - CategoriesState( - status: $enumDecode(_$CategoriesStatusEnumMap, json['status']), - categories: (json['categories'] as List?) - ?.map((e) => $enumDecode(_$CategoryEnumMap, e)) - .toList(), - selectedCategory: - $enumDecodeNullable(_$CategoryEnumMap, json['selectedCategory']), - ); - -Map _$CategoriesStateToJson(CategoriesState instance) => - { - 'status': _$CategoriesStatusEnumMap[instance.status]!, - 'categories': - instance.categories?.map((e) => _$CategoryEnumMap[e]!).toList(), - 'selectedCategory': _$CategoryEnumMap[instance.selectedCategory], - }; - -const _$CategoriesStatusEnumMap = { - CategoriesStatus.initial: 'initial', - CategoriesStatus.loading: 'loading', - CategoriesStatus.populated: 'populated', - CategoriesStatus.failure: 'failure', -}; - -const _$CategoryEnumMap = { - Category.business: 'business', - Category.entertainment: 'entertainment', - Category.top: 'top', - Category.health: 'health', - Category.science: 'science', - Category.sports: 'sports', - Category.technology: 'technology', -}; diff --git a/flutter_news_example/lib/categories/bloc/categories_state.dart b/flutter_news_example/lib/categories/bloc/categories_state.dart index 15465da41..c3e387c8b 100644 --- a/flutter_news_example/lib/categories/bloc/categories_state.dart +++ b/flutter_news_example/lib/categories/bloc/categories_state.dart @@ -7,7 +7,6 @@ enum CategoriesStatus { failure, } -@JsonSerializable() class CategoriesState extends Equatable { const CategoriesState({ required this.status, @@ -20,13 +19,20 @@ class CategoriesState extends Equatable { status: CategoriesStatus.initial, ); - factory CategoriesState.fromJson(Map json) => - _$CategoriesStateFromJson(json); - final CategoriesStatus status; final List? categories; final Category? selectedCategory; + String? getCategoryName(String categoryId) { + try { + return categories + ?.firstWhere((category) => category.id == categoryId) + .name; + } catch (_) { + return null; + } + } + @override List get props => [ status, @@ -45,6 +51,4 @@ class CategoriesState extends Equatable { selectedCategory: selectedCategory ?? this.selectedCategory, ); } - - Map toJson() => _$CategoriesStateToJson(this); } diff --git a/flutter_news_example/lib/feed/widgets/category_feed_item.dart b/flutter_news_example/lib/feed/widgets/category_feed_item.dart index 0f24c547d..42e10ef5d 100644 --- a/flutter_news_example/lib/feed/widgets/category_feed_item.dart +++ b/flutter_news_example/lib/feed/widgets/category_feed_item.dart @@ -33,8 +33,13 @@ class CategoryFeedItem extends StatelessWidget { onPressed: (action) => _onFeedItemAction(context, action), ); } else if (newsBlock is PostLargeBlock) { + final categoryName = context + .read() + .state + .getCategoryName(newsBlock.categoryId); widget = PostLarge( block: newsBlock, + categoryName: categoryName, premiumText: context.l10n.newsBlockPremiumText, isLocked: newsBlock.isPremium && !isUserSubscribed, onPressed: (action) => _onFeedItemAction(context, action), @@ -50,8 +55,13 @@ class CategoryFeedItem extends StatelessWidget { onPressed: (action) => _onFeedItemAction(context, action), ); } else if (newsBlock is PostGridGroupBlock) { + final categoryName = context + .read() + .state + .getCategoryName(newsBlock.categoryId); widget = PostGrid( gridGroupBlock: newsBlock, + categoryName: categoryName, premiumText: context.l10n.newsBlockPremiumText, onPressed: (action) => _onFeedItemAction(context, action), ); diff --git a/flutter_news_example/lib/home/view/home_page.dart b/flutter_news_example/lib/home/view/home_page.dart index 19e297c35..f283b9e33 100644 --- a/flutter_news_example/lib/home/view/home_page.dart +++ b/flutter_news_example/lib/home/view/home_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/feed/feed.dart'; import 'package:flutter_news_example/home/home.dart'; import 'package:news_repository/news_repository.dart'; @@ -14,11 +13,6 @@ class HomePage extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (context) => CategoriesBloc( - newsRepository: context.read(), - )..add(const CategoriesRequested()), - ), BlocProvider( create: (context) => FeedBloc( newsRepository: context.read(), diff --git a/flutter_news_example/packages/news_blocks_ui/lib/src/article_introduction.dart b/flutter_news_example/packages/news_blocks_ui/lib/src/article_introduction.dart index 44a81d88f..5ca2b6bf1 100644 --- a/flutter_news_example/packages/news_blocks_ui/lib/src/article_introduction.dart +++ b/flutter_news_example/packages/news_blocks_ui/lib/src/article_introduction.dart @@ -10,6 +10,7 @@ class ArticleIntroduction extends StatelessWidget { /// {@macro article_introduction} const ArticleIntroduction({ required this.block, + required this.categoryName, required this.premiumText, super.key, }); @@ -17,6 +18,9 @@ class ArticleIntroduction extends StatelessWidget { /// The associated [ArticleIntroductionBlock] instance. final ArticleIntroductionBlock block; + /// The name of the category of the associated article. + final String? categoryName; + /// Text displayed when article is premium content. final String premiumText; @@ -28,7 +32,7 @@ class ArticleIntroduction extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), child: PostContent( - categoryName: block.category.name, + categoryName: categoryName, title: block.title, author: block.author, publishedAt: block.publishedAt, diff --git a/flutter_news_example/packages/news_blocks_ui/lib/src/post_grid.dart b/flutter_news_example/packages/news_blocks_ui/lib/src/post_grid.dart index 2b2d7dc0e..d1eb651ff 100644 --- a/flutter_news_example/packages/news_blocks_ui/lib/src/post_grid.dart +++ b/flutter_news_example/packages/news_blocks_ui/lib/src/post_grid.dart @@ -11,6 +11,7 @@ class PostGrid extends StatelessWidget { /// {@macro post_grid} const PostGrid({ required this.gridGroupBlock, + required this.categoryName, required this.premiumText, this.isLocked = false, this.onPressed, @@ -20,6 +21,9 @@ class PostGrid extends StatelessWidget { /// The associated [PostGridGroupBlock] instance. final PostGridGroupBlock gridGroupBlock; + /// The name of the category of the associated article. + final String? categoryName; + /// Text displayed when post is premium content. final String premiumText; @@ -53,6 +57,7 @@ class PostGrid extends StatelessWidget { if (index == 0) { return PostLarge( block: block.toPostLargeBlock(), + categoryName: categoryName, premiumText: premiumText, isLocked: isLocked, onPressed: onPressed, diff --git a/flutter_news_example/packages/news_blocks_ui/lib/src/post_large/post_large.dart b/flutter_news_example/packages/news_blocks_ui/lib/src/post_large/post_large.dart index 03b6b554e..ba8e68edc 100644 --- a/flutter_news_example/packages/news_blocks_ui/lib/src/post_large/post_large.dart +++ b/flutter_news_example/packages/news_blocks_ui/lib/src/post_large/post_large.dart @@ -11,6 +11,7 @@ class PostLarge extends StatelessWidget { /// {@macro post_large} const PostLarge({ required this.block, + required this.categoryName, required this.premiumText, required this.isLocked, this.onPressed, @@ -20,6 +21,9 @@ class PostLarge extends StatelessWidget { /// The associated [PostLargeBlock] instance. final PostLargeBlock block; + /// The name of the category of the associated article. + final String? categoryName; + /// Text displayed when post is premium content. final String premiumText; @@ -45,7 +49,7 @@ class PostLarge extends StatelessWidget { ), PostContent( author: block.author, - categoryName: block.category.name, + categoryName: categoryName, publishedAt: block.publishedAt, title: block.title, isPremium: block.isPremium, diff --git a/flutter_news_example/packages/news_blocks_ui/lib/src/video_introduction.dart b/flutter_news_example/packages/news_blocks_ui/lib/src/video_introduction.dart index 27d9f753a..f4c9f659b 100644 --- a/flutter_news_example/packages/news_blocks_ui/lib/src/video_introduction.dart +++ b/flutter_news_example/packages/news_blocks_ui/lib/src/video_introduction.dart @@ -8,11 +8,18 @@ import 'package:news_blocks_ui/src/widgets/widgets.dart'; /// {@endtemplate} class VideoIntroduction extends StatelessWidget { /// {@macro video_introduction} - const VideoIntroduction({required this.block, super.key}); + const VideoIntroduction({ + required this.block, + required this.categoryName, + super.key, + }); /// The associated [VideoIntroductionBlock] instance. final VideoIntroductionBlock block; + /// The name of the category of the associated article. + final String? categoryName; + @override Widget build(BuildContext context) { return Column( @@ -29,7 +36,7 @@ class VideoIntroduction extends StatelessWidget { AppSpacing.lg, ), child: PostContent( - categoryName: block.category.name, + categoryName: categoryName, title: block.title, isVideoContent: true, ), diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/article_introduction_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/article_introduction_test.dart index 0c7c87de0..0579b9761 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/article_introduction_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/article_introduction_test.dart @@ -7,7 +7,7 @@ import 'package:news_blocks_ui/news_blocks_ui.dart'; import '../helpers/helpers.dart'; void main() { - const category = PostCategory.technology; + const category = Category.technology; const author = 'Sean Hollister'; final publishedAt = DateTime(2022, 3, 9); const imageUrl = @@ -25,7 +25,7 @@ void main() { ); final technologyArticleIntroduction = ArticleIntroductionBlock( - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -40,6 +40,7 @@ void main() { children: [ ArticleIntroduction( block: technologyArticleIntroduction, + categoryName: category.name, premiumText: premiumText, ), ], diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/post_grid_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/post_grid_test.dart index 5d47572de..6713ba0bc 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/post_grid_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/post_grid_test.dart @@ -10,9 +10,10 @@ import '../helpers/helpers.dart'; void main() { group('PostGrid', () { + const category = Category.science; final postGridTileBlock = PostGridTileBlock( id: '842e3193-86d2-4069-a7e6-f769faa6f970', - category: PostCategory.science, + categoryId: category.id, author: 'SciTechDaily', publishedAt: DateTime(2022, 5, 5), imageUrl: @@ -26,7 +27,7 @@ void main() { testWidgets('renders correctly 5 PostGridTiles', (tester) async { final gridGroupBlock = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: List.generate(5, (index) => postGridTileBlock), ); @@ -36,6 +37,7 @@ void main() { slivers: [ PostGrid( gridGroupBlock: gridGroupBlock, + categoryName: category.name, premiumText: 'Premium', ), ], @@ -53,7 +55,7 @@ void main() { testWidgets('renders correctly 1 PostGridTile', (tester) async { final gridGroupBlock = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [postGridTileBlock], ); @@ -61,7 +63,11 @@ void main() { () async => tester.pumpContentThemedApp( CustomScrollView( slivers: [ - PostGrid(gridGroupBlock: gridGroupBlock, premiumText: 'Premium'), + PostGrid( + gridGroupBlock: gridGroupBlock, + categoryName: category.name, + premiumText: 'Premium', + ), ], ), ), @@ -74,7 +80,7 @@ void main() { testWidgets('handles empty tiles list', (tester) async { final gridGroupBlock = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [], ); @@ -82,7 +88,11 @@ void main() { () async => tester.pumpContentThemedApp( CustomScrollView( slivers: [ - PostGrid(gridGroupBlock: gridGroupBlock, premiumText: 'Premium'), + PostGrid( + gridGroupBlock: gridGroupBlock, + categoryName: category.name, + premiumText: 'Premium', + ), ], ), ), diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/post_large/post_large_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/post_large/post_large_test.dart index 1d23c9fc6..d3523d38b 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/post_large/post_large_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/post_large/post_large_test.dart @@ -11,7 +11,7 @@ import '../../helpers/helpers.dart'; void main() { const id = '499305f6-5096-4051-afda-824dcfc7df23'; - const category = PostCategory.technology; + const category = Category.technology; const author = 'Sean Hollister'; final publishedAt = DateTime(2022, 3, 9); const imageUrl = @@ -32,7 +32,7 @@ void main() { 'when isLocked is true', (tester) async { final technologyPostLarge = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -46,6 +46,7 @@ void main() { children: [ PostLarge( block: technologyPostLarge, + categoryName: category.name, premiumText: 'Premium', isLocked: true, ), @@ -64,7 +65,7 @@ void main() { 'when isLocked is false', (tester) async { final technologyPostLarge = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -78,6 +79,7 @@ void main() { children: [ PostLarge( block: technologyPostLarge, + categoryName: category.name, premiumText: 'Premium', isLocked: false, ), @@ -98,7 +100,7 @@ void main() { 'when isLocked is true', (tester) async { final technologyPostLarge = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -112,6 +114,7 @@ void main() { children: [ PostLarge( block: technologyPostLarge, + categoryName: category.name, premiumText: 'Premium', isLocked: true, ), @@ -130,7 +133,7 @@ void main() { 'when isLocked is false', (tester) async { final technologyPostLarge = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -144,6 +147,7 @@ void main() { children: [ PostLarge( block: technologyPostLarge, + categoryName: category.name, premiumText: 'Premium', isLocked: false, ), @@ -165,7 +169,7 @@ void main() { final technologyPostLarge = PostLargeBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -180,6 +184,7 @@ void main() { children: [ PostLarge( block: technologyPostLarge, + categoryName: category.name, premiumText: 'Premium', onPressed: actions.add, isLocked: false, diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/post_medium/post_medium_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/post_medium/post_medium_test.dart index f045ce0c1..e0f96e32b 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/post_medium/post_medium_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/post_medium/post_medium_test.dart @@ -24,7 +24,7 @@ void main() { group('PostMedium', () { const id = '82c49bf1-946d-4920-a801-302291f367b5'; - const category = PostCategory.sports; + const category = Category.sports; const author = 'Tom Dierberger'; final publishedAt = DateTime(2022, 3, 10); const imageUrl = @@ -39,7 +39,7 @@ void main() { testWidgets('renders correctly overlaid layout', (tester) async { final postMediumBlock = PostMediumBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -63,7 +63,7 @@ void main() { testWidgets('renders correctly description layout', (tester) async { final postMediumBlock = PostMediumBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, @@ -88,7 +88,7 @@ void main() { final actions = []; final postMediumBlock = PostMediumBlock( id: id, - category: category, + categoryId: category.id, author: author, publishedAt: publishedAt, imageUrl: imageUrl, diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/post_small_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/post_small_test.dart index b09c2654a..0ed4d144e 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/post_small_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/post_small_test.dart @@ -22,6 +22,7 @@ void main() { }); testWidgets('renders correctly without image', (tester) async { + const category = Category.technology; await mockNetworkImages(() async { await tester.pumpApp( Column( @@ -29,7 +30,7 @@ void main() { PostSmall( block: PostSmallBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, publishedAt: DateTime(2022, 03, 12), title: 'Nvidia and AMD GPUs are ' 'returning to shelves and prices ' @@ -48,6 +49,7 @@ void main() { }); testWidgets('renders correctly with image', (tester) async { + const category = Category.technology; await mockNetworkImages(() async { await tester.pumpApp( Column( @@ -55,7 +57,7 @@ void main() { PostSmall( block: PostSmallBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, publishedAt: DateTime(2022, 03, 12), title: 'Nvidia and AMD GPUs are ' 'returning to shelves and prices ' @@ -78,6 +80,7 @@ void main() { testWidgets('onPressed is called with action when tapped', (tester) async { final action = NavigateToArticleAction(articleId: 'id'); final actions = []; + const category = Category.technology; await mockNetworkImages(() async { await tester.pumpApp( @@ -86,7 +89,7 @@ void main() { PostSmall( block: PostSmallBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, publishedAt: DateTime(2022, 03, 12), title: 'Nvidia and AMD GPUs are returning to shelves and prices ' diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/section_header_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/section_header_test.dart index 15d200603..741387a41 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/section_header_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/section_header_test.dart @@ -27,11 +27,12 @@ void main() { }); testWidgets('renders correctly with action', (tester) async { + const category = Category.sports; const widget = Center( child: SectionHeader( block: SectionHeaderBlock( title: 'example', - action: NavigateToFeedCategoryAction(category: Category.top), + action: NavigateToFeedCategoryAction(category: category), ), ), ); @@ -45,8 +46,9 @@ void main() { }); testWidgets('onPressed is called with action on tap', (tester) async { + const category = Category.sports; final actions = []; - const action = NavigateToFeedCategoryAction(category: Category.top); + const action = NavigateToFeedCategoryAction(category: category); final widget = Center( child: SectionHeader( diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/trending_story_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/trending_story_test.dart index 166fff79f..a3e9459f9 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/trending_story_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/trending_story_test.dart @@ -21,13 +21,14 @@ void main() { }); testWidgets('renders correctly', (tester) async { + const category = Category.technology; await mockNetworkImages(() async { final widget = TrendingStory( title: 'TRENDING', block: TrendingStoryBlock( content: PostSmallBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/packages/news_blocks_ui/test/src/video_introduction_test.dart b/flutter_news_example/packages/news_blocks_ui/test/src/video_introduction_test.dart index 87439714b..26a98a80c 100644 --- a/flutter_news_example/packages/news_blocks_ui/test/src/video_introduction_test.dart +++ b/flutter_news_example/packages/news_blocks_ui/test/src/video_introduction_test.dart @@ -11,7 +11,7 @@ import 'package:video_player_platform_interface/video_player_platform_interface. import '../helpers/helpers.dart'; void main() { - const category = PostCategory.technology; + const category = Category.technology; const videoUrl = 'https://cdn.vox-cdn.com/thumbor/OTpmptgr7XcTVAJ27UBvIxl0vrg=' '/0x146:2040x1214/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset' @@ -32,7 +32,7 @@ void main() { testWidgets('renders correctly', (tester) async { final technologyVideoIntroduction = VideoIntroductionBlock( - category: category, + categoryId: category.id, videoUrl: videoUrl, title: title, ); @@ -42,7 +42,10 @@ void main() { SingleChildScrollView( child: Column( children: [ - VideoIntroduction(block: technologyVideoIntroduction), + VideoIntroduction( + block: technologyVideoIntroduction, + categoryName: category.name, + ), ], ), ), diff --git a/flutter_news_example/test/app/view/app_test.dart b/flutter_news_example/test/app/view/app_test.dart index 11d0507a4..41b75e4db 100644 --- a/flutter_news_example/test/app/view/app_test.dart +++ b/flutter_news_example/test/app/view/app_test.dart @@ -6,6 +6,7 @@ import 'package:article_repository/article_repository.dart'; import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_news_example/analytics/analytics.dart' as analytics; import 'package:flutter_news_example/app/app.dart'; +import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/home/home.dart'; import 'package:flutter_news_example/onboarding/onboarding.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -38,6 +39,9 @@ class MockAdsConsentClient extends Mock implements AdsConsentClient {} class MockAppBloc extends MockBloc implements AppBloc {} +class MockCategoriesBloc extends MockBloc + implements CategoriesBloc {} + class MockAnalyticsBloc extends MockBloc implements analytics.AnalyticsBloc {} @@ -117,11 +121,15 @@ void main() { }); testWidgets('navigates to HomePage when unauthenticated', (tester) async { + final categoriesBloc = MockCategoriesBloc(); when(() => appBloc.state).thenReturn(AppState.unauthenticated()); + when(() => categoriesBloc.state) + .thenReturn(const CategoriesState(status: CategoriesStatus.initial)); await tester.pumpApp( const AppView(), appBloc: appBloc, userRepository: userRepository, + categoriesBloc: categoriesBloc, ); await tester.pumpAndSettle(); expect(find.byType(HomePage), findsOneWidget); @@ -129,12 +137,16 @@ void main() { testWidgets('navigates to HomePage when authenticated', (tester) async { final user = MockUser(); + final categoriesBloc = MockCategoriesBloc(); when(() => user.isAnonymous).thenReturn(false); when(() => appBloc.state).thenReturn(AppState.authenticated(user)); + when(() => categoriesBloc.state) + .thenReturn(const CategoriesState(status: CategoriesStatus.initial)); await tester.pumpApp( const AppView(), appBloc: appBloc, userRepository: userRepository, + categoriesBloc: categoriesBloc, ); await tester.pumpAndSettle(); expect(find.byType(HomePage), findsOneWidget); diff --git a/flutter_news_example/test/article/widgets/article_content_item_test.dart b/flutter_news_example/test/article/widgets/article_content_item_test.dart index 10b07da4a..e56be6c44 100644 --- a/flutter_news_example/test/article/widgets/article_content_item_test.dart +++ b/flutter_news_example/test/article/widgets/article_content_item_test.dart @@ -152,8 +152,9 @@ void main() { testWidgets( 'renders ArticleIntroduction ' 'for ArticleIntroductionBlock', (tester) async { + const category = Category.technology; final block = ArticleIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -178,9 +179,9 @@ void main() { 'renders VideoIntroduction ' 'for VideoIntroductionBlock', (tester) async { setUpVideoPlayerPlatform(); - + const category = Category.technology; final block = VideoIntroductionBlock( - category: PostCategory.technology, + categoryId: category.id, title: 'title', videoUrl: 'videoUrl', ); @@ -267,9 +268,10 @@ void main() { testWidgets( 'renders TrendingStory ' 'for TrendingStoryBlock', (tester) async { + const category = Category.health; final content = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', diff --git a/flutter_news_example/test/article/widgets/article_trailing_content_test.dart b/flutter_news_example/test/article/widgets/article_trailing_content_test.dart index 3fa8ceffd..2df16e733 100644 --- a/flutter_news_example/test/article/widgets/article_trailing_content_test.dart +++ b/flutter_news_example/test/article/widgets/article_trailing_content_test.dart @@ -28,10 +28,11 @@ void main() { group('ArticleTrailingContent', () { late ArticleBloc articleBloc; late AppBloc appBloc; + const category = Category.technology; final postSmallBlock = PostSmallBlock( id: '36f4a017-d099-4fce-8727-1d9ca6a0398c', - category: PostCategory.technology, + categoryId: category.id, author: 'Tom Phillips', publishedAt: DateTime(2022, 6, 2), imageUrl: diff --git a/flutter_news_example/test/categories/bloc/categories_bloc_test.dart b/flutter_news_example/test/categories/bloc/categories_bloc_test.dart index 6cd6ded57..753974ffe 100644 --- a/flutter_news_example/test/categories/bloc/categories_bloc_test.dart +++ b/flutter_news_example/test/categories/bloc/categories_bloc_test.dart @@ -27,19 +27,6 @@ void main() { categoriesBloc = CategoriesBloc(newsRepository: newsRepository); }); - test('can be (de)serialized', () { - final categoriesState = CategoriesState( - status: CategoriesStatus.populated, - categories: categoriesResponse.categories, - selectedCategory: categoriesResponse.categories.first, - ); - - final serialized = categoriesBloc.toJson(categoriesState); - final deserialized = categoriesBloc.fromJson(serialized!); - - expect(deserialized, categoriesState); - }); - group('CategoriesRequested', () { blocTest( 'emits [loading, populated] ' diff --git a/flutter_news_example/test/feed/widgets/category_feed_item_test.dart b/flutter_news_example/test/feed/widgets/category_feed_item_test.dart index 5e67cef12..48c936998 100644 --- a/flutter_news_example/test/feed/widgets/category_feed_item_test.dart +++ b/flutter_news_example/test/feed/widgets/category_feed_item_test.dart @@ -115,9 +115,10 @@ void main() { testWidgets( 'renders PostLarge ' 'for PostLargeBlock', (tester) async { + const category = Category.technology; final block = PostLargeBlock( id: 'id', - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -141,9 +142,10 @@ void main() { testWidgets( 'renders PostMedium ' 'for PostMediumBlock', (tester) async { + const category = Category.sports; final block = PostMediumBlock( id: 'id', - category: PostCategory.sports, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 10), imageUrl: 'imageUrl', @@ -165,9 +167,10 @@ void main() { testWidgets( 'renders PostSmall ' 'for PostSmallBlock', (tester) async { + const category = Category.health; final block = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', @@ -189,12 +192,13 @@ void main() { testWidgets( 'renders PostGrid ' 'for PostGridGroupBlock', (tester) async { + const category = Category.science; final block = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [ PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', @@ -255,9 +259,10 @@ void main() { const articleId = 'articleId'; testWidgets('from PostLarge', (tester) async { + const category = Category.technology; final block = PostLargeBlock( id: articleId, - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -286,9 +291,10 @@ void main() { }); testWidgets('from PostMedium', (tester) async { + const category = Category.sports; final block = PostMediumBlock( id: 'id', - category: PostCategory.sports, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 10), imageUrl: 'imageUrl', @@ -319,9 +325,10 @@ void main() { }); testWidgets('from PostSmall', (tester) async { + const category = Category.health; final block = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', @@ -350,12 +357,13 @@ void main() { }); testWidgets('from PostGrid', (tester) async { + const category = Category.science; final block = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [ PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', @@ -395,9 +403,10 @@ void main() { const articleId = 'articleId'; testWidgets('from PostLarge', (tester) async { + const category = Category.technology; final block = PostLargeBlock( id: articleId, - category: PostCategory.technology, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 9), imageUrl: 'imageUrl', @@ -431,9 +440,10 @@ void main() { }); testWidgets('from PostMedium', (tester) async { + const category = Category.sports; final block = PostMediumBlock( id: 'id', - category: PostCategory.sports, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 10), imageUrl: 'imageUrl', @@ -467,9 +477,10 @@ void main() { }); testWidgets('from PostSmall', (tester) async { + const category = Category.health; final block = PostSmallBlock( id: 'id', - category: PostCategory.health, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 11), imageUrl: 'imageUrl', @@ -502,12 +513,13 @@ void main() { }); testWidgets('from PostGrid', (tester) async { + const category = Category.science; final block = PostGridGroupBlock( - category: PostCategory.science, + categoryId: category.id, tiles: [ PostGridTileBlock( id: 'id', - category: PostCategory.science, + categoryId: category.id, author: 'author', publishedAt: DateTime(2022, 3, 12), imageUrl: 'imageUrl', diff --git a/flutter_news_example/test/helpers/pump_app.dart b/flutter_news_example/test/helpers/pump_app.dart index 26cd9c2e2..79473f913 100644 --- a/flutter_news_example/test/helpers/pump_app.dart +++ b/flutter_news_example/test/helpers/pump_app.dart @@ -7,6 +7,7 @@ import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_news_example/ads/ads.dart'; import 'package:flutter_news_example/analytics/analytics.dart'; import 'package:flutter_news_example/app/app.dart'; +import 'package:flutter_news_example/categories/categories.dart'; import 'package:flutter_news_example/l10n/l10n.dart'; import 'package:flutter_news_example/theme_selector/theme_selector.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -39,6 +40,21 @@ class MockFullScreenAdsBloc FullScreenAdsState get state => const FullScreenAdsState.initial(); } +class MockCategoriesBloc extends MockBloc + implements CategoriesBloc { + @override + CategoriesState get state => const CategoriesState( + status: CategoriesStatus.populated, + categories: [ + Category.sports, + Category.health, + Category.technology, + Category.science, + ], + selectedCategory: Category.sports, + ); +} + class MockUserRepository extends Mock implements UserRepository { @override Stream get incomingEmailLinks => const Stream.empty(); @@ -74,6 +90,7 @@ extension AppTester on WidgetTester { AppBloc? appBloc, AnalyticsBloc? analyticsBloc, FullScreenAdsBloc? fullScreenAdsBloc, + CategoriesBloc? categoriesBloc, UserRepository? userRepository, NewsRepository? newsRepository, NotificationsRepository? notificationRepository, @@ -115,6 +132,7 @@ extension AppTester on WidgetTester { BlocProvider.value( value: fullScreenAdsBloc ?? MockFullScreenAdsBloc(), ), + BlocProvider.value(value: categoriesBloc ?? MockCategoriesBloc()), ], child: MaterialApp( title: 'Flutter News Example', From b381008a26ae462c65d3c8c48abc44413e61fd44 Mon Sep 17 00:00:00 2001 From: matiasleyba Date: Thu, 28 Nov 2024 15:03:29 -0300 Subject: [PATCH 2/2] fix: typo --- flutter_news_example/lib/article/widgets/article_content.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_news_example/lib/article/widgets/article_content.dart b/flutter_news_example/lib/article/widgets/article_content.dart index 12a40ecbd..f15eab3a8 100644 --- a/flutter_news_example/lib/article/widgets/article_content.dart +++ b/flutter_news_example/lib/article/widgets/article_content.dart @@ -23,8 +23,8 @@ class ArticleContent extends StatelessWidget { final hasMoreContent = context.select((ArticleBloc bloc) => bloc.state.hasMoreContent); - /// Show loader while categories are loading as articles may need to consume - /// them + /// Show loader while categories are loading as article blocks may need + /// to consume them. if (status == ArticleStatus.initial || categoriesStatus == CategoriesStatus.initial) { return const ArticleContentLoaderItem(