From f533746fd7b07d71a1a3cbec8944056c0d329e84 Mon Sep 17 00:00:00 2001 From: Lisandro Pérez Meyer Date: Mon, 20 Nov 2023 17:47:26 -0300 Subject: Date time updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original from Sabin Sajeevan Bug-AGL: SPEC-4971 Change-Id: I7a961e57715fdbf8b05f54dfcf8e56159cadd068 Signed-off-by: Lisandro Pérez Meyer --- lib/data/data_providers/app_provider.dart | 9 +- lib/data/data_providers/datetime_notifier.dart | 14 -- lib/data/data_providers/time_notifier.dart | 3 + lib/data/models/date_time.dart | 59 ------ .../common_widget/custom_bottom_bar.dart | 3 +- lib/presentation/router/routes/routes.dart | 3 + lib/presentation/screens/clock/clock.dart | 45 ++--- .../date_time/date/date_screen.dart | 198 +++++++++++++++------ .../date_time/date/select_year.dart | 121 +++++++++++++ .../date_time/date_time_screen.dart | 9 +- .../date_time/time/time_screen.dart | 9 +- 11 files changed, 294 insertions(+), 179 deletions(-) delete mode 100644 lib/data/data_providers/datetime_notifier.dart delete mode 100644 lib/data/models/date_time.dart create mode 100644 lib/presentation/screens/settings/settings_screens/date_time/date/select_year.dart (limited to 'lib') diff --git a/lib/data/data_providers/app_provider.dart b/lib/data/data_providers/app_provider.dart index 80416a4..f6fb1ad 100644 --- a/lib/data/data_providers/app_provider.dart +++ b/lib/data/data_providers/app_provider.dart @@ -1,11 +1,9 @@ -import 'package:flutter_ics_homescreen/data/data_providers/datetime_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/hybrid_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/signal_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/time_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/units_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/audio_notifier.dart'; import 'package:flutter_ics_homescreen/data/data_providers/users_notifier.dart'; -import 'package:flutter_ics_homescreen/data/models/date_time.dart'; import 'package:flutter_ics_homescreen/export.dart'; import '../models/users.dart'; @@ -33,7 +31,8 @@ enum AppState { tempUnit, clock, date, - time + time, + year } final appProvider = StateProvider((ref) => AppState.splash); @@ -55,10 +54,6 @@ final usersProvider = StateNotifierProvider((ref) { return UsersNotifier(Users.initial()); }); -final dateTimeStateProvider = - StateNotifierProvider((ref) { - return DateTimeNotifier(DateAndTime.initial()); -}); final hybridtateProvider = StateNotifierProvider((ref) { return HybridNotifier(const Hybrid.initial()); }); diff --git a/lib/data/data_providers/datetime_notifier.dart b/lib/data/data_providers/datetime_notifier.dart deleted file mode 100644 index 6947a34..0000000 --- a/lib/data/data_providers/datetime_notifier.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter_ics_homescreen/data/models/date_time.dart'; -import 'package:flutter_ics_homescreen/export.dart'; - -class DateTimeNotifier extends StateNotifier { - DateTimeNotifier(super.state); - - void setDate(String newVal) { - state = state.copyWith(date: newVal); - } - - void setTime(String newVal) { - state = state.copyWith(time: newVal); - } -} diff --git a/lib/data/data_providers/time_notifier.dart b/lib/data/data_providers/time_notifier.dart index 9737b2b..c290526 100644 --- a/lib/data/data_providers/time_notifier.dart +++ b/lib/data/data_providers/time_notifier.dart @@ -11,6 +11,8 @@ class CurrentTimeNotifier extends StateNotifier { } bool _hasInitialized = false; + int? selectedYear; + bool isYearChanged = false; void _initializeTimer() { Timer.periodic(const Duration(seconds: 1), (timer) { @@ -20,5 +22,6 @@ class CurrentTimeNotifier extends StateNotifier { void setCurrentTime(DateTime newTime) { state = newTime; + selectedYear = newTime.year; } } diff --git a/lib/data/models/date_time.dart b/lib/data/models/date_time.dart deleted file mode 100644 index 62d7743..0000000 --- a/lib/data/models/date_time.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter_ics_homescreen/export.dart'; -import 'package:intl/intl.dart'; - -@immutable -class DateAndTime { - final String date; - final String time; - const DateAndTime({ - required this.date, - required this.time, - }); - - DateAndTime.initial() - : date = DateFormat().add_yMMMMd().format(DateTime.now()), - time = DateFormat('hh:mm a').format(DateTime.now()); - DateAndTime copyWith({ - String? date, - String? time, - }) { - return DateAndTime( - date: date ?? this.date, - time: time ?? this.time, - ); - } - - Map toMap() { - return { - 'date': date, - 'time': time, - }; - } - - factory DateAndTime.fromMap(Map map) { - return DateAndTime( - date: map['date'], - time: map['time'], - ); - } - - String toJson() => json.encode(toMap()); - - factory DateAndTime.fromJson(String source) => - DateAndTime.fromMap(json.decode(source)); - - @override - String toString() => 'DateAndTime(date: $date, time: $time)'; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is DateAndTime && other.date == date && other.time == time; - } - - @override - int get hashCode => date.hashCode ^ time.hashCode; -} diff --git a/lib/presentation/common_widget/custom_bottom_bar.dart b/lib/presentation/common_widget/custom_bottom_bar.dart index 13084c0..64684e9 100644 --- a/lib/presentation/common_widget/custom_bottom_bar.dart +++ b/lib/presentation/common_widget/custom_bottom_bar.dart @@ -44,7 +44,7 @@ class CustomBottomBarState extends ConsumerState { setState(() { selectedNav = title; }); - + ref.read(currentTimeProvider.notifier).isYearChanged = false; ref.read(appProvider.notifier).update((state) => state = status); } @@ -60,7 +60,6 @@ class CustomBottomBarState extends ConsumerState { mainAxisSize: MainAxisSize.min, children: [ Container( - margin: const EdgeInsets.symmetric( horizontal: 2, ), diff --git a/lib/presentation/router/routes/routes.dart b/lib/presentation/router/routes/routes.dart index d6d74c4..57e50d2 100644 --- a/lib/presentation/router/routes/routes.dart +++ b/lib/presentation/router/routes/routes.dart @@ -1,4 +1,5 @@ import 'package:flutter_ics_homescreen/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart'; +import 'package:flutter_ics_homescreen/presentation/screens/settings/settings_screens/date_time/date/select_year.dart'; import 'package:flutter_ics_homescreen/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart'; import '../../../../export.dart'; @@ -52,5 +53,7 @@ List> onGenerateAppViewPages( return [DatePage.page()]; case AppState.time: return [TimePage.page()]; + case AppState.year: + return [SelectYearPage.page()]; } } diff --git a/lib/presentation/screens/clock/clock.dart b/lib/presentation/screens/clock/clock.dart index f0858e7..ec419d6 100644 --- a/lib/presentation/screens/clock/clock.dart +++ b/lib/presentation/screens/clock/clock.dart @@ -1,6 +1,5 @@ -import 'dart:async'; - import 'package:flutter_ics_homescreen/export.dart'; +import 'package:intl/intl.dart'; class ClockPage extends ConsumerWidget { const ClockPage({super.key}); @@ -10,6 +9,7 @@ class ClockPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { double clockSize = MediaQuery.sizeOf(context).width * 0.51; + final currentTime = ref.watch(currentTimeProvider); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -66,8 +66,9 @@ class ClockPage extends ConsumerWidget { ), ), ), - child: const AnalogClock( + child: AnalogClock( dialColor: null, + dateTime: currentTime, markingColor: null, hourNumberColor: null, secondHandColor: AGLDemoColors.jordyBlueColor, @@ -96,47 +97,21 @@ class ClockPage extends ConsumerWidget { } } -class RealTimeClock extends StatefulWidget { +class RealTimeClock extends ConsumerStatefulWidget { const RealTimeClock({super.key}); @override - State createState() => _RealTimeClockState(); + RealTimeClockState createState() => RealTimeClockState(); } -class _RealTimeClockState extends State { +class RealTimeClockState extends ConsumerState { late String _timeString; - late Timer _timer; - - @override - void initState() { - _timeString = _formatDateTime(DateTime.now()); - _timer = - Timer.periodic(const Duration(seconds: 1), (Timer t) => _getTime()); - super.initState(); - } - - @override - void dispose() { - _timer.cancel(); - super.dispose(); - } - - void _getTime() { - final DateTime now = DateTime.now(); - final String formattedDateTime = _formatDateTime(now); - if (mounted) { - setState(() { - _timeString = formattedDateTime; - }); - } - } - - String _formatDateTime(DateTime dateTime) { - return "${dateTime.hour}:${dateTime.minute.toString().padLeft(2, '0')}"; - } + DateFormat dateFormat = DateFormat('hh:mm a'); @override Widget build(BuildContext context) { + final currentTime = ref.watch(currentTimeProvider); + _timeString = dateFormat.format(currentTime); return Text( _timeString, style: GoogleFonts.brunoAce(color: Colors.white, fontSize: 128), diff --git a/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart index 6802ed0..9f40a76 100644 --- a/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart @@ -1,5 +1,6 @@ +import 'package:flutter_calendar_carousel/classes/event.dart'; +import 'package:flutter_calendar_carousel/flutter_calendar_carousel.dart'; import 'package:flutter_ics_homescreen/export.dart'; -import 'package:calendar_date_picker2/calendar_date_picker2.dart'; import 'package:intl/intl.dart'; class DatePage extends ConsumerWidget { @@ -14,6 +15,7 @@ class DatePage extends ConsumerWidget { title: 'Date', hasBackButton: true, onPressed: () { + ref.read(currentTimeProvider.notifier).isYearChanged = false; context.flow().update((state) => AppState.dateTime); }, ), @@ -36,84 +38,170 @@ class DateScreenWidget extends ConsumerStatefulWidget { } class DateScreenWidgetState extends ConsumerState { - late String selectedDate; + late DateTime _currentDate; + late DateTime _currentDate2; + late String _currentMonth; + late DateTime _targetDateTime; onPressed({required String type}) { if (type == "confirm") { - ref.read(dateTimeStateProvider.notifier).setDate(selectedDate); + DateTime selectedeDate = _currentDate.copyWith( + day: _currentDate2.day, + year: _currentDate2.year, + month: _currentDate2.month); + + ref.read(currentTimeProvider.notifier).setCurrentTime(selectedeDate); context.flow().update((state) => AppState.dateTime); } else if (type == "cancel") { + ref.read(currentTimeProvider.notifier).isYearChanged = false; context.flow().update((state) => AppState.dateTime); } } @override void initState() { - selectedDate = ref.read(dateTimeStateProvider).date; - + _currentDate = ref.read(currentTimeProvider); + int? selectedYear = ref.read(currentTimeProvider.notifier).selectedYear; + if (selectedYear != null && + ref.read(currentTimeProvider.notifier).isYearChanged) { + _currentDate = _currentDate.copyWith(year: selectedYear); + } + _currentDate2 = _currentDate; + _currentMonth = DateFormat.yMMM().format(_currentDate); + _targetDateTime = _currentDate; super.initState(); } @override Widget build(BuildContext context) { Size size = MediaQuery.sizeOf(context); + + final calendarCarouselNoHeader = CalendarCarousel( + onDayPressed: (date, events) { + setState(() => _currentDate2 = date); + }, + daysHaveCircularBorder: true, + showOnlyCurrentMonthDate: false, + weekendTextStyle: + const TextStyle(color: AGLDemoColors.periwinkleColor, fontSize: 40), + daysTextStyle: + const TextStyle(color: AGLDemoColors.periwinkleColor, fontSize: 40), + thisMonthDayBorderColor: Colors.transparent, + weekFormat: false, + height: 720.0, + selectedDateTime: _currentDate2, + targetDateTime: _targetDateTime, + selectedDayButtonColor: AGLDemoColors.buttonFillEnabledColor, + customGridViewPhysics: const NeverScrollableScrollPhysics(), + showHeader: false, + todayTextStyle: + const TextStyle(color: AGLDemoColors.periwinkleColor, fontSize: 40), + nextDaysTextStyle: const TextStyle(color: Colors.transparent), + todayButtonColor: Colors.transparent, + selectedDayTextStyle: const TextStyle(color: Colors.white, fontSize: 40), + minSelectedDate: _currentDate.subtract(const Duration(days: 10958)), + maxSelectedDate: _currentDate.add(const Duration(days: 10958)), + prevDaysTextStyle: const TextStyle( + color: Colors.transparent, + ), + weekdayTextStyle: const TextStyle(color: Colors.white, fontSize: 26), + todayBorderColor: AGLDemoColors.buttonFillEnabledColor, + onCalendarChanged: (DateTime date) { + setState(() { + _targetDateTime = date; + _currentMonth = DateFormat.yMMM().format(_targetDateTime); + }); + }, + onDayLongPressed: (DateTime date) {}, + ); + return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - CalendarDatePicker2( - config: CalendarDatePicker2Config( - calendarType: CalendarDatePicker2Type.single, - dayBuilder: ( - {required date, - decoration, - isDisabled, - isSelected, - isToday, - textStyle}) { - Widget? dayWidget; - dayWidget = Container( - decoration: decoration, - child: Center( - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - Text( - MaterialLocalizations.of(context) - .formatDecimal(date.day), - style: textStyle, - ), - ], + Container( + margin: const EdgeInsets.only( + top: 30.0, + bottom: 16.0, + left: 16.0, + right: 16.0, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: TextButton( + onPressed: () { + context.flow().update((state) => AppState.year); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _currentMonth, + style: const TextStyle( + color: AGLDemoColors.periwinkleColor, + fontSize: 40.0, + ), ), + const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Icon( + Icons.keyboard_arrow_down, + size: 40, + color: AGLDemoColors.periwinkleColor, + ), + ) + ], + ), + )), + Row( + children: [ + TextButton( + child: const Padding( + padding: EdgeInsets.all(15.0), + child: Icon( + Icons.arrow_back_ios, + size: 30, + color: AGLDemoColors.periwinkleColor, + ), + ), + onPressed: () { + setState(() { + _targetDateTime = DateTime( + _targetDateTime.year, _targetDateTime.month - 1); + _currentMonth = + DateFormat.yMMM().format(_targetDateTime); + }); + }, ), - ); - - return dayWidget; - }, - dayTextStyle: const TextStyle( - color: AGLDemoColors.periwinkleColor, fontSize: 40), - selectedDayHighlightColor: AGLDemoColors.neonBlueColor, - controlsTextStyle: const TextStyle( - color: AGLDemoColors.periwinkleColor, fontSize: 40), - weekdayLabelTextStyle: const TextStyle( - color: AGLDemoColors.periwinkleColor, fontSize: 40), - controlsHeight: 40, - dayTextStylePredicate: ({required date}) { - return const TextStyle( - color: AGLDemoColors.periwinkleColor, fontSize: 40); - }, - selectedDayTextStyle: - const TextStyle(color: Colors.white, fontSize: 40)), - value: selectedDate == "mm/dd/yyyy" - ? [] - : [DateFormat().add_yMMMMd().parse(selectedDate)], - onValueChanged: (dates) { - setState(() { - selectedDate = DateFormat().add_yMMMMd().format(dates.first!); - }); - }, + TextButton( + child: const Padding( + padding: EdgeInsets.all(15.0), + child: Icon( + Icons.arrow_forward_ios, + size: 30, + color: AGLDemoColors.periwinkleColor, + ), + ), + onPressed: () { + setState(() { + _targetDateTime = DateTime( + _targetDateTime.year, _targetDateTime.month + 1); + _currentMonth = + DateFormat.yMMM().format(_targetDateTime); + }); + }, + ), + ], + ) + ], + ), + ), + Container( + child: calendarCarouselNoHeader, ), const SizedBox( - height: 120, + height: 180, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/lib/presentation/screens/settings/settings_screens/date_time/date/select_year.dart b/lib/presentation/screens/settings/settings_screens/date_time/date/select_year.dart new file mode 100644 index 0000000..f41a60e --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/date_time/date/select_year.dart @@ -0,0 +1,121 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class SelectYearPage extends ConsumerWidget { + const SelectYearPage({super.key}); + static Page page() => const MaterialPage(child: SelectYearPage()); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column(children: [ + CommonTitle( + title: 'Select Year', + hasBackButton: true, + onPressed: () { + context.flow().update((state) => AppState.date); + }, + ), + const Expanded( + child: Padding( + padding: + EdgeInsets.only(top: 50, left: 144, right: 144, bottom: 200), + child: SelectYearWidget()), + ), + ]), + ); + } +} + +class SelectYearWidget extends ConsumerStatefulWidget { + const SelectYearWidget({super.key}); + Page page() => const MaterialPage(child: SelectYearWidget()); + + @override + SelectYearWidgetState createState() => SelectYearWidgetState(); +} + +class SelectYearWidgetState extends ConsumerState { + late int selectedYear; + late ScrollController controller; + + onPressed({required int year}) { + setState(() { + selectedYear = year; + }); + ref.read(currentTimeProvider.notifier).selectedYear = selectedYear; + ref.read(currentTimeProvider.notifier).isYearChanged = true; + context.flow().update((state) => AppState.date); + } + + @override + void initState() { + DateTime currentDate = ref.read(currentTimeProvider); + int? selYear = ref.read(currentTimeProvider.notifier).selectedYear; + + if (selYear != null && + ref.read(currentTimeProvider.notifier).isYearChanged) { + selectedYear = selYear; + } else { + selectedYear = currentDate.year; + } + controller = ScrollController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + final position = controller.position.maxScrollExtent / 2; + controller.jumpTo(position); + }); + super.initState(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 20, bottom: 150), + child: SingleChildScrollView( + controller: controller, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (var i = selectedYear - 30; i < selectedYear + 30; i++) + Column( + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric( + vertical: 30, horizontal: 30), + onTap: () { + onPressed(year: i); + }, + title: Text( + i.toString(), + style: TextStyle( + color: selectedYear == i + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontSize: 40), + ), + trailing: selectedYear == i + ? const Icon( + Icons.check, + color: AGLDemoColors.neonBlueColor, + size: 40, + ) + : null, + ), + const Divider( + color: AGLDemoColors.buttonFillEnabledColor, + height: 1, + thickness: 1, + ) + ], + ) + ], + ), + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart index c9a3abf..caf56a1 100644 --- a/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart @@ -7,8 +7,9 @@ class DateTimePage extends ConsumerWidget { static Page page() => const MaterialPage(child: DateTimePage()); @override Widget build(BuildContext context, WidgetRef ref) { - final dateTime = ref.watch(dateTimeStateProvider.select((val) => val)); - DateFormat dateFormat = DateFormat('hh:mm a'); + DateFormat dateFormat = DateFormat().add_yMMMMd(); + DateFormat timeFormat = DateFormat('hh:mm a'); + final currentime = ref.watch(currentTimeProvider); return Scaffold( @@ -29,7 +30,7 @@ class DateTimePage extends ConsumerWidget { UnitsTile( image: "assets/Calendar.svg", title: 'Date', - unitName: dateTime.date, + unitName: dateFormat.format(currentime), hasSwich: false, voidCallback: () async { context @@ -39,7 +40,7 @@ class DateTimePage extends ConsumerWidget { UnitsTile( image: "assets/Time.svg", title: 'Time', - unitName: dateFormat.format(currentime), + unitName: timeFormat.format(currentime), hasSwich: true, voidCallback: () { context diff --git a/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart index de8adb4..8d0a228 100644 --- a/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart @@ -43,14 +43,17 @@ class TimeScreenWidgetState extends ConsumerState { TextEditingController hourController = TextEditingController(); TextEditingController minuteController = TextEditingController(); - + late DateTime currentTime; onPressed({required String type}) { if (type == "confirm") { if (hourController.text.isNotEmpty && minuteController.text.isNotEmpty) { String input = '${hourController.text}:${minuteController.text} $selectedMeridien'; DateTime selectedeDatetime = DateFormat.jm().parse(input); - + selectedeDatetime = selectedeDatetime.copyWith( + day: currentTime.day, + year: currentTime.year, + month: currentTime.month); ref .read(currentTimeProvider.notifier) .setCurrentTime(selectedeDatetime); @@ -69,7 +72,7 @@ class TimeScreenWidgetState extends ConsumerState { @override void initState() { - DateTime currentTime = ref.read(currentTimeProvider); + currentTime = ref.read(currentTimeProvider); String time = DateFormat('hh:mm a').format(currentTime); List split = time.split(":"); -- cgit 1.2.3-korg