main.dart 4.35 KB
Newer Older
1 2 3 4
// 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.

5 6
library fitness;

7
import 'package:playfair/playfair.dart' as playfair;
8 9
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
10
import 'package:gcm/gcm.dart' as gcm;
11

12
import 'user_data.dart';
Eric Seidel's avatar
Eric Seidel committed
13 14
import 'date_utils.dart';
import 'dart:async';
15
import 'dart:math' as math;
16

17 18 19 20 21 22
part 'feed.dart';
part 'fitness_item.dart';
part 'fitness_types.dart';
part 'meal.dart';
part 'measurement.dart';
part 'settings.dart';
23

24 25
abstract class UserData {
  BackupMode get backupMode;
26
  double get goalWeight;
27 28 29 30 31
  List<FitnessItem> get items;
}

class UserDataImpl extends UserData {
  UserDataImpl();
32

Hixie's avatar
Hixie committed
33
  List<FitnessItem> _items = <FitnessItem>[];
Eric Seidel's avatar
Eric Seidel committed
34

35 36
  BackupMode _backupMode;
  BackupMode get backupMode => _backupMode;
37
  void set backupMode(BackupMode value) {
38
    _backupMode = value;
39 40
  }

41 42 43 44
  double _goalWeight;
  double get goalWeight => _goalWeight;
  void set goalWeight(double value) {
    _goalWeight = value;
Eric Seidel's avatar
Eric Seidel committed
45 46
  }

47 48
  List<FitnessItem> get items => _items;

Eric Seidel's avatar
Eric Seidel committed
49
  void sort() {
Hixie's avatar
Hixie committed
50
    _items.sort((FitnessItem a, FitnessItem b) => a.when.compareTo(b.when));
Eric Seidel's avatar
Eric Seidel committed
51 52
  }

53
  void add(FitnessItem item) {
Eric Seidel's avatar
Eric Seidel committed
54 55 56 57
    _items.add(item);
    sort();
  }

58
  void remove(FitnessItem item) {
Eric Seidel's avatar
Eric Seidel committed
59 60 61
    _items.remove(item);
  }

62 63
  Future save() => saveFitnessData(this);

64
  UserDataImpl.fromJson(Map json) {
65 66 67 68
    json['items'].forEach((item) {
      _items.add(new Measurement.fromJson(item));
    });
    try {
69
      _backupMode = BackupMode.values.firstWhere((BackupMode mode) {
70 71 72
        return mode.toString() == json['backupMode'];
      });
    } catch(e) {
Hixie's avatar
Hixie committed
73
      print("Failed to load backup mode: $e");
74
    }
75
    _goalWeight = json['goalWeight'];
76 77 78 79
  }

  Map toJson() {
    Map json = new Map();
Hixie's avatar
Hixie committed
80
    json['items'] = _items.map((FitnessItem item) => item.toJson()).toList();
81
    json['backupMode'] = _backupMode.toString();
82
    json['goalWeight'] = _goalWeight;
83 84
    return json;
  }
Eric Seidel's avatar
Eric Seidel committed
85
}
86

87 88 89 90 91
class FitnessApp extends StatefulComponent {
  FitnessAppState createState() => new FitnessAppState();
}

class FitnessAppState extends State<FitnessApp> {
92
  UserDataImpl _userData;
93

94 95
  void initState() {
    super.initState();
96 97
    loadFitnessData().then((UserData data) {
      setState(() => _userData = data);
98 99 100 101
    }).catchError((e) {
      print("Failed to load data: $e");
      setState(() => _userData = new UserDataImpl());
    });
102 103
  }

104
  void _handleItemCreated(FitnessItem item) {
105 106 107 108
    setState(() {
      _userData.add(item);
      _userData.save();
    });
109 110
  }

111
  void _handleItemDeleted(FitnessItem item) {
112 113 114 115
    setState(() {
      _userData.remove(item);
      _userData.save();
    });
116 117
  }

118
  void settingsUpdater({ BackupMode backup, double goalWeight }) {
119 120
    setState(() {
      if (backup != null)
121 122 123 124
        _userData.backupMode = backup;
      if (goalWeight != null)
        _userData.goalWeight = goalWeight;
      _userData.save();
125 126 127
    });
  }

Hixie's avatar
Hixie committed
128
  Widget build(BuildContext context) {
Adam Barth's avatar
Adam Barth committed
129
    return new MaterialApp(
130 131 132 133 134
      theme: new ThemeData(
        brightness: ThemeBrightness.light,
        primarySwatch: Colors.indigo,
        accentColor: Colors.pinkAccent[200]
      ),
135
      title: 'Fitness',
Hixie's avatar
Hixie committed
136
      routes: <String, RouteBuilder>{
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
        '/': (RouteArguments args) {
          return new FeedFragment(
            userData: _userData,
            onItemCreated: _handleItemCreated,
            onItemDeleted: _handleItemDeleted
          );
        },
        '/meals/new': (RouteArguments args) {
          return new MealFragment(
            onCreated: _handleItemCreated
          );
        },
        '/measurements/new': (RouteArguments args) {
          return new MeasurementFragment(
            onCreated: _handleItemCreated
          );
        },
        '/settings': (RouteArguments args) {
          return new SettingsFragment(
            userData: _userData,
            updater: settingsUpdater
          );
        }
      }
161 162 163 164
    );
  }
}

165 166 167 168 169 170 171 172 173 174 175 176 177
initGcm() async {
  // Register for GCM messages using the senderId provided in the
  // google-services.json we received when registering our app.
  String token;
  token = await gcm.registerGcmService(
      "858790231562", (String from, String message) {
    print("onMessageReceived: $from; $message");
    gcm.unsubscribeTopics(token, ["global"]);
  });
  gcm.subscribeTopics(token, ["global"]);
}

main() {
178
  initGcm();
179 180
  runApp(new FitnessApp());
}