Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@

import 'package:sky/painting/text_style.dart';
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/card.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/dismissable.dart';
import 'package:sky/widgets/dialog.dart';
import 'package:sky/widgets/drawer.dart';
import 'package:sky/widgets/drawer_divider.dart';
import 'package:sky/widgets/drawer_header.dart';
import 'package:sky/widgets/drawer_item.dart';
import 'package:sky/widgets/flat_button.dart';
import 'package:sky/widgets/floating_action_button.dart';
import 'package:sky/widgets/icon_button.dart';
import 'package:sky/widgets/icon.dart';
Expand All @@ -24,103 +23,60 @@ import 'package:sky/widgets/tool_bar.dart';
import 'package:sky/widgets/widget.dart';

import 'fitness_types.dart';
import 'fitness_item.dart';
import 'measurement.dart';
import 'meal.dart';

class MeasurementList extends Component {
MeasurementList({ Key key, this.measurements, this.onDismissed }) : super(key: key);
class FitnessItemList extends Component {
FitnessItemList({ Key key, this.items, this.onDismissed }) : super(key: key);

final List<Measurement> measurements;
final MeasurementHandler onDismissed;
final List<FitnessItem> items;
final FitnessItemHandler onDismissed;

Widget build() {
return new Material(
type: MaterialType.canvas,
child: new ScrollableList<Measurement>(
items: measurements,
itemHeight: MeasurementRow.kHeight,
itemBuilder: (measurement) => new MeasurementRow(
measurement: measurement,
child: new ScrollableList<FitnessItem>(
items: items,
itemHeight: kFitnessItemHeight,
itemBuilder: (item) => new MeasurementRow(
measurement: item as Measurement,
onDismissed: onDismissed
)
)
);
}
}

class MeasurementRow extends Component {

MeasurementRow({ Measurement measurement, this.onDismissed }) : this.measurement = measurement, super(key: new Key.stringify(measurement.when));

final Measurement measurement;
final MeasurementHandler onDismissed;

static const double kHeight = 79.0;

Widget build() {

List<Widget> children = [
new Flexible(
child: new Text(
measurement.displayWeight,
style: const TextStyle(textAlign: TextAlign.right)
)
),
new Flexible(
child: new Text(
measurement.displayDate,
style: Theme.of(this).text.caption.copyWith(textAlign: TextAlign.right)
)
)
];

return new Dismissable(
key: new Key.stringify(measurement.when),
onDismissed: () => onDismissed(measurement),
child: new Card(
child: new Container(
height: kHeight,
padding: const EdgeDims.all(8.0),
child: new Flex(
children,
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(this).textBaseline
)
)
)
);
}
}

class HomeFragment extends StatefulComponent {

HomeFragment({ this.navigator, this.userData, this.onMeasurementCreated, this.onMeasurementDeleted });
class FeedFragment extends StatefulComponent {
FeedFragment({ this.navigator, this.userData, this.onItemCreated, this.onItemDeleted });

Navigator navigator;
List<Measurement> userData;
MeasurementHandler onMeasurementCreated;
MeasurementHandler onMeasurementDeleted;
List<FitnessItem> userData;
FitnessItemHandler onItemCreated;
FitnessItemHandler onItemDeleted;

FitnessMode _fitnessMode = FitnessMode.measure;
FitnessMode _fitnessMode = FitnessMode.feed;

void initState() {
// if (debug)
// new Timer(new Duration(seconds: 1), dumpState);
super.initState();
}

void syncFields(HomeFragment source) {
void syncFields(FeedFragment source) {
navigator = source.navigator;
userData = source.userData;
onMeasurementCreated = source.onMeasurementCreated;
onMeasurementDeleted = source.onMeasurementDeleted;
onItemCreated = source.onItemCreated;
onItemDeleted = source.onItemDeleted;
}

bool _isShowingSnackBar = false;
bool _isRunning = false;

void _handleFitnessModeChange(FitnessMode value) {
setState(() {
_fitnessMode = value;
_drawerShowing = false;
});
}

Expand All @@ -135,15 +91,15 @@ class HomeFragment extends StatefulComponent {
children: [
new DrawerHeader(children: [new Text('Fitness')]),
new DrawerItem(
icon: 'action/assessment',
onPressed: () => _handleFitnessModeChange(FitnessMode.measure),
selected: _fitnessMode == FitnessMode.measure,
children: [new Text('Measure')]),
icon: 'action/list',
onPressed: () => _handleFitnessModeChange(FitnessMode.feed),
selected: _fitnessMode == FitnessMode.feed,
children: [new Text('Feed')]),
new DrawerItem(
icon: 'maps/directions_run',
onPressed: () => _handleFitnessModeChange(FitnessMode.run),
selected: _fitnessMode == FitnessMode.run,
children: [new Text('Run')]),
icon: 'action/assessment',
onPressed: () => _handleFitnessModeChange(FitnessMode.chart),
selected: _fitnessMode == FitnessMode.chart,
children: [new Text('Chart')]),
new DrawerDivider(),
new DrawerItem(
icon: 'action/settings',
Expand Down Expand Up @@ -180,8 +136,8 @@ class HomeFragment extends StatefulComponent {
// TODO(jackson): We should be localizing
String get fitnessModeTitle {
switch(_fitnessMode) {
case FitnessMode.measure: return "Measure";
case FitnessMode.run: return "Run";
case FitnessMode.feed: return "Feed";
case FitnessMode.chart: return "Chart";
}
}

Expand All @@ -194,47 +150,46 @@ class HomeFragment extends StatefulComponent {
);
}

// TODO(jackson): Pull from file
Measurement _undoMeasurement;
FitnessItem _undoItem;

void _handleMeasurementDismissed(Measurement measurement) {
onMeasurementDeleted(measurement);
void _handleItemDismissed(FitnessItem item) {
onItemDeleted(item);
setState(() {
_undoMeasurement = measurement;
_undoItem = item;
_isShowingSnackBar = true;
});
}

Widget buildBody() {
TextStyle style = Theme.of(this).text.title;
switch (_fitnessMode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be two classes somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it should -- will refactor in a future CL

case FitnessMode.measure:
case FitnessMode.feed:
if (userData.length > 0)
return new MeasurementList(
measurements: userData,
onDismissed: _handleMeasurementDismissed
return new FitnessItemList(
items: userData,
onDismissed: _handleItemDismissed
);
return new Material(
type: MaterialType.canvas,
child: new Flex(
[new Text("No measurements yet.\nAdd a new one!", style: style)],
[new Text("No data yet.\nAdd some!", style: style)],
justifyContent: FlexJustifyContent.center
)
);
case FitnessMode.run:
case FitnessMode.chart:
return new Material(
type: MaterialType.canvas,
child: new Flex([
new Text(_isRunning ? "Go go go!" : "Start a new run!", style: style)
new Text("Charts are coming soon!", style: style)
], justifyContent: FlexJustifyContent.center)
);
}
}

void _handleUndo() {
onMeasurementCreated(_undoMeasurement);
onItemCreated(_undoItem);
setState(() {
_undoMeasurement = null;
_undoItem = null;
_isShowingSnackBar = false;
});
}
Expand All @@ -243,48 +198,72 @@ class HomeFragment extends StatefulComponent {
if (!_isShowingSnackBar)
return null;
return new SnackBar(
content: new Text("Measurement deleted."),
showing: _isShowingSnackBar,
content: new Text("Item deleted."),
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)]
);
}

void _handleRunStarted() {
setState(() {
_isRunning = true;
});
bool _isShowingDialog = false;

Widget buildDialog() {
return new Dialog(
title: new Text("New item"),
content: new Text("What are you trying to do?"),
onDismiss: navigator.pop,
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: navigator.pop
),
new FlatButton(
child: new Text('EAT'),
onPressed: () {
navigator.pop();
navigator.pushNamed("/meals/new");
}
),
new FlatButton(
child: new Text('MEASURE'),
onPressed: () {
navigator.pop();
navigator.pushNamed("/measurements/new");
}
),
]
);
}

void _handleRunStopped() {
void _handleActionButtonPressed() {
setState(() {
_isRunning = false;
_isShowingDialog = true;
});
}

Widget buildFloatingActionButton() {
switch (_fitnessMode) {
case FitnessMode.measure:
case FitnessMode.feed:
return new FloatingActionButton(
child: new Icon(type: 'content/add', size: 24),
onPressed: () => navigator.pushNamed("/measurements/new")
);
case FitnessMode.run:
return new FloatingActionButton(
child: new Icon(
type: _isRunning ? 'av/stop' : 'maps/directions_run',
size: 24
),
onPressed: _isRunning ? _handleRunStopped : _handleRunStarted
onPressed: _handleActionButtonPressed
);
case FitnessMode.chart:
return null;
}
}

Widget build() {
return new Scaffold(
toolbar: buildToolBar(),
body: buildBody(),
snackBar: buildSnackBar(),
floatingActionButton: buildFloatingActionButton(),
drawer: buildDrawer()
);
List<Widget> layers = [
new Scaffold(
toolbar: buildToolBar(),
body: buildBody(),
snackBar: buildSnackBar(),
floatingActionButton: buildFloatingActionButton(),
drawer: buildDrawer()
)
];
if (_isShowingDialog)
layers.add(buildDialog());
return new Stack(layers);
}
}
46 changes: 46 additions & 0 deletions sky/sdk/example/fitness/lib/fitness_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/card.dart';
import 'package:sky/widgets/dismissable.dart';

typedef void FitnessItemHandler(FitnessItem item);

const double kFitnessItemHeight = 79.0;

class FitnessItem {
FitnessItem({ this.when }) {
assert(when != null);
}
final DateTime when;

// TODO(jackson): Internationalize
String get displayDate => "${when.year.toString()}-${when.month.toString().padLeft(2,'0')}-${when.day.toString().padLeft(2,'0')}";
}

abstract class FitnessItemRow extends Component {

FitnessItemRow({ FitnessItem item, this.onDismissed })
: this.item = item,
super(key: new Key(item.when.toString()));

final FitnessItem item;
final FitnessItemHandler onDismissed;

Widget buildContent();

Widget build() {
return new Dismissable(
onDismissed: () => onDismissed(item),
child: new Card(
child: new Container(
height: kFitnessItemHeight,
padding: const EdgeDims.all(8.0),
child: buildContent()
)
)
);
}
}
2 changes: 1 addition & 1 deletion sky/sdk/example/fitness/lib/fitness_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

enum FitnessMode { measure, run }
enum FitnessMode { feed, chart }
enum BackupMode { enabled, disabled }
Loading