From f1226e563899cfc0950865a9734448d4e00601b9 Mon Sep 17 00:00:00 2001 From: Jagandeep Brar Date: Wed, 28 Sep 2022 01:28:16 -0400 Subject: [PATCH] feat(calendar): scroll to selected date when switching from calendar to schedule view --- lib/modules/dashboard/core/state.dart | 32 ++++++++++--- .../routes/dashboard/pages/calendar.dart | 2 +- .../dashboard/widgets/calendar_view.dart | 46 ++++++------------- .../dashboard/widgets/schedule_view.dart | 30 +++++------- .../dashboard/widgets/switch_view_action.dart | 6 +-- lib/widgets/ui/text_style.dart | 30 ++++++------ 6 files changed, 71 insertions(+), 75 deletions(-) diff --git a/lib/modules/dashboard/core/state.dart b/lib/modules/dashboard/core/state.dart index 5f5d31b6..b04b1b88 100644 --- a/lib/modules/dashboard/core/state.dart +++ b/lib/modules/dashboard/core/state.dart @@ -1,8 +1,11 @@ import 'package:lunasea/database/tables/dashboard.dart'; +import 'package:lunasea/extensions/datetime.dart'; +import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_size.dart'; import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_type.dart'; import 'package:lunasea/modules/dashboard/core/api/api.dart'; import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart'; import 'package:lunasea/state/state.dart'; +import 'package:lunasea/vendor.dart'; class ModuleState extends LunaModuleState { ModuleState() { @@ -16,11 +19,19 @@ class ModuleState extends LunaModuleState { resetUpcoming(); } - CalendarStartingType _calendarStartingType = + CalendarStartingType _calendarType = DashboardDatabase.CALENDAR_STARTING_TYPE.read(); - CalendarStartingType get calendarStartingType => _calendarStartingType; - set calendarStartingType(CalendarStartingType calendarStartingType) { - _calendarStartingType = calendarStartingType; + CalendarStartingType get calendarType => _calendarType; + set calendarType(CalendarStartingType calendarStartingType) { + _calendarType = calendarStartingType; + notifyListeners(); + } + + CalendarFormat _calendarFormat = + DashboardDatabase.CALENDAR_STARTING_SIZE.read().data; + CalendarFormat get calendarFormat => _calendarFormat; + set calendarFormat(CalendarFormat calendarFormat) { + _calendarFormat = calendarFormat; notifyListeners(); } @@ -31,10 +42,10 @@ class ModuleState extends LunaModuleState { notifyListeners(); } - DateTime? _today; - DateTime? get today => _today; + DateTime _today = DateTime.now().floor(); + DateTime get today => _today; void resetToday() { - _today = DateTime.now(); + _today = DateTime.now().floor(); notifyListeners(); } @@ -44,4 +55,11 @@ class ModuleState extends LunaModuleState { if (_api != null) _upcoming = _api!.getUpcoming(DateTime.now()); notifyListeners(); } + + DateTime _selected = DateTime.now().floor(); + DateTime get selected => _selected; + set selected(DateTime selected) { + _selected = selected; + notifyListeners(); + } } diff --git a/lib/modules/dashboard/routes/dashboard/pages/calendar.dart b/lib/modules/dashboard/routes/dashboard/pages/calendar.dart index 664e3367..7523810b 100644 --- a/lib/modules/dashboard/routes/dashboard/pages/calendar.dart +++ b/lib/modules/dashboard/routes/dashboard/pages/calendar.dart @@ -56,7 +56,7 @@ class _State extends State snapshot.hasData) { final events = snapshot.data!; return Selector( - selector: (_, s) => s.calendarStartingType, + selector: (_, s) => s.calendarType, builder: (context, type, _) { if (type == CalendarStartingType.CALENDAR) return CalendarView(events: events); diff --git a/lib/modules/dashboard/routes/dashboard/widgets/calendar_view.dart b/lib/modules/dashboard/routes/dashboard/widgets/calendar_view.dart index e613526b..b855b2c9 100644 --- a/lib/modules/dashboard/routes/dashboard/widgets/calendar_view.dart +++ b/lib/modules/dashboard/routes/dashboard/widgets/calendar_view.dart @@ -5,7 +5,6 @@ import 'package:lunasea/database/box.dart'; import 'package:lunasea/database/tables/dashboard.dart'; import 'package:lunasea/extensions/datetime.dart'; import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_day.dart'; -import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_size.dart'; import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart'; import 'package:lunasea/modules/dashboard/core/api/data/lidarr.dart'; import 'package:lunasea/modules/dashboard/core/api/data/radarr.dart'; @@ -30,26 +29,11 @@ class CalendarView extends StatefulWidget { class _State extends State { final double _calendarBulletSize = 8.0; - List _selectedEvents = []; - - late DateTime _selected; - late CalendarFormat _calendarFormat; - late final TextStyle dayStyle = _getTextStyle(LunaColours.white); late final TextStyle outsideStyle = _getTextStyle(LunaColours.white70); late final TextStyle unavailableStyle = _getTextStyle(LunaColours.white10); late final TextStyle weekdayStyle = _getTextStyle(LunaColours.accent); - @override - void initState() { - super.initState(); - - final size = DashboardDatabase.CALENDAR_STARTING_SIZE.read(); - _selected = context.read().today!.floor(); - _selectedEvents = widget.events[_selected] ?? []; - _calendarFormat = size.data; - } - TextStyle _getTextStyle(Color color) { return TextStyle( color: color, @@ -60,11 +44,7 @@ class _State extends State { void _onDaySelected(DateTime selected, DateTime focused) { HapticFeedback.selectionClick(); - if (mounted) - setState(() { - _selected = selected.floor(); - _selectedEvents = widget.events[selected.floor()] ?? []; - }); + context.read().selected = selected.floor(); } @override @@ -128,10 +108,10 @@ class _State extends State { DashboardDatabase.CALENDAR_STARTING_SIZE, ], builder: (context, _) { - DateTime firstDay = context.watch().today!.subtract( + DateTime firstDay = context.watch().today.subtract( Duration(days: DashboardDatabase.CALENDAR_DAYS_PAST.read()), ); - DateTime lastDay = context.watch().today!.add( + DateTime lastDay = context.watch().today.add( Duration(days: DashboardDatabase.CALENDAR_DAYS_FUTURE.read()), ); return SafeArea( @@ -144,7 +124,7 @@ class _State extends State { ), rowHeight: 48.0, rangeSelectionMode: RangeSelectionMode.disabled, - focusedDay: _selected, + focusedDay: context.watch().selected, firstDay: firstDay, lastDay: lastDay, //events: widget.events, @@ -161,8 +141,9 @@ class _State extends State { )), startingDayOfWeek: DashboardDatabase.CALENDAR_STARTING_DAY.read().data, - selectedDayPredicate: (date) => - date.floor() == _selected.floor(), + selectedDayPredicate: (date) { + return date.floor() == context.read().selected; + }, calendarStyle: CalendarStyle( markersMaxCount: 1, isTodayHighlighted: true, @@ -188,8 +169,9 @@ class _State extends State { markersAlignment: Alignment.bottomCenter, todayTextStyle: dayStyle, ), - onFormatChanged: (format) => - setState(() => _calendarFormat = format), + onFormatChanged: (format) { + context.read().calendarFormat = format; + }, daysOfWeekStyle: DaysOfWeekStyle( weekendStyle: weekdayStyle, weekdayStyle: weekdayStyle, @@ -198,7 +180,7 @@ class _State extends State { if (widget.events.isEmpty) return []; return widget.events[date.floor()] ?? []; }, - calendarFormat: _calendarFormat, + calendarFormat: context.watch().calendarFormat, availableCalendarFormats: const { CalendarFormat.month: 'Month', CalendarFormat.twoWeeks: '2 Weeks', @@ -246,7 +228,9 @@ class _State extends State { } Widget _calendarList() { - if (_selectedEvents.isEmpty) { + final selected = context.read().selected; + final events = widget.events[selected.floor()] ?? []; + if (events.isEmpty) { return Expanded( child: LunaListView( controller: HomeNavigationBar.scrollControllers[1], @@ -262,7 +246,7 @@ class _State extends State { return Expanded( child: LunaListView( controller: HomeNavigationBar.scrollControllers[1], - children: _selectedEvents.map(ContentBlock.new).toList(), + children: events.map(ContentBlock.new).toList(), padding: MediaQuery.of(context).padding.copyWith(top: 0.0, bottom: 8.0), ), ); diff --git a/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart b/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart index ec9e9ebe..1576fcf9 100644 --- a/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart +++ b/lib/modules/dashboard/routes/dashboard/widgets/schedule_view.dart @@ -1,6 +1,5 @@ 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'; @@ -24,14 +23,6 @@ class ScheduleView extends StatefulWidget { class _State extends State { final _formatter = DateFormat('EEEE / MMMM dd, y'); - late DateTime _today; - - @override - void initState() { - super.initState(); - DateTime _floored = context.read().today!.floor(); - _today = _floored; - } @override Widget build(BuildContext context) { @@ -65,19 +56,22 @@ class _State extends State { Tuple2, double> _buildSchedule() { double offset = 0.0; - double offsetOfToday = 0.0; + double offsetOfSelected = 0.0; List days = []; List keys = widget.events.keys.toList(); keys.sort(); 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; - bool isToday = _today.isAtSameMomentAs(key); + final selected = context.read().selected; + final today = context.read().today; - if (isToday) { - offsetOfToday = offset; + 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; + bool isSelected = selected.isAtSameMomentAs(key); + + if (isSelected) { + offsetOfSelected = offset; } if ((pastDays || dayInFuture) && hasEvents) { @@ -87,14 +81,14 @@ class _State extends State { } } - return Tuple2(days, offsetOfToday); + return Tuple2(days, offsetOfSelected); } Tuple2, double> _buildDay(DateTime day) { List events = widget.events[day]!; final extent = LunaBlock.calculateItemExtent(3); - final offset = 39.0 + events.length * extent; + final offset = 39.30 + events.length * extent; final slivers = [ SliverToBoxAdapter( child: LunaHeader(text: _formatter.format(day)), diff --git a/lib/modules/dashboard/routes/dashboard/widgets/switch_view_action.dart b/lib/modules/dashboard/routes/dashboard/widgets/switch_view_action.dart index d2fa6067..d6bfe8f1 100644 --- a/lib/modules/dashboard/routes/dashboard/widgets/switch_view_action.dart +++ b/lib/modules/dashboard/routes/dashboard/widgets/switch_view_action.dart @@ -45,7 +45,7 @@ class _State extends State with LunaLoadCallbackMixin { @override Widget build(BuildContext context) { return Selector( - selector: (_, state) => state.calendarStartingType, + selector: (_, state) => state.calendarType, builder: (context, view, _) { if (_showButton) { return LunaIconButton.appBar( @@ -53,9 +53,9 @@ class _State extends State with LunaLoadCallbackMixin { onPressed: () { final state = context.read(); if (view == CalendarStartingType.CALENDAR) - state.calendarStartingType = CalendarStartingType.SCHEDULE; + state.calendarType = CalendarStartingType.SCHEDULE; else - state.calendarStartingType = CalendarStartingType.CALENDAR; + state.calendarType = CalendarStartingType.CALENDAR; }, ); } diff --git a/lib/widgets/ui/text_style.dart b/lib/widgets/ui/text_style.dart index c4e9b8b5..af9e663c 100644 --- a/lib/widgets/ui/text_style.dart +++ b/lib/widgets/ui/text_style.dart @@ -4,7 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; class LunaTextStyle { static TextStyle bodySmall() { return GoogleFonts.robotoFlex( - height: 16.0, // md.sys.typescale.body-small.line-height + height: 1.33, // md.sys.typescale.body-small.line-height fontSize: 12.0, // md.sys.typescale.body-small.size fontWeight: FontWeight.w400, // md.sys.typescale.body-small.weight ); @@ -12,7 +12,7 @@ class LunaTextStyle { static TextStyle bodyMedium() { return GoogleFonts.robotoFlex( - height: 20.0, // md.sys.typescale.body-medium.line-height + height: 1.43, // md.sys.typescale.body-medium.line-height fontSize: 14.0, // md.sys.typescale.body-medium.size fontWeight: FontWeight.w400, // md.sys.typescale.body-medium.weight ); @@ -20,7 +20,7 @@ class LunaTextStyle { static TextStyle bodyLarge() { return GoogleFonts.robotoFlex( - height: 24.0, // md.sys.typescale.body-large.line-height + height: 1.50, // md.sys.typescale.body-large.line-height fontSize: 16.0, // md.sys.typescale.body-large.size fontWeight: FontWeight.w400, // md.sys.typescale.body-large.weight ); @@ -28,7 +28,7 @@ class LunaTextStyle { static TextStyle displaySmall() { return GoogleFonts.robotoFlex( - height: 44.0, // md.sys.typescale.display-small.line-height + height: 1.22, // md.sys.typescale.display-small.line-height fontSize: 36.0, // md.sys.typescale.display-small.size fontWeight: FontWeight.w400, // md.sys.typescale.display-small.weight ); @@ -36,7 +36,7 @@ class LunaTextStyle { static TextStyle displayMedium() { return GoogleFonts.robotoFlex( - height: 52.0, // md.sys.typescale.display-medium.line-height + height: 1.56, // md.sys.typescale.display-medium.line-height fontSize: 45.0, // md.sys.typescale.display-medium.size fontWeight: FontWeight.w400, // md.sys.typescale.display-medium.weight ); @@ -44,7 +44,7 @@ class LunaTextStyle { static TextStyle displayLarge() { return GoogleFonts.robotoFlex( - height: 64.0, // md.sys.typescale.display-large.line-height + height: 1.23, // md.sys.typescale.display-large.line-height fontSize: 57.0, // md.sys.typescale.display-large.size fontWeight: FontWeight.w400, // md.sys.typescale.display-large.weight ); @@ -52,7 +52,7 @@ class LunaTextStyle { static TextStyle headlineSmall() { return GoogleFonts.robotoFlex( - height: 40.0, // md.sys.typescale.headline-small.line-height + height: 1.25, // md.sys.typescale.headline-small.line-height fontSize: 32.0, // md.sys.typescale.headline-small.size fontWeight: FontWeight.w400, // md.sys.typescale.headline-small.weight ); @@ -60,7 +60,7 @@ class LunaTextStyle { static TextStyle headlineMedium() { return GoogleFonts.robotoFlex( - height: 36.0, // md.sys.typescale.headline-medium.line-height + height: 1.29, // md.sys.typescale.headline-medium.line-height fontSize: 28.0, // md.sys.typescale.headline-medium.size fontWeight: FontWeight.w400, // md.sys.typescale.headline-medium.weight ); @@ -68,7 +68,7 @@ class LunaTextStyle { static TextStyle headlineLarge() { return GoogleFonts.robotoFlex( - height: 32.0, // md.sys.typescale.headline-large.line-height + height: 1.33, // md.sys.typescale.headline-large.line-height fontSize: 24.0, // md.sys.typescale.headline-large.size fontWeight: FontWeight.w400, // md.sys.typescale.headline-large.weight ); @@ -76,7 +76,7 @@ class LunaTextStyle { static TextStyle labelSmall() { return GoogleFonts.robotoFlex( - height: 16.0, // md.sys.typescale.label-small.line-height + height: 1.45, // md.sys.typescale.label-small.line-height fontSize: 11.0, // md.sys.typescale.label-small.size fontWeight: FontWeight.w500, // md.sys.typescale.label-small.weight ); @@ -84,7 +84,7 @@ class LunaTextStyle { static TextStyle labelMedium() { return GoogleFonts.robotoFlex( - height: 16.0, // md.sys.typescale.label-medium.line-height + height: 1.33, // md.sys.typescale.label-medium.line-height fontSize: 12.0, // md.sys.typescale.label-medium.size fontWeight: FontWeight.w500, // md.sys.typescale.label-medium.weight ); @@ -92,7 +92,7 @@ class LunaTextStyle { static TextStyle labelLarge() { return GoogleFonts.robotoFlex( - height: 20.0, // md.sys.typescale.label-large.line-height + height: 1.43, // md.sys.typescale.label-large.line-height fontSize: 14.0, // md.sys.typescale.label-large.size fontWeight: FontWeight.w500, // md.sys.typescale.label-large.weight ); @@ -100,7 +100,7 @@ class LunaTextStyle { static TextStyle titleSmall() { return GoogleFonts.robotoFlex( - height: 20.0, // md.sys.typescale.title-small.line-height + height: 1.43, // md.sys.typescale.title-small.line-height fontSize: 14.0, // md.sys.typescale.title-small.size fontWeight: FontWeight.w500, // md.sys.typescale.title-small.weight ); @@ -108,7 +108,7 @@ class LunaTextStyle { static TextStyle titleMedium() { return GoogleFonts.robotoFlex( - height: 24.0, // md.sys.typescale.title-medium.line-height + height: 1.50, // md.sys.typescale.title-medium.line-height fontSize: 16.0, // md.sys.typescale.title-medium.size fontWeight: FontWeight.w500, // md.sys.typescale.title-medium.weight ); @@ -116,7 +116,7 @@ class LunaTextStyle { static TextStyle titleLarge() { return GoogleFonts.robotoFlex( - height: 28.0, // md.sys.typescale.title-large.line-height + height: 1.27, // md.sys.typescale.title-large.line-height fontSize: 22.0, // md.sys.typescale.title-large.size fontWeight: FontWeight.w400, // md.sys.typescale.title-large.weight );