2023-08-02 21:09:28 -04:00
|
|
|
import 'dart:async';
|
|
|
|
|
2024-07-06 20:09:18 -04:00
|
|
|
import 'package:animated_bottom_navigation_bar/'
|
|
|
|
'animated_bottom_navigation_bar.dart';
|
|
|
|
import 'package:awesome_extensions/awesome_extensions.dart';
|
2023-07-28 20:36:05 -04:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
import 'package:flutter_animate/flutter_animate.dart';
|
|
|
|
import 'package:flutter_translate/flutter_translate.dart';
|
2023-09-24 15:30:54 -04:00
|
|
|
import 'package:preload_page_view/preload_page_view.dart';
|
2024-06-16 22:12:24 -04:00
|
|
|
import 'package:provider/provider.dart';
|
2023-07-28 20:36:05 -04:00
|
|
|
|
2024-07-09 13:27:54 -04:00
|
|
|
import '../../../chat/chat.dart';
|
|
|
|
import '../../../contact_invitation/contact_invitation.dart';
|
|
|
|
import '../../../theme/theme.dart';
|
2024-01-26 21:02:11 -05:00
|
|
|
import 'account_page.dart';
|
2024-01-09 20:58:27 -05:00
|
|
|
import 'bottom_sheet_action_button.dart';
|
2024-01-26 21:02:11 -05:00
|
|
|
import 'chats_page.dart';
|
2023-07-28 20:36:05 -04:00
|
|
|
|
2024-01-08 21:37:08 -05:00
|
|
|
class MainPager extends StatefulWidget {
|
2024-01-28 21:31:53 -05:00
|
|
|
const MainPager({super.key});
|
2023-07-28 20:36:05 -04:00
|
|
|
|
|
|
|
@override
|
|
|
|
MainPagerState createState() => MainPagerState();
|
2023-08-06 19:46:40 -04:00
|
|
|
|
|
|
|
static MainPagerState? of(BuildContext context) =>
|
|
|
|
context.findAncestorStateOfType<MainPagerState>();
|
2023-07-28 20:36:05 -04:00
|
|
|
}
|
|
|
|
|
2024-01-09 20:58:27 -05:00
|
|
|
class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
|
2023-07-28 20:36:05 -04:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
2023-08-06 19:46:40 -04:00
|
|
|
pageController.dispose();
|
2023-07-28 20:36:05 -04:00
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
2024-07-06 20:09:18 -04:00
|
|
|
bool _onScrollNotification(ScrollNotification notification) {
|
2023-07-28 20:36:05 -04:00
|
|
|
if (notification is UserScrollNotification &&
|
|
|
|
notification.metrics.axis == Axis.vertical) {
|
|
|
|
switch (notification.direction) {
|
|
|
|
case ScrollDirection.forward:
|
|
|
|
// _hideBottomBarAnimationController.reverse();
|
|
|
|
// _fabAnimationController.forward(from: 0);
|
|
|
|
break;
|
|
|
|
case ScrollDirection.reverse:
|
|
|
|
// _hideBottomBarAnimationController.forward();
|
|
|
|
// _fabAnimationController.reverse(from: 1);
|
|
|
|
break;
|
|
|
|
case ScrollDirection.idle:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-09-23 12:56:54 -04:00
|
|
|
Future<void> scanContactInvitationDialog(BuildContext context) async {
|
2023-08-05 01:00:46 -04:00
|
|
|
await showDialog<void>(
|
|
|
|
context: context,
|
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
builder: (context) {
|
2024-02-14 21:33:15 -05:00
|
|
|
return AlertDialog(
|
|
|
|
shape: const RoundedRectangleBorder(
|
2023-08-05 01:00:46 -04:00
|
|
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
|
|
|
),
|
2024-02-14 21:33:15 -05:00
|
|
|
contentPadding: const EdgeInsets.only(
|
2023-08-05 01:00:46 -04:00
|
|
|
top: 10,
|
|
|
|
),
|
2024-02-14 21:33:15 -05:00
|
|
|
title: const Text(
|
2023-09-23 12:56:54 -04:00
|
|
|
'Scan Contact Invite',
|
2023-08-05 01:00:46 -04:00
|
|
|
style: TextStyle(fontSize: 24),
|
|
|
|
),
|
2024-04-05 22:03:04 -04:00
|
|
|
content: ScanInvitationDialog(
|
2024-06-16 22:12:24 -04:00
|
|
|
locator: context.read,
|
2024-02-14 21:33:15 -05:00
|
|
|
));
|
2023-08-05 01:00:46 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-07-06 20:09:18 -04:00
|
|
|
Widget _buildBottomBarItem(int index, bool isActive) {
|
|
|
|
final theme = Theme.of(context);
|
|
|
|
final scale = theme.extension<ScaleScheme>()!;
|
|
|
|
final scaleConfig = theme.extension<ScaleConfig>()!;
|
|
|
|
|
|
|
|
final color = scaleConfig.useVisualIndicators
|
|
|
|
? (scaleConfig.preferBorders
|
|
|
|
? scale.primaryScale.border
|
|
|
|
: scale.primaryScale.borderText)
|
|
|
|
: (isActive
|
|
|
|
? (scaleConfig.preferBorders
|
|
|
|
? scale.primaryScale.border
|
|
|
|
: scale.primaryScale.borderText)
|
|
|
|
: (scaleConfig.preferBorders
|
|
|
|
? scale.primaryScale.subtleBorder
|
|
|
|
: scale.primaryScale.borderText.withAlpha(0x80)));
|
|
|
|
|
|
|
|
final item = Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
_selectedIconList[index],
|
|
|
|
size: 24,
|
|
|
|
color: color,
|
|
|
|
),
|
|
|
|
const SizedBox(height: 4),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
|
|
child: Text(
|
|
|
|
_bottomLabelList[index],
|
2024-07-08 21:29:52 -04:00
|
|
|
style: theme.textTheme.labelMedium!.copyWith(
|
2024-07-06 20:09:18 -04:00
|
|
|
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
|
|
|
|
color: color),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
if (scaleConfig.useVisualIndicators && isActive) {
|
|
|
|
return DecoratedBox(
|
|
|
|
decoration: ShapeDecoration(
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
borderRadius: BorderRadius.circular(
|
|
|
|
14 * scaleConfig.borderRadiusScale),
|
|
|
|
side: BorderSide(
|
|
|
|
width: 2,
|
|
|
|
color: scaleConfig.preferBorders
|
|
|
|
? scale.primaryScale.border
|
|
|
|
: scale.primaryScale.borderText))),
|
|
|
|
child: item)
|
|
|
|
.paddingLTRB(8, 0, 8, 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
2024-02-14 21:33:15 -05:00
|
|
|
Widget _bottomSheetBuilder(BuildContext sheetContext, BuildContext context) {
|
2024-06-24 23:44:08 +00:00
|
|
|
if (currentPage == 0) {
|
2023-08-01 00:39:50 -04:00
|
|
|
// New contact invitation
|
2024-04-10 16:13:08 -04:00
|
|
|
return newContactBottomSheetBuilder(sheetContext, context);
|
2024-06-24 23:44:08 +00:00
|
|
|
} else if (currentPage == 1) {
|
2023-08-01 00:39:50 -04:00
|
|
|
// New chat
|
2024-04-10 16:13:08 -04:00
|
|
|
return newChatBottomSheetBuilder(sheetContext, context);
|
2023-08-02 21:09:28 -04:00
|
|
|
} else {
|
|
|
|
// Unknown error
|
2024-02-11 14:17:10 -05:00
|
|
|
return debugPage('unknown page');
|
2023-08-01 00:39:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-28 20:36:05 -04:00
|
|
|
@override
|
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final theme = Theme.of(context);
|
2023-08-05 01:00:46 -04:00
|
|
|
final scale = theme.extension<ScaleScheme>()!;
|
2024-07-06 20:09:18 -04:00
|
|
|
final scaleConfig = theme.extension<ScaleConfig>()!;
|
2023-08-05 01:00:46 -04:00
|
|
|
|
2023-07-28 20:36:05 -04:00
|
|
|
return Scaffold(
|
2023-09-23 12:56:54 -04:00
|
|
|
//extendBody: true,
|
|
|
|
backgroundColor: Colors.transparent,
|
2023-07-28 20:36:05 -04:00
|
|
|
body: NotificationListener<ScrollNotification>(
|
2024-07-06 20:09:18 -04:00
|
|
|
onNotification: _onScrollNotification,
|
2023-09-24 15:30:54 -04:00
|
|
|
child: PreloadPageView(
|
2024-06-24 23:44:08 +00:00
|
|
|
key: _pageViewKey,
|
2023-09-23 12:56:54 -04:00
|
|
|
controller: pageController,
|
2023-09-24 15:30:54 -04:00
|
|
|
preloadPagesCount: 2,
|
2023-09-23 12:56:54 -04:00
|
|
|
onPageChanged: (index) {
|
|
|
|
setState(() {
|
2024-06-24 23:44:08 +00:00
|
|
|
currentPage = index;
|
2023-09-23 12:56:54 -04:00
|
|
|
});
|
|
|
|
},
|
2024-01-28 21:31:53 -05:00
|
|
|
children: const [
|
|
|
|
AccountPage(),
|
|
|
|
ChatsPage(),
|
2023-09-23 12:56:54 -04:00
|
|
|
])),
|
2023-07-28 20:36:05 -04:00
|
|
|
// appBar: AppBar(
|
|
|
|
// toolbarHeight: 24,
|
|
|
|
// title: Text(
|
|
|
|
// 'C',
|
|
|
|
// style: Theme.of(context).textTheme.headlineSmall,
|
|
|
|
// ),
|
|
|
|
// ),
|
2024-07-06 20:09:18 -04:00
|
|
|
bottomNavigationBar: AnimatedBottomNavigationBar.builder(
|
|
|
|
itemCount: 2,
|
|
|
|
height: 64,
|
|
|
|
tabBuilder: _buildBottomBarItem,
|
|
|
|
activeIndex: currentPage,
|
|
|
|
gapLocation: GapLocation.end,
|
|
|
|
gapWidth: 90,
|
|
|
|
notchSmoothness: NotchSmoothness.defaultEdge,
|
|
|
|
notchMargin: 4,
|
|
|
|
backgroundColor: scaleConfig.preferBorders
|
|
|
|
? scale.primaryScale.hoverElementBackground
|
|
|
|
: scale.primaryScale.hoverBorder,
|
|
|
|
elevation: 0,
|
2023-07-28 20:36:05 -04:00
|
|
|
onTap: (index) async {
|
2023-08-06 19:46:40 -04:00
|
|
|
await pageController.animateToPage(index,
|
2023-07-29 10:55:35 -04:00
|
|
|
duration: 250.ms, curve: Curves.easeInOut);
|
2023-07-28 20:36:05 -04:00
|
|
|
},
|
|
|
|
),
|
2023-08-02 21:09:28 -04:00
|
|
|
floatingActionButton: BottomSheetActionButton(
|
2024-07-06 20:09:18 -04:00
|
|
|
shape: CircleBorder(
|
|
|
|
side: !scaleConfig.useVisualIndicators
|
|
|
|
? BorderSide.none
|
|
|
|
: BorderSide(
|
|
|
|
strokeAlign: BorderSide.strokeAlignCenter,
|
|
|
|
color: scaleConfig.preferBorders
|
|
|
|
? scale.secondaryScale.border
|
|
|
|
: scale.secondaryScale.borderText,
|
|
|
|
width: 2),
|
|
|
|
),
|
|
|
|
foregroundColor: scaleConfig.preferBorders
|
|
|
|
? scale.secondaryScale.border
|
|
|
|
: scale.secondaryScale.borderText,
|
|
|
|
backgroundColor: scaleConfig.preferBorders
|
|
|
|
? scale.secondaryScale.hoverElementBackground
|
|
|
|
: scale.secondaryScale.hoverBorder,
|
2023-08-02 21:09:28 -04:00
|
|
|
builder: (context) => Icon(
|
2024-06-24 23:44:08 +00:00
|
|
|
_fabIconList[currentPage],
|
2024-07-06 20:09:18 -04:00
|
|
|
color: scaleConfig.preferBorders
|
|
|
|
? scale.secondaryScale.border
|
|
|
|
: scale.secondaryScale.borderText,
|
2023-08-02 21:09:28 -04:00
|
|
|
),
|
2024-02-14 21:33:15 -05:00
|
|
|
bottomSheetBuilder: (sheetContext) =>
|
|
|
|
_bottomSheetBuilder(sheetContext, context)),
|
2023-07-28 20:36:05 -04:00
|
|
|
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
|
|
|
);
|
|
|
|
}
|
2023-09-30 21:11:06 -04:00
|
|
|
|
2024-06-24 23:44:08 +00:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
final _selectedIconList = <IconData>[Icons.person, Icons.chat];
|
|
|
|
// final _unselectedIconList = <IconData>[
|
|
|
|
// Icons.chat_outlined,
|
|
|
|
// Icons.person_outlined
|
|
|
|
// ];
|
|
|
|
final _fabIconList = <IconData>[
|
|
|
|
Icons.person_add_sharp,
|
|
|
|
Icons.add_comment_sharp,
|
|
|
|
];
|
|
|
|
final _bottomLabelList = <String>[
|
|
|
|
translate('pager.contacts'),
|
|
|
|
translate('pager.chats'),
|
|
|
|
];
|
|
|
|
final _pageViewKey = GlobalKey(debugLabel: '_pageViewKey');
|
|
|
|
|
|
|
|
// key-accessible controller
|
|
|
|
int currentPage = 0;
|
|
|
|
final pageController = PreloadPageController();
|
|
|
|
|
2023-09-29 22:45:50 -04:00
|
|
|
@override
|
|
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
|
|
super.debugFillProperties(properties);
|
2024-06-24 23:44:08 +00:00
|
|
|
properties
|
|
|
|
..add(IntProperty('currentPage', currentPage))
|
|
|
|
..add(DiagnosticsProperty<PreloadPageController>(
|
|
|
|
'pageController', pageController));
|
2023-09-29 22:45:50 -04:00
|
|
|
}
|
2023-07-28 20:36:05 -04:00
|
|
|
}
|