diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_detail/mm_calendar_detail_page.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/mm_calendar_detail_page.dart index 3758ac6..f6b1ec4 100644 --- a/lib/src/features/mm_calendar/presentation/mm_calendar_detail/mm_calendar_detail_page.dart +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/mm_calendar_detail_page.dart @@ -5,7 +5,9 @@ import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:iconly/iconly.dart'; import 'package:mmcalendar/src/shared/shared.dart'; -import 'package:mmcalendar/src/utils/dates.dart'; + +import 'widgets/landscape_date_detail_widget.dart'; +import 'widgets/portrait_date_detail_widget.dart'; @RoutePage() class MmCalendarDetailPage extends StatefulHookConsumerWidget { @@ -88,54 +90,6 @@ class _MmCalendarDetailPageState extends ConsumerState { @override Widget build(BuildContext context) { - final mmCalendar = ref.watch(mmCalendarProvider); - - // final calLanguage = ref.watch(calendarLanguageControllerProvider); - // final langCatalog = LanguageCatalog(language: calLanguage); - - final day = DateFormat().add_d().format(_date); - final dow = DateFormat().add_EEEE().format(_date); - final monthAndYear = DateFormat('MMMM, yyyy').format(_date); - - final mmDate = mmCalendar.fromDateTime(_date); - final fortnightDay = mmDate.getFortnightDay(); - - final mmDow = mmDate.format('En'); - - final mmDay = fortnightDay.isNotEmpty - ? mmDate.format('M p f r n') - : mmDate.format('M p n'); - - final mmDateFull = fortnightDay.isNotEmpty - ? mmDate.format() - : mmDate.format('S s k, B y k, M p, En'); - - final languageCatalog = LanguageCatalog(); - final astro = mmDate.astro; - - final sabbath = astro.getSabbath(); - final astrologicalDay = astro.getAstrologicalDay(); - - final nagaMM = languageCatalog.translate('Naga'); - final headMM = languageCatalog.translate('Head'); - final facingMM = languageCatalog.translate('Facing'); - final nagahle = astro.getNagahle(); - - final bornMM = languageCatalog.translate('Born'); - final mahabote = astro.getMahabote(); - - final yearMM = languageCatalog.translate('Year'); - final yearname = astro.getYearName(); - - final nakhatMM = languageCatalog.translate('Nakhat'); - final nakhat = astro.getNakhat(); - - final nagapor = astro.getNagapor(); - - List holidays = mmDate.holidays; - final holidayColor = Theme.of(context).colorScheme.error; - final isPublicHoliday = isHoliday(_date, mmDate); - return Scaffold( appBar: AppBar( actions: [ @@ -149,202 +103,21 @@ class _MmCalendarDetailPageState extends ConsumerState { controller: _pageController, onPageChanged: _handlePageChange, itemBuilder: (context, index) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Container( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: isPublicHoliday - ? Theme.of(context).colorScheme.errorContainer - : Theme.of(context).colorScheme.primaryContainer, - border: Border.all( - color: isPublicHoliday - ? holidayColor - : Theme.of(context).colorScheme.primary, - ), - borderRadius: const BorderRadius.all(Radius.circular(10)), - ), - child: Text( - mmDateFull, - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: - Theme.of(context).colorScheme.onPrimaryContainer, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - sabbath, - textAlign: TextAlign.start, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - Expanded( - flex: 2, - child: Text( - // tr(LocaleKeys.nagahle, args: [nagahle]), - nagahle.isEmpty - ? '' - : '$nagaMM$headMM $nagahle $facingMM', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - astrologicalDay, - textAlign: TextAlign.start, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - Expanded( - child: Text( - mahabote.isEmpty ? '' : '$mahabote $bornMM', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - yearname.isEmpty ? '' : '$yearname $yearMM', - textAlign: TextAlign.start, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - Expanded( - child: Text( - nakhat.isEmpty ? '' : '$nakhat $nakhatMM', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - nagapor, - textAlign: TextAlign.start, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - Expanded( - child: Text( - '', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - Expanded( - child: Row( - children: [ - IconButton( - onPressed: _handlePreviousPage, - iconSize: 35, - icon: const Icon(Icons.chevron_left), - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '$mmDow ($dow)', - style: Theme.of(context).textTheme.titleLarge, - ), - if (isPublicHoliday) ...[ - const SizedBox(height: 10), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16), - child: Text( - holidays.join(', '), - style: Theme.of(context) - .textTheme - .titleMedium - ?.copyWith(color: holidayColor), - ), - ), - ], - Text( - day, - style: Theme.of(context) - .textTheme - .headlineLarge - ?.copyWith( - fontSize: - MediaQuery.sizeOf(context).width / 2, - color: isPublicHoliday - ? holidayColor - : Theme.of(context).colorScheme.onSurface, - ), - ), - Text( - monthAndYear, - style: Theme.of(context).textTheme.titleLarge, - ), - const SizedBox(height: 20), - MoonPhaseWidget( - date: _date, - size: MediaQuery.sizeOf(context).width / 6, - ), - const SizedBox(height: 20), - Text( - mmDay, - style: Theme.of(context).textTheme.titleMedium, - ), - ], - ), - ), - IconButton( - onPressed: _handleNextPage, - iconSize: 35, - icon: const Icon(Icons.chevron_right), - ), - ], - ), - ), - const SizedBox(height: 16), - ], - ); + return OrientationBuilder(builder: (context, orientation) { + if (orientation == Orientation.landscape) { + return LandscapeDateDetailWidget( + date: _date, + onPrevTap: _handlePreviousPage, + onNextTap: _handleNextPage, + ); + } + + return PortraitDateDetailWidget( + date: _date, + onPrevTap: _handlePreviousPage, + onNextTap: _handleNextPage, + ); + }); }, ), ); diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/landscape_date_detail_widget.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/landscape_date_detail_widget.dart new file mode 100644 index 0000000..35cc55c --- /dev/null +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/landscape_date_detail_widget.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:intl/intl.dart'; +import 'package:mmcalendar/src/shared/shared.dart'; +import 'package:mmcalendar/src/utils/dates.dart'; + +class LandscapeDateDetailWidget extends HookConsumerWidget { + const LandscapeDateDetailWidget({ + super.key, + required this.date, + this.onPrevTap, + this.onNextTap, + }); + + final DateTime date; + final VoidCallback? onPrevTap; + final VoidCallback? onNextTap; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final mmCalendar = ref.watch(mmCalendarProvider); + final config = ref.watch(mmCalendarConfigControllerProvider); + + final day = DateFormat().add_d().format(date); + final dow = DateFormat().add_EEEE().format(date); + final monthAndYear = DateFormat('MMMM, yyyy').format(date); + + final mmDate = mmCalendar.fromDateTime(date); + final fortnightDay = mmDate.getFortnightDay(); + + final mmDow = mmDate.format('En'); + + final mmDay = fortnightDay.isNotEmpty + ? mmDate.format('M p f r n') + : mmDate.format('M p n'); + + final mmDateFull = fortnightDay.isNotEmpty + ? mmDate.format() + : mmDate.format('S s k, B y k, M p, En'); + + final astro = mmDate.astro; + + final sabbath = astro.getSabbath(); + final astrologicalDay = astro.getAstrologicalDay(); + + final languageCatalog = LanguageCatalog(language: config.language); + final nagaMM = languageCatalog.translate('Naga'); + final headMM = languageCatalog.translate('Head'); + final facingMM = languageCatalog.translate('Facing'); + final nagahle = astro.getNagahle(); + + final bornMM = languageCatalog.translate('Born'); + final mahabote = astro.getMahabote(); + + final yearMM = languageCatalog.translate('Year'); + final yearname = astro.getYearName(); + + final nakhatMM = languageCatalog.translate('Nakhat'); + final nakhat = astro.getNakhat(); + + final nagapor = astro.getNagapor(); + + List holidays = mmDate.holidays; + final holidayColor = Theme.of(context).colorScheme.error; + final isPublicHoliday = isHoliday(date, mmDate); + + return Row( + children: [ + if (onPrevTap != null) + IconButton( + onPressed: onPrevTap, + iconSize: 35, + icon: const Icon(Icons.chevron_left), + ), + Expanded( + child: ListView( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + children: [ + Text( + '$mmDow ($dow)', + style: Theme.of(context).textTheme.titleLarge, + ), + if (isPublicHoliday && holidays.isNotEmpty) ...[ + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text( + holidays.join(', '), + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(color: holidayColor), + ), + ), + ], + Text( + day, + style: Theme.of(context) + .textTheme + .headlineLarge + ?.copyWith( + fontSize: MediaQuery.sizeOf(context).height / 4, + color: isPublicHoliday + ? holidayColor + : Theme.of(context).colorScheme.onSurface, + ), + ), + Text( + monthAndYear, + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 10), + MoonPhaseWidget( + date: date, + size: 50, + ), + const SizedBox(height: 10), + Text( + mmDay, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + ), + const SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + border: Border( + left: BorderSide( + width: 8, + color: isPublicHoliday + ? Theme.of(context).colorScheme.error + : Theme.of(context).colorScheme.primary, + ), + ), + // borderRadius: + // const BorderRadius.all(Radius.circular(4)), + ), + child: Text( + mmDateFull, + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith( + color: Theme.of(context) + .colorScheme + .onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Divider(), + ), + if (sabbath.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $sabbath', + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (nagapor.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $nagapor', + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (nagahle.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $nagaMM$headMM $nagahle $facingMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (astrologicalDay.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $astrologicalDay', + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (mahabote.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $mahabote $bornMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (nakhat.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $nakhat $nakhatMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + if (yearname.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + '\u2022 $yearname $yearMM', + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ], + ), + ), + ], + ), + ], + ), + ), + if (onNextTap != null) + IconButton( + onPressed: onNextTap, + iconSize: 35, + icon: const Icon(Icons.chevron_right), + ), + ], + ); + } +} diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/portrait_date_detail_widget.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/portrait_date_detail_widget.dart new file mode 100644 index 0000000..a3728cc --- /dev/null +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_detail/widgets/portrait_date_detail_widget.dart @@ -0,0 +1,256 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:intl/intl.dart'; +import 'package:mmcalendar/src/shared/shared.dart'; +import 'package:mmcalendar/src/utils/dates.dart'; + +class PortraitDateDetailWidget extends HookConsumerWidget { + const PortraitDateDetailWidget({ + super.key, + required this.date, + this.onPrevTap, + this.onNextTap, + }); + + final DateTime date; + final VoidCallback? onPrevTap; + final VoidCallback? onNextTap; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final mmCalendar = ref.watch(mmCalendarProvider); + final config = ref.watch(mmCalendarConfigControllerProvider); + + final day = DateFormat().add_d().format(date); + final dow = DateFormat().add_EEEE().format(date); + final monthAndYear = DateFormat('MMMM, yyyy').format(date); + + final mmDate = mmCalendar.fromDateTime(date); + final fortnightDay = mmDate.getFortnightDay(); + + final mmDow = mmDate.format('En'); + + final mmDay = fortnightDay.isNotEmpty + ? mmDate.format('M p f r n') + : mmDate.format('M p n'); + + final mmDateFull = fortnightDay.isNotEmpty + ? mmDate.format() + : mmDate.format('S s k, B y k, M p, En'); + + final languageCatalog = LanguageCatalog(language: config.language); + final astro = mmDate.astro; + + final sabbath = astro.getSabbath(); + final astrologicalDay = astro.getAstrologicalDay(); + + final nagaMM = languageCatalog.translate('Naga'); + final headMM = languageCatalog.translate('Head'); + final facingMM = languageCatalog.translate('Facing'); + final nagahle = astro.getNagahle(); + + final bornMM = languageCatalog.translate('Born'); + final mahabote = astro.getMahabote(); + + final yearMM = languageCatalog.translate('Year'); + final yearname = astro.getYearName(); + + final nakhatMM = languageCatalog.translate('Nakhat'); + final nakhat = astro.getNakhat(); + + final nagapor = astro.getNagapor(); + + List holidays = mmDate.holidays; + final holidayColor = Theme.of(context).colorScheme.error; + final isPublicHoliday = isHoliday(date, mmDate); + + return ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: isPublicHoliday + ? Theme.of(context).colorScheme.errorContainer + : Theme.of(context).colorScheme.primaryContainer, + border: Border.all( + color: isPublicHoliday + ? holidayColor + : Theme.of(context).colorScheme.primary, + ), + borderRadius: const BorderRadius.all(Radius.circular(10)), + ), + child: Text( + mmDateFull, + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context).colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + sabbath, + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Expanded( + flex: 2, + child: Text( + // tr(LocaleKeys.nagahle, args: [nagahle]), + nagahle.isEmpty ? '' : '$nagaMM$headMM $nagahle $facingMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + astrologicalDay, + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Expanded( + child: Text( + mahabote.isEmpty ? '' : '$mahabote $bornMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + yearname.isEmpty ? '' : '$yearname $yearMM', + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Expanded( + child: Text( + nakhat.isEmpty ? '' : '$nakhat $nakhatMM', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + nagapor, + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Expanded( + child: Text( + '', + textAlign: TextAlign.end, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Row( + children: [ + if (onPrevTap != null) + IconButton( + onPressed: onPrevTap, + iconSize: 35, + icon: const Icon(Icons.chevron_left), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '$mmDow ($dow)', + style: Theme.of(context).textTheme.titleLarge, + ), + if (isPublicHoliday) ...[ + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text( + holidays.join(', '), + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(color: holidayColor), + ), + ), + ], + Text( + day, + style: Theme.of(context).textTheme.headlineLarge?.copyWith( + fontSize: MediaQuery.sizeOf(context).width / 2, + color: isPublicHoliday + ? holidayColor + : Theme.of(context).colorScheme.onSurface, + ), + ), + Text( + monthAndYear, + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + MoonPhaseWidget( + date: date, + size: MediaQuery.sizeOf(context).width / 6, + ), + const SizedBox(height: 20), + Text( + mmDay, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + ), + if (onNextTap != null) + IconButton( + onPressed: onNextTap, + iconSize: 35, + icon: const Icon(Icons.chevron_right), + ), + ], + ), + const SizedBox(height: 16), + ], + ); + } +} diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_home/mm_calendar_home_page.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_home/mm_calendar_home_page.dart index f989bcd..f9c37ef 100644 --- a/lib/src/features/mm_calendar/presentation/mm_calendar_home/mm_calendar_home_page.dart +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_home/mm_calendar_home_page.dart @@ -1,13 +1,13 @@ import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:iconly/iconly.dart'; import 'package:mmcalendar/src/l10n/l10n.dart'; import 'package:mmcalendar/src/routes/routes.dart'; -import 'package:mmcalendar/src/shared/shared.dart'; -import 'package:table_calendar/table_calendar.dart'; + +import 'widgets/lanscape_calendar_view.dart'; +import 'widgets/portrait_calendar_view.dart'; @RoutePage() class MmCalendarHomePage extends StatefulHookConsumerWidget { @@ -18,7 +18,6 @@ class MmCalendarHomePage extends StatefulHookConsumerWidget { } class _MmCalendarHomePageState extends ConsumerState { - CalendarFormat _calendarFormat = CalendarFormat.month; DateTime _selectedDay = DateTime.now(); DateTime _focusDay = DateTime.now(); @@ -38,11 +37,23 @@ class _MmCalendarHomePageState extends ConsumerState { }); } + void _handleDaySelected(DateTime selectedDay, DateTime focusedDay) { + setState(() { + _selectedDay = selectedDay; + _focusDay = focusedDay; + }); + + context.router.push(MmCalendarDetailRoute(date: _selectedDay)); + } + + void _handlePageChanged(DateTime focusedDay) { + setState(() { + _focusDay = focusedDay; + }); + } + @override Widget build(BuildContext context) { - final mmCalendar = ref.watch(mmCalendarProvider); - final config = ref.watch(mmCalendarConfigControllerProvider); - return Scaffold( appBar: AppBar( title: const Text(LocaleKeys.myanmar_calendar).tr(), @@ -54,162 +65,24 @@ class _MmCalendarHomePageState extends ConsumerState { ), ], ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: TableCalendar( - availableCalendarFormats: const { - CalendarFormat.month: 'Month', - }, - locale: context.locale.languageCode, - shouldFillViewport: true, - daysOfWeekHeight: 50, - firstDay: DateTime.utc(1900, 01, 01), - lastDay: DateTime.utc(3000, 01, 01), - focusedDay: _focusDay, - calendarFormat: _calendarFormat, - calendarStyle: CalendarStyle( - selectedDecoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.primary, - ), - todayDecoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.secondary, - ), - ), - onHeaderTapped: _handleHeaderTap, - onFormatChanged: (format) { - setState(() { - _calendarFormat = format; - }); - }, - selectedDayPredicate: (day) { - return isSameDay(_selectedDay, day); - }, - onDaySelected: (selectedDay, focusedDay) { - setState(() { - _selectedDay = selectedDay; - _focusDay = focusedDay; - }); - - context.router.push(MmCalendarDetailRoute(date: _selectedDay)); - }, - onPageChanged: (focusedDay) { - setState(() { - _focusDay = focusedDay; - }); - }, - calendarBuilders: CalendarBuilders( - dowBuilder: (context, day) { - final text = DateFormat().add_E().format(day); - - if (day.weekday == DateTime.saturday || - day.weekday == DateTime.sunday) { - return Center( - child: Text( - text, - style: Theme.of(context).textTheme.labelLarge?.copyWith( - color: Theme.of(context).colorScheme.error), - ), - ); - } - - return Center( - child: Text( - text, - style: Theme.of(context).textTheme.labelLarge?.copyWith( - color: Theme.of(context).colorScheme.primary), - ), - ); - }, - defaultBuilder: (context, day, focusedDay) { - final enDay = DateFormat().add_d().format(day); - - final myanmarDate = - mmCalendar.fromDateTime(day, config: config); - - final moonPhase = myanmarDate.format('p'); - final fortnightDay = myanmarDate.format('f'); - - final mmDay = fortnightDay.isEmpty ? moonPhase : fortnightDay; - - final holidays = myanmarDate.holidays; - - return Container( - padding: const EdgeInsets.all(2), - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: Theme.of(context) - .colorScheme - .onSurface - .withOpacity(0.2), - ), - borderRadius: - const BorderRadius.all(Radius.circular(8)), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (holidays.isNotEmpty) ...[ - Container( - height: 10, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.error, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(8), - topRight: Radius.circular(8), - ), - ), - ), - ], - const SizedBox(height: 4), - Expanded( - child: Text( - enDay, - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .labelSmall - ?.copyWith(fontSize: 14), - ), - ), - const SizedBox(height: 2), - Expanded( - child: Text( - mmDay, - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .labelSmall - ?.copyWith(fontSize: 12), - ), - ), - if (fortnightDay.isNotEmpty) ...[ - Expanded( - child: Text( - moonPhase, - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .labelSmall - ?.copyWith(fontSize: 10), - ), - ), - ], - const SizedBox(height: 2), - ], - ), - ), - ); - }, - ), - ), - ), - ], - ), + body: OrientationBuilder(builder: (context, orientation) { + if (orientation == Orientation.landscape) { + return LanscapeCalendarView( + selectedDay: _selectedDay, + focusedDay: _focusDay, + onHeaderTapped: _handleHeaderTap, + onDaySelected: _handleDaySelected, + onPageChanged: _handlePageChanged, + ); + } + return PortraitCalendarView( + selectedDay: _selectedDay, + focusedDay: _focusDay, + onHeaderTapped: _handleHeaderTap, + onDaySelected: _handleDaySelected, + onPageChanged: _handlePageChanged, + ); + }), ); } } diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/lanscape_calendar_view.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/lanscape_calendar_view.dart new file mode 100644 index 0000000..6219ca2 --- /dev/null +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/lanscape_calendar_view.dart @@ -0,0 +1,177 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mmcalendar/src/shared/shared.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class LanscapeCalendarView extends HookConsumerWidget { + const LanscapeCalendarView({ + super.key, + required this.selectedDay, + required this.focusedDay, + this.calendarFormat = CalendarFormat.month, + this.onHeaderTapped, + this.onFormatChanged, + this.onPageChanged, + this.selectedDayPredicate, + this.onDaySelected, + }); + + final DateTime selectedDay; + final DateTime focusedDay; + final CalendarFormat calendarFormat; + final void Function(DateTime)? onHeaderTapped; + final void Function(CalendarFormat)? onFormatChanged; + final void Function(DateTime)? onPageChanged; + final bool Function(DateTime)? selectedDayPredicate; + final void Function(DateTime, DateTime)? onDaySelected; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final mmCalendar = ref.watch(mmCalendarProvider); + final config = ref.watch(mmCalendarConfigControllerProvider); + + return TableCalendar( + availableCalendarFormats: const {CalendarFormat.month: 'Month'}, + locale: context.locale.languageCode, + shouldFillViewport: true, + daysOfWeekHeight: 50, + firstDay: DateTime.utc(1900, 01, 01), + lastDay: DateTime.utc(3000, 01, 01), + focusedDay: focusedDay, + calendarFormat: calendarFormat, + calendarStyle: CalendarStyle( + selectedDecoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).colorScheme.primary, + ), + todayDecoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).colorScheme.secondary, + ), + ), + onHeaderTapped: onHeaderTapped, + onFormatChanged: onFormatChanged, + selectedDayPredicate: selectedDayPredicate ?? + (day) { + return isSameDay(selectedDay, day); + }, + onDaySelected: onDaySelected, + onPageChanged: onPageChanged, + calendarBuilders: CalendarBuilders( + dowBuilder: (context, day) { + final text = DateFormat().add_E().format(day); + + if (day.weekday == DateTime.saturday || + day.weekday == DateTime.sunday) { + return Center( + child: Text( + text, + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(color: Theme.of(context).colorScheme.error), + ), + ); + } + + return Center( + child: Text( + text, + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(color: Theme.of(context).colorScheme.primary), + ), + ); + }, + defaultBuilder: (context, day, focusedDay) { + final enDay = DateFormat().add_d().format(day); + + final myanmarDate = mmCalendar.fromDateTime(day, config: config); + + final isWeekend = myanmarDate.isWeekend(); + + final moonPhase = myanmarDate.format('p'); + final fortnightDay = myanmarDate.format('f'); + + final mmDay = fortnightDay.isEmpty ? moonPhase : fortnightDay; + + final holidays = myanmarDate.holidays; + + return Container( + padding: const EdgeInsets.all(2), + child: Container( + decoration: BoxDecoration( + color: isWeekend + ? Theme.of(context).colorScheme.errorContainer + : null, + border: Border.all( + color: isWeekend + ? Theme.of(context).colorScheme.error.withOpacity(0.2) + : Theme.of(context) + .colorScheme + .onSurface + .withOpacity(0.2), + ), + borderRadius: const BorderRadius.all(Radius.circular(8)), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (holidays.isNotEmpty) ...[ + Container( + height: 10, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.error, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(8), + topRight: Radius.circular(8), + ), + ), + ), + ], + Expanded( + child: Center( + child: Text( + enDay, + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith(fontSize: 14), + ), + ), + ), + if (fortnightDay.isNotEmpty) ...[ + Expanded( + child: Center( + child: Text( + moonPhase, + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith(fontSize: 10), + ), + ), + ), + ], + Expanded( + child: Center( + child: Text( + mmDay, + style: Theme.of(context).textTheme.labelSmall?.copyWith( + fontSize: 12, fontWeight: FontWeight.bold), + ), + ), + ), + const SizedBox(width: 2), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/portrait_calendar_view.dart b/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/portrait_calendar_view.dart new file mode 100644 index 0000000..ea259d9 --- /dev/null +++ b/lib/src/features/mm_calendar/presentation/mm_calendar_home/widgets/portrait_calendar_view.dart @@ -0,0 +1,189 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mmcalendar/flutter_mmcalendar.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mmcalendar/src/shared/shared.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class PortraitCalendarView extends HookConsumerWidget { + const PortraitCalendarView({ + super.key, + required this.selectedDay, + required this.focusedDay, + this.calendarFormat = CalendarFormat.month, + this.onHeaderTapped, + this.onFormatChanged, + this.onPageChanged, + this.selectedDayPredicate, + this.onDaySelected, + }); + + final DateTime selectedDay; + final DateTime focusedDay; + final CalendarFormat calendarFormat; + final void Function(DateTime)? onHeaderTapped; + final void Function(CalendarFormat)? onFormatChanged; + final void Function(DateTime)? onPageChanged; + final bool Function(DateTime)? selectedDayPredicate; + final void Function(DateTime, DateTime)? onDaySelected; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final mmCalendar = ref.watch(mmCalendarProvider); + final config = ref.watch(mmCalendarConfigControllerProvider); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: TableCalendar( + availableCalendarFormats: const {CalendarFormat.month: 'Month'}, + locale: context.locale.languageCode, + shouldFillViewport: true, + daysOfWeekHeight: 50, + firstDay: DateTime.utc(1900, 01, 01), + lastDay: DateTime.utc(3000, 01, 01), + focusedDay: focusedDay, + calendarFormat: calendarFormat, + calendarStyle: CalendarStyle( + selectedDecoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).colorScheme.primary, + ), + todayDecoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).colorScheme.secondary, + ), + ), + onHeaderTapped: onHeaderTapped, + onFormatChanged: onFormatChanged, + selectedDayPredicate: selectedDayPredicate ?? + (day) { + return isSameDay(selectedDay, day); + }, + onDaySelected: onDaySelected, + onPageChanged: onPageChanged, + calendarBuilders: CalendarBuilders( + dowBuilder: (context, day) { + final text = DateFormat().add_E().format(day); + + if (day.weekday == DateTime.saturday || + day.weekday == DateTime.sunday) { + return Center( + child: Text( + text, + style: Theme.of(context).textTheme.labelLarge?.copyWith( + color: Theme.of(context).colorScheme.error), + ), + ); + } + + return Center( + child: Text( + text, + style: Theme.of(context).textTheme.labelLarge?.copyWith( + color: Theme.of(context).colorScheme.primary), + ), + ); + }, + defaultBuilder: (context, day, focusedDay) { + final enDay = DateFormat().add_d().format(day); + + final myanmarDate = + mmCalendar.fromDateTime(day, config: config); + + final isWeekend = myanmarDate.isWeekend(); + + final moonPhase = myanmarDate.format('p'); + final fortnightDay = myanmarDate.format('f'); + + final mmDay = fortnightDay.isEmpty ? moonPhase : fortnightDay; + + final holidays = myanmarDate.holidays; + + return Container( + padding: const EdgeInsets.all(2), + child: Container( + decoration: BoxDecoration( + color: isWeekend + ? Theme.of(context).colorScheme.errorContainer + : null, + border: Border.all( + color: isWeekend + ? Theme.of(context) + .colorScheme + .error + .withOpacity(0.2) + : Theme.of(context) + .colorScheme + .onSurface + .withOpacity(0.2), + ), + borderRadius: const BorderRadius.all(Radius.circular(8)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (holidays.isNotEmpty) ...[ + Container( + height: 10, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.error, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(8), + topRight: Radius.circular(8), + ), + ), + ), + ], + const SizedBox(height: 4), + Expanded( + child: Text( + enDay, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith(fontSize: 14), + ), + ), + const SizedBox(height: 2), + Expanded( + child: Text( + mmDay, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ), + if (fortnightDay.isNotEmpty) ...[ + Expanded( + child: Text( + moonPhase, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith(fontSize: 10), + ), + ), + ], + const SizedBox(height: 2), + ], + ), + ), + ); + }, + ), + ), + ), + SizedBox(height: MediaQuery.sizeOf(context).height * 0.2), + ], + ); + } +}