Skip to content

Commit

Permalink
Added ViewModel in HomePage
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinusX committed Oct 6, 2017
1 parent f04ed4a commit 8585d0d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 40 deletions.
66 changes: 42 additions & 24 deletions lib/home_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'package:weight_tracker/logic/redux_core.dart';
import 'package:weight_tracker/model/weight_entry.dart';
import 'package:weight_tracker/weight_entry_dialog.dart';
Expand All @@ -16,20 +13,38 @@ class HomePage extends StatefulWidget {
_HomePageState createState() => new _HomePageState();
}

class HomePageViewModel {
//fields
bool hasEntryBeenAdded;
List<WeightEntry> entries;

//functions
var acceptEntryAddedCallback;
var editEntryCallback;
var addEntryCallback;
}

class _HomePageState extends State<HomePage> {
ScrollController _listViewScrollController = new ScrollController();
Store<ReduxState> _store;

@override
Widget build(BuildContext context) {
return new StoreConnector<ReduxState, Null>(
return new StoreConnector<ReduxState, HomePageViewModel>(
converter: (store) {
_store = store;
return new HomePageViewModel()
..hasEntryBeenAdded = store.state.hasEntryBeenAdded
..entries = store.state.entries
..acceptEntryAddedCallback =
(() => store.dispatch(new AcceptEntryAddedAction()))
..addEntryCallback =
((entry) => store.dispatch(new LocalAddAction(entry)))
..editEntryCallback =
((entry) => store.dispatch(new LocalEditAction(entry)));
},
builder: (context, nil) {
if (_store.state.hasEntryBeenAdded) {
builder: (context, viewModel) {
if (viewModel.hasEntryBeenAdded) {
_scrollToTop();
_store.dispatch(new AcceptEntryAddedAction());
viewModel.acceptEntryAddedCallback();
}
return new Scaffold(
appBar: new AppBar(
Expand All @@ -38,22 +53,26 @@ class _HomePageState extends State<HomePage> {
body: new ListView.builder(
shrinkWrap: true,
controller: _listViewScrollController,
itemCount: _store.state.entries.length,
itemCount: viewModel.entries.length,
itemBuilder: (buildContext, index) {
//calculating difference
double difference = index == _store.state.entries.length - 1
double difference = index == viewModel.entries.length - 1
? 0.0
: _store.state.entries[index].weight -
_store.state.entries[index + 1].weight;
: viewModel.entries[index].weight -
viewModel.entries[index + 1].weight;
return new InkWell(
onTap: () =>
_openEditEntryDialog(_store.state.entries[index]),
child: new WeightListItem(
_store.state.entries[index], difference));
_openEditEntryDialog(
viewModel.entries[index],
viewModel.editEntryCallback),
child:
new WeightListItem(viewModel.entries[index], difference));
},
),
floatingActionButton: new FloatingActionButton(
onPressed: _openAddEntryDialog,
onPressed: () =>
_openAddEntryDialog(
viewModel.entries, viewModel.addEntryCallback),
tooltip: 'Add new weight entry',
child: new Icon(Icons.add),
),
Expand All @@ -62,7 +81,7 @@ class _HomePageState extends State<HomePage> {
);
}

_openEditEntryDialog(WeightEntry weightEntry) {
_openEditEntryDialog(WeightEntry weightEntry, onSubmittedCallback) async {
Navigator
.of(context)
.push(
Expand All @@ -76,22 +95,21 @@ class _HomePageState extends State<HomePage> {
.then((WeightEntry newEntry) {
if (newEntry != null) {
newEntry.key = weightEntry.key;
_store.dispatch(new LocalEditAction(newEntry));
onSubmittedCallback(newEntry);
}
});
}

Future _openAddEntryDialog() async {
_openAddEntryDialog(List<WeightEntry> entries, onSubmittedCallback) async {
WeightEntry entry =
await Navigator.of(context).push(new MaterialPageRoute<WeightEntry>(
builder: (BuildContext context) {
return new WeightEntryDialog.add(_store.state.entries.isNotEmpty
? _store.state.entries.first.weight
: 60.0);
return new WeightEntryDialog.add(
entries.isNotEmpty ? entries.first.weight : 60.0);
},
fullscreenDialog: true));
if (entry != null) {
_store.dispatch(new LocalAddAction(entry));
onSubmittedCallback(entry);
}
}

Expand Down
25 changes: 11 additions & 14 deletions lib/logic/redux_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:async';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:redux/redux.dart';
import 'package:weight_tracker/model/weight_entry.dart';

class LocalAddAction {
Expand All @@ -17,11 +16,13 @@ class LocalEditAction {
LocalEditAction(this.weightEntry);
}

typedef void EventCallback(Event event);

class InitAction {
//It is needed so we can invoke methods when we got firebase results
final Store<ReduxState> store;
final EventCallback onEntryAddedCallback;
final EventCallback onEntryEditedCallback;

InitAction(this.store);
InitAction({this.onEntryAddedCallback, this.onEntryEditedCallback});
}

class OnAddedAction {
Expand All @@ -48,8 +49,7 @@ class ReduxState {
ReduxState stateReducer(ReduxState state, action) {
if (action is InitAction) {
FirebaseDatabase.instance.setPersistenceEnabled(true);
_loginAnonymous(action.store.state)
.then((nil) => _updateFirebaseAuth(action.store));
_loginAnonymous(state).then((nil) => _updateFirebaseAuth(state, action));
} else if (action is LocalAddAction) {
_addEntry(state, action.weightEntry);
} else if (action is LocalEditAction) {
Expand All @@ -73,16 +73,13 @@ Future<Null> _loginAnonymous(ReduxState state) async {
}
}

_updateFirebaseAuth(Store<ReduxState> store) async {
store.state.firebaseUser = await FirebaseAuth.instance.currentUser();
store.state.mainReference = FirebaseDatabase.instance
_updateFirebaseAuth(ReduxState state, InitAction action) async {
state.mainReference = FirebaseDatabase.instance
.reference()
.child(store.state.firebaseUser.uid)
.child(state.firebaseUser.uid)
.child("entries");
store.state.mainReference.onChildAdded
.listen((event) => store.dispatch(new OnAddedAction(event)));
store.state.mainReference.onChildChanged
.listen((event) => store.dispatch(new OnChangedAction(event)));
state.mainReference.onChildAdded.listen(action.onEntryAddedCallback);
state.mainReference.onChildChanged.listen(action.onEntryEditedCallback);
}

_addEntry(ReduxState state, WeightEntry entry) {
Expand Down
7 changes: 5 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:redux/redux.dart';
import 'package:weight_tracker/home_page.dart';
import 'package:weight_tracker/logic/redux_core.dart';


void main() {
runApp(new MyApp());
}
Expand All @@ -14,7 +13,11 @@ class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
store.dispatch(new InitAction(store));
store.dispatch(new InitAction(
onEntryAddedCallback: (event) => store.dispatch(new OnAddedAction(event)),
onEntryEditedCallback: (event) =>
store.dispatch(new OnChangedAction(event)),
));
return new MaterialApp(
title: 'Weight Tracker',
theme: new ThemeData(
Expand Down

0 comments on commit 8585d0d

Please sign in to comment.