Showing
9 changed files
with
129 additions
and
91 deletions
| @@ -405,28 +405,33 @@ class TodayTabBody extends StatelessWidget { | @@ -405,28 +405,33 @@ class TodayTabBody extends StatelessWidget { | ||
| 405 | 405 | ||
| 406 | Widget _buildWeekdayCell(BuildContext context, DateTime day) { | 406 | Widget _buildWeekdayCell(BuildContext context, DateTime day) { |
| 407 | final selected = isSameDay(controller.selectedDate.value, day); | 407 | final selected = isSameDay(controller.selectedDate.value, day); |
| 408 | + final isEnabled = !_isAfterToday(day); | ||
| 408 | 409 | ||
| 409 | - return Center( | ||
| 410 | - child: Container( | ||
| 411 | - width: _selectedDayWidth, | ||
| 412 | - height: _weekRowsHeight / 2, | ||
| 413 | - alignment: Alignment.center, | ||
| 414 | - decoration: selected | ||
| 415 | - ? BoxDecoration( | ||
| 416 | - color: context.colors.primary, | ||
| 417 | - borderRadius: const BorderRadius.vertical( | ||
| 418 | - top: Radius.circular(22), | ||
| 419 | - ), | ||
| 420 | - ) | ||
| 421 | - : null, | ||
| 422 | - child: Text( | ||
| 423 | - isSameDay(day, controller.lastSelectableDay) | ||
| 424 | - ? AppLocalizations.of(context)!.today | ||
| 425 | - : _weekdayText(context, day), | ||
| 426 | - style: TextStyle( | ||
| 427 | - color: _calendarTextColor(context, day, selected: selected), | ||
| 428 | - fontSize: 12, | ||
| 429 | - fontWeight: FontWeight.w500, | 410 | + return GestureDetector( |
| 411 | + behavior: HitTestBehavior.opaque, | ||
| 412 | + onTap: isEnabled ? () => _onDaySelected(day, day) : null, | ||
| 413 | + child: Center( | ||
| 414 | + child: Container( | ||
| 415 | + width: _selectedDayWidth, | ||
| 416 | + height: _weekRowsHeight / 2, | ||
| 417 | + alignment: Alignment.center, | ||
| 418 | + decoration: selected | ||
| 419 | + ? BoxDecoration( | ||
| 420 | + color: context.colors.primary, | ||
| 421 | + borderRadius: const BorderRadius.vertical( | ||
| 422 | + top: Radius.circular(22), | ||
| 423 | + ), | ||
| 424 | + ) | ||
| 425 | + : null, | ||
| 426 | + child: Text( | ||
| 427 | + isSameDay(day, controller.lastSelectableDay) | ||
| 428 | + ? AppLocalizations.of(context)!.today | ||
| 429 | + : _weekdayText(context, day), | ||
| 430 | + style: TextStyle( | ||
| 431 | + color: _calendarTextColor(context, day, selected: selected), | ||
| 432 | + fontSize: 12, | ||
| 433 | + fontWeight: FontWeight.w500, | ||
| 434 | + ), | ||
| 430 | ), | 435 | ), |
| 431 | ), | 436 | ), |
| 432 | ), | 437 | ), |
| @@ -438,25 +443,31 @@ class TodayTabBody extends StatelessWidget { | @@ -438,25 +443,31 @@ class TodayTabBody extends StatelessWidget { | ||
| 438 | DateTime day, { | 443 | DateTime day, { |
| 439 | bool selected = false, | 444 | bool selected = false, |
| 440 | }) { | 445 | }) { |
| 441 | - return Center( | ||
| 442 | - child: Container( | ||
| 443 | - width: _selectedDayWidth, | ||
| 444 | - height: _weekRowsHeight / 2, | ||
| 445 | - alignment: Alignment.center, | ||
| 446 | - decoration: selected | ||
| 447 | - ? BoxDecoration( | ||
| 448 | - color: context.colors.primary, | ||
| 449 | - borderRadius: const BorderRadius.vertical( | ||
| 450 | - bottom: Radius.circular(22), | ||
| 451 | - ), | ||
| 452 | - ) | ||
| 453 | - : null, | ||
| 454 | - child: Text( | ||
| 455 | - '${day.day}', | ||
| 456 | - style: TextStyle( | ||
| 457 | - color: _calendarTextColor(context, day, selected: selected), | ||
| 458 | - fontSize: 12, | ||
| 459 | - fontWeight: FontWeight.w500, | 446 | + final isEnabled = !_isAfterToday(day); |
| 447 | + | ||
| 448 | + return GestureDetector( | ||
| 449 | + behavior: HitTestBehavior.opaque, | ||
| 450 | + onTap: isEnabled ? () => _onDaySelected(day, day) : null, | ||
| 451 | + child: Center( | ||
| 452 | + child: Container( | ||
| 453 | + width: _selectedDayWidth, | ||
| 454 | + height: _weekRowsHeight / 2, | ||
| 455 | + alignment: Alignment.center, | ||
| 456 | + decoration: selected | ||
| 457 | + ? BoxDecoration( | ||
| 458 | + color: context.colors.primary, | ||
| 459 | + borderRadius: const BorderRadius.vertical( | ||
| 460 | + bottom: Radius.circular(22), | ||
| 461 | + ), | ||
| 462 | + ) | ||
| 463 | + : null, | ||
| 464 | + child: Text( | ||
| 465 | + '${day.day}', | ||
| 466 | + style: TextStyle( | ||
| 467 | + color: _calendarTextColor(context, day, selected: selected), | ||
| 468 | + fontSize: 12, | ||
| 469 | + fontWeight: FontWeight.w500, | ||
| 470 | + ), | ||
| 460 | ), | 471 | ), |
| 461 | ), | 472 | ), |
| 462 | ), | 473 | ), |
| @@ -480,7 +491,12 @@ class TodayTabBody extends StatelessWidget { | @@ -480,7 +491,12 @@ class TodayTabBody extends StatelessWidget { | ||
| 480 | if (isSameDay(selectedDay, today.subtract(const Duration(days: 2)))) { | 491 | if (isSameDay(selectedDay, today.subtract(const Duration(days: 2)))) { |
| 481 | return '前天'; | 492 | return '前天'; |
| 482 | } | 493 | } |
| 483 | - return MaterialLocalizations.of(context).formatShortMonthDay(selectedDay); | 494 | + final locale = Localizations.localeOf(context).toString(); |
| 495 | + if (selectedDay.year == today.year) { | ||
| 496 | + return DateFormat.Md(locale).format(selectedDay); | ||
| 497 | + } else { | ||
| 498 | + return DateFormat.yMd(locale).format(selectedDay); | ||
| 499 | + } | ||
| 484 | } | 500 | } |
| 485 | 501 | ||
| 486 | bool _isAfterToday(DateTime day) { | 502 | bool _isAfterToday(DateTime day) { |
| 1 | +import 'package:doublefeel_flutter/app/routes/app_pages.dart'; | ||
| 1 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; | 2 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; |
| 2 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; | 3 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; |
| 3 | import 'package:flutter/material.dart'; | 4 | import 'package:flutter/material.dart'; |
| @@ -247,12 +248,19 @@ class _ContactText extends StatelessWidget { | @@ -247,12 +248,19 @@ class _ContactText extends StatelessWidget { | ||
| 247 | ), | 248 | ), |
| 248 | children: [ | 249 | children: [ |
| 249 | TextSpan(text: l10n.todayFaqContactPrefix), | 250 | TextSpan(text: l10n.todayFaqContactPrefix), |
| 250 | - TextSpan( | ||
| 251 | - text: l10n.todayFaqContactAction, | ||
| 252 | - style: TextStyle( | ||
| 253 | - color: context.colors.primary, | ||
| 254 | - fontWeight: FontWeight.w600, | ||
| 255 | - decoration: TextDecoration.underline, | 251 | + WidgetSpan( |
| 252 | + child: GestureDetector( | ||
| 253 | + onTap: () { | ||
| 254 | + Get.toNamed(Routes.SUBMIT_FEEDBACK); | ||
| 255 | + }, | ||
| 256 | + child: Text( | ||
| 257 | + l10n.todayFaqContactAction, | ||
| 258 | + style: TextStyle( | ||
| 259 | + color: context.colors.primary, | ||
| 260 | + fontWeight: FontWeight.w600, | ||
| 261 | + decoration: TextDecoration.underline, | ||
| 262 | + ), | ||
| 263 | + ), | ||
| 256 | ), | 264 | ), |
| 257 | ), | 265 | ), |
| 258 | TextSpan(text: l10n.todayFaqContactSuffix), | 266 | TextSpan(text: l10n.todayFaqContactSuffix), |
| @@ -19,33 +19,38 @@ class TodayHrvNumberCard extends StatelessWidget { | @@ -19,33 +19,38 @@ class TodayHrvNumberCard extends StatelessWidget { | ||
| 19 | color: Colors.white, | 19 | color: Colors.white, |
| 20 | borderRadius: BorderRadius.circular(16), | 20 | borderRadius: BorderRadius.circular(16), |
| 21 | ), | 21 | ), |
| 22 | - child: Obx(() => Row( | ||
| 23 | - children: [ | ||
| 24 | - // HRV | ||
| 25 | - Expanded( | ||
| 26 | - child: _NumberItem( | ||
| 27 | - label: controller.isFriend | ||
| 28 | - ? 'Ta今日的平均HRV' | ||
| 29 | - : context.l10n.averageHrvForTheDay, | ||
| 30 | - value: | ||
| 31 | - controller.v2HealthData.value?.hrvAvg?.toString() ?? '--', | ||
| 32 | - unit: 'ms', | ||
| 33 | - ), | 22 | + child: Obx(() { |
| 23 | + var sameDay = DateUtils.isSameDay( | ||
| 24 | + controller.selectedDate.value, controller.lastSelectableDay); | ||
| 25 | + | ||
| 26 | + return Row( | ||
| 27 | + children: [ | ||
| 28 | + // HRV | ||
| 29 | + Expanded( | ||
| 30 | + child: _NumberItem( | ||
| 31 | + label: controller.isFriend | ||
| 32 | + ? (sameDay ? 'Ta的今日平均HRV' : 'Ta的该日平均HRV') | ||
| 33 | + : (sameDay ? '今日HRV趋势' : context.l10n.averageHrvForTheDay), | ||
| 34 | + value: | ||
| 35 | + controller.v2HealthData.value?.hrvAvg?.toString() ?? '--', | ||
| 36 | + unit: 'ms', | ||
| 34 | ), | 37 | ), |
| 38 | + ), | ||
| 35 | 39 | ||
| 36 | - Expanded( | ||
| 37 | - child: _NumberItem( | ||
| 38 | - label: controller.isFriend | ||
| 39 | - ? 'Ta的静息心率' | ||
| 40 | - : context.l10n.restingHeartRate, | ||
| 41 | - value: controller.v2HealthData.value?.lastRestingHrValue | ||
| 42 | - ?.toString() ?? | ||
| 43 | - '--', | ||
| 44 | - unit: 'bpm', | ||
| 45 | - ), | 40 | + Expanded( |
| 41 | + child: _NumberItem( | ||
| 42 | + label: controller.isFriend | ||
| 43 | + ? 'Ta的静息心率' | ||
| 44 | + : context.l10n.restingHeartRate, | ||
| 45 | + value: controller.v2HealthData.value?.lastRestingHrValue | ||
| 46 | + ?.toString() ?? | ||
| 47 | + '--', | ||
| 48 | + unit: 'bpm', | ||
| 46 | ), | 49 | ), |
| 47 | - ], | ||
| 48 | - )), | 50 | + ), |
| 51 | + ], | ||
| 52 | + ); | ||
| 53 | + }), | ||
| 49 | ); | 54 | ); |
| 50 | } | 55 | } |
| 51 | } | 56 | } |
| 1 | import 'package:doublefeel_flutter/app/modules/membership_offer/controllers/membership_offer_controller.dart'; | 1 | import 'package:doublefeel_flutter/app/modules/membership_offer/controllers/membership_offer_controller.dart'; |
| 2 | import 'package:doublefeel_flutter/app/routes/app_pages.dart'; | 2 | import 'package:doublefeel_flutter/app/routes/app_pages.dart'; |
| 3 | -import 'package:doublefeel_flutter/core/services/user_state_service.dart'; | ||
| 4 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; | 3 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; |
| 5 | -import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; | ||
| 6 | import 'package:doublefeel_flutter/data/models/pay/pay_models.dart'; | 4 | import 'package:doublefeel_flutter/data/models/pay/pay_models.dart'; |
| 7 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; | 5 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; |
| 8 | import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; | 6 | import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; |
| @@ -41,7 +39,9 @@ class MembershipOfferView extends GetView<MembershipOfferController> { | @@ -41,7 +39,9 @@ class MembershipOfferView extends GetView<MembershipOfferController> { | ||
| 41 | ), | 39 | ), |
| 42 | child: Stack( | 40 | child: Stack( |
| 43 | children: [ | 41 | children: [ |
| 44 | - Lottie.asset('assets/lottie/scatter_flowers.json'), | 42 | + IgnorePointer( |
| 43 | + child: Lottie.asset('assets/lottie/scatter_flowers.json'), | ||
| 44 | + ), | ||
| 45 | Column( | 45 | Column( |
| 46 | mainAxisSize: MainAxisSize.max, | 46 | mainAxisSize: MainAxisSize.max, |
| 47 | children: [ | 47 | children: [ |
| @@ -106,20 +106,27 @@ class MembershipOfferView extends GetView<MembershipOfferController> { | @@ -106,20 +106,27 @@ class MembershipOfferView extends GetView<MembershipOfferController> { | ||
| 106 | ], | 106 | ], |
| 107 | ); | 107 | ); |
| 108 | }), | 108 | }), |
| 109 | - const SizedBox(height: 70), | 109 | + const SizedBox(height: 58), |
| 110 | GestureDetector( | 110 | GestureDetector( |
| 111 | + behavior: HitTestBehavior.opaque, | ||
| 111 | onTap: () { | 112 | onTap: () { |
| 112 | Get.offNamed(Routes.PURCHASE); | 113 | Get.offNamed(Routes.PURCHASE); |
| 113 | }, | 114 | }, |
| 114 | - child: Text( | ||
| 115 | - l10n.onboardingMemberAllOptions, | ||
| 116 | - textAlign: TextAlign.center, | ||
| 117 | - style: TextStyle( | ||
| 118 | - color: context.colors.textPrimary, | ||
| 119 | - fontSize: 12, | ||
| 120 | - decoration: TextDecoration.underline, | ||
| 121 | - decorationColor: context.colors.textPrimary, | ||
| 122 | - letterSpacing: 0, | 115 | + child: Padding( |
| 116 | + padding: const EdgeInsets.symmetric( | ||
| 117 | + vertical: 12, | ||
| 118 | + horizontal: 24, | ||
| 119 | + ), | ||
| 120 | + child: Text( | ||
| 121 | + l10n.onboardingMemberAllOptions, | ||
| 122 | + textAlign: TextAlign.center, | ||
| 123 | + style: TextStyle( | ||
| 124 | + color: context.colors.textPrimary, | ||
| 125 | + fontSize: 12, | ||
| 126 | + decoration: TextDecoration.underline, | ||
| 127 | + decorationColor: context.colors.textPrimary, | ||
| 128 | + letterSpacing: 0, | ||
| 129 | + ), | ||
| 123 | ), | 130 | ), |
| 124 | ), | 131 | ), |
| 125 | ), | 132 | ), |
| @@ -62,7 +62,9 @@ class PremiumActivatedView extends GetView<PremiumActivatedController> { | @@ -62,7 +62,9 @@ class PremiumActivatedView extends GetView<PremiumActivatedController> { | ||
| 62 | Widget _buildContentView(BuildContext context) { | 62 | Widget _buildContentView(BuildContext context) { |
| 63 | return Stack( | 63 | return Stack( |
| 64 | children: [ | 64 | children: [ |
| 65 | - Lottie.asset('assets/lottie/scatter_flowers.json'), | 65 | + IgnorePointer( |
| 66 | + child: Lottie.asset('assets/lottie/scatter_flowers.json'), | ||
| 67 | + ), | ||
| 66 | Column( | 68 | Column( |
| 67 | mainAxisAlignment: MainAxisAlignment.start, | 69 | mainAxisAlignment: MainAxisAlignment.start, |
| 68 | crossAxisAlignment: CrossAxisAlignment.center, | 70 | crossAxisAlignment: CrossAxisAlignment.center, |
| @@ -187,11 +187,11 @@ class V2HealthData { | @@ -187,11 +187,11 @@ class V2HealthData { | ||
| 187 | sleepStateStr() { | 187 | sleepStateStr() { |
| 188 | switch (sleepState) { | 188 | switch (sleepState) { |
| 189 | case 1: | 189 | case 1: |
| 190 | - return '睡得很棒'; | 190 | + return '优秀'; |
| 191 | case 2: | 191 | case 2: |
| 192 | - return '睡得不错'; | 192 | + return '正常'; |
| 193 | case 3: | 193 | case 3: |
| 194 | - return '睡得差'; | 194 | + return '注意'; |
| 195 | } | 195 | } |
| 196 | return '--'; | 196 | return '--'; |
| 197 | } | 197 | } |
| @@ -305,7 +305,7 @@ | @@ -305,7 +305,7 @@ | ||
| 305 | "todayFaqWatchFaceDelayRestartWatch": "· 若仍未自动刷新,请重启手表。长时间运行或后台占用过高可能导致表盘暂停更新。", | 305 | "todayFaqWatchFaceDelayRestartWatch": "· 若仍未自动刷新,请重启手表。长时间运行或后台占用过高可能导致表盘暂停更新。", |
| 306 | "todayFaqWatchFaceBlackScreenTitle": "手表表盘出现黑屏?", | 306 | "todayFaqWatchFaceBlackScreenTitle": "手表表盘出现黑屏?", |
| 307 | "todayFaqWatchFaceBlackScreenDescription": "若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。", | 307 | "todayFaqWatchFaceBlackScreenDescription": "若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。", |
| 308 | - "today": "今天", | 308 | + "today": "今日", |
| 309 | "yesterday": "昨天", | 309 | "yesterday": "昨天", |
| 310 | "backToToday": "回今天", | 310 | "backToToday": "回今天", |
| 311 | "redeemOffer": "领取优惠", | 311 | "redeemOffer": "领取优惠", |
| @@ -1434,7 +1434,7 @@ abstract class AppLocalizations { | @@ -1434,7 +1434,7 @@ abstract class AppLocalizations { | ||
| 1434 | /// No description provided for @today. | 1434 | /// No description provided for @today. |
| 1435 | /// | 1435 | /// |
| 1436 | /// In zh, this message translates to: | 1436 | /// In zh, this message translates to: |
| 1437 | - /// **'今天'** | 1437 | + /// **'今日'** |
| 1438 | String get today; | 1438 | String get today; |
| 1439 | 1439 | ||
| 1440 | /// No description provided for @yesterday. | 1440 | /// No description provided for @yesterday. |
| @@ -733,7 +733,7 @@ class AppLocalizationsZh extends AppLocalizations { | @@ -733,7 +733,7 @@ class AppLocalizationsZh extends AppLocalizations { | ||
| 733 | '若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。'; | 733 | '若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。'; |
| 734 | 734 | ||
| 735 | @override | 735 | @override |
| 736 | - String get today => '今天'; | 736 | + String get today => '今日'; |
| 737 | 737 | ||
| 738 | @override | 738 | @override |
| 739 | String get yesterday => '昨天'; | 739 | String get yesterday => '昨天'; |
-
Please register or login to post a comment