├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-50x50@1x.png │ │ │ ├── Icon-App-50x50@2x.png │ │ │ ├── Icon-App-57x57@1x.png │ │ │ ├── Icon-App-57x57@2x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-72x72@1x.png │ │ │ ├── Icon-App-72x72@2x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ ├── xcshareddata │ └── xcschemes │ │ └── Runner.xcscheme │ └── project.pbxproj ├── android.zip ├── icons ├── icon.png ├── icon.psd └── final_icon.png ├── lib ├── features │ ├── splash_screen │ │ ├── domain │ │ │ ├── entities │ │ │ │ └── empty_entity.dart │ │ │ ├── repos │ │ │ │ └── splash_screen_repo.dart │ │ │ └── usecases │ │ │ │ └── navigate_to_main_screen.dart │ │ ├── presentation │ │ │ ├── bloc │ │ │ │ ├── splash_screen_event.dart │ │ │ │ ├── splash_screen_state.dart │ │ │ │ └── splash_screen_bloc.dart │ │ │ ├── pages │ │ │ │ └── splash_screen.dart │ │ │ └── widgets │ │ │ │ ├── splash_screen_widget.dart │ │ │ │ └── internet_error_widget.dart │ │ └── data │ │ │ └── repos │ │ │ └── splash_scree_repo_impl.dart │ └── covid_19 │ │ ├── presentation │ │ ├── bloc │ │ │ ├── covid_event.dart │ │ │ ├── covid_state.dart │ │ │ └── covid_bloc.dart │ │ ├── constants │ │ │ └── theme_data.dart │ │ ├── widgets │ │ │ ├── LoadingStateDisplay.dart │ │ │ ├── EmptyStateDisplay.dart │ │ │ ├── app_bar_design.dart │ │ │ ├── LoadingStateDisplayGetAllEventDispatch.dart │ │ │ ├── LoadingStateDisplayGetSLEventDispatch.dart │ │ │ ├── WorldControl.dart │ │ │ ├── SLControl.dart │ │ │ ├── LoadedCovidAllStateDisaplay.dart │ │ │ ├── CovidControl.dart │ │ │ ├── LoadedCovidCountryDisplay.dart │ │ │ ├── LoadedCovidAllStateDisplayNew.dart │ │ │ └── LoadedCovidSLStateDisplayNew.dart │ │ └── pages │ │ │ └── coivd_page.dart │ │ ├── domain │ │ ├── repos │ │ │ └── covid_repo.dart │ │ ├── usecases │ │ │ ├── get_all_covid_info.dart │ │ │ ├── get_lk_specific_covid_info.dart │ │ │ └── get_country_specific_covid_info.dart │ │ └── entities │ │ │ ├── covid_all.dart │ │ │ └── covid_country.dart │ │ └── data │ │ ├── models │ │ ├── covid_all_model.dart │ │ └── covid_country_model.dart │ │ ├── datasources │ │ ├── covid_remote_data_source.dart │ │ └── covid_local_data_source.dart │ │ └── repos │ │ └── covid_repo_impl.dart ├── core │ ├── Usecase │ │ └── use_case.dart │ ├── Error │ │ ├── exceptions.dart │ │ └── Faliure.dart │ ├── Platform │ │ └── network_info.dart │ └── util │ │ └── input_converter.dart ├── main.dart └── injection_container.dart ├── ss ├── v1.0.0 │ ├── ss1.jpg │ ├── ss2.jpg │ ├── ss3.jpg │ ├── ss4.jpeg │ └── ss5.jpeg └── v1.1.0 │ ├── ss1.jpg │ ├── ss1.png │ ├── ss2.jpg │ ├── ss2.png │ ├── ss3.png │ ├── ss4.png │ ├── ss5.png │ ├── ss3.jpeg │ ├── ss4.jpeg │ └── ss5.jpeg ├── fonts └── Questrial-Regular.ttf ├── test ├── fixtures │ ├── coivd_all.json │ ├── fixture_reader.dart │ ├── covid_country.json │ └── country.json ├── features │ └── covid_19 │ │ ├── domain │ │ ├── entities │ │ │ ├── covid_all_test.dart │ │ │ └── covid_country_test.dart │ │ └── usecases │ │ │ ├── get_all_covid_info_test.dart │ │ │ ├── get_country_specific_covid_info_test.dart │ │ │ └── get_lk_specific_covid_info_test.dart │ │ └── data │ │ ├── models │ │ ├── covid_all_model_test.dart │ │ └── covid_country_model_test.dart │ │ └── repos │ │ └── covid_repo_impl_test.dart ├── widget_test.dart └── core │ └── platform │ └── NetworkInfo_test.dart ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── drawable │ │ │ │ │ └── launch_background.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── covid_19_info │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── .flutter-plugins-dependencies ├── .metadata ├── pubspec.yaml ├── README.md ├── .gitignore └── pubspec.lock /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /android.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android.zip -------------------------------------------------------------------------------- /icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/icons/icon.png -------------------------------------------------------------------------------- /icons/icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/icons/icon.psd -------------------------------------------------------------------------------- /lib/features/splash_screen/domain/entities/empty_entity.dart: -------------------------------------------------------------------------------- 1 | class EmptyEntity{ 2 | 3 | } -------------------------------------------------------------------------------- /ss/v1.0.0/ss1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.0.0/ss1.jpg -------------------------------------------------------------------------------- /ss/v1.0.0/ss2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.0.0/ss2.jpg -------------------------------------------------------------------------------- /ss/v1.0.0/ss3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.0.0/ss3.jpg -------------------------------------------------------------------------------- /ss/v1.1.0/ss1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss1.jpg -------------------------------------------------------------------------------- /ss/v1.1.0/ss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss1.png -------------------------------------------------------------------------------- /ss/v1.1.0/ss2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss2.jpg -------------------------------------------------------------------------------- /ss/v1.1.0/ss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss2.png -------------------------------------------------------------------------------- /ss/v1.1.0/ss3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss3.png -------------------------------------------------------------------------------- /ss/v1.1.0/ss4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss4.png -------------------------------------------------------------------------------- /ss/v1.1.0/ss5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss5.png -------------------------------------------------------------------------------- /ss/v1.0.0/ss4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.0.0/ss4.jpeg -------------------------------------------------------------------------------- /ss/v1.0.0/ss5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.0.0/ss5.jpeg -------------------------------------------------------------------------------- /ss/v1.1.0/ss3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss3.jpeg -------------------------------------------------------------------------------- /ss/v1.1.0/ss4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss4.jpeg -------------------------------------------------------------------------------- /ss/v1.1.0/ss5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ss/v1.1.0/ss5.jpeg -------------------------------------------------------------------------------- /icons/final_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/icons/final_icon.png -------------------------------------------------------------------------------- /fonts/Questrial-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/fonts/Questrial-Regular.ttf -------------------------------------------------------------------------------- /test/fixtures/coivd_all.json: -------------------------------------------------------------------------------- 1 | { 2 | "cases": 250618, 3 | "deaths": 10254, 4 | "recovered": 89044, 5 | "updated": 1584701849216 6 | } -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | android.enableR8=true 4 | android.useAndroidX=true 5 | android.enableJetifier=true 6 | -------------------------------------------------------------------------------- /test/fixtures/fixture_reader.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | String fixtureReader(String name) => 4 | File('test/fixtures/$name').readAsStringSync(); 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Achintha444/Covid19News/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/core/Usecase/use_case.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import '../error/Faliure.dart'; 3 | 4 | abstract class UseCase { 5 | Future> call(Params params); 6 | } 7 | 8 | class NoParams {} -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/bloc/splash_screen_event.dart: -------------------------------------------------------------------------------- 1 | part of 'splash_screen_bloc.dart'; 2 | 3 | @immutable 4 | abstract class SplashScreenEvent {} 5 | 6 | class NavigateToMainScreenEvent implements SplashScreenEvent {} -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/fixtures/covid_country.json: -------------------------------------------------------------------------------- 1 | { 2 | "country": "Sri Lanka", 3 | "cases": 66, 4 | "todayCases": 6, 5 | "deaths": 0, 6 | "todayDeaths": 0, 7 | "recovered": 3, 8 | "active": 63, 9 | "critical": 0, 10 | "casesPerOneMillion": 3 11 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /lib/features/splash_screen/domain/repos/splash_screen_repo.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | 3 | import '../../../../core/error/Faliure.dart'; 4 | import '../entities/empty_entity.dart'; 5 | 6 | abstract class SplashScreenRepo { 7 | Future> navigateToMainScreen(); 8 | } -------------------------------------------------------------------------------- /lib/core/Error/exceptions.dart: -------------------------------------------------------------------------------- 1 | class ServerException implements Exception {} 2 | 3 | class CacheException implements Exception {} 4 | 5 | class CountryNotFoundException implements Exception{} 6 | 7 | class InvalidInputException implements Exception{} 8 | 9 | class InternetConnectionFaliure implements Exception{} -------------------------------------------------------------------------------- /.flutter-plugins-dependencies: -------------------------------------------------------------------------------- 1 | {"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}]} -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 68587a0916366e9512a78df22c44163d041dd5f3 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/bloc/splash_screen_state.dart: -------------------------------------------------------------------------------- 1 | part of 'splash_screen_bloc.dart'; 2 | 3 | @immutable 4 | abstract class SplashScreenState {} 5 | 6 | class Initial extends SplashScreenState {} 7 | 8 | class Loading extends SplashScreenState {} 9 | 10 | class Loaded extends SplashScreenState {} 11 | 12 | class InternetError extends SplashScreenState {} 13 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/bloc/covid_event.dart: -------------------------------------------------------------------------------- 1 | part of 'covid_bloc.dart'; 2 | 3 | @immutable 4 | abstract class CovidEvent { 5 | } 6 | 7 | class GetAllCovidInfoEvent extends CovidEvent{} 8 | 9 | class GetCountrySpecificCovidInfoEvent extends CovidEvent{ 10 | final String country; 11 | 12 | GetCountrySpecificCovidInfoEvent({@required this.country}); 13 | 14 | } 15 | 16 | class GetLKSpecificCovidInfoEvent extends CovidEvent{} -------------------------------------------------------------------------------- /lib/core/Platform/network_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:data_connection_checker/data_connection_checker.dart'; 2 | 3 | abstract class NetworkInfo { 4 | Future get isConnected; 5 | } 6 | 7 | 8 | class NetworkInfoImpl implements NetworkInfo{ 9 | final DataConnectionChecker connectionChecker; 10 | 11 | NetworkInfoImpl(this.connectionChecker); 12 | 13 | @override 14 | Future get isConnected => connectionChecker.hasConnection; 15 | 16 | } -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/covid_19_info/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.covid_19_info 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/repos/covid_repo.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | 3 | import '../../../../core/error/Faliure.dart'; 4 | import '../entities/covid_all.dart'; 5 | import '../entities/covid_country.dart'; 6 | 7 | abstract class CovidRepo { 8 | Future> getAllCovidInfo(); 9 | Future> getCountrySpecifiCovidInfo(String country); 10 | Future> getLKSpecifiCovidInfo(); 11 | } -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/core/Error/Faliure.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class Faliure extends Equatable { 4 | Faliure([List props = const []]) : super(props); 5 | } 6 | 7 | //General Faliures 8 | 9 | class ServerFaliure extends Faliure {} 10 | 11 | class CacheFaliure extends Faliure {} 12 | 13 | class CountryNotFoundFaliure extends Faliure{} 14 | 15 | class InvalidInputFaliure extends Faliure{} 16 | 17 | class InternetConnectionFaliure extends Faliure{} 18 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/constants/theme_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | var themeData = ThemeData( 4 | primaryColor: Color(0xffc23938), 5 | accentColor: Color(0xffff6161), 6 | backgroundColor: Colors.white, 7 | errorColor: Color(0xffde483e), 8 | 9 | fontFamily: 'Questrial', 10 | ); 11 | 12 | var mainTextStyle = TextStyle( 13 | color: Color(0xffc23938), 14 | letterSpacing: 1, 15 | ); 16 | 17 | var accentTextStyle = TextStyle( 18 | color: Colors.white, 19 | ); -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadingStateDisplay.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LoadingStateDisplay extends StatelessWidget { 4 | const LoadingStateDisplay({Key key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | padding: EdgeInsets.only(top: 10, bottom: 20), 10 | height: (MediaQuery.of(context).size.height) / 3, 11 | child: Center( 12 | child: CircularProgressIndicator(), 13 | ), 14 | ); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /lib/core/util/input_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/core/Error/Faliure.dart'; 2 | import 'package:dartz/dartz.dart'; 3 | import '../Error/Faliure.dart'; 4 | 5 | class InputConverter { 6 | Either check(String str) { 7 | try { 8 | if (str.isEmpty) throw FormatException(); 9 | final alphanumeric = RegExp('[a-zA-Z]'); 10 | final response = alphanumeric.hasMatch(str); 11 | if (!response) throw FormatException(); 12 | return Right(str); 13 | } on FormatException { 14 | return Left(InvalidInputFaliure()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/usecases/get_all_covid_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Usecase/use_case.dart'; 5 | import '../../../../core/error/Faliure.dart'; 6 | import '../entities/covid_all.dart'; 7 | import '../repos/covid_repo.dart'; 8 | 9 | class GetAllCovidInfo implements UseCase { 10 | CovidRepo _repo; 11 | 12 | GetAllCovidInfo({@required CovidRepo repo}) { 13 | this._repo = repo; 14 | } 15 | 16 | @override 17 | Future> call(NoParams params) async { 18 | return await this._repo.getAllCovidInfo(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/usecases/get_lk_specific_covid_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Usecase/use_case.dart'; 5 | import '../../../../core/error/Faliure.dart'; 6 | import '../entities/covid_country.dart'; 7 | import '../repos/covid_repo.dart'; 8 | 9 | class GetLKSpecifiCovidInfo implements UseCase { 10 | CovidRepo _repo; 11 | 12 | GetLKSpecifiCovidInfo({@required CovidRepo repo}) { 13 | this._repo = repo; 14 | } 15 | 16 | @override 17 | Future> call(NoParams params) async { 18 | return this._repo.getLKSpecifiCovidInfo(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/usecases/get_country_specific_covid_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Usecase/use_case.dart'; 5 | import '../../../../core/error/Faliure.dart'; 6 | import '../entities/covid_country.dart'; 7 | import '../repos/covid_repo.dart'; 8 | 9 | class GetCountrySpecifiCovidInfo implements UseCase { 10 | CovidRepo _repo; 11 | 12 | GetCountrySpecifiCovidInfo({@required CovidRepo repo}) { 13 | this._repo = repo; 14 | } 15 | 16 | @override 17 | Future> call(String country) async { 18 | return this._repo.getCountrySpecifiCovidInfo(country); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.71' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/entities/covid_all.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class CovidAll extends Equatable { 5 | int _cases; 6 | int _deaths; 7 | int _recovered; 8 | 9 | CovidAll({ 10 | @required int cases, 11 | @required int deaths, 12 | @required int recovered, 13 | }) : super([cases, deaths,recovered]) { 14 | this._cases = cases; 15 | this._deaths = deaths; 16 | this._recovered = recovered; 17 | } 18 | 19 | int get getCases { 20 | return this._cases; 21 | } 22 | 23 | int get getDeaths { 24 | return this._deaths; 25 | } 26 | 27 | int get getRecovered{ 28 | return this._recovered; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/EmptyStateDisplay.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class EmptyStateDisplay extends StatelessWidget { 4 | final String message; 5 | 6 | const EmptyStateDisplay({Key key, @required this.message}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | padding: EdgeInsets.only(top: 10, bottom: 20), 12 | height: (MediaQuery.of(context).size.height) / 4, 13 | child: Center( 14 | child: SingleChildScrollView( 15 | child: Text( 16 | this.message, 17 | style: TextStyle(fontSize: 25), 18 | textAlign: TextAlign.center, 19 | ), 20 | ), 21 | ), 22 | 23 | ); 24 | 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /lib/features/splash_screen/domain/usecases/navigate_to_main_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Usecase/use_case.dart'; 5 | import '../../../../core/error/Faliure.dart'; 6 | 7 | import '../entities/empty_entity.dart'; 8 | import '../repos/splash_screen_repo.dart'; 9 | 10 | class NavigateToMainScreen implements UseCase{ 11 | SplashScreenRepo _splashScreenRepo; 12 | 13 | NavigateToMainScreen({@required SplashScreenRepo splashScreenRepo}) { 14 | this._splashScreenRepo = splashScreenRepo; 15 | } 16 | 17 | @override 18 | Future> call(NoParams params) async { 19 | return await this._splashScreenRepo.navigateToMainScreen(); 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/features/splash_screen/data/repos/splash_scree_repo_impl.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Platform/network_info.dart'; 5 | import '../../../../core/error/Faliure.dart'; 6 | import '../../domain/entities/empty_entity.dart'; 7 | import '../../domain/repos/splash_screen_repo.dart'; 8 | 9 | class SplashScreenRepoImpl implements SplashScreenRepo { 10 | NetworkInfo _networkInfo; 11 | 12 | SplashScreenRepoImpl({@required NetworkInfo networkInfo}) { 13 | this._networkInfo = networkInfo; 14 | } 15 | 16 | @override 17 | Future> navigateToMainScreen() async { 18 | await Future.delayed( 19 | Duration(seconds: 4), 20 | ); 21 | if (await this._networkInfo.isConnected) { 22 | return Right(EmptyEntity()); 23 | } else { 24 | return Left(InternetConnectionFaliure()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'features/covid_19/presentation/constants/theme_data.dart'; 4 | import 'features/covid_19/presentation/pages/coivd_page.dart'; 5 | import 'features/splash_screen/presentation/pages/splash_screen.dart'; 6 | import 'injection_container.dart'; 7 | 8 | Future main() async { 9 | WidgetsFlutterBinding.ensureInitialized(); 10 | await init(); 11 | 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | // This widget is the root of your application. 17 | @override 18 | Widget build(BuildContext context) { 19 | 20 | return MaterialApp( 21 | debugShowCheckedModeBanner: false, 22 | title: 'Covid 19 News', 23 | theme: themeData, 24 | routes: { 25 | '/splash': (BuildContext context) => SplashScreen(), 26 | '/covidPage': (BuildContext context) => CovidPage(), 27 | }, 28 | home: SplashScreen(), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/app_bar_design.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../constants/theme_data.dart'; 4 | 5 | class AppBarDesign extends StatelessWidget implements PreferredSizeWidget { 6 | 7 | static final AppBar appBar = new AppBar(); 8 | 9 | const AppBarDesign({ 10 | Key key, 11 | }) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return AppBar( 16 | title: Center( 17 | child: Padding( 18 | padding: const EdgeInsets.only(top: 3.0), 19 | child: Text( 20 | 'Covid 19 News'.toUpperCase(), 21 | style: mainTextStyle, 22 | ), 23 | ), 24 | ), 25 | backgroundColor: Colors.white, 26 | bottomOpacity: 0.0, 27 | elevation: 0.0, 28 | iconTheme: new IconThemeData(color: Theme.of(context).primaryColor), 29 | ); 30 | } 31 | 32 | @override 33 | Size get preferredSize => new Size.fromHeight(appBar.preferredSize.height); 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadingStateDisplayGetAllEventDispatch.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/covid_bloc.dart'; 5 | 6 | class LoadingStateDisplayGetAllEventDispatch extends StatefulWidget { 7 | @override 8 | _LoadingStateDisplayGetAllEventDispatchState createState() => 9 | _LoadingStateDisplayGetAllEventDispatchState(); 10 | } 11 | 12 | class _LoadingStateDisplayGetAllEventDispatchState 13 | extends State { 14 | @override 15 | void initState() { 16 | super.initState(); 17 | BlocProvider.of(context).dispatch(GetAllCovidInfoEvent()); 18 | } 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Container( 23 | padding: EdgeInsets.only(top: 10, bottom: 20), 24 | height: (MediaQuery.of(context).size.height) / 4.5, 25 | child: Center( 26 | child: CircularProgressIndicator(), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadingStateDisplayGetSLEventDispatch.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/covid_bloc.dart'; 5 | 6 | class LoadingStateDisplayGetSLEventDispatch extends StatefulWidget { 7 | @override 8 | _LoadingStateDisplayGetSLEventDispatchState createState() => 9 | _LoadingStateDisplayGetSLEventDispatchState(); 10 | } 11 | 12 | class _LoadingStateDisplayGetSLEventDispatchState 13 | extends State { 14 | @override 15 | void initState() { 16 | super.initState(); 17 | BlocProvider.of(context).dispatch(GetLKSpecificCovidInfoEvent()); 18 | } 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Container( 23 | padding: EdgeInsets.only(top: 10, bottom: 20), 24 | height: (MediaQuery.of(context).size.height) / 4, 25 | child: Center( 26 | child: CircularProgressIndicator(), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: covid_19_info 2 | description: A new Flutter project. 3 | 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=2.1.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # Service Locator 14 | get_it: ^4.0.1 15 | 16 | #Bloc for state management 17 | flutter_bloc: ^0.21.0 18 | 19 | # Value equality 20 | equatable: ^0.4.0 21 | 22 | #For functional programming 23 | dartz: ^0.8.6 24 | 25 | #Remote API 26 | data_connection_checker: ^0.3.4 27 | http: ^0.12.0+2 28 | 29 | #Local Cache 30 | shared_preferences: ^0.5.6+3 31 | 32 | #Launcher Icon 33 | flutter_launcher_icons: ^0.7.4 34 | 35 | cupertino_icons: ^0.1.2 36 | 37 | flutter_icons: 38 | image_path: "icons/final_icon.png" 39 | android: true 40 | ios: true 41 | 42 | dev_dependencies: 43 | flutter_test: 44 | sdk: flutter 45 | 46 | #For creating mock tests 47 | mockito: ^4.1.0 48 | 49 | flutter: 50 | uses-material-design: true 51 | fonts: 52 | - family: Questrial 53 | fonts: 54 | - asset: fonts/Questrial-Regular.ttf 55 | 56 | -------------------------------------------------------------------------------- /lib/features/covid_19/data/models/covid_all_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_all.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /* {"cases":250618, 5 | "deaths":10254, 6 | "recovered":89044, 7 | "updated":1584701849216}*/ 8 | 9 | class CovidAllModel extends CovidAll { 10 | int _cases; 11 | int _deaths; 12 | int _recovered; 13 | 14 | CovidAllModel({ 15 | @required int cases, 16 | @required int deaths, 17 | @required int recovered, 18 | }) : super(cases: cases, deaths: deaths, recovered: recovered) { 19 | this._cases = cases; 20 | this._deaths = deaths; 21 | this._recovered = recovered; 22 | } 23 | 24 | factory CovidAllModel.fromJson(Map covid) { 25 | return CovidAllModel( 26 | cases: covid['cases'], 27 | deaths: covid['deaths'], 28 | recovered: covid['recovered'], 29 | ); 30 | } 31 | 32 | Map toJson() { 33 | return { 34 | 'cases': super.getCases, 35 | 'deaths': super.getDeaths, 36 | 'recovered': super.getRecovered, 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/features/covid_19/domain/entities/covid_all_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_all.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | final int cases = 1; 6 | final int deaths = 1; 7 | final int recovered = 1; 8 | 9 | final tCovidAll = 10 | CovidAll(cases: cases, deaths: deaths, recovered: recovered); 11 | 12 | //* getCases 13 | test( 14 | 'should return same cases provided', 15 | () async { 16 | //act 17 | final result = tCovidAll.getCases; 18 | //assert 19 | expect(result, cases); 20 | }, 21 | ); 22 | 23 | //* getDeaths 24 | test( 25 | 'should return same Deaths provided', 26 | () async { 27 | //act 28 | final result = tCovidAll.getDeaths; 29 | //assert 30 | expect(result, deaths); 31 | }, 32 | ); 33 | 34 | //* getRecovered 35 | test( 36 | 'should return same Recovered provided', 37 | () async { 38 | //act 39 | final result = tCovidAll.getRecovered; 40 | //assert 41 | expect(result, recovered); 42 | }, 43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:covid_19_info/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/bloc/covid_state.dart: -------------------------------------------------------------------------------- 1 | part of 'covid_bloc.dart'; 2 | 3 | @immutable 4 | abstract class CovidState {} 5 | 6 | class Empty extends CovidState {} 7 | 8 | class Loading extends CovidState {} 9 | 10 | class LoadingAll extends CovidState {} 11 | 12 | class LoadingSL extends CovidState {} 13 | 14 | class LoadedCovidAll extends CovidState { 15 | 16 | final CovidAll covidAll; 17 | 18 | LoadedCovidAll({@required this.covidAll}); 19 | 20 | } 21 | 22 | class LoadedCovidSL extends CovidState { 23 | 24 | final CovidCountry covidSL; 25 | 26 | LoadedCovidSL({@required this.covidSL}); 27 | 28 | } 29 | 30 | class LoadedCovidCountry extends CovidState { 31 | 32 | final CovidCountry covidCountry; 33 | 34 | LoadedCovidCountry({@required this.covidCountry}); 35 | 36 | } 37 | 38 | class Error extends CovidState { 39 | 40 | final String message; 41 | 42 | Error({@required this.message}); 43 | 44 | } 45 | 46 | class ErrorAll extends CovidState { 47 | 48 | final String message; 49 | 50 | ErrorAll({@required this.message}); 51 | 52 | } 53 | 54 | class ErrorSL extends CovidState { 55 | 56 | final String message; 57 | 58 | ErrorSL({@required this.message}); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /test/core/platform/NetworkInfo_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/core/Platform/network_info.dart'; 2 | import 'package:data_connection_checker/data_connection_checker.dart'; 3 | import 'package:mockito/mockito.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | 6 | class MockDataConnectionChecker extends Mock implements DataConnectionChecker {} 7 | 8 | void main() { 9 | NetworkInfoImpl networkInfoImpl; 10 | MockDataConnectionChecker mockDataConnectionChecker; 11 | 12 | setUp(() { 13 | mockDataConnectionChecker = new MockDataConnectionChecker(); 14 | networkInfoImpl = new NetworkInfoImpl(mockDataConnectionChecker); 15 | }); 16 | 17 | group('isConnected()', () { 18 | test( 19 | 'should forward the call to DataConnectionChecker.hasConnection', 20 | () async { 21 | //arrange 22 | final hasConnection = Future.value(true); 23 | when(mockDataConnectionChecker.hasConnection) 24 | .thenAnswer((_) => hasConnection); 25 | //act 26 | final result = networkInfoImpl.isConnected; 27 | //assert 28 | expect(result, hasConnection); 29 | verify(mockDataConnectionChecker.hasConnection); 30 | }, 31 | ); 32 | 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/bloc/splash_screen_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:bloc/bloc.dart'; 4 | import 'package:covid_19_info/core/Usecase/use_case.dart'; 5 | import 'package:covid_19_info/features/splash_screen/domain/usecases/navigate_to_main_screen.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_bloc/flutter_bloc.dart'; 8 | 9 | part 'splash_screen_event.dart'; 10 | part 'splash_screen_state.dart'; 11 | 12 | class SplashScreenBloc extends Bloc { 13 | NavigateToMainScreen _navigateToMainScreen; 14 | 15 | SplashScreenBloc({@required NavigateToMainScreen navigateToMainScreen}) { 16 | this._navigateToMainScreen = navigateToMainScreen; 17 | } 18 | 19 | @override 20 | SplashScreenState get initialState => Initial(); 21 | 22 | 23 | @override 24 | Stream mapEventToState( 25 | SplashScreenEvent event, 26 | ) async* { 27 | if (event is NavigateToMainScreenEvent) { 28 | yield Loading(); 29 | final response = await this._navigateToMainScreen.call( 30 | NoParams(), 31 | ); 32 | yield response.fold( 33 | (faliure) => InternetError(), 34 | (_) => Loaded(), 35 | ); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/features/covid_19/domain/usecases/get_all_covid_info_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/core/Usecase/use_case.dart'; 2 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_all.dart'; 3 | import 'package:covid_19_info/features/covid_19/domain/repos/covid_repo.dart'; 4 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_all_covid_info.dart'; 5 | import 'package:dartz/dartz.dart'; 6 | import 'package:mockito/mockito.dart'; 7 | import 'package:flutter_test/flutter_test.dart'; 8 | 9 | class MockCovidRepo extends Mock implements CovidRepo {} 10 | 11 | void main() { 12 | GetAllCovidInfo getAllCovidInfo; 13 | MockCovidRepo mockCovidRepo; 14 | 15 | setUp(() { 16 | mockCovidRepo = new MockCovidRepo(); 17 | getAllCovidInfo = new GetAllCovidInfo(repo: mockCovidRepo); 18 | }); 19 | 20 | final int cases = 1; 21 | final int deaths = 1; 22 | final int recovered = 1; 23 | 24 | final tCovidAll = 25 | CovidAll(cases: cases, deaths: deaths, recovered: recovered); 26 | 27 | //* call() 28 | test( 29 | 'should return the CovidAll object when called the call() ', 30 | () async { 31 | //arrange 32 | when(mockCovidRepo.getAllCovidInfo()).thenAnswer( 33 | (_) async => Right(tCovidAll), 34 | ); 35 | //act 36 | final result = await getAllCovidInfo(NoParams()); 37 | //assert 38 | expect(result, Right(tCovidAll)); 39 | verify(mockCovidRepo.getAllCovidInfo()); 40 | verifyNoMoreInteractions(mockCovidRepo); 41 | }, 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /test/features/covid_19/data/models/covid_all_model_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:covid_19_info/features/covid_19/data/models/covid_all_model.dart'; 4 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_all.dart'; 5 | import 'package:flutter_test/flutter_test.dart'; 6 | 7 | import '../../../../fixtures/fixture_reader.dart'; 8 | 9 | void main() { 10 | final int cases = 250618; 11 | final int deaths = 10254; 12 | final int recovered = 89044; 13 | 14 | final tCovidAll = 15 | CovidAllModel(cases: cases, deaths: deaths, recovered: recovered); 16 | 17 | test( 18 | 'should be a subclass of CovidAll', 19 | () async { 20 | //assert 21 | expect(tCovidAll, isA()); 22 | }, 23 | ); 24 | 25 | //* fromJson() 26 | test( 27 | 'should return CovidAllModel when fromJson() called', 28 | () async { 29 | //arrange 30 | final Map jsonMap = json.decode( 31 | fixtureReader('coivd_all.json'), 32 | ); 33 | //act 34 | final result = CovidAllModel.fromJson(jsonMap); 35 | //assert 36 | expect(result, equals(tCovidAll)); 37 | }, 38 | ); 39 | 40 | //* toJson() 41 | test( 42 | 'should return a JSON map when toJson() called', 43 | () async { 44 | //act 45 | final result = tCovidAll.toJson(); 46 | //assert 47 | final expectedMap = { 48 | "cases": 250618, 49 | "deaths": 10254, 50 | "recovered": 89044, 51 | }; 52 | expect(result, expectedMap); 53 | }, 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Covid 19 News 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Covid 19 News 2 | 3 | This is a mobile app created using Flutter, corona.lmao.ninja (Real Time News about Covid 19). 4 | There are some test files that needed to be completed, but anyone is interested they can help me to finish these test files as well. 5 | Thank You! 😊😊 6 | 7 | ## Getting Started 8 | 9 | This is an application created using Flutter Clean Architecture and Test Driven Developement. 10 | 11 | Here is a video tutorial to get you started if you are interested in learning Flutter Clean Architecture and Test Driven Developement: 12 | 13 | - [Video Tutorial: Flutter Clean Architecture and Test Driven Developement](https://www.youtube.com/watch?v=dc3B_mMrZ-Q&t=577s) 14 | 15 | Here are few resources you can use if you want to learn more about the used REST API's in this app 16 | 17 | - [Covid 19 REST API](https://corona.lmao.ninja/docs/) 18 | - [Medium Article on how to use COVID 19 API with Flutter](https://medium.com/@achinthaisuru444/integrate-novelcovid-api-with-flutter-70ba1bb62733) 19 | 20 | ### PS ⭕⭕ 21 | 22 | Endpoint of the API has been changed. The app has been updated according to it. 23 | 24 | ## Screen Shots of the App 25 | 26 | ### v 1.0.0 27 | 28 |     29 | 30 | ### v 1.1.0 31 | 32 |     33 | -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/pages/splash_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../../../../injection_container.dart'; 5 | import '../../../covid_19/presentation/pages/coivd_page.dart'; 6 | import '../bloc/splash_screen_bloc.dart'; 7 | import '../widgets/internet_error_widget.dart'; 8 | import '../widgets/splash_screen_widget.dart'; 9 | 10 | class SplashScreen extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | body: _buildBody(context), 15 | ); 16 | } 17 | 18 | BlocProvider _buildBody(BuildContext context) { 19 | return BlocProvider( 20 | builder: (context) => sl(), 21 | child: Container( 22 | height: MediaQuery.of(context).size.height, 23 | width: MediaQuery.of(context).size.width, 24 | decoration: BoxDecoration( 25 | color: Theme.of(context).primaryColor, 26 | ), 27 | child: Center( 28 | child: BlocBuilder( 29 | condition: (prev, cur) { 30 | if ((prev == Loading()) && (cur == Loaded())) { 31 | return false; 32 | } 33 | return true; 34 | }, 35 | builder: (context, state) { 36 | if ((state is Initial) || (state is Loading)) { 37 | return SplashScreenWidget(); 38 | } else if (state is Loaded) { 39 | return CovidPage(); 40 | } else if (state is InternetError) { 41 | return InternetErrorWidget(); 42 | } 43 | }, 44 | ), 45 | ), 46 | ), 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | .vscode/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | .dart_tool/ 27 | .flutter-plugins 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Generated.xcconfig 62 | **/ios/Flutter/app.flx 63 | **/ios/Flutter/app.zip 64 | **/ios/Flutter/flutter_assets/ 65 | **/ios/Flutter/flutter_export_environment.sh 66 | **/ios/ServiceDefinitions.json 67 | **/ios/Runner/GeneratedPluginRegistrant.* 68 | 69 | # Exceptions to above rules. 70 | !**/ios/**/default.mode1v3 71 | !**/ios/**/default.mode2v3 72 | !**/ios/**/default.pbxuser 73 | !**/ios/**/default.perspectivev3 74 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 75 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/WorldControl.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/covid_bloc.dart'; 5 | 6 | class WorldControl extends StatelessWidget { 7 | const WorldControl({ 8 | Key key, 9 | }) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Row( 14 | crossAxisAlignment: CrossAxisAlignment.center, 15 | mainAxisAlignment: MainAxisAlignment.center, 16 | children: [ 17 | Text( 18 | 'World'.toUpperCase(), 19 | style: TextStyle( 20 | fontSize: 25, 21 | color: Theme.of(context).primaryColor, 22 | fontWeight: FontWeight.bold, 23 | letterSpacing: 3, 24 | ), 25 | ), 26 | Padding( 27 | padding: EdgeInsets.only( 28 | left: 15, 29 | right: 15, 30 | ), 31 | ), 32 | RaisedButton( 33 | color: Theme.of(context).accentColor, 34 | child: Row( 35 | children: [ 36 | Icon( 37 | Icons.refresh, 38 | color: Colors.white, 39 | ), 40 | Padding( 41 | padding: EdgeInsets.only( 42 | left: 2, 43 | right: 2, 44 | ), 45 | ), 46 | Text( 47 | 'Refresh'.toUpperCase(), 48 | style: TextStyle(letterSpacing: 1, color: Colors.white), 49 | ), 50 | ], 51 | ), 52 | onPressed: () { 53 | BlocProvider.of(context) 54 | .dispatch(GetAllCovidInfoEvent()); 55 | }, 56 | ), 57 | ], 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/SLControl.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/covid_bloc.dart'; 5 | 6 | class SLControl extends StatelessWidget { 7 | const SLControl({ 8 | Key key, 9 | }) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Row( 14 | crossAxisAlignment: CrossAxisAlignment.center, 15 | mainAxisAlignment: MainAxisAlignment.center, 16 | children: [ 17 | Text( 18 | 'Sri Lanka'.toUpperCase(), 19 | style: TextStyle( 20 | fontSize: 25, 21 | color: Theme.of(context).primaryColor, 22 | fontWeight: FontWeight.bold, 23 | letterSpacing: 2, 24 | ), 25 | ), 26 | Padding( 27 | padding: EdgeInsets.only( 28 | left: 15, 29 | right: 15, 30 | ), 31 | ), 32 | RaisedButton( 33 | color: Theme.of(context).accentColor, 34 | child: Row( 35 | children: [ 36 | Icon( 37 | Icons.refresh, 38 | color: Colors.white, 39 | ), 40 | Padding( 41 | padding: EdgeInsets.only( 42 | left: 2, 43 | right: 2, 44 | ), 45 | ), 46 | Text( 47 | 'Refresh'.toUpperCase(), 48 | style: TextStyle(letterSpacing: 1, color: Colors.white), 49 | ), 50 | ], 51 | ), 52 | onPressed: () { 53 | BlocProvider.of(context) 54 | .dispatch(GetLKSpecificCovidInfoEvent()); 55 | }, 56 | ), 57 | ], 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /test/features/covid_19/domain/usecases/get_country_specific_covid_info_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_country.dart'; 2 | import 'package:covid_19_info/features/covid_19/domain/repos/covid_repo.dart'; 3 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_country_specific_covid_info.dart'; 4 | import 'package:dartz/dartz.dart'; 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:mockito/mockito.dart'; 7 | 8 | class MockCovidRepo extends Mock implements CovidRepo {} 9 | 10 | void main() { 11 | GetCountrySpecifiCovidInfo getCountrySpecifiCovidInfo; 12 | MockCovidRepo mockCovidRepo; 13 | 14 | setUp( 15 | () { 16 | mockCovidRepo = new MockCovidRepo(); 17 | getCountrySpecifiCovidInfo = 18 | new GetCountrySpecifiCovidInfo(repo: mockCovidRepo); 19 | }, 20 | ); 21 | 22 | final String imageUrl = 'https://restcountries.eu/data/usa.svg'; 23 | final String country = 'test'; 24 | final int cases = 1; 25 | final int deaths = 1; 26 | final int recovered = 1; 27 | final int todayDeaths = 1; 28 | final int active = 1; 29 | final int critical = 1; 30 | final int casesPerOneMillion = 1; 31 | 32 | final tCovidAll = CovidCountry( 33 | cases: cases, 34 | deaths: deaths, 35 | recovered: recovered, 36 | active: active, 37 | casesPerOneMillion: casesPerOneMillion, 38 | country: country, 39 | critical: critical, 40 | imageUrl: imageUrl, 41 | todayDeaths: todayDeaths, 42 | ); 43 | 44 | //* call() 45 | test( 46 | 'should return the CovidCountry() object when called', 47 | () async { 48 | //arrange 49 | when(mockCovidRepo.getCountrySpecifiCovidInfo(any)).thenAnswer( 50 | (_) async => Right(tCovidAll), 51 | ); 52 | //act 53 | final result = await getCountrySpecifiCovidInfo(country); 54 | //assert 55 | expect(result, Right(tCovidAll)); 56 | verify(mockCovidRepo.getCountrySpecifiCovidInfo(country)); 57 | verifyNoMoreInteractions(mockCovidRepo); 58 | }, 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /lib/features/covid_19/data/datasources/covid_remote_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import '../../../../core/Error/exceptions.dart'; 7 | import '../models/covid_all_model.dart'; 8 | import '../models/covid_country_model.dart'; 9 | 10 | abstract class CovidRemoteDataSource { 11 | /// Calls https://corona.lmao.ninja/countries/all endpoint 12 | /// 13 | /// Throws a [ServerException] for Server Errors 14 | Future getAllCovidInfo(); 15 | 16 | /// Calls https://corona.lmao.ninja/countries/{country} and http://restcountries.eu/rest/v2/name/{country} endpoints 17 | /// 18 | /// Throws a [ServerException] for Server Errors 19 | /// Throws [CountryNotFoundException] for wrong inputs 20 | Future getCountrySpecifiCovidInfo(String country); 21 | } 22 | 23 | class CovidRemoteDataSourceImpl implements CovidRemoteDataSource { 24 | http.Client _httpClient; 25 | 26 | CovidRemoteDataSourceImpl({@required http.Client httpClient}) { 27 | this._httpClient = httpClient; 28 | } 29 | 30 | @override 31 | Future getAllCovidInfo() async { 32 | final response = 33 | await this._httpClient.get('https://corona.lmao.ninja/v2/all'); 34 | if (response.statusCode != 200) { 35 | throw ServerException(); 36 | } else { 37 | return CovidAllModel.fromJson( 38 | json.decode(response.body), 39 | ); 40 | } 41 | } 42 | 43 | @override 44 | Future getCountrySpecifiCovidInfo(String country) async { 45 | final responseCovid = await this 46 | ._httpClient 47 | .get('https://corona.lmao.ninja/v2/countries/$country'); 48 | 49 | if ((responseCovid.statusCode != 200)) { 50 | throw ServerException(); 51 | } else { 52 | try { 53 | return CovidCountryModel.fromJson( 54 | json.decode(responseCovid.body) 55 | ); 56 | } on Exception { 57 | throw CountryNotFoundException(); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/features/covid_19/domain/usecases/get_lk_specific_covid_info_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/core/Usecase/use_case.dart'; 2 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_country.dart'; 3 | import 'package:covid_19_info/features/covid_19/domain/repos/covid_repo.dart'; 4 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_lk_specific_covid_info.dart'; 5 | import 'package:dartz/dartz.dart'; 6 | import 'package:flutter_test/flutter_test.dart'; 7 | import 'package:mockito/mockito.dart'; 8 | 9 | class MockCovidRepo extends Mock implements CovidRepo {} 10 | 11 | void main() { 12 | GetLKSpecifiCovidInfo getLKSpecifiCovidInfo; 13 | MockCovidRepo mockCovidRepo; 14 | 15 | setUp( 16 | () { 17 | mockCovidRepo = new MockCovidRepo(); 18 | getLKSpecifiCovidInfo = 19 | new GetLKSpecifiCovidInfo(repo: mockCovidRepo); 20 | }, 21 | ); 22 | 23 | final String imageUrl = 'https://restcountries.eu/data/usa.svg'; 24 | final String country = 'test'; 25 | final int cases = 1; 26 | final int deaths = 1; 27 | final int recovered = 1; 28 | final int todayDeaths = 1; 29 | final int active = 1; 30 | final int critical = 1; 31 | final int casesPerOneMillion = 1; 32 | 33 | final tCovidAll = CovidCountry( 34 | cases: cases, 35 | deaths: deaths, 36 | recovered: recovered, 37 | active: active, 38 | casesPerOneMillion: casesPerOneMillion, 39 | country: country, 40 | critical: critical, 41 | imageUrl: imageUrl, 42 | todayDeaths: todayDeaths, 43 | ); 44 | 45 | //* call() 46 | test( 47 | 'should return the CovidCountry() object when called', 48 | () async { 49 | //arrange 50 | when(mockCovidRepo.getLKSpecifiCovidInfo()).thenAnswer( 51 | (_) async => Right(tCovidAll), 52 | ); 53 | //act 54 | final result = await getLKSpecifiCovidInfo(NoParams()); 55 | //assert 56 | expect(result, Right(tCovidAll)); 57 | verify(mockCovidRepo.getLKSpecifiCovidInfo()); 58 | verifyNoMoreInteractions(mockCovidRepo); 59 | }, 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/widgets/splash_screen_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/splash_screen_bloc.dart'; 5 | 6 | class SplashScreenWidget extends StatefulWidget { 7 | @override 8 | _SplashScreenWidgetState createState() => _SplashScreenWidgetState(); 9 | } 10 | 11 | class _SplashScreenWidgetState extends State { 12 | @override 13 | void initState() { 14 | super.initState(); 15 | this._dispatchEvent(context); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | height: MediaQuery.of(context).size.height, 22 | width: MediaQuery.of(context).size.width, 23 | child: Center( 24 | child: Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | crossAxisAlignment: CrossAxisAlignment.center, 27 | children: [ 28 | Center( 29 | child: Text( 30 | 'COVID 19', 31 | style: TextStyle( 32 | color: Colors.white, 33 | fontSize: 50, 34 | letterSpacing: 2, 35 | ), 36 | ), 37 | ), 38 | Padding( 39 | padding: EdgeInsets.only( 40 | top: 10, 41 | bottom: 10, 42 | ), 43 | ), 44 | Center( 45 | child: Text( 46 | 'NEWS', 47 | style: TextStyle( 48 | color: Colors.white, 49 | fontSize: 20, 50 | letterSpacing: 30, 51 | ), 52 | ), 53 | ), 54 | Padding( 55 | padding: EdgeInsets.only( 56 | top: 30, 57 | bottom: 30, 58 | ), 59 | ), 60 | CircularProgressIndicator( 61 | backgroundColor: Colors.white, 62 | ), 63 | ], 64 | ), 65 | ), 66 | ); 67 | } 68 | 69 | void _dispatchEvent(BuildContext context) { 70 | BlocProvider.of(context).dispatch( 71 | NavigateToMainScreenEvent(), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /test/features/covid_19/data/models/covid_country_model_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:covid_19_info/features/covid_19/data/models/covid_country_model.dart'; 4 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_country.dart'; 5 | import 'package:flutter_test/flutter_test.dart'; 6 | 7 | import '../../../../fixtures/fixture_reader.dart'; 8 | 9 | void main() { 10 | final String imageUrl = 'https://restcountries.eu/data/usa.svg'; 11 | final String country = 'Sri Lanka'; 12 | final int cases = 66; 13 | final int deaths = 0; 14 | final int recovered = 3; 15 | final int todayDeaths = 0; 16 | final int active = 63; 17 | final int critical = 0; 18 | final int casesPerOneMillion = 3; 19 | 20 | final tCovidAll = CovidCountryModel( 21 | cases: cases, 22 | deaths: deaths, 23 | recovered: recovered, 24 | active: active, 25 | casesPerOneMillion: casesPerOneMillion, 26 | country: country, 27 | critical: critical, 28 | imageUrl: imageUrl, 29 | todayDeaths: todayDeaths, 30 | ); 31 | 32 | test( 33 | 'should be a subclass of CovidAll', 34 | () async { 35 | //assert 36 | expect(tCovidAll, isA()); 37 | }, 38 | ); 39 | 40 | //* fromJson() 41 | test( 42 | 'should return CovidAllModel when fromJson() called', 43 | () async { 44 | //arrange 45 | final Map jsonMapCovidCountry = json.decode( 46 | fixtureReader('covid_country.json'), 47 | ); 48 | //act 49 | final result = 50 | CovidCountryModel.fromJson(jsonMapCovidCountry); 51 | //assert 52 | expect(result, equals(tCovidAll)); 53 | }, 54 | ); 55 | 56 | //* toJson() 57 | test( 58 | 'should return a JSON map when toJson() called', 59 | () async { 60 | //act 61 | final result = tCovidAll.toJson(); 62 | //assert 63 | final expectedMap = { 64 | "imageUrl": 'https://restcountries.eu/data/usa.svg', 65 | "country": 'Sri Lanka', 66 | "cases": 66, 67 | "deaths": 0, 68 | "recovered": 3, 69 | "todayDeaths": 0, 70 | "active": 63, 71 | "critical": 0, 72 | "casesPerOneMillion": 3, 73 | }; 74 | expect(result, expectedMap); 75 | }, 76 | ); 77 | } 78 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.covid_19_info" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 67 | } 68 | -------------------------------------------------------------------------------- /lib/features/covid_19/domain/entities/covid_country.dart: -------------------------------------------------------------------------------- 1 | /* {"country":"Sri Lanka", 2 | "cases":66, 3 | "todayCases":6, 4 | "deaths":0, 5 | "todayDeaths":0, 6 | "recovered":3, 7 | "active":63, 8 | "critical":0, 9 | "casesPerOneMillion":3}*/ 10 | 11 | import 'package:equatable/equatable.dart'; 12 | import 'package:flutter/material.dart'; 13 | 14 | class CovidCountry extends Equatable { 15 | String _imageUrl; 16 | String _country; 17 | num _cases; 18 | num _deaths; 19 | num _todayDeaths; 20 | num _recovered; 21 | num _active; 22 | num _critical; 23 | num _casesPerOneMillion; 24 | num _todayCases; 25 | 26 | CovidCountry({ 27 | @required String imageUrl, 28 | @required String country, 29 | @required num cases, 30 | @required num todayCases, 31 | @required num deaths, 32 | @required num todayDeaths, 33 | @required num recovered, 34 | @required num active, 35 | @required num critical, 36 | @required num casesPerOneMillion, 37 | }) : super([ 38 | imageUrl, 39 | country, 40 | cases, 41 | deaths, 42 | todayDeaths, 43 | recovered, 44 | active, 45 | critical, 46 | casesPerOneMillion, 47 | todayCases, 48 | ]) { 49 | this._imageUrl = imageUrl; 50 | this._country = country; 51 | this._cases = cases; 52 | this._deaths = deaths; 53 | this._todayDeaths = todayDeaths; 54 | this._recovered = recovered; 55 | this._active = active; 56 | this._critical = critical; 57 | this._casesPerOneMillion = casesPerOneMillion; 58 | this._todayCases = todayCases; 59 | } 60 | 61 | String get getImageUrl { 62 | return this._imageUrl; 63 | } 64 | 65 | String get getCountry { 66 | return this._country; 67 | } 68 | 69 | num get getCases { 70 | return this._cases; 71 | } 72 | 73 | num get getDeaths { 74 | return this._deaths; 75 | } 76 | 77 | num get getTodayDeaths { 78 | return this._todayDeaths; 79 | } 80 | 81 | num get getRecovered { 82 | return this._recovered; 83 | } 84 | 85 | num get getActive { 86 | return this._active; 87 | } 88 | 89 | num get getCritical { 90 | return this._critical; 91 | } 92 | 93 | num get getCasesPerOneMillion { 94 | return this._casesPerOneMillion; 95 | } 96 | 97 | num get getTodayCases{ 98 | return this._todayCases; 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/features/covid_19/data/datasources/covid_local_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:shared_preferences/shared_preferences.dart'; 5 | 6 | import '../../../../core/Error/exceptions.dart'; 7 | import '../models/covid_all_model.dart'; 8 | import '../models/covid_country_model.dart'; 9 | 10 | abstract class CovidLocalDataSource { 11 | /// Throws a [CacheException] for all error codes. 12 | Future getLastCountrySpecifiCovidInfo(); 13 | 14 | /// Throws a [CacheException] for all error codes. 15 | Future getLastAllCovidInfo(); 16 | 17 | Future cacheAllCovidInfo(CovidAllModel covidAllModel); 18 | 19 | Future cacheCountrySpecifiCovidInfo(CovidCountryModel countryModel); 20 | } 21 | 22 | class CovidLocalDataSourceImpl implements CovidLocalDataSource { 23 | SharedPreferences _sharedPreferences; 24 | 25 | CovidLocalDataSourceImpl({@required SharedPreferences sharedPreferences}) { 26 | this._sharedPreferences = sharedPreferences; 27 | } 28 | 29 | @override 30 | Future cacheAllCovidInfo(CovidAllModel covidAllModel) { 31 | return this._sharedPreferences.setString( 32 | 'CACHED_COVID_ALL', 33 | json.encode( 34 | covidAllModel.toJson(), 35 | ), 36 | ); 37 | } 38 | 39 | @override 40 | Future cacheCountrySpecifiCovidInfo(CovidCountryModel countryModel) { 41 | return this._sharedPreferences.setString( 42 | 'CACHED_COVID_COUNTRY', 43 | json.encode( 44 | countryModel.toJson(), 45 | ), 46 | ); 47 | } 48 | 49 | @override 50 | Future getLastAllCovidInfo() { 51 | final String jsonCovidAll = 52 | this._sharedPreferences.getString('CACHED_COVID_ALL'); 53 | if (jsonCovidAll != null) { 54 | return Future.value( 55 | CovidAllModel.fromJson( 56 | json.decode(jsonCovidAll), 57 | ), 58 | ); 59 | } else { 60 | //There is an error in throwing this error! 61 | throw CacheException(); 62 | } 63 | } 64 | 65 | @override 66 | Future getLastCountrySpecifiCovidInfo() { 67 | final String jsonCovidCountry = 68 | this._sharedPreferences.getString('CACHED_COVID_COUNTRY'); 69 | if (jsonCovidCountry != null) { 70 | return Future.value( 71 | CovidCountryModel.fromJson( 72 | json.decode(jsonCovidCountry), 73 | ), 74 | ); 75 | } else { 76 | //There is an error in throwing this error! 77 | throw CacheException(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/features/splash_screen/presentation/widgets/internet_error_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/features/splash_screen/presentation/bloc/splash_screen_bloc.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | class InternetErrorWidget extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | height: MediaQuery.of(context).size.height, 10 | width: MediaQuery.of(context).size.width, 11 | child: Center( 12 | child: Column( 13 | mainAxisAlignment: MainAxisAlignment.center, 14 | crossAxisAlignment: CrossAxisAlignment.center, 15 | children: [ 16 | Center( 17 | child: Text( 18 | 'NO INTERNET'.toUpperCase(), 19 | style: TextStyle( 20 | color: Colors.white, 21 | fontSize: 30, 22 | letterSpacing: 2, 23 | ), 24 | ), 25 | ), 26 | Padding( 27 | padding: EdgeInsets.only( 28 | top: 3, 29 | bottom: 3, 30 | ), 31 | ), 32 | Center( 33 | child: Text( 34 | 'connection'.toUpperCase(), 35 | style: TextStyle( 36 | color: Colors.white, 37 | fontSize: 30, 38 | letterSpacing: 2, 39 | ), 40 | ), 41 | ), 42 | Padding( 43 | padding: EdgeInsets.only( 44 | top: 10, 45 | bottom: 10, 46 | ), 47 | ), 48 | Center( 49 | child: Text( 50 | 'Connect to internet and try again'.toUpperCase(), 51 | style: TextStyle( 52 | color: Colors.white, 53 | fontSize: 10, 54 | letterSpacing: 1, 55 | ), 56 | ), 57 | ), 58 | Padding( 59 | padding: EdgeInsets.only( 60 | top: 30, 61 | bottom: 30, 62 | ), 63 | ), 64 | FloatingActionButton( 65 | child: Icon( 66 | Icons.replay, 67 | size: 30, 68 | ), 69 | onPressed: () { 70 | BlocProvider.of(context).dispatch( 71 | NavigateToMainScreenEvent(), 72 | ); 73 | }, 74 | ), 75 | ], 76 | ), 77 | ), 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadedCovidAllStateDisaplay.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../domain/entities/covid_all.dart'; 4 | 5 | class LoadedCovidAllStateDisplay extends StatelessWidget { 6 | final CovidAll covidAll; 7 | 8 | const LoadedCovidAllStateDisplay({Key key, @required this.covidAll}) 9 | : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | padding: EdgeInsets.only(top: 10, bottom: 20), 15 | height: (MediaQuery.of(context).size.height) / 2, 16 | child: Center( 17 | child: Column( 18 | mainAxisAlignment: MainAxisAlignment.center, 19 | crossAxisAlignment: CrossAxisAlignment.center, 20 | children: [ 21 | Center( 22 | child: Text( 23 | 'All Cases : ' + covidAll.getCases.toString(), 24 | style: TextStyle(fontSize: 25), 25 | ), 26 | ), 27 | Padding( 28 | padding: const EdgeInsets.only( 29 | top: 5, 30 | bottom: 5, 31 | ), 32 | ), 33 | Center( 34 | child: Text( 35 | 'All Deaths : ' + covidAll.getDeaths.toString(), 36 | style: TextStyle( 37 | fontSize: 25, 38 | color: Colors.red, 39 | ), 40 | ), 41 | ), 42 | Padding( 43 | padding: const EdgeInsets.only( 44 | top: 5, 45 | bottom: 5, 46 | ), 47 | ), 48 | Center( 49 | child: Text( 50 | 'All Recovered : ' + covidAll.getRecovered.toString(), 51 | style: TextStyle( 52 | fontSize: 25, 53 | color: Colors.green, 54 | ), 55 | ), 56 | ), 57 | Padding( 58 | padding: const EdgeInsets.only( 59 | top: 5, 60 | bottom: 5, 61 | ), 62 | ), 63 | Center( 64 | child: Text( 65 | 'All Active Cases : ' + 66 | (covidAll.getCases - 67 | covidAll.getDeaths - 68 | covidAll.getRecovered) 69 | .toString(), 70 | style: TextStyle( 71 | fontSize: 25, 72 | color: Colors.orange, 73 | ), 74 | ), 75 | ), 76 | ], 77 | ), 78 | ), 79 | 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /test/fixtures/country.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "United States of America", 4 | "topLevelDomain": [ 5 | ".us" 6 | ], 7 | "alpha2Code": "US", 8 | "alpha3Code": "USA", 9 | "callingCodes": [ 10 | "1" 11 | ], 12 | "capital": "Washington, D.C.", 13 | "altSpellings": [ 14 | "US", 15 | "USA", 16 | "United States of America" 17 | ], 18 | "region": "Americas", 19 | "subregion": "Northern America", 20 | "population": 323947000, 21 | "latlng": [ 22 | 38.0, 23 | -97.0 24 | ], 25 | "demonym": "American", 26 | "area": 9629091.0, 27 | "gini": 48.0, 28 | "timezones": [ 29 | "UTC-12:00", 30 | "UTC-11:00", 31 | "UTC-10:00", 32 | "UTC-09:00", 33 | "UTC-08:00", 34 | "UTC-07:00", 35 | "UTC-06:00", 36 | "UTC-05:00", 37 | "UTC-04:00", 38 | "UTC+10:00", 39 | "UTC+12:00" 40 | ], 41 | "borders": [ 42 | "CAN", 43 | "MEX" 44 | ], 45 | "nativeName": "United States", 46 | "numericCode": "840", 47 | "currencies": [ 48 | { 49 | "code": "USD", 50 | "name": "United States dollar", 51 | "symbol": "$" 52 | } 53 | ], 54 | "languages": [ 55 | { 56 | "iso639_1": "en", 57 | "iso639_2": "eng", 58 | "name": "English", 59 | "nativeName": "English" 60 | } 61 | ], 62 | "translations": { 63 | "de": "Vereinigte Staaten von Amerika", 64 | "es": "Estados Unidos", 65 | "fr": "États-Unis", 66 | "ja": "アメリカ合衆国", 67 | "it": "Stati Uniti D'America", 68 | "br": "Estados Unidos", 69 | "pt": "Estados Unidos", 70 | "nl": "Verenigde Staten", 71 | "hr": "Sjedinjene Američke Države", 72 | "fa": "ایالات متحده آمریکا" 73 | }, 74 | "flag": "https://restcountries.eu/data/usa.svg", 75 | "regionalBlocs": [ 76 | { 77 | "acronym": "NAFTA", 78 | "name": "North American Free Trade Agreement", 79 | "otherAcronyms": [], 80 | "otherNames": [ 81 | "Tratado de Libre Comercio de América del Norte", 82 | "Accord de Libre-échange Nord-Américain" 83 | ] 84 | } 85 | ], 86 | "cioc": "USA" 87 | } 88 | ] -------------------------------------------------------------------------------- /lib/features/covid_19/data/repos/covid_repo_impl.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../../../../core/Error/exceptions.dart'; 5 | import '../../../../core/Platform/network_info.dart'; 6 | import '../../../../core/error/Faliure.dart'; 7 | import '../../domain/entities/covid_all.dart'; 8 | import '../../domain/entities/covid_country.dart'; 9 | import '../../domain/repos/covid_repo.dart'; 10 | import '../datasources/covid_local_data_source.dart'; 11 | import '../datasources/covid_remote_data_source.dart'; 12 | 13 | class CovidRepoImpl implements CovidRepo { 14 | CovidRemoteDataSource _covidRemoteDataSource; 15 | CovidLocalDataSource _covidLocalDataSource; 16 | NetworkInfo _networkInfo; 17 | 18 | CovidRepoImpl( 19 | {@required CovidRemoteDataSource covidRemoteDataSource, 20 | @required CovidLocalDataSource covidLocalDataSource, 21 | @required NetworkInfo networkInfo}) { 22 | this._covidLocalDataSource = covidLocalDataSource; 23 | this._covidRemoteDataSource = covidRemoteDataSource; 24 | this._networkInfo = networkInfo; 25 | } 26 | 27 | @override 28 | Future> getAllCovidInfo() async { 29 | if (await _networkInfo.isConnected) { 30 | try { 31 | final _finalCovidAllModel = 32 | await _covidRemoteDataSource.getAllCovidInfo(); 33 | await _covidLocalDataSource.cacheAllCovidInfo(_finalCovidAllModel); 34 | return Right(_finalCovidAllModel); 35 | } on ServerException { 36 | return (Left(ServerFaliure())); 37 | } 38 | } else { 39 | try { 40 | final _finalCovidAllModel = 41 | await _covidLocalDataSource.getLastAllCovidInfo(); 42 | return Right(_finalCovidAllModel); 43 | } on CacheException { 44 | return (Left(CacheFaliure())); 45 | } 46 | } 47 | } 48 | 49 | @override 50 | Future> getCountrySpecifiCovidInfo( 51 | String country) async { 52 | if (await _networkInfo.isConnected) { 53 | try { 54 | final _finalCovidCountryModel = 55 | await _covidRemoteDataSource.getCountrySpecifiCovidInfo(country); 56 | await _covidLocalDataSource.cacheCountrySpecifiCovidInfo(_finalCovidCountryModel); 57 | return Right(_finalCovidCountryModel); 58 | } on ServerException { 59 | return (Left(ServerFaliure())); 60 | } on CountryNotFoundException{ 61 | return (Left(CountryNotFoundFaliure())); 62 | } 63 | } else { 64 | try { 65 | final _finalCovidCountryModel = 66 | await _covidLocalDataSource.getLastCountrySpecifiCovidInfo(); 67 | return Right(_finalCovidCountryModel); 68 | } on CacheException { 69 | return (Left(CacheFaliure())); 70 | } 71 | } 72 | } 73 | 74 | @override 75 | Future> getLKSpecifiCovidInfo() { 76 | return this.getCountrySpecifiCovidInfo('Sri Lanka'); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/CovidControl.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../bloc/covid_bloc.dart'; 5 | 6 | class CovidControl extends StatefulWidget { 7 | const CovidControl({ 8 | Key key, 9 | }) : super(key: key); 10 | 11 | @override 12 | _CovidControlState createState() => _CovidControlState(); 13 | } 14 | 15 | class _CovidControlState extends State { 16 | final controller = TextEditingController(); 17 | String inputString; 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Column( 22 | children: [ 23 | Container( 24 | child: TextField( 25 | controller: this.controller, 26 | decoration: InputDecoration( 27 | border: OutlineInputBorder(), 28 | hintText: 'Input a Country', 29 | ), 30 | onChanged: (val) { 31 | this.inputString = val; 32 | }, 33 | onSubmitted: (_) { 34 | this.controller.clear(); 35 | BlocProvider.of(context).dispatch( 36 | GetCountrySpecificCovidInfoEvent(country: this.inputString), 37 | ); 38 | }, 39 | ), 40 | ), 41 | Padding( 42 | padding: const EdgeInsets.only(top: 5), 43 | ), 44 | Row( 45 | children: [ 46 | Expanded( 47 | child: RaisedButton( 48 | child: Text('Search'), 49 | color: Theme.of(context).primaryColor, 50 | textColor: Colors.white, 51 | onPressed: () { 52 | this.controller.clear(); 53 | BlocProvider.of(context).dispatch( 54 | GetCountrySpecificCovidInfoEvent(country: this.inputString), 55 | ); 56 | }, 57 | ), 58 | ), 59 | ], 60 | ), 61 | Padding( 62 | padding: const EdgeInsets.only(top: 3), 63 | ), 64 | Center( 65 | child: SingleChildScrollView( 66 | child: Text( 67 | 'IMPORTANT', 68 | style: TextStyle( 69 | fontSize: 14, color: Theme.of(context).primaryColor), 70 | textAlign: TextAlign.center, 71 | ), 72 | ), 73 | ), 74 | Padding( 75 | padding: const EdgeInsets.only(top: 3), 76 | ), 77 | Center( 78 | child: SingleChildScrollView( 79 | child: Text( 80 | 'Search "South Korea" as "Korea"', 81 | style: TextStyle(fontSize: 14), 82 | textAlign: TextAlign.center, 83 | ), 84 | ), 85 | ), 86 | Padding( 87 | padding: const EdgeInsets.only( 88 | top: 5, 89 | bottom: 5, 90 | ), 91 | ), 92 | ], 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /test/features/covid_19/domain/entities/covid_country_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_country.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | final String imageUrl = 'https://restcountries.eu/data/usa.svg'; 6 | final String country = 'test'; 7 | final int cases = 1; 8 | final int deaths = 1; 9 | final int recovered = 1; 10 | final int todayDeaths = 1; 11 | final int active = 1; 12 | final int critical = 1; 13 | final int casesPerOneMillion = 1; 14 | 15 | final tCovidAll = CovidCountry( 16 | cases: cases, 17 | deaths: deaths, 18 | recovered: recovered, 19 | active: active, 20 | casesPerOneMillion: casesPerOneMillion, 21 | country: country, 22 | critical: critical, 23 | imageUrl: imageUrl, 24 | todayDeaths: todayDeaths, 25 | ); 26 | //* getCases 27 | test( 28 | 'should return same cases provided', 29 | () async { 30 | //act 31 | final result = tCovidAll.getCases; 32 | //assert 33 | expect(result, cases); 34 | }, 35 | ); 36 | 37 | //* getDeaths 38 | test( 39 | 'should return same Deaths provided', 40 | () async { 41 | //act 42 | final result = tCovidAll.getDeaths; 43 | //assert 44 | expect(result, deaths); 45 | }, 46 | ); 47 | 48 | //* getRecovered 49 | test( 50 | 'should return same Recovered provided', 51 | () async { 52 | //act 53 | final result = tCovidAll.getRecovered; 54 | //assert 55 | expect(result, recovered); 56 | }, 57 | ); 58 | 59 | //* getActive 60 | test( 61 | 'should return same Active provided', 62 | () async { 63 | //act 64 | final result = tCovidAll.getActive; 65 | //assert 66 | expect(result, active); 67 | }, 68 | ); 69 | 70 | //* getcasesPerOneMillion 71 | test( 72 | 'should return same casesPerOneMillion provided', 73 | () async { 74 | //act 75 | final result = tCovidAll.getCasesPerOneMillion; 76 | //assert 77 | expect(result, casesPerOneMillion); 78 | }, 79 | ); 80 | 81 | //* getcountry 82 | test( 83 | 'should return same country provided', 84 | () async { 85 | //act 86 | final result = tCovidAll.getCountry; 87 | //assert 88 | expect(result, country); 89 | }, 90 | ); 91 | 92 | //* getcritical 93 | test( 94 | 'should return same critical provided', 95 | () async { 96 | //act 97 | final result = tCovidAll.getCritical; 98 | //assert 99 | expect(result, critical); 100 | }, 101 | ); 102 | 103 | //* getimageUrl 104 | test( 105 | 'should return same imageUrl provided', 106 | () async { 107 | //act 108 | final result = tCovidAll.getImageUrl; 109 | //assert 110 | expect(result, imageUrl); 111 | }, 112 | ); 113 | 114 | //* gettodayDeaths 115 | test( 116 | 'should return same todayDeaths provided', 117 | () async { 118 | //act 119 | final result = tCovidAll.getTodayDeaths; 120 | //assert 121 | expect(result, todayDeaths); 122 | }, 123 | ); 124 | } 125 | -------------------------------------------------------------------------------- /lib/injection_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:data_connection_checker/data_connection_checker.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:http/http.dart' as http; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | import 'core/Platform/network_info.dart'; 8 | import 'core/util/input_converter.dart'; 9 | import 'features/covid_19/data/datasources/covid_local_data_source.dart'; 10 | import 'features/covid_19/data/datasources/covid_remote_data_source.dart'; 11 | import 'features/covid_19/data/repos/covid_repo_impl.dart'; 12 | import 'features/covid_19/domain/repos/covid_repo.dart'; 13 | import 'features/covid_19/domain/usecases/get_all_covid_info.dart'; 14 | import 'features/covid_19/domain/usecases/get_country_specific_covid_info.dart'; 15 | import 'features/covid_19/domain/usecases/get_lk_specific_covid_info.dart'; 16 | import 'features/covid_19/presentation/bloc/covid_bloc.dart'; 17 | import 'features/splash_screen/data/repos/splash_scree_repo_impl.dart'; 18 | import 'features/splash_screen/domain/repos/splash_screen_repo.dart'; 19 | import 'features/splash_screen/domain/usecases/navigate_to_main_screen.dart'; 20 | import 'features/splash_screen/presentation/bloc/splash_screen_bloc.dart'; 21 | 22 | final sl = GetIt.instance; 23 | Future init() async { 24 | //! Features - splash_screen 25 | 26 | //* Bloc 27 | sl.registerFactory( 28 | () => SplashScreenBloc( 29 | navigateToMainScreen: sl(), 30 | ), 31 | ); 32 | 33 | //* usecases 34 | sl.registerLazySingleton( 35 | () => NavigateToMainScreen( 36 | splashScreenRepo: sl(), 37 | ), 38 | ); 39 | 40 | //* repo 41 | 42 | sl.registerLazySingleton( 43 | () => SplashScreenRepoImpl( 44 | networkInfo: sl(), 45 | ), 46 | ); 47 | 48 | //! Features - covid_19 49 | 50 | //* Bloc 51 | sl.registerFactory(() => CovidBloc( 52 | getAllCovidInfo: sl(), 53 | getCountrySpecifiCovidInfo: sl(), 54 | getLKSpecifiCovidInfo: sl(), 55 | inputConverter: sl())); 56 | 57 | //* usecases 58 | sl.registerLazySingleton(() => GetAllCovidInfo(repo: sl())); 59 | sl.registerLazySingleton(() => GetCountrySpecifiCovidInfo(repo: sl())); 60 | sl.registerLazySingleton(() => GetLKSpecifiCovidInfo(repo: sl())); 61 | 62 | //* repo 63 | sl.registerLazySingleton( 64 | () => CovidRepoImpl( 65 | covidRemoteDataSource: sl(), 66 | covidLocalDataSource: sl(), 67 | networkInfo: sl()), 68 | ); 69 | 70 | //* datasource 71 | sl.registerLazySingleton( 72 | () => CovidLocalDataSourceImpl(sharedPreferences: sl()), 73 | ); 74 | sl.registerLazySingleton( 75 | () => CovidRemoteDataSourceImpl(httpClient: sl()), 76 | ); 77 | 78 | //! Core 79 | sl.registerLazySingleton(() => InputConverter()); 80 | sl.registerLazySingleton(() => NetworkInfoImpl(sl())); 81 | 82 | //! External Libraries 83 | 84 | final sharedPreferences = await SharedPreferences.getInstance(); 85 | sl.registerLazySingleton(() => sharedPreferences); 86 | sl.registerLazySingleton(() => http.Client()); 87 | sl.registerLazySingleton(() => DataConnectionChecker()); 88 | } 89 | -------------------------------------------------------------------------------- /lib/features/covid_19/data/models/covid_country_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../domain/entities/covid_country.dart'; 4 | 5 | /* 6 | {"country":"Sri Lanka", 7 | "cases":66, 8 | "todayCases":6, 9 | "deaths":0, 10 | "todayDeaths":0, 11 | "recovered":3, 12 | "active":63, 13 | "critical":0, 14 | "casesPerOneMillion":3}*/ 15 | 16 | class CovidCountryModel extends CovidCountry { 17 | String _imageUrl; 18 | String _country; 19 | num _cases; 20 | num _deaths; 21 | num _todayDeaths; 22 | num _recovered; 23 | num _active; 24 | num _critical; 25 | num _casesPerOneMillion; 26 | 27 | CovidCountryModel({ 28 | @required String imageUrl, 29 | @required String country, 30 | @required num cases, 31 | @required num todayCases, 32 | @required num deaths, 33 | @required num todayDeaths, 34 | @required num recovered, 35 | @required num active, 36 | @required num critical, 37 | @required num casesPerOneMillion, 38 | }) : super( 39 | imageUrl: imageUrl, 40 | country: country, 41 | cases: cases, 42 | todayCases: todayCases, 43 | deaths: deaths, 44 | todayDeaths: todayDeaths, 45 | recovered: recovered, 46 | active: active, 47 | critical: critical, 48 | casesPerOneMillion: casesPerOneMillion) { 49 | this._imageUrl = imageUrl; 50 | this._country = country; 51 | this._cases = cases; 52 | this._deaths = deaths; 53 | this._todayDeaths = todayDeaths; 54 | this._recovered = recovered; 55 | this._active = active; 56 | this._critical = critical; 57 | this._casesPerOneMillion = casesPerOneMillion; 58 | } 59 | 60 | // factory CovidCountryModel.fromJson( 61 | // Map covidCountry, Map country) { 62 | // return CovidCountryModel( 63 | // active: covidCountry['active'], 64 | // country: covidCountry['country'], 65 | // critical: covidCountry['critical'], 66 | // imageUrl: covidCountry['flag'], 67 | // casesPerOneMillion: covidCountry['casesPerOneMillion'], 68 | // todayDeaths: covidCountry['todayDeaths'], 69 | // cases: covidCountry['cases'], 70 | // todayCases: covidCountry['todayCases'], 71 | // deaths: covidCountry['deaths'], 72 | // recovered: covidCountry['recovered'], 73 | // ); 74 | // } 75 | 76 | factory CovidCountryModel.fromJson(Map covidCountry) { 77 | return CovidCountryModel( 78 | active: covidCountry['active'], 79 | country: covidCountry['country'], 80 | critical: covidCountry['critical'], 81 | imageUrl: covidCountry['countryInfo']['flag'], 82 | casesPerOneMillion: covidCountry['casesPerOneMillion'], 83 | todayDeaths: covidCountry['todayDeaths'], 84 | cases: covidCountry['cases'], 85 | todayCases: covidCountry['todayCases'], 86 | deaths: covidCountry['deaths'], 87 | recovered: covidCountry['recovered'], 88 | ); 89 | } 90 | 91 | Map toJson() { 92 | return { 93 | 'active': super.getActive, 94 | 'country': super.getCountry, 95 | 'critical': super.getCritical, 96 | 'imageUrl': super.getImageUrl, 97 | 'casesPerOneMillion': super.getCasesPerOneMillion, 98 | 'todayDeaths': super.getTodayDeaths, 99 | 'cases': super.getCases, 100 | 'todayCases': super.getTodayCases, 101 | 'deaths': super.getDeaths, 102 | 'recovered': super.getRecovered, 103 | }; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/bloc/covid_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:bloc/bloc.dart'; 4 | import 'package:covid_19_info/core/error/Faliure.dart'; 5 | import 'package:covid_19_info/core/Usecase/use_case.dart'; 6 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_all_covid_info.dart'; 7 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_country_specific_covid_info.dart'; 8 | import 'package:covid_19_info/features/covid_19/domain/usecases/get_lk_specific_covid_info.dart'; 9 | import 'package:covid_19_info/features/splash_screen/presentation/bloc/splash_screen_bloc.dart'; 10 | import 'package:meta/meta.dart'; 11 | import 'package:flutter/material.dart'; 12 | 13 | import '../../../../core/util/input_converter.dart'; 14 | import '../../domain/entities/covid_all.dart'; 15 | import '../../domain/entities/covid_country.dart'; 16 | 17 | part 'covid_event.dart'; 18 | part 'covid_state.dart'; 19 | 20 | const String SERVER_FALIURE_MESSAGE = 'Server Faliure'; 21 | const String CACHE_FALIURE_MESSAGE = 'Cache Faliure'; 22 | const String INVALID_INPUT_FALIURE_MESSAGE = 'Invalid Input Faliure'; 23 | const String COUNTRY_NOT_FOUND_FALIURE_MESSAGE = 'Country not Found'; 24 | const String UNEXPECTED_ERROR_MESSAGE = 'Unexpected Error'; 25 | 26 | class CovidBloc extends Bloc { 27 | final GetAllCovidInfo getAllCovidInfo; 28 | final GetCountrySpecifiCovidInfo getCountrySpecifiCovidInfo; 29 | final GetLKSpecifiCovidInfo getLKSpecifiCovidInfo; 30 | final InputConverter inputConverter; 31 | 32 | CovidBloc({ 33 | @required this.getAllCovidInfo, 34 | @required this.getCountrySpecifiCovidInfo, 35 | @required this.getLKSpecifiCovidInfo, 36 | @required this.inputConverter, 37 | }); 38 | 39 | @override 40 | CovidState get initialState => Empty(); 41 | 42 | @override 43 | Stream mapEventToState( 44 | CovidEvent event, 45 | ) async* { 46 | if (event is GetAllCovidInfoEvent) { 47 | yield Empty(); 48 | final response = await getAllCovidInfo( 49 | NoParams(), 50 | ); 51 | yield response.fold( 52 | (faliure) => ErrorAll(message: _mapFaliureToMessage(faliure)), 53 | (covidAll) => LoadedCovidAll(covidAll: covidAll), 54 | ); 55 | } else if (event is GetCountrySpecificCovidInfoEvent) { 56 | final country = inputConverter.check(event.country); 57 | yield* country.fold( 58 | (faliure) async* { 59 | yield Error(message: INVALID_INPUT_FALIURE_MESSAGE); 60 | }, 61 | (coun) async* { 62 | yield Loading(); 63 | final response = await getCountrySpecifiCovidInfo(coun); 64 | yield response.fold( 65 | (faliure) => Error(message: _mapFaliureToMessage(faliure)), 66 | (covidCountry) => LoadedCovidCountry(covidCountry: covidCountry), 67 | ); 68 | }, 69 | ); 70 | } else if (event is GetLKSpecificCovidInfoEvent) { 71 | yield Empty(); 72 | final response = await getLKSpecifiCovidInfo( 73 | NoParams(), 74 | ); 75 | yield response.fold( 76 | (faliure) => ErrorSL(message: _mapFaliureToMessage(faliure)), 77 | (covidSL) => LoadedCovidSL(covidSL: covidSL), 78 | ); 79 | } 80 | } 81 | 82 | String _mapFaliureToMessage(Faliure faliure) { 83 | switch (faliure.runtimeType) { 84 | case ServerFaliure: 85 | return SERVER_FALIURE_MESSAGE; 86 | 87 | case CacheFaliure: 88 | return CACHE_FALIURE_MESSAGE; 89 | 90 | case CountryNotFoundFaliure: 91 | return COUNTRY_NOT_FOUND_FALIURE_MESSAGE; 92 | 93 | default: 94 | return UNEXPECTED_ERROR_MESSAGE; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/pages/coivd_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import '../../../../injection_container.dart'; 5 | import '../bloc/covid_bloc.dart'; 6 | import '../widgets/CovidControl.dart'; 7 | import '../widgets/EmptyStateDisplay.dart'; 8 | import '../widgets/LoadedCovidAllStateDisplayNew.dart'; 9 | import '../widgets/LoadedCovidCountryDisplay.dart'; 10 | import '../widgets/LoadedCovidSLStateDisplayNew.dart'; 11 | import '../widgets/LoadingStateDisplay.dart'; 12 | import '../widgets/LoadingStateDisplayGetAllEventDispatch.dart'; 13 | import '../widgets/LoadingStateDisplayGetSLEventDispatch.dart'; 14 | import '../widgets/SLControl.dart'; 15 | import '../widgets/WorldControl.dart'; 16 | import '../widgets/app_bar_design.dart'; 17 | 18 | class CovidPage extends StatelessWidget { 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | backgroundColor: Theme.of(context).backgroundColor, 23 | appBar: AppBarDesign(), 24 | body: SingleChildScrollView( 25 | scrollDirection: Axis.vertical, 26 | child: Container( 27 | child: Padding( 28 | padding: const EdgeInsets.all(10), 29 | child: Column( 30 | children: [ 31 | //* World Part 32 | _buildWorld(context), 33 | 34 | Padding( 35 | padding: EdgeInsets.only( 36 | top: 10, 37 | bottom: 10, 38 | ), 39 | ), 40 | 41 | //* SL Part 42 | _buildSL(context), 43 | 44 | Padding( 45 | padding: EdgeInsets.only( 46 | top: 10, 47 | bottom: 10, 48 | ), 49 | ), 50 | 51 | //* Country Part 52 | _buildCountry(context), 53 | ], 54 | ), 55 | ), 56 | ), 57 | ), 58 | ); 59 | } 60 | 61 | BlocProvider _buildWorld(BuildContext context) { 62 | return BlocProvider( 63 | builder: (context) => sl(), 64 | child: Column( 65 | children: [ 66 | WorldControl(), 67 | Padding( 68 | padding: EdgeInsets.only( 69 | top: 10, 70 | bottom: 10, 71 | ), 72 | ), 73 | BlocBuilder(builder: (context, state) { 74 | if (state is Empty) { 75 | return new LoadingStateDisplayGetAllEventDispatch(); 76 | } else if (state is LoadedCovidAll) { 77 | return LoadedCovidAllStateDisplayNew( 78 | covidAll: state.covidAll, 79 | ); 80 | } else if (state is ErrorAll) { 81 | return EmptyStateDisplay( 82 | message: state.message, 83 | ); 84 | } else { 85 | return Text(state.toString()); 86 | } 87 | }), 88 | ], 89 | ), 90 | ); 91 | } 92 | 93 | BlocProvider _buildSL(BuildContext context) { 94 | return BlocProvider( 95 | builder: (context) => sl(), 96 | child: Column( 97 | children: [ 98 | SLControl(), 99 | Padding( 100 | padding: EdgeInsets.only( 101 | top: 10, 102 | bottom: 10, 103 | ), 104 | ), 105 | BlocBuilder( 106 | builder: (context, state) { 107 | if (state is Empty) { 108 | return new LoadingStateDisplayGetSLEventDispatch(); 109 | } else if (state is LoadedCovidSL) { 110 | return LoadedCovidSLStateDisplayNew( 111 | covidSL: state.covidSL, 112 | ); 113 | } else if (state is ErrorSL) { 114 | return EmptyStateDisplay( 115 | message: state.message, 116 | ); 117 | } else { 118 | return Text(state.toString()); 119 | } 120 | }, 121 | ), 122 | ], 123 | ), 124 | ); 125 | } 126 | 127 | BlocProvider _buildCountry(BuildContext context) { 128 | return BlocProvider( 129 | builder: (context) => sl(), 130 | child: Column( 131 | children: [ 132 | Text( 133 | 'Update of a Country'.toUpperCase(), 134 | style: TextStyle( 135 | fontSize: 25, 136 | color: Theme.of(context).primaryColor, 137 | fontWeight: FontWeight.bold, 138 | letterSpacing: 1, 139 | ), 140 | ), 141 | Padding( 142 | padding: EdgeInsets.only( 143 | top: 2.5, 144 | bottom: 2.5, 145 | ), 146 | ), 147 | BlocBuilder( 148 | builder: (context, state) { 149 | if (state is Empty) { 150 | return EmptyStateDisplay( 151 | message: 'Input a Country to get Updates'); 152 | } else if (state is Loading) { 153 | return LoadingStateDisplay(); 154 | } else if (state is Error) { 155 | return EmptyStateDisplay(message: state.message); 156 | } else if (state is LoadedCovidCountry) { 157 | return LoadedCovidCountryDisplay( 158 | covidCountry: state.covidCountry); 159 | } 160 | }, 161 | ), 162 | CovidControl(), 163 | ], 164 | ), 165 | ); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadedCovidCountryDisplay.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../domain/entities/covid_country.dart'; 4 | 5 | class LoadedCovidCountryDisplay extends StatelessWidget { 6 | final CovidCountry covidCountry; 7 | 8 | const LoadedCovidCountryDisplay({Key key, @required this.covidCountry}) 9 | : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | print(this.covidCountry.getImageUrl); 14 | return Container( 15 | padding: EdgeInsets.only(top: 10, bottom: 20), 16 | height: (MediaQuery.of(context).size.height) / 1.4, 17 | child: Center( 18 | child: Column( 19 | mainAxisAlignment: MainAxisAlignment.center, 20 | crossAxisAlignment: CrossAxisAlignment.center, 21 | children: [ 22 | Center( 23 | child: Text( 24 | covidCountry.getCountry.toString().toUpperCase(), 25 | style: TextStyle( 26 | fontSize: 40, 27 | color: Theme.of(context).primaryColor, 28 | ), 29 | ), 30 | ), 31 | Padding( 32 | padding: const EdgeInsets.only( 33 | top: 2.5, 34 | bottom: 2.5, 35 | ), 36 | ), 37 | Center( 38 | child: Container( 39 | height: 60, 40 | decoration: BoxDecoration( 41 | border: Border.all( 42 | color: Theme.of(context).accentColor, 43 | width: 1, 44 | ), 45 | ), 46 | child: Image( 47 | image: NetworkImage( 48 | this.covidCountry.getImageUrl, 49 | ), 50 | ), 51 | ), 52 | ), 53 | Padding( 54 | padding: const EdgeInsets.only( 55 | top: 10, 56 | bottom: 10, 57 | ), 58 | ), 59 | Center( 60 | child: Text( 61 | 'Cases : ' + covidCountry.getCases.toString(), 62 | style: TextStyle( 63 | fontSize: 20, 64 | ), 65 | ), 66 | ), 67 | Padding( 68 | padding: const EdgeInsets.only( 69 | top: 4, 70 | bottom: 4, 71 | ), 72 | ), 73 | Center( 74 | child: Text( 75 | 'Today Cases : ' + covidCountry.getTodayCases.toString(), 76 | style: TextStyle( 77 | fontSize: 20, 78 | color: Colors.blue, 79 | ), 80 | ), 81 | ), 82 | Padding( 83 | padding: const EdgeInsets.only( 84 | top: 4, 85 | bottom: 4, 86 | ), 87 | ), 88 | Center( 89 | child: Text( 90 | 'Deaths : ' + covidCountry.getDeaths.toString(), 91 | style: TextStyle( 92 | fontSize: 20, 93 | color: Colors.red, 94 | ), 95 | ), 96 | ), 97 | Padding( 98 | padding: const EdgeInsets.only( 99 | top: 4, 100 | bottom: 4, 101 | ), 102 | ), 103 | Center( 104 | child: Text( 105 | 'Today Deaths : ' + covidCountry.getTodayDeaths.toString(), 106 | style: TextStyle( 107 | fontSize: 20, 108 | color: Colors.redAccent, 109 | ), 110 | ), 111 | ), 112 | Padding( 113 | padding: const EdgeInsets.only( 114 | top: 4, 115 | bottom: 4, 116 | ), 117 | ), 118 | Center( 119 | child: Text( 120 | 'Recovered : ' + covidCountry.getRecovered.toString(), 121 | style: TextStyle( 122 | fontSize: 20, 123 | color: Colors.green, 124 | ), 125 | ), 126 | ), 127 | Padding( 128 | padding: const EdgeInsets.only( 129 | top: 5, 130 | bottom: 5, 131 | ), 132 | ), 133 | Center( 134 | child: Text( 135 | 'Active Cases : ' + covidCountry.getActive.toString(), 136 | style: TextStyle( 137 | fontSize: 20, 138 | color: Colors.orange, 139 | ), 140 | ), 141 | ), 142 | Padding( 143 | padding: const EdgeInsets.only( 144 | top: 4, 145 | bottom: 4, 146 | ), 147 | ), 148 | Center( 149 | child: Text( 150 | 'Critical : ' + covidCountry.getCritical.toString(), 151 | style: TextStyle( 152 | fontSize: 20, 153 | color: Colors.orangeAccent, 154 | ), 155 | ), 156 | ), 157 | Padding( 158 | padding: const EdgeInsets.only( 159 | top: 4, 160 | bottom: 4, 161 | ), 162 | ), 163 | Center( 164 | child: Text( 165 | 'Cases Per Million : ' + 166 | covidCountry.getCasesPerOneMillion.toString(), 167 | style: TextStyle( 168 | fontSize: 20, 169 | color: Colors.grey, 170 | ), 171 | ), 172 | ), 173 | ], 174 | ), 175 | ), 176 | ); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /test/features/covid_19/data/repos/covid_repo_impl_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:covid_19_info/core/Error/Faliure.dart'; 2 | import 'package:covid_19_info/core/Error/exceptions.dart'; 3 | import 'package:covid_19_info/core/Platform/network_info.dart'; 4 | import 'package:covid_19_info/features/covid_19/data/datasources/covid_local_data_source.dart'; 5 | import 'package:covid_19_info/features/covid_19/data/datasources/covid_remote_data_source.dart'; 6 | import 'package:covid_19_info/features/covid_19/data/models/covid_all_model.dart'; 7 | import 'package:covid_19_info/features/covid_19/data/models/covid_country_model.dart'; 8 | import 'package:covid_19_info/features/covid_19/data/repos/covid_repo_impl.dart'; 9 | import 'package:covid_19_info/features/covid_19/domain/entities/covid_all.dart'; 10 | import 'package:dartz/dartz.dart'; 11 | import 'package:flutter_test/flutter_test.dart'; 12 | import 'package:mockito/mockito.dart'; 13 | 14 | class MockRemoteDataSource extends Mock implements CovidRemoteDataSource {} 15 | 16 | class MockLocalDataSource extends Mock implements CovidLocalDataSource {} 17 | 18 | class MockNetworkInfo extends Mock implements NetworkInfo {} 19 | 20 | void main() { 21 | MockRemoteDataSource mockRemoteDataSource; 22 | MockLocalDataSource mockLocalDataSource; 23 | MockNetworkInfo mockNetworkInfo; 24 | CovidRepoImpl covidRepoImpl; 25 | 26 | setUp(() { 27 | mockRemoteDataSource = new MockRemoteDataSource(); 28 | mockLocalDataSource = new MockLocalDataSource(); 29 | mockNetworkInfo = new MockNetworkInfo(); 30 | covidRepoImpl = new CovidRepoImpl( 31 | covidRemoteDataSource: mockRemoteDataSource, 32 | covidLocalDataSource: mockLocalDataSource, 33 | networkInfo: mockNetworkInfo, 34 | ); 35 | }); 36 | 37 | group( 38 | 'getAllCovidInfo()', 39 | () { 40 | final int cases = 250618; 41 | final int deaths = 10254; 42 | final int recovered = 89044; 43 | 44 | final tCovidAllModel = 45 | CovidAllModel(cases: cases, deaths: deaths, recovered: recovered); 46 | final CovidAll tCovidAll = tCovidAllModel; 47 | 48 | test( 49 | 'should check if the device is online', 50 | () async { 51 | //arrange 52 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); 53 | //act 54 | covidRepoImpl.getAllCovidInfo(); 55 | //assert 56 | verify(mockNetworkInfo.isConnected); 57 | }, 58 | ); 59 | 60 | group( 61 | 'when the device is online', 62 | () { 63 | setUp( 64 | () { 65 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); 66 | }, 67 | ); 68 | test( 69 | 'should return remote data and cache data', 70 | () async { 71 | //arrange 72 | when(mockRemoteDataSource.getAllCovidInfo()) 73 | .thenAnswer((_) async => tCovidAllModel); 74 | //act 75 | final result = await covidRepoImpl.getAllCovidInfo(); 76 | //assert 77 | verify(mockRemoteDataSource.getAllCovidInfo()); 78 | verify(mockLocalDataSource.cacheAllCovidInfo(tCovidAllModel)); 79 | expect(result, Right(tCovidAllModel)); 80 | }, 81 | ); 82 | }, 83 | ); 84 | 85 | group( 86 | 'when the device is offline', 87 | () { 88 | setUp( 89 | () { 90 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => false); 91 | }, 92 | ); 93 | 94 | test( 95 | 'should return local all data', 96 | () async { 97 | //arrange 98 | when(mockLocalDataSource.getLastAllCovidInfo()) 99 | .thenAnswer((_) async => tCovidAllModel); 100 | //act 101 | final result = await covidRepoImpl.getAllCovidInfo(); 102 | //assert 103 | verify(mockLocalDataSource.getLastAllCovidInfo()); 104 | verifyZeroInteractions(mockRemoteDataSource); 105 | expect(result, Right(tCovidAllModel)); 106 | }, 107 | ); 108 | }, 109 | ); 110 | }, 111 | ); 112 | 113 | group( 114 | 'getCountrySpecifiCovidInfo()', 115 | () { 116 | final String imageUrl = 'https://restcountries.eu/data/usa.svg'; 117 | final String country = 'test'; 118 | final int cases = 1; 119 | final int deaths = 1; 120 | final int recovered = 1; 121 | final int todayDeaths = 1; 122 | final int active = 1; 123 | final int critical = 1; 124 | final int casesPerOneMillion = 1; 125 | 126 | final tCovidCountryModel = CovidCountryModel( 127 | cases: cases, 128 | deaths: deaths, 129 | recovered: recovered, 130 | active: active, 131 | casesPerOneMillion: casesPerOneMillion, 132 | country: country, 133 | critical: critical, 134 | imageUrl: imageUrl, 135 | todayDeaths: todayDeaths, 136 | ); 137 | test( 138 | 'should check if the device is online', 139 | () async { 140 | //arrange 141 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); 142 | //act 143 | covidRepoImpl.getAllCovidInfo(); 144 | //assert 145 | verify(mockNetworkInfo.isConnected); 146 | }, 147 | ); 148 | 149 | group( 150 | 'when the device is online', 151 | () { 152 | setUp( 153 | () { 154 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => true); 155 | }, 156 | ); 157 | test( 158 | 'should return remote data and cache data', 159 | () async { 160 | //arrange 161 | when(mockRemoteDataSource.getCountrySpecifiCovidInfo(any)) 162 | .thenAnswer((_) async => tCovidCountryModel); 163 | //act 164 | final result = await covidRepoImpl.getCountrySpecifiCovidInfo('USA'); 165 | //assert 166 | verify(mockRemoteDataSource.getCountrySpecifiCovidInfo(any)); 167 | verify(mockLocalDataSource.cacheCountrySpecifiCovidInfo(tCovidCountryModel)); 168 | expect(result, Right(tCovidCountryModel)); 169 | }, 170 | ); 171 | }, 172 | ); 173 | 174 | group( 175 | 'when the device is offline', 176 | () { 177 | setUp( 178 | () { 179 | when(mockNetworkInfo.isConnected).thenAnswer((_) async => false); 180 | }, 181 | ); 182 | 183 | test( 184 | 'should return local all data', 185 | () async { 186 | //arrange 187 | when(mockLocalDataSource.getLastCountrySpecifiCovidInfo()) 188 | .thenAnswer((_) async => tCovidCountryModel); 189 | //act 190 | final result = await covidRepoImpl.getCountrySpecifiCovidInfo('USA'); 191 | //assert 192 | verify(mockLocalDataSource.getLastCountrySpecifiCovidInfo()); 193 | verifyZeroInteractions(mockRemoteDataSource); 194 | expect(result, Right(tCovidCountryModel)); 195 | }, 196 | ); 197 | }, 198 | ); 199 | 200 | }, 201 | ); 202 | } 203 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.0.11" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.5.2" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.4.0" 25 | bloc: 26 | dependency: transitive 27 | description: 28 | name: bloc 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "0.15.0" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.0.5" 39 | charcode: 40 | dependency: transitive 41 | description: 42 | name: charcode 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.2" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.14.11" 53 | convert: 54 | dependency: transitive 55 | description: 56 | name: convert 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.1" 60 | crypto: 61 | dependency: transitive 62 | description: 63 | name: crypto 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "2.1.3" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.1.3" 74 | dartz: 75 | dependency: "direct main" 76 | description: 77 | name: dartz 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "0.8.9" 81 | data_connection_checker: 82 | dependency: "direct main" 83 | description: 84 | name: data_connection_checker 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "0.3.4" 88 | equatable: 89 | dependency: "direct main" 90 | description: 91 | name: equatable 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "0.4.0" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_bloc: 101 | dependency: "direct main" 102 | description: 103 | name: flutter_bloc 104 | url: "https://pub.dartlang.org" 105 | source: hosted 106 | version: "0.21.0" 107 | flutter_launcher_icons: 108 | dependency: "direct main" 109 | description: 110 | name: flutter_launcher_icons 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "0.7.4" 114 | flutter_test: 115 | dependency: "direct dev" 116 | description: flutter 117 | source: sdk 118 | version: "0.0.0" 119 | flutter_web_plugins: 120 | dependency: transitive 121 | description: flutter 122 | source: sdk 123 | version: "0.0.0" 124 | get_it: 125 | dependency: "direct main" 126 | description: 127 | name: get_it 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "4.0.1" 131 | http: 132 | dependency: "direct main" 133 | description: 134 | name: http 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "0.12.0+4" 138 | http_parser: 139 | dependency: transitive 140 | description: 141 | name: http_parser 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "3.1.3" 145 | image: 146 | dependency: transitive 147 | description: 148 | name: image 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.1.4" 152 | matcher: 153 | dependency: transitive 154 | description: 155 | name: matcher 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "0.12.6" 159 | meta: 160 | dependency: transitive 161 | description: 162 | name: meta 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.1.8" 166 | mockito: 167 | dependency: "direct dev" 168 | description: 169 | name: mockito 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "4.1.1" 173 | path: 174 | dependency: transitive 175 | description: 176 | name: path 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.6.4" 180 | pedantic: 181 | dependency: transitive 182 | description: 183 | name: pedantic 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "1.8.0+1" 187 | petitparser: 188 | dependency: transitive 189 | description: 190 | name: petitparser 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "2.4.0" 194 | provider: 195 | dependency: transitive 196 | description: 197 | name: provider 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "3.2.0" 201 | quiver: 202 | dependency: transitive 203 | description: 204 | name: quiver 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "2.0.5" 208 | rxdart: 209 | dependency: transitive 210 | description: 211 | name: rxdart 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "0.22.6" 215 | shared_preferences: 216 | dependency: "direct main" 217 | description: 218 | name: shared_preferences 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "0.5.6+3" 222 | shared_preferences_macos: 223 | dependency: transitive 224 | description: 225 | name: shared_preferences_macos 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "0.0.1+6" 229 | shared_preferences_platform_interface: 230 | dependency: transitive 231 | description: 232 | name: shared_preferences_platform_interface 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "1.0.1" 236 | shared_preferences_web: 237 | dependency: transitive 238 | description: 239 | name: shared_preferences_web 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "0.1.2+4" 243 | sky_engine: 244 | dependency: transitive 245 | description: flutter 246 | source: sdk 247 | version: "0.0.99" 248 | source_span: 249 | dependency: transitive 250 | description: 251 | name: source_span 252 | url: "https://pub.dartlang.org" 253 | source: hosted 254 | version: "1.5.5" 255 | stack_trace: 256 | dependency: transitive 257 | description: 258 | name: stack_trace 259 | url: "https://pub.dartlang.org" 260 | source: hosted 261 | version: "1.9.3" 262 | stream_channel: 263 | dependency: transitive 264 | description: 265 | name: stream_channel 266 | url: "https://pub.dartlang.org" 267 | source: hosted 268 | version: "2.0.0" 269 | string_scanner: 270 | dependency: transitive 271 | description: 272 | name: string_scanner 273 | url: "https://pub.dartlang.org" 274 | source: hosted 275 | version: "1.0.5" 276 | term_glyph: 277 | dependency: transitive 278 | description: 279 | name: term_glyph 280 | url: "https://pub.dartlang.org" 281 | source: hosted 282 | version: "1.1.0" 283 | test_api: 284 | dependency: transitive 285 | description: 286 | name: test_api 287 | url: "https://pub.dartlang.org" 288 | source: hosted 289 | version: "0.2.11" 290 | typed_data: 291 | dependency: transitive 292 | description: 293 | name: typed_data 294 | url: "https://pub.dartlang.org" 295 | source: hosted 296 | version: "1.1.6" 297 | vector_math: 298 | dependency: transitive 299 | description: 300 | name: vector_math 301 | url: "https://pub.dartlang.org" 302 | source: hosted 303 | version: "2.0.8" 304 | xml: 305 | dependency: transitive 306 | description: 307 | name: xml 308 | url: "https://pub.dartlang.org" 309 | source: hosted 310 | version: "3.5.0" 311 | yaml: 312 | dependency: transitive 313 | description: 314 | name: yaml 315 | url: "https://pub.dartlang.org" 316 | source: hosted 317 | version: "2.2.0" 318 | sdks: 319 | dart: ">=2.4.0 <3.0.0" 320 | flutter: ">=1.12.13+hotfix.4 <2.0.0" 321 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadedCovidAllStateDisplayNew.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../domain/entities/covid_all.dart'; 4 | 5 | class LoadedCovidAllStateDisplayNew extends StatelessWidget { 6 | final CovidAll covidAll; 7 | 8 | LoadedCovidAllStateDisplayNew({@required this.covidAll}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | height: MediaQuery.of(context).size.height / 4.5, 14 | child: ListView( 15 | scrollDirection: Axis.horizontal, 16 | children: [ 17 | Row( 18 | children: [ 19 | Container( 20 | height: MediaQuery.of(context).size.height / 3.7, 21 | width: MediaQuery.of(context).size.height / 3.7, 22 | child: Card( 23 | color: Colors.blueGrey, 24 | margin: EdgeInsets.all(5), 25 | shape: RoundedRectangleBorder( 26 | borderRadius: BorderRadius.all(Radius.circular(10))), 27 | child: Center( 28 | child: Column( 29 | mainAxisAlignment: MainAxisAlignment.center, 30 | crossAxisAlignment: CrossAxisAlignment.center, 31 | children: [ 32 | Text( 33 | 'Total'.toUpperCase(), 34 | style: TextStyle( 35 | color: Colors.white, 36 | letterSpacing: 2, 37 | fontSize: 15, 38 | fontWeight: FontWeight.bold, 39 | ), 40 | ), 41 | Text( 42 | 'Cases'.toUpperCase(), 43 | style: TextStyle( 44 | color: Colors.white, 45 | letterSpacing: 2, 46 | fontSize: 15, 47 | fontWeight: FontWeight.bold, 48 | ), 49 | ), 50 | Padding( 51 | padding: EdgeInsets.only( 52 | top: 10, 53 | bottom: 5, 54 | ), 55 | ), 56 | Text( 57 | this.covidAll.getCases.toString(), 58 | style: TextStyle( 59 | color: Colors.white, 60 | letterSpacing: 2, 61 | fontSize: 25, 62 | fontWeight: FontWeight.bold, 63 | ), 64 | ), 65 | ], 66 | ), 67 | ), 68 | ), 69 | ), 70 | Container( 71 | height: MediaQuery.of(context).size.height / 3.7, 72 | width: MediaQuery.of(context).size.height / 3.7, 73 | child: Card( 74 | color: Colors.red, 75 | margin: EdgeInsets.all(5), 76 | shape: RoundedRectangleBorder( 77 | borderRadius: BorderRadius.all(Radius.circular(10))), 78 | child: Center( 79 | child: Column( 80 | mainAxisAlignment: MainAxisAlignment.center, 81 | crossAxisAlignment: CrossAxisAlignment.center, 82 | children: [ 83 | Text( 84 | 'Total'.toUpperCase(), 85 | style: TextStyle( 86 | color: Colors.white, 87 | letterSpacing: 2, 88 | fontSize: 15, 89 | fontWeight: FontWeight.bold, 90 | ), 91 | ), 92 | Text( 93 | 'Deaths'.toUpperCase(), 94 | style: TextStyle( 95 | color: Colors.white, 96 | letterSpacing: 2, 97 | fontSize: 15, 98 | fontWeight: FontWeight.bold, 99 | ), 100 | ), 101 | Padding( 102 | padding: EdgeInsets.only( 103 | top: 10, 104 | bottom: 5, 105 | ), 106 | ), 107 | Text( 108 | this.covidAll.getDeaths.toString(), 109 | style: TextStyle( 110 | color: Colors.white, 111 | letterSpacing: 2, 112 | fontSize: 25, 113 | fontWeight: FontWeight.bold, 114 | ), 115 | ), 116 | ], 117 | ), 118 | ), 119 | ), 120 | ), 121 | Container( 122 | height: MediaQuery.of(context).size.height / 3.7, 123 | width: MediaQuery.of(context).size.height / 3.7, 124 | child: Card( 125 | color: Colors.green, 126 | margin: EdgeInsets.all(5), 127 | shape: RoundedRectangleBorder( 128 | borderRadius: BorderRadius.all(Radius.circular(10))), 129 | child: Center( 130 | child: Column( 131 | mainAxisAlignment: MainAxisAlignment.center, 132 | crossAxisAlignment: CrossAxisAlignment.center, 133 | children: [ 134 | Text( 135 | 'Total'.toUpperCase(), 136 | style: TextStyle( 137 | color: Colors.white, 138 | letterSpacing: 2, 139 | fontSize: 15, 140 | fontWeight: FontWeight.bold, 141 | ), 142 | ), 143 | Text( 144 | 'Recovered'.toUpperCase(), 145 | style: TextStyle( 146 | color: Colors.white, 147 | letterSpacing: 2, 148 | fontSize: 15, 149 | fontWeight: FontWeight.bold, 150 | ), 151 | ), 152 | Padding( 153 | padding: EdgeInsets.only( 154 | top: 10, 155 | bottom: 5, 156 | ), 157 | ), 158 | Text( 159 | this.covidAll.getRecovered.toString(), 160 | style: TextStyle( 161 | color: Colors.white, 162 | letterSpacing: 2, 163 | fontSize: 25, 164 | fontWeight: FontWeight.bold, 165 | ), 166 | ), 167 | ], 168 | ), 169 | ), 170 | ), 171 | ), 172 | Container( 173 | height: MediaQuery.of(context).size.height / 3.7, 174 | width: MediaQuery.of(context).size.height / 3.7, 175 | child: Card( 176 | color: Colors.orange, 177 | margin: EdgeInsets.all(5), 178 | shape: RoundedRectangleBorder( 179 | borderRadius: BorderRadius.all(Radius.circular(10))), 180 | child: Center( 181 | child: Column( 182 | mainAxisAlignment: MainAxisAlignment.center, 183 | crossAxisAlignment: CrossAxisAlignment.center, 184 | children: [ 185 | Text( 186 | 'Active'.toUpperCase(), 187 | style: TextStyle( 188 | color: Colors.white, 189 | letterSpacing: 2, 190 | fontSize: 15, 191 | fontWeight: FontWeight.bold, 192 | ), 193 | ), 194 | Text( 195 | 'Cases'.toUpperCase(), 196 | style: TextStyle( 197 | color: Colors.white, 198 | letterSpacing: 2, 199 | fontSize: 15, 200 | fontWeight: FontWeight.bold, 201 | ), 202 | ), 203 | Padding( 204 | padding: EdgeInsets.only( 205 | top: 10, 206 | bottom: 5, 207 | ), 208 | ), 209 | Text( 210 | (this.covidAll.getCases - 211 | this.covidAll.getDeaths - 212 | this.covidAll.getRecovered) 213 | .toString(), 214 | style: TextStyle( 215 | color: Colors.white, 216 | letterSpacing: 2, 217 | fontSize: 25, 218 | fontWeight: FontWeight.bold, 219 | ), 220 | ), 221 | ], 222 | ), 223 | ), 224 | ), 225 | ), 226 | ], 227 | ) 228 | ], 229 | ), 230 | ); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /lib/features/covid_19/presentation/widgets/LoadedCovidSLStateDisplayNew.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../domain/entities/covid_country.dart'; 4 | 5 | class LoadedCovidSLStateDisplayNew extends StatelessWidget { 6 | final CovidCountry covidSL; 7 | 8 | LoadedCovidSLStateDisplayNew({@required this.covidSL}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | height: MediaQuery.of(context).size.height / 3.5, 14 | child: ListView( 15 | scrollDirection: Axis.horizontal, 16 | children: [ 17 | Row( 18 | children: [ 19 | Container( 20 | height: MediaQuery.of(context).size.height / 3.5, 21 | width: MediaQuery.of(context).size.height / 3.5, 22 | child: Card( 23 | color: Colors.blueGrey, 24 | margin: EdgeInsets.all(5), 25 | shape: RoundedRectangleBorder( 26 | borderRadius: BorderRadius.all(Radius.circular(10))), 27 | child: Center( 28 | child: Column( 29 | mainAxisAlignment: MainAxisAlignment.center, 30 | crossAxisAlignment: CrossAxisAlignment.center, 31 | children: [ 32 | Text( 33 | 'Total'.toUpperCase(), 34 | style: TextStyle( 35 | color: Colors.white, 36 | letterSpacing: 2, 37 | fontSize: 20, 38 | fontWeight: FontWeight.bold, 39 | ), 40 | ), 41 | Text( 42 | 'Cases'.toUpperCase(), 43 | style: TextStyle( 44 | color: Colors.white, 45 | letterSpacing: 2, 46 | fontSize: 20, 47 | fontWeight: FontWeight.bold, 48 | ), 49 | ), 50 | Padding( 51 | padding: EdgeInsets.only( 52 | top: 10, 53 | bottom: 5, 54 | ), 55 | ), 56 | Text( 57 | this.covidSL.getCases.toString(), 58 | style: TextStyle( 59 | color: Colors.white, 60 | letterSpacing: 2, 61 | fontSize: 30, 62 | fontWeight: FontWeight.bold, 63 | ), 64 | ), 65 | ], 66 | ), 67 | ), 68 | ), 69 | ), 70 | Container( 71 | height: MediaQuery.of(context).size.height / 3.5, 72 | width: MediaQuery.of(context).size.height / 3.5, 73 | child: Card( 74 | color: Colors.blueAccent, 75 | margin: EdgeInsets.all(5), 76 | shape: RoundedRectangleBorder( 77 | borderRadius: BorderRadius.all(Radius.circular(10))), 78 | child: Center( 79 | child: Column( 80 | mainAxisAlignment: MainAxisAlignment.center, 81 | crossAxisAlignment: CrossAxisAlignment.center, 82 | children: [ 83 | Text( 84 | 'Today'.toUpperCase(), 85 | style: TextStyle( 86 | color: Colors.white, 87 | letterSpacing: 2, 88 | fontSize: 20, 89 | fontWeight: FontWeight.bold, 90 | ), 91 | ), 92 | Text( 93 | 'Cases'.toUpperCase(), 94 | style: TextStyle( 95 | color: Colors.white, 96 | letterSpacing: 2, 97 | fontSize: 20, 98 | fontWeight: FontWeight.bold, 99 | ), 100 | ), 101 | Padding( 102 | padding: EdgeInsets.only( 103 | top: 10, 104 | bottom: 5, 105 | ), 106 | ), 107 | Text( 108 | this.covidSL.getTodayCases.toString(), 109 | style: TextStyle( 110 | color: Colors.white, 111 | letterSpacing: 2, 112 | fontSize: 30, 113 | fontWeight: FontWeight.bold, 114 | ), 115 | ), 116 | ], 117 | ), 118 | ), 119 | ), 120 | ), 121 | Container( 122 | height: MediaQuery.of(context).size.height / 3.5, 123 | width: MediaQuery.of(context).size.height / 3.5, 124 | child: Card( 125 | color: Colors.redAccent, 126 | margin: EdgeInsets.all(5), 127 | shape: RoundedRectangleBorder( 128 | borderRadius: BorderRadius.all(Radius.circular(10))), 129 | child: Center( 130 | child: Column( 131 | mainAxisAlignment: MainAxisAlignment.center, 132 | crossAxisAlignment: CrossAxisAlignment.center, 133 | children: [ 134 | Text( 135 | 'Total'.toUpperCase(), 136 | style: TextStyle( 137 | color: Colors.white, 138 | letterSpacing: 2, 139 | fontSize: 20, 140 | fontWeight: FontWeight.bold, 141 | ), 142 | ), 143 | Text( 144 | 'Deaths'.toUpperCase(), 145 | style: TextStyle( 146 | color: Colors.white, 147 | letterSpacing: 2, 148 | fontSize: 20, 149 | fontWeight: FontWeight.bold, 150 | ), 151 | ), 152 | Padding( 153 | padding: EdgeInsets.only( 154 | top: 10, 155 | bottom: 5, 156 | ), 157 | ), 158 | Text( 159 | this.covidSL.getDeaths.toString(), 160 | style: TextStyle( 161 | color: Colors.white, 162 | letterSpacing: 2, 163 | fontSize: 30, 164 | fontWeight: FontWeight.bold, 165 | ), 166 | ), 167 | ], 168 | ), 169 | ), 170 | ), 171 | ), 172 | Container( 173 | height: MediaQuery.of(context).size.height / 3.5, 174 | width: MediaQuery.of(context).size.height / 3.5, 175 | child: Card( 176 | color: Colors.red, 177 | margin: EdgeInsets.all(5), 178 | shape: RoundedRectangleBorder( 179 | borderRadius: BorderRadius.all(Radius.circular(10))), 180 | child: Center( 181 | child: Column( 182 | mainAxisAlignment: MainAxisAlignment.center, 183 | crossAxisAlignment: CrossAxisAlignment.center, 184 | children: [ 185 | Text( 186 | 'Today'.toUpperCase(), 187 | style: TextStyle( 188 | color: Colors.white, 189 | letterSpacing: 2, 190 | fontSize: 20, 191 | fontWeight: FontWeight.bold, 192 | ), 193 | ), 194 | Text( 195 | 'Deaths'.toUpperCase(), 196 | style: TextStyle( 197 | color: Colors.white, 198 | letterSpacing: 2, 199 | fontSize: 20, 200 | fontWeight: FontWeight.bold, 201 | ), 202 | ), 203 | Padding( 204 | padding: EdgeInsets.only( 205 | top: 10, 206 | bottom: 5, 207 | ), 208 | ), 209 | Text( 210 | this.covidSL.getTodayDeaths.toString(), 211 | style: TextStyle( 212 | color: Colors.white, 213 | letterSpacing: 2, 214 | fontSize: 30, 215 | fontWeight: FontWeight.bold, 216 | ), 217 | ), 218 | ], 219 | ), 220 | ), 221 | ), 222 | ), 223 | Container( 224 | height: MediaQuery.of(context).size.height / 3.5, 225 | width: MediaQuery.of(context).size.height / 3.5, 226 | child: Card( 227 | color: Colors.green, 228 | margin: EdgeInsets.all(5), 229 | shape: RoundedRectangleBorder( 230 | borderRadius: BorderRadius.all(Radius.circular(10))), 231 | child: Center( 232 | child: Column( 233 | mainAxisAlignment: MainAxisAlignment.center, 234 | crossAxisAlignment: CrossAxisAlignment.center, 235 | children: [ 236 | Text( 237 | 'Total'.toUpperCase(), 238 | style: TextStyle( 239 | color: Colors.white, 240 | letterSpacing: 2, 241 | fontSize: 20, 242 | fontWeight: FontWeight.bold, 243 | ), 244 | ), 245 | Text( 246 | 'Recovered'.toUpperCase(), 247 | style: TextStyle( 248 | color: Colors.white, 249 | letterSpacing: 2, 250 | fontSize: 20, 251 | fontWeight: FontWeight.bold, 252 | ), 253 | ), 254 | Padding( 255 | padding: EdgeInsets.only( 256 | top: 10, 257 | bottom: 5, 258 | ), 259 | ), 260 | Text( 261 | this.covidSL.getRecovered.toString(), 262 | style: TextStyle( 263 | color: Colors.white, 264 | letterSpacing: 2, 265 | fontSize: 30, 266 | fontWeight: FontWeight.bold, 267 | ), 268 | ), 269 | ], 270 | ), 271 | ), 272 | ), 273 | ), 274 | Container( 275 | height: MediaQuery.of(context).size.height / 3.5, 276 | width: MediaQuery.of(context).size.height / 3.5, 277 | child: Card( 278 | color: Colors.orange, 279 | margin: EdgeInsets.all(5), 280 | shape: RoundedRectangleBorder( 281 | borderRadius: BorderRadius.all(Radius.circular(10))), 282 | child: Center( 283 | child: Column( 284 | mainAxisAlignment: MainAxisAlignment.center, 285 | crossAxisAlignment: CrossAxisAlignment.center, 286 | children: [ 287 | Text( 288 | 'Active'.toUpperCase(), 289 | style: TextStyle( 290 | color: Colors.white, 291 | letterSpacing: 2, 292 | fontSize: 20, 293 | fontWeight: FontWeight.bold, 294 | ), 295 | ), 296 | Text( 297 | 'Cases'.toUpperCase(), 298 | style: TextStyle( 299 | color: Colors.white, 300 | letterSpacing: 2, 301 | fontSize: 20, 302 | fontWeight: FontWeight.bold, 303 | ), 304 | ), 305 | Padding( 306 | padding: EdgeInsets.only( 307 | top: 10, 308 | bottom: 5, 309 | ), 310 | ), 311 | Text( 312 | this.covidSL.getActive.toString(), 313 | style: TextStyle( 314 | color: Colors.white, 315 | letterSpacing: 2, 316 | fontSize: 30, 317 | fontWeight: FontWeight.bold, 318 | ), 319 | ), 320 | ], 321 | ), 322 | ), 323 | ), 324 | ), 325 | Container( 326 | height: MediaQuery.of(context).size.height / 3.5, 327 | width: MediaQuery.of(context).size.height / 3.5, 328 | child: Card( 329 | color: Colors.deepPurpleAccent, 330 | margin: EdgeInsets.all(5), 331 | shape: RoundedRectangleBorder( 332 | borderRadius: BorderRadius.all(Radius.circular(10))), 333 | child: Center( 334 | child: Column( 335 | mainAxisAlignment: MainAxisAlignment.center, 336 | crossAxisAlignment: CrossAxisAlignment.center, 337 | children: [ 338 | Text( 339 | 'Critical'.toUpperCase(), 340 | style: TextStyle( 341 | color: Colors.white, 342 | letterSpacing: 2, 343 | fontSize: 20, 344 | fontWeight: FontWeight.bold, 345 | ), 346 | ), 347 | Text( 348 | 'Cases'.toUpperCase(), 349 | style: TextStyle( 350 | color: Colors.white, 351 | letterSpacing: 2, 352 | fontSize: 20, 353 | fontWeight: FontWeight.bold, 354 | ), 355 | ), 356 | Padding( 357 | padding: EdgeInsets.only( 358 | top: 10, 359 | bottom: 5, 360 | ), 361 | ), 362 | Text( 363 | this.covidSL.getCritical.toString(), 364 | style: TextStyle( 365 | color: Colors.white, 366 | letterSpacing: 2, 367 | fontSize: 30, 368 | fontWeight: FontWeight.bold, 369 | ), 370 | ), 371 | ], 372 | ), 373 | ), 374 | ), 375 | ), 376 | Container( 377 | height: MediaQuery.of(context).size.height / 3.5, 378 | width: MediaQuery.of(context).size.height / 3.5, 379 | child: Card( 380 | color: Colors.grey, 381 | margin: EdgeInsets.all(5), 382 | shape: RoundedRectangleBorder( 383 | borderRadius: BorderRadius.all(Radius.circular(10))), 384 | child: Center( 385 | child: Column( 386 | mainAxisAlignment: MainAxisAlignment.center, 387 | crossAxisAlignment: CrossAxisAlignment.center, 388 | children: [ 389 | Text( 390 | 'Cases'.toUpperCase(), 391 | style: TextStyle( 392 | color: Colors.white, 393 | letterSpacing: 2, 394 | fontSize: 20, 395 | fontWeight: FontWeight.bold, 396 | ), 397 | ), 398 | Text( 399 | 'Per Million'.toUpperCase(), 400 | style: TextStyle( 401 | color: Colors.white, 402 | letterSpacing: 2, 403 | fontSize: 20, 404 | fontWeight: FontWeight.bold, 405 | ), 406 | ), 407 | Padding( 408 | padding: EdgeInsets.only( 409 | top: 10, 410 | bottom: 5, 411 | ), 412 | ), 413 | Text( 414 | this.covidSL.getCasesPerOneMillion.toString(), 415 | style: TextStyle( 416 | color: Colors.white, 417 | letterSpacing: 2, 418 | fontSize: 30, 419 | fontWeight: FontWeight.bold, 420 | ), 421 | ), 422 | ], 423 | ), 424 | ), 425 | ), 426 | ), 427 | 428 | ], 429 | ) 430 | ], 431 | ), 432 | ); 433 | } 434 | } 435 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 19 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 20 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXCopyFilesBuildPhase section */ 24 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 25 | isa = PBXCopyFilesBuildPhase; 26 | buildActionMask = 2147483647; 27 | dstPath = ""; 28 | dstSubfolderSpec = 10; 29 | files = ( 30 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 31 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 32 | ); 33 | name = "Embed Frameworks"; 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 40 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 41 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 42 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 43 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 44 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 45 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 46 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 47 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 48 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 49 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 62 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | 9740EEB11CF90186004384FC /* Flutter */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 3B80C3931E831B6300D905FE /* App.framework */, 73 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 74 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 75 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 76 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 77 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 78 | ); 79 | name = Flutter; 80 | sourceTree = ""; 81 | }; 82 | 97C146E51CF9000F007C117D = { 83 | isa = PBXGroup; 84 | children = ( 85 | 9740EEB11CF90186004384FC /* Flutter */, 86 | 97C146F01CF9000F007C117D /* Runner */, 87 | 97C146EF1CF9000F007C117D /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 97C146EF1CF9000F007C117D /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 97C146EE1CF9000F007C117D /* Runner.app */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 97C146F01CF9000F007C117D /* Runner */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 103 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 104 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 105 | 97C147021CF9000F007C117D /* Info.plist */, 106 | 97C146F11CF9000F007C117D /* Supporting Files */, 107 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 108 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 109 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 110 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 111 | ); 112 | path = Runner; 113 | sourceTree = ""; 114 | }; 115 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | ); 119 | name = "Supporting Files"; 120 | sourceTree = ""; 121 | }; 122 | /* End PBXGroup section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | 97C146ED1CF9000F007C117D /* Runner */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 128 | buildPhases = ( 129 | 9740EEB61CF901F6004384FC /* Run Script */, 130 | 97C146EA1CF9000F007C117D /* Sources */, 131 | 97C146EB1CF9000F007C117D /* Frameworks */, 132 | 97C146EC1CF9000F007C117D /* Resources */, 133 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 134 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = Runner; 141 | productName = Runner; 142 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 97C146E61CF9000F007C117D /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 1020; 152 | ORGANIZATIONNAME = "The Chromium Authors"; 153 | TargetAttributes = { 154 | 97C146ED1CF9000F007C117D = { 155 | CreatedOnToolsVersion = 7.3.1; 156 | LastSwiftMigration = 0910; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = en; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | en, 166 | Base, 167 | ); 168 | mainGroup = 97C146E51CF9000F007C117D; 169 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 170 | projectDirPath = ""; 171 | projectRoot = ""; 172 | targets = ( 173 | 97C146ED1CF9000F007C117D /* Runner */, 174 | ); 175 | }; 176 | /* End PBXProject section */ 177 | 178 | /* Begin PBXResourcesBuildPhase section */ 179 | 97C146EC1CF9000F007C117D /* Resources */ = { 180 | isa = PBXResourcesBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 184 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 185 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 186 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 187 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXResourcesBuildPhase section */ 192 | 193 | /* Begin PBXShellScriptBuildPhase section */ 194 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 195 | isa = PBXShellScriptBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | ); 199 | inputPaths = ( 200 | ); 201 | name = "Thin Binary"; 202 | outputPaths = ( 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | shellPath = /bin/sh; 206 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 207 | }; 208 | 9740EEB61CF901F6004384FC /* Run Script */ = { 209 | isa = PBXShellScriptBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | inputPaths = ( 214 | ); 215 | name = "Run Script"; 216 | outputPaths = ( 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 221 | }; 222 | /* End PBXShellScriptBuildPhase section */ 223 | 224 | /* Begin PBXSourcesBuildPhase section */ 225 | 97C146EA1CF9000F007C117D /* Sources */ = { 226 | isa = PBXSourcesBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 230 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXSourcesBuildPhase section */ 235 | 236 | /* Begin PBXVariantGroup section */ 237 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 238 | isa = PBXVariantGroup; 239 | children = ( 240 | 97C146FB1CF9000F007C117D /* Base */, 241 | ); 242 | name = Main.storyboard; 243 | sourceTree = ""; 244 | }; 245 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 97C147001CF9000F007C117D /* Base */, 249 | ); 250 | name = LaunchScreen.storyboard; 251 | sourceTree = ""; 252 | }; 253 | /* End PBXVariantGroup section */ 254 | 255 | /* Begin XCBuildConfiguration section */ 256 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 257 | isa = XCBuildConfiguration; 258 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 259 | buildSettings = { 260 | ALWAYS_SEARCH_USER_PATHS = NO; 261 | CLANG_ANALYZER_NONNULL = YES; 262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 263 | CLANG_CXX_LIBRARY = "libc++"; 264 | CLANG_ENABLE_MODULES = YES; 265 | CLANG_ENABLE_OBJC_ARC = YES; 266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_COMMA = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 271 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 272 | CLANG_WARN_EMPTY_BODY = YES; 273 | CLANG_WARN_ENUM_CONVERSION = YES; 274 | CLANG_WARN_INFINITE_RECURSION = YES; 275 | CLANG_WARN_INT_CONVERSION = YES; 276 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 278 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 279 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 280 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 281 | CLANG_WARN_STRICT_PROTOTYPES = YES; 282 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 283 | CLANG_WARN_UNREACHABLE_CODE = YES; 284 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 285 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 286 | COPY_PHASE_STRIP = NO; 287 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 288 | ENABLE_NS_ASSERTIONS = NO; 289 | ENABLE_STRICT_OBJC_MSGSEND = YES; 290 | GCC_C_LANGUAGE_STANDARD = gnu99; 291 | GCC_NO_COMMON_BLOCKS = YES; 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 299 | MTL_ENABLE_DEBUG_INFO = NO; 300 | SDKROOT = iphoneos; 301 | TARGETED_DEVICE_FAMILY = "1,2"; 302 | VALIDATE_PRODUCT = YES; 303 | }; 304 | name = Profile; 305 | }; 306 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 307 | isa = XCBuildConfiguration; 308 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 309 | buildSettings = { 310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 311 | CLANG_ENABLE_MODULES = YES; 312 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 313 | ENABLE_BITCODE = NO; 314 | FRAMEWORK_SEARCH_PATHS = ( 315 | "$(inherited)", 316 | "$(PROJECT_DIR)/Flutter", 317 | ); 318 | INFOPLIST_FILE = Runner/Info.plist; 319 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 320 | LIBRARY_SEARCH_PATHS = ( 321 | "$(inherited)", 322 | "$(PROJECT_DIR)/Flutter", 323 | ); 324 | PRODUCT_BUNDLE_IDENTIFIER = com.example.covid19Info; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 327 | SWIFT_VERSION = 4.0; 328 | VERSIONING_SYSTEM = "apple-generic"; 329 | }; 330 | name = Profile; 331 | }; 332 | 97C147031CF9000F007C117D /* Debug */ = { 333 | isa = XCBuildConfiguration; 334 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 339 | CLANG_CXX_LIBRARY = "libc++"; 340 | CLANG_ENABLE_MODULES = YES; 341 | CLANG_ENABLE_OBJC_ARC = YES; 342 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 343 | CLANG_WARN_BOOL_CONVERSION = YES; 344 | CLANG_WARN_COMMA = YES; 345 | CLANG_WARN_CONSTANT_CONVERSION = YES; 346 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 347 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 348 | CLANG_WARN_EMPTY_BODY = YES; 349 | CLANG_WARN_ENUM_CONVERSION = YES; 350 | CLANG_WARN_INFINITE_RECURSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 354 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 355 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 356 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 357 | CLANG_WARN_STRICT_PROTOTYPES = YES; 358 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 359 | CLANG_WARN_UNREACHABLE_CODE = YES; 360 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 361 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 362 | COPY_PHASE_STRIP = NO; 363 | DEBUG_INFORMATION_FORMAT = dwarf; 364 | ENABLE_STRICT_OBJC_MSGSEND = YES; 365 | ENABLE_TESTABILITY = YES; 366 | GCC_C_LANGUAGE_STANDARD = gnu99; 367 | GCC_DYNAMIC_NO_PIC = NO; 368 | GCC_NO_COMMON_BLOCKS = YES; 369 | GCC_OPTIMIZATION_LEVEL = 0; 370 | GCC_PREPROCESSOR_DEFINITIONS = ( 371 | "DEBUG=1", 372 | "$(inherited)", 373 | ); 374 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 375 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 376 | GCC_WARN_UNDECLARED_SELECTOR = YES; 377 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 378 | GCC_WARN_UNUSED_FUNCTION = YES; 379 | GCC_WARN_UNUSED_VARIABLE = YES; 380 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 381 | MTL_ENABLE_DEBUG_INFO = YES; 382 | ONLY_ACTIVE_ARCH = YES; 383 | SDKROOT = iphoneos; 384 | TARGETED_DEVICE_FAMILY = "1,2"; 385 | }; 386 | name = Debug; 387 | }; 388 | 97C147041CF9000F007C117D /* Release */ = { 389 | isa = XCBuildConfiguration; 390 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 391 | buildSettings = { 392 | ALWAYS_SEARCH_USER_PATHS = NO; 393 | CLANG_ANALYZER_NONNULL = YES; 394 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 395 | CLANG_CXX_LIBRARY = "libc++"; 396 | CLANG_ENABLE_MODULES = YES; 397 | CLANG_ENABLE_OBJC_ARC = YES; 398 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 399 | CLANG_WARN_BOOL_CONVERSION = YES; 400 | CLANG_WARN_COMMA = YES; 401 | CLANG_WARN_CONSTANT_CONVERSION = YES; 402 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 403 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 404 | CLANG_WARN_EMPTY_BODY = YES; 405 | CLANG_WARN_ENUM_CONVERSION = YES; 406 | CLANG_WARN_INFINITE_RECURSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 413 | CLANG_WARN_STRICT_PROTOTYPES = YES; 414 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 415 | CLANG_WARN_UNREACHABLE_CODE = YES; 416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 418 | COPY_PHASE_STRIP = NO; 419 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 420 | ENABLE_NS_ASSERTIONS = NO; 421 | ENABLE_STRICT_OBJC_MSGSEND = YES; 422 | GCC_C_LANGUAGE_STANDARD = gnu99; 423 | GCC_NO_COMMON_BLOCKS = YES; 424 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 425 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 426 | GCC_WARN_UNDECLARED_SELECTOR = YES; 427 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 428 | GCC_WARN_UNUSED_FUNCTION = YES; 429 | GCC_WARN_UNUSED_VARIABLE = YES; 430 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 431 | MTL_ENABLE_DEBUG_INFO = NO; 432 | SDKROOT = iphoneos; 433 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 434 | TARGETED_DEVICE_FAMILY = "1,2"; 435 | VALIDATE_PRODUCT = YES; 436 | }; 437 | name = Release; 438 | }; 439 | 97C147061CF9000F007C117D /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 442 | buildSettings = { 443 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 444 | CLANG_ENABLE_MODULES = YES; 445 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 446 | ENABLE_BITCODE = NO; 447 | FRAMEWORK_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "$(PROJECT_DIR)/Flutter", 450 | ); 451 | INFOPLIST_FILE = Runner/Info.plist; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | LIBRARY_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "$(PROJECT_DIR)/Flutter", 456 | ); 457 | PRODUCT_BUNDLE_IDENTIFIER = com.example.covid19Info; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 460 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 461 | SWIFT_VERSION = 4.0; 462 | VERSIONING_SYSTEM = "apple-generic"; 463 | }; 464 | name = Debug; 465 | }; 466 | 97C147071CF9000F007C117D /* Release */ = { 467 | isa = XCBuildConfiguration; 468 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | CLANG_ENABLE_MODULES = YES; 472 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 473 | ENABLE_BITCODE = NO; 474 | FRAMEWORK_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "$(PROJECT_DIR)/Flutter", 477 | ); 478 | INFOPLIST_FILE = Runner/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 480 | LIBRARY_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "$(PROJECT_DIR)/Flutter", 483 | ); 484 | PRODUCT_BUNDLE_IDENTIFIER = com.example.covid19Info; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 487 | SWIFT_VERSION = 4.0; 488 | VERSIONING_SYSTEM = "apple-generic"; 489 | }; 490 | name = Release; 491 | }; 492 | /* End XCBuildConfiguration section */ 493 | 494 | /* Begin XCConfigurationList section */ 495 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 97C147031CF9000F007C117D /* Debug */, 499 | 97C147041CF9000F007C117D /* Release */, 500 | 249021D3217E4FDB00AE95B9 /* Profile */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 97C147061CF9000F007C117D /* Debug */, 509 | 97C147071CF9000F007C117D /* Release */, 510 | 249021D4217E4FDB00AE95B9 /* Profile */, 511 | ); 512 | defaultConfigurationIsVisible = 0; 513 | defaultConfigurationName = Release; 514 | }; 515 | /* End XCConfigurationList section */ 516 | 517 | }; 518 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 519 | } 520 | --------------------------------------------------------------------------------