Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Commit

Permalink
Added save feature for countries
Browse files Browse the repository at this point in the history
additionaly fixed some code problems
  • Loading branch information
Qizot committed Mar 22, 2020
1 parent 7e86eb4 commit 6f9edc0
Show file tree
Hide file tree
Showing 23 changed files with 519 additions and 113 deletions.
17 changes: 13 additions & 4 deletions frontend/coronavirus_visualizer/lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@


import 'package:coronavirus_visualizer/src/bloc/saved_countries/bloc.dart';
import 'package:coronavirus_visualizer/src/bloc/timeline_bloc/bloc.dart';
import 'package:coronavirus_visualizer/src/ui/country_timeline/country_picker_screen.dart';
import 'package:coronavirus_visualizer/src/ui/country_timeline/country_timeline_screen.dart';
Expand All @@ -16,10 +17,18 @@ class App extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocProvider<TimelineBloc>(
create: (context) => TimelineBloc()
..add(TimelineInitialize()),
child: MaterialApp(
return MultiBlocProvider(
providers: [
BlocProvider<TimelineBloc>(
create: (context) => TimelineBloc()
..add(TimelineInitialize()),
),
BlocProvider<SavedCountriesBloc>(
create: (context) => SavedCountriesBloc()
..add(SavedCountriesFetch()),
)
],
child:MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'saved_countries_bloc.dart';
export 'saved_countries_event.dart';
export 'saved_countries_state.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import 'dart:async';
import 'package:coronavirus_visualizer/src/services/countries.dart';
import 'package:localstorage/localstorage.dart';
import 'package:bloc/bloc.dart';
import 'package:coronavirus_visualizer/src/bloc/saved_countries/bloc.dart';

class SavedCountriesBloc extends Bloc<SavedCountriesEvent, SavedCountriesState> {

final _storage = LocalStorage('coronavirus');
int _fetched = 0;
int _errors = 0;
int _successes = 0;


@override
SavedCountriesState get initialState => SavedCountriesUninitialized();

@override
Stream<SavedCountriesState> mapEventToState(SavedCountriesEvent event) async* {
if (event is SavedCountriesAddCountry) {
yield* _mapAddCountry(event);
}
if (event is SavedCountriesRemoveCountry) {
yield* _mapRemoveCountry(event);
}
if (event is SavedCountriesFetch) {
yield* _mapFetch(event);
}
}

List<Country> _getCountries() {
return (_storage.getItem('countries') as List)
?.map((country) => Country.fromJson(country))
?.toList() ?? [];
}

Stream<SavedCountriesState> _mapAddCountry(SavedCountriesAddCountry event) async* {
try {
final countries = _getCountries();

if (countries.indexOf(event.country, 0) != -1) {
_errors += 1;
yield SavedCountriesError(error: "Country has already been saved!", version: _errors);
} else {
countries.add(event.country);
await _storage.setItem('countries',
countries
.map((c) => c.toJson())
.toList()
);
_successes += 1;
yield SavedCountriesSuccess(message: "Country has been saved!", version: _successes);
add(SavedCountriesFetch());
}
} catch (error) {
_errors += 1;
yield SavedCountriesError(error: "Failed to save country!", version: _errors);
}
}

Stream<SavedCountriesState> _mapRemoveCountry(SavedCountriesRemoveCountry event) async* {
try {
final countries = _getCountries();

if (countries.indexOf(event.country, 0) == -1) {

_errors += 1;
yield SavedCountriesError(error: "Country was not previously saved!", version: _errors);
} else {
countries.remove(event.country);
_storage.setItem('countries', countries.map((c) => c.toJson()).toList());

_successes += 1;
yield SavedCountriesSuccess(message: "Country has been removed!", version: _successes);
add(SavedCountriesFetch());
}

} catch (error) {

_errors += 1;
yield SavedCountriesError(error: "Failed to remove country!", version: _errors);
}
}

Stream<SavedCountriesState> _mapFetch(SavedCountriesFetch event) async* {
try {
final countries = _getCountries();

_fetched += 1;
yield SavedCountriesFetched(countries: countries, version: _fetched);
} catch (error) {

_errors += 1;
yield SavedCountriesError(error: "Failed to fetch saved countries!", version: _errors);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:coronavirus_visualizer/src/services/countries.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';


abstract class SavedCountriesEvent extends Equatable {
const SavedCountriesEvent();

@override
List<Object> get props => [];
}

class SavedCountriesAddCountry extends SavedCountriesEvent {
final Country country;

SavedCountriesAddCountry({@required this.country});

@override
List<Object> get props => [country];

@override
String toString() {
return 'SavedCountriesAddCountry { country: $country }';
}
}

class SavedCountriesRemoveCountry extends SavedCountriesEvent {
final Country country;

SavedCountriesRemoveCountry({@required this.country});

@override
List<Object> get props => [country];

@override
String toString() {
return 'SavedCountriesRemoveCountry { country: $country }';
}
}

class SavedCountriesFetch extends SavedCountriesEvent {
@override
String toString() {
return 'SavedCountriesFetch { }';
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:coronavirus_visualizer/src/services/countries.dart';
import 'package:equatable/equatable.dart';


abstract class SavedCountriesState extends Equatable {
const SavedCountriesState();

@override
List<Object> get props => [];
}

class SavedCountriesUninitialized extends SavedCountriesState {
@override
String toString() => 'SavedCountriesUninitialized { }';

}

class SavedCountriesError extends SavedCountriesState {
final String error;
final int version;

SavedCountriesError({this.error, this.version});

@override
List<Object> get props => [version, error];

@override
String toString() => 'SavedCountriesStateError { version: $version, error: $error }';
}

class SavedCountriesSuccess extends SavedCountriesState {
final String message;
final int version;

SavedCountriesSuccess({this.message, this.version});

@override
List<Object> get props => [version, message];

@override
String toString() => 'SavedCountriesSuccess { version: $version, message: $message }';
}

class SavedCountriesLoading extends SavedCountriesState {
@override
String toString() => 'SavedCountriesStateLoading { }';
}

class SavedCountriesFetched extends SavedCountriesState {
final List<Country> countries;
final int version;

SavedCountriesFetched({this.countries, this.version});

@override
List<Object> get props => [version, countries];

@override
String toString() => 'SavedCountriesFetched { version: $version, countries: $countries }';
}

Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class TimelineBloc extends Bloc<TimelineEvent, TimelineState> {
final globalTimeline = await _repository.getGlobalTimeline();
await showLoadingScreen;
yield TimelineFetchedGlobalTimeline(globalTimeline: globalTimeline);
} on DioError catch (e) {
} on DioError {
yield TimelineError(error: "Error has occured while communicating with backend!");
} catch (e) {
} on Exception {
yield TimelineError(error: "Unknown error has occured, try again later!");
}
}
Expand All @@ -40,9 +40,9 @@ class TimelineBloc extends Bloc<TimelineEvent, TimelineState> {
final countryTimeline = await _repository.getCountryTimeline(event.countryCode);
await showLoadingScreen;
yield TimelineFetchedCountryTimeline(countryTimeline: countryTimeline);
} on DioError catch (e) {
} on DioError {
yield TimelineError(error: "Error has occured while communicating with backend!");
} catch (e) {
} on Exception {
yield TimelineError(error: "Unknown error has occured, try again later!");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ abstract class TimelineEvent extends Equatable {

class TimelineInitialize extends TimelineEvent {
@override
String toString() {
return 'TimelineInitialize { }';
}
String toString() => 'TimelineInitialize { }';
}

class TimelineFetchTimeline extends TimelineEvent {
Expand All @@ -25,9 +23,7 @@ class TimelineFetchTimeline extends TimelineEvent {
List<Object> get props => [dateFrom, dateTo];

@override
String toString() {
return 'TimelineFetchTimeline { dateFrom: $dateFrom, dateTo: $dateTo }';
}
String toString() => 'TimelineFetchTimeline { dateFrom: $dateFrom, dateTo: $dateTo }';
}

class TimelineFetchCountryTimeline extends TimelineEvent {
Expand All @@ -41,7 +37,5 @@ class TimelineFetchCountryTimeline extends TimelineEvent {
List<Object> get props => [countryCode, dateFrom, dateTo];

@override
String toString() {
return 'TimelineFetchCountryTimeline { countryCode: $countryCode, dateFrom: $dateFrom, dateTo: $dateTo }';
}
}
String toString() => 'TimelineFetchCountryTimeline { countryCode: $countryCode, dateFrom: $dateFrom, dateTo: $dateTo }';
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,17 @@ abstract class TimelineState extends Equatable {

class TimelineUninitialized extends TimelineState {
@override
String toString() {
return 'TImelineUninitialized { }';
}
String toString() => 'TImelineUninitialized { }';
}

class TimelineLoading extends TimelineState {
@override
String toString() {
return 'TimelineLoading { }';
}
String toString() => 'TimelineLoading { }';
}

class TimelineInitialized extends TimelineState {
@override
String toString() {
return 'TimelineInitialized { }';
}
String toString() => 'TimelineInitialized { }';
}

class TimelineError extends TimelineState {
Expand All @@ -40,9 +34,7 @@ class TimelineError extends TimelineState {
List<Object> get props => [error];

@override
String toString() {
return 'TimelineError { error: $error }';
}
String toString() => 'TimelineError { error: $error }';
}

class TimelineFetchedGlobalTimeline extends TimelineState {
Expand All @@ -54,9 +46,7 @@ class TimelineFetchedGlobalTimeline extends TimelineState {
List<Object> get props => [globalTimeline];

@override
String toString() {
return 'TimelineFetchedGlobalTimeline { globalTimeline: $globalTimeline }';
}
String toString() => 'TimelineFetchedGlobalTimeline { globalTimeline: $globalTimeline }';
}

class TimelineFetchedCountryTimeline extends TimelineState {
Expand All @@ -68,8 +58,5 @@ class TimelineFetchedCountryTimeline extends TimelineState {
List<Object> get props => [countryTimeline];

@override
String toString() {
return 'TimelineFetchedCountryTimeline { countryTimeline: $countryTimeline }';
}

}
String toString() => 'TimelineFetchedCountryTimeline { countryTimeline: $countryTimeline }';
}
23 changes: 20 additions & 3 deletions frontend/coronavirus_visualizer/lib/src/services/countries.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@


import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

class Country {
class Country extends Equatable {
final String name;
final String code;

@override
List get props => [name, code];

Country({@required this.name, @required this.code});

Country.fromJson(Map<String, dynamic> json): name = json['name'], code = json['code'];

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['code'] = this.code;
return data;
}

@override
String toString() {
return 'Country { name: $name, code: $code }';
}
}

class CountriesService {
Expand Down
Loading

0 comments on commit 6f9edc0

Please sign in to comment.