💄 Optimize check in widget and add today's countdown
This commit is contained in:
		| @@ -1,3 +1,4 @@ | |||||||
|  | import 'dart:async'; | ||||||
| import 'dart:convert'; | import 'dart:convert'; | ||||||
|  |  | ||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
| @@ -57,11 +58,21 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|     final todayResult = ref.watch(checkInResultTodayProvider); |     final todayResult = ref.watch(checkInResultTodayProvider); | ||||||
|     final nextNotableDay = ref.watch(nextNotableDayProvider); |     final nextNotableDay = ref.watch(nextNotableDayProvider); | ||||||
|  |  | ||||||
|  |     // Update time every second for live progress | ||||||
|  |     final currentTime = useState(DateTime.now()); | ||||||
|  |     useEffect(() { | ||||||
|  |       final timer = Timer.periodic(const Duration(seconds: 1), (_) { | ||||||
|  |         currentTime.value = DateTime.now(); | ||||||
|  |       }); | ||||||
|  |       return timer.cancel; | ||||||
|  |     }, []); | ||||||
|  |  | ||||||
|  |     final now = currentTime.value; | ||||||
|  |  | ||||||
|     final userinfo = ref.watch(userInfoProvider); |     final userinfo = ref.watch(userInfoProvider); | ||||||
|     final isAdult = useMemoized(() { |     final isAdult = useMemoized(() { | ||||||
|       final birthday = userinfo.value?.profile.birthday; |       final birthday = userinfo.value?.profile.birthday; | ||||||
|       if (birthday == null) return false; |       if (birthday == null) return false; | ||||||
|       final now = DateTime.now(); |  | ||||||
|       final age = |       final age = | ||||||
|           now.year - |           now.year - | ||||||
|           birthday.year - |           birthday.year - | ||||||
| @@ -72,6 +83,12 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|       return age >= 18; |       return age >= 18; | ||||||
|     }, [userinfo]); |     }, [userinfo]); | ||||||
|  |  | ||||||
|  |     final progress = (now.hour * 60.0 + now.minute) / (24 * 60); | ||||||
|  |     final endOfDay = DateTime(now.year, now.month, now.day, 23, 59, 59); | ||||||
|  |     final timeLeft = endOfDay.difference(now); | ||||||
|  |     final timeLeftFormatted = | ||||||
|  |         '${timeLeft.inHours.toString().padLeft(2, '0')}:${(timeLeft.inMinutes % 60).toString().padLeft(2, '0')}:${(timeLeft.inSeconds % 60).toString().padLeft(2, '0')}'; | ||||||
|  |  | ||||||
|     Future<void> checkIn({String? captchatTk}) async { |     Future<void> checkIn({String? captchatTk}) async { | ||||||
|       final client = ref.read(apiClientProvider); |       final client = ref.read(apiClientProvider); | ||||||
|       try { |       try { | ||||||
| @@ -119,37 +136,22 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|                       fill: 1, |                       fill: 1, | ||||||
|                       size: 16, |                       size: 16, | ||||||
|                     ).padding(right: 2), |                     ).padding(right: 2), | ||||||
|                     Text(DateFormat('EEE').format(DateTime.now())) |                     Text( | ||||||
|                         .fontSize(16) |                       DateFormat('EEE').format(DateTime.now()), | ||||||
|                         .bold() |                     ).fontSize(16).bold(), | ||||||
|                         .textColor( |                     Text( | ||||||
|                           Theme.of(context).colorScheme.onSecondaryContainer, |                       DateFormat('MM/dd').format(DateTime.now()), | ||||||
|  |                     ).fontSize(16), | ||||||
|  |                     Tooltip( | ||||||
|  |                       message: timeLeftFormatted, | ||||||
|  |                       child: SizedBox( | ||||||
|  |                         width: 20, | ||||||
|  |                         height: 20, | ||||||
|  |                         child: CircularProgressIndicator( | ||||||
|  |                           value: progress, | ||||||
|  |                           strokeWidth: 2, | ||||||
|                         ), |                         ), | ||||||
|                     Text(DateFormat('MM/dd').format(DateTime.now())) |  | ||||||
|                         .fontSize(16) |  | ||||||
|                         .textColor( |  | ||||||
|                           Theme.of(context).colorScheme.onSecondaryContainer, |  | ||||||
|                       ), |                       ), | ||||||
|                     Expanded( |  | ||||||
|                       child: AnimatedSwitcher( |  | ||||||
|                         duration: const Duration(milliseconds: 300), |  | ||||||
|                         child: todayResult.when( |  | ||||||
|                           data: (result) { |  | ||||||
|                             return Text( |  | ||||||
|                               result == null |  | ||||||
|                                   ? 'checkInNone' |  | ||||||
|                                   : 'checkInResultLevel${result.level}', |  | ||||||
|                               textAlign: TextAlign.start, |  | ||||||
|                             ).tr().fontSize(15).bold(); |  | ||||||
|                           }, |  | ||||||
|                           loading: |  | ||||||
|                               () => |  | ||||||
|                                   Text('checkInNone').tr().fontSize(15).bold(), |  | ||||||
|                           error: |  | ||||||
|                               (err, stack) => |  | ||||||
|                                   Text('error').tr().fontSize(15).bold(), |  | ||||||
|                         ), |  | ||||||
|                       ).alignment(Alignment.centerLeft), |  | ||||||
|                     ), |                     ), | ||||||
|                   ], |                   ], | ||||||
|                 ), |                 ), | ||||||
| @@ -171,7 +173,7 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|                       ), |                       ), | ||||||
|                   ], |                   ], | ||||||
|                 ), |                 ), | ||||||
|                 const Gap(6), |                 const Gap(2), | ||||||
|                 AnimatedSwitcher( |                 AnimatedSwitcher( | ||||||
|                   duration: const Duration(milliseconds: 300), |                   duration: const Duration(milliseconds: 300), | ||||||
|                   child: todayResult.when( |                   child: todayResult.when( | ||||||
| @@ -224,7 +226,31 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|               ], |               ], | ||||||
|             ), |             ), | ||||||
|           ), |           ), | ||||||
|  |           Column( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             spacing: 3, | ||||||
|  |             children: [ | ||||||
|  |               AnimatedSwitcher( | ||||||
|  |                 duration: const Duration(milliseconds: 300), | ||||||
|  |                 child: todayResult.when( | ||||||
|  |                   data: (result) { | ||||||
|  |                     return Text( | ||||||
|  |                       result == null | ||||||
|  |                           ? 'checkInNone' | ||||||
|  |                           : 'checkInResultLevel${result.level}', | ||||||
|  |                       textAlign: TextAlign.start, | ||||||
|  |                     ).tr().fontSize(15).bold(); | ||||||
|  |                   }, | ||||||
|  |                   loading: () => Text('checkInNone').tr().fontSize(15).bold(), | ||||||
|  |                   error: (err, stack) => Text('error').tr().fontSize(15).bold(), | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|               IconButton.outlined( |               IconButton.outlined( | ||||||
|  |                 iconSize: 16, | ||||||
|  |                 visualDensity: const VisualDensity( | ||||||
|  |                   horizontal: -3, | ||||||
|  |                   vertical: -2, | ||||||
|  |                 ), | ||||||
|                 onPressed: () { |                 onPressed: () { | ||||||
|                   if (todayResult.valueOrNull == null) { |                   if (todayResult.valueOrNull == null) { | ||||||
|                     checkIn(); |                     checkIn(); | ||||||
| @@ -251,6 +277,8 @@ class CheckInWidget extends HookConsumerWidget { | |||||||
|                 ), |                 ), | ||||||
|               ), |               ), | ||||||
|             ], |             ], | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|       ).padding(horizontal: 16, vertical: 12), |       ).padding(horizontal: 16, vertical: 12), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user