[Stocks App] NNBD migration, refresh gen-l10n (#79460)
This commit is contained in:
parent
9077a5c69b
commit
1ab20d6f42
@ -16,3 +16,7 @@ output-localization-file: stock_strings.dart
|
|||||||
## generating Flutter's localization files.
|
## generating Flutter's localization files.
|
||||||
synthetic-package: false
|
synthetic-package: false
|
||||||
template-arb-file: stocks_en.arb
|
template-arb-file: stocks_en.arb
|
||||||
|
## setting `nullable-getter` to false generates a non-nullable
|
||||||
|
## StockStrings getter. This removes the need for adding null checks
|
||||||
|
## in the Flutter application itself.
|
||||||
|
nullable-getter: false
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// THE FOLLLOWING FILES WERE GENERATED BY `flutter gen-l10n`.
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// THE FOLLLOWING FILES WERE GENERATED BY `flutter gen-l10n`.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@ -39,7 +41,7 @@ import 'stock_strings_es.dart';
|
|||||||
/// # Internationalization support.
|
/// # Internationalization support.
|
||||||
/// flutter_localizations:
|
/// flutter_localizations:
|
||||||
/// sdk: flutter
|
/// sdk: flutter
|
||||||
/// intl: 0.16.1
|
/// intl: any # Use the pinned version from flutter_localizations
|
||||||
///
|
///
|
||||||
/// # rest of dependencies
|
/// # rest of dependencies
|
||||||
/// ```
|
/// ```
|
||||||
@ -64,12 +66,12 @@ import 'stock_strings_es.dart';
|
|||||||
/// be consistent with the languages listed in the StockStrings.supportedLocales
|
/// be consistent with the languages listed in the StockStrings.supportedLocales
|
||||||
/// property.
|
/// property.
|
||||||
abstract class StockStrings {
|
abstract class StockStrings {
|
||||||
StockStrings(String locale) : assert(locale != null), localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
StockStrings(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||||
|
|
||||||
final String localeName;
|
final String localeName;
|
||||||
|
|
||||||
static StockStrings of(BuildContext context) {
|
static StockStrings of(BuildContext context) {
|
||||||
return Localizations.of<StockStrings>(context, StockStrings);
|
return Localizations.of<StockStrings>(context, StockStrings)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LocalizationsDelegate<StockStrings> delegate = _StockStringsDelegate();
|
static const LocalizationsDelegate<StockStrings> delegate = _StockStringsDelegate();
|
||||||
@ -98,13 +100,22 @@ abstract class StockStrings {
|
|||||||
Locale('es')
|
Locale('es')
|
||||||
];
|
];
|
||||||
|
|
||||||
// Title for the Stocks application
|
/// Title for the Stocks application
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Stocks'**
|
||||||
String get title;
|
String get title;
|
||||||
|
|
||||||
// Label for the Market tab
|
/// Label for the Market tab
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'MARKET'**
|
||||||
String get market;
|
String get market;
|
||||||
|
|
||||||
// Label for the Portfolio tab
|
/// Label for the Portfolio tab
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'PORTFOLIO'**
|
||||||
String get portfolio;
|
String get portfolio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,22 +137,27 @@ class _StockStringsDelegate extends LocalizationsDelegate<StockStrings> {
|
|||||||
StockStrings _lookupStockStrings(Locale locale) {
|
StockStrings _lookupStockStrings(Locale locale) {
|
||||||
|
|
||||||
|
|
||||||
// Lookup logic when language+country codes are specified.
|
// Lookup logic when language+country codes are specified.
|
||||||
switch (locale.languageCode) {
|
switch (locale.languageCode) {
|
||||||
case 'en': {
|
case 'en': {
|
||||||
switch (locale.countryCode) {
|
switch (locale.countryCode) {
|
||||||
case 'US': return StockStringsEnUs();
|
case 'US': return StockStringsEnUs();
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
// Lookup logic when only language code is specified.
|
}
|
||||||
switch (locale.languageCode) {
|
}
|
||||||
case 'en': return StockStringsEn();
|
|
||||||
case 'es': return StockStringsEs();
|
// Lookup logic when only language code is specified.
|
||||||
}
|
switch (locale.languageCode) {
|
||||||
|
case 'en': return StockStringsEn();
|
||||||
assert(false, 'StockStrings.delegate failed to load unsupported locale "$locale"');
|
case 'es': return StockStringsEs();
|
||||||
return null;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
throw FlutterError(
|
||||||
|
'StockStrings.delegate failed to load unsupported locale "$locale". This is likely '
|
||||||
|
'an issue with the localizations generation tool. Please file an issue '
|
||||||
|
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||||
|
'that was used.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// THE FOLLLOWING FILES WERE GENERATED BY `flutter gen-l10n`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'stock_strings.dart';
|
import 'stock_strings.dart';
|
||||||
|
|
||||||
/// The translations for English (`en`).
|
/// The translations for English (`en`).
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// THE FOLLLOWING FILES WERE GENERATED BY `flutter gen-l10n`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'stock_strings.dart';
|
import 'stock_strings.dart';
|
||||||
|
|
||||||
/// The translations for Spanish Castilian (`es`).
|
/// The translations for Spanish Castilian (`es`).
|
||||||
|
@ -20,14 +20,14 @@ import 'stock_symbol_viewer.dart';
|
|||||||
import 'stock_types.dart';
|
import 'stock_types.dart';
|
||||||
|
|
||||||
class StocksApp extends StatefulWidget {
|
class StocksApp extends StatefulWidget {
|
||||||
const StocksApp({Key key}) : super(key: key);
|
const StocksApp({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
StocksAppState createState() => StocksAppState();
|
StocksAppState createState() => StocksAppState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class StocksAppState extends State<StocksApp> {
|
class StocksAppState extends State<StocksApp> {
|
||||||
StockData stocks;
|
late StockData stocks = StockData();
|
||||||
|
|
||||||
StockConfiguration _configuration = StockConfiguration(
|
StockConfiguration _configuration = StockConfiguration(
|
||||||
stockMode: StockMode.optimistic,
|
stockMode: StockMode.optimistic,
|
||||||
@ -42,12 +42,6 @@ class StocksAppState extends State<StocksApp> {
|
|||||||
showSemanticsDebugger: false,
|
showSemanticsDebugger: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
stocks = StockData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void configurationUpdater(StockConfiguration value) {
|
void configurationUpdater(StockConfiguration value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_configuration = value;
|
_configuration = value;
|
||||||
@ -67,16 +61,14 @@ class StocksAppState extends State<StocksApp> {
|
|||||||
primarySwatch: Colors.purple,
|
primarySwatch: Colors.purple,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
assert(_configuration.stockMode != null);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Route<dynamic> _getRoute(RouteSettings settings) {
|
Route<dynamic>? _getRoute(RouteSettings settings) {
|
||||||
if (settings.name == '/stock') {
|
if (settings.name == '/stock') {
|
||||||
final String symbol = settings.arguments as String;
|
final String? symbol = settings.arguments as String?;
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
settings: settings,
|
settings: settings,
|
||||||
builder: (BuildContext context) => StockSymbolPage(symbol: symbol, stocks: stocks),
|
builder: (BuildContext context) => StockSymbolPage(symbol: symbol!, stocks: stocks),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// The other paths we support are in the routes table.
|
// The other paths we support are in the routes table.
|
||||||
|
@ -7,7 +7,10 @@ import 'dart:math' as math;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class StockArrowPainter extends CustomPainter {
|
class StockArrowPainter extends CustomPainter {
|
||||||
StockArrowPainter({ this.color, this.percentChange });
|
StockArrowPainter({
|
||||||
|
required this.color,
|
||||||
|
required this.percentChange,
|
||||||
|
});
|
||||||
|
|
||||||
final Color color;
|
final Color color;
|
||||||
final double percentChange;
|
final double percentChange;
|
||||||
@ -53,7 +56,7 @@ class StockArrowPainter extends CustomPainter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StockArrow extends StatelessWidget {
|
class StockArrow extends StatelessWidget {
|
||||||
const StockArrow({ Key key, this.percentChange }) : super(key: key);
|
const StockArrow({ Key? key, required this.percentChange }) : super(key: key);
|
||||||
|
|
||||||
final double percentChange;
|
final double percentChange;
|
||||||
|
|
||||||
@ -65,8 +68,8 @@ class StockArrow extends StatelessWidget {
|
|||||||
|
|
||||||
Color _colorForPercentChange(double percentChange) {
|
Color _colorForPercentChange(double percentChange) {
|
||||||
if (percentChange > 0)
|
if (percentChange > 0)
|
||||||
return Colors.green[_colorIndexForPercentChange(percentChange)];
|
return Colors.green[_colorIndexForPercentChange(percentChange)]!;
|
||||||
return Colors.red[_colorIndexForPercentChange(percentChange)];
|
return Colors.red[_colorIndexForPercentChange(percentChange)]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -31,11 +31,11 @@ class Stock {
|
|||||||
percentChange = (_rng.nextDouble() * 20) - 10;
|
percentChange = (_rng.nextDouble() * 20) - 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
String symbol;
|
late String symbol;
|
||||||
String name;
|
late String name;
|
||||||
double lastSale;
|
late double lastSale;
|
||||||
String marketCap;
|
late String marketCap;
|
||||||
double percentChange;
|
late double percentChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StockData extends ChangeNotifier {
|
class StockData extends ChangeNotifier {
|
||||||
@ -51,7 +51,7 @@ class StockData extends ChangeNotifier {
|
|||||||
|
|
||||||
List<String> get allSymbols => _symbols;
|
List<String> get allSymbols => _symbols;
|
||||||
|
|
||||||
Stock operator [](String symbol) => _stocks[symbol];
|
Stock? operator [](String symbol) => _stocks[symbol];
|
||||||
|
|
||||||
bool get loading => _httpClient != null;
|
bool get loading => _httpClient != null;
|
||||||
|
|
||||||
@ -71,12 +71,12 @@ class StockData extends ChangeNotifier {
|
|||||||
Uri _urlToFetch(int chunk) => Uri.https(
|
Uri _urlToFetch(int chunk) => Uri.https(
|
||||||
'domokit.github.io', 'examples/stocks/data/stock_data_$chunk.json');
|
'domokit.github.io', 'examples/stocks/data/stock_data_$chunk.json');
|
||||||
|
|
||||||
http.Client _httpClient;
|
http.Client? _httpClient;
|
||||||
|
|
||||||
static bool actuallyFetchData = true;
|
static bool actuallyFetchData = true;
|
||||||
|
|
||||||
void _fetchNextChunk() {
|
void _fetchNextChunk() {
|
||||||
_httpClient.get(_urlToFetch(_nextChunk++)).then<void>((http.Response response) {
|
_httpClient!.get(_urlToFetch(_nextChunk++)).then<void>((http.Response response) {
|
||||||
final String json = response.body;
|
final String json = response.body;
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
debugPrint('Failed to load stock data chunk ${_nextChunk - 1}');
|
debugPrint('Failed to load stock data chunk ${_nextChunk - 1}');
|
||||||
@ -94,7 +94,7 @@ class StockData extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _end() {
|
void _end() {
|
||||||
_httpClient?.close();
|
_httpClient!.close();
|
||||||
_httpClient = null;
|
_httpClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class _NotImplementedDialog extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StockHome extends StatefulWidget {
|
class StockHome extends StatefulWidget {
|
||||||
const StockHome(this.stocks, this.configuration, this.updater, {Key key}) : super(key: key);
|
const StockHome(this.stocks, this.configuration, this.updater, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
final StockData stocks;
|
final StockData stocks;
|
||||||
final StockConfiguration configuration;
|
final StockConfiguration configuration;
|
||||||
@ -69,7 +69,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
bool _autorefresh = false;
|
bool _autorefresh = false;
|
||||||
|
|
||||||
void _handleSearchBegin() {
|
void _handleSearchBegin() {
|
||||||
ModalRoute.of(context).addLocalHistoryEntry(LocalHistoryEntry(
|
ModalRoute.of(context)!.addLocalHistoryEntry(LocalHistoryEntry(
|
||||||
onRemove: () {
|
onRemove: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSearching = false;
|
_isSearching = false;
|
||||||
@ -82,7 +82,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleStockModeChange(StockMode value) {
|
void _handleStockModeChange(StockMode? value) {
|
||||||
if (widget.updater != null)
|
if (widget.updater != null)
|
||||||
widget.updater(widget.configuration.copyWith(stockMode: value));
|
widget.updater(widget.configuration.copyWith(stockMode: value));
|
||||||
}
|
}
|
||||||
@ -231,8 +231,9 @@ class StockHomeState extends State<StockHome> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Iterable<Stock> _getStockList(StockData stocks, Iterable<String> symbols) {
|
static Iterable<Stock> _getStockList(StockData stocks, Iterable<String> symbols) {
|
||||||
return symbols.map<Stock>((String symbol) => stocks[symbol])
|
return symbols.map<Stock?>((String symbol) => stocks[symbol])
|
||||||
.where((Stock stock) => stock != null);
|
.where((Stock? stock) => stock != null)
|
||||||
|
.cast<Stock>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<Stock> _filterBySearchQuery(Iterable<Stock> stocks) {
|
Iterable<Stock> _filterBySearchQuery(Iterable<Stock> stocks) {
|
||||||
@ -266,7 +267,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
Navigator.pushNamed(context, '/stock', arguments: stock.symbol);
|
Navigator.pushNamed(context, '/stock', arguments: stock.symbol);
|
||||||
},
|
},
|
||||||
onShow: (Stock stock) {
|
onShow: (Stock stock) {
|
||||||
_scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) => StockSymbolBottomSheet(stock: stock));
|
_scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) => StockSymbolBottomSheet(stock: stock));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -275,7 +276,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
key: ValueKey<StockHomeTab>(tab),
|
key: ValueKey<StockHomeTab>(tab),
|
||||||
animation: Listenable.merge(<Listenable>[_searchQuery, widget.stocks]),
|
animation: Listenable.merge(<Listenable>[_searchQuery, widget.stocks]),
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return _buildStockList(context, _filterBySearchQuery(_getStockList(widget.stocks, stockSymbols)).toList(), tab);
|
return _buildStockList(context, _filterBySearchQuery(_getStockList(widget.stocks, stockSymbols)).toList(), tab);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,13 @@ import 'stock_data.dart';
|
|||||||
import 'stock_row.dart';
|
import 'stock_row.dart';
|
||||||
|
|
||||||
class StockList extends StatelessWidget {
|
class StockList extends StatelessWidget {
|
||||||
const StockList({ Key key, this.stocks, this.onOpen, this.onShow, this.onAction }) : super(key: key);
|
const StockList({
|
||||||
|
Key? key,
|
||||||
|
required this.stocks,
|
||||||
|
required this.onOpen,
|
||||||
|
required this.onShow,
|
||||||
|
required this.onAction,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final List<Stock> stocks;
|
final List<Stock> stocks;
|
||||||
final StockRowActionCallback onOpen;
|
final StockRowActionCallback onOpen;
|
||||||
|
@ -11,20 +11,20 @@ typedef StockRowActionCallback = void Function(Stock stock);
|
|||||||
|
|
||||||
class StockRow extends StatelessWidget {
|
class StockRow extends StatelessWidget {
|
||||||
StockRow({
|
StockRow({
|
||||||
this.stock,
|
required this.stock,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
this.onDoubleTap,
|
this.onDoubleTap,
|
||||||
this.onLongPressed,
|
this.onLongPressed,
|
||||||
}) : super(key: ObjectKey(stock));
|
}) : super(key: ObjectKey(stock));
|
||||||
|
|
||||||
final Stock stock;
|
final Stock stock;
|
||||||
final StockRowActionCallback onPressed;
|
final StockRowActionCallback? onPressed;
|
||||||
final StockRowActionCallback onDoubleTap;
|
final StockRowActionCallback? onDoubleTap;
|
||||||
final StockRowActionCallback onLongPressed;
|
final StockRowActionCallback? onLongPressed;
|
||||||
|
|
||||||
static const double kHeight = 79.0;
|
static const double kHeight = 79.0;
|
||||||
|
|
||||||
GestureTapCallback _getHandler(StockRowActionCallback callback) {
|
GestureTapCallback? _getHandler(StockRowActionCallback? callback) {
|
||||||
return callback == null ? null : () => callback(stock);
|
return callback == null ? null : () => callback(stock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'stock_types.dart';
|
import 'stock_types.dart';
|
||||||
|
|
||||||
class StockSettings extends StatefulWidget {
|
class StockSettings extends StatefulWidget {
|
||||||
const StockSettings(this.configuration, this.updater, {Key key}) : super(key: key);
|
const StockSettings(this.configuration, this.updater, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
final StockConfiguration configuration;
|
final StockConfiguration configuration;
|
||||||
final ValueChanged<StockConfiguration> updater;
|
final ValueChanged<StockConfiguration> updater;
|
||||||
@ -17,7 +17,7 @@ class StockSettings extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StockSettingsState extends State<StockSettings> {
|
class StockSettingsState extends State<StockSettings> {
|
||||||
void _handleOptimismChanged(bool value) {
|
void _handleOptimismChanged(bool? value) {
|
||||||
value ??= false;
|
value ??= false;
|
||||||
sendUpdates(widget.configuration.copyWith(stockMode: value ? StockMode.optimistic : StockMode.pessimistic));
|
sendUpdates(widget.configuration.copyWith(stockMode: value ? StockMode.optimistic : StockMode.pessimistic));
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ class StockSettingsState extends State<StockSettings> {
|
|||||||
onTap: _confirmOptimismChange,
|
onTap: _confirmOptimismChange,
|
||||||
trailing: Checkbox(
|
trailing: Checkbox(
|
||||||
value: widget.configuration.stockMode == StockMode.optimistic,
|
value: widget.configuration.stockMode == StockMode.optimistic,
|
||||||
onChanged: (bool value) => _confirmOptimismChange(),
|
onChanged: (bool? value) => _confirmOptimismChange(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
@ -8,7 +8,10 @@ import 'stock_arrow.dart';
|
|||||||
import 'stock_data.dart';
|
import 'stock_data.dart';
|
||||||
|
|
||||||
class _StockSymbolView extends StatelessWidget {
|
class _StockSymbolView extends StatelessWidget {
|
||||||
const _StockSymbolView({ this.stock, this.arrow });
|
const _StockSymbolView({
|
||||||
|
required this.stock,
|
||||||
|
required this.arrow,
|
||||||
|
});
|
||||||
|
|
||||||
final Stock stock;
|
final Stock stock;
|
||||||
final Widget arrow;
|
final Widget arrow;
|
||||||
@ -21,7 +24,7 @@ class _StockSymbolView extends StatelessWidget {
|
|||||||
if (stock.percentChange > 0)
|
if (stock.percentChange > 0)
|
||||||
changeInPrice = '+' + changeInPrice;
|
changeInPrice = '+' + changeInPrice;
|
||||||
|
|
||||||
final TextStyle headings = Theme.of(context).textTheme.bodyText1;
|
final TextStyle headings = Theme.of(context).textTheme.bodyText1!;
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -65,7 +68,11 @@ class _StockSymbolView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StockSymbolPage extends StatelessWidget {
|
class StockSymbolPage extends StatelessWidget {
|
||||||
const StockSymbolPage({ Key key, this.symbol, this.stocks }) : super(key: key);
|
const StockSymbolPage({
|
||||||
|
Key? key,
|
||||||
|
required this.symbol,
|
||||||
|
required this.stocks,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final String symbol;
|
final String symbol;
|
||||||
final StockData stocks;
|
final StockData stocks;
|
||||||
@ -74,8 +81,8 @@ class StockSymbolPage extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
animation: stocks,
|
animation: stocks,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
final Stock stock = stocks[symbol];
|
final Stock? stock = stocks[symbol];
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(stock?.name ?? symbol),
|
title: Text(stock?.name ?? symbol),
|
||||||
@ -113,7 +120,10 @@ class StockSymbolPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StockSymbolBottomSheet extends StatelessWidget {
|
class StockSymbolBottomSheet extends StatelessWidget {
|
||||||
const StockSymbolBottomSheet({ Key key, this.stock }) : super(key: key);
|
const StockSymbolBottomSheet({
|
||||||
|
Key? key,
|
||||||
|
required this.stock,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final Stock stock;
|
final Stock stock;
|
||||||
|
|
||||||
|
@ -2,23 +2,21 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
enum StockMode { optimistic, pessimistic }
|
enum StockMode { optimistic, pessimistic }
|
||||||
enum BackupMode { enabled, disabled }
|
enum BackupMode { enabled, disabled }
|
||||||
|
|
||||||
class StockConfiguration {
|
class StockConfiguration {
|
||||||
StockConfiguration({
|
StockConfiguration({
|
||||||
@required this.stockMode,
|
required this.stockMode,
|
||||||
@required this.backupMode,
|
required this.backupMode,
|
||||||
@required this.debugShowGrid,
|
required this.debugShowGrid,
|
||||||
@required this.debugShowSizes,
|
required this.debugShowSizes,
|
||||||
@required this.debugShowBaselines,
|
required this.debugShowBaselines,
|
||||||
@required this.debugShowLayers,
|
required this.debugShowLayers,
|
||||||
@required this.debugShowPointers,
|
required this.debugShowPointers,
|
||||||
@required this.debugShowRainbow,
|
required this.debugShowRainbow,
|
||||||
@required this.showPerformanceOverlay,
|
required this.showPerformanceOverlay,
|
||||||
@required this.showSemanticsDebugger,
|
required this.showSemanticsDebugger,
|
||||||
}) : assert(stockMode != null),
|
}) : assert(stockMode != null),
|
||||||
assert(backupMode != null),
|
assert(backupMode != null),
|
||||||
assert(debugShowGrid != null),
|
assert(debugShowGrid != null),
|
||||||
@ -42,16 +40,16 @@ class StockConfiguration {
|
|||||||
final bool showSemanticsDebugger;
|
final bool showSemanticsDebugger;
|
||||||
|
|
||||||
StockConfiguration copyWith({
|
StockConfiguration copyWith({
|
||||||
StockMode stockMode,
|
StockMode? stockMode,
|
||||||
BackupMode backupMode,
|
BackupMode? backupMode,
|
||||||
bool debugShowGrid,
|
bool? debugShowGrid,
|
||||||
bool debugShowSizes,
|
bool? debugShowSizes,
|
||||||
bool debugShowBaselines,
|
bool? debugShowBaselines,
|
||||||
bool debugShowLayers,
|
bool? debugShowLayers,
|
||||||
bool debugShowPointers,
|
bool? debugShowPointers,
|
||||||
bool debugShowRainbow,
|
bool? debugShowRainbow,
|
||||||
bool showPerformanceOverlay,
|
bool? showPerformanceOverlay,
|
||||||
bool showSemanticsDebugger,
|
bool? showSemanticsDebugger,
|
||||||
}) {
|
}) {
|
||||||
return StockConfiguration(
|
return StockConfiguration(
|
||||||
stockMode: stockMode ?? this.stockMode,
|
stockMode: stockMode ?? this.stockMode,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: stocks
|
name: stocks
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.0.0-dev.68.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
@ -9,7 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:stocks/main.dart' as stocks;
|
import 'package:stocks/main.dart' as stocks;
|
||||||
import 'package:stocks/stock_data.dart' as stock_data;
|
import 'package:stocks/stock_data.dart' as stock_data;
|
||||||
|
|
||||||
Element findElementOfExactWidgetTypeGoingDown(Element node, Type targetType) {
|
Element? findElementOfExactWidgetTypeGoingDown(Element node, Type targetType) {
|
||||||
void walker(Element child) {
|
void walker(Element child) {
|
||||||
if (child.widget.runtimeType == targetType)
|
if (child.widget.runtimeType == targetType)
|
||||||
throw child;
|
throw child;
|
||||||
@ -23,12 +23,14 @@ Element findElementOfExactWidgetTypeGoingDown(Element node, Type targetType) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
|
Element? findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
|
||||||
Element result;
|
Element? result;
|
||||||
bool walker(Element ancestor) {
|
bool walker(Element ancestor) {
|
||||||
if (ancestor.widget.runtimeType == targetType)
|
if (ancestor.widget.runtimeType == targetType) {
|
||||||
result = ancestor;
|
result = ancestor;
|
||||||
return result == null;
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
node.visitAncestorElements(walker);
|
node.visitAncestorElements(walker);
|
||||||
return result;
|
return result;
|
||||||
@ -37,11 +39,10 @@ Element findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
|
|||||||
final RegExp materialIconAssetNameColorExtractor = RegExp(r'[^/]+/ic_.+_(white|black)_[0-9]+dp\.png');
|
final RegExp materialIconAssetNameColorExtractor = RegExp(r'[^/]+/ic_.+_(white|black)_[0-9]+dp\.png');
|
||||||
|
|
||||||
void checkIconColor(WidgetTester tester, String label, Color color) {
|
void checkIconColor(WidgetTester tester, String label, Color color) {
|
||||||
final Element listTile = findElementOfExactWidgetTypeGoingUp(tester.element(find.text(label)), ListTile);
|
final Element listTile = findElementOfExactWidgetTypeGoingUp(tester.element(find.text(label)), ListTile)!;
|
||||||
expect(listTile, isNotNull);
|
final Element asset = findElementOfExactWidgetTypeGoingDown(listTile, RichText)!;
|
||||||
final Element asset = findElementOfExactWidgetTypeGoingDown(listTile, RichText);
|
|
||||||
final RichText richText = asset.widget as RichText;
|
final RichText richText = asset.widget as RichText;
|
||||||
expect(richText.text.style.color, equals(color));
|
expect(richText.text.style!.color, equals(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -9,15 +9,14 @@ import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('scrolling performance test', () {
|
group('scrolling performance test', () {
|
||||||
FlutterDriver driver;
|
late FlutterDriver driver;
|
||||||
|
|
||||||
setUpAll(() async {
|
setUpAll(() async {
|
||||||
driver = await FlutterDriver.connect();
|
driver = await FlutterDriver.connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDownAll(() async {
|
tearDownAll(() async {
|
||||||
if (driver != null)
|
driver.close();
|
||||||
driver.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('measure', () async {
|
test('measure', () async {
|
||||||
|
@ -9,16 +9,14 @@ import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('basic stock view test', () {
|
group('basic stock view test', () {
|
||||||
FlutterDriver driver;
|
late FlutterDriver driver;
|
||||||
|
|
||||||
setUpAll(() async {
|
setUpAll(() async {
|
||||||
driver = await FlutterDriver.connect();
|
driver = await FlutterDriver.connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDownAll(() async {
|
tearDownAll(() async {
|
||||||
if (driver != null) {
|
driver.close();
|
||||||
driver.close();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Stock list is shown', () async {
|
test('Stock list is shown', () async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user