Skip to content

Commit

Permalink
refactor settings page to use provider
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzabuzaid committed Oct 12, 2019
1 parent 6559e85 commit ee0cb4b
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 109 deletions.
113 changes: 48 additions & 65 deletions lib/app/app.dart
@@ -1,99 +1,82 @@
import 'package:flutter/material.dart';
import 'package:learning_flutter/app/core/constants/index.dart';
import 'package:learning_flutter/app/core/helpers/logger.dart';
import 'package:learning_flutter/app/locator.dart';
import 'package:learning_flutter/app/pages/home/home.view.dart';
import 'package:learning_flutter/app/pages/meals/melas.view.dart';
import 'package:learning_flutter/app/pages/portal/portal.view.dart';
import 'package:learning_flutter/app/pages/settings/index.dart';
import 'package:learning_flutter/app/routes.dart';
import 'package:learning_flutter/app/shared/services/user/user.service.dart';
import 'package:provider/provider.dart';

class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class App extends StatelessWidget {
static final settingBloc = locator<SettingsBloc>();

App({Key key}) : super(key: key) {
settingBloc.getSettings();
}

class _AppState extends State<App> {
lightTheme(BuildContext context) {
ThemeData lightTheme(BuildContext context) {
return ThemeData(
primarySwatch: Colors.red,
brightness: Brightness.light,
);
}

darkTheme(BuildContext context) {
ThemeData darkTheme(BuildContext context) {
return ThemeData(
primarySwatch: Colors.red,
primaryColor: Colors.blue,
brightness: Brightness.dark,
);
}

Brightness mode;
static Brightness get brightness =>
settingBloc.settings.darkMode ? Brightness.dark : Brightness.light;

isLight() {
return mode == Brightness.light;
static isLight() {
return brightness == Brightness.light;
}

void switchTheme(Brightness mode) {
if (this.mode != mode) {
setState(() {
this.mode = mode;
});
}
static switchTheme() {
settingBloc.switchTheme();
}

ThemeData prepareTheme(BuildContext context, bool darkMode) {
final theme = brightness == Brightness.dark ? darkTheme : lightTheme;
return theme(context);
}

@override
Widget build(BuildContext context) {
// The setting should be available after user is logged in
return StreamBuilder(
stream: settingsBloc.settings.stream,
builder: (context, AsyncSnapshot<SettingsModel> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
final data = snapshot.data;
mode = data.darkMode ? Brightness.dark : Brightness.light;
final _themeData = mode == Brightness.dark ? darkTheme : lightTheme;
return ThemeSwitcher(
data: this,
child: MaterialApp(
theme: _themeData(context),
title: AppplicationConstants.appName,
supportedLocales: [
const Locale('en'),
const Locale('ar'),
],
routes: routes,
home: FutureBuilder(
future: User().isAuthenticated(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.data == true ? HomeView() : MealsView();
},
),
// TODO: The setting should be available after user is logged in
return ChangeNotifierProvider<SettingsBloc>(
builder: (_) => settingBloc,
child: Selector<SettingsBloc, bool>(
selector: (buildContext, bloc) {
// TODO: there's an error that the settings is und
return bloc.settings.darkMode;
},
builder: (context, darkMode, child) {
return MaterialApp(
theme: prepareTheme(context, darkMode),
title: AppplicationConstants.appName,
supportedLocales: [
// TODO: setup localization
const Locale('en'),
const Locale('ar'),
],
routes: routes,
home: FutureBuilder(
future: User().isAuthenticated(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.data == true ? HomeView() : PortalView();
},
),
);
});
}
}

class ThemeSwitcher extends InheritedWidget {
final _AppState data;

const ThemeSwitcher({
Key key,
@required this.data,
@required Widget child,
}) : assert(child != null),
super(key: key, child: child);

static _AppState of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(ThemeSwitcher)
as ThemeSwitcher)
.data;
}

@override
bool updateShouldNotify(ThemeSwitcher old) {
return this != old;
},
),
);
}
}
2 changes: 2 additions & 0 deletions lib/app/locator.dart
Expand Up @@ -3,6 +3,7 @@ import 'package:learning_flutter/app/core/auth.service.dart';
import 'package:learning_flutter/app/pages/home/home.bloc.dart';
import 'package:learning_flutter/app/pages/meals/index.dart';
import 'package:learning_flutter/app/pages/menus/index.dart';
import 'package:learning_flutter/app/pages/settings/settings.bloc.dart';

GetIt locator = GetIt();

Expand All @@ -12,4 +13,5 @@ void setupLocator() {
locator.registerSingleton(MealsService());
locator.registerSingleton(HomeBloc());
locator.registerSingleton(MealsBloc());
locator.registerSingleton(SettingsBloc());
}
11 changes: 5 additions & 6 deletions lib/app/pages/home/home.view.dart
Expand Up @@ -13,12 +13,13 @@ import '../../layout/index.dart';
import '../../layout/toolbar.dart';

class HomeBody extends StatelessWidget {
HomeBody({Key key}) : super(key: key);
HomeBody({Key key}) : super(key: key) {
final bloc = locator<HomeBloc>();
bloc.fetchMenus();
}

@override
Widget build(BuildContext context) {
final bloc = locator<HomeBloc>();
bloc.fetchMenus();
return ChangeNotifierProvider<HomeBloc>(
child: Column(
children: <Widget>[
Expand All @@ -27,9 +28,7 @@ class HomeBody extends StatelessWidget {
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: ThemeSwitcher.of(context).isLight()
? Colors.black26
: Colors.transparent,
color: App.isLight() ? Colors.black26 : Colors.transparent,
blurRadius: 100,
),
],
Expand Down
2 changes: 1 addition & 1 deletion lib/app/pages/menus/menus.view.dart
Expand Up @@ -71,7 +71,7 @@ class _MenuPageBodyState extends State<_MenuPageBody> {
trailing: IconButton(
icon: Icon(
EvaIcons.arrowCircleRight,
color: ThemeSwitcher.of(context).mode ==
color: App.brightness ==
Brightness.dark
? Theme.of(context).primaryColorLight
: Theme.of(context).primaryColorDark,
Expand Down
26 changes: 16 additions & 10 deletions lib/app/pages/settings/settings.bloc.dart
@@ -1,16 +1,22 @@
import 'package:learning_flutter/app/core/helpers/bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:learning_flutter/app/pages/settings/index.dart';

class SettingsBloc {
final settings = Bloc<SettingsModel>();
SettingsBloc() {
settings.sink.addStream(settingsService.getSettings().asStream());
class SettingsBloc with ChangeNotifier {
SettingsModel settings;

void presistSettings() async {
await settingsService.setSettings(this.settings);
notifyListeners();
}

setSettings(SettingsModel data) {
settingsService.setSettings(data);
settings.sink.add(data);
void getSettings() async {
settings = await settingsService.getSettings();
notifyListeners();
}
}

final settingsBloc = SettingsBloc();
void switchTheme() async {
settings.darkMode = !settings.darkMode;
presistSettings();
}

}
35 changes: 14 additions & 21 deletions lib/app/pages/settings/settings.view.dart
Expand Up @@ -8,6 +8,7 @@ import 'package:learning_flutter/app/pages/settings/settings.bloc.dart';
import 'package:learning_flutter/app/pages/settings/settings.model.dart';
import 'package:learning_flutter/app/shared/services/user/user.service.dart';
import 'package:learning_flutter/app/widgets/full-width.dart';
import 'package:provider/provider.dart';
import '../../layout/index.dart';
import '../../layout/toolbar.dart';

Expand Down Expand Up @@ -62,38 +63,30 @@ class _Divider extends StatelessWidget {
}

class _SettingBody extends StatelessWidget {
final settingBloc = locator<SettingsBloc>();

@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: settingsBloc.settings.stream,
builder: (context, AsyncSnapshot<SettingsModel> snapshot) {
// FIXME: Make it generic
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
final data = snapshot.data;
logger.w(data.toJson());
return ChangeNotifierProvider<SettingsBloc>(
builder: (_) => settingBloc,
child: Consumer<SettingsBloc>(builder: (context, bloc, child) {
return Column(
children: <Widget>[
SwitchListTile(
value: data.darkMode,
value: bloc.settings.darkMode,
onChanged: (value) {
data.darkMode = value;
ThemeSwitcher.of(context).switchTheme(
value == true ? Brightness.dark : Brightness.light);
settingsBloc.setSettings(data);
bloc.switchTheme();
App.switchTheme();
},
title: _Text('Dark mode'.toUpperCase()),
),
_Divider(),
SwitchListTile(
value: data.notification,
value: bloc.settings.notification,
onChanged: (value) {
data.notification = value;
settingsBloc.setSettings(data);
// TODO: partial argument function
bloc.settings.notification = value;
bloc.presistSettings();
},
title: _Text('notification'.toUpperCase()),
),
Expand Down Expand Up @@ -135,7 +128,7 @@ class _SettingBody extends StatelessWidget {
),
],
);
},
}),
);
}
}
Expand Down

0 comments on commit ee0cb4b

Please sign in to comment.