Port stocks to fn3 and introduce an App component.
diff --git a/examples/stocks/lib/main.dart b/examples/stocks/lib/main.dart
index a70739b..aaacab0 100644
--- a/examples/stocks/lib/main.dart
+++ b/examples/stocks/lib/main.dart
@@ -10,7 +10,8 @@
import 'package:sky/animation.dart';
import 'package:sky/material.dart';
-import 'package:sky/widgets.dart';
+import 'package:sky/painting.dart';
+import 'package:sky/src/fn3.dart';
import 'stock_data.dart';
@@ -22,53 +23,16 @@
part 'stock_settings.dart';
part 'stock_types.dart';
-class StocksApp extends App {
+class StocksApp extends StatefulComponent {
+ StocksAppState createState() => new StocksAppState();
+}
- NavigationState _navigationState;
-
- void initState() {
- _navigationState = new NavigationState([
- new Route(
- name: '/',
- builder: (navigator, route) => new StockHome(navigator, _stocks, optimismSetting, modeUpdater)
- ),
- new Route(
- name: '/settings',
- builder: (navigator, route) => new StockSettings(navigator, optimismSetting, backupSetting, settingsUpdater)
- ),
- ]);
- super.initState();
- }
-
- void onBack() {
- if (_navigationState.hasPrevious()) {
- setState(() {
- _navigationState.pop();
- });
- } else {
- super.onBack();
- }
- }
-
- StockMode optimismSetting = StockMode.optimistic;
- BackupMode backupSetting = BackupMode.disabled;
- void modeUpdater(StockMode optimism) {
- setState(() {
- optimismSetting = optimism;
- });
- }
- void settingsUpdater({ StockMode optimism, BackupMode backup }) {
- setState(() {
- if (optimism != null)
- optimismSetting = optimism;
- if (backup != null)
- backupSetting = backup;
- });
- }
+class StocksAppState extends State<StocksApp> {
final List<Stock> _stocks = [];
- void didMount() {
- super.didMount();
+
+ void initState(BuildContext context) {
+ super.initState(context);
new StockDataFetcher((StockData data) {
setState(() {
data.appendTo(_stocks);
@@ -76,32 +40,47 @@
});
}
- Widget build() {
+ StockMode _optimismSetting = StockMode.optimistic;
+ BackupMode _backupSetting = BackupMode.disabled;
+ void modeUpdater(StockMode optimism) {
+ setState(() {
+ _optimismSetting = optimism;
+ });
+ }
+ void settingsUpdater({ StockMode optimism, BackupMode backup }) {
+ setState(() {
+ if (optimism != null)
+ _optimismSetting = optimism;
+ if (backup != null)
+ _backupSetting = backup;
+ });
+ }
- ThemeData theme;
- if (optimismSetting == StockMode.optimistic) {
- theme = new ThemeData(
- brightness: ThemeBrightness.light,
- primarySwatch: Colors.purple
- );
- } else {
- theme = new ThemeData(
- brightness: ThemeBrightness.dark,
- accentColor: Colors.redAccent[200]
- );
+ ThemeData get theme {
+ switch (_optimismSetting) {
+ case StockMode.optimistic:
+ return new ThemeData(
+ brightness: ThemeBrightness.light,
+ primarySwatch: Colors.purple
+ );
+ case StockMode.pessimistic:
+ return new ThemeData(
+ brightness: ThemeBrightness.dark,
+ accentColor: Colors.redAccent[200]
+ );
}
+ }
- return new Theme(
- data: theme,
- child: new DefaultTextStyle(
- style: Typography.error, // if you see this, you've forgotten to correctly configure the text style!
- child: new Title(
- title: 'Stocks',
- child: new Navigator(_navigationState)
- )
- )
- );
- }
+ Widget build(BuildContext context) {
+ return new App(
+ title: 'Stocks',
+ theme: theme,
+ routes: <String, RouteBuilder>{
+ '/': (navigator, route) => new StockHome(navigator, _stocks, _optimismSetting, modeUpdater),
+ '/settings': (navigator, route) => new StockSettings(navigator, _optimismSetting, _backupSetting, settingsUpdater)
+ }
+ );
+ }
}
void main() {
diff --git a/examples/stocks/lib/stock_arrow.dart b/examples/stocks/lib/stock_arrow.dart
index 394eda3..a1f56b5 100644
--- a/examples/stocks/lib/stock_arrow.dart
+++ b/examples/stocks/lib/stock_arrow.dart
@@ -4,8 +4,7 @@
part of stocks;
-class StockArrow extends Component {
-
+class StockArrow extends StatelessComponent {
StockArrow({ Key key, this.percentChange }) : super(key: key);
final double percentChange;
@@ -22,7 +21,7 @@
return Colors.red[_colorIndexForPercentChange(percentChange)];
}
- Widget build() {
+ Widget build(BuildContext context) {
// TODO(jackson): This should change colors with the theme
Color color = _colorForPercentChange(percentChange);
const double kSize = 40.0;
@@ -65,5 +64,4 @@
margin: const EdgeDims.symmetric(horizontal: 5.0)
);
}
-
}
diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart
index c85dd54..ee47f6e 100644
--- a/examples/stocks/lib/stock_home.dart
+++ b/examples/stocks/lib/stock_home.dart
@@ -9,20 +9,17 @@
const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200);
class StockHome extends StatefulComponent {
-
StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater);
- Navigator navigator;
- List<Stock> stocks;
- StockMode stockMode;
- ModeUpdater modeUpdater;
+ final NavigatorState navigator;
+ final List<Stock> stocks;
+ final StockMode stockMode;
+ final ModeUpdater modeUpdater;
- void syncConstructorArguments(StockHome source) {
- navigator = source.navigator;
- stocks = source.stocks;
- stockMode = source.stockMode;
- modeUpdater = source.modeUpdater;
- }
+ StockHomeState createState() => new StockHomeState();
+}
+
+class StockHomeState extends State<StockHome> {
bool _isSearching = false;
String _searchQuery;
@@ -31,7 +28,7 @@
bool _isSnackBarShowing = false;
void _handleSearchBegin() {
- navigator.pushState(this, (_) {
+ config.navigator.pushState(this, (_) {
setState(() {
_isSearching = false;
_searchQuery = null;
@@ -43,9 +40,9 @@
}
void _handleSearchEnd() {
- assert(navigator.currentRoute is RouteState);
- assert((navigator.currentRoute as RouteState).owner == this); // TODO(ianh): remove cast once analyzer is cleverer
- navigator.pop();
+ assert(config.navigator.currentRoute is RouteState);
+ assert((config.navigator.currentRoute as RouteState).owner == this); // TODO(ianh): remove cast once analyzer is cleverer
+ config.navigator.pop();
setState(() {
_isSearching = false;
_searchQuery = null;
@@ -82,15 +79,12 @@
}
void _handleStockModeChange(StockMode value) {
- setState(() {
- stockMode = value;
- });
- if (modeUpdater != null)
- modeUpdater(value);
+ if (config.modeUpdater != null)
+ config.modeUpdater(value);
}
void _handleMenuShow() {
- showStockMenu(navigator,
+ showStockMenu(config.navigator,
autorefresh: _autorefresh,
onAutorefreshChanged: _handleAutorefreshChanged
);
@@ -104,7 +98,7 @@
level: 3,
showing: _drawerShowing,
onDismissed: _handleDrawerDismissed,
- navigator: navigator,
+ navigator: config.navigator,
children: [
new DrawerHeader(child: new Text('Stocks')),
new DrawerItem(
@@ -122,7 +116,7 @@
onPressed: () => _handleStockModeChange(StockMode.optimistic),
child: new Row([
new Flexible(child: new Text('Optimistic')),
- new Radio(value: StockMode.optimistic, groupValue: stockMode, onChanged: _handleStockModeChange)
+ new Radio(value: StockMode.optimistic, groupValue: config.stockMode, onChanged: _handleStockModeChange)
])
),
new DrawerItem(
@@ -130,7 +124,7 @@
onPressed: () => _handleStockModeChange(StockMode.pessimistic),
child: new Row([
new Flexible(child: new Text('Pessimistic')),
- new Radio(value: StockMode.pessimistic, groupValue: stockMode, onChanged: _handleStockModeChange)
+ new Radio(value: StockMode.pessimistic, groupValue: config.stockMode, onChanged: _handleStockModeChange)
])
),
new DrawerDivider(),
@@ -146,23 +140,26 @@
}
void _handleShowSettings() {
- navigator.pop();
- navigator.pushNamed('/settings');
+ config.navigator.pop();
+ config.navigator.pushNamed('/settings');
}
Widget buildToolBar() {
return new ToolBar(
left: new IconButton(
icon: "navigation/menu",
- onPressed: _handleOpenDrawer),
+ onPressed: _handleOpenDrawer
+ ),
center: new Text('Stocks'),
right: [
new IconButton(
icon: "action/search",
- onPressed: _handleSearchBegin),
+ onPressed: _handleSearchBegin
+ ),
new IconButton(
icon: "navigation/more_vert",
- onPressed: _handleMenuShow)
+ onPressed: _handleMenuShow
+ )
]
);
}
@@ -181,12 +178,12 @@
return stocks.where((stock) => stock.symbol.contains(regexp));
}
- Widget buildMarketStockList() {
- return new Stocklist(stocks: _filterBySearchQuery(stocks).toList());
+ Widget buildMarketStockList(BuildContext context) {
+ return new Stocklist(stocks: _filterBySearchQuery(config.stocks).toList());
}
- Widget buildPortfolioStocklist() {
- return new Stocklist(stocks: _filterBySearchQuery(_filterByPortfolio(stocks)).toList());
+ Widget buildPortfolioStocklist(BuildContext context) {
+ return new Stocklist(stocks: _filterBySearchQuery(_filterByPortfolio(config.stocks)).toList());
}
Widget buildTabNavigator() {
@@ -216,7 +213,7 @@
return new ToolBar(
left: new IconButton(
icon: "navigation/arrow_back",
- color: Theme.of(this).accentColor,
+ color: Theme.of(context).accentColor,
onPressed: _handleSearchEnd
),
center: new Input(
@@ -224,7 +221,7 @@
placeholder: 'Search stocks',
onChanged: _handleSearchQueryChanged
),
- backgroundColor: Theme.of(this).canvasColor
+ backgroundColor: Theme.of(context).canvasColor
);
}
@@ -255,17 +252,14 @@
}
Widget buildFloatingActionButton() {
- return new TransitionProxy(
- transitionKey: snackBarKey,
- child: new FloatingActionButton(
- child: new Icon(type: 'content/add', size: 24),
- backgroundColor: Colors.redAccent[200],
- onPressed: _handleStockPurchased
- )
+ return new FloatingActionButton(
+ child: new Icon(type: 'content/add', size: 24),
+ backgroundColor: Colors.redAccent[200],
+ onPressed: _handleStockPurchased
);
}
- Widget build() {
+ Widget build(BuildContext context) {
return new Scaffold(
toolbar: _isSearching ? buildSearchBar() : buildToolBar(),
body: buildTabNavigator(),
diff --git a/examples/stocks/lib/stock_list.dart b/examples/stocks/lib/stock_list.dart
index 42ea384..a65d735 100644
--- a/examples/stocks/lib/stock_list.dart
+++ b/examples/stocks/lib/stock_list.dart
@@ -4,18 +4,18 @@
part of stocks;
-class Stocklist extends Component {
+class Stocklist extends StatelessComponent {
Stocklist({ Key key, this.stocks }) : super(key: key);
final List<Stock> stocks;
- Widget build() {
+ Widget build(BuildContext context) {
return new Material(
type: MaterialType.canvas,
child: new ScrollableList<Stock>(
items: stocks,
itemExtent: StockRow.kHeight,
- itemBuilder: (Stock stock) => new StockRow(stock: stock)
+ itemBuilder: (BuildContext context, Stock stock) => new StockRow(stock: stock)
)
);
}
diff --git a/examples/stocks/lib/stock_menu.dart b/examples/stocks/lib/stock_menu.dart
index a61073a..f9c3278 100644
--- a/examples/stocks/lib/stock_menu.dart
+++ b/examples/stocks/lib/stock_menu.dart
@@ -4,19 +4,27 @@
part of stocks;
-Future showStockMenu(Navigator navigator, { bool autorefresh, ValueChanged onAutorefreshChanged }) {
- return showMenu(
+enum _MenuItems { add, remove, autorefresh }
+
+Future showStockMenu(NavigatorState navigator, { bool autorefresh, ValueChanged onAutorefreshChanged }) async {
+ switch (await showMenu(
navigator: navigator,
position: new MenuPosition(
right: sky.view.paddingRight,
top: sky.view.paddingTop
),
- builder: (Navigator navigator) {
+ builder: (NavigatorState navigator) {
return <PopupMenuItem>[
- new PopupMenuItem(child: new Text('Add stock')),
- new PopupMenuItem(child: new Text('Remove stock')),
new PopupMenuItem(
- onPressed: () => onAutorefreshChanged(!autorefresh),
+ value: _MenuItems.add,
+ child: new Text('Add stock')
+ ),
+ new PopupMenuItem(
+ value: _MenuItems.remove,
+ child: new Text('Remove stock')
+ ),
+ new PopupMenuItem(
+ value: _MenuItems.autorefresh,
child: new Row([
new Flexible(child: new Text('Autorefresh')),
new Checkbox(
@@ -28,5 +36,28 @@
),
];
}
- );
+ )) {
+ case _MenuItems.autorefresh:
+ onAutorefreshChanged(!autorefresh);
+ break;
+ case _MenuItems.add:
+ case _MenuItems.remove:
+ await showDialog(navigator, (NavigatorState navigator) {
+ return new Dialog(
+ title: new Text('Not Implemented'),
+ content: new Text('This feature has not yet been implemented.'),
+ actions: [
+ new FlatButton(
+ child: new Text('OH WELL'),
+ onPressed: () {
+ navigator.pop(false);
+ }
+ ),
+ ]
+ );
+ });
+ break;
+ default:
+ // menu was canceled.
+ }
}
\ No newline at end of file
diff --git a/examples/stocks/lib/stock_row.dart b/examples/stocks/lib/stock_row.dart
index f2f4e68..4ebe859 100644
--- a/examples/stocks/lib/stock_row.dart
+++ b/examples/stocks/lib/stock_row.dart
@@ -4,15 +4,14 @@
part of stocks;
-class StockRow extends Component {
-
+class StockRow extends StatelessComponent {
StockRow({ Stock stock }) : this.stock = stock, super(key: new Key(stock.symbol));
final Stock stock;
static const double kHeight = 79.0;
- Widget build() {
+ Widget build(BuildContext context) {
String lastSale = "\$${stock.lastSale.toStringAsFixed(2)}";
String changeInPrice = "${stock.percentChange.toStringAsFixed(2)}%";
@@ -32,7 +31,7 @@
new Flexible(
child: new Text(
changeInPrice,
- style: Theme.of(this).text.caption.copyWith(textAlign: TextAlign.right)
+ style: Theme.of(context).text.caption.copyWith(textAlign: TextAlign.right)
)
)
];
@@ -43,7 +42,7 @@
height: kHeight,
decoration: new BoxDecoration(
border: new Border(
- bottom: new BorderSide(color: Theme.of(this).dividerColor)
+ bottom: new BorderSide(color: Theme.of(context).dividerColor)
)
),
child: new Row([
@@ -55,7 +54,7 @@
child: new Row(
children,
alignItems: FlexAlignItems.baseline,
- textBaseline: DefaultTextStyle.of(this).textBaseline
+ textBaseline: DefaultTextStyle.of(context).textBaseline
)
)
])
diff --git a/examples/stocks/lib/stock_settings.dart b/examples/stocks/lib/stock_settings.dart
index 19f3125..269afe1 100644
--- a/examples/stocks/lib/stock_settings.dart
+++ b/examples/stocks/lib/stock_settings.dart
@@ -10,42 +10,32 @@
});
class StockSettings extends StatefulComponent {
+ const StockSettings(this.navigator, this.optimism, this.backup, this.updater);
- StockSettings(this.navigator, this.optimism, this.backup, this.updater);
+ final NavigatorState navigator;
+ final StockMode optimism;
+ final BackupMode backup;
+ final SettingsUpdater updater;
- Navigator navigator;
- StockMode optimism;
- BackupMode backup;
- SettingsUpdater updater;
+ StockSettingsState createState() => new StockSettingsState();
+}
- void syncConstructorArguments(StockSettings source) {
- navigator = source.navigator;
- optimism = source.optimism;
- backup = source.backup;
- updater = source.updater;
- }
-
+class StockSettingsState extends State<StockSettings> {
void _handleOptimismChanged(bool value) {
- setState(() {
- optimism = value ? StockMode.optimistic : StockMode.pessimistic;
- });
- sendUpdates();
+ sendUpdates(value ? StockMode.optimistic : StockMode.pessimistic, config.backup);
}
void _handleBackupChanged(bool value) {
- setState(() {
- backup = value ? BackupMode.enabled : BackupMode.disabled;
- });
- sendUpdates();
+ sendUpdates(config.optimism, value ? BackupMode.enabled : BackupMode.disabled);
}
void _confirmOptimismChange() {
- switch (optimism) {
+ switch (config.optimism) {
case StockMode.optimistic:
_handleOptimismChanged(false);
break;
case StockMode.pessimistic:
- showDialog(navigator, (navigator) {
+ showDialog(config.navigator, (NavigatorState navigator) {
return new Dialog(
title: new Text("Change mode?"),
content: new Text("Optimistic mode means everything is awesome. Are you sure you can handle that?"),
@@ -72,24 +62,25 @@
}
}
- void sendUpdates() {
- if (updater != null)
- updater(
+ void sendUpdates(StockMode optimism, BackupMode backup) {
+ if (config.updater != null)
+ config.updater(
optimism: optimism,
backup: backup
);
}
- Widget buildToolBar() {
+ Widget buildToolBar(BuildContext context) {
return new ToolBar(
left: new IconButton(
icon: 'navigation/arrow_back',
- onPressed: navigator.pop),
+ onPressed: config.navigator.pop
+ ),
center: new Text('Settings')
);
}
- Widget buildSettingsPane() {
+ Widget buildSettingsPane(BuildContext context) {
// TODO(ianh): Once we have the gesture API hooked up, fix https://github.com/domokit/mojo/issues/281
// (whereby tapping the widgets below causes both the widget and the menu item to fire their callbacks)
return new Material(
@@ -103,15 +94,21 @@
onPressed: () => _confirmOptimismChange(),
child: new Row([
new Flexible(child: new Text('Everything is awesome')),
- new Checkbox(value: optimism == StockMode.optimistic, onChanged: (_) => _confirmOptimismChange()),
+ new Checkbox(
+ value: config.optimism == StockMode.optimistic,
+ onChanged: (_) => _confirmOptimismChange()
+ ),
])
),
new DrawerItem(
icon: 'action/backup',
- onPressed: () { _handleBackupChanged(!(backup == BackupMode.enabled)); },
+ onPressed: () { _handleBackupChanged(!(config.backup == BackupMode.enabled)); },
child: new Row([
new Flexible(child: new Text('Back up stock list to the cloud')),
- new Switch(value: backup == BackupMode.enabled, onChanged: _handleBackupChanged),
+ new Switch(
+ value: config.backup == BackupMode.enabled,
+ onChanged: _handleBackupChanged
+ ),
])
),
])
@@ -120,10 +117,10 @@
);
}
- Widget build() {
+ Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(),
- body: buildSettingsPane()
+ toolbar: buildToolBar(context),
+ body: buildSettingsPane(context)
);
}
}