Commit 1217f3b5 authored by Collin Jackson's avatar Collin Jackson

Merge pull request #713 from collinjackson/goalweight

Support for saving goal weight
parents de966121 3e3f6242
...@@ -22,6 +22,7 @@ part 'settings.dart'; ...@@ -22,6 +22,7 @@ part 'settings.dart';
abstract class UserData { abstract class UserData {
BackupMode get backupMode; BackupMode get backupMode;
double get goalWeight;
List<FitnessItem> get items; List<FitnessItem> get items;
} }
...@@ -32,31 +33,29 @@ class UserDataImpl extends UserData { ...@@ -32,31 +33,29 @@ class UserDataImpl extends UserData {
BackupMode _backupMode; BackupMode _backupMode;
BackupMode get backupMode => _backupMode; BackupMode get backupMode => _backupMode;
void setBackupModeAndSave(BackupMode value) { void set backupMode(BackupMode value) {
_backupMode = value; _backupMode = value;
save();
} }
List<FitnessItem> get items => _items; double _goalWeight;
void set items(List<FitnessItem> newItems) { double get goalWeight => _goalWeight;
_items = []; void set goalWeight(double value) {
_items.addAll(newItems); _goalWeight = value;
sort();
} }
List<FitnessItem> get items => _items;
void sort() { void sort() {
_items.sort((a, b) => -a.when.compareTo(b.when)); _items.sort((a, b) => -a.when.compareTo(b.when));
} }
void addAndSave(FitnessItem item) { void add(FitnessItem item) {
_items.add(item); _items.add(item);
sort(); sort();
save();
} }
void removeAndSave(FitnessItem item) { void remove(FitnessItem item) {
_items.remove(item); _items.remove(item);
save();
} }
Future save() => saveFitnessData(this); Future save() => saveFitnessData(this);
...@@ -72,12 +71,14 @@ class UserDataImpl extends UserData { ...@@ -72,12 +71,14 @@ class UserDataImpl extends UserData {
} catch(e) { } catch(e) {
print("Failed to load backup mode: ${e}"); print("Failed to load backup mode: ${e}");
} }
_goalWeight = json['goalWeight'];
} }
Map toJson() { Map toJson() {
Map json = new Map(); Map json = new Map();
json['items'] = _items.map((item) => item.toJson()).toList(); json['items'] = _items.map((item) => item.toJson()).toList();
json['backupMode'] = _backupMode.toString(); json['backupMode'] = _backupMode.toString();
json['goalWeight'] = _goalWeight;
return json; return json;
} }
} }
...@@ -139,17 +140,26 @@ class FitnessApp extends App { ...@@ -139,17 +140,26 @@ class FitnessApp extends App {
} }
void _handleItemCreated(FitnessItem item) { void _handleItemCreated(FitnessItem item) {
setState(() => _userData.addAndSave(item)); setState(() {
_userData.add(item);
_userData.save();
});
} }
void _handleItemDeleted(FitnessItem item) { void _handleItemDeleted(FitnessItem item) {
setState(() => _userData.removeAndSave(item)); setState(() {
_userData.remove(item);
_userData.save();
});
} }
void settingsUpdater({ BackupMode backup }) { void settingsUpdater({ BackupMode backup, double goalWeight }) {
setState(() { setState(() {
if (backup != null) if (backup != null)
_userData.setBackupModeAndSave(backup); _userData.backupMode = backup;
if (goalWeight != null)
_userData.goalWeight = goalWeight;
_userData.save();
}); });
} }
......
...@@ -5,20 +5,35 @@ ...@@ -5,20 +5,35 @@
part of fitness; part of fitness;
typedef void SettingsUpdater({ typedef void SettingsUpdater({
BackupMode backup BackupMode backup,
double goalWeight
}); });
class SettingsFragment extends Component { class SettingsFragment extends StatefulComponent {
SettingsFragment({ this.navigator, this.userData, this.updater }); SettingsFragment({ this.navigator, this.userData, this.updater });
final Navigator navigator; Navigator navigator;
final UserData userData; UserData userData;
final SettingsUpdater updater; SettingsUpdater updater;
void syncFields(SettingsFragment source) {
navigator = source.navigator;
userData = source.userData;
updater = source.updater;
}
void _handleBackupChanged(bool value) { void _handleBackupChanged(bool value) {
if (updater != null) assert(updater != null);
updater(backup: value ? BackupMode.enabled : BackupMode.disabled); updater(backup: value ? BackupMode.enabled : BackupMode.disabled);
}
void _goalWeightChanged(double value) {
assert(updater != null);
setState(() {
optimism = value ? StockMode.optimistic : StockMode.pessimistic;
});
sendUpdates();
} }
Widget buildToolBar() { Widget buildToolBar() {
...@@ -30,6 +45,64 @@ class SettingsFragment extends Component { ...@@ -30,6 +45,64 @@ class SettingsFragment extends Component {
); );
} }
String get goalWeightText {
if (userData.goalWeight == null || userData.goalWeight == 0.0)
return "None";
else
return "${userData.goalWeight}";
}
static final GlobalKey weightGoalKey = new GlobalKey();
double _goalWeight;
void _handleGoalWeightChanged(String goalWeight) {
// TODO(jackson): Looking for null characters to detect enter key is a hack
if (goalWeight.endsWith("\u{0}")) {
navigator.pop(double.parse(goalWeight.replaceAll("\u{0}", "")));
} else {
setState(() {
try {
_goalWeight = double.parse(goalWeight);
} on FormatException {
_goalWeight = 0.0;
}
});
}
}
EventDisposition _handleGoalWeightPressed() {
showDialog(navigator, (navigator) {
return new Dialog(
title: new Text("Goal Weight"),
content: new Input(
key: weightGoalKey,
placeholder: 'Goal weight in lbs',
keyboardType: KeyboardType_NUMBER,
onChanged: _handleGoalWeightChanged
),
onDismiss: () {
navigator.pop();
},
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: () {
navigator.pop();
}
),
new FlatButton(
child: new Text('SAVE'),
onPressed: () {
navigator.pop(_goalWeight);
}
),
]
);
}).then((double goalWeight) => updater(goalWeight: goalWeight));
return EventDisposition.processed;
}
Widget buildSettingsPane() { Widget buildSettingsPane() {
return new Material( return new Material(
type: MaterialType.canvas, type: MaterialType.canvas,
...@@ -43,7 +116,16 @@ class SettingsFragment extends Component { ...@@ -43,7 +116,16 @@ class SettingsFragment extends Component {
new Flexible(child: new Text('Back up data to the cloud')), new Flexible(child: new Text('Back up data to the cloud')),
new Switch(value: userData.backupMode == BackupMode.enabled, onChanged: _handleBackupChanged) new Switch(value: userData.backupMode == BackupMode.enabled, onChanged: _handleBackupChanged)
] ]
) ),
new DrawerItem(
onPressed: () => _handleGoalWeightPressed(),
children: [
new Flex([
new Text('Goal Weight'),
new Text(goalWeightText, style: Theme.of(this).text.caption),
], direction: FlexDirection.vertical, alignItems: FlexAlignItems.start)
]
),
]) ])
) )
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment