Compare commits

...

3 Commits

Author SHA1 Message Date
Michael Thomas 306defc6df Make header links work properly 2022-09-03 14:46:39 -04:00
Michael Thomas 373004f52a Fix event modal position 2022-09-03 14:46:24 -04:00
Michael Thomas 1c7f353e5f Migrate to auto_router 2022-09-03 14:46:00 -04:00
13 changed files with 640 additions and 476 deletions

View File

@ -2,5 +2,5 @@ import 'package:flutter/material.dart';
import 'package:furman_now/src/app.dart'; import 'package:furman_now/src/app.dart';
void main() { void main() {
runApp(const App()); runApp(App());
} }

View File

@ -1,147 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:furman_now/src/screens/events/index.dart'; import 'package:furman_now/src/routes/index.gr.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/utils/theme.dart'; import 'package:furman_now/src/utils/theme.dart';
import 'package:navbar_router/navbar_router.dart';
class App extends StatelessWidget { class App extends StatelessWidget {
const App({super.key}); App({super.key});
final _appRouter = AppRouter();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp.router(
title: 'Furman Now!', title: "Furman Now!",
home: const MainPage(), debugShowCheckedModeBanner: false,
routeInformationParser: _appRouter.defaultRouteParser(),
routerDelegate: _appRouter.delegate(),
theme: myFurmanTheme, theme: myFurmanTheme,
); );
} }
} }
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List<NavbarItem> 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<int, Map<String, Widget>> _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<void> navigate(BuildContext context, String route,
{bool isDialog = false,
bool isRootNavigator = true,
Map<String, dynamic>? arguments}) =>
Navigator.of(context, rootNavigator: isRootNavigator)
.pushNamed(route, arguments: arguments);

View File

@ -1,49 +1,96 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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({ const MainLayout({
Key? key, Key? key,
this.body,
}) : super(key: key); }) : super(key: key);
final Widget? body; @override
State<MainLayout> createState() => _MainLayoutState();
}
void _onItemTapped(int index) { class _MainLayoutState extends State<MainLayout> {
// Navigate to the second screen using a named route. DateTime oldTime = DateTime.now();
// Navigator.pushNamed(context, '/second'); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return AutoTabsScaffold(
body: body, routes: const [
bottomNavigationBar: BottomNavigationBar( HomeRoute(),
items: const <BottomNavigationBarItem>[ MapRoute(),
BottomNavigationBarItem( StudentIdRoute(),
icon: Icon(Icons.home), EventsRoute(),
label: 'Home', 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>[
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,
),
); );
} }
} }

View File

@ -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/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) { import '../layouts/main/index.dart';
switch (settings.name) {
case '/': @MaterialAutoRouter(
return MaterialPageRoute(builder: (_) => const HomeScreen()); replaceInRouteName: 'Screen,Route',
// case '/home': routes: <AutoRoute>[
// return MaterialPageRoute(builder: (_) => HomeScreen()); AutoRoute(path: "/", page: MainLayout, children: [
// case '/auth': AutoRoute(path: "home", page: HomeScreen),
// return MaterialPageRoute(builder: (_) => AuthenticationScreen()); AutoRoute(path: "map", page: MapScreen),
default: AutoRoute(path: "student-id", page: StudentIdScreen),
return MaterialPageRoute(builder: (_) => const HomeScreen()); AutoRoute(path: "events", page: EventsScreen),
} AutoRoute(path: "info", page: InfoScreen),
} ]),
],
)
class $AppRouter {}

View File

@ -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<String, _i7.PageFactory> pagesMap = {
MainLayout.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
routeData: routeData, child: const _i1.MainLayout());
},
HomeRoute.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
routeData: routeData, child: const _i2.HomeScreen());
},
MapRoute.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
routeData: routeData, child: const _i3.MapScreen());
},
StudentIdRoute.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
routeData: routeData, child: const _i4.StudentIdScreen());
},
EventsRoute.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
routeData: routeData, child: const _i5.EventsScreen());
},
InfoRoute.name: (routeData) {
return _i7.MaterialPageX<dynamic>(
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<void> {
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<void> {
const HomeRoute() : super(HomeRoute.name, path: 'home');
static const String name = 'HomeRoute';
}
/// generated route for
/// [_i3.MapScreen]
class MapRoute extends _i7.PageRouteInfo<void> {
const MapRoute() : super(MapRoute.name, path: 'map');
static const String name = 'MapRoute';
}
/// generated route for
/// [_i4.StudentIdScreen]
class StudentIdRoute extends _i7.PageRouteInfo<void> {
const StudentIdRoute() : super(StudentIdRoute.name, path: 'student-id');
static const String name = 'StudentIdRoute';
}
/// generated route for
/// [_i5.EventsScreen]
class EventsRoute extends _i7.PageRouteInfo<void> {
const EventsRoute() : super(EventsRoute.name, path: 'events');
static const String name = 'EventsRoute';
}
/// generated route for
/// [_i6.InfoScreen]
class InfoRoute extends _i7.PageRouteInfo<void> {
const InfoRoute() : super(InfoRoute.name, path: 'info');
static const String name = 'InfoRoute';
}

View File

@ -15,96 +15,93 @@ class EventsScreen extends StatelessWidget {
body: Container( body: Container(
color: Colors.grey[100], color: Colors.grey[100],
child: SafeArea( child: SafeArea(
child: Padding( child: Stack(
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), fit: StackFit.loose,
child: Stack( children: [
fit: StackFit.loose, SizedBox(
children: [ width: double.infinity,
SizedBox( height: double.infinity,
width: double.infinity, child: Align(
height: double.infinity, alignment: Alignment.topLeft,
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: Container( child: Container(
decoration: const BoxDecoration( padding: const EdgeInsets.symmetric(horizontal: 30),
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, width: double.infinity,
height: 100,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const HeaderWidget(title: "Today"), Wrap(
Padding( crossAxisAlignment: WrapCrossAlignment.center,
padding: const EdgeInsets.symmetric(horizontal: 20), children: [
child: EventsList() Icon(Icons.calendar_month_outlined, size: 35, color: Colors.grey[700]),
), const SizedBox(width: 12),
const HeaderWidget(title: "Tomorrow"), Text("Events", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
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"),
],
),
), ),
], ],
), ),
), ),
), ),
], ),
), 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"),
],
),
),
],
),
),
),
],
), ),
), ),
), ),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; 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/greeting.dart';
import 'package:furman_now/src/utils/theme.dart'; import 'package:furman_now/src/utils/theme.dart';
import 'package:furman_now/src/widgets/header.dart'; import 'package:furman_now/src/widgets/header.dart';
@ -18,7 +19,6 @@ class HomeScreen extends StatelessWidget {
child: SafeArea( child: SafeArea(
child: Container( child: Container(
color: Colors.grey[100], color: Colors.grey[100],
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
child: Stack( child: Stack(
fit: StackFit.loose, fit: StackFit.loose,
children: [ children: [
@ -68,7 +68,7 @@ class HomeScreen extends StatelessWidget {
children: [ children: [
const HeaderWidget( const HeaderWidget(
title: "Today's Events", title: "Today's Events",
link: HeaderLink(text: "View more", href: ""), link: HeaderLink(text: "View more", href: EventsRoute()),
), ),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 20), padding: const EdgeInsets.symmetric(horizontal: 20),

View File

@ -12,75 +12,72 @@ class InfoScreen extends StatelessWidget {
body: Container( body: Container(
color: Colors.grey[100], color: Colors.grey[100],
child: SafeArea( child: SafeArea(
child: Padding( child: Stack(
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), fit: StackFit.loose,
child: Stack( children: [
fit: StackFit.loose, SizedBox(
children: [ width: double.infinity,
SizedBox( height: double.infinity,
width: double.infinity, child: Align(
height: double.infinity, alignment: Alignment.topLeft,
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: Container( child: Container(
decoration: const BoxDecoration( padding: const EdgeInsets.symmetric(horizontal: 30),
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, width: double.infinity,
height: 100,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
InfoCard( Wrap(
color: Colors.red.shade50, crossAxisAlignment: WrapCrossAlignment.center,
icon: Icons.local_hospital, children: [
title: "Health and Safety", Icon(Icons.info_outline, size: 35, color: Colors.grey[700]),
description: "Important contact information and links regarding student health and safety.", const SizedBox(width: 12),
), Text("Info", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
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.",
), ),
], ],
), ),
), ),
), ),
], ),
), 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.",
),
],
),
),
),
],
), ),
), ),
), ),

View File

@ -82,145 +82,142 @@ class _MapScreenState extends State<MapScreen>
color: const Color(0xffb7acc9), color: const Color(0xffb7acc9),
child: SafeArea( child: SafeArea(
top: false, top: false,
child: Padding( child: Stack(
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight), children: [
child: Stack( FlutterMap(
children: [ mapController: _mapController,
FlutterMap( options: MapOptions(
mapController: _mapController, center: LatLng(34.925926, -82.439397),
options: MapOptions( enableMultiFingerGestureRace: true,
center: LatLng(34.925926, -82.439397), rotationWinGestures: MultiFingerGesture.all,
enableMultiFingerGestureRace: true, pinchZoomThreshold: 0.2,
rotationWinGestures: MultiFingerGesture.all, rotationThreshold: 8,
pinchZoomThreshold: 0.2, zoom: 15,
rotationThreshold: 8, minZoom: 12,
zoom: 15, maxZoom: 18,
minZoom: 12, plugins: [
maxZoom: 18, LocationMarkerPlugin(
plugins: [ centerCurrentLocationStream:
LocationMarkerPlugin( _centerCurrentLocationStreamController.stream,
centerCurrentLocationStream: centerOnLocationUpdate: _centerOnLocationUpdate,
_centerCurrentLocationStreamController.stream, ),
centerOnLocationUpdate: _centerOnLocationUpdate, ],
), onPositionChanged: (MapPosition position, bool hasGesture) {
], if (hasGesture) {
onPositionChanged: (MapPosition position, bool hasGesture) { setState(
if (hasGesture) { () => _centerOnLocationUpdate = CenterOnLocationUpdate.never,
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: // Rotation reset fab
"https://tile.openstreetmap.org/{z}/{x}/{y}.png", Positioned(
userAgentPackageName: 'edu.furman.now', top: 12,
), left: 0,
LocationMarkerLayerOptions(), right: 0,
], child: SafeArea(
nonRotatedChildren: [ child: Column(
AttributionWidget( crossAxisAlignment: CrossAxisAlignment.start,
attributionBuilder: (BuildContext context) { children: [
return const ColoredBox( Padding(
color: Color(0xCCFFFFFF), padding: const EdgeInsets.symmetric(horizontal: 12),
child: Padding( child: Container(
padding: EdgeInsets.all(3), width: double.infinity,
child: Text("©️ OpenStreetMap contributors"), 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(
// Rotation reset fab crossAxisAlignment: WrapCrossAlignment.center,
Positioned( children: [
top: 12, SvgPicture.asset("assets/images/bell-tower.svg", color: Theme.of(context).primaryColor, height: 32),
left: 0, const SizedBox(width: 10),
right: 0, Text(
child: SafeArea( "Search locations",
child: Column( style: furmanTextStyle(TextStyle(
crossAxisAlignment: CrossAxisAlignment.start, fontSize: 18,
children: [ fontWeight: FontWeight.w500,
Padding( color: Colors.grey.shade500,
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,
)),
),
],
),
),
],
),
),
),
// 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, Positioned(
bottom: 20, right: 20,
child: FloatingActionButton( bottom: 20,
onPressed: () { child: FloatingActionButton(
// Automatically center the location marker on the map when location updated until user interact with the map. onPressed: () {
setState( // Automatically center the location marker on the map when location updated until user interact with the map.
() => _centerOnLocationUpdate = CenterOnLocationUpdate.always, setState(
); () => _centerOnLocationUpdate = CenterOnLocationUpdate.always,
// Center the location marker on the map and zoom the map to level 18. );
_centerCurrentLocationStreamController.add(16); // Center the location marker on the map and zoom the map to level 18.
}, _centerCurrentLocationStreamController.add(16);
child: const Icon( },
Icons.my_location, child: const Icon(
color: Colors.white, Icons.my_location,
), color: Colors.white,
) ),
) )
], )
), ],
), ),
), ),
), ),

View File

@ -35,12 +35,12 @@ class _EventModalState extends State<_EventModal> {
void updateMaxHeight() { void updateMaxHeight() {
if (_parentConstraints != null) { if (_parentConstraints != null) {
print(_key.currentContext?.size?.height);
var listHeight = _key.currentContext?.size?.height; var listHeight = _key.currentContext?.size?.height;
var parentHeight = _parentConstraints?.maxHeight; var parentHeight = _parentConstraints?.maxHeight;
if (listHeight != null && parentHeight != null) { if (listHeight != null && parentHeight != null) {
var maxHeight = (listHeight + 50) / parentHeight;
setState(() { setState(() {
_maxChildHeight = (listHeight + 150) / parentHeight; _maxChildHeight = (maxHeight < 0.75) ? maxHeight : 0.75;
}); });
} }
} }
@ -71,8 +71,6 @@ class _EventModalState extends State<_EventModal> {
builder: (_, controller) { builder: (_, controller) {
return Container( return Container(
color: Colors.grey.shade100, color: Colors.grey.shade100,
margin: const EdgeInsets.only(
bottom: kBottomNavigationBarHeight),
child: Column( child: Column(
children: [ children: [
const Align( const Align(
@ -119,7 +117,7 @@ class _EventModalContent extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.symmetric(horizontal: 40), padding: const EdgeInsets.only(left: 40, right: 40, bottom: 40),
controller: controller, controller: controller,
children: <Widget>[ children: <Widget>[
// Title // Title

View File

@ -1,3 +1,4 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:furman_now/src/utils/theme.dart'; import 'package:furman_now/src/utils/theme.dart';
@ -28,13 +29,16 @@ class HeaderWidget extends StatelessWidget {
)), )),
), ),
if (link != null) if (link != null)
Text( GestureDetector(
link!.text, onTap: () => context.router.navigate(link!.href),
style: furmanTextStyle(const TextStyle( child: Text(
color: Color(0xff755898), link!.text,
fontSize: 12, style: furmanTextStyle(const TextStyle(
fontWeight: FontWeight.bold, color: Color(0xff755898),
)), fontSize: 12,
fontWeight: FontWeight.bold,
)),
),
), ),
], ],
), ),
@ -45,7 +49,7 @@ class HeaderWidget extends StatelessWidget {
@immutable @immutable
class HeaderLink { class HeaderLink {
final String text; final String text;
final String href; final PageRouteInfo href;
const HeaderLink({ const HeaderLink({
required this.text, required this.text,

View File

@ -36,6 +36,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.1" 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: barcode:
dependency: transitive dependency: transitive
description: description:
@ -57,6 +64,62 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" 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: characters:
dependency: transitive dependency: transitive
description: description:
@ -71,6 +134,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -78,6 +148,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -113,6 +190,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" 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: english_words:
dependency: "direct main" dependency: "direct main"
description: description:
@ -141,6 +225,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -254,6 +345,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -296,6 +394,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.4" version: "0.6.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.0"
latlong2: latlong2:
dependency: "direct main" dependency: "direct main"
description: description:
@ -359,13 +464,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" 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: node_preamble:
dependency: transitive dependency: transitive
description: description:
@ -520,6 +618,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
qr: qr:
dependency: transitive dependency: transitive
description: description:
@ -567,6 +672,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" 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: source_map_stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -602,6 +714,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" 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: string_scanner:
dependency: transitive dependency: transitive
description: description:
@ -637,6 +756,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.13" version: "0.4.13"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
tuple: tuple:
dependency: transitive dependency: transitive
description: description:

View File

@ -30,12 +30,10 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
english_words: ^4.0.0 english_words: ^4.0.0
navbar_router: ^0.3.2
intl: ^0.17.0 intl: ^0.17.0
google_fonts: ^3.0.1 google_fonts: ^3.0.1
http: ^0.13.5 http: ^0.13.5
@ -60,6 +58,8 @@ dev_dependencies:
# package. See that file for information about deactivating specific lint # package. See that file for information about deactivating specific lint
# rules and activating additional ones. # rules and activating additional ones.
flutter_lints: ^2.0.0 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 # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec