Commit d5b95558ca33ef8cfcb3c59ccb7d32e4e88a0b8e

Authored by 常守达
1 parent 08bbfa57

fix(today):数据展示兼容

@@ -667,9 +667,9 @@ class TodayController extends GetMaterialController { @@ -667,9 +667,9 @@ class TodayController extends GetMaterialController {
667 super.didChangeAppLifecycleState(state); 667 super.didChangeAppLifecycleState(state);
668 668
669 if (state == AppLifecycleState.resumed) { 669 if (state == AppLifecycleState.resumed) {
670 - var today = DateUtils.dateOnly(DateTime.now());  
671 - lastSelectableDay.value = today;  
672 - changeDate(today); 670 + // var today = DateUtils.dateOnly(DateTime.now());
  671 + // lastSelectableDay.value = today;
  672 + // changeDate(today);
673 checkAddFriendVisible(); 673 checkAddFriendVisible();
674 checkHrvAdBannerVisible(); 674 checkHrvAdBannerVisible();
675 checkHealthDataAuthCardVisible(); 675 checkHealthDataAuthCardVisible();
@@ -682,9 +682,9 @@ class TodayController extends GetMaterialController { @@ -682,9 +682,9 @@ class TodayController extends GetMaterialController {
682 _isFirstLoad = false; 682 _isFirstLoad = false;
683 return; 683 return;
684 } 684 }
685 - var today = DateUtils.dateOnly(DateTime.now());  
686 - lastSelectableDay.value = today;  
687 - changeDate(today); 685 + // var today = DateUtils.dateOnly(DateTime.now());
  686 + // lastSelectableDay.value = today;
  687 + // changeDate(today);
688 checkAddFriendVisible(); 688 checkAddFriendVisible();
689 checkHrvAdBannerVisible(); 689 checkHrvAdBannerVisible();
690 checkHealthDataAuthCardVisible(); 690 checkHealthDataAuthCardVisible();
@@ -7,8 +7,8 @@ import 'package:flutter/material.dart'; @@ -7,8 +7,8 @@ import 'package:flutter/material.dart';
7 /// 传入 [score](0~100 压力分): 7 /// 传入 [score](0~100 压力分):
8 /// - null → 加载态:四段等宽 20px,无 indicator 8 /// - null → 加载态:四段等宽 20px,无 indicator
9 /// - 0~20 → 优秀·绿段(status 3) 9 /// - 0~20 → 优秀·绿段(status 3)
10 -/// - 21~50 → 正常·蓝段(status 2)  
11 -/// - 51~80 → 注意压力·橙段(status 1) 10 +/// - 21~60 → 正常·蓝段(status 2)
  11 +/// - 61~80 → 注意压力·橙段(status 1)
12 /// - 81~100 → 压力过载·红段(status 0) 12 /// - 81~100 → 压力过载·红段(status 0)
13 /// 13 ///
14 /// indicator 在命中段内的横向位置由分数在该区间的位置决定: 14 /// indicator 在命中段内的横向位置由分数在该区间的位置决定:
@@ -43,19 +43,19 @@ class StressProgressBar extends StatelessWidget { @@ -43,19 +43,19 @@ class StressProgressBar extends StatelessWidget {
43 static const _curve = Curves.easeInOut; 43 static const _curve = Curves.easeInOut;
44 44
45 // ── 分数区间边界(左闭右闭)─────────────────────────── 45 // ── 分数区间边界(左闭右闭)───────────────────────────
46 - // status 3 (绿): 0~20 status 2 (蓝): 21~50  
47 - // status 1 (橙): 51~80 status 0 (红): 81~100 46 + // status 3 (绿): 0~20 status 2 (蓝): 21~60
  47 + // status 1 (橙): 61~80 status 0 (红): 81~100
48 static const _ranges = [ 48 static const _ranges = [
49 (lo: 81, hi: 100), // status 0 49 (lo: 81, hi: 100), // status 0
50 - (lo: 51, hi: 80), // status 1  
51 - (lo: 21, hi: 50), // status 2 50 + (lo: 61, hi: 80), // status 1
  51 + (lo: 21, hi: 60), // status 2
52 (lo: 0, hi: 20), // status 3 52 (lo: 0, hi: 20), // status 3
53 ]; 53 ];
54 54
55 /// 由压力分计算命中段(0=过载, 1=注意, 2=正常, 3=活力) 55 /// 由压力分计算命中段(0=过载, 1=注意, 2=正常, 3=活力)
56 static int _statusFromScore(int s) { 56 static int _statusFromScore(int s) {
57 if (s <= 20) return 3; 57 if (s <= 20) return 3;
58 - if (s <= 50) return 2; 58 + if (s <= 60) return 2;
59 if (s <= 80) return 1; 59 if (s <= 80) return 1;
60 return 0; 60 return 0;
61 } 61 }
@@ -376,10 +376,11 @@ class TodayHrvChartCard extends StatelessWidget { @@ -376,10 +376,11 @@ class TodayHrvChartCard extends StatelessWidget {
376 return l10n.waitingForData; 376 return l10n.waitingForData;
377 } 377 }
378 378
379 - List<TextSpan>? _getTooltip(BarChartRodData rod, int x, int? state) { 379 + List<TextSpan>? _getTooltip(
  380 + BarChartRodData rod, int x, int? state, bool? isWorkout) {
380 return [ 381 return [
381 TextSpan( 382 TextSpan(
382 - text: '○ ', 383 + text: isWorkout == true ? '◉ ' : '○ ',
383 style: TextStyle( 384 style: TextStyle(
384 fontSize: 14, 385 fontSize: 14,
385 color: _getColorByState(state), 386 color: _getColorByState(state),
@@ -390,7 +391,9 @@ class TodayHrvChartCard extends StatelessWidget { @@ -390,7 +391,9 @@ class TodayHrvChartCard extends StatelessWidget {
390 ), 391 ),
391 ), 392 ),
392 TextSpan( 393 TextSpan(
393 - text: '${_getStatusByState(state)} ${_formatNumber(rod.toY)}%', 394 + text: isWorkout == true
  395 + ? l10n.frequentMovement
  396 + : '${_getStatusByState(state)} ${_formatNumber(rod.toY)}%',
394 style: TextStyle( 397 style: TextStyle(
395 fontSize: 18, 398 fontSize: 18,
396 color: _getColorByState(state), 399 color: _getColorByState(state),
@@ -531,13 +534,16 @@ class _HrvLineChartState extends State<_HrvLineChart> { @@ -531,13 +534,16 @@ class _HrvLineChartState extends State<_HrvLineChart> {
531 534
532 @override 535 @override
533 Widget build(BuildContext context) { 536 Widget build(BuildContext context) {
  537 + final maxY = widget.spots.isEmpty
  538 + ? 100.0
  539 + : widget.spots.map((s) => s.y).reduce((a, b) => a > b ? a : b) * 1.1;
534 return LineChart( 540 return LineChart(
535 LineChartData( 541 LineChartData(
536 clipData: const FlClipData.none(), 542 clipData: const FlClipData.none(),
537 minX: 0, 543 minX: 0,
538 maxX: widget.maxSeconds, 544 maxX: widget.maxSeconds,
539 minY: 0, 545 minY: 0,
540 - maxY: 100, 546 + maxY: maxY,
541 gridData: FlGridData( 547 gridData: FlGridData(
542 show: true, 548 show: true,
543 drawVerticalLine: true, 549 drawVerticalLine: true,
@@ -626,7 +632,7 @@ class _HrvLineChartState extends State<_HrvLineChart> { @@ -626,7 +632,7 @@ class _HrvLineChartState extends State<_HrvLineChart> {
626 ], 632 ],
627 lineTouchData: LineTouchData( 633 lineTouchData: LineTouchData(
628 getTouchLineStart: (barData, spotIndex) => 0, 634 getTouchLineStart: (barData, spotIndex) => 0,
629 - getTouchLineEnd: (barData, spotIndex) => 100, 635 + getTouchLineEnd: (barData, spotIndex) => maxY,
630 handleBuiltInTouches: false, 636 handleBuiltInTouches: false,
631 touchSpotThreshold: 20.0, 637 touchSpotThreshold: 20.0,
632 touchCallback: 638 touchCallback:
@@ -743,7 +749,7 @@ class _StressBarChart extends StatefulWidget { @@ -743,7 +749,7 @@ class _StressBarChart extends StatefulWidget {
743 final VoidCallback onTapPurchase; 749 final VoidCallback onTapPurchase;
744 final double maxSeconds; 750 final double maxSeconds;
745 final Color Function(int?) getColorByState; 751 final Color Function(int?) getColorByState;
746 - final List<TextSpan>? Function(BarChartRodData, int, int?) getTooltip; 752 + final List<TextSpan>? Function(BarChartRodData, int, int?, bool?) getTooltip;
747 final String? Function(double) timeLabel; 753 final String? Function(double) timeLabel;
748 754
749 @override 755 @override
@@ -802,24 +808,26 @@ class _StressBarChartState extends State<_StressBarChart> { @@ -802,24 +808,26 @@ class _StressBarChartState extends State<_StressBarChart> {
802 ..sort((a, b) => a.fromTime.compareTo(b.fromTime)); 808 ..sort((a, b) => a.fromTime.compareTo(b.fromTime));
803 809
804 // 2. 合并相邻且间隔小于 2 小时的睡眠区间,避免因短暂醒来分段导致多个床图标或跨天首尾大面积相连 810 // 2. 合并相邻且间隔小于 2 小时的睡眠区间,避免因短暂醒来分段导致多个床图标或跨天首尾大面积相连
805 - final mergedList = <V2SleepTimeRange>[];  
806 - for (final range in sortedList) {  
807 - if (mergedList.isEmpty) {  
808 - mergedList.add(range);  
809 - } else {  
810 - final lastRange = mergedList.last;  
811 - if (range.fromTime - lastRange.toTime <= 2 * 3600) {  
812 - mergedList[mergedList.length - 1] = V2SleepTimeRange(  
813 - fromTime: lastRange.fromTime,  
814 - toTime: range.toTime > lastRange.toTime  
815 - ? range.toTime  
816 - : lastRange.toTime,  
817 - );  
818 - } else {  
819 - mergedList.add(range);  
820 - }  
821 - }  
822 - } 811 + // final mergedList = <V2SleepTimeRange>[];
  812 + // for (final range in sortedList) {
  813 + // if (mergedList.isEmpty) {
  814 + // mergedList.add(range);
  815 + // } else {
  816 + // final lastRange = mergedList.last;
  817 + // if (range.fromTime - lastRange.toTime <= 2 * 3600) {
  818 + // mergedList[mergedList.length - 1] = V2SleepTimeRange(
  819 + // fromTime: lastRange.fromTime,
  820 + // toTime: range.toTime > lastRange.toTime
  821 + // ? range.toTime
  822 + // : lastRange.toTime,
  823 + // );
  824 + // } else {
  825 + // mergedList.add(range);
  826 + // }
  827 + // }
  828 + // }
  829 + // 2. 不合并睡眠段,直接使用排序后的列表
  830 + final mergedList = sortedList;
823 831
824 // 3. 渲染合并后的睡眠区间 Positioned widgets 832 // 3. 渲染合并后的睡眠区间 Positioned widgets
825 for (final range in mergedList) { 833 for (final range in mergedList) {
@@ -888,7 +896,8 @@ class _StressBarChartState extends State<_StressBarChart> { @@ -888,7 +896,8 @@ class _StressBarChartState extends State<_StressBarChart> {
888 } 896 }
889 897
890 // 槽时间秒 → state 映射 898 // 槽时间秒 → state 映射
891 - final slotStateMap = <int, ({int value, int? state})>{}; 899 + final slotStateMap =
  900 + <int, ({int value, int? state, bool? isWorkout})>{};
892 for (final p in widget.stressPoints) { 901 for (final p in widget.stressPoints) {
893 final sec = 902 final sec =
894 TodayHrvChartCard._tsToSecondsFromMidnight(p.time).round(); 903 TodayHrvChartCard._tsToSecondsFromMidnight(p.time).round();
@@ -896,7 +905,14 @@ class _StressBarChartState extends State<_StressBarChart> { @@ -896,7 +905,14 @@ class _StressBarChartState extends State<_StressBarChart> {
896 final v = p.value ?? 0; 905 final v = p.value ?? 0;
897 final existing = slotStateMap[slot]; 906 final existing = slotStateMap[slot];
898 if (existing == null || v > existing.value) { 907 if (existing == null || v > existing.value) {
899 - slotStateMap[slot] = (value: v, state: p.state); 908 + final isWorkout = (p.isWorkout ?? 0) == 1;
  909 + final isSuspectedActivity = (p.isSuspectedActivity ?? 0) == 1;
  910 + final isMoving = (p.isMoving ?? 0) == 1;
  911 + slotStateMap[slot] = (
  912 + value: v,
  913 + state: p.state,
  914 + isWorkout: (isWorkout || isSuspectedActivity || isMoving)
  915 + );
900 } 916 }
901 } 917 }
902 918
@@ -1116,8 +1132,8 @@ class _StressBarChartState extends State<_StressBarChart> { @@ -1116,8 +1132,8 @@ class _StressBarChartState extends State<_StressBarChart> {
1116 color: Colors.white, 1132 color: Colors.white,
1117 fontWeight: FontWeight.bold, 1133 fontWeight: FontWeight.bold,
1118 ), 1134 ),
1119 - children: widget.getTooltip(  
1120 - group.barRods[0], group.x, state), 1135 + children: widget.getTooltip(group.barRods[0], group.x,
  1136 + state, entry.isWorkout),
1121 textAlign: TextAlign.start, 1137 textAlign: TextAlign.start,
1122 ); 1138 );
1123 }, 1139 },
@@ -173,7 +173,7 @@ class LoginView extends GetView<LoginController> { @@ -173,7 +173,7 @@ class LoginView extends GetView<LoginController> {
173 ), 173 ),
174 // Terms agreement text + checkbox 174 // Terms agreement text + checkbox
175 Positioned( 175 Positioned(
176 - bottom: bottom(25), 176 + bottom: bottom(0),
177 left: 0, 177 left: 0,
178 right: 0, 178 right: 0,
179 child: const _AgreementText(), 179 child: const _AgreementText(),
@@ -300,8 +300,10 @@ class _AgreementText extends GetView<LoginController> { @@ -300,8 +300,10 @@ class _AgreementText extends GetView<LoginController> {
300 return GestureDetector( 300 return GestureDetector(
301 onTap: controller.toggleTermsChecked, 301 onTap: controller.toggleTermsChecked,
302 behavior: HitTestBehavior.opaque, 302 behavior: HitTestBehavior.opaque,
303 - child: Padding(  
304 - padding: const EdgeInsets.fromLTRB(24.0, 20, 24.0, 15), 303 + child: Container(
  304 + height: 85,
  305 + alignment: Alignment(0.0, -0.25),
  306 + padding: EdgeInsets.symmetric(horizontal: 24),
305 child: Text.rich( 307 child: Text.rich(
306 TextSpan( 308 TextSpan(
307 style: baseStyle, 309 style: baseStyle,
@@ -321,17 +321,32 @@ class V2HrvTrendData { @@ -321,17 +321,32 @@ class V2HrvTrendData {
321 321
322 /// Single item in v2/realtime_stress/ list 322 /// Single item in v2/realtime_stress/ list
323 class V2RealtimeStressItem { 323 class V2RealtimeStressItem {
324 - const V2RealtimeStressItem({this.time, this.value, this.state}); 324 + const V2RealtimeStressItem(
  325 + {this.time,
  326 + this.value,
  327 + this.state,
  328 + this.isWorkout,
  329 + this.isSuspectedActivity,
  330 + this.isMoving,
  331 + this.isAsleep});
325 332
326 final int? time; 333 final int? time;
327 final int? value; 334 final int? value;
328 final int? state; 335 final int? state;
  336 + final int? isWorkout;
  337 + final int? isSuspectedActivity;
  338 + final int? isMoving;
  339 + final int? isAsleep;
329 340
330 factory V2RealtimeStressItem.fromJson(Map<String, dynamic> json) { 341 factory V2RealtimeStressItem.fromJson(Map<String, dynamic> json) {
331 return V2RealtimeStressItem( 342 return V2RealtimeStressItem(
332 time: _parseInt(json['time']), 343 time: _parseInt(json['time']),
333 value: _parseInt(json['value']), 344 value: _parseInt(json['value']),
334 state: _parseInt(json['state']), 345 state: _parseInt(json['state']),
  346 + isWorkout: _parseInt(json['is_workout']),
  347 + isSuspectedActivity: _parseInt(json['is_suspected_activity']),
  348 + isMoving: _parseInt(json['is_moving']),
  349 + isAsleep: _parseInt(json['is_asleep']),
335 ); 350 );
336 } 351 }
337 352
@@ -340,6 +355,11 @@ class V2RealtimeStressItem { @@ -340,6 +355,11 @@ class V2RealtimeStressItem {
340 if (time != null) val['time'] = time; 355 if (time != null) val['time'] = time;
341 if (value != null) val['value'] = value; 356 if (value != null) val['value'] = value;
342 if (state != null) val['state'] = state; 357 if (state != null) val['state'] = state;
  358 + if (isWorkout != null) val['is_workout'] = isWorkout;
  359 + if (isSuspectedActivity != null)
  360 + val['is_suspected_activity'] = isSuspectedActivity;
  361 + if (isMoving != null) val['is_moving'] = isMoving;
  362 + if (isAsleep != null) val['is_asleep'] = isAsleep;
343 return val; 363 return val;
344 } 364 }
345 } 365 }
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 "switchLanguage": "Switch Language", 21 "switchLanguage": "Switch Language",
22 "settings": "Settings", 22 "settings": "Settings",
23 "onboardingIntroTitle": "DoubleFeel is a health companion app built for Apple Watch", 23 "onboardingIntroTitle": "DoubleFeel is a health companion app built for Apple Watch",
24 - "onboardingIntroBody": "We hope to help you\n<em>notice changes in your mind and body, and help the people who love you</em> see when you are <em>tired or need support</em>", 24 + "onboardingIntroBody": "<em>Understand yourself better</em>, and let people who care about you <em>notice when you need support.</em>",
25 "onboardingStateQuestion": "Which of these often happens to you?", 25 "onboardingStateQuestion": "Which of these often happens to you?",
26 "onboardingStateStressAnxiety": "I often feel stressed or anxious", 26 "onboardingStateStressAnxiety": "I often feel stressed or anxious",
27 "onboardingStateTired": "I get tired easily", 27 "onboardingStateTired": "I get tired easily",
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 "onboardingReliefSun": "More sunlight", 41 "onboardingReliefSun": "More sunlight",
42 "onboardingReliefWater": "Drink more water", 42 "onboardingReliefWater": "Drink more water",
43 "onboardingReliefMeditation": "Mindfulness meditation", 43 "onboardingReliefMeditation": "Mindfulness meditation",
44 - "onboardingKeyDataTitle": "Did you know?", 44 + "onboardingKeyDataTitle": "",
45 "onboardingKeyDataSubtitle": "Everyone has a magical and important body metric that can help us:", 45 "onboardingKeyDataSubtitle": "Everyone has a magical and important body metric that can help us:",
46 "onboardingKeyDataStress": "Monitor stress", 46 "onboardingKeyDataStress": "Monitor stress",
47 "onboardingKeyDataFatigue": "Avoid overwork and physical fatigue", 47 "onboardingKeyDataFatigue": "Avoid overwork and physical fatigue",
@@ -53,7 +53,7 @@ @@ -53,7 +53,7 @@
53 "onboardingHrvSubtitle": "It helps us measure overall stress and health", 53 "onboardingHrvSubtitle": "It helps us measure overall stress and health",
54 "onboardingHrvDescription": "Heart rate variability (HRV) is the tiny variation in time between heartbeats. It reflects autonomic nervous system activity and how the body responds to stress.", 54 "onboardingHrvDescription": "Heart rate variability (HRV) is the tiny variation in time between heartbeats. It reflects autonomic nervous system activity and how the body responds to stress.",
55 "onboardingTellMeMore": "Tell me more", 55 "onboardingTellMeMore": "Tell me more",
56 - "onboardingResearchTitle": "Many studies show that HRV changes are closely related to how our body and mind feel", 56 + "onboardingResearchTitle": "Research shows HRV is closely linked to how your body feels",
57 "onboardingResearchFatigue": "Physical fatigue", 57 "onboardingResearchFatigue": "Physical fatigue",
58 "onboardingResearchEnergy": "Full of energy", 58 "onboardingResearchEnergy": "Full of energy",
59 "onboardingResearchHrvDown": "HRV down", 59 "onboardingResearchHrvDown": "HRV down",
@@ -62,10 +62,10 @@ @@ -62,10 +62,10 @@
62 "onboardingHealthPermissionBody": "DoubleFeel needs connected wearable health data to send reminders, count stress moments, and provide suggestions.", 62 "onboardingHealthPermissionBody": "DoubleFeel needs connected wearable health data to send reminders, count stress moments, and provide suggestions.",
63 "onboardingHealthPermissionPrivacy": "Your health data is stored locally. We do not upload any related data.", 63 "onboardingHealthPermissionPrivacy": "Your health data is stored locally. We do not upload any related data.",
64 "onboardingNotificationTitle": "Turn on notifications", 64 "onboardingNotificationTitle": "Turn on notifications",
65 - "onboardingNotificationSubtitle": "Learn about every body change in time",  
66 - "onboardingNotificationBody": "After Apple Watch data updates, we can remind you in time and help you act to improve your stress state.",  
67 - "onboardingMemberTitle": "Get an annual membership offer",  
68 - "onboardingMemberBody": "Start your pressure alert and health companion journey, so love and care are always present.", 65 + "onboardingNotificationSubtitle": "",
  66 + "onboardingNotificationBody": "Get notified when your body shows unusual stress or fatigue signals.",
  67 + "onboardingMemberTitle": "Get Annual Membership Offer",
  68 + "onboardingMemberBody": "Start your stress tracking and wellness journey, and never miss caring moments.",
69 "onboardingMemberAllOptions": "View all purchase options", 69 "onboardingMemberAllOptions": "View all purchase options",
70 "healthCompanionIsNowAvailable": "Health Companion is now available", 70 "healthCompanionIsNowAvailable": "Health Companion is now available",
71 "youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired": "You can now view each other's HRV, stress levels, and sleep patterns, and reach out to check in when the other person seems tired.", 71 "youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired": "You can now view each other's HRV, stress levels, and sleep patterns, and reach out to check in when the other person seems tired.",
@@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
82 "onboardingResearchHealthy": "Feeling Great", 82 "onboardingResearchHealthy": "Feeling Great",
83 "onboardingResearchPoorSleep": "Poor Sleep", 83 "onboardingResearchPoorSleep": "Poor Sleep",
84 "onboardingResearchGoodSleep": "Good Sleep", 84 "onboardingResearchGoodSleep": "Good Sleep",
85 - "loginSlogan": "Start your pressure alert and health companion journey\nso love and care are always present", 85 + "loginSlogan": "Start your journey of stress insights and caring connection.",
86 "loginWithPhone": "Sign in with Phone", 86 "loginWithPhone": "Sign in with Phone",
87 "loginWithApple": "Sign in with Apple", 87 "loginWithApple": "Sign in with Apple",
88 "loginLastUsed": "Last used", 88 "loginLastUsed": "Last used",
@@ -696,5 +696,6 @@ @@ -696,5 +696,6 @@
696 "feedbackInvalidEmail": "Invalid email format, please enter again", 696 "feedbackInvalidEmail": "Invalid email format, please enter again",
697 "feedbackSubmitSuccessTitle": "Feedback submitted successfully", 697 "feedbackSubmitSuccessTitle": "Feedback submitted successfully",
698 "feedbackSubmitSuccessMessage": "Thank you for your feedback. If further communication is needed, we will contact you via the email address you left as soon as possible. Please keep an eye on your inbox.", 698 "feedbackSubmitSuccessMessage": "Thank you for your feedback. If further communication is needed, we will contact you via the email address you left as soon as possible. Please keep an eye on your inbox.",
699 - "feedbackSubmitSuccessConfirm": "OK"  
700 -} 699 + "feedbackSubmitSuccessConfirm": "OK",
  700 + "frequentMovement": "Frequent movement"
  701 +}
@@ -1075,5 +1075,6 @@ @@ -1075,5 +1075,6 @@
1075 "feedbackInvalidEmail": "邮箱格式错误,请重新输入", 1075 "feedbackInvalidEmail": "邮箱格式错误,请重新输入",
1076 "feedbackSubmitSuccessTitle": "反馈提交成功", 1076 "feedbackSubmitSuccessTitle": "反馈提交成功",
1077 "feedbackSubmitSuccessMessage": "谢谢您的反馈。如需进一步沟通,我们会尽快通过您留下的邮箱地址与您联系,请留意查收邮件。", 1077 "feedbackSubmitSuccessMessage": "谢谢您的反馈。如需进一步沟通,我们会尽快通过您留下的邮箱地址与您联系,请留意查收邮件。",
1078 - "feedbackSubmitSuccessConfirm": "好的"  
1079 -} 1078 + "feedbackSubmitSuccessConfirm": "好的",
  1079 + "frequentMovement": "频繁移动"
  1080 +}
@@ -3998,6 +3998,12 @@ abstract class AppLocalizations { @@ -3998,6 +3998,12 @@ abstract class AppLocalizations {
3998 /// In zh, this message translates to: 3998 /// In zh, this message translates to:
3999 /// **'好的'** 3999 /// **'好的'**
4000 String get feedbackSubmitSuccessConfirm; 4000 String get feedbackSubmitSuccessConfirm;
  4001 +
  4002 + /// No description provided for @frequentMovement.
  4003 + ///
  4004 + /// In zh, this message translates to:
  4005 + /// **'频繁移动'**
  4006 + String get frequentMovement;
4001 } 4007 }
4002 4008
4003 class _AppLocalizationsDelegate 4009 class _AppLocalizationsDelegate
@@ -74,7 +74,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -74,7 +74,7 @@ class AppLocalizationsEn extends AppLocalizations {
74 74
75 @override 75 @override
76 String get onboardingIntroBody => 76 String get onboardingIntroBody =>
77 - 'We hope to help you\n<em>notice changes in your mind and body, and help the people who love you</em> see when you are <em>tired or need support</em>'; 77 + '<em>Understand yourself better</em>, and let people who care about you <em>notice when you need support.</em>';
78 78
79 @override 79 @override
80 String get onboardingStateQuestion => 'Which of these often happens to you?'; 80 String get onboardingStateQuestion => 'Which of these often happens to you?';
@@ -139,7 +139,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -139,7 +139,7 @@ class AppLocalizationsEn extends AppLocalizations {
139 String get onboardingReliefMeditation => 'Mindfulness meditation'; 139 String get onboardingReliefMeditation => 'Mindfulness meditation';
140 140
141 @override 141 @override
142 - String get onboardingKeyDataTitle => 'Did you know?'; 142 + String get onboardingKeyDataTitle => '';
143 143
144 @override 144 @override
145 String get onboardingKeyDataSubtitle => 145 String get onboardingKeyDataSubtitle =>
@@ -180,7 +180,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -180,7 +180,7 @@ class AppLocalizationsEn extends AppLocalizations {
180 180
181 @override 181 @override
182 String get onboardingResearchTitle => 182 String get onboardingResearchTitle =>
183 - 'Many studies show that HRV changes are closely related to how our body and mind feel'; 183 + 'Research shows HRV is closely linked to how your body feels';
184 184
185 @override 185 @override
186 String get onboardingResearchFatigue => 'Physical fatigue'; 186 String get onboardingResearchFatigue => 'Physical fatigue';
@@ -209,19 +209,18 @@ class AppLocalizationsEn extends AppLocalizations { @@ -209,19 +209,18 @@ class AppLocalizationsEn extends AppLocalizations {
209 String get onboardingNotificationTitle => 'Turn on notifications'; 209 String get onboardingNotificationTitle => 'Turn on notifications';
210 210
211 @override 211 @override
212 - String get onboardingNotificationSubtitle =>  
213 - 'Learn about every body change in time'; 212 + String get onboardingNotificationSubtitle => '';
214 213
215 @override 214 @override
216 String get onboardingNotificationBody => 215 String get onboardingNotificationBody =>
217 - 'After Apple Watch data updates, we can remind you in time and help you act to improve your stress state.'; 216 + 'Get notified when your body shows unusual stress or fatigue signals.';
218 217
219 @override 218 @override
220 - String get onboardingMemberTitle => 'Get an annual membership offer'; 219 + String get onboardingMemberTitle => 'Get Annual Membership Offer';
221 220
222 @override 221 @override
223 String get onboardingMemberBody => 222 String get onboardingMemberBody =>
224 - 'Start your pressure alert and health companion journey, so love and care are always present.'; 223 + 'Start your stress tracking and wellness journey, and never miss caring moments.';
225 224
226 @override 225 @override
227 String get onboardingMemberAllOptions => 'View all purchase options'; 226 String get onboardingMemberAllOptions => 'View all purchase options';
@@ -276,7 +275,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -276,7 +275,7 @@ class AppLocalizationsEn extends AppLocalizations {
276 275
277 @override 276 @override
278 String get loginSlogan => 277 String get loginSlogan =>
279 - 'Start your pressure alert and health companion journey\nso love and care are always present'; 278 + 'Start your journey of stress insights and caring connection.';
280 279
281 @override 280 @override
282 String get loginWithPhone => 'Sign in with Phone'; 281 String get loginWithPhone => 'Sign in with Phone';
@@ -2240,4 +2239,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -2240,4 +2239,7 @@ class AppLocalizationsEn extends AppLocalizations {
2240 2239
2241 @override 2240 @override
2242 String get feedbackSubmitSuccessConfirm => 'OK'; 2241 String get feedbackSubmitSuccessConfirm => 'OK';
  2242 +
  2243 + @override
  2244 + String get frequentMovement => 'Frequent movement';
2243 } 2245 }
@@ -2130,4 +2130,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -2130,4 +2130,7 @@ class AppLocalizationsZh extends AppLocalizations {
2130 2130
2131 @override 2131 @override
2132 String get feedbackSubmitSuccessConfirm => '好的'; 2132 String get feedbackSubmitSuccessConfirm => '好的';
  2133 +
  2134 + @override
  2135 + String get frequentMovement => '频繁移动';
2133 } 2136 }