Showing
10 changed files
with
117 additions
and
66 deletions
| @@ -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 | } |
-
Please register or login to post a comment