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:
Lynne Megido 2020-09-30 11:45:57 +10:00
parent 91fbf180d7
commit caf0d03e3b
Signed by: lynnesbian
GPG key ID: F0A184B5213D9F90
8 changed files with 217 additions and 67 deletions

View file

@ -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(),
class MyApp extends StatelessWidget { child: MaterialApp(
// This widget is the root of your application. initialRoute: '/splash',
@override routes: {
Widget build(BuildContext context) { '/': (context) => RouteHome(),
return MaterialApp( '/splash': (context) => RouteSplash(),
title: "Buypeeb", },
theme: ThemeData(
primarySwatch: Colors.orange, title: "Buypeeb Mobile",
), theme: ThemeData(
home: MainPage(), primarySwatch: Colors.orange,
); ),
} )
} ),
);
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()])));
},
);
}
} }

View 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
View 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
View 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(),
)
);
}
}

View file

@ -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"

View file

@ -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:

View file

@ -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);