From 9e78ce173beed260b9a783e5ebd5671586600100 Mon Sep 17 00:00:00 2001 From: Sachin Dapkara <92971894+superiorsd10@users.noreply.github.com> Date: Thu, 7 Sep 2023 20:32:22 +0530 Subject: [PATCH] Feature: Implemented SliverAppBar on HomePage (#62) * adding the sliver app bar to home page * solving the merge conflict * solving the merge conflict 2 --- .../home/controllers/home_controller.dart | 13 + lib/app/modules/home/views/home_view.dart | 503 ++++++++++-------- 2 files changed, 282 insertions(+), 234 deletions(-) diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index 68b8cdf4..5a8512f3 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -37,6 +37,9 @@ class HomeController extends GetxController with AlarmHandlerSetupModel { final alarmIdController = TextEditingController(); + ScrollController scrollController = ScrollController(); + RxDouble scalingFactor = 1.0.obs; + loginWithGoogle() async { // Logging in again to ensure right details if User has linked account if (await SecureStorageProvider().retrieveUserModel() != null) { @@ -167,6 +170,16 @@ class HomeController extends GetxController with AlarmHandlerSetupModel { void onInit() async { super.onInit(); if (!isUserSignedIn.value) await loginWithGoogle(); + + scrollController.addListener(() { + final offset = scrollController.offset; + const maxOffset = 100.0; + const minFactor = 0.8; + const maxFactor = 1.0; + + final newFactor = 1.0 - (offset / maxOffset).clamp(0.0, 1.0); + scalingFactor.value = (minFactor + (maxFactor - minFactor) * newFactor); + }); } refreshUpcomingAlarms() async { diff --git a/lib/app/modules/home/views/home_view.dart b/lib/app/modules/home/views/home_view.dart index 08b5bfcb..30c1d39f 100644 --- a/lib/app/modules/home/views/home_view.dart +++ b/lib/app/modules/home/views/home_view.dart @@ -20,248 +20,285 @@ class HomeView extends GetView { var width = Get.width; var height = Get.height; return Scaffold( - floatingActionButtonLocation: ExpandableFab.location, - floatingActionButton: Obx( - () => Container( - child: (controller.isUserSignedIn.value) - ? ExpandableFab( - key: controller.floatingButtonKey, - initialOpen: false, - type: ExpandableFabType.up, - childrenOffset: Offset.zero, - distance: 70, - child: const Icon(Icons.add), - children: [ - TextButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor), - ), - onPressed: () { - Utils.hapticFeedback(); - controller.floatingButtonKey.currentState!.toggle(); - Get.defaultDialog( - title: "Join an alarm", - titlePadding: - const EdgeInsets.fromLTRB(0, 21, 0, 0), - backgroundColor: ksecondaryBackgroundColor, - titleStyle: Theme.of(context) - .textTheme - .displaySmall! - .copyWith(color: kprimaryTextColor), - contentPadding: const EdgeInsets.all(21), - content: TextField( - controller: controller.alarmIdController, - style: Theme.of(context).textTheme.bodyLarge, - cursorColor: kprimaryTextColor.withOpacity(0.75), - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: kprimaryTextColor - .withOpacity(0.75), - width: 1), - borderRadius: const BorderRadius.all( - Radius.circular(12))), - border: OutlineInputBorder( - borderSide: BorderSide( - color: kprimaryTextColor - .withOpacity(0.75), - width: 1), - borderRadius: const BorderRadius.all( - Radius.circular(12))), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: kprimaryTextColor - .withOpacity(0.75), - width: 1), - borderRadius: - const BorderRadius.all(Radius.circular(12))), - hintText: 'Enter Alarm ID', - hintStyle: Theme.of(context).textTheme.bodyLarge!.copyWith(color: kprimaryDisabledTextColor)), - ), - buttonColor: ksecondaryBackgroundColor, - confirm: TextButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor)), - child: Text( - 'Join', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith(color: ksecondaryTextColor), + floatingActionButtonLocation: ExpandableFab.location, + floatingActionButton: Obx( + () => Container( + child: (controller.isUserSignedIn.value) + ? ExpandableFab( + key: controller.floatingButtonKey, + initialOpen: false, + type: ExpandableFabType.up, + childrenOffset: Offset.zero, + distance: 70, + child: const Icon(Icons.add), + children: [ + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(kprimaryColor), + ), + onPressed: () { + Utils.hapticFeedback(); + controller.floatingButtonKey.currentState!.toggle(); + Get.defaultDialog( + title: "Join an alarm", + titlePadding: + const EdgeInsets.fromLTRB(0, 21, 0, 0), + backgroundColor: ksecondaryBackgroundColor, + titleStyle: Theme.of(context) + .textTheme + .displaySmall! + .copyWith(color: kprimaryTextColor), + contentPadding: const EdgeInsets.all(21), + content: TextField( + controller: controller.alarmIdController, + style: Theme.of(context).textTheme.bodyLarge, + cursorColor: + kprimaryTextColor.withOpacity(0.75), + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: kprimaryTextColor + .withOpacity(0.75), + width: 1), + borderRadius: const BorderRadius.all( + Radius.circular(12))), + border: OutlineInputBorder( + borderSide: BorderSide( + color: kprimaryTextColor + .withOpacity(0.75), + width: 1), + borderRadius: const BorderRadius.all( + Radius.circular(12))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: kprimaryTextColor + .withOpacity(0.75), + width: 1), + borderRadius: const BorderRadius.all(Radius.circular(12))), + hintText: 'Enter Alarm ID', + hintStyle: Theme.of(context).textTheme.bodyLarge!.copyWith(color: kprimaryDisabledTextColor)), ), - onPressed: () async { - Utils.hapticFeedback(); - var result = - await FirestoreDb.addUserToAlarmSharedUsers( - controller.userModel.value, - controller.alarmIdController.text); + buttonColor: ksecondaryBackgroundColor, + confirm: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + kprimaryColor)), + child: Text( + 'Join', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith(color: ksecondaryTextColor), + ), + onPressed: () async { + Utils.hapticFeedback(); + var result = await FirestoreDb + .addUserToAlarmSharedUsers( + controller.userModel.value, + controller.alarmIdController.text); - if (result != true) { - Get.defaultDialog( - titlePadding: const EdgeInsets.symmetric( - vertical: 20), - backgroundColor: - ksecondaryBackgroundColor, - title: 'Error!', - titleStyle: Theme.of(context) - .textTheme - .displaySmall, - content: Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children: [ - const Icon( - Icons.close, - size: 50, - color: Colors.red, - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10.0), - child: Text( - result == null - ? "You cannot join your own alarm!" - : "An alarm with this ID doesn't exist!", - style: Theme.of(context) - .textTheme - .displaySmall, - textAlign: TextAlign.center, + if (result != true) { + Get.defaultDialog( + titlePadding: + const EdgeInsets.symmetric( + vertical: 20), + backgroundColor: + ksecondaryBackgroundColor, + title: 'Error!', + titleStyle: Theme.of(context) + .textTheme + .displaySmall, + content: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + const Icon( + Icons.close, + size: 50, + color: Colors.red, ), - ), - TextButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all( - kprimaryColor)), + Padding( + padding: + const EdgeInsets.symmetric( + vertical: 10.0), child: Text( - 'Okay', + result == null + ? "You cannot join your own alarm!" + : "An alarm with this ID doesn't exist!", style: Theme.of(context) .textTheme - .displaySmall! - .copyWith( - color: - ksecondaryTextColor), + .displaySmall, + textAlign: TextAlign.center, ), - onPressed: () { - Utils.hapticFeedback(); - Get.back(); - }), - ], - )); - } else { - Get.back(); - } - }, - ), - ); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Icons.alarm, - color: ksecondaryTextColor, - ), - const SizedBox(width: 8.0), - Text( - 'Join alarm', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith(color: ksecondaryTextColor), - ), - ], - ), - ), - TextButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor), + ), + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty + .all( + kprimaryColor)), + child: Text( + 'Okay', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: + ksecondaryTextColor), + ), + onPressed: () { + Utils.hapticFeedback(); + Get.back(); + }), + ], + )); + } else { + Get.back(); + } + }, + ), + ); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.alarm, + color: ksecondaryTextColor, + ), + const SizedBox(width: 8.0), + Text( + 'Join alarm', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith(color: ksecondaryTextColor), + ), + ], + ), ), - onPressed: () { - Utils.hapticFeedback(); - controller.floatingButtonKey.currentState!.toggle(); - Get.toNamed('/add-update-alarm'); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Icons.add, - color: ksecondaryTextColor, - ), - const SizedBox(width: 8.0), - Text( - 'Create alarm', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith(color: ksecondaryTextColor), - ), - ], + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(kprimaryColor), + ), + onPressed: () { + Utils.hapticFeedback(); + controller.floatingButtonKey.currentState!.toggle(); + Get.toNamed('/add-update-alarm'); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.add, + color: ksecondaryTextColor, + ), + const SizedBox(width: 8.0), + Text( + 'Create alarm', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith(color: ksecondaryTextColor), + ), + ], + ), ), + ], + ) + : ExpandableFab( + initialOpen: false, + child: const Icon(Icons.add), + key: controller.floatingButtonKeyLoggedOut, + children: const [], + onOpen: () { + controller.floatingButtonKeyLoggedOut.currentState! + .toggle(); + Utils.hapticFeedback(); + Get.toNamed('/add-update-alarm'); + }, + )), + ), + body: SafeArea( + child: NestedScrollView( + controller: controller.scrollController, + headerSliverBuilder: (context, innerBoxIsScrolled) => [ + SliverAppBar( + expandedHeight: height / 7.9, + floating: true, + pinned: true, + snap: false, + centerTitle: true, + flexibleSpace: LayoutBuilder( + builder: (context, constraints) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment + .center, // Center everything vertically + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: EdgeInsets.symmetric( + horizontal: + 25 * controller.scalingFactor.value), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Next alarm', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: kprimaryDisabledTextColor, + fontSize: 16 * + controller.scalingFactor.value, + ), + ), + Obx( + () => Text(controller.alarmTime.value, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: kprimaryTextColor + .withOpacity(0.75), + fontSize: 14 * + controller + .scalingFactor.value, + )), + ), + ], + ), + ), + Visibility( + visible: controller.scalingFactor < 0.95 + ? false + : true, + child: IconButton( + onPressed: () { + Utils.hapticFeedback(); + Get.toNamed('/settings'); + }, + icon: const Icon(Icons.settings), + color: kprimaryTextColor.withOpacity(0.75), + iconSize: 27 * controller.scalingFactor.value, + ), + ), + ], + ), + ], ), - ], - ) - : ExpandableFab( - initialOpen: false, - child: const Icon(Icons.add), - key: controller.floatingButtonKeyLoggedOut, - children: const [], - onOpen: () { - controller.floatingButtonKeyLoggedOut.currentState! - .toggle(); - Utils.hapticFeedback(); - Get.toNamed('/add-update-alarm'); - }, - )), - ), - body: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: const EdgeInsets.fromLTRB(25, 25, 0, 25), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Next alarm', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith(color: kprimaryDisabledTextColor), - ), - Obx( - () => Text(controller.alarmTime.value, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: - kprimaryTextColor.withOpacity(0.75))), - ) - ], - )), - IconButton( - onPressed: () { - Utils.hapticFeedback(); - Get.toNamed('/settings'); - }, - icon: const Icon(Icons.settings), - color: kprimaryTextColor.withOpacity(0.75), - iconSize: 27, - ) + ); + }, + ), + ), ], - ), - Expanded( - child: Column( + body: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -687,8 +724,6 @@ class HomeView extends GetView { ], ), ), - ], - )), - ); + )); } }