a lot of boo things
- split app into separate pages/routes - put models in their own folder - use provider to sync state between pages - generate a preset list of items instead of an infinite amount - added a splash screen
This commit is contained in:
parent
91fbf180d7
commit
caf0d03e3b
8 changed files with 217 additions and 67 deletions
|
@ -15,75 +15,33 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:buyeeb_mobile/pages/main_page.dart';
|
||||||
|
import 'package:buyeeb_mobile/pages/splash.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sprintf/sprintf.dart';
|
import 'package:sprintf/sprintf.dart';
|
||||||
import 'yahoo_auctions_item.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'models/yahoo_auctions_item.dart';
|
||||||
|
import 'models/user_listings.dart';
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(MyApp());
|
runApp(
|
||||||
}
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => UserListings(),
|
||||||
|
child: MaterialApp(
|
||||||
|
initialRoute: '/splash',
|
||||||
|
routes: {
|
||||||
|
'/': (context) => RouteHome(),
|
||||||
|
'/splash': (context) => RouteSplash(),
|
||||||
|
},
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
title: "Buypeeb Mobile",
|
||||||
// This widget is the root of your application.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MaterialApp(
|
|
||||||
title: "Buypeeb",
|
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Colors.orange,
|
primarySwatch: Colors.orange,
|
||||||
),
|
),
|
||||||
home: MainPage(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MainPage extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_MainPageState createState() => _MainPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MainPageState extends State<MainPage> {
|
|
||||||
final _items = <YahooAuctionsItem>[];
|
|
||||||
final _rng = new Random();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(title: Text("Buypeeb"), actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.search),
|
|
||||||
onPressed: () => null,
|
|
||||||
tooltip: "Search",
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.list),
|
|
||||||
onPressed: () => null,
|
|
||||||
tooltip: "Filter",
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.settings),
|
|
||||||
onPressed: () => null,
|
|
||||||
tooltip: "Settings",
|
|
||||||
)
|
)
|
||||||
]),
|
),
|
||||||
body: _buildAuctionListings(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAuctionListings() {
|
|
||||||
return ListView.builder(
|
|
||||||
padding: EdgeInsets.all(16.0),
|
|
||||||
itemBuilder: (context, i) {
|
|
||||||
if (i.isOdd) return Divider();
|
|
||||||
|
|
||||||
final newItem = YahooAuctionsItem(id: "Henlo", name: "Hi Pempa!", price: _rng.nextInt(5000) + 500);
|
|
||||||
|
|
||||||
_items.add(newItem);
|
|
||||||
|
|
||||||
return ListTile(title: Text(newItem.name),
|
|
||||||
subtitle: Text(sprintf("¥%d (≈\$%2.2f)", [newItem.price, newItem.getLocalPrice()])));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
24
lib/models/user_listings.dart
Normal file
24
lib/models/user_listings.dart
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import 'dart:collection';
|
||||||
|
import 'package:buyeeb_mobile/models/yahoo_auctions_item.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
class UserListings extends ChangeNotifier {
|
||||||
|
final List<YahooAuctionsItem> _items = [];
|
||||||
|
|
||||||
|
UnmodifiableListView<YahooAuctionsItem> get items => UnmodifiableListView(_items);
|
||||||
|
|
||||||
|
void add (YahooAuctionsItem item) {
|
||||||
|
_items.add(item);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(YahooAuctionsItem item) {
|
||||||
|
_items.remove(item);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeAll() {
|
||||||
|
_items.clear();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
79
lib/pages/main_page.dart
Normal file
79
lib/pages/main_page.dart
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import 'package:buyeeb_mobile/models/user_listings.dart';
|
||||||
|
import 'package:buyeeb_mobile/models/yahoo_auctions_item.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sprintf/sprintf.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
class RouteHome extends StatelessWidget {
|
||||||
|
// This widget is the root of your application.
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: "Buypeeb",
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.orange,
|
||||||
|
),
|
||||||
|
home: MainPage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_MainPageState createState() => _MainPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MainPageState extends State<MainPage> {
|
||||||
|
final _items = <YahooAuctionsItem>[];
|
||||||
|
final _rng = new Random();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: Text("Buypeeb"), actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.search),
|
||||||
|
onPressed: () => null,
|
||||||
|
tooltip: "Search",
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.list),
|
||||||
|
onPressed: () => null,
|
||||||
|
tooltip: "Filter",
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.settings),
|
||||||
|
onPressed: () => null,
|
||||||
|
tooltip: "Settings",
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
body: _buildAuctionListings(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAuctionListings() {
|
||||||
|
var listings = context.watch<UserListings>();
|
||||||
|
return ListView.builder(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
// itemBuilder: (context, i) {
|
||||||
|
// if (i.isOdd) return Divider();
|
||||||
|
//
|
||||||
|
// final newItem = YahooAuctionsItem(id: "Henlo", name: "Hi Pempa!", price: _rng.nextInt(5000) + 500);
|
||||||
|
//
|
||||||
|
// _items.add(newItem);
|
||||||
|
//
|
||||||
|
// return ListTile(title: Text(newItem.name),
|
||||||
|
// subtitle: Text(sprintf("¥%d (≈\$%2.2f)", [newItem.price, newItem.getLocalPrice()])));
|
||||||
|
// },
|
||||||
|
itemCount: listings.items.length,
|
||||||
|
itemBuilder: (context, i) => ListTile(
|
||||||
|
title: Text(listings.items[i].name),
|
||||||
|
subtitle: Text(sprintf(
|
||||||
|
"¥%d (≈\$%2.2f)",
|
||||||
|
[listings.items[i].price, listings.items[i].getLocalPrice()]
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
50
lib/pages/splash.dart
Normal file
50
lib/pages/splash.dart
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import 'package:buyeeb_mobile/models/user_listings.dart';
|
||||||
|
import 'package:buyeeb_mobile/models/yahoo_auctions_item.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
class RouteSplash extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_RouteSplashState createState() => _RouteSplashState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RouteSplashState extends State<RouteSplash> {
|
||||||
|
bool _ready = false;
|
||||||
|
|
||||||
|
_loadUserSettings() async {
|
||||||
|
// sleep for a bit to "simulate" loading
|
||||||
|
await Future.delayed(Duration(seconds: 3));
|
||||||
|
// add some random stuff to the listings
|
||||||
|
var listings = context.read<UserListings>();
|
||||||
|
var _rng = new Random();
|
||||||
|
final names = ["Hi Pempa!", "Pebulon Crystal", "The Peebler Chronicles", "Pecha Sludge", "The Forbidden Book of Peebus"];
|
||||||
|
for (var i = 0; i < 15; i++) {
|
||||||
|
listings.add(YahooAuctionsItem(
|
||||||
|
id: "Henlo",
|
||||||
|
name: names[_rng.nextInt(names.length)],
|
||||||
|
price: _rng.nextInt(5000) + 500
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_ready = true;
|
||||||
|
Navigator.pushNamed(context, '/');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadUserSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
36
pubspec.lock
36
pubspec.lock
|
@ -81,6 +81,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.8"
|
version: "1.1.8"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.4"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -88,6 +95,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.7.0"
|
||||||
|
provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.2+2"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -107,6 +121,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.0"
|
||||||
|
sqflite:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: sqflite
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1+1"
|
||||||
|
sqflite_common:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_common
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2+1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -128,6 +156,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0+2"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -158,3 +193,4 @@ packages:
|
||||||
version: "2.0.8"
|
version: "2.0.8"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.9.0-14.0.dev <3.0.0"
|
dart: ">=2.9.0-14.0.dev <3.0.0"
|
||||||
|
flutter: ">=1.16.0 <2.0.0"
|
||||||
|
|
|
@ -29,6 +29,8 @@ dependencies:
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^0.1.3
|
cupertino_icons: ^0.1.3
|
||||||
sprintf: "^4.0.0"
|
sprintf: "^4.0.0"
|
||||||
|
provider: ^4.1.0
|
||||||
|
sqflite: ^1.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
|
import 'package:buyeeb_mobile/pages/main_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import 'package:buyeeb_mobile/main.dart';
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
// Build our app and trigger a frame.
|
// Build our app and trigger a frame.
|
||||||
await tester.pumpWidget(MyApp());
|
await tester.pumpWidget(RouteHome());
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
// Verify that our counter starts at 0.
|
||||||
expect(find.text('0'), findsOneWidget);
|
expect(find.text('0'), findsOneWidget);
|
||||||
|
|
Loading…
Reference in a new issue