diff --git a/lib/main.dart b/lib/main.dart index 4cebb67..93553aa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,5 +2,5 @@ import 'package:flutter/material.dart'; import 'package:furman_now/src/app.dart'; void main() { - runApp(const App()); + runApp(App()); } diff --git a/lib/src/app.dart b/lib/src/app.dart index 6e16d1d..62f72a1 100644 --- a/lib/src/app.dart +++ b/lib/src/app.dart @@ -1,147 +1,20 @@ import 'package:flutter/material.dart'; -import 'package:furman_now/src/screens/events/index.dart'; -import 'package:furman_now/src/screens/home/index.dart'; -import 'package:furman_now/src/screens/info/index.dart'; -import 'package:furman_now/src/screens/map/index.dart'; -import 'package:furman_now/src/screens/student_id/index.dart'; +import 'package:furman_now/src/routes/index.gr.dart'; import 'package:furman_now/src/utils/theme.dart'; -import 'package:navbar_router/navbar_router.dart'; class App extends StatelessWidget { - const App({super.key}); + App({super.key}); + + final _appRouter = AppRouter(); @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Furman Now!', - home: const MainPage(), + return MaterialApp.router( + title: "Furman Now!", + debugShowCheckedModeBanner: false, + routeInformationParser: _appRouter.defaultRouteParser(), + routerDelegate: _appRouter.delegate(), theme: myFurmanTheme, ); } } - -class MainPage extends StatefulWidget { - const MainPage({Key? key}) : super(key: key); - - @override - State createState() => _MainPageState(); -} - -class _MainPageState extends State { - List items = [ - NavbarItem(Icons.home_outlined, 'Home', backgroundColor: colors[0]), - NavbarItem(Icons.map_outlined, 'Map', backgroundColor: colors[0]), - NavbarItem(Icons.person_outline, 'Meal ID', backgroundColor: colors[0]), - NavbarItem(Icons.calendar_month_outlined, 'Events', backgroundColor: colors[0]), - NavbarItem(Icons.info_outline, 'Info', backgroundColor: colors[0]), - ]; - - final Map> _routes = const { - 0: { - '/': HomeScreen(), - // FeedDetail.route: FeedDetail(), - }, - 1: { - '/': MapScreen(), - // ProductDetail.route: ProductDetail(), - // ProductComments.route: ProductComments(), - }, - 2: { - '/': StudentIdScreen(), - // ProductDetail.route: ProductDetail(), - // ProductComments.route: ProductComments(), - }, - 3: { - '/': EventsScreen(), - // ProfileEdit.route: ProfileEdit(), - }, - 4: { - '/': InfoScreen(), - // ProfileEdit.route: ProfileEdit(), - }, - }; - - void showSnackBar() { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - duration: Duration(milliseconds: 600), - margin: EdgeInsets.only( - bottom: kBottomNavigationBarHeight + 2, right: 2, left: 2), - content: Text('Tap back button again to exit'), - ), - ); - } - - void hideSnackBar() { - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - } - - DateTime oldTime = DateTime.now(); - DateTime newTime = DateTime.now(); - - @override - Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; - return Scaffold( - resizeToAvoidBottomInset: false, - body: NavbarRouter( - errorBuilder: (context) { - return const Center(child: Text('Error 404')); - }, - isDesktop: size.width > 600 ? true : false, - onBackButtonPressed: (isExitingApp) { - if (isExitingApp) { - newTime = DateTime.now(); - int difference = newTime.difference(oldTime).inMilliseconds; - oldTime = newTime; - if (difference < 1000) { - hideSnackBar(); - return isExitingApp; - } else { - showSnackBar(); - return false; - } - } else { - return isExitingApp; - } - }, - destinationAnimationCurve: Curves.fastOutSlowIn, - destinationAnimationDuration: 600, - decoration: NavbarDecoration( - selectedLabelTextStyle: const TextStyle(color: Colors.deepPurple), - showUnselectedLabels: true, - unselectedLabelTextStyle: - const TextStyle(color: Colors.black, fontSize: 10), - selectedIconTheme: const IconThemeData(color: Colors.deepPurple), - isExtended: size.width > 800 ? true : false, - navbarType: BottomNavigationBarType.fixed), - // onChanged: (x) { - // debugPrint('index changed $x'); - // }, - backButtonBehavior: BackButtonBehavior.rememberHistory, - destinations: [ - for (int i = 0; i < items.length; i++) - DestinationRouter( - navbarItem: items[i], - destinations: [ - for (int j = 0; j < _routes[i]!.keys.length; j++) - Destination( - route: _routes[i]!.keys.elementAt(j), - widget: _routes[i]!.values.elementAt(j), - ), - ], - initialRoute: _routes[i]!.keys.first, - ), - ], - ), - ); - } -} - -Future navigate(BuildContext context, String route, - {bool isDialog = false, - bool isRootNavigator = true, - Map? arguments}) => - Navigator.of(context, rootNavigator: isRootNavigator) - .pushNamed(route, arguments: arguments); diff --git a/lib/src/layouts/main/index.dart b/lib/src/layouts/main/index.dart index da17dea..b804df5 100644 --- a/lib/src/layouts/main/index.dart +++ b/lib/src/layouts/main/index.dart @@ -1,49 +1,96 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:furman_now/src/routes/index.gr.dart'; -class MainLayout extends StatelessWidget { +class MainLayout extends StatefulWidget { const MainLayout({ Key? key, - this.body, }) : super(key: key); - final Widget? body; + @override + State createState() => _MainLayoutState(); +} - void _onItemTapped(int index) { - // Navigate to the second screen using a named route. - // Navigator.pushNamed(context, '/second'); +class _MainLayoutState extends State { + DateTime oldTime = DateTime.now(); + DateTime newTime = DateTime.now(); + + void showSnackBar() { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + duration: Duration(milliseconds: 600), + margin: EdgeInsets.only(bottom: 2, right: 2, left: 2), + content: Text('Tap back button again to exit'), + ), + ); + } + + void hideSnackBar() { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); } @override Widget build(BuildContext context) { - return Scaffold( - body: body, - bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Home', + return AutoTabsScaffold( + routes: const [ + HomeRoute(), + MapRoute(), + StudentIdRoute(), + EventsRoute(), + InfoRoute(), + ], + bottomNavigationBuilder: (_, tabsRouter) { + return WillPopScope( + onWillPop: () async { + if (tabsRouter.canNavigateBack) { + tabsRouter.navigateBack(); + return false; + } else { + // if can't navigate back then we're probably trying to exit + newTime = DateTime.now(); + int difference = newTime.difference(oldTime).inMilliseconds; + oldTime = newTime; + if (difference < 1000) { + hideSnackBar(); + return true; + } else { + showSnackBar(); + return false; + } + } + }, + child: BottomNavigationBar( + items: const [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Home', + ), + BottomNavigationBarItem( + icon: Icon(Icons.map), + label: 'Map', + ), + BottomNavigationBarItem( + icon: Icon(Icons.perm_identity), + label: 'Meal Card', + ), + BottomNavigationBarItem( + icon: Icon(Icons.calendar_month), + label: 'Events', + ), + BottomNavigationBarItem( + icon: Icon(Icons.info_outline), + label: 'Info', + ), + ], + currentIndex: tabsRouter.activeIndex, + selectedItemColor: Theme.of(context).primaryColor, + unselectedItemColor: Colors.grey[600], + onTap: tabsRouter.setActiveIndex, ), - BottomNavigationBarItem( - icon: Icon(Icons.map), - label: 'Map', - ), - BottomNavigationBarItem( - icon: Icon(Icons.perm_identity), - label: 'Meal Card', - ), - BottomNavigationBarItem( - icon: Icon(Icons.calendar_month), - label: 'Events', - ), - BottomNavigationBarItem( - icon: Icon(Icons.info_outline), - label: 'Info', - ), - ], - currentIndex: 0, - selectedItemColor: Colors.grey[700], - onTap: _onItemTapped, - ), + ); + }, ); } } \ No newline at end of file diff --git a/lib/src/routes/index.dart b/lib/src/routes/index.dart index 3eff20e..e5400ec 100644 --- a/lib/src/routes/index.dart +++ b/lib/src/routes/index.dart @@ -1,15 +1,22 @@ -import 'package:flutter/material.dart'; +import 'package:auto_route/auto_route.dart'; +import 'package:furman_now/src/screens/events/index.dart'; import 'package:furman_now/src/screens/home/index.dart'; +import 'package:furman_now/src/screens/info/index.dart'; +import 'package:furman_now/src/screens/map/index.dart'; +import 'package:furman_now/src/screens/student_id/index.dart'; -Route routes(RouteSettings settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute(builder: (_) => const HomeScreen()); - // case '/home': - // return MaterialPageRoute(builder: (_) => HomeScreen()); - // case '/auth': - // return MaterialPageRoute(builder: (_) => AuthenticationScreen()); - default: - return MaterialPageRoute(builder: (_) => const HomeScreen()); - } -} +import '../layouts/main/index.dart'; + +@MaterialAutoRouter( + replaceInRouteName: 'Screen,Route', + routes: [ + AutoRoute(path: "/", page: MainLayout, children: [ + AutoRoute(path: "home", page: HomeScreen), + AutoRoute(path: "map", page: MapScreen), + AutoRoute(path: "student-id", page: StudentIdScreen), + AutoRoute(path: "events", page: EventsScreen), + AutoRoute(path: "info", page: InfoScreen), + ]), + ], +) +class $AppRouter {} \ No newline at end of file diff --git a/lib/src/routes/index.gr.dart b/lib/src/routes/index.gr.dart new file mode 100644 index 0000000..244e358 --- /dev/null +++ b/lib/src/routes/index.gr.dart @@ -0,0 +1,118 @@ +// ************************************************************************** +// AutoRouteGenerator +// ************************************************************************** + +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// AutoRouteGenerator +// ************************************************************************** +// +// ignore_for_file: type=lint + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:auto_route/auto_route.dart' as _i7; +import 'package:flutter/material.dart' as _i8; + +import '../layouts/main/index.dart' as _i1; +import '../screens/events/index.dart' as _i5; +import '../screens/home/index.dart' as _i2; +import '../screens/info/index.dart' as _i6; +import '../screens/map/index.dart' as _i3; +import '../screens/student_id/index.dart' as _i4; + +class AppRouter extends _i7.RootStackRouter { + AppRouter([_i8.GlobalKey<_i8.NavigatorState>? navigatorKey]) + : super(navigatorKey); + + @override + final Map pagesMap = { + MainLayout.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i1.MainLayout()); + }, + HomeRoute.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i2.HomeScreen()); + }, + MapRoute.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i3.MapScreen()); + }, + StudentIdRoute.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i4.StudentIdScreen()); + }, + EventsRoute.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i5.EventsScreen()); + }, + InfoRoute.name: (routeData) { + return _i7.MaterialPageX( + routeData: routeData, child: const _i6.InfoScreen()); + } + }; + + @override + List<_i7.RouteConfig> get routes => [ + _i7.RouteConfig(MainLayout.name, path: '/', children: [ + _i7.RouteConfig(HomeRoute.name, + path: 'home', parent: MainLayout.name), + _i7.RouteConfig(MapRoute.name, path: 'map', parent: MainLayout.name), + _i7.RouteConfig(StudentIdRoute.name, + path: 'student-id', parent: MainLayout.name), + _i7.RouteConfig(EventsRoute.name, + path: 'events', parent: MainLayout.name), + _i7.RouteConfig(InfoRoute.name, path: 'info', parent: MainLayout.name) + ]) + ]; +} + +/// generated route for +/// [_i1.MainLayout] +class MainLayout extends _i7.PageRouteInfo { + const MainLayout({List<_i7.PageRouteInfo>? children}) + : super(MainLayout.name, path: '/', initialChildren: children); + + static const String name = 'MainLayout'; +} + +/// generated route for +/// [_i2.HomeScreen] +class HomeRoute extends _i7.PageRouteInfo { + const HomeRoute() : super(HomeRoute.name, path: 'home'); + + static const String name = 'HomeRoute'; +} + +/// generated route for +/// [_i3.MapScreen] +class MapRoute extends _i7.PageRouteInfo { + const MapRoute() : super(MapRoute.name, path: 'map'); + + static const String name = 'MapRoute'; +} + +/// generated route for +/// [_i4.StudentIdScreen] +class StudentIdRoute extends _i7.PageRouteInfo { + const StudentIdRoute() : super(StudentIdRoute.name, path: 'student-id'); + + static const String name = 'StudentIdRoute'; +} + +/// generated route for +/// [_i5.EventsScreen] +class EventsRoute extends _i7.PageRouteInfo { + const EventsRoute() : super(EventsRoute.name, path: 'events'); + + static const String name = 'EventsRoute'; +} + +/// generated route for +/// [_i6.InfoScreen] +class InfoRoute extends _i7.PageRouteInfo { + const InfoRoute() : super(InfoRoute.name, path: 'info'); + + static const String name = 'InfoRoute'; +} diff --git a/lib/src/screens/events/index.dart b/lib/src/screens/events/index.dart index 3c2af3e..bff7bac 100644 --- a/lib/src/screens/events/index.dart +++ b/lib/src/screens/events/index.dart @@ -15,96 +15,93 @@ class EventsScreen extends StatelessWidget { body: Container( color: Colors.grey[100], child: SafeArea( - child: Padding( - padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), - child: Stack( - fit: StackFit.loose, - children: [ - SizedBox( - width: double.infinity, - height: double.infinity, - child: Align( - alignment: Alignment.topLeft, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 30), - width: double.infinity, - height: 100, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon(Icons.calendar_month_outlined, size: 35, color: Colors.grey[700]), - const SizedBox(width: 12), - Text("Events", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))), - ], - ), - ], - ), - ), - ), - ), - ScrollViewWithHeight( + child: Stack( + fit: StackFit.loose, + children: [ + SizedBox( + width: double.infinity, + height: double.infinity, + child: Align( + alignment: Alignment.topLeft, child: Container( - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.vertical(top: Radius.circular(30)), - ), - padding: const EdgeInsets.symmetric(vertical: 20), - margin: const EdgeInsets.only(top: 100), + padding: const EdgeInsets.symmetric(horizontal: 30), width: double.infinity, + height: 100, child: Column( + mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const HeaderWidget(title: "Today"), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: EventsList() - ), - const HeaderWidget(title: "Tomorrow"), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: EventsList(dateRange: constructDateRange( - DateTime.now().add(const Duration(days: 1)), - DateTime.now().add(const Duration(days: 1)), - )), - ), - ...[for(var i=2; i<7; i+=1) i].map((i) { - var date = DateTime.now().add(Duration(days: i)); - var dayName = DateFormat('EEEE').format(date); - return Wrap( - children: [ - HeaderWidget(title: dayName), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: EventsList(dateRange: constructDateRange( - date, - date, - )), - ), - ], - ); - }), - Center(child: - Wrap( - direction: Axis.vertical, - crossAxisAlignment: WrapCrossAlignment.center, - children: const [ - Text("Need more events?"), - Text("Syncdin"), - Text("Athletics"), - Text("CLPs"), - ], - ), + Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Icon(Icons.calendar_month_outlined, size: 35, color: Colors.grey[700]), + const SizedBox(width: 12), + Text("Events", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))), + ], ), ], ), ), ), - ], - ), + ), + ScrollViewWithHeight( + child: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(30)), + ), + padding: const EdgeInsets.symmetric(vertical: 20), + margin: const EdgeInsets.only(top: 100), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const HeaderWidget(title: "Today"), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: EventsList() + ), + const HeaderWidget(title: "Tomorrow"), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: EventsList(dateRange: constructDateRange( + DateTime.now().add(const Duration(days: 1)), + DateTime.now().add(const Duration(days: 1)), + )), + ), + ...[for(var i=2; i<7; i+=1) i].map((i) { + var date = DateTime.now().add(Duration(days: i)); + var dayName = DateFormat('EEEE').format(date); + return Wrap( + children: [ + HeaderWidget(title: dayName), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: EventsList(dateRange: constructDateRange( + date, + date, + )), + ), + ], + ); + }), + Center(child: + Wrap( + direction: Axis.vertical, + crossAxisAlignment: WrapCrossAlignment.center, + children: const [ + Text("Need more events?"), + Text("Syncdin"), + Text("Athletics"), + Text("CLPs"), + ], + ), + ), + ], + ), + ), + ), + ], ), ), ), diff --git a/lib/src/screens/home/index.dart b/lib/src/screens/home/index.dart index 2c136e1..81f4e94 100644 --- a/lib/src/screens/home/index.dart +++ b/lib/src/screens/home/index.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:furman_now/src/routes/index.gr.dart'; import 'package:furman_now/src/utils/greeting.dart'; import 'package:furman_now/src/utils/theme.dart'; import 'package:furman_now/src/widgets/header.dart'; @@ -18,7 +19,6 @@ class HomeScreen extends StatelessWidget { child: SafeArea( child: Container( color: Colors.grey[100], - padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), child: Stack( fit: StackFit.loose, children: [ @@ -68,7 +68,7 @@ class HomeScreen extends StatelessWidget { children: [ const HeaderWidget( title: "Today's Events", - link: HeaderLink(text: "View more", href: ""), + link: HeaderLink(text: "View more", href: EventsRoute()), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 20), diff --git a/lib/src/screens/info/index.dart b/lib/src/screens/info/index.dart index 51842fc..84f8ea3 100644 --- a/lib/src/screens/info/index.dart +++ b/lib/src/screens/info/index.dart @@ -12,75 +12,72 @@ class InfoScreen extends StatelessWidget { body: Container( color: Colors.grey[100], child: SafeArea( - child: Padding( - padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), - child: Stack( - fit: StackFit.loose, - children: [ - SizedBox( - width: double.infinity, - height: double.infinity, - child: Align( - alignment: Alignment.topLeft, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 30), - width: double.infinity, - height: 100, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon(Icons.info_outline, size: 35, color: Colors.grey[700]), - const SizedBox(width: 12), - Text("Info", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))), - ], - ), - ], - ), - ), - ), - ), - ScrollViewWithHeight( + child: Stack( + fit: StackFit.loose, + children: [ + SizedBox( + width: double.infinity, + height: double.infinity, + child: Align( + alignment: Alignment.topLeft, child: Container( - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.vertical(top: Radius.circular(30)), - ), - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), - margin: const EdgeInsets.only(top: 100), + padding: const EdgeInsets.symmetric(horizontal: 30), width: double.infinity, + height: 100, child: Column( + mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - InfoCard( - color: Colors.red.shade50, - icon: Icons.local_hospital, - title: "Health and Safety", - description: "Important contact information and links regarding student health and safety.", - ), - const SizedBox(height: 10), - InfoCard( - color: Colors.deepPurple.shade50, - icon: Icons.phone, - title: "Contacts", - description: "Important contact information and links regarding student health and safety.", - ), - const SizedBox(height: 10), - InfoCard( - color: Colors.blue.shade50, - icon: Icons.access_time, - title: "Hours", - description: "Important contact information and links regarding student health and safety.", + Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Icon(Icons.info_outline, size: 35, color: Colors.grey[700]), + const SizedBox(width: 12), + Text("Info", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))), + ], ), ], ), ), ), - ], - ), + ), + ScrollViewWithHeight( + child: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(30)), + ), + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + margin: const EdgeInsets.only(top: 100), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InfoCard( + color: Colors.red.shade50, + icon: Icons.local_hospital, + title: "Health and Safety", + description: "Important contact information and links regarding student health and safety.", + ), + const SizedBox(height: 10), + InfoCard( + color: Colors.deepPurple.shade50, + icon: Icons.phone, + title: "Contacts", + description: "Important contact information and links regarding student health and safety.", + ), + const SizedBox(height: 10), + InfoCard( + color: Colors.blue.shade50, + icon: Icons.access_time, + title: "Hours", + description: "Important contact information and links regarding student health and safety.", + ), + ], + ), + ), + ), + ], ), ), ), diff --git a/lib/src/screens/map/index.dart b/lib/src/screens/map/index.dart index c6d4283..fafeeec 100644 --- a/lib/src/screens/map/index.dart +++ b/lib/src/screens/map/index.dart @@ -82,145 +82,142 @@ class _MapScreenState extends State color: const Color(0xffb7acc9), child: SafeArea( top: false, - child: Padding( - padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), - child: Stack( - children: [ - FlutterMap( - mapController: _mapController, - options: MapOptions( - center: LatLng(34.925926, -82.439397), - enableMultiFingerGestureRace: true, - rotationWinGestures: MultiFingerGesture.all, - pinchZoomThreshold: 0.2, - rotationThreshold: 8, - zoom: 15, - minZoom: 12, - maxZoom: 18, - plugins: [ - LocationMarkerPlugin( - centerCurrentLocationStream: - _centerCurrentLocationStreamController.stream, - centerOnLocationUpdate: _centerOnLocationUpdate, - ), - ], - onPositionChanged: (MapPosition position, bool hasGesture) { - if (hasGesture) { - setState( - () => _centerOnLocationUpdate = CenterOnLocationUpdate.never, - ); - } + child: Stack( + children: [ + FlutterMap( + mapController: _mapController, + options: MapOptions( + center: LatLng(34.925926, -82.439397), + enableMultiFingerGestureRace: true, + rotationWinGestures: MultiFingerGesture.all, + pinchZoomThreshold: 0.2, + rotationThreshold: 8, + zoom: 15, + minZoom: 12, + maxZoom: 18, + plugins: [ + LocationMarkerPlugin( + centerCurrentLocationStream: + _centerCurrentLocationStreamController.stream, + centerOnLocationUpdate: _centerOnLocationUpdate, + ), + ], + onPositionChanged: (MapPosition position, bool hasGesture) { + if (hasGesture) { + setState( + () => _centerOnLocationUpdate = CenterOnLocationUpdate.never, + ); + } + }, + ), + layers: [ + TileLayerOptions( + urlTemplate: + "https://tile.openstreetmap.org/{z}/{x}/{y}.png", + userAgentPackageName: 'edu.furman.now', + ), + LocationMarkerLayerOptions(), + ], + nonRotatedChildren: [ + AttributionWidget( + attributionBuilder: (BuildContext context) { + return const ColoredBox( + color: Color(0xCCFFFFFF), + child: Padding( + padding: EdgeInsets.all(3), + child: Text("©️ OpenStreetMap contributors"), + ), + ); }, ), - layers: [ - TileLayerOptions( - urlTemplate: - "https://tile.openstreetmap.org/{z}/{x}/{y}.png", - userAgentPackageName: 'edu.furman.now', - ), - LocationMarkerLayerOptions(), - ], - nonRotatedChildren: [ - AttributionWidget( - attributionBuilder: (BuildContext context) { - return const ColoredBox( - color: Color(0xCCFFFFFF), - child: Padding( - padding: EdgeInsets.all(3), - child: Text("©️ OpenStreetMap contributors"), + ], + ), + // Rotation reset fab + Positioned( + top: 12, + left: 0, + right: 0, + child: SafeArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Container( + width: double.infinity, + height: 50, + padding: const EdgeInsets.only(left: 10, right: 20), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(60)), + boxShadow: [ + BoxShadow( + color: Color(0x33000000), + blurRadius: 8, + ), + ], ), - ); - }, - ), - ], - ), - // Rotation reset fab - Positioned( - top: 12, - left: 0, - right: 0, - child: SafeArea( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Container( - width: double.infinity, - height: 50, - padding: const EdgeInsets.only(left: 10, right: 20), - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(60)), - boxShadow: [ - BoxShadow( - color: Color(0x33000000), - blurRadius: 8, + child: Stack( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + SvgPicture.asset("assets/images/bell-tower.svg", color: Theme.of(context).primaryColor, height: 32), + const SizedBox(width: 10), + Text( + "Search locations", + style: furmanTextStyle(TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Colors.grey.shade500, + )), + ), + ], ), - ], - ), - child: Stack( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - SvgPicture.asset("assets/images/bell-tower.svg", color: Theme.of(context).primaryColor, height: 32), - const SizedBox(width: 10), - Text( - "Search locations", - style: furmanTextStyle(TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - color: Colors.grey.shade500, - )), - ), - ], - ), - ), - ], - ), - ), - ), - // const SizedBox(height: 12), - SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), - scrollDirection: Axis.horizontal, - child: Wrap( - spacing: 6, - children: const [ - MapFilterChip(icon: Icons.restaurant, text: "Restaurants"), - MapFilterChip(icon: Icons.train, text: "Transportation"), - MapFilterChip(icon: Icons.school, text: "Campus Buildings"), + ), ], ), ), - MapRotateCompass(rotation: _rotation, resetRotation: resetRotation), - ], - ), + ), + // const SizedBox(height: 12), + SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + scrollDirection: Axis.horizontal, + child: Wrap( + spacing: 6, + children: const [ + MapFilterChip(icon: Icons.restaurant, text: "Restaurants"), + MapFilterChip(icon: Icons.train, text: "Transportation"), + MapFilterChip(icon: Icons.school, text: "Campus Buildings"), + ], + ), + ), + MapRotateCompass(rotation: _rotation, resetRotation: resetRotation), + ], ), ), - Positioned( - right: 20, - bottom: 20, - child: FloatingActionButton( - onPressed: () { - // Automatically center the location marker on the map when location updated until user interact with the map. - setState( - () => _centerOnLocationUpdate = CenterOnLocationUpdate.always, - ); - // Center the location marker on the map and zoom the map to level 18. - _centerCurrentLocationStreamController.add(16); - }, - child: const Icon( - Icons.my_location, - color: Colors.white, - ), - ) + ), + Positioned( + right: 20, + bottom: 20, + child: FloatingActionButton( + onPressed: () { + // Automatically center the location marker on the map when location updated until user interact with the map. + setState( + () => _centerOnLocationUpdate = CenterOnLocationUpdate.always, + ); + // Center the location marker on the map and zoom the map to level 18. + _centerCurrentLocationStreamController.add(16); + }, + child: const Icon( + Icons.my_location, + color: Colors.white, + ), ) - ], - ), + ) + ], ), ), ), diff --git a/pubspec.lock b/pubspec.lock index 37fb60d..6293e2f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -36,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.1" + auto_route_generator: + dependency: "direct dev" + description: + name: auto_route_generator + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.2" barcode: dependency: transitive description: @@ -57,6 +64,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.3" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.4.1" characters: dependency: transitive description: @@ -71,6 +134,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -78,6 +148,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.0" collection: dependency: transitive description: @@ -113,6 +190,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" english_words: dependency: "direct main" description: @@ -141,6 +225,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" flutter: dependency: "direct main" description: flutter @@ -254,6 +345,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" http: dependency: "direct main" description: @@ -296,6 +394,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.4" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.6.0" latlong2: dependency: "direct main" description: @@ -359,13 +464,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - navbar_router: - dependency: "direct main" - description: - name: navbar_router - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.2" node_preamble: dependency: transitive description: @@ -520,6 +618,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" qr: dependency: transitive description: @@ -567,6 +672,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2" source_map_stack_trace: dependency: transitive description: @@ -602,6 +714,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" string_scanner: dependency: transitive description: @@ -637,6 +756,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.13" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" tuple: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7f68f31..b833515 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,12 +30,10 @@ dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 english_words: ^4.0.0 - navbar_router: ^0.3.2 intl: ^0.17.0 google_fonts: ^3.0.1 http: ^0.13.5 @@ -60,6 +58,8 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + auto_route_generator: ^5.0.1 + build_runner: ^2.2.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec