From 6eff6c902cd7bcd523d83be09034098234679a79 Mon Sep 17 00:00:00 2001 From: Jagandeep Brar Date: Tue, 27 Sep 2022 02:03:21 -0400 Subject: [PATCH] fix(calendar): start to current date when past days are enabled --- lib/extensions/scroll_controller.dart | 13 +++- .../dashboard/widgets/schedule_view.dart | 68 +++++++++++++++---- lib/widgets/ui/list_view.dart | 1 + .../ui/list_view/custom_scroll_view.dart | 26 +++++++ 4 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 lib/widgets/ui/list_view/custom_scroll_view.dart diff --git a/lib/extensions/scroll_controller.dart b/lib/extensions/scroll_controller.dart index 089e26dcb..61a3ea75a 100644 --- a/lib/extensions/scroll_controller.dart +++ b/lib/extensions/scroll_controller.dart @@ -4,13 +4,24 @@ import 'package:lunasea/core.dart'; extension ScrollControllerExtension on ScrollController { static const _duration = Duration(milliseconds: LunaUI.ANIMATION_SPEED_SCROLLING); + static const _curve = Curves.easeInOutQuart; Future animateToStart() async { if (this.hasClients) { this.animateTo( 0.00, duration: _duration, - curve: Curves.easeInOutQuart, + curve: _curve, + ); + } + } + + Future animateToOffset(double offset) async { + if (this.hasClients) { + return this.animateTo( + offset, + duration: _duration, + curve: _curve, ); } } diff --git a/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart b/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart index 0b45b2773..ec9e9ebe8 100644 --- a/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart +++ b/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:lunasea/database/tables/dashboard.dart'; import 'package:lunasea/extensions/datetime.dart'; +import 'package:lunasea/extensions/scroll_controller.dart'; import 'package:lunasea/vendor.dart'; import 'package:lunasea/widgets/ui.dart'; @@ -22,6 +23,7 @@ class ScheduleView extends StatefulWidget { } class _State extends State { + final _formatter = DateFormat('EEEE / MMMM dd, y'); late DateTime _today; @override @@ -33,43 +35,79 @@ class _State extends State { @override Widget build(BuildContext context) { + final controller = HomeNavigationBar.scrollControllers[1]; + if (widget.events.isEmpty) { return LunaListView( - controller: HomeNavigationBar.scrollControllers[1], + controller: controller, children: [ LunaMessage.inList(text: 'dashboard.NoNewContent'.tr()), ], ); } - return LunaListView( - controller: HomeNavigationBar.scrollControllers[1], - children: _buildSchedule().expand((e) => e).toList(), + + final schedule = _buildSchedule(); + Future.microtask(() => controller.animateToOffset(schedule.item2)); + + return LunaCustomScrollView( + controller: controller, + slivers: [ + const SliverPadding( + padding: EdgeInsets.symmetric(vertical: LunaUI.MARGIN_SIZE_HALF), + ), + ...schedule.item1, + const SliverPadding( + padding: EdgeInsets.only(bottom: LunaUI.MARGIN_SIZE_HALF), + ), + ], ); } - List> _buildSchedule() { - List> days = []; + Tuple2, double> _buildSchedule() { + double offset = 0.0; + double offsetOfToday = 0.0; + List days = []; List keys = widget.events.keys.toList(); keys.sort(); - for (var key in keys) { + for (final key in keys) { bool pastDays = DashboardDatabase.CALENDAR_SHOW_PAST_DAYS.read(); bool dayInFuture = key.isAfter(_today.subtract(const Duration(days: 1))); bool hasEvents = widget.events[key]?.isNotEmpty ?? false; - if ((pastDays || dayInFuture) && hasEvents) days.add(_buildDay(key)); + bool isToday = _today.isAtSameMomentAs(key); + + if (isToday) { + offsetOfToday = offset; + } + + if ((pastDays || dayInFuture) && hasEvents) { + final built = _buildDay(key); + offset += built.item2; + days.addAll(built.item1); + } } - return days; + return Tuple2(days, offsetOfToday); } - List _buildDay(DateTime day) { - List content = []; + Tuple2, double> _buildDay(DateTime day) { List events = widget.events[day]!; - for (final event in events) content.add(ContentBlock(event)); - return [ - LunaHeader(text: DateFormat('EEEE / MMMM dd, y').format(day)), - ...content, + final extent = LunaBlock.calculateItemExtent(3); + final offset = 39.0 + events.length * extent; + final slivers = [ + SliverToBoxAdapter( + child: LunaHeader(text: _formatter.format(day)), + ), + SliverFixedExtentList( + delegate: SliverChildBuilderDelegate( + (_, index) => ContentBlock(events[index]), + childCount: events.length, + ), + itemExtent: extent, + ), ]; + + return Tuple2(slivers, offset); } } diff --git a/lib/widgets/ui/list_view.dart b/lib/widgets/ui/list_view.dart index b5489a722..40c6d2cac 100644 --- a/lib/widgets/ui/list_view.dart +++ b/lib/widgets/ui/list_view.dart @@ -1,3 +1,4 @@ +export 'list_view/custom_scroll_view.dart'; export 'list_view/list_view.dart'; export 'list_view/list_view_builder.dart'; export 'list_view/list_view_modal.dart'; diff --git a/lib/widgets/ui/list_view/custom_scroll_view.dart b/lib/widgets/ui/list_view/custom_scroll_view.dart new file mode 100644 index 000000000..3ef17c6c3 --- /dev/null +++ b/lib/widgets/ui/list_view/custom_scroll_view.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +class LunaCustomScrollView extends StatelessWidget { + final ScrollController controller; + final List slivers; + + const LunaCustomScrollView({ + super.key, + required this.controller, + required this.slivers, + }); + + @override + Widget build(BuildContext context) { + return Scrollbar( + controller: controller, + interactive: true, + child: CustomScrollView( + controller: controller, + keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + slivers: slivers, + physics: const AlwaysScrollableScrollPhysics(), + ), + ); + } +}