From 45369f6ee6e564df5a405b4f3e2524e3df44858b Mon Sep 17 00:00:00 2001 From: Shounak Mulay Date: Fri, 12 Apr 2024 16:19:06 +0530 Subject: [PATCH 1/5] Convert freezed sealed unions to dart sealed classed. Convert abstract classes to interfaces. --- .../{{name.snakeCase()}}_screen_intent.dart | 6 ++--- bricks/destination/brick.yaml | 2 +- lib/foundation/mapper/mapper2.dart | 2 +- lib/foundation/mapper/mapper3.dart | 2 +- lib/interactor/base/base_interactor.dart | 1 - lib/interactor/theme/theme_interactor.dart | 2 +- .../favorite/favorite_weather_interactor.dart | 2 +- .../favorite_weather_interactor_impl.dart | 3 +-- .../favorite/ui_weather_list_mapper.dart | 2 +- .../search/city_search_result_mapper.dart | 6 ++--- .../search/search_city_interactor.dart | 2 +- .../search/search_city_interactor_impl.dart | 2 +- .../weather/search/ui_city_mapper.dart | 2 +- lib/navigation/base/base_navigator.dart | 2 +- .../weather/home/home_navigator.dart | 2 +- .../weather/search/search_navigator.dart | 2 +- .../base/intent/intent_handler.dart | 2 +- .../base/renderer/list_item_renderer.dart | 2 +- lib/presentation/base/theme/theme_intent.dart | 20 +++++++++++---- .../base/theme/theme_view_model_impl.dart | 16 ++++++------ .../dynamic_theme_switch.dart | 2 +- .../theme/theme_picker/theme_picker.dart | 2 +- .../destinations/weather/home/home_page.dart | 2 +- .../weather/home/home_screen.dart | 2 +- .../weather/home/home_screen_intent.dart | 9 ++++--- .../weather/home/home_view_model_impl.dart | 7 +++--- .../list/ui_day_weather_heading_renderer.dart | 3 ++- .../widgets/list/ui_weather_renderer.dart | 3 ++- .../weather/search/search_page.dart | 2 +- .../weather/search/search_screen.dart | 2 +- .../weather/search/search_screen_intent.dart | 24 +++++++++++------- .../search/search_view_model_impl.dart | 25 +++++++++---------- .../widgets/list/ui_city_list_item.dart | 2 +- .../search/widgets/list/ui_city_renderer.dart | 2 +- .../search_page_body/search_page_body.dart | 2 +- lib/presentation/entity/intent/intent.dart | 2 +- lib/presentation/entity/screen/screen.dart | 2 +- lib/repository/date/date_repository.dart | 2 +- .../preferences/preferences_repository.dart | 2 +- lib/repository/theme/theme_repository.dart | 2 +- .../weather/local_weather_mapper.dart | 2 +- .../weather/weather_repository.dart | 2 +- .../preferences/preferences_service.dart | 2 +- .../weather/local/weather_local_service.dart | 2 +- .../remote/fake_weather_remote_service.dart | 2 +- .../remote/weather_remote_service.dart | 2 +- .../weather/search/search_page_test.dart | 8 +++--- .../search/search_view_model_test.dart | 16 ++++++------ .../search_page_results_content_test.dart | 2 +- 49 files changed, 114 insertions(+), 103 deletions(-) delete mode 100644 lib/interactor/base/base_interactor.dart diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart index 35942929..db5305ef 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart @@ -1,9 +1,7 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -part '{{name.snakeCase()}}_screen_intent.freezed.dart'; -@freezed -class {{name.pascalCase()}}ScreenIntent with _${{name.pascalCase()}}ScreenIntent implements BaseIntent { - factory {{name.pascalCase()}}ScreenIntent.newIntent() = _HomeScreenIntent_NewIntent; +class {{name.pascalCase()}}ScreenIntent implements BaseIntent { + const {{name.pascalCase()}}ScreenIntent(); } diff --git a/bricks/destination/brick.yaml b/bricks/destination/brick.yaml index fcbe0956..182adbe4 100644 --- a/bricks/destination/brick.yaml +++ b/bricks/destination/brick.yaml @@ -8,7 +8,7 @@ description: A new brick created with the Mason CLI. # The following defines the version and build number for your brick. # A version number is three numbers separated by dots, like 1.2.34 # followed by an optional build number (separated by a +). -version: 0.1.0+1 +version: 0.1.1+1 # The following defines the environment for the current brick. # It includes the version of mason that the brick requires. diff --git a/lib/foundation/mapper/mapper2.dart b/lib/foundation/mapper/mapper2.dart index 98102e3c..feb655c1 100644 --- a/lib/foundation/mapper/mapper2.dart +++ b/lib/foundation/mapper/mapper2.dart @@ -1,3 +1,3 @@ -abstract class Mapper2 { +abstract interface class Mapper2 { TO map(FROM1 from1, FROM2 from2); } diff --git a/lib/foundation/mapper/mapper3.dart b/lib/foundation/mapper/mapper3.dart index 3bd178ec..6dacb9c8 100644 --- a/lib/foundation/mapper/mapper3.dart +++ b/lib/foundation/mapper/mapper3.dart @@ -1,3 +1,3 @@ -abstract class Mapper3 { +abstract interface class Mapper3 { TO map(FROM1 from1, FROM2 from2, FROM3 from3); } diff --git a/lib/interactor/base/base_interactor.dart b/lib/interactor/base/base_interactor.dart deleted file mode 100644 index 6d4a2547..00000000 --- a/lib/interactor/base/base_interactor.dart +++ /dev/null @@ -1 +0,0 @@ -abstract class BaseInteractor {} diff --git a/lib/interactor/theme/theme_interactor.dart b/lib/interactor/theme/theme_interactor.dart index 6419ef97..801f3ea8 100644 --- a/lib/interactor/theme/theme_interactor.dart +++ b/lib/interactor/theme/theme_interactor.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -abstract class ThemeInteractor { +abstract interface class ThemeInteractor { ThemeMode getThemeMode(); Future setThemeMode(ThemeMode themeMode); bool getIsDynamicEnabled(); diff --git a/lib/interactor/weather/favorite/favorite_weather_interactor.dart b/lib/interactor/weather/favorite/favorite_weather_interactor.dart index 9f536e40..bf7d007f 100644 --- a/lib/interactor/weather/favorite/favorite_weather_interactor.dart +++ b/lib/interactor/weather/favorite/favorite_weather_interactor.dart @@ -2,7 +2,7 @@ import 'package:flutter_template/core/entity/result.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -abstract class FavoriteWeatherInteractor { +abstract interface class FavoriteWeatherInteractor { Future> setCityFavorite(UICity uiCity); Future> removeCityFavorite(UICity uiCity); diff --git a/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart b/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart index 38932431..f67fa3ed 100644 --- a/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart +++ b/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart @@ -6,14 +6,13 @@ import 'package:flutter_template/domain/weather/remove_favorite_city_use_case.da import 'package:flutter_template/domain/weather/set_city_favorite_use_case.dart'; import 'package:flutter_template/foundation/extensions/object_ext.dart'; import 'package:flutter_template/foundation/unit.dart'; -import 'package:flutter_template/interactor/base/base_interactor.dart'; import 'package:flutter_template/interactor/weather/favorite/favorite_weather_interactor.dart'; import 'package:flutter_template/interactor/weather/favorite/ui_weather_list_mapper.dart'; import 'package:flutter_template/interactor/weather/search/ui_city_mapper.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -class FavoriteWeatherInteractorImpl extends BaseInteractor +class FavoriteWeatherInteractorImpl implements FavoriteWeatherInteractor { final FetchFavoriteCitiesWeatherUseCase fetchFavoriteCitiesWeatherUseCase; final GetFavoriteCitiesStreamUseCase getFavoriteCitiesStreamUseCase; diff --git a/lib/interactor/weather/favorite/ui_weather_list_mapper.dart b/lib/interactor/weather/favorite/ui_weather_list_mapper.dart index f8becfa7..9c92dcef 100644 --- a/lib/interactor/weather/favorite/ui_weather_list_mapper.dart +++ b/lib/interactor/weather/favorite/ui_weather_list_mapper.dart @@ -5,7 +5,7 @@ import 'package:flutter_template/foundation/mapper/mapper.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_weather.dart'; -abstract class UIWeatherListMapper +abstract interface class UIWeatherListMapper extends Mapper, List> {} class UIWeatherListMapperImpl extends UIWeatherListMapper { diff --git a/lib/interactor/weather/search/city_search_result_mapper.dart b/lib/interactor/weather/search/city_search_result_mapper.dart index 5d1219c2..802f54fd 100644 --- a/lib/interactor/weather/search/city_search_result_mapper.dart +++ b/lib/interactor/weather/search/city_search_result_mapper.dart @@ -4,10 +4,10 @@ import 'package:flutter_template/foundation/mapper/mapper2.dart'; import 'package:flutter_template/interactor/weather/search/ui_city_mapper.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; -abstract class CitySearchResultMapper - extends Mapper2, List, List> {} +abstract interface class CitySearchResultMapper + implements Mapper2, List, List> {} -class CitySearchResultMapperImpl extends CitySearchResultMapper { +class CitySearchResultMapperImpl implements CitySearchResultMapper { final UICityMapper uiCityMapper; CitySearchResultMapperImpl({required this.uiCityMapper}); diff --git a/lib/interactor/weather/search/search_city_interactor.dart b/lib/interactor/weather/search/search_city_interactor.dart index b659b42e..36b2c8de 100644 --- a/lib/interactor/weather/search/search_city_interactor.dart +++ b/lib/interactor/weather/search/search_city_interactor.dart @@ -1,6 +1,6 @@ import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; -abstract class SearchCityInteractor { +abstract interface class SearchCityInteractor { Stream> get searchResultsStream; Future search(String term); diff --git a/lib/interactor/weather/search/search_city_interactor_impl.dart b/lib/interactor/weather/search/search_city_interactor_impl.dart index 40f7968e..d0402563 100644 --- a/lib/interactor/weather/search/search_city_interactor_impl.dart +++ b/lib/interactor/weather/search/search_city_interactor_impl.dart @@ -11,7 +11,7 @@ import 'package:flutter_template/interactor/weather/search/search_city_interacto import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:rxdart/rxdart.dart'; -class SearchCityInteractorImpl extends SearchCityInteractor { +class SearchCityInteractorImpl implements SearchCityInteractor { final SearchCitiesUseCase searchCitiesUseCase; final GetFavoriteCitiesStreamUseCase favoriteCitiesStreamUseCase; final CitySearchResultMapper citySearchResultMapper; diff --git a/lib/interactor/weather/search/ui_city_mapper.dart b/lib/interactor/weather/search/ui_city_mapper.dart index 65445424..0a03dd7d 100644 --- a/lib/interactor/weather/search/ui_city_mapper.dart +++ b/lib/interactor/weather/search/ui_city_mapper.dart @@ -3,7 +3,7 @@ import 'package:flutter_template/foundation/extensions/object_ext.dart'; import 'package:flutter_template/foundation/mapper/mapper2.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -abstract class UICityMapper extends Mapper2 { +abstract class UICityMapper implements Mapper2 { City mapCity(UICity from); UICity mapFavouriteCity(City from); diff --git a/lib/navigation/base/base_navigator.dart b/lib/navigation/base/base_navigator.dart index 5ec07cc5..45c5c1a4 100644 --- a/lib/navigation/base/base_navigator.dart +++ b/lib/navigation/base/base_navigator.dart @@ -1,6 +1,6 @@ import 'package:auto_route/auto_route.dart'; -abstract class BaseNavigator { +abstract interface class BaseNavigator { void to(PageRouteInfo route); void back(); diff --git a/lib/navigation/weather/home/home_navigator.dart b/lib/navigation/weather/home/home_navigator.dart index cafb761c..6efab9ed 100644 --- a/lib/navigation/weather/home/home_navigator.dart +++ b/lib/navigation/weather/home/home_navigator.dart @@ -1,3 +1,3 @@ -abstract class HomeNavigator { +abstract interface class HomeNavigator { void toSearchScreen(); } diff --git a/lib/navigation/weather/search/search_navigator.dart b/lib/navigation/weather/search/search_navigator.dart index 9a6cf651..f02da6a9 100644 --- a/lib/navigation/weather/search/search_navigator.dart +++ b/lib/navigation/weather/search/search_navigator.dart @@ -1,3 +1,3 @@ -abstract class SearchNavigator { +abstract interface class SearchNavigator { void back(); } diff --git a/lib/presentation/base/intent/intent_handler.dart b/lib/presentation/base/intent/intent_handler.dart index 15385577..b6f185af 100644 --- a/lib/presentation/base/intent/intent_handler.dart +++ b/lib/presentation/base/intent/intent_handler.dart @@ -1,5 +1,5 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; -abstract class IntentHandler { +abstract interface class IntentHandler { void onIntent(T intent); } diff --git a/lib/presentation/base/renderer/list_item_renderer.dart b/lib/presentation/base/renderer/list_item_renderer.dart index b42f8733..4ac1f568 100644 --- a/lib/presentation/base/renderer/list_item_renderer.dart +++ b/lib/presentation/base/renderer/list_item_renderer.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/intent/intent.dart'; -abstract class ListItemRenderer { +abstract interface class ListItemRenderer { const ListItemRenderer(); Widget getWidget(BuildContext context, T data, StreamSink sink); } diff --git a/lib/presentation/base/theme/theme_intent.dart b/lib/presentation/base/theme/theme_intent.dart index f3d05457..d0629afd 100644 --- a/lib/presentation/base/theme/theme_intent.dart +++ b/lib/presentation/base/theme/theme_intent.dart @@ -2,10 +2,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/presentation/entity/intent/intent.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -part 'theme_intent.freezed.dart'; +sealed class ThemeIntent implements BaseIntent { + const ThemeIntent(); +} + +class SetThemeModeThemeIntent extends ThemeIntent { + final ThemeMode mode; -@freezed -class ThemeIntent with _$ThemeIntent implements BaseIntent { - factory ThemeIntent.setThemeMode(ThemeMode mode) = _ThemeIntent_SetThemeMode; - factory ThemeIntent.setIsDynamic(bool isDynamic) = _ThemeIntent_SetIsDynamic; + const SetThemeModeThemeIntent({required this.mode}); } + +class SetIsDynamicThemeIntent extends ThemeIntent { + final bool isDynamic; + + const SetIsDynamicThemeIntent({required this.isDynamic}); +} + + diff --git a/lib/presentation/base/theme/theme_view_model_impl.dart b/lib/presentation/base/theme/theme_view_model_impl.dart index 53f4991d..b50ed616 100644 --- a/lib/presentation/base/theme/theme_view_model_impl.dart +++ b/lib/presentation/base/theme/theme_view_model_impl.dart @@ -21,17 +21,15 @@ class ThemeViewModelImpl extends ThemeViewModel { } @override - void onIntent(ThemeIntent intent) { - intent.when( - setThemeMode: (mode) async { - await themeInteractor.setThemeMode(mode); + Future onIntent(ThemeIntent intent) async { + switch (intent) { + case SetThemeModeThemeIntent(): + await themeInteractor.setThemeMode(intent.mode); state = state.copyWith(themeMode: themeInteractor.getThemeMode()); - }, - setIsDynamic: (isDynamic) async { - await themeInteractor.setIsDynamicEnabled(isDynamic); + case SetIsDynamicThemeIntent(): + await themeInteractor.setIsDynamicEnabled(intent.isDynamic); state = state.copyWith(isDynamic: themeInteractor.getIsDynamicEnabled()); - }, - ); + } } } diff --git a/lib/presentation/base/widgets/theme/dynamic_theme_switch/dynamic_theme_switch.dart b/lib/presentation/base/widgets/theme/dynamic_theme_switch/dynamic_theme_switch.dart index cd5cf1a4..3476cbf3 100644 --- a/lib/presentation/base/widgets/theme/dynamic_theme_switch/dynamic_theme_switch.dart +++ b/lib/presentation/base/widgets/theme/dynamic_theme_switch/dynamic_theme_switch.dart @@ -15,7 +15,7 @@ class DynamicThemeSwitch extends ConsumerWidget { return DynamicThemeSwitchContent( isDynamic: isDynamic, onIsDynamicToggled: (isDynamic) { - themeViewModel.onIntent(ThemeIntent.setIsDynamic(isDynamic)); + themeViewModel.onIntent(SetIsDynamicThemeIntent(isDynamic: isDynamic)); }, ); } diff --git a/lib/presentation/base/widgets/theme/theme_picker/theme_picker.dart b/lib/presentation/base/widgets/theme/theme_picker/theme_picker.dart index 742dbd43..c82646b4 100644 --- a/lib/presentation/base/widgets/theme/theme_picker/theme_picker.dart +++ b/lib/presentation/base/widgets/theme/theme_picker/theme_picker.dart @@ -15,7 +15,7 @@ class ThemePicker extends ConsumerWidget { return ThemePickerContent( themeMode: themeState.themeMode, onThemeModeSelected: (ThemeMode mode) { - themeViewModel.onIntent(ThemeIntent.setThemeMode(mode)); + themeViewModel.onIntent(SetThemeModeThemeIntent(mode: mode)); }, ); } diff --git a/lib/presentation/destinations/weather/home/home_page.dart b/lib/presentation/destinations/weather/home/home_page.dart index f255c5a7..3b071c82 100644 --- a/lib/presentation/destinations/weather/home/home_page.dart +++ b/lib/presentation/destinations/weather/home/home_page.dart @@ -40,7 +40,7 @@ class HomePage extends ConsumerWidget { IconButton( onPressed: () { final viewModel = ref.watch(homeViewModelProvider.notifier); - viewModel.onIntent(HomeScreenIntent.search()); + viewModel.onIntent(const SearchHomeScreenIntent()); }, icon: const Icon(Icons.search), ), diff --git a/lib/presentation/destinations/weather/home/home_screen.dart b/lib/presentation/destinations/weather/home/home_screen.dart index 2f1a8e0f..f3e8ccc1 100644 --- a/lib/presentation/destinations/weather/home/home_screen.dart +++ b/lib/presentation/destinations/weather/home/home_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter_template/presentation/entity/routes/routes.dart'; import 'package:flutter_template/presentation/entity/screen/screen.dart'; -class HomeScreen extends Screen { +class HomeScreen implements Screen { const HomeScreen() : super(); static get path => Routes.home; diff --git a/lib/presentation/destinations/weather/home/home_screen_intent.dart b/lib/presentation/destinations/weather/home/home_screen_intent.dart index cd62ad27..a66005fd 100644 --- a/lib/presentation/destinations/weather/home/home_screen_intent.dart +++ b/lib/presentation/destinations/weather/home/home_screen_intent.dart @@ -1,9 +1,10 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -part 'home_screen_intent.freezed.dart'; +sealed class HomeScreenIntent implements BaseIntent { + const HomeScreenIntent(); +} -@freezed -class HomeScreenIntent with _$HomeScreenIntent implements BaseIntent { - factory HomeScreenIntent.search() = _HomeScreenIntent_Search; +class SearchHomeScreenIntent extends HomeScreenIntent { + const SearchHomeScreenIntent(); } diff --git a/lib/presentation/destinations/weather/home/home_view_model_impl.dart b/lib/presentation/destinations/weather/home/home_view_model_impl.dart index 7b40de63..7bffe731 100644 --- a/lib/presentation/destinations/weather/home/home_view_model_impl.dart +++ b/lib/presentation/destinations/weather/home/home_view_model_impl.dart @@ -45,10 +45,9 @@ class HomeViewModelImpl extends HomeViewModel { @override void onIntent(HomeScreenIntent intent) { - intent.when( - search: () { + switch (intent) { + case SearchHomeScreenIntent(): homeNavigator.toSearchScreen(); - }, - ); + } } } diff --git a/lib/presentation/destinations/weather/home/widgets/list/ui_day_weather_heading_renderer.dart b/lib/presentation/destinations/weather/home/widgets/list/ui_day_weather_heading_renderer.dart index 9bb92ab3..8672810b 100644 --- a/lib/presentation/destinations/weather/home/widgets/list/ui_day_weather_heading_renderer.dart +++ b/lib/presentation/destinations/weather/home/widgets/list/ui_day_weather_heading_renderer.dart @@ -7,8 +7,9 @@ import 'package:flutter_template/presentation/destinations/weather/home/widgets/ import 'package:flutter_template/presentation/entity/weather/ui_day_weather_heading.dart'; class UIDayWeatherHeaderRenderer - extends ListItemRenderer { + implements ListItemRenderer { const UIDayWeatherHeaderRenderer(); + @override Widget getWidget(BuildContext context, UIDayWeatherHeading data, StreamSink sink) { diff --git a/lib/presentation/destinations/weather/home/widgets/list/ui_weather_renderer.dart b/lib/presentation/destinations/weather/home/widgets/list/ui_weather_renderer.dart index e6182c2a..3d022d50 100644 --- a/lib/presentation/destinations/weather/home/widgets/list/ui_weather_renderer.dart +++ b/lib/presentation/destinations/weather/home/widgets/list/ui_weather_renderer.dart @@ -5,7 +5,8 @@ import 'package:flutter_template/presentation/destinations/weather/home/home_scr import 'package:flutter_template/presentation/destinations/weather/home/widgets/list/ui_weather_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_weather.dart'; -class UIWeatherRenderer extends ListItemRenderer { +class UIWeatherRenderer + implements ListItemRenderer { const UIWeatherRenderer(); @override diff --git a/lib/presentation/destinations/weather/search/search_page.dart b/lib/presentation/destinations/weather/search/search_page.dart index 13c7229e..09faa3c9 100644 --- a/lib/presentation/destinations/weather/search/search_page.dart +++ b/lib/presentation/destinations/weather/search/search_page.dart @@ -23,7 +23,7 @@ class SearchPage extends StatelessWidget { viewModelProvider: searchViewModelProvider, screen: searchScreen, onAppBarBackPressed: (viewModel) => viewModel.onIntent( - SearchScreenIntent.back(), + BackSearchScreenIntent(), ), body: const SearchPageBody(), onEffect: _handleEffect, diff --git a/lib/presentation/destinations/weather/search/search_screen.dart b/lib/presentation/destinations/weather/search/search_screen.dart index 1803d09b..6366dba4 100644 --- a/lib/presentation/destinations/weather/search/search_screen.dart +++ b/lib/presentation/destinations/weather/search/search_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter_template/presentation/entity/routes/routes.dart'; import 'package:flutter_template/presentation/entity/screen/screen.dart'; -class SearchScreen extends Screen { +class SearchScreen implements Screen { const SearchScreen() : super(); static get path => Routes.search; diff --git a/lib/presentation/destinations/weather/search/search_screen_intent.dart b/lib/presentation/destinations/weather/search/search_screen_intent.dart index a8b7ed43..f9f84376 100644 --- a/lib/presentation/destinations/weather/search/search_screen_intent.dart +++ b/lib/presentation/destinations/weather/search/search_screen_intent.dart @@ -1,16 +1,22 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -part 'search_screen_intent.freezed.dart'; +sealed class SearchScreenIntent implements BaseIntent { + const SearchScreenIntent(); +} + +class BackSearchScreenIntent extends SearchScreenIntent { + const BackSearchScreenIntent(); +} -@freezed -class SearchScreenIntent with _$SearchScreenIntent implements BaseIntent { - factory SearchScreenIntent.back() = _SearchScreenIntent_Back; +class SearchSearchScreenIntent extends SearchScreenIntent { + final String searchTerm; + + const SearchSearchScreenIntent({required this.searchTerm}); +} - factory SearchScreenIntent.search({required String searchTerm}) = - _SearchScreenIntent_Search; +class ToggleFavoriteSearchScreenIntent extends SearchScreenIntent { + final UICity city; - factory SearchScreenIntent.toggleFavorite({required UICity city}) = - _SearchScreenIntent_Favorite; + const ToggleFavoriteSearchScreenIntent({required this.city}); } diff --git a/lib/presentation/destinations/weather/search/search_view_model_impl.dart b/lib/presentation/destinations/weather/search/search_view_model_impl.dart index 6b5b2b94..9bff95ac 100644 --- a/lib/presentation/destinations/weather/search/search_view_model_impl.dart +++ b/lib/presentation/destinations/weather/search/search_view_model_impl.dart @@ -59,21 +59,20 @@ class SearchViewModelImpl extends SearchViewModel { ); @override - void onIntent(SearchScreenIntent intent) { - intent.when( - back: () => searchNavigator.back(), - search: (newSearchTerm) { - if (newSearchTerm != searchTerm) { - _searchTermSubject.add(newSearchTerm); + Future onIntent(SearchScreenIntent intent) async { + switch (intent) { + case BackSearchScreenIntent(): + searchNavigator.back(); + case SearchSearchScreenIntent(): + if (intent.searchTerm != searchTerm) { + _searchTermSubject.add(intent.searchTerm); } - }, - toggleFavorite: (UICity city) async { - if (city.isFavourite) { - await favoriteWeatherInteractor.removeCityFavorite(city); + case ToggleFavoriteSearchScreenIntent(): + if (intent.city.isFavourite) { + await favoriteWeatherInteractor.removeCityFavorite(intent.city); } else { - await favoriteWeatherInteractor.setCityFavorite(city); + await favoriteWeatherInteractor.setCityFavorite(intent.city); } - }, - ); + } } } diff --git a/lib/presentation/destinations/weather/search/widgets/list/ui_city_list_item.dart b/lib/presentation/destinations/weather/search/widgets/list/ui_city_list_item.dart index fb74fcaa..381705f3 100644 --- a/lib/presentation/destinations/weather/search/widgets/list/ui_city_list_item.dart +++ b/lib/presentation/destinations/weather/search/widgets/list/ui_city_list_item.dart @@ -29,7 +29,7 @@ class UICityListItem extends StatelessWidget { color: Theme.of(context).colorScheme.secondary, ), onPressed: () { - sink.add(SearchScreenIntent.toggleFavorite(city: city)); + sink.add(ToggleFavoriteSearchScreenIntent(city: city)); }, ), ], diff --git a/lib/presentation/destinations/weather/search/widgets/list/ui_city_renderer.dart b/lib/presentation/destinations/weather/search/widgets/list/ui_city_renderer.dart index 32b6882a..621e252e 100644 --- a/lib/presentation/destinations/weather/search/widgets/list/ui_city_renderer.dart +++ b/lib/presentation/destinations/weather/search/widgets/list/ui_city_renderer.dart @@ -6,7 +6,7 @@ import 'package:flutter_template/presentation/destinations/weather/search/search import 'package:flutter_template/presentation/destinations/weather/search/widgets/list/ui_city_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -class UICityRenderer extends ListItemRenderer { +class UICityRenderer implements ListItemRenderer { const UICityRenderer(); @override Widget getWidget( diff --git a/lib/presentation/destinations/weather/search/widgets/search_page_body/search_page_body.dart b/lib/presentation/destinations/weather/search/widgets/search_page_body/search_page_body.dart index 0138fcf2..c0d0b869 100644 --- a/lib/presentation/destinations/weather/search/widgets/search_page_body/search_page_body.dart +++ b/lib/presentation/destinations/weather/search/widgets/search_page_body/search_page_body.dart @@ -20,7 +20,7 @@ class SearchPageBody extends HookConsumerWidget { textController.addListener(() { final viewModel = ref.read(searchViewModelProvider.notifier); - viewModel.onIntent(SearchScreenIntent.search( + viewModel.onIntent(SearchSearchScreenIntent( searchTerm: textController.text, )); }); diff --git a/lib/presentation/entity/intent/intent.dart b/lib/presentation/entity/intent/intent.dart index 1dc556e0..3a21cac5 100644 --- a/lib/presentation/entity/intent/intent.dart +++ b/lib/presentation/entity/intent/intent.dart @@ -1 +1 @@ -abstract class BaseIntent {} +interface class BaseIntent {} diff --git a/lib/presentation/entity/screen/screen.dart b/lib/presentation/entity/screen/screen.dart index f1846d5b..1929d361 100644 --- a/lib/presentation/entity/screen/screen.dart +++ b/lib/presentation/entity/screen/screen.dart @@ -1,3 +1,3 @@ -abstract class Screen { +abstract interface class Screen { const Screen(); } diff --git a/lib/repository/date/date_repository.dart b/lib/repository/date/date_repository.dart index 4c89eb41..770896e8 100644 --- a/lib/repository/date/date_repository.dart +++ b/lib/repository/date/date_repository.dart @@ -3,7 +3,7 @@ import 'package:flutter_template/domain/entity/base/datetime/date_time.dart'; import 'package:flutter_template/domain/entity/base/datetime/time.dart'; import 'package:flutter_template/foundation/global_type_alias.dart'; -abstract class DateRepository { +abstract interface class DateRepository { DartDateTime nowDartDateTime(); Date todayDate(); diff --git a/lib/repository/preferences/preferences_repository.dart b/lib/repository/preferences/preferences_repository.dart index 45c03e09..a313e602 100644 --- a/lib/repository/preferences/preferences_repository.dart +++ b/lib/repository/preferences/preferences_repository.dart @@ -1,4 +1,4 @@ -abstract class PreferencesRepository { +abstract interface class PreferencesRepository { bool contains({required String key}); int getInt({required String key, required int defaultValue}); diff --git a/lib/repository/theme/theme_repository.dart b/lib/repository/theme/theme_repository.dart index e4e18251..80a0056f 100644 --- a/lib/repository/theme/theme_repository.dart +++ b/lib/repository/theme/theme_repository.dart @@ -1,6 +1,6 @@ import 'package:flutter_template/domain/entity/theme/theme_mode.dart'; -abstract class ThemeRepository { +abstract interface class ThemeRepository { AppThemeMode getThemeMode(); Future setThemeMode({required AppThemeMode themeMode}); bool getIsDynamicEnabled(); diff --git a/lib/repository/weather/local_weather_mapper.dart b/lib/repository/weather/local_weather_mapper.dart index 8e8df107..fc4e9cda 100644 --- a/lib/repository/weather/local_weather_mapper.dart +++ b/lib/repository/weather/local_weather_mapper.dart @@ -7,7 +7,7 @@ import 'package:flutter_template/services/base/database/app_database.dart'; import 'package:flutter_template/services/entity/open_weather/current_weather/remote/remote_current_weather.dart'; import 'package:flutter_template/services/entity/open_weather/current_weather/remote/remote_current_weather_weather.dart'; -abstract class LocalWeatherMapper extends Mapper3 {} class LocalWeatherMapperImpl extends LocalWeatherMapper { diff --git a/lib/repository/weather/weather_repository.dart b/lib/repository/weather/weather_repository.dart index 5b2622f5..5d313935 100644 --- a/lib/repository/weather/weather_repository.dart +++ b/lib/repository/weather/weather_repository.dart @@ -1,7 +1,7 @@ import 'package:flutter_template/domain/entity/weather/city.dart'; import 'package:flutter_template/domain/entity/weather/weather.dart'; -abstract class WeatherRepository { +abstract interface class WeatherRepository { Future> searchCities(String searchTerm); Stream> getFavoriteCitiesStream(); diff --git a/lib/services/preferences/preferences_service.dart b/lib/services/preferences/preferences_service.dart index 66d5161f..ecb1b714 100644 --- a/lib/services/preferences/preferences_service.dart +++ b/lib/services/preferences/preferences_service.dart @@ -1,4 +1,4 @@ -abstract class PreferencesService { +abstract interface class PreferencesService { bool containsKey(String key); Future setInt({required String key, required int value}); diff --git a/lib/services/weather/local/weather_local_service.dart b/lib/services/weather/local/weather_local_service.dart index 46cd84e5..be1d798d 100644 --- a/lib/services/weather/local/weather_local_service.dart +++ b/lib/services/weather/local/weather_local_service.dart @@ -1,6 +1,6 @@ import 'package:flutter_template/services/base/database/app_database.dart'; -abstract class WeatherLocalService { +abstract interface class WeatherLocalService { Stream> getFavoriteCitiesStream(); Future> getFavouriteCities(); diff --git a/lib/services/weather/remote/fake_weather_remote_service.dart b/lib/services/weather/remote/fake_weather_remote_service.dart index 44d285a2..bd1b2813 100644 --- a/lib/services/weather/remote/fake_weather_remote_service.dart +++ b/lib/services/weather/remote/fake_weather_remote_service.dart @@ -9,7 +9,7 @@ import 'package:flutter_template/services/entity/open_weather/current_weather/re import 'package:flutter_template/services/entity/open_weather/geo_coding/remote/remote_location.dart'; import 'package:flutter_template/services/weather/remote/weather_remote_service.dart'; -class FakeWeatherRemoteService extends WeatherRemoteService { +class FakeWeatherRemoteService implements WeatherRemoteService { @override Future currentWeather( {required String cityAndState}) async { diff --git a/lib/services/weather/remote/weather_remote_service.dart b/lib/services/weather/remote/weather_remote_service.dart index af5ad91e..51602ce8 100644 --- a/lib/services/weather/remote/weather_remote_service.dart +++ b/lib/services/weather/remote/weather_remote_service.dart @@ -1,7 +1,7 @@ import 'package:flutter_template/services/entity/open_weather/current_weather/remote/remote_current_weather.dart'; import 'package:flutter_template/services/entity/open_weather/geo_coding/remote/remote_location.dart'; -abstract class WeatherRemoteService { +abstract interface class WeatherRemoteService { Future> geocodingSearch({required String searchTerm}); Future currentWeather({required String cityAndState}); diff --git a/test/presentation/integration/destinations/weather/search/search_page_test.dart b/test/presentation/integration/destinations/weather/search/search_page_test.dart index d8caf268..06ba3471 100644 --- a/test/presentation/integration/destinations/weather/search/search_page_test.dart +++ b/test/presentation/integration/destinations/weather/search/search_page_test.dart @@ -196,7 +196,7 @@ void main() { // Then verify(() => fakeSearchViewModel - .onIntent(SearchScreenIntent.search(searchTerm: "search"))).called(1); + .onIntent(const SearchSearchScreenIntent(searchTerm: "search"))).called(1); }); testWidgets( @@ -211,7 +211,7 @@ void main() { await tester.pump(); // Then - verify(() => fakeSearchViewModel.onIntent(SearchScreenIntent.back())) + verify(() => fakeSearchViewModel.onIntent(const BackSearchScreenIntent())) .called(1); }); @@ -258,8 +258,8 @@ void main() { // Then verify(() => fakeSearchViewModel.onIntent( - SearchScreenIntent.toggleFavorite(city: uiCityList.first))).called(1); + ToggleFavoriteSearchScreenIntent(city: uiCityList.first))).called(1); verify(() => fakeSearchViewModel.onIntent( - SearchScreenIntent.toggleFavorite(city: uiCityList.last))).called(1); + ToggleFavoriteSearchScreenIntent(city: uiCityList.last))).called(1); }); } diff --git a/test/presentation/unit/destinations/weather/search/search_view_model_test.dart b/test/presentation/unit/destinations/weather/search/search_view_model_test.dart index 7628034c..27239e6b 100644 --- a/test/presentation/unit/destinations/weather/search/search_view_model_test.dart +++ b/test/presentation/unit/destinations/weather/search/search_view_model_test.dart @@ -105,7 +105,7 @@ void main() { emits(getInitialState().copyWith(showLoading: false)), ]); - viewModel.onIntent(SearchScreenIntent.search(searchTerm: searchTerm)); + viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm)); }); test( @@ -128,10 +128,10 @@ void main() { emits(getInitialState().copyWith(showLoading: false)), ]); - viewModel.onIntent(SearchScreenIntent.search(searchTerm: searchTerm1)); - viewModel.onIntent(SearchScreenIntent.search(searchTerm: searchTerm2)); - viewModel.onIntent(SearchScreenIntent.search(searchTerm: searchTerm3)); - viewModel.onIntent(SearchScreenIntent.search(searchTerm: searchTerm4)); + viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm1)); + viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm2)); + viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm3)); + viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm4)); // Then // Make sure no calls happen instantly @@ -151,7 +151,7 @@ void main() { createViewModel(); // When - viewModel.onIntent(SearchScreenIntent.back()); + viewModel.onIntent(const BackSearchScreenIntent()); // Then verify(() => searchNavigator.back()).called(1); @@ -169,7 +169,7 @@ void main() { createViewModel(); // When - viewModel.onIntent(SearchScreenIntent.toggleFavorite(city: city)); + viewModel.onIntent(ToggleFavoriteSearchScreenIntent(city: city)); // Then verify(() => favoriteWeatherInteractor.setCityFavorite(city)).called(1); @@ -188,7 +188,7 @@ void main() { createViewModel(); // When - viewModel.onIntent(SearchScreenIntent.toggleFavorite(city: city)); + viewModel.onIntent(ToggleFavoriteSearchScreenIntent(city: city)); // Then verify(() => favoriteWeatherInteractor.removeCityFavorite(city)).called(1); diff --git a/test/presentation/widget/destinations/weather/search/widgets/search_page_results_content_test.dart b/test/presentation/widget/destinations/weather/search/widgets/search_page_results_content_test.dart index acdefe72..823046f1 100644 --- a/test/presentation/widget/destinations/weather/search/widgets/search_page_results_content_test.dart +++ b/test/presentation/widget/destinations/weather/search/widgets/search_page_results_content_test.dart @@ -174,7 +174,7 @@ void main() { // Then verify( () => intentHandler.onIntent( - SearchScreenIntent.toggleFavorite( + ToggleFavoriteSearchScreenIntent( city: searchList.first, ), ), From 7f47cdf9aa3608de10b70c52b3952308cf08192a Mon Sep 17 00:00:00 2001 From: Shounak Mulay Date: Fri, 12 Apr 2024 16:28:07 +0530 Subject: [PATCH 2/5] Update destination brick --- .../{{name.snakeCase()}}_page_body.dart | 2 +- .../{{name.snakeCase()}}/{{name.snakeCase()}}_screen.dart | 2 +- .../{{name.snakeCase()}}_screen_intent.dart | 4 +--- .../{{name.snakeCase()}}/{{name.snakeCase()}}_view_model.dart | 2 +- .../{{name.snakeCase()}}_view_model_impl.dart | 2 ++ 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/widgets/{{name.snakeCase()}}_page_body/{{name.snakeCase()}}_page_body.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/widgets/{{name.snakeCase()}}_page_body/{{name.snakeCase()}}_page_body.dart index cdfbc2f6..85fc343b 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/widgets/{{name.snakeCase()}}_page_body/{{name.snakeCase()}}_page_body.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/widgets/{{name.snakeCase()}}_page_body/{{name.snakeCase()}}_page_body.dart @@ -10,6 +10,6 @@ class {{name.pascalCase()}}PageBody extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final {{name.camelCase()}}ViewModel = ref.watch({{name.camelCase()}}ViewModelProvider.notifier); - return {{name.pascalCase()}}PageBodyContent(); + return {{name.pascalCase()}}PageBodyContent(intentHandler: {{name.camelCase()}}ViewModel.onIntent); } } \ No newline at end of file diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen.dart index 42478d6b..699166f3 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter_template/presentation/entity/routes/routes.dart'; import 'package:flutter_template/presentation/entity/screen/screen.dart'; -class {{name.pascalCase()}}Screen extends Screen { +class {{name.pascalCase()}}Screen implements Screen { const {{name.pascalCase()}}Screen() : super(); static get path => Routes.{{name.camelCase()}}; diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart index db5305ef..40cd2958 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart @@ -1,7 +1,5 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -class {{name.pascalCase()}}ScreenIntent implements BaseIntent { +sealed class {{name.pascalCase()}}ScreenIntent implements BaseIntent { const {{name.pascalCase()}}ScreenIntent(); } diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model.dart index b60828ff..b512c209 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model.dart @@ -10,5 +10,5 @@ final {{name.camelCase()}}ViewModelProvider = abstract class {{name.pascalCase()}}ViewModel extends BaseViewModel<{{name.pascalCase()}}Screen, {{name.pascalCase()}}ScreenState> implements IntentHandler<{{name.pascalCase()}}ScreenIntent> { - {{name.pascalCase()}}ViewModel({{name.pascalCase()}}ScreenState state) : super(state); + {{name.pascalCase()}}ViewModel(super.state); } diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model_impl.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model_impl.dart index cad04b54..96605a2c 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model_impl.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_view_model_impl.dart @@ -29,6 +29,8 @@ class {{name.pascalCase()}}ViewModelImpl extends {{name.pascalCase()}}ViewModel @override void onIntent({{name.pascalCase()}}ScreenIntent intent) { + switch (intent) { + } } } From 4f58d8eeaa9c289011173e744e28f60f6b2eb533 Mon Sep 17 00:00:00 2001 From: Shounak Mulay Date: Fri, 12 Apr 2024 16:36:09 +0530 Subject: [PATCH 3/5] Fix lint errors --- lib/presentation/base/theme/theme_intent.dart | 1 - .../destinations/weather/home/home_screen_intent.dart | 1 - .../destinations/weather/search/search_page.dart | 2 +- .../weather/search/search_view_model_impl.dart | 1 - .../weather/search/search_view_model_test.dart | 10 +++++----- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/presentation/base/theme/theme_intent.dart b/lib/presentation/base/theme/theme_intent.dart index d0629afd..e86374ae 100644 --- a/lib/presentation/base/theme/theme_intent.dart +++ b/lib/presentation/base/theme/theme_intent.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/presentation/entity/intent/intent.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; sealed class ThemeIntent implements BaseIntent { const ThemeIntent(); diff --git a/lib/presentation/destinations/weather/home/home_screen_intent.dart b/lib/presentation/destinations/weather/home/home_screen_intent.dart index a66005fd..692304ae 100644 --- a/lib/presentation/destinations/weather/home/home_screen_intent.dart +++ b/lib/presentation/destinations/weather/home/home_screen_intent.dart @@ -1,5 +1,4 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; sealed class HomeScreenIntent implements BaseIntent { const HomeScreenIntent(); diff --git a/lib/presentation/destinations/weather/search/search_page.dart b/lib/presentation/destinations/weather/search/search_page.dart index 09faa3c9..903b0931 100644 --- a/lib/presentation/destinations/weather/search/search_page.dart +++ b/lib/presentation/destinations/weather/search/search_page.dart @@ -23,7 +23,7 @@ class SearchPage extends StatelessWidget { viewModelProvider: searchViewModelProvider, screen: searchScreen, onAppBarBackPressed: (viewModel) => viewModel.onIntent( - BackSearchScreenIntent(), + const BackSearchScreenIntent(), ), body: const SearchPageBody(), onEffect: _handleEffect, diff --git a/lib/presentation/destinations/weather/search/search_view_model_impl.dart b/lib/presentation/destinations/weather/search/search_view_model_impl.dart index 9bff95ac..b1caaa6b 100644 --- a/lib/presentation/destinations/weather/search/search_view_model_impl.dart +++ b/lib/presentation/destinations/weather/search/search_view_model_impl.dart @@ -7,7 +7,6 @@ import 'package:flutter_template/presentation/destinations/weather/search/search import 'package:flutter_template/presentation/destinations/weather/search/search_view_model.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/base/ui_toolbar.dart'; -import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; import 'package:flutter_template/presentation/intl/translations/translation_keys.dart'; import 'package:rxdart/rxdart.dart'; diff --git a/test/presentation/unit/destinations/weather/search/search_view_model_test.dart b/test/presentation/unit/destinations/weather/search/search_view_model_test.dart index 27239e6b..5427bf38 100644 --- a/test/presentation/unit/destinations/weather/search/search_view_model_test.dart +++ b/test/presentation/unit/destinations/weather/search/search_view_model_test.dart @@ -105,7 +105,7 @@ void main() { emits(getInitialState().copyWith(showLoading: false)), ]); - viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm)); + viewModel.onIntent(const SearchSearchScreenIntent(searchTerm: searchTerm)); }); test( @@ -128,10 +128,10 @@ void main() { emits(getInitialState().copyWith(showLoading: false)), ]); - viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm1)); - viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm2)); - viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm3)); - viewModel.onIntent(SearchSearchScreenIntent(searchTerm: searchTerm4)); + viewModel.onIntent(const SearchSearchScreenIntent(searchTerm: searchTerm1)); + viewModel.onIntent(const SearchSearchScreenIntent(searchTerm: searchTerm2)); + viewModel.onIntent(const SearchSearchScreenIntent(searchTerm: searchTerm3)); + viewModel.onIntent(const SearchSearchScreenIntent(searchTerm: searchTerm4)); // Then // Make sure no calls happen instantly From 9f11acafdf61f84cd46552743aa2eb6bb6fc0887 Mon Sep 17 00:00:00 2001 From: Shounak Mulay Date: Fri, 12 Apr 2024 16:40:40 +0530 Subject: [PATCH 4/5] Run dart format --- .../weather/favorite/favorite_weather_interactor_impl.dart | 3 +-- lib/presentation/base/renderer/list_item_renderer.dart | 3 ++- lib/presentation/base/theme/theme_intent.dart | 2 -- lib/repository/weather/local_weather_mapper.dart | 6 ++++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart b/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart index f67fa3ed..0e2d7624 100644 --- a/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart +++ b/lib/interactor/weather/favorite/favorite_weather_interactor_impl.dart @@ -12,8 +12,7 @@ import 'package:flutter_template/interactor/weather/search/ui_city_mapper.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -class FavoriteWeatherInteractorImpl - implements FavoriteWeatherInteractor { +class FavoriteWeatherInteractorImpl implements FavoriteWeatherInteractor { final FetchFavoriteCitiesWeatherUseCase fetchFavoriteCitiesWeatherUseCase; final GetFavoriteCitiesStreamUseCase getFavoriteCitiesStreamUseCase; final SetCityFavoriteUseCase setCityFavoriteUseCase; diff --git a/lib/presentation/base/renderer/list_item_renderer.dart b/lib/presentation/base/renderer/list_item_renderer.dart index 4ac1f568..d5df798b 100644 --- a/lib/presentation/base/renderer/list_item_renderer.dart +++ b/lib/presentation/base/renderer/list_item_renderer.dart @@ -4,7 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/presentation/entity/base/ui_list_item.dart'; import 'package:flutter_template/presentation/entity/intent/intent.dart'; -abstract interface class ListItemRenderer { +abstract interface class ListItemRenderer { const ListItemRenderer(); Widget getWidget(BuildContext context, T data, StreamSink sink); } diff --git a/lib/presentation/base/theme/theme_intent.dart b/lib/presentation/base/theme/theme_intent.dart index e86374ae..cafb986c 100644 --- a/lib/presentation/base/theme/theme_intent.dart +++ b/lib/presentation/base/theme/theme_intent.dart @@ -16,5 +16,3 @@ class SetIsDynamicThemeIntent extends ThemeIntent { const SetIsDynamicThemeIntent({required this.isDynamic}); } - - diff --git a/lib/repository/weather/local_weather_mapper.dart b/lib/repository/weather/local_weather_mapper.dart index fc4e9cda..3d824852 100644 --- a/lib/repository/weather/local_weather_mapper.dart +++ b/lib/repository/weather/local_weather_mapper.dart @@ -7,8 +7,10 @@ import 'package:flutter_template/services/base/database/app_database.dart'; import 'package:flutter_template/services/entity/open_weather/current_weather/remote/remote_current_weather.dart'; import 'package:flutter_template/services/entity/open_weather/current_weather/remote/remote_current_weather_weather.dart'; -abstract interface class LocalWeatherMapper implements Mapper3 {} +abstract interface class LocalWeatherMapper + implements + Mapper3 {} class LocalWeatherMapperImpl extends LocalWeatherMapper { final DateRepository dateRepository; From e45da76de8ba3218256ea008648afc1196a84e5b Mon Sep 17 00:00:00 2001 From: Shounak Mulay Date: Fri, 12 Apr 2024 16:52:17 +0530 Subject: [PATCH 5/5] Make base intent equatable --- .../{{name.snakeCase()}}_screen_intent.dart | 2 +- lib/presentation/base/theme/theme_intent.dart | 8 +++++++- .../destinations/weather/home/home_screen_intent.dart | 5 ++++- .../weather/search/search_screen_intent.dart | 11 ++++++++++- lib/presentation/entity/intent/intent.dart | 6 +++++- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart index 40cd2958..82fada5f 100644 --- a/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart +++ b/bricks/destination/__brick__/{{name.snakeCase()}}/{{name.snakeCase()}}_screen_intent.dart @@ -1,5 +1,5 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; -sealed class {{name.pascalCase()}}ScreenIntent implements BaseIntent { +sealed class {{name.pascalCase()}}ScreenIntent extends BaseIntent { const {{name.pascalCase()}}ScreenIntent(); } diff --git a/lib/presentation/base/theme/theme_intent.dart b/lib/presentation/base/theme/theme_intent.dart index cafb986c..1539c2c5 100644 --- a/lib/presentation/base/theme/theme_intent.dart +++ b/lib/presentation/base/theme/theme_intent.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/presentation/entity/intent/intent.dart'; -sealed class ThemeIntent implements BaseIntent { +sealed class ThemeIntent extends BaseIntent { const ThemeIntent(); } @@ -9,10 +9,16 @@ class SetThemeModeThemeIntent extends ThemeIntent { final ThemeMode mode; const SetThemeModeThemeIntent({required this.mode}); + + @override + List get props => [mode]; } class SetIsDynamicThemeIntent extends ThemeIntent { final bool isDynamic; const SetIsDynamicThemeIntent({required this.isDynamic}); + + @override + List get props => [isDynamic]; } diff --git a/lib/presentation/destinations/weather/home/home_screen_intent.dart b/lib/presentation/destinations/weather/home/home_screen_intent.dart index 692304ae..173ba6f5 100644 --- a/lib/presentation/destinations/weather/home/home_screen_intent.dart +++ b/lib/presentation/destinations/weather/home/home_screen_intent.dart @@ -1,9 +1,12 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; -sealed class HomeScreenIntent implements BaseIntent { +sealed class HomeScreenIntent extends BaseIntent { const HomeScreenIntent(); } class SearchHomeScreenIntent extends HomeScreenIntent { const SearchHomeScreenIntent(); + + @override + List get props => []; } diff --git a/lib/presentation/destinations/weather/search/search_screen_intent.dart b/lib/presentation/destinations/weather/search/search_screen_intent.dart index f9f84376..a027ad3d 100644 --- a/lib/presentation/destinations/weather/search/search_screen_intent.dart +++ b/lib/presentation/destinations/weather/search/search_screen_intent.dart @@ -1,22 +1,31 @@ import 'package:flutter_template/presentation/entity/intent/intent.dart'; import 'package:flutter_template/presentation/entity/weather/ui_city.dart'; -sealed class SearchScreenIntent implements BaseIntent { +sealed class SearchScreenIntent extends BaseIntent { const SearchScreenIntent(); } class BackSearchScreenIntent extends SearchScreenIntent { const BackSearchScreenIntent(); + + @override + List get props => []; } class SearchSearchScreenIntent extends SearchScreenIntent { final String searchTerm; const SearchSearchScreenIntent({required this.searchTerm}); + + @override + List get props => [searchTerm]; } class ToggleFavoriteSearchScreenIntent extends SearchScreenIntent { final UICity city; const ToggleFavoriteSearchScreenIntent({required this.city}); + + @override + List get props => [city]; } diff --git a/lib/presentation/entity/intent/intent.dart b/lib/presentation/entity/intent/intent.dart index 3a21cac5..bec69404 100644 --- a/lib/presentation/entity/intent/intent.dart +++ b/lib/presentation/entity/intent/intent.dart @@ -1 +1,5 @@ -interface class BaseIntent {} +import 'package:equatable/equatable.dart'; + +abstract class BaseIntent extends Equatable { + const BaseIntent(); +}