Skip to content

Commit

Permalink
Improved app performances
Browse files Browse the repository at this point in the history
  • Loading branch information
rafoolin committed Oct 10, 2020
1 parent 6635c08 commit b9cfda5
Show file tree
Hide file tree
Showing 21 changed files with 1,945 additions and 1,398 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This project is very simple and I did my best to add comments for almost every s
- [x] Dark/Light Theme(Rxdart).
- [x] Dynamic Theme based on the weather condition(Rxdart).
- [x] Handle exceptions.(a very simple one)
- [ ] Add a history page for forecasts on previous dates.

# Build

Expand Down
1 change: 1 addition & 0 deletions lib/src/blocs/preference_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class PreferencesBloc extends Bloc {
/// `current` is the current location key.
///
/// `places` is the other places key.
//TODO: Isn't Used, delete it if is useless
get currentLocationPlacesStream =>
Rx.combineLatest2<List<String>, String, Map<String, dynamic>>(
_places.stream,
Expand Down
44 changes: 18 additions & 26 deletions lib/src/my_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,19 @@ class MyApp extends StatelessWidget {
..fetchTemperature()
..fetchDistance()
..fetchPressure()
..fetchWind();
..fetchWind()
..fetchPlaces();
ForecastBloc forecastBloc = ForecastBloc(preferencesBloc: prefBloc);
return BlocProvider(
bloc: prefBloc,
child: BlocProvider(
bloc: forecastBloc,
child: StreamBuilder(
stream: forecastBloc.climateColorStream,
builder: (context, colorSnapshot) {
return StreamBuilder(
stream: prefBloc.themeStream,
builder: (context, snapshot) {
ThemeData theme = snapshot.hasData
? snapshot.data ? darkTheme : lightTheme
: lightTheme;
return MaterialApp(
// Color of accentColor matches the weather condition
theme: theme.copyWith(accentColor: colorSnapshot.data),
onGenerateRoute: _onGenerateRoute,
);
},
child: StreamBuilder<ThemeData>(
stream: prefBloc.themeStream,
builder: (context, themeSnapshot) {
return MaterialApp(
theme: themeSnapshot.data ?? lightTheme,
onGenerateRoute: _onGenerateRoute,
);
},
),
Expand All @@ -60,55 +52,55 @@ class MyApp extends StatelessWidget {
// SettingsPage
case SettingsPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => SettingsPage(),
builder: (BuildContext context) => const SettingsPage(),
);
break;
// LocationPage
case LocationPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => LocationPage(),
builder: (BuildContext context) => const LocationPage(),
);
break;
// LocationConfigPage
case LocationConfigPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => LocationConfigPage(),
builder: (BuildContext context) => const LocationConfigPage(),
);
break;
// TempPage
case TempPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => TempPage(),
builder: (BuildContext context) => const TempPage(),
);
break;
// WindPage
case WindPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => WindPage(),
builder: (BuildContext context) => const WindPage(),
);
break;
// PressurePage
case PressurePage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => PressurePage(),
builder: (BuildContext context) => const PressurePage(),
);
break;
// DistancePage
case DistancePage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => DistancePage(),
builder: (BuildContext context) => const DistancePage(),
);
break;
// TimezonePage
case TimezonePage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => TimezonePage(),
builder: (BuildContext context) => const TimezonePage(),
);
break;
// EmptyPage
case EmptyPage.routeName:
return MaterialPageRoute(
builder: (BuildContext context) => EmptyPage(),
builder: (BuildContext context) => const EmptyPage(),
);
break;
// CustomLicensePage
Expand All @@ -135,7 +127,7 @@ class MyApp extends StatelessWidget {
case SplashPage.routeName:
default:
return MaterialPageRoute(
builder: (BuildContext context) => SplashPage(),
builder: (BuildContext context) => const SplashPage(),
);
}
}
Expand Down
150 changes: 97 additions & 53 deletions lib/src/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,107 @@ class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
ForecastBloc bloc = BlocProvider.of<ForecastBloc>(context);

return StreamBuilder<ConsolidatedWeather>(
stream: bloc.todayForecastStream,
builder:
(BuildContext context, AsyncSnapshot<ConsolidatedWeather> snapshot) {
if (snapshot.hasError) {
if (snapshot.error is EmptyLocationException) return EmptyPage();
if (snapshot.error is NoInternetException)
return ExceptionPage(exception: snapshot.error);
return ExceptionPage(
exception: Exception('Sorry something went wrong o _ O'),
);
}
return Scaffold(
drawer: const CustomDrawer(),
body: CustomScrollView(
slivers: [
SliverPersistentHeader(
floating: false,
delegate:
PersistHeader(height: MediaQuery.of(context).size.height),
pinned: true,
),
SliverToBoxAdapter(child: const SizedBox(height: 16.0)),
SliverToBoxAdapter(child: const WeatherStatus()),
SliverToBoxAdapter(child: const SizedBox(height: 16.0)),
SliverToBoxAdapter(child: const WeekForecast()),
SliverToBoxAdapter(child: const SizedBox(height: 48.0)),
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'DETAILS',
style: Theme.of(context)
.textTheme
.headline4
.copyWith(fontWeight: FontWeight.w700, fontSize: 30),
return Scaffold(
drawer: const CustomDrawer(),
body: RefreshIndicator(
onRefresh: () async => Future.delayed(Duration(milliseconds: 200))
.then((value) => bloc.fetchForecast()),
child: StreamBuilder<ConsolidatedWeather>(
stream: bloc.todayForecastStream,
builder: (BuildContext context,
AsyncSnapshot<ConsolidatedWeather> snapshot) {
if (snapshot.hasError) {
if (snapshot.error is EmptyLocationException)
return const EmptyPage();
if (snapshot.error is NoInternetException)
return ExceptionPage(exception: snapshot.error);
return ExceptionPage(
exception: Exception('Sorry something went wrong o _ O'),
);
}
return CustomScrollView(
slivers: [
SliverPersistentHeader(
floating: false,
delegate: PersistHeader(
height: MediaQuery.of(context).size.height,
),
pinned: true,
),
SliverToBoxAdapter(child: const SizedBox(height: 16.0)),
SliverToBoxAdapter(child: const WeatherStatus()),
SliverToBoxAdapter(child: const SizedBox(height: 16.0)),
SliverToBoxAdapter(child: const WeekForecast()),
SliverToBoxAdapter(child: const SizedBox(height: 48.0)),
SliverToBoxAdapter(child: const DetailsHeader()),
SliverToBoxAdapter(child: const ForecastDetails()),
SliverToBoxAdapter(child: const SizedBox(height: 36.0)),
SliverToBoxAdapter(child: const SourcesHeader()),
SliverToBoxAdapter(child: const Sources()),
],
);
},
),
),
);
}
}

// --------------------------------- DetailsHeader ---------------------------------
class DetailsHeader extends StatelessWidget {
const DetailsHeader();
@override
Widget build(BuildContext context) {
// print('DetailsHeader');
PreferencesBloc prefBloc = BlocProvider.of<PreferencesBloc>(context);
return StreamBuilder<ThemeData>(
stream: prefBloc.themeStream,
builder: (context, themeSnapshot) {
switch (themeSnapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.done:
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'DETAILS',
style: themeSnapshot.data.textTheme.headline4
.copyWith(fontWeight: FontWeight.w700, fontSize: 30),
),
SliverToBoxAdapter(child: const ForecastDetails()),
SliverToBoxAdapter(child: const SizedBox(height: 36.0)),
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Sources',
style: Theme.of(context)
.textTheme
.headline4
.copyWith(fontWeight: FontWeight.w700, fontSize: 30),
),
),
);
break;
default:
return Container();
}
},
);
}
}

// --------------------------------- SourcesHeader ---------------------------------
class SourcesHeader extends StatelessWidget {
const SourcesHeader();
@override
Widget build(BuildContext context) {
// print('SourcesHeader');
PreferencesBloc prefBloc = BlocProvider.of<PreferencesBloc>(context);
return StreamBuilder<ThemeData>(
stream: prefBloc.themeStream,
builder: (context, themeSnapshot) {
switch (themeSnapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.done:
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Sources',
style: themeSnapshot.data.textTheme.headline4
.copyWith(fontWeight: FontWeight.w700, fontSize: 30),
),
SliverToBoxAdapter(child: const Sources()),
],
),
);
);
break;
default:
return Container();
}
},
);
}
Expand Down
Loading

0 comments on commit b9cfda5

Please sign in to comment.