diff --git a/examples/fitness/lib/fitness_item.dart b/examples/fitness/lib/fitness_item.dart index 5ad4193ea99..34e71c6e0bb 100644 --- a/examples/fitness/lib/fitness_item.dart +++ b/examples/fitness/lib/fitness_item.dart @@ -9,11 +9,15 @@ typedef void FitnessItemHandler(FitnessItem item); const double kFitnessItemHeight = 79.0; abstract class FitnessItem { + FitnessItem.fromJson(Map json) : when = DateTime.parse(json['when']); + FitnessItem({ this.when }) { assert(when != null); } final DateTime when; + Map toJson() => { 'when' : when.toIso8601String() }; + // TODO(jackson): Internationalize String get displayDate => "${when.year.toString()}-${when.month.toString().padLeft(2,'0')}-${when.day.toString().padLeft(2,'0')}"; diff --git a/examples/fitness/lib/main.dart b/examples/fitness/lib/main.dart index ca7dfafbcf7..debf33ef31c 100644 --- a/examples/fitness/lib/main.dart +++ b/examples/fitness/lib/main.dart @@ -8,6 +8,7 @@ import 'package:sky/editing/input.dart'; import 'package:sky/painting/text_style.dart'; import 'package:sky/theme/colors.dart' as colors; import 'package:sky/widgets.dart'; +import 'user_data.dart'; part 'feed.dart'; part 'fitness_item.dart'; @@ -19,10 +20,21 @@ part 'settings.dart'; class FitnessApp extends App { NavigationState _navigationState; - final List _userData = [ - new Measurement(weight: 180.0, when: new DateTime.now().add(const Duration(days: -1))), - new Measurement(weight: 160.0, when: new DateTime.now()), - ]; + final List _userData = []; + + void didMount() { + super.didMount(); + loadFitnessData().then((List list) { + setState(() { + _userData.addAll(list); + }); + }).catchError((e) => print("Failed to load data: $e")); + } + + void save() { + saveFitnessData(_userData) + .catchError((e) => print("Failed to load data: $e")); + } void initState() { _navigationState = new NavigationState([ @@ -71,12 +83,14 @@ class FitnessApp extends App { setState(() { _userData.add(item); _userData.sort((a, b) => a.when.compareTo(b.when)); + save(); }); } void _handleItemDeleted(FitnessItem item) { setState(() { _userData.remove(item); + saveFitnessData(_userData); }); } diff --git a/examples/fitness/lib/measurement.dart b/examples/fitness/lib/measurement.dart index 8bbbfad0fec..359109f2847 100644 --- a/examples/fitness/lib/measurement.dart +++ b/examples/fitness/lib/measurement.dart @@ -6,12 +6,20 @@ part of fitness; class Measurement extends FitnessItem { Measurement({ DateTime when, this.weight }) : super(when: when); + Measurement.fromJson(Map json) : super.fromJson(json), weight = json['weight']; final double weight; // TODO(jackson): Internationalize String get displayWeight => "${weight.toStringAsFixed(2)} lbs"; + @override + Map toJson() { + Map json = super.toJson(); + json['weight'] = weight; + return json; + } + FitnessItemRow toRow({ FitnessItemHandler onDismissed }) { return new MeasurementRow(measurement: this, onDismissed: onDismissed); } diff --git a/examples/fitness/lib/user_data.dart b/examples/fitness/lib/user_data.dart new file mode 100644 index 00000000000..1bec1d38120 --- /dev/null +++ b/examples/fitness/lib/user_data.dart @@ -0,0 +1,44 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; +import 'dart:async'; + +import 'package:path/path.dart' as path; + +import 'main.dart'; +import 'package:sky/mojo/activity.dart'; + +String cachedDataFilePath = null; + +Future dataFilePath() async { + if (cachedDataFilePath == null) { + String dataDir = await getFilesDir(); + cachedDataFilePath = path.join(dataDir, 'data.json'); + } + return cachedDataFilePath; +} + +Future> loadFitnessData() async { + List items = []; + String dataPath = await dataFilePath(); + print("Loading from $dataPath"); + JsonDecoder decoder = new JsonDecoder(); + var data = await decoder.convert(await new File(dataPath).readAsString()); + data.forEach((item) { + items.add(new Measurement.fromJson(item)); + }); + return items; +} + +// Intentionally synchronous for execution just before shutdown. +Future saveFitnessData(List data) async { + String dataPath = await dataFilePath(); + print("Saving to $dataPath"); + JsonEncoder encoder = new JsonEncoder(); + String contents = await encoder.convert(data); + File dataFile = await new File(dataPath).writeAsString(contents); + print("Success! $dataFile"); +} diff --git a/examples/fitness/pubspec.yaml b/examples/fitness/pubspec.yaml new file mode 100644 index 00000000000..a24792ae8de --- /dev/null +++ b/examples/fitness/pubspec.yaml @@ -0,0 +1,10 @@ +name: fitness +dependencies: + sky: any + sky_tools: any +dependency_overrides: + path: "^1.3.6" + material_design_icons: + path: ../../sky/packages/material_design_icons + sky: + path: ../../sky/packages/sky diff --git a/sky/packages/sky/lib/mojo/activity.dart b/sky/packages/sky/lib/mojo/activity.dart index 8be46a1e67b..5026b96db8c 100644 --- a/sky/packages/sky/lib/mojo/activity.dart +++ b/sky/packages/sky/lib/mojo/activity.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:sky'; +import 'dart:async'; import 'package:sky/mojo/shell.dart' as shell; import 'package:sky_services/activity/activity.mojom.dart'; @@ -53,3 +54,7 @@ void updateTaskDescription(String label, Color color) { _activity.ptr.setTaskDescription(description); } + +Future getFilesDir() async => (await _activity.ptr.getFilesDir()).path; + +Future getCacheDir() async => (await _activity.ptr.getCacheDir()).path;