diff --git a/lib/route/collection.dart b/lib/route/collection.dart index 4a63909..582d8ac 100644 --- a/lib/route/collection.dart +++ b/lib/route/collection.dart @@ -1,26 +1,43 @@ -import 'package:escape_earth/model/RocketLaunch.dart'; +import 'package:escape_earth/route/launches_result.dart'; import 'package:escape_earth/service/RocketService.dart'; import 'package:escape_earth/view/RocketView.dart'; +import 'package:escape_earth/view/RoundSearch.dart'; import 'package:flutter/material.dart'; class CollectionRocketRoute extends StatelessWidget { @override Widget build(BuildContext context) { - return FutureBuilder( - future: RocketService.getLaunches(), - initialData: null, - builder: (context, snap) { - if (snap.data == null || snap.data.length == 0) { - return Center( - child: CircularProgressIndicator(), - ); - } + return Stack( + children: [ + FutureBuilder( + future: RocketService.getLaunches(), + initialData: null, + builder: (context, snap) { + if (snap.data == null || snap.data.length == 0) { + return Center( + child: CircularProgressIndicator(), + ); + } - return ListView.builder( - itemCount: snap.data.length, - itemBuilder: (context, i) => RocketView(launch: snap.data[i]), - ); - }, + if (snap.error != null) { + print(snap.error); + return Center(child: Icon(Icons.portable_wifi_off)); + } + + return ListView.builder( + padding: EdgeInsets.only(top: 90.0), + itemCount: snap.data.length, + itemBuilder: (context, i) => RocketView(launch: snap.data[i]), + ); + }, + ), + Align( + alignment: Alignment.topCenter, + child: RoundSearch(onSearch: (query) { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => LaunchesResultRoute(query: query))); + }), + ), + ], ); } } diff --git a/lib/route/home.dart b/lib/route/home.dart index 2be4400..96481d0 100644 --- a/lib/route/home.dart +++ b/lib/route/home.dart @@ -1,5 +1,7 @@ import 'package:escape_earth/bottom_home.dart'; import 'package:escape_earth/route/collection.dart'; +import 'package:escape_earth/route/qa.dart'; +import 'package:escape_earth/view/RocketHero.dart'; import 'package:flutter/material.dart'; class Home extends StatefulWidget { @@ -12,7 +14,6 @@ class HomeState extends State { @override void initState() { - // TODO: implement initState super.initState(); currentFragment = HomeBody(); } @@ -30,21 +31,28 @@ class HomeState extends State { alignment: Alignment.bottomCenter, child: BottomHome( buttons: [ - Image( - image: AssetImage("assets/img/ic_home_news.png"), + Image.asset("assets/img/ic_home_news.png", color: Colors.white), + GestureDetector( + child: RocketHero(), + onVerticalDragEnd: (_) => Navigator.of(context) + .push(MaterialPageRoute(builder: (_) => QaRoute()))), + Image.asset("assets/img/home_collection.png", color: Colors.white), - Image(image: AssetImage("assets/img/home_rocket.png")), - Image( - image: AssetImage("assets/img/home_collection.png"), - color: Colors.white), // TODO: change icon ], clickListener: (index) { switch (index) { case 0: - // TODO + // TODO click break; case 1: - // TODO + if (currentFragment is HomeBody) { + Navigator.of(context) + .push(MaterialPageRoute(builder: (_) => QaRoute())); + } else { + setState(() { + currentFragment = HomeBody(); + }); + } break; case 2: setState(() { @@ -64,7 +72,7 @@ class HomeState extends State { class HomeBody extends StatelessWidget { @override Widget build(BuildContext context) { - // TODO: implement build + // TODO: implement HomeBody return Container(); } } diff --git a/lib/route/launches_result.dart b/lib/route/launches_result.dart new file mode 100644 index 0000000..415d733 --- /dev/null +++ b/lib/route/launches_result.dart @@ -0,0 +1,51 @@ +import 'package:escape_earth/service/RocketService.dart'; +import 'package:escape_earth/view/RocketView.dart'; +import 'package:flutter/material.dart'; + +class LaunchesResultRoute extends StatelessWidget { + final String query; + + LaunchesResultRoute({ + Key key, + this.query, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Stack( + children: [ + FutureBuilder( + future: RocketService.getLaunches(query: query), + initialData: null, + builder: (context, snap) { + if (snap.data == null || snap.data.length == 0) { + return Center( + child: CircularProgressIndicator(), + ); + } + + return ListView.builder( + padding: EdgeInsets.only(top: 48.0), + itemCount: snap.data.length, + itemBuilder: (context, i) => RocketView(launch: snap.data[i]), + ); + }, + ), + Align( + alignment: Alignment.topLeft, + child: GestureDetector( + child: Padding( + padding: EdgeInsets.all(8.0), + child: Icon(Icons.arrow_back, + color: Colors.white, size: 32.0)), + onTap: () => Navigator.of(context).pop(), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/route/qa.dart b/lib/route/qa.dart new file mode 100644 index 0000000..1035398 --- /dev/null +++ b/lib/route/qa.dart @@ -0,0 +1,46 @@ +import 'package:escape_earth/view/RocketHero.dart'; +import 'package:flutter/material.dart'; + +class QaRoute extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: ListView( + children: [ + GestureDetector( + child: RocketHero(), + onTap: () => Navigator.of(context).pop(), + onVerticalDragEnd: (_) => Navigator.of(context).pop(), + ), + // TODO Q&A + Text( + """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent viverra facilisis libero, non imperdiet magna varius in. Integer placerat porta leo quis hendrerit. Nullam mattis porttitor neque, at tempus quam fermentum eget. Proin faucibus lacus in sapien faucibus tincidunt. Donec elementum mollis justo, eget rutrum metus lacinia vel. Sed blandit viverra fringilla. Nunc vel ligula eleifend, convallis nulla vitae, imperdiet erat. + +Sed malesuada ac neque non varius. Quisque sollicitudin magna a ullamcorper aliquam. Suspendisse et consequat quam. Praesent aliquam arcu ac massa volutpat, sed posuere nunc sollicitudin. Quisque non sapien ultrices, tristique enim eu, efficitur risus. Etiam efficitur ligula in sagittis feugiat. Nam id nisi ut dolor ultrices iaculis. Nulla rhoncus varius consectetur. Nunc pharetra urna in varius fermentum. Nunc pulvinar purus purus, nec laoreet ex fermentum a. Vivamus suscipit elementum dolor, nec mollis dolor fermentum id. Vestibulum vehicula mauris in sem scelerisque dignissim. + +Morbi posuere ultrices leo dapibus varius. Nunc eros massa, bibendum sed quam non, varius efficitur magna. Aliquam sed tellus non sapien bibendum efficitur quis in justo. Aliquam vitae dolor congue, malesuada erat at, congue velit. Ut scelerisque felis nec molestie vehicula. Mauris sit amet mauris metus. Etiam leo tellus, pulvinar ac dignissim ut, facilisis vel nunc. + +Curabitur ante leo, sollicitudin elementum viverra vitae, dignissim venenatis lorem. In eu felis ac augue vehicula mattis at eu ligula. Etiam et justo ipsum. Sed vitae consectetur turpis. Vestibulum ultrices dolor vestibulum tortor faucibus accumsan. Sed eget ante dolor. Nullam sollicitudin luctus ligula, et tincidunt velit. Morbi porta volutpat sapien, in dictum ipsum euismod in. Sed quis arcu sagittis, euismod risus eu, bibendum turpis. Morbi eleifend ligula tempus nulla auctor aliquet. In hac habitasse platea dictumst. Vivamus vestibulum at nibh eu mattis. Duis consectetur ipsum at velit mattis, sit amet ullamcorper ligula mattis. Sed varius efficitur urna. Quisque enim nunc, malesuada nec pulvinar at, auctor eget dolor. Cras tempus nunc id ex convallis, nec imperdiet libero tempus. + +Aliquam erat volutpat. Nulla arcu quam, placerat vel est et, rutrum dignissim libero. Aenean venenatis dolor id sem lobortis vulputate. Etiam nisi augue, feugiat ut libero vitae, dignissim commodo odio. Phasellus congue lacus eget molestie consectetur. Cras vestibulum lorem in ligula eleifend molestie. Phasellus a ex libero. In ut libero sed nulla mattis vulputate. Mauris faucibus purus ante, facilisis condimentum augue varius sit amet. Cras cursus justo nisl, at ultricies enim ultricies at. Nulla maximus, ex id eleifend venenatis, augue diam sagittis augue, consectetur porta enim dui vitae lectus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent viverra facilisis libero, non imperdiet magna varius in. Integer placerat porta leo quis hendrerit. Nullam mattis porttitor neque, at tempus quam fermentum eget. Proin faucibus lacus in sapien faucibus tincidunt. Donec elementum mollis justo, eget rutrum metus lacinia vel. Sed blandit viverra fringilla. Nunc vel ligula eleifend, convallis nulla vitae, imperdiet erat. + +Sed malesuada ac neque non varius. Quisque sollicitudin magna a ullamcorper aliquam. Suspendisse et consequat quam. Praesent aliquam arcu ac massa volutpat, sed posuere nunc sollicitudin. Quisque non sapien ultrices, tristique enim eu, efficitur risus. Etiam efficitur ligula in sagittis feugiat. Nam id nisi ut dolor ultrices iaculis. Nulla rhoncus varius consectetur. Nunc pharetra urna in varius fermentum. Nunc pulvinar purus purus, nec laoreet ex fermentum a. Vivamus suscipit elementum dolor, nec mollis dolor fermentum id. Vestibulum vehicula mauris in sem scelerisque dignissim. + +Morbi posuere ultrices leo dapibus varius. Nunc eros massa, bibendum sed quam non, varius efficitur magna. Aliquam sed tellus non sapien bibendum efficitur quis in justo. Aliquam vitae dolor congue, malesuada erat at, congue velit. Ut scelerisque felis nec molestie vehicula. Mauris sit amet mauris metus. Etiam leo tellus, pulvinar ac dignissim ut, facilisis vel nunc. + +Curabitur ante leo, sollicitudin elementum viverra vitae, dignissim venenatis lorem. In eu felis ac augue vehicula mattis at eu ligula. Etiam et justo ipsum. Sed vitae consectetur turpis. Vestibulum ultrices dolor vestibulum tortor faucibus accumsan. Sed eget ante dolor. Nullam sollicitudin luctus ligula, et tincidunt velit. Morbi porta volutpat sapien, in dictum ipsum euismod in. Sed quis arcu sagittis, euismod risus eu, bibendum turpis. Morbi eleifend ligula tempus nulla auctor aliquet. In hac habitasse platea dictumst. Vivamus vestibulum at nibh eu mattis. Duis consectetur ipsum at velit mattis, sit amet ullamcorper ligula mattis. Sed varius efficitur urna. Quisque enim nunc, malesuada nec pulvinar at, auctor eget dolor. Cras tempus nunc id ex convallis, nec imperdiet libero tempus. + +Aliquam erat volutpat. Nulla arcu quam, placerat vel est et, rutrum dignissim libero. Aenean venenatis dolor id sem lobortis vulputate. Etiam nisi augue, feugiat ut libero vitae, dignissim commodo odio. Phasellus congue lacus eget molestie consectetur. Cras vestibulum lorem in ligula eleifend molestie. Phasellus a ex libero. In ut libero sed nulla mattis vulputate. Mauris faucibus purus ante, facilisis condimentum augue varius sit amet. Cras cursus justo nisl, at ultricies enim ultricies at. Nulla maximus, ex id eleifend venenatis, augue diam sagittis augue, consectetur porta enim dui vitae lectus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent viverra facilisis libero, non imperdiet magna varius in. Integer placerat porta leo quis hendrerit. Nullam mattis porttitor neque, at tempus quam fermentum eget. Proin faucibus lacus in sapien faucibus tincidunt. Donec elementum mollis justo, eget rutrum metus lacinia vel. Sed blandit viverra fringilla. Nunc vel ligula eleifend, convallis nulla vitae, imperdiet erat. + +Sed malesuada ac neque non varius. Quisque sollicitudin magna a ullamcorper aliquam. Suspendisse et consequat quam. Praesent aliquam arcu ac massa volutpat, sed posuere nunc sollicitudin. Quisque non sapien ultrices, tristique enim eu, efficitur risus. Etiam efficitur ligula in sagittis feugiat. Nam id nisi ut dolor ultrices iaculis. Nulla rhoncus varius consectetur. Nunc pharetra urna in varius fermentum. Nunc pulvinar purus purus, nec laoreet ex fermentum a. Vivamus suscipit elementum dolor, nec mollis dolor fermentum id. Vestibulum vehicula mauris in sem scelerisque dignissim. + +Morbi posuere ultrices leo dapibus varius. Nunc eros massa, bibendum sed quam non, varius efficitur magna. Aliquam sed tellus non sapien bibendum efficitur quis in justo. Aliquam vitae dolor congue, malesuada erat at, congue velit. Ut scelerisque felis nec molestie vehicula. Mauris sit amet mauris metus. Etiam leo tellus, pulvinar ac dignissim ut, facilisis vel nunc. + +Curabitur ante leo, sollicitudin elementum viverra vitae, dignissim venenatis lorem. In eu felis ac augue vehicula mattis at eu ligula. Etiam et justo ipsum. Sed vitae consectetur turpis. Vestibulum ultrices dolor vestibulum tortor faucibus accumsan. Sed eget ante dolor. Nullam sollicitudin luctus ligula, et tincidunt velit. Morbi porta volutpat sapien, in dictum ipsum euismod in. Sed quis arcu sagittis, euismod risus eu, bibendum turpis. Morbi eleifend ligula tempus nulla auctor aliquet. In hac habitasse platea dictumst. Vivamus vestibulum at nibh eu mattis. Duis consectetur ipsum at velit mattis, sit amet ullamcorper ligula mattis. Sed varius efficitur urna. Quisque enim nunc, malesuada nec pulvinar at, auctor eget dolor. Cras tempus nunc id ex convallis, nec imperdiet libero tempus. + +Aliquam erat volutpat. Nulla arcu quam, placerat vel est et, rutrum dignissim libero. Aenean venenatis dolor id sem lobortis vulputate. Etiam nisi augue, feugiat ut libero vitae, dignissim commodo odio. Phasellus congue lacus eget molestie consectetur. Cras vestibulum lorem in ligula eleifend molestie. Phasellus a ex libero. In ut libero sed nulla mattis vulputate. Mauris faucibus purus ante, facilisis condimentum augue varius sit amet. Cras cursus justo nisl, at ultricies enim ultricies at. Nulla maximus, ex id eleifend venenatis, augue diam sagittis augue, consectetur porta enim dui vitae lectus.""") + ], + ), + ); + } +} diff --git a/lib/service/RocketService.dart b/lib/service/RocketService.dart index 25be0fb..af81bbb 100644 --- a/lib/service/RocketService.dart +++ b/lib/service/RocketService.dart @@ -5,12 +5,17 @@ import 'package:escape_earth/model/RocketLaunch.dart'; import 'package:http/http.dart' as http; class RocketService { - static Future> getLaunches() async { - final rawLaunchesResponse = - await http.get("https://launchlibrary.net/1.4/launch?next=25"); + static Future> getLaunches({ String query }) async { + http.Response rawLaunchesResponse; + if (query == null || query == "") { + rawLaunchesResponse = await http.get("https://launchlibrary.net/1.4/launch?next=25"); + } else { + rawLaunchesResponse = await http.get("https://launchlibrary.net/1.4/launch?next=25&name=$query"); + } + final List launchesContent = json.decode(rawLaunchesResponse.body)["launches"]; - + final agRequests = []; for (Map item in launchesContent) { agRequests.add(getAgencyById(item["lsp"])); diff --git a/lib/view/RocketHero.dart b/lib/view/RocketHero.dart new file mode 100644 index 0000000..c1810d0 --- /dev/null +++ b/lib/view/RocketHero.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class RocketHero extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Hero( + child: Image.asset("assets/img/home_rocket.png", height: 72.0), + tag: "home_rocket", + ); + } +} diff --git a/lib/view/RoundSearch.dart b/lib/view/RoundSearch.dart new file mode 100644 index 0000000..038788c --- /dev/null +++ b/lib/view/RoundSearch.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +typedef void SearchListener(string); + +class RoundSearch extends StatelessWidget { + final SearchListener onSearch; + + RoundSearch({ + Key key, + this.onSearch, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.all(16.0), + child: Material( + elevation: 16.0, + borderRadius: BorderRadius.circular(16.0), + color: Colors.white, + child: Padding( + padding: EdgeInsets.only(right: 8.0, left: 8.0), + child: TextField( + style: TextStyle(color: Colors.black), + cursorColor: Colors.grey, + keyboardType: TextInputType.text, + maxLines: 1, + onSubmitted: onSearch, + decoration: InputDecoration( + border: InputBorder.none, + hintText: "Search a launch...", + hintStyle: TextStyle(color: Colors.grey), + ), + ), + ), + ), + ), + ); + } +}