Files
Krow-workspace/mobile-apps/client-app/lib/features/home/presentation/home_screen.dart

247 lines
6.8 KiB
Dart

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gap/gap.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/core/application/routing/routes.gr.dart';
import 'package:krow/core/presentation/gen/assets.gen.dart';
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
import 'package:krow/core/presentation/styles/theme.dart';
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
import 'package:krow/core/sevices/app_update_service.dart';
import 'package:krow/features/home/presentation/create_event_widget.dart';
import '../../notificatins/domain/bloc/notifications_bloc.dart';
BuildContext? _nestedContext;
BuildContext? homeContext;
@RoutePage()
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final ListenableOverlayPortalController _controller =
ListenableOverlayPortalController();
final List<PageRouteInfo> _routes = const [
EventsFlowRoute(),
InvoiceFlowRoute(),
NotificationFlowRoute(),
ProfileFlowRoute(),
];
bool _shouldHideBottomNavBar(BuildContext nestedContext) {
final currentPath = context.router.currentPath;
return _allowBottomNavBarRoutes
.any((route) => currentPath == route.toString());
}
final List<String> _allowBottomNavBarRoutes = [
'/home/events/list',
'/home/invoice/list',
'/home/notifications/list',
'/home/profile/preview',
];
double opacity = 0.0;
getMediaQueryData(BuildContext context) {
if (!_shouldHideBottomNavBar(context)) {
return MediaQuery.of(context);
} else {
//76 - navigation height, 22 - bottom padding
var newBottomPadding = MediaQuery.of(context).padding.bottom + 76 + 22;
var newPadding =
MediaQuery.of(context).padding.copyWith(bottom: newBottomPadding);
return MediaQuery.of(context).copyWith(padding: newPadding);
}
}
@override
void initState() {
super.initState();
_controller.addListener(() {
setState(() {});
});
_controller.addOnHideListener(_hide);
_controller.addOnShowListener(_show);
WidgetsBinding.instance.addPostFrameCallback((call) {
getIt<AppUpdateService>().checkForUpdate(context);
});
}
@override
Widget build(BuildContext context) {
homeContext = context;
return BlocProvider(
create: (context) => NotificationsBloc()..add(NotificationsInitEvent()),
child: Scaffold(
body: AutoTabsRouter(
duration: const Duration(milliseconds: 250),
routes: _routes,
builder: (context, child) {
_nestedContext = context;
return Stack(
children: [
MediaQuery(
data: getMediaQueryData(context),
child: child,
),
_buildBarrier(),
if (_shouldHideBottomNavBar(context)) _bottomNavBar(context),
],
);
},
),
),
);
}
Widget _buildBarrier() {
return IgnorePointer(
ignoring: opacity == 0.0,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: opacity,
child: GestureDetector(
onTap: () {
_controller.hide();
},
child: const SizedBox(
height: double.maxFinite,
width: double.maxFinite,
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.black38,
),
),
),
),
),
);
}
Widget _bottomNavBar(context) {
final tabsRouter = AutoTabsRouter.of(context);
return Positioned(
bottom: 22,
left: 16,
right: 16,
child: SafeArea(
top: false,
child: Container(
height: 76,
padding: const EdgeInsets.symmetric(horizontal: 24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(38),
color: AppColors.bgColorDark,
),
child: Row(
children: [
_navBarItem('Events', Assets.images.icons.navigation.confetti, 0,
tabsRouter),
_navBarItem('Invoice', Assets.images.icons.navigation.emptyWallet,
1, tabsRouter),
Gap(8),
_createEventButton(),
Gap(8),
_navBarItem('Alerts', Assets.images.icons.appBar.notification, 2,
tabsRouter),
_navBarItem('Profile', Assets.images.icons.navigation.profile, 3,
tabsRouter),
],
),
),
),
);
}
Widget _navBarItem(
String text,
SvgGenImage icon,
int index,
tabsRouter,
) {
var color = tabsRouter.activeIndex == index
? AppColors.grayWhite
: AppColors.tintDarkBlue;
return Expanded(
child: GestureDetector(
onTap: () {
if(index<0) return;
if (_controller.isShowing) {
_controller.hide();
}
tabsRouter.setActiveIndex(index);
},
child: Container(
color: Colors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon.svg(
colorFilter: ColorFilter.mode(
color,
BlendMode.srcIn,
),
),
const Gap(8),
Text(
text,
style: (tabsRouter.activeIndex == index
? AppTextStyles.bodyTinyMed
: AppTextStyles.bodyTinyReg)
.copyWith(color: color),
),
],
),
),
),
);
}
_createEventButton() {
return CreateEventPopup(
opacity: opacity,
controller: _controller,
child: KwButton.accent(
onPressed: () {
if (_controller.isShowing) {
_controller.hide();
} else {
_controller.show();
}
},
fit: KwButtonFit.circular,
iconSize: 24,
leftIcon: Assets.images.icons.navigation.noteFavorite,
).copyWith(
originalIconsColors: true,
color: _controller.isShowing
? AppColors.buttonPrimaryYellowDrop
: null));
}
Future<void> _hide() async {
setState(() {
opacity = 0.0;
});
await Future.delayed(const Duration(milliseconds: 200), () {});
}
Future<void> _show() async {
WidgetsBinding.instance.addPostFrameCallback((call) {
setState(() {
opacity = 1.0;
});
});
}
}