Commit 3b1ac09f8cf23e217f24a9cc405a9198a8ec4550

Authored by 权海
1 parent f692e513

feat(ui):接入主题接口, runner现在可以直接跑起来了

@@ -29,21 +29,14 @@ flutter_ios_podfile_setup @@ -29,21 +29,14 @@ flutter_ios_podfile_setup
29 target 'Runner' do 29 target 'Runner' do
30 use_frameworks! 30 use_frameworks!
31 31
32 -# pod 'SDWebImage'  
33 -# pod 'ThinkingSDK'  
34 -  
35 flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
36 -  
37 end 33 end
38 34
39 -target 'Runner Watch App' do  
40 - platform :watchos, '10.0'  
41 - use_frameworks! 35 +#target 'Runner Watch App' do
  36 +# platform :watchos, '10.0'
  37 +# use_frameworks!
42 38
43 -# pod 'SDWebImage'  
44 -# pod 'SDWebImageSwiftUI'  
45 -# pod 'ThinkingDataAnalyticsExtension'  
46 -end 39 +#end
47 40
48 41
49 post_install do |installer| 42 post_install do |installer|
@@ -64,7 +64,7 @@ EXTERNAL SOURCES: @@ -64,7 +64,7 @@ EXTERNAL SOURCES:
64 :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" 64 :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
65 65
66 SPEC CHECKSUMS: 66 SPEC CHECKSUMS:
67 - Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 67 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
68 fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1 68 fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
69 image_cropper: c4326ea50132b1e1564499e5d32a84f01fb03537 69 image_cropper: c4326ea50132b1e1564499e5d32a84f01fb03537
70 image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a 70 image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
@@ -76,6 +76,6 @@ SPEC CHECKSUMS: @@ -76,6 +76,6 @@ SPEC CHECKSUMS:
76 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 76 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
77 webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2 77 webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
78 78
79 -PODFILE CHECKSUM: 0c5ef213fb4730cd4252ac64735589552e4ee974 79 +PODFILE CHECKSUM: b9265b4a06e32777ce541c63a22ad629b9ccc6ae
80 80
81 COCOAPODS: 1.16.2 81 COCOAPODS: 1.16.2
@@ -11,8 +11,6 @@ @@ -11,8 +11,6 @@
11 661A0D342FE2AB340026EEBB /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */; }; 11 661A0D342FE2AB340026EEBB /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */; };
12 661A0D352FE2AB340026EEBB /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */; }; 12 661A0D352FE2AB340026EEBB /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */; };
13 661A0D402FE2AB360026EEBB /* hippo-watch-extensionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 661A0D332FE2AB340026EEBB /* hippo-watch-extensionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 13 661A0D402FE2AB360026EEBB /* hippo-watch-extensionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 661A0D332FE2AB340026EEBB /* hippo-watch-extensionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
14 - 66FBE58C2FDA4F0F00F515B4 /* Runner Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 66FBE58B2FDA4F0F00F515B4 /* Runner Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };  
15 - D0E7FB41C5122A32579199E1 /* Pods_Runner_Watch_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */; };  
16 /* End PBXBuildFile section */ 14 /* End PBXBuildFile section */
17 15
18 /* Begin PBXContainerItemProxy section */ 16 /* Begin PBXContainerItemProxy section */
@@ -23,27 +21,9 @@ @@ -23,27 +21,9 @@
23 remoteGlobalIDString = 661A0D322FE2AB340026EEBB; 21 remoteGlobalIDString = 661A0D322FE2AB340026EEBB;
24 remoteInfo = "hippo-watch-extensionExtension"; 22 remoteInfo = "hippo-watch-extensionExtension";
25 }; 23 };
26 - 66569B6E2FE27D0400B7E33C /* PBXContainerItemProxy */ = {  
27 - isa = PBXContainerItemProxy;  
28 - containerPortal = 66FBE5762FDA4F0E00F515B4 /* Project object */;  
29 - proxyType = 1;  
30 - remoteGlobalIDString = 66FBE58A2FDA4F0F00F515B4;  
31 - remoteInfo = "Runner Watch App";  
32 - };  
33 /* End PBXContainerItemProxy section */ 24 /* End PBXContainerItemProxy section */
34 25
35 /* Begin PBXCopyFilesBuildPhase section */ 26 /* Begin PBXCopyFilesBuildPhase section */
36 - 66FBE59B2FDA4F1000F515B4 /* Embed Watch Content */ = {  
37 - isa = PBXCopyFilesBuildPhase;  
38 - buildActionMask = 2147483647;  
39 - dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";  
40 - dstSubfolderSpec = 16;  
41 - files = (  
42 - 66FBE58C2FDA4F0F00F515B4 /* Runner Watch App.app in Embed Watch Content */,  
43 - );  
44 - name = "Embed Watch Content";  
45 - runOnlyForDeploymentPostprocessing = 0;  
46 - };  
47 66FBE5BE2FDA518D00F515B4 /* Embed Foundation Extensions */ = { 27 66FBE5BE2FDA518D00F515B4 /* Embed Foundation Extensions */ = {
48 isa = PBXCopyFilesBuildPhase; 28 isa = PBXCopyFilesBuildPhase;
49 buildActionMask = 2147483647; 29 buildActionMask = 2147483647;
@@ -58,12 +38,9 @@ @@ -58,12 +38,9 @@
58 /* End PBXCopyFilesBuildPhase section */ 38 /* End PBXCopyFilesBuildPhase section */
59 39
60 /* Begin PBXFileReference section */ 40 /* Begin PBXFileReference section */
61 - 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.release.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.release.xcconfig"; sourceTree = "<group>"; };  
62 - 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_Watch_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };  
63 4A9B7C102FDB0A1200F515B4 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; 41 4A9B7C102FDB0A1200F515B4 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
64 4A9B7C112FDB0A1200F515B4 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; 42 4A9B7C112FDB0A1200F515B4 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
65 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
66 - 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.debug.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.debug.xcconfig"; sourceTree = "<group>"; };  
67 661A0D332FE2AB340026EEBB /* hippo-watch-extensionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "hippo-watch-extensionExtension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 661A0D332FE2AB340026EEBB /* hippo-watch-extensionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "hippo-watch-extensionExtension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
68 66FBE57E2FDA4F0E00F515B4 /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 66FBE57E2FDA4F0E00F515B4 /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
69 66FBE58B2FDA4F0F00F515B4 /* Runner Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runner Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 66FBE58B2FDA4F0F00F515B4 /* Runner Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runner Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -162,7 +139,6 @@ @@ -162,7 +139,6 @@
162 isa = PBXFrameworksBuildPhase; 139 isa = PBXFrameworksBuildPhase;
163 buildActionMask = 2147483647; 140 buildActionMask = 2147483647;
164 files = ( 141 files = (
165 - D0E7FB41C5122A32579199E1 /* Pods_Runner_Watch_App.framework in Frameworks */,  
166 ); 142 );
167 runOnlyForDeploymentPostprocessing = 0; 143 runOnlyForDeploymentPostprocessing = 0;
168 }; 144 };
@@ -208,7 +184,6 @@ @@ -208,7 +184,6 @@
208 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */, 184 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */,
209 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */, 185 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */,
210 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */, 186 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */,
211 - 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */,  
212 ); 187 );
213 name = Frameworks; 188 name = Frameworks;
214 sourceTree = "<group>"; 189 sourceTree = "<group>";
@@ -218,8 +193,6 @@ @@ -218,8 +193,6 @@
218 children = ( 193 children = (
219 9D4354F0FB273F6846CD38C3 /* Pods-Runner.debug.xcconfig */, 194 9D4354F0FB273F6846CD38C3 /* Pods-Runner.debug.xcconfig */,
220 7845C91D0615F45450905891 /* Pods-Runner.release.xcconfig */, 195 7845C91D0615F45450905891 /* Pods-Runner.release.xcconfig */,
221 - 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */,  
222 - 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */,  
223 ); 196 );
224 path = Pods; 197 path = Pods;
225 sourceTree = "<group>"; 198 sourceTree = "<group>";
@@ -255,7 +228,6 @@ @@ -255,7 +228,6 @@
255 66FBE57A2FDA4F0E00F515B4 /* Sources */, 228 66FBE57A2FDA4F0E00F515B4 /* Sources */,
256 66FBE57B2FDA4F0E00F515B4 /* Frameworks */, 229 66FBE57B2FDA4F0E00F515B4 /* Frameworks */,
257 66FBE57C2FDA4F0E00F515B4 /* Resources */, 230 66FBE57C2FDA4F0E00F515B4 /* Resources */,
258 - 66FBE59B2FDA4F1000F515B4 /* Embed Watch Content */,  
259 66FB07192FDAA64500F515B4 /* ShellScript */, 231 66FB07192FDAA64500F515B4 /* ShellScript */,
260 66FB071A2FDAA65C00F515B4 /* Thin Binary */, 232 66FB071A2FDAA65C00F515B4 /* Thin Binary */,
261 4348DC7B38CB739C4ABA7DAC /* [CP] Embed Pods Frameworks */, 233 4348DC7B38CB739C4ABA7DAC /* [CP] Embed Pods Frameworks */,
@@ -264,7 +236,6 @@ @@ -264,7 +236,6 @@
264 buildRules = ( 236 buildRules = (
265 ); 237 );
266 dependencies = ( 238 dependencies = (
267 - 66569B6F2FE27D0400B7E33C /* PBXTargetDependency */,  
268 ); 239 );
269 fileSystemSynchronizedGroups = ( 240 fileSystemSynchronizedGroups = (
270 66FBE5802FDA4F0E00F515B4 /* Runner */, 241 66FBE5802FDA4F0E00F515B4 /* Runner */,
@@ -278,7 +249,6 @@ @@ -278,7 +249,6 @@
278 isa = PBXNativeTarget; 249 isa = PBXNativeTarget;
279 buildConfigurationList = 66FBE5982FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner Watch App" */; 250 buildConfigurationList = 66FBE5982FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner Watch App" */;
280 buildPhases = ( 251 buildPhases = (
281 - BA66C644AE443BFC9EB5FA40 /* [CP] Check Pods Manifest.lock */,  
282 66FBE5872FDA4F0F00F515B4 /* Sources */, 252 66FBE5872FDA4F0F00F515B4 /* Sources */,
283 66FBE5882FDA4F0F00F515B4 /* Frameworks */, 253 66FBE5882FDA4F0F00F515B4 /* Frameworks */,
284 66FBE5892FDA4F0F00F515B4 /* Resources */, 254 66FBE5892FDA4F0F00F515B4 /* Resources */,
@@ -438,28 +408,6 @@ @@ -438,28 +408,6 @@
438 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 408 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
439 showEnvVarsInLog = 0; 409 showEnvVarsInLog = 0;
440 }; 410 };
441 - BA66C644AE443BFC9EB5FA40 /* [CP] Check Pods Manifest.lock */ = {  
442 - isa = PBXShellScriptBuildPhase;  
443 - buildActionMask = 2147483647;  
444 - files = (  
445 - );  
446 - inputFileListPaths = (  
447 - );  
448 - inputPaths = (  
449 - "${PODS_PODFILE_DIR_PATH}/Podfile.lock",  
450 - "${PODS_ROOT}/Manifest.lock",  
451 - );  
452 - name = "[CP] Check Pods Manifest.lock";  
453 - outputFileListPaths = (  
454 - );  
455 - outputPaths = (  
456 - "$(DERIVED_FILE_DIR)/Pods-Runner Watch App-checkManifestLockResult.txt",  
457 - );  
458 - runOnlyForDeploymentPostprocessing = 0;  
459 - shellPath = /bin/sh;  
460 - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";  
461 - showEnvVarsInLog = 0;  
462 - };  
463 E68ABE0C79927AE95370205A /* [CP] Copy Pods Resources */ = { 411 E68ABE0C79927AE95370205A /* [CP] Copy Pods Resources */ = {
464 isa = PBXShellScriptBuildPhase; 412 isa = PBXShellScriptBuildPhase;
465 buildActionMask = 2147483647; 413 buildActionMask = 2147483647;
@@ -509,11 +457,6 @@ @@ -509,11 +457,6 @@
509 target = 661A0D322FE2AB340026EEBB /* hippo-watch-extensionExtension */; 457 target = 661A0D322FE2AB340026EEBB /* hippo-watch-extensionExtension */;
510 targetProxy = 661A0D3E2FE2AB360026EEBB /* PBXContainerItemProxy */; 458 targetProxy = 661A0D3E2FE2AB360026EEBB /* PBXContainerItemProxy */;
511 }; 459 };
512 - 66569B6F2FE27D0400B7E33C /* PBXTargetDependency */ = {  
513 - isa = PBXTargetDependency;  
514 - target = 66FBE58A2FDA4F0F00F515B4 /* Runner Watch App */;  
515 - targetProxy = 66569B6E2FE27D0400B7E33C /* PBXContainerItemProxy */;  
516 - };  
517 /* End PBXTargetDependency section */ 460 /* End PBXTargetDependency section */
518 461
519 /* Begin XCBuildConfiguration section */ 462 /* Begin XCBuildConfiguration section */
@@ -704,7 +647,6 @@ @@ -704,7 +647,6 @@
704 }; 647 };
705 66FBE5992FDA4F1000F515B4 /* Debug */ = { 648 66FBE5992FDA4F1000F515B4 /* Debug */ = {
706 isa = XCBuildConfiguration; 649 isa = XCBuildConfiguration;
707 - baseConfigurationReference = 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */;  
708 buildSettings = { 650 buildSettings = {
709 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 651 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
710 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 652 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -743,7 +685,6 @@ @@ -743,7 +685,6 @@
743 }; 685 };
744 66FBE59A2FDA4F1000F515B4 /* Release */ = { 686 66FBE59A2FDA4F1000F515B4 /* Release */ = {
745 isa = XCBuildConfiguration; 687 isa = XCBuildConfiguration;
746 - baseConfigurationReference = 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */;  
747 buildSettings = { 688 buildSettings = {
748 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 689 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
749 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 690 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -2,6 +2,7 @@ import 'package:doublefeel_flutter/app/apple_health_upload/apple_health_upload_t @@ -2,6 +2,7 @@ import 'package:doublefeel_flutter/app/apple_health_upload/apple_health_upload_t
2 import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart'; 2 import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart';
3 import 'package:doublefeel_flutter/core/network/api/friend_api.dart'; 3 import 'package:doublefeel_flutter/core/network/api/friend_api.dart';
4 import 'package:doublefeel_flutter/core/network/api/health_api.dart'; 4 import 'package:doublefeel_flutter/core/network/api/health_api.dart';
  5 +import 'package:doublefeel_flutter/core/network/api/theme_api.dart';
5 import 'package:doublefeel_flutter/core/network/api/user_api.dart'; 6 import 'package:doublefeel_flutter/core/network/api/user_api.dart';
6 import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; 7 import 'package:doublefeel_flutter/core/network/api/vip_api.dart';
7 import 'package:doublefeel_flutter/core/services/health_kit_upload_service.dart'; 8 import 'package:doublefeel_flutter/core/services/health_kit_upload_service.dart';
@@ -29,7 +30,8 @@ class HomeBinding extends Bindings { @@ -29,7 +30,8 @@ class HomeBinding extends Bindings {
29 fenix: true, 30 fenix: true,
30 ); 31 );
31 Get.lazyPut<MyController>( 32 Get.lazyPut<MyController>(
32 - () => MyController(Get.find<UserApi>(), Get.find<VipApi>()), 33 + () => MyController(
  34 + Get.find<UserApi>(), Get.find<VipApi>(), Get.find<ThemeApi>()),
33 fenix: true, 35 fenix: true,
34 ); 36 );
35 Get.lazyPut<TrendController>(() => TrendController(), fenix: true); 37 Get.lazyPut<TrendController>(() => TrendController(), fenix: true);
  1 +import 'dart:async';
  2 +
  3 +import 'package:doublefeel_flutter/app/modules/watch_theme/models/watch_theme_models.dart';
1 import 'package:doublefeel_flutter/app/routes/app_pages.dart'; 4 import 'package:doublefeel_flutter/app/routes/app_pages.dart';
  5 +import 'package:doublefeel_flutter/core/network/api/theme_api.dart';
2 import 'package:doublefeel_flutter/core/network/api/user_api.dart'; 6 import 'package:doublefeel_flutter/core/network/api/user_api.dart';
3 import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; 7 import 'package:doublefeel_flutter/core/network/api/vip_api.dart';
4 import 'package:doublefeel_flutter/core/result/app_result.dart'; 8 import 'package:doublefeel_flutter/core/result/app_result.dart';
@@ -9,11 +13,32 @@ import 'package:get/get.dart'; @@ -9,11 +13,32 @@ import 'package:get/get.dart';
9 import 'package:image_picker/image_picker.dart'; 13 import 'package:image_picker/image_picker.dart';
10 14
11 class MyController extends GetxController { 15 class MyController extends GetxController {
12 - MyController(this._userApi, this._vipApi); 16 + MyController(this._userApi, this._vipApi, this._themeApi);
13 17
14 final UserApi _userApi; 18 final UserApi _userApi;
15 final VipApi _vipApi; 19 final VipApi _vipApi;
  20 + final ThemeApi _themeApi;
16 final ImagePicker _picker = ImagePicker(); 21 final ImagePicker _picker = ImagePicker();
  22 + final watchThemeItems = <WatchThemeItem>[].obs;
  23 + final isLoadingWatchThemes = false.obs;
  24 +
  25 + List<WatchThemeItem> get officialWatchThemes =>
  26 + watchThemeItems.where((theme) => theme.isOfficialTheme).toList();
  27 +
  28 + @override
  29 + void onInit() {
  30 + super.onInit();
  31 + unawaited(loadWatchThemes());
  32 + }
  33 +
  34 + Future<void> loadWatchThemes() async {
  35 + isLoadingWatchThemes.value = true;
  36 + final result = await _themeApi.getThemeList(errorHandlingPolicy: null);
  37 + isLoadingWatchThemes.value = false;
  38 + if (result case AppSuccess<WatchThemeResponse>(data: final response)) {
  39 + watchThemeItems.assignAll(response.themes);
  40 + }
  41 + }
17 42
18 void updateNickname(String nickname) async { 43 void updateNickname(String nickname) async {
19 final result = await _userApi.updateOwnerUserInfo(nickname: nickname); 44 final result = await _userApi.updateOwnerUserInfo(nickname: nickname);
@@ -34,11 +59,16 @@ class MyController extends GetxController { @@ -34,11 +59,16 @@ class MyController extends GetxController {
34 } 59 }
35 } 60 }
36 61
37 - void goWatchThemePage() {  
38 - Get.toNamed( 62 + Future<void> goWatchThemePage() async {
  63 + final hasCustomThemes = watchThemeItems.any((theme) => theme.isCustomTheme);
  64 + await Get.toNamed(
39 Routes.WATCH_THEME, 65 Routes.WATCH_THEME,
40 - arguments: {'isPremium': false, 'hasCustomThemes': false}, 66 + arguments: {
  67 + 'isPremium': hasCustomThemes,
  68 + 'hasCustomThemes': hasCustomThemes,
  69 + },
41 ); 70 );
  71 + await loadWatchThemes();
42 } 72 }
43 73
44 void testAppleHealthUpload() { 74 void testAppleHealthUpload() {
@@ -53,6 +53,8 @@ class MyTab extends GetView<MyController> { @@ -53,6 +53,8 @@ class MyTab extends GetView<MyController> {
53 : const _UnlockPremiumCard(), 53 : const _UnlockPremiumCard(),
54 const SizedBox(height: 12), 54 const SizedBox(height: 12),
55 _WatchThemeCard( 55 _WatchThemeCard(
  56 + themes: controller.officialWatchThemes,
  57 + isLoading: controller.isLoadingWatchThemes.value,
56 onTap: () => controller.goWatchThemePage(), 58 onTap: () => controller.goWatchThemePage(),
57 ), 59 ),
58 const SizedBox(height: 12), 60 const SizedBox(height: 12),
@@ -459,8 +461,14 @@ class _ProCard extends StatelessWidget { @@ -459,8 +461,14 @@ class _ProCard extends StatelessWidget {
459 // } 461 // }
460 462
461 class _WatchThemeCard extends StatelessWidget { 463 class _WatchThemeCard extends StatelessWidget {
462 - const _WatchThemeCard({required this.onTap}); 464 + const _WatchThemeCard({
  465 + required this.themes,
  466 + required this.isLoading,
  467 + required this.onTap,
  468 + });
463 469
  470 + final List<WatchThemeItem> themes;
  471 + final bool isLoading;
464 final VoidCallback onTap; 472 final VoidCallback onTap;
465 473
466 final double _itemSize = 64; 474 final double _itemSize = 64;
@@ -502,23 +510,27 @@ class _WatchThemeCard extends StatelessWidget { @@ -502,23 +510,27 @@ class _WatchThemeCard extends StatelessWidget {
502 SizedBox(height: 17.dp), 510 SizedBox(height: 17.dp),
503 SizedBox( 511 SizedBox(
504 height: _itemSize, 512 height: _itemSize,
505 - child: ListView.builder(  
506 - scrollDirection: Axis.horizontal,  
507 - clipBehavior: Clip.none,  
508 - itemCount: officialThemes.length,  
509 - itemBuilder: (context, index) {  
510 - return Transform.translate(  
511 - offset: Offset(index == 0 ? 0 : -_overlap * index, 0),  
512 - child: _ThemeBubble(  
513 - size: _itemSize,  
514 - assetPath: officialThemes[index]  
515 - .infoList  
516 - .firstOrNull  
517 - ?.assetPath ??  
518 - '',  
519 - ));  
520 - },  
521 - ), 513 + child: isLoading && themes.isEmpty
  514 + ? const Align(
  515 + alignment: Alignment.centerLeft,
  516 + child: CircularProgressIndicator(strokeWidth: 2),
  517 + )
  518 + : ListView.builder(
  519 + scrollDirection: Axis.horizontal,
  520 + clipBehavior: Clip.none,
  521 + itemCount: themes.length,
  522 + itemBuilder: (context, index) {
  523 + final image = themes[index].infoList.firstOrNull;
  524 + return Transform.translate(
  525 + offset: Offset(index == 0 ? 0 : -_overlap * index, 0),
  526 + child: _ThemeBubble(
  527 + size: _itemSize,
  528 + imageUrl: image?.imgUrl,
  529 + assetPath: image?.assetPath,
  530 + ),
  531 + );
  532 + },
  533 + ),
522 ), 534 ),
523 SizedBox(height: 10.dp), 535 SizedBox(height: 10.dp),
524 Text( 536 Text(
@@ -538,10 +550,15 @@ class _WatchThemeCard extends StatelessWidget { @@ -538,10 +550,15 @@ class _WatchThemeCard extends StatelessWidget {
538 } 550 }
539 551
540 class _ThemeBubble extends StatelessWidget { 552 class _ThemeBubble extends StatelessWidget {
541 - const _ThemeBubble({required this.size, required this.assetPath}); 553 + const _ThemeBubble({
  554 + required this.size,
  555 + this.imageUrl,
  556 + this.assetPath,
  557 + });
542 558
543 final double size; 559 final double size;
544 - final String assetPath; 560 + final String? imageUrl;
  561 + final String? assetPath;
545 562
546 @override 563 @override
547 Widget build(BuildContext context) { 564 Widget build(BuildContext context) {
@@ -554,12 +571,27 @@ class _ThemeBubble extends StatelessWidget { @@ -554,12 +571,27 @@ class _ThemeBubble extends StatelessWidget {
554 border: Border.all(color: Colors.white, width: 4), 571 border: Border.all(color: Colors.white, width: 4),
555 ), 572 ),
556 alignment: Alignment.center, 573 alignment: Alignment.center,
557 - child: Image.asset(  
558 - assetPath, 574 + child: _buildImage(),
  575 + );
  576 + }
  577 +
  578 + Widget _buildImage() {
  579 + if (imageUrl != null && imageUrl!.isNotEmpty) {
  580 + return CachedNetworkImage(
  581 + imageUrl: imageUrl!,
559 width: 36, 582 width: 36,
560 height: 36, 583 height: 36,
561 fit: BoxFit.fill, 584 fit: BoxFit.fill,
562 - ),  
563 - ); 585 + );
  586 + }
  587 + if (assetPath != null && assetPath!.isNotEmpty) {
  588 + return Image.asset(
  589 + assetPath!,
  590 + width: 36,
  591 + height: 36,
  592 + fit: BoxFit.fill,
  593 + );
  594 + }
  595 + return const SizedBox.shrink();
564 } 596 }
565 } 597 }
@@ -129,13 +129,15 @@ class CreateWatchThemeController extends GetxController { @@ -129,13 +129,15 @@ class CreateWatchThemeController extends GetxController {
129 //TODO: - 上传图片 129 //TODO: - 上传图片
130 130
131 // final result = await _themeApi.createTheme( 131 // final result = await _themeApi.createTheme(
132 - // name: customThemeName.value,  
133 - // fullOfEnergyName: customStatusNames[0],  
134 - // normalName: customStatusNames[1],  
135 - // overpressureName: customStatusNames[3],  
136 - // fullOfEnergyImage: customImagePaths[0] ?? '', 132 + // themeName: customThemeName.value,
  133 + // energeticDescription: customStatusNames[0],
  134 + // energeticImage: customImagePaths[0] ?? '',
  135 + // normalDescription: customStatusNames[1],
137 // normalImage: customImagePaths[1] ?? '', 136 // normalImage: customImagePaths[1] ?? '',
138 - // overpressureImage: customImagePaths[3] ?? customImagePaths[2] ?? '', 137 + // slightStressfulDescription: customStatusNames[2],
  138 + // slightStressfulImage: customImagePaths[2] ?? '',
  139 + // stressfulDescription: customStatusNames[3],
  140 + // stressfulImage: customImagePaths[3] ?? '',
139 // ); 141 // );
140 isSaving.value = false; 142 isSaving.value = false;
141 143
@@ -151,15 +153,15 @@ class CreateWatchThemeController extends GetxController { @@ -151,15 +153,15 @@ class CreateWatchThemeController extends GetxController {
151 153
152 WatchThemeItem _buildThemeItem() { 154 WatchThemeItem _buildThemeItem() {
153 return WatchThemeItem( 155 return WatchThemeItem(
154 - title: customThemeName.value,  
155 - isCustomTheme: true,  
156 - infoList: [  
157 - for (var index = 0; index < customStatusNames.length; index++)  
158 - WatchThemeItemInfo(  
159 - title: customStatusNames[index],  
160 - assetPath: customImagePaths[index],  
161 - ),  
162 - ], 156 + themeName: customThemeName.value,
  157 + energeticDescription: customStatusNames[0],
  158 + energeticImage: customImagePaths[0],
  159 + normalDescription: customStatusNames[1],
  160 + normalImage: customImagePaths[1],
  161 + slightStressfulDescription: customStatusNames[2],
  162 + slightStressfulImage: customImagePaths[2],
  163 + stressfulDescription: customStatusNames[3],
  164 + stressfulImage: customImagePaths[3],
163 ); 165 );
164 } 166 }
165 167
@@ -25,9 +25,7 @@ class CustomWatchThemePreviewController extends GetxController { @@ -25,9 +25,7 @@ class CustomWatchThemePreviewController extends GetxController {
25 @override 25 @override
26 void onInit() { 26 void onInit() {
27 super.onInit(); 27 super.onInit();
28 - themeItem = _readThemeArgument() ??  
29 - customThemes.firstOrNull ??  
30 - WatchThemeItem.empty(); 28 + themeItem = _readThemeArgument() ?? WatchThemeItem.empty();
31 } 29 }
32 30
33 WatchThemeItem? _readThemeArgument() { 31 WatchThemeItem? _readThemeArgument() {
@@ -14,8 +14,8 @@ class WatchThemeController extends GetxController { @@ -14,8 +14,8 @@ class WatchThemeController extends GetxController {
14 final hasCustomThemes = false.obs; 14 final hasCustomThemes = false.obs;
15 final isPremium = false.obs; 15 final isPremium = false.obs;
16 final isLoadingThemes = false.obs; 16 final isLoadingThemes = false.obs;
17 - final officialThemeItems = <WatchThemeItem>[...officialThemes].obs;  
18 - final customThemeItems = <WatchThemeItem>[...customThemes].obs; 17 + final officialThemeItems = <WatchThemeItem>[].obs;
  18 + final customThemeItems = <WatchThemeItem>[].obs;
19 19
20 @override 20 @override
21 void onInit() { 21 void onInit() {
@@ -34,24 +34,15 @@ class WatchThemeController extends GetxController { @@ -34,24 +34,15 @@ class WatchThemeController extends GetxController {
34 isLoadingThemes.value = false; 34 isLoadingThemes.value = false;
35 35
36 if (result is! AppSuccess<WatchThemeResponse>) { 36 if (result is! AppSuccess<WatchThemeResponse>) {
37 - hasCustomThemes.value = customThemeItems.isNotEmpty;  
38 - isPremium.value = isPremium.value || hasCustomThemes.value;  
39 return; 37 return;
40 } 38 }
41 39
42 final themes = result.data.themes; 40 final themes = result.data.themes;
43 - if (themes.isEmpty) {  
44 - hasCustomThemes.value = customThemeItems.isNotEmpty;  
45 - isPremium.value = isPremium.value || hasCustomThemes.value;  
46 - return;  
47 - }  
48 -  
49 - final official = themes.where((theme) => !theme.isCustomTheme).toList(); 41 + final official = themes.where((theme) => theme.isOfficialTheme).toList();
50 final custom = themes.where((theme) => theme.isCustomTheme).toList(); 42 final custom = themes.where((theme) => theme.isCustomTheme).toList();
51 - if (official.isNotEmpty) {  
52 - officialThemeItems.assignAll(official);  
53 - } 43 + officialThemeItems.assignAll(official);
54 customThemeItems.assignAll(custom); 44 customThemeItems.assignAll(custom);
  45 + selectedOfficialIndex.value = 0;
55 hasCustomThemes.value = custom.isNotEmpty; 46 hasCustomThemes.value = custom.isNotEmpty;
56 isPremium.value = isPremium.value || hasCustomThemes.value; 47 isPremium.value = isPremium.value || hasCustomThemes.value;
57 } 48 }
@@ -23,7 +23,7 @@ class WatchThemePreviewController extends GetxController { @@ -23,7 +23,7 @@ class WatchThemePreviewController extends GetxController {
23 @override 23 @override
24 void onInit() { 24 void onInit() {
25 super.onInit(); 25 super.onInit();
26 - themeItem = _readThemeArgument() ?? officialThemes.first; 26 + themeItem = _readThemeArgument() ?? WatchThemeItem.empty();
27 } 27 }
28 28
29 WatchThemeItem? _readThemeArgument() { 29 WatchThemeItem? _readThemeArgument() {
1 import 'dart:ui'; 1 import 'dart:ui';
2 2
3 -import 'package:doublefeel_flutter/app/modules/watch_theme/widgets/watch_theme_colors.dart'; 3 +import '../widgets/watch_theme_colors.dart';
4 4
5 class WatchThemeItem { 5 class WatchThemeItem {
6 const WatchThemeItem({ 6 const WatchThemeItem({
7 this.id, 7 this.id,
8 - this.createTime,  
9 - this.updateTime,  
10 this.userId, 8 this.userId,
11 this.status, 9 this.status,
12 - this.isCustomTheme = false,  
13 - this.isDefaultCharacter = false,  
14 - required this.title,  
15 - required this.infoList, 10 + required this.themeName,
  11 + required this.energeticDescription,
  12 + this.energeticImage,
  13 + required this.normalDescription,
  14 + this.normalImage,
  15 + required this.slightStressfulDescription,
  16 + this.slightStressfulImage,
  17 + required this.stressfulDescription,
  18 + this.stressfulImage,
  19 + this.isOfficial = 0,
  20 + this.isDefaultTheme = 0,
  21 + this.officialThemeId,
  22 + this.createTime,
  23 + this.updateTime,
16 }); 24 });
17 25
18 final int? id; 26 final int? id;
19 - final int? createTime;  
20 - final int? updateTime;  
21 final int? userId; 27 final int? userId;
22 final int? status; 28 final int? status;
23 - final bool isDefaultCharacter;  
24 - final bool isCustomTheme;  
25 - final String title;  
26 - final List<WatchThemeItemInfo> infoList; 29 + final String themeName;
  30 + final String energeticDescription;
  31 + final String? energeticImage;
  32 + final String normalDescription;
  33 + final String? normalImage;
  34 + final String slightStressfulDescription;
  35 + final String? slightStressfulImage;
  36 + final String stressfulDescription;
  37 + final String? stressfulImage;
  38 + final int isOfficial;
  39 + final int isDefaultTheme;
  40 + final int? officialThemeId;
  41 + final int? createTime;
  42 + final int? updateTime;
27 43
28 factory WatchThemeItem.fromJson(Map<String, dynamic> json) { 44 factory WatchThemeItem.fromJson(Map<String, dynamic> json) {
29 - final isDefaultTheme = json['is_default_theme'] == true;  
30 - final userId = json['user_id'] as int?;  
31 - final positiveDescription = json['positive_description'] as String?;  
32 - final normalDescription = json['normal_description'] as String?;  
33 - final negativeDescription = json['negative_description'] as String?;  
34 - final positiveImage = json['positive_image'] as String?;  
35 - final normalImage = json['normal_image'] as String?;  
36 - final negativeImage = json['negative_image'] as String?;  
37 -  
38 return WatchThemeItem( 45 return WatchThemeItem(
39 - id: json['id'] as int?,  
40 - createTime: json['create_time'] as int?,  
41 - updateTime: json['update_time'] as int?,  
42 - userId: userId,  
43 - status: json['status'] as int?,  
44 - isDefaultCharacter: isDefaultTheme,  
45 - isCustomTheme: userId != null,  
46 - title: (json['theme_name'] as String?) ?? '自定义主题',  
47 - infoList: [ 46 + id: _intFromJson(json['id']),
  47 + userId: _intFromJson(json['user_id']),
  48 + status: _intFromJson(json['status']),
  49 + themeName: _stringFromJson(json['theme_name'], '自定义主题'),
  50 + energeticDescription:
  51 + _stringFromJson(json['energetic_description'], '状态优秀'),
  52 + energeticImage: _nullableStringFromJson(json['energetic_image']),
  53 + normalDescription: _stringFromJson(json['normal_description'], '状态正常'),
  54 + normalImage: _nullableStringFromJson(json['normal_image']),
  55 + slightStressfulDescription:
  56 + _stringFromJson(json['slight_stressful_description'], '注意压力'),
  57 + slightStressfulImage:
  58 + _nullableStringFromJson(json['slight_stressful_image']),
  59 + stressfulDescription:
  60 + _stringFromJson(json['stressful_description'], '压力过载'),
  61 + stressfulImage: _nullableStringFromJson(json['stressful_image']),
  62 + isOfficial: _intFromJson(json['is_official']) ?? 0,
  63 + isDefaultTheme: _intFromJson(json['is_default_theme']) ?? 0,
  64 + officialThemeId: _intFromJson(json['official_theme_id']),
  65 + createTime: _intFromJson(json['create_time']),
  66 + updateTime: _intFromJson(json['update_time']),
  67 + );
  68 + }
  69 +
  70 + Map<String, dynamic> toJson() {
  71 + return {
  72 + if (id != null) 'id': id,
  73 + if (userId != null) 'user_id': userId,
  74 + if (status != null) 'status': status,
  75 + 'theme_name': themeName,
  76 + 'energetic_description': energeticDescription,
  77 + 'energetic_image': energeticImage,
  78 + 'normal_description': normalDescription,
  79 + 'normal_image': normalImage,
  80 + 'slight_stressful_description': slightStressfulDescription,
  81 + 'slight_stressful_image': slightStressfulImage,
  82 + 'stressful_description': stressfulDescription,
  83 + 'stressful_image': stressfulImage,
  84 + 'is_official': isOfficial,
  85 + 'is_default_theme': isDefaultTheme,
  86 + if (officialThemeId != null) 'official_theme_id': officialThemeId,
  87 + if (createTime != null) 'create_time': createTime,
  88 + if (updateTime != null) 'update_time': updateTime,
  89 + };
  90 + }
  91 +
  92 + String get title => themeName;
  93 +
  94 + bool get isCustomTheme => isOfficial != 1;
  95 +
  96 + bool get isOfficialTheme => isOfficial == 1;
  97 +
  98 + bool get isDefault => isDefaultTheme == 1;
  99 +
  100 + List<WatchThemeItemInfo> get infoList => [
48 WatchThemeItemInfo( 101 WatchThemeItemInfo(
49 - title: positiveDescription ?? '状态优秀',  
50 - imgUrl: positiveImage, 102 + title: energeticDescription,
  103 + image: energeticImage,
51 ), 104 ),
52 WatchThemeItemInfo( 105 WatchThemeItemInfo(
53 - title: normalDescription ?? '状态正常',  
54 - imgUrl: normalImage, 106 + title: normalDescription,
  107 + image: normalImage,
55 ), 108 ),
56 WatchThemeItemInfo( 109 WatchThemeItemInfo(
57 - title: negativeDescription ?? '注意压力',  
58 - imgUrl: negativeImage, 110 + title: slightStressfulDescription,
  111 + image: slightStressfulImage,
59 ), 112 ),
60 WatchThemeItemInfo( 113 WatchThemeItemInfo(
61 - title: negativeDescription ?? '压力过载',  
62 - imgUrl: negativeImage, 114 + title: stressfulDescription,
  115 + image: stressfulImage,
63 ), 116 ),
64 - ], 117 + ];
  118 +
  119 + static WatchThemeItem empty() {
  120 + return const WatchThemeItem(
  121 + themeName: '自定义主题',
  122 + energeticDescription: '状态优秀',
  123 + normalDescription: '状态正常',
  124 + slightStressfulDescription: '注意压力',
  125 + stressfulDescription: '压力过载',
65 ); 126 );
66 } 127 }
67 128
68 - Map<String, dynamic> toJson() {  
69 - final excellent = infoList.elementAtOrNull(0);  
70 - final normal = infoList.elementAtOrNull(1);  
71 - final overload = infoList.elementAtOrNull(3) ?? infoList.elementAtOrNull(2);  
72 - final json = <String, dynamic>{};  
73 - if (id != null) json['id'] = id;  
74 - if (createTime != null) json['create_time'] = createTime;  
75 - if (updateTime != null) json['update_time'] = updateTime;  
76 - if (userId != null) json['user_id'] = userId;  
77 - if (status != null) json['status'] = status;  
78 - json['theme_name'] = title;  
79 - json['is_default_theme'] = isDefaultCharacter;  
80 - json['positive_description'] = excellent?.title;  
81 - json['positive_image'] = excellent?.image;  
82 - json['normal_description'] = normal?.title;  
83 - json['normal_image'] = normal?.image;  
84 - json['negative_description'] = overload?.title;  
85 - json['negative_image'] = overload?.image;  
86 - return json; 129 + static int? _intFromJson(Object? value) {
  130 + if (value is int) return value;
  131 + if (value is num) return value.toInt();
  132 + if (value is String) return int.tryParse(value);
  133 + if (value is bool) return value ? 1 : 0;
  134 + return null;
87 } 135 }
88 136
89 - static WatchThemeItem empty() {  
90 - return WatchThemeItem(  
91 - title: '自定义主题',  
92 - infoList: [],  
93 - ); 137 + static String _stringFromJson(Object? value, String fallback) {
  138 + final result = _nullableStringFromJson(value);
  139 + return result ?? fallback;
  140 + }
  141 +
  142 + static String? _nullableStringFromJson(Object? value) {
  143 + if (value == null) return null;
  144 + final result = value.toString().trim();
  145 + return result.isEmpty ? null : result;
94 } 146 }
95 } 147 }
96 148
97 class WatchThemeItemInfo { 149 class WatchThemeItemInfo {
  150 + const WatchThemeItemInfo({
  151 + required this.title,
  152 + this.image,
  153 + });
  154 +
98 final String title; 155 final String title;
99 - final String? imgUrl;  
100 - final String? assetPath; 156 + final String? image;
  157 +
  158 + String? get imgUrl => _isNetworkImage ? image : null;
101 159
102 - WatchThemeItemInfo({required this.title, this.imgUrl, this.assetPath}); 160 + String? get assetPath => _isNetworkImage ? null : image;
103 161
104 - String? get image => imgUrl ?? assetPath; 162 + bool get _isNetworkImage {
  163 + final value = image?.toLowerCase();
  164 + return value?.startsWith('http://') == true ||
  165 + value?.startsWith('https://') == true;
  166 + }
105 } 167 }
106 168
107 class WatchThemeResponse { 169 class WatchThemeResponse {
@@ -111,15 +173,14 @@ class WatchThemeResponse { @@ -111,15 +173,14 @@ class WatchThemeResponse {
111 173
112 factory WatchThemeResponse.fromJson(Map<String, dynamic> json) { 174 factory WatchThemeResponse.fromJson(Map<String, dynamic> json) {
113 final rawThemes = json['themes']; 175 final rawThemes = json['themes'];
  176 + if (rawThemes is! List) return const WatchThemeResponse();
114 return WatchThemeResponse( 177 return WatchThemeResponse(
115 - themes: rawThemes is List  
116 - ? rawThemes  
117 - .whereType<Map>()  
118 - .map((theme) => WatchThemeItem.fromJson(  
119 - Map<String, dynamic>.from(theme),  
120 - ))  
121 - .toList()  
122 - : const [], 178 + themes: rawThemes
  179 + .whereType<Map>()
  180 + .map((theme) => WatchThemeItem.fromJson(
  181 + Map<String, dynamic>.from(theme),
  182 + ))
  183 + .toList(),
123 ); 184 );
124 } 185 }
125 } 186 }
@@ -127,173 +188,44 @@ class WatchThemeResponse { @@ -127,173 +188,44 @@ class WatchThemeResponse {
127 class WatchThemeUpsertRequest { 188 class WatchThemeUpsertRequest {
128 const WatchThemeUpsertRequest({ 189 const WatchThemeUpsertRequest({
129 this.themeId, 190 this.themeId,
130 - required this.name,  
131 - required this.fullOfEnergyName,  
132 - required this.normalName,  
133 - required this.overpressureName,  
134 - required this.fullOfEnergyImage, 191 + required this.themeName,
  192 + required this.energeticDescription,
  193 + required this.energeticImage,
  194 + required this.normalDescription,
135 required this.normalImage, 195 required this.normalImage,
136 - required this.overpressureImage, 196 + required this.slightStressfulDescription,
  197 + required this.slightStressfulImage,
  198 + required this.stressfulDescription,
  199 + required this.stressfulImage,
137 }); 200 });
138 201
139 final int? themeId; 202 final int? themeId;
140 - final String name;  
141 - final String fullOfEnergyName;  
142 - final String normalName;  
143 - final String overpressureName;  
144 - final String fullOfEnergyImage; 203 + final String themeName;
  204 + final String energeticDescription;
  205 + final String energeticImage;
  206 + final String normalDescription;
145 final String normalImage; 207 final String normalImage;
146 - final String overpressureImage; 208 + final String slightStressfulDescription;
  209 + final String slightStressfulImage;
  210 + final String stressfulDescription;
  211 + final String stressfulImage;
147 212
148 Map<String, dynamic> toJson() { 213 Map<String, dynamic> toJson() {
149 return { 214 return {
150 if (themeId != null) 'theme_id': themeId, 215 if (themeId != null) 'theme_id': themeId,
151 - 'theme_name': name,  
152 - 'positive_description': fullOfEnergyName,  
153 - 'positive_image': fullOfEnergyImage,  
154 - 'normal_description': normalName, 216 + 'theme_name': themeName,
  217 + 'energetic_description': energeticDescription,
  218 + 'energetic_image': energeticImage,
  219 + 'normal_description': normalDescription,
155 'normal_image': normalImage, 220 'normal_image': normalImage,
156 - 'negative_description': overpressureName,  
157 - 'negative_image': overpressureImage, 221 + 'slight_stressful_description': slightStressfulDescription,
  222 + 'slight_stressful_image': slightStressfulImage,
  223 + 'stressful_description': stressfulDescription,
  224 + 'stressful_image': stressfulImage,
158 }; 225 };
159 } 226 }
160 } 227 }
161 228
162 -final officialThemes = <WatchThemeItem>[  
163 - WatchThemeItem(  
164 - title: '默认主题',  
165 - isDefaultCharacter: true,  
166 - infoList: [  
167 - WatchThemeItemInfo(  
168 - title: '状态优秀',  
169 - assetPath: 'assets/images/watch_theme/official_default_green.png',  
170 - ),  
171 - WatchThemeItemInfo(  
172 - title: '状态正常',  
173 - assetPath: 'assets/images/watch_theme/official_default_blue.png',  
174 - ),  
175 - WatchThemeItemInfo(  
176 - title: '注意压力',  
177 - assetPath: 'assets/images/watch_theme/official_default_orange.png',  
178 - ),  
179 - WatchThemeItemInfo(  
180 - title: '压力过载',  
181 - assetPath: 'assets/images/watch_theme/official_default_red.png',  
182 - ),  
183 - ],  
184 - ),  
185 - /*  
186 - WatchThemeItem(  
187 - title: '垂耳粉兔',  
188 - infoList: [  
189 - WatchThemeItemInfo(  
190 - title: '状态优秀',  
191 - assetPath: 'assets/images/watch_theme/official_rabbit_pink.png',  
192 - ),  
193 - WatchThemeItemInfo(  
194 - title: '状态正常',  
195 - assetPath: 'assets/images/watch_theme/official_rabbit_pink.png',  
196 - ),  
197 - WatchThemeItemInfo(  
198 - title: '注意压力',  
199 - assetPath: 'assets/images/watch_theme/official_rabbit_pink.png',  
200 - ),  
201 - WatchThemeItemInfo(  
202 - title: '压力过载',  
203 - assetPath: 'assets/images/watch_theme/official_rabbit_pink.png',  
204 - ),  
205 - ],  
206 - ),  
207 - WatchThemeItem(  
208 - title: '蓝象哥哥',  
209 - infoList: [  
210 - WatchThemeItemInfo(  
211 - title: '状态优秀',  
212 - assetPath: 'assets/images/watch_theme/official_elephant_blue.png',  
213 - ),  
214 - WatchThemeItemInfo(  
215 - title: '状态正常',  
216 - assetPath: 'assets/images/watch_theme/official_elephant_blue.png',  
217 - ),  
218 - WatchThemeItemInfo(  
219 - title: '注意压力',  
220 - assetPath: 'assets/images/watch_theme/official_elephant_blue.png',  
221 - ),  
222 - WatchThemeItemInfo(  
223 - title: '压力过载',  
224 - assetPath: 'assets/images/watch_theme/official_elephant_blue.png',  
225 - ),  
226 - ],  
227 - ),  
228 - WatchThemeItem(  
229 - title: '小狗白白',  
230 - infoList: [  
231 - WatchThemeItemInfo(  
232 - title: '状态优秀',  
233 - assetPath: 'assets/images/watch_theme/official_dog_white.png',  
234 - ),  
235 - WatchThemeItemInfo(  
236 - title: '状态正常',  
237 - assetPath: 'assets/images/watch_theme/official_dog_white.png',  
238 - ),  
239 - WatchThemeItemInfo(  
240 - title: '注意压力',  
241 - assetPath: 'assets/images/watch_theme/official_dog_white.png',  
242 - ),  
243 - WatchThemeItemInfo(  
244 - title: '压力过载',  
245 - assetPath: 'assets/images/watch_theme/official_dog_white.png',  
246 - ),  
247 - ],  
248 - ),  
249 - WatchThemeItem(  
250 - title: '猫猫狗狗',  
251 - infoList: [  
252 - WatchThemeItemInfo(  
253 - title: '状态优秀',  
254 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
255 - ),  
256 - WatchThemeItemInfo(  
257 - title: '状态正常',  
258 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
259 - ),  
260 - WatchThemeItemInfo(  
261 - title: '注意压力',  
262 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
263 - ),  
264 - WatchThemeItemInfo(  
265 - title: '压力过载',  
266 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
267 - ),  
268 - ],  
269 - ),  
270 - */  
271 -];  
272 -  
273 -final customThemes = <WatchThemeItem>[  
274 - WatchThemeItem(  
275 - title: '猫猫狗狗-AAA',  
276 - infoList: [  
277 - WatchThemeItemInfo(  
278 - title: '状态优秀',  
279 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
280 - ),  
281 - WatchThemeItemInfo(  
282 - title: '状态正常',  
283 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
284 - ),  
285 - WatchThemeItemInfo(  
286 - title: '注意压力',  
287 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
288 - ),  
289 - WatchThemeItemInfo(  
290 - title: '压力过载',  
291 - assetPath: 'assets/images/watch_theme/custom_cat_dog.png',  
292 - ),  
293 - ],  
294 - ),  
295 -];  
296 -  
297 final defaultThemeTemplates = [ 229 final defaultThemeTemplates = [
298 WatchThemeTemplateItem(title: '状态优秀', color: WatchThemeColors.excellent), 230 WatchThemeTemplateItem(title: '状态优秀', color: WatchThemeColors.excellent),
299 WatchThemeTemplateItem(title: '状态正常', color: WatchThemeColors.normal), 231 WatchThemeTemplateItem(title: '状态正常', color: WatchThemeColors.normal),
@@ -302,8 +234,8 @@ final defaultThemeTemplates = [ @@ -302,8 +234,8 @@ final defaultThemeTemplates = [
302 ]; 234 ];
303 235
304 class WatchThemeTemplateItem { 236 class WatchThemeTemplateItem {
  237 + WatchThemeTemplateItem({required this.title, required this.color});
  238 +
305 final String title; 239 final String title;
306 final Color color; 240 final Color color;
307 -  
308 - WatchThemeTemplateItem({required this.title, required this.color});  
309 } 241 }
@@ -144,7 +144,8 @@ class _CustomThemeItem extends StatelessWidget { @@ -144,7 +144,8 @@ class _CustomThemeItem extends StatelessWidget {
144 WatchThemeCharacterAvatar( 144 WatchThemeCharacterAvatar(
145 size: 88, 145 size: 88,
146 assetPath: item.infoList.firstOrNull?.assetPath, 146 assetPath: item.infoList.firstOrNull?.assetPath,
147 - empty: item.infoList.firstOrNull?.assetPath == null, 147 + imageUrl: item.infoList.firstOrNull?.imgUrl,
  148 + empty: item.infoList.firstOrNull?.image == null,
148 ), 149 ),
149 SizedBox(height: 8.dp), 150 SizedBox(height: 8.dp),
150 Text( 151 Text(
@@ -48,6 +48,7 @@ class OfficialThemeGrid extends StatelessWidget { @@ -48,6 +48,7 @@ class OfficialThemeGrid extends StatelessWidget {
48 size: 88, 48 size: 88,
49 selected: index == selectedIndex, 49 selected: index == selectedIndex,
50 assetPath: theme.infoList.firstOrNull?.assetPath, 50 assetPath: theme.infoList.firstOrNull?.assetPath,
  51 + imageUrl: theme.infoList.firstOrNull?.imgUrl,
51 ), 52 ),
52 SizedBox(height: 8), 53 SizedBox(height: 8),
53 Text( 54 Text(
@@ -36,6 +36,7 @@ class StatusPreviewCard extends StatelessWidget { @@ -36,6 +36,7 @@ class StatusPreviewCard extends StatelessWidget {
36 WatchThemeCharacterAvatar( 36 WatchThemeCharacterAvatar(
37 size: 60, 37 size: 60,
38 assetPath: infoList[i].assetPath, 38 assetPath: infoList[i].assetPath,
  39 + imageUrl: infoList[i].imgUrl,
39 ), 40 ),
40 SizedBox(height: 4.dp), 41 SizedBox(height: 4.dp),
41 Text( 42 Text(
@@ -8,12 +8,14 @@ class WatchThemeCharacterAvatar extends StatelessWidget { @@ -8,12 +8,14 @@ class WatchThemeCharacterAvatar extends StatelessWidget {
8 super.key, 8 super.key,
9 required this.size, 9 required this.size,
10 this.assetPath, 10 this.assetPath,
  11 + this.imageUrl,
11 this.selected = false, 12 this.selected = false,
12 this.empty = false, 13 this.empty = false,
13 }); 14 });
14 15
15 final double size; 16 final double size;
16 final String? assetPath; 17 final String? assetPath;
  18 + final String? imageUrl;
17 final bool selected; 19 final bool selected;
18 final bool empty; 20 final bool empty;
19 21
@@ -36,14 +38,9 @@ class WatchThemeCharacterAvatar extends StatelessWidget { @@ -36,14 +38,9 @@ class WatchThemeCharacterAvatar extends StatelessWidget {
36 : null, 38 : null,
37 ), 39 ),
38 alignment: Alignment.center, 40 alignment: Alignment.center,
39 - child: empty 41 + child: empty || (assetPath == null && imageUrl == null)
40 ? const SizedBox.shrink() 42 ? const SizedBox.shrink()
41 - : Image.asset(  
42 - assetPath!,  
43 - width: avatarSize * 0.82,  
44 - height: avatarSize * 0.82,  
45 - fit: BoxFit.contain,  
46 - )), 43 + : _buildImage(avatarSize)),
47 if (selected) 44 if (selected)
48 Positioned( 45 Positioned(
49 right: -1.dp, 46 right: -1.dp,
@@ -66,4 +63,23 @@ class WatchThemeCharacterAvatar extends StatelessWidget { @@ -66,4 +63,23 @@ class WatchThemeCharacterAvatar extends StatelessWidget {
66 ), 63 ),
67 ); 64 );
68 } 65 }
  66 +
  67 + Widget _buildImage(double avatarSize) {
  68 + final width = avatarSize * 0.82;
  69 + if (imageUrl != null && imageUrl!.isNotEmpty) {
  70 + return Image.network(
  71 + imageUrl!,
  72 + width: width,
  73 + height: width,
  74 + fit: BoxFit.contain,
  75 + errorBuilder: (_, __, ___) => const SizedBox.shrink(),
  76 + );
  77 + }
  78 + return Image.asset(
  79 + assetPath!,
  80 + width: width,
  81 + height: width,
  82 + fit: BoxFit.contain,
  83 + );
  84 + }
69 } 85 }
@@ -11,26 +11,30 @@ class ThemeApi { @@ -11,26 +11,30 @@ class ThemeApi {
11 final DioClient _dioClient; 11 final DioClient _dioClient;
12 12
13 Future<AppResult<void>> createTheme({ 13 Future<AppResult<void>> createTheme({
14 - required String name,  
15 - required String fullOfEnergyName,  
16 - required String normalName,  
17 - required String overpressureName,  
18 - required String fullOfEnergyImage, 14 + required String themeName,
  15 + required String energeticDescription,
  16 + required String energeticImage,
  17 + required String normalDescription,
19 required String normalImage, 18 required String normalImage,
20 - required String overpressureImage, 19 + required String slightStressfulDescription,
  20 + required String slightStressfulImage,
  21 + required String stressfulDescription,
  22 + required String stressfulImage,
21 }) { 23 }) {
22 return safeCall( 24 return safeCall(
23 call: () async { 25 call: () async {
24 await _dioClient.dio.post( 26 await _dioClient.dio.post(
25 ApiPaths.watchTheme, 27 ApiPaths.watchTheme,
26 data: WatchThemeUpsertRequest( 28 data: WatchThemeUpsertRequest(
27 - name: name,  
28 - fullOfEnergyName: fullOfEnergyName,  
29 - normalName: normalName,  
30 - overpressureName: overpressureName,  
31 - fullOfEnergyImage: fullOfEnergyImage, 29 + themeName: themeName,
  30 + energeticDescription: energeticDescription,
  31 + energeticImage: energeticImage,
  32 + normalDescription: normalDescription,
32 normalImage: normalImage, 33 normalImage: normalImage,
33 - overpressureImage: overpressureImage, 34 + slightStressfulDescription: slightStressfulDescription,
  35 + slightStressfulImage: slightStressfulImage,
  36 + stressfulDescription: stressfulDescription,
  37 + stressfulImage: stressfulImage,
34 ).toJson(), 38 ).toJson(),
35 ); 39 );
36 }, 40 },
@@ -39,13 +43,15 @@ class ThemeApi { @@ -39,13 +43,15 @@ class ThemeApi {
39 43
40 Future<AppResult<void>> editTheme({ 44 Future<AppResult<void>> editTheme({
41 required int themeId, 45 required int themeId,
42 - required String name,  
43 - required String fullOfEnergyName,  
44 - required String normalName,  
45 - required String overpressureName,  
46 - required String fullOfEnergyImage, 46 + required String themeName,
  47 + required String energeticDescription,
  48 + required String energeticImage,
  49 + required String normalDescription,
47 required String normalImage, 50 required String normalImage,
48 - required String overpressureImage, 51 + required String slightStressfulDescription,
  52 + required String slightStressfulImage,
  53 + required String stressfulDescription,
  54 + required String stressfulImage,
49 }) { 55 }) {
50 return safeCall( 56 return safeCall(
51 call: () async { 57 call: () async {
@@ -53,13 +59,15 @@ class ThemeApi { @@ -53,13 +59,15 @@ class ThemeApi {
53 ApiPaths.watchTheme, 59 ApiPaths.watchTheme,
54 data: WatchThemeUpsertRequest( 60 data: WatchThemeUpsertRequest(
55 themeId: themeId, 61 themeId: themeId,
56 - name: name,  
57 - fullOfEnergyName: fullOfEnergyName,  
58 - normalName: normalName,  
59 - overpressureName: overpressureName,  
60 - fullOfEnergyImage: fullOfEnergyImage, 62 + themeName: themeName,
  63 + energeticDescription: energeticDescription,
  64 + energeticImage: energeticImage,
  65 + normalDescription: normalDescription,
61 normalImage: normalImage, 66 normalImage: normalImage,
62 - overpressureImage: overpressureImage, 67 + slightStressfulDescription: slightStressfulDescription,
  68 + slightStressfulImage: slightStressfulImage,
  69 + stressfulDescription: stressfulDescription,
  70 + stressfulImage: stressfulImage,
63 ).toJson(), 71 ).toJson(),
64 ); 72 );
65 }, 73 },
@@ -83,13 +91,16 @@ class ThemeApi { @@ -83,13 +91,16 @@ class ThemeApi {
83 ); 91 );
84 } 92 }
85 93
  94 +// 主题类型 choices: [(0, '所有主题'), (1, '官方主题'), (2, '用户主题')]
86 Future<AppResult<WatchThemeResponse>> getThemeList({ 95 Future<AppResult<WatchThemeResponse>> getThemeList({
87 HttpErrorHandlingPolicy? errorHandlingPolicy = 96 HttpErrorHandlingPolicy? errorHandlingPolicy =
88 HttpErrorHandlingPolicy.defaultPolicy, 97 HttpErrorHandlingPolicy.defaultPolicy,
  98 + int themeType = 0,
89 }) { 99 }) {
90 return safeCall( 100 return safeCall(
91 call: () async { 101 call: () async {
92 - final response = await _dioClient.dio.get(ApiPaths.watchThemeList); 102 + final response = await _dioClient.dio.get(ApiPaths.watchThemeList,
  103 + queryParameters: {'theme_type': themeType});
93 return WatchThemeResponse.fromJson( 104 return WatchThemeResponse.fromJson(
94 response.data as Map<String, dynamic>, 105 response.data as Map<String, dynamic>,
95 ); 106 );
@@ -61,10 +61,10 @@ abstract final class ApiPaths { @@ -61,10 +61,10 @@ abstract final class ApiPaths {
61 static const userVipInfo = '/client/doublefeel/user/vip/info/'; 61 static const userVipInfo = '/client/doublefeel/user/vip/info/';
62 62
63 // Watch theme 63 // Watch theme
64 - static const watchTheme = '/client/doublefeel/theme/watch_theme/';  
65 - static const watchThemeList = '/client/doublefeel/theme/watch_theme/list/'; 64 + static const watchTheme = '/client/doublefeel/theme/v2/watch_theme/';
  65 + static const watchThemeList = '/client/doublefeel/theme/v2/watch_theme/list/';
66 static const watchThemeActive = 66 static const watchThemeActive =
67 - '/client/doublefeel/theme/watch_theme/active/'; 67 + '/client/doublefeel/theme/v2/watch_theme/active/';
68 68
69 // friends 69 // friends
70 static const friends = '/client/doublefeel/health/v2/friends/'; 70 static const friends = '/client/doublefeel/health/v2/friends/';
@@ -62,8 +62,7 @@ import 'app_localizations_zh.dart'; @@ -62,8 +62,7 @@ import 'app_localizations_zh.dart';
62 /// be consistent with the languages listed in the AppLocalizations.supportedLocales 62 /// be consistent with the languages listed in the AppLocalizations.supportedLocales
63 /// property. 63 /// property.
64 abstract class AppLocalizations { 64 abstract class AppLocalizations {
65 - AppLocalizations(String locale)  
66 - : localeName = intl.Intl.canonicalizedLocale(locale.toString()); 65 + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
67 66
68 final String localeName; 67 final String localeName;
69 68
@@ -71,8 +70,7 @@ abstract class AppLocalizations { @@ -71,8 +70,7 @@ abstract class AppLocalizations {
71 return Localizations.of<AppLocalizations>(context, AppLocalizations); 70 return Localizations.of<AppLocalizations>(context, AppLocalizations);
72 } 71 }
73 72
74 - static const LocalizationsDelegate<AppLocalizations> delegate =  
75 - _AppLocalizationsDelegate(); 73 + static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
76 74
77 /// A list of this localizations delegate along with the default localizations 75 /// A list of this localizations delegate along with the default localizations
78 /// delegates. 76 /// delegates.
@@ -84,8 +82,7 @@ abstract class AppLocalizations { @@ -84,8 +82,7 @@ abstract class AppLocalizations {
84 /// Additional delegates can be added by appending to this list in 82 /// Additional delegates can be added by appending to this list in
85 /// MaterialApp. This list does not have to be used at all if a custom list 83 /// MaterialApp. This list does not have to be used at all if a custom list
86 /// of delegates is preferred or required. 84 /// of delegates is preferred or required.
87 - static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =  
88 - <LocalizationsDelegate<dynamic>>[ 85 + static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
89 delegate, 86 delegate,
90 GlobalMaterialLocalizations.delegate, 87 GlobalMaterialLocalizations.delegate,
91 GlobalCupertinoLocalizations.delegate, 88 GlobalCupertinoLocalizations.delegate,
@@ -528,8 +525,7 @@ abstract class AppLocalizations { @@ -528,8 +525,7 @@ abstract class AppLocalizations {
528 /// 525 ///
529 /// In zh, this message translates to: 526 /// In zh, this message translates to:
530 /// **'你们现在可以查看彼此的 HRV、压力与睡眠变化,并在对方疲惫时及时送上关心。'** 527 /// **'你们现在可以查看彼此的 HRV、压力与睡眠变化,并在对方疲惫时及时送上关心。'**
531 - String  
532 - get youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired; 528 + String get youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired;
533 529
534 /// No description provided for @bindPartnerTitle. 530 /// No description provided for @bindPartnerTitle.
535 /// 531 ///
@@ -3082,8 +3078,7 @@ abstract class AppLocalizations { @@ -3082,8 +3078,7 @@ abstract class AppLocalizations {
3082 String get appReviewIllustrationPlaceholder; 3078 String get appReviewIllustrationPlaceholder;
3083 } 3079 }
3084 3080
3085 -class _AppLocalizationsDelegate  
3086 - extends LocalizationsDelegate<AppLocalizations> { 3081 +class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
3087 const _AppLocalizationsDelegate(); 3082 const _AppLocalizationsDelegate();
3088 3083
3089 @override 3084 @override
@@ -3092,25 +3087,25 @@ class _AppLocalizationsDelegate @@ -3092,25 +3087,25 @@ class _AppLocalizationsDelegate
3092 } 3087 }
3093 3088
3094 @override 3089 @override
3095 - bool isSupported(Locale locale) =>  
3096 - <String>['en', 'zh'].contains(locale.languageCode); 3090 + bool isSupported(Locale locale) => <String>['en', 'zh'].contains(locale.languageCode);
3097 3091
3098 @override 3092 @override
3099 bool shouldReload(_AppLocalizationsDelegate old) => false; 3093 bool shouldReload(_AppLocalizationsDelegate old) => false;
3100 } 3094 }
3101 3095
3102 AppLocalizations lookupAppLocalizations(Locale locale) { 3096 AppLocalizations lookupAppLocalizations(Locale locale) {
  3097 +
  3098 +
3103 // Lookup logic when only language code is specified. 3099 // Lookup logic when only language code is specified.
3104 switch (locale.languageCode) { 3100 switch (locale.languageCode) {
3105 - case 'en':  
3106 - return AppLocalizationsEn();  
3107 - case 'zh':  
3108 - return AppLocalizationsZh(); 3101 + case 'en': return AppLocalizationsEn();
  3102 + case 'zh': return AppLocalizationsZh();
3109 } 3103 }
3110 3104
3111 throw FlutterError( 3105 throw FlutterError(
3112 - 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '  
3113 - 'an issue with the localizations generation tool. Please file an issue '  
3114 - 'on GitHub with a reproducible sample app and the gen-l10n configuration '  
3115 - 'that was used.'); 3106 + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
  3107 + 'an issue with the localizations generation tool. Please file an issue '
  3108 + 'on GitHub with a reproducible sample app and the gen-l10n configuration '
  3109 + 'that was used.'
  3110 + );
3116 } 3111 }
1 -// ignore: unused_import  
2 -import 'package:intl/intl.dart' as intl;  
3 import 'app_localizations.dart'; 1 import 'app_localizations.dart';
4 2
5 // ignore_for_file: type=lint 3 // ignore_for_file: type=lint
@@ -69,12 +67,10 @@ class AppLocalizationsEn extends AppLocalizations { @@ -69,12 +67,10 @@ class AppLocalizationsEn extends AppLocalizations {
69 String get settings => 'Settings'; 67 String get settings => 'Settings';
70 68
71 @override 69 @override
72 - String get onboardingIntroTitle =>  
73 - 'DoubleFeel is a health companion app built for Apple Watch'; 70 + String get onboardingIntroTitle => 'DoubleFeel is a health companion app built for Apple Watch';
74 71
75 @override 72 @override
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>'; 73 + String get 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>';
78 74
79 @override 75 @override
80 String get onboardingStateQuestion => 'Which of these often happens to you?'; 76 String get onboardingStateQuestion => 'Which of these often happens to you?';
@@ -86,19 +82,16 @@ class AppLocalizationsEn extends AppLocalizations { @@ -86,19 +82,16 @@ class AppLocalizationsEn extends AppLocalizations {
86 String get onboardingStateTired => 'I get tired easily'; 82 String get onboardingStateTired => 'I get tired easily';
87 83
88 @override 84 @override
89 - String get onboardingStatePoorRest =>  
90 - 'I wake up but still do not feel rested'; 85 + String get onboardingStatePoorRest => 'I wake up but still do not feel rested';
91 86
92 @override 87 @override
93 - String get onboardingStateNeedStimulants =>  
94 - 'I rely on cigarettes, alcohol, coffee, or other stimulants to stay alert'; 88 + String get onboardingStateNeedStimulants => 'I rely on cigarettes, alcohol, coffee, or other stimulants to stay alert';
95 89
96 @override 90 @override
97 String get onboardingStateNone => 'None of the above'; 91 String get onboardingStateNone => 'None of the above';
98 92
99 @override 93 @override
100 - String get onboardingStressGoalQuestion =>  
101 - 'What do you want to learn by understanding stress?'; 94 + String get onboardingStressGoalQuestion => 'What do you want to learn by understanding stress?';
102 95
103 @override 96 @override
104 String get onboardingStressGoalSource => 'Understand where stress comes from'; 97 String get onboardingStressGoalSource => 'Understand where stress comes from';
@@ -107,8 +100,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -107,8 +100,7 @@ class AppLocalizationsEn extends AppLocalizations {
107 String get onboardingStressGoalReminder => 'Get reminded when stress appears'; 100 String get onboardingStressGoalReminder => 'Get reminded when stress appears';
108 101
109 @override 102 @override
110 - String get onboardingStressGoalLovedOnes =>  
111 - 'Let people who care about me know my stress state'; 103 + String get onboardingStressGoalLovedOnes => 'Let people who care about me know my stress state';
112 104
113 @override 105 @override
114 String get onboardingStressGoalRelax => 'Understand stress and feel lighter'; 106 String get onboardingStressGoalRelax => 'Understand stress and feel lighter';
@@ -117,8 +109,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -117,8 +109,7 @@ class AppLocalizationsEn extends AppLocalizations {
117 String get onboardingStressGoalBodyTalk => 'Communicate better with my body'; 109 String get onboardingStressGoalBodyTalk => 'Communicate better with my body';
118 110
119 @override 111 @override
120 - String get onboardingReliefQuestion =>  
121 - 'Which methods do you think can ease stress?'; 112 + String get onboardingReliefQuestion => 'Which methods do you think can ease stress?';
122 113
123 @override 114 @override
124 String get onboardingReliefSleep => 'Regular sleep'; 115 String get onboardingReliefSleep => 'Regular sleep';
@@ -142,8 +133,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -142,8 +133,7 @@ class AppLocalizationsEn extends AppLocalizations {
142 String get onboardingKeyDataTitle => 'Did you know?'; 133 String get onboardingKeyDataTitle => 'Did you know?';
143 134
144 @override 135 @override
145 - String get onboardingKeyDataSubtitle =>  
146 - 'Everyone has a magical and important body metric that can help us:'; 136 + String get onboardingKeyDataSubtitle => 'Everyone has a magical and important body metric that can help us:';
147 137
148 @override 138 @override
149 String get onboardingKeyDataStress => 'Monitor stress'; 139 String get onboardingKeyDataStress => 'Monitor stress';
@@ -158,8 +148,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -158,8 +148,7 @@ class AppLocalizationsEn extends AppLocalizations {
158 String get onboardingKeyDataHabits => 'Build healthy habits'; 148 String get onboardingKeyDataHabits => 'Build healthy habits';
159 149
160 @override 150 @override
161 - String get onboardingKeyDataLovedOnes =>  
162 - 'Help important people care about your state in time'; 151 + String get onboardingKeyDataLovedOnes => 'Help important people care about your state in time';
163 152
164 @override 153 @override
165 String get onboardingTellMeWhatItIs => 'Tell me what it is!'; 154 String get onboardingTellMeWhatItIs => 'Tell me what it is!';
@@ -168,19 +157,16 @@ class AppLocalizationsEn extends AppLocalizations { @@ -168,19 +157,16 @@ class AppLocalizationsEn extends AppLocalizations {
168 String get onboardingHrvTitle => 'It is HRV, heart rate variability'; 157 String get onboardingHrvTitle => 'It is HRV, heart rate variability';
169 158
170 @override 159 @override
171 - String get onboardingHrvSubtitle =>  
172 - 'It helps us measure overall stress and health'; 160 + String get onboardingHrvSubtitle => 'It helps us measure overall stress and health';
173 161
174 @override 162 @override
175 - String get onboardingHrvDescription =>  
176 - '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.'; 163 + String get 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.';
177 164
178 @override 165 @override
179 String get onboardingTellMeMore => 'Tell me more'; 166 String get onboardingTellMeMore => 'Tell me more';
180 167
181 @override 168 @override
182 - String get onboardingResearchTitle =>  
183 - 'Many studies show that HRV changes are closely related to how our body and mind feel'; 169 + String get onboardingResearchTitle => 'Many studies show that HRV changes are closely related to how our body and mind feel';
184 170
185 @override 171 @override
186 String get onboardingResearchFatigue => 'Physical fatigue'; 172 String get onboardingResearchFatigue => 'Physical fatigue';
@@ -198,30 +184,25 @@ class AppLocalizationsEn extends AppLocalizations { @@ -198,30 +184,25 @@ class AppLocalizationsEn extends AppLocalizations {
198 String get onboardingHealthPermissionTitle => 'Allow health data access'; 184 String get onboardingHealthPermissionTitle => 'Allow health data access';
199 185
200 @override 186 @override
201 - String get onboardingHealthPermissionBody =>  
202 - 'DoubleFeel needs connected wearable health data to send reminders, count stress moments, and provide suggestions.'; 187 + String get onboardingHealthPermissionBody => 'DoubleFeel needs connected wearable health data to send reminders, count stress moments, and provide suggestions.';
203 188
204 @override 189 @override
205 - String get onboardingHealthPermissionPrivacy =>  
206 - 'Your health data is stored locally. We do not upload any related data.'; 190 + String get onboardingHealthPermissionPrivacy => 'Your health data is stored locally. We do not upload any related data.';
207 191
208 @override 192 @override
209 String get onboardingNotificationTitle => 'Turn on notifications'; 193 String get onboardingNotificationTitle => 'Turn on notifications';
210 194
211 @override 195 @override
212 - String get onboardingNotificationSubtitle =>  
213 - 'Learn about every body change in time'; 196 + String get onboardingNotificationSubtitle => 'Learn about every body change in time';
214 197
215 @override 198 @override
216 - String get onboardingNotificationBody =>  
217 - 'After Apple Watch data updates, we can remind you in time and help you act to improve your stress state.'; 199 + String get onboardingNotificationBody => 'After Apple Watch data updates, we can remind you in time and help you act to improve your stress state.';
218 200
219 @override 201 @override
220 String get onboardingMemberTitle => 'Get an annual membership offer'; 202 String get onboardingMemberTitle => 'Get an annual membership offer';
221 203
222 @override 204 @override
223 - String get onboardingMemberBody =>  
224 - 'Start your pressure alert and health companion journey, so love and care are always present.'; 205 + String get onboardingMemberBody => 'Start your pressure alert and health companion journey, so love and care are always present.';
225 206
226 @override 207 @override
227 String get onboardingMemberOriginalPrice => 'Original ¥72.00/year'; 208 String get onboardingMemberOriginalPrice => 'Original ¥72.00/year';
@@ -236,16 +217,13 @@ class AppLocalizationsEn extends AppLocalizations { @@ -236,16 +217,13 @@ class AppLocalizationsEn extends AppLocalizations {
236 String get onboardingMemberAllOptions => 'View all purchase options'; 217 String get onboardingMemberAllOptions => 'View all purchase options';
237 218
238 @override 219 @override
239 - String get healthCompanionIsNowAvailable =>  
240 - 'Health Companion is now available'; 220 + String get healthCompanionIsNowAvailable => 'Health Companion is now available';
241 221
242 @override 222 @override
243 - String get youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired =>  
244 - '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.'; 223 + String get 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.';
245 224
246 @override 225 @override
247 - String get bindPartnerTitle =>  
248 - 'Add a Close Contact\nOne more person to care about your health'; 226 + String get bindPartnerTitle => 'Add a Close Contact\nOne more person to care about your health';
249 227
250 @override 228 @override
251 String get bindPartnerMyId => 'My ID'; 229 String get bindPartnerMyId => 'My ID';
@@ -284,8 +262,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -284,8 +262,7 @@ class AppLocalizationsEn extends AppLocalizations {
284 String get onboardingResearchGoodSleep => 'Good Sleep'; 262 String get onboardingResearchGoodSleep => 'Good Sleep';
285 263
286 @override 264 @override
287 - String get loginSlogan =>  
288 - 'Start your pressure alert and health companion journey\nso love and care are always present'; 265 + String get loginSlogan => 'Start your pressure alert and health companion journey\nso love and care are always present';
289 266
290 @override 267 @override
291 String get loginWithPhone => 'Sign in with Phone'; 268 String get loginWithPhone => 'Sign in with Phone';
@@ -335,15 +312,13 @@ class AppLocalizationsEn extends AppLocalizations { @@ -335,15 +312,13 @@ class AppLocalizationsEn extends AppLocalizations {
335 String get phoneLoginCodeHint => 'Enter verification code'; 312 String get phoneLoginCodeHint => 'Enter verification code';
336 313
337 @override 314 @override
338 - String get phoneLoginAutoRegisterHint =>  
339 - 'Unregistered numbers will be registered automatically'; 315 + String get phoneLoginAutoRegisterHint => 'Unregistered numbers will be registered automatically';
340 316
341 @override 317 @override
342 String get phoneLoginLoggingIn => 'Signing in...'; 318 String get phoneLoginLoggingIn => 'Signing in...';
343 319
344 @override 320 @override
345 - String get loginAgreeToTermsToast =>  
346 - 'Please read and agree to the Terms of Service and Privacy Policy first'; 321 + String get loginAgreeToTermsToast => 'Please read and agree to the Terms of Service and Privacy Policy first';
347 322
348 @override 323 @override
349 String get phoneLoginInvalidPhone => 'Invalid phone number'; 324 String get phoneLoginInvalidPhone => 'Invalid phone number';
@@ -355,12 +330,10 @@ class AppLocalizationsEn extends AppLocalizations { @@ -355,12 +330,10 @@ class AppLocalizationsEn extends AppLocalizations {
355 String get phoneLoginInvalidCode => 'Invalid verification code'; 330 String get phoneLoginInvalidCode => 'Invalid verification code';
356 331
357 @override 332 @override
358 - String get todayHealthDataAuthTitle =>  
359 - 'Unable to access heart rate health data'; 333 + String get todayHealthDataAuthTitle => 'Unable to access heart rate health data';
360 334
361 @override 335 @override
362 - String get todayHealthDataAuthDescription =>  
363 - 'DoubleFeel needs permission to access your health data to provide stress reminders, real-time stress statistics, and health suggestions. Otherwise, some app features may not work properly. Your health data is stored locally only and will not be uploaded to any server.'; 336 + String get todayHealthDataAuthDescription => 'DoubleFeel needs permission to access your health data to provide stress reminders, real-time stress statistics, and health suggestions. Otherwise, some app features may not work properly. Your health data is stored locally only and will not be uploaded to any server.';
364 337
365 @override 338 @override
366 String get todayHealthDataAuthAction => 'Authorize health data access'; 339 String get todayHealthDataAuthAction => 'Authorize health data access';
@@ -381,24 +354,19 @@ class AppLocalizationsEn extends AppLocalizations { @@ -381,24 +354,19 @@ class AppLocalizationsEn extends AppLocalizations {
381 String get todayFaqLinkNoData => 'What if the app or watch face has no data?'; 354 String get todayFaqLinkNoData => 'What if the app or watch face has no data?';
382 355
383 @override 356 @override
384 - String get todayFaqLinkHrvRealtimeUpdate =>  
385 - 'How can HRV data update in real time?'; 357 + String get todayFaqLinkHrvRealtimeUpdate => 'How can HRV data update in real time?';
386 358
387 @override 359 @override
388 - String get todayFaqLinkWatchNoStatusNotification =>  
389 - 'Why can\'t my watch receive status notifications?'; 360 + String get todayFaqLinkWatchNoStatusNotification => 'Why can\'t my watch receive status notifications?';
390 361
391 @override 362 @override
392 - String get todayFaqLinkWatchNoStatusAndInteractionNotification =>  
393 - 'Why can\'t my watch receive status and interaction notifications?'; 363 + String get todayFaqLinkWatchNoStatusAndInteractionNotification => 'Why can\'t my watch receive status and interaction notifications?';
394 364
395 @override 365 @override
396 - String get todayFaqLinkWatchFaceDataDelay =>  
397 - 'Why is watch face data delayed or not updating?'; 366 + String get todayFaqLinkWatchFaceDataDelay => 'Why is watch face data delayed or not updating?';
398 367
399 @override 368 @override
400 - String get todayFaqLinkWatchFaceBlackScreen =>  
401 - 'Why does the watch face turn black?'; 369 + String get todayFaqLinkWatchFaceBlackScreen => 'Why does the watch face turn black?';
402 370
403 @override 371 @override
404 String get todayStressStatusTitle => 'Overall stress status'; 372 String get todayStressStatusTitle => 'Overall stress status';
@@ -425,176 +393,136 @@ class AppLocalizationsEn extends AppLocalizations { @@ -425,176 +393,136 @@ class AppLocalizationsEn extends AppLocalizations {
425 String get todayStressStatusInsufficientData => 'Insufficient data'; 393 String get todayStressStatusInsufficientData => 'Insufficient data';
426 394
427 @override 395 @override
428 - String get todayStressStatusOverloadDescription =>  
429 - 'Your current HRV is much lower than your long-term average, which may indicate fatigue, high stress, or insufficient recovery. Rest is recommended.'; 396 + String get todayStressStatusOverloadDescription => 'Your current HRV is much lower than your long-term average, which may indicate fatigue, high stress, or insufficient recovery. Rest is recommended.';
430 397
431 @override 398 @override
432 - String get todayStressStatusCautionDescription =>  
433 - 'Your current HRV is below the normal range, and your body may be accumulating stress. Pay attention to rest and recovery.'; 399 + String get todayStressStatusCautionDescription => 'Your current HRV is below the normal range, and your body may be accumulating stress. Pay attention to rest and recovery.';
434 400
435 @override 401 @override
436 - String get todayStressStatusNormalDescription =>  
437 - 'Your current body state is within your normal fluctuation range.'; 402 + String get todayStressStatusNormalDescription => 'Your current body state is within your normal fluctuation range.';
438 403
439 @override 404 @override
440 - String get todayStressStatusExcellentDescription =>  
441 - 'Your current HRV is higher than your recent average, indicating better recovery and overall state.'; 405 + String get todayStressStatusExcellentDescription => 'Your current HRV is higher than your recent average, indicating better recovery and overall state.';
442 406
443 @override 407 @override
444 - String get todayStressStatusInsufficientDataDescription =>  
445 - 'There is not enough available data to accurately assess your stress state yet.'; 408 + String get todayStressStatusInsufficientDataDescription => 'There is not enough available data to accurately assess your stress state yet.';
446 409
447 @override 410 @override
448 - String get todayHrvMeasurementIntro =>  
449 - 'Apple Watch measures HRV every 2-5 hours by default. If you want to measure it manually right now, follow these steps:'; 411 + String get todayHrvMeasurementIntro => 'Apple Watch measures HRV every 2-5 hours by default. If you want to measure it manually right now, follow these steps:';
450 412
451 @override 413 @override
452 - String get todayHrvMeasurementStep1 =>  
453 - '1. Wear your Apple Watch snugly, sit down, and stay calm'; 414 + String get todayHrvMeasurementStep1 => '1. Wear your Apple Watch snugly, sit down, and stay calm';
454 415
455 @override 416 @override
456 - String get todayHrvMeasurementStep2 =>  
457 - '2. Open Mindfulness on Apple Watch and start Breathe'; 417 + String get todayHrvMeasurementStep2 => '2. Open Mindfulness on Apple Watch and start Breathe';
458 418
459 @override 419 @override
460 - String get todayHrvMeasurementStep3 =>  
461 - '3. Keep breathing steadily and wait 1-3 minutes'; 420 + String get todayHrvMeasurementStep3 => '3. Keep breathing steadily and wait 1-3 minutes';
462 421
463 @override 422 @override
464 - String get todayHrvMeasurementStep4 =>  
465 - '4. After breathing is complete, lock and unlock your iPhone once'; 423 + String get todayHrvMeasurementStep4 => '4. After breathing is complete, lock and unlock your iPhone once';
466 424
467 @override 425 @override
468 - String get todayHrvMeasurementStep5 =>  
469 - '5. Wait about one minute. StressWatch will receive and display your data'; 426 + String get todayHrvMeasurementStep5 => '5. Wait about one minute. StressWatch will receive and display your data';
470 427
471 @override 428 @override
472 - String get todayHrvMeasurementHint =>  
473 - 'Tip: Data comes from Apple Watch. After measurement, there may be delays or data may not sync immediately. If this happens, measure again and wait for the data to be read.'; 429 + String get todayHrvMeasurementHint => 'Tip: Data comes from Apple Watch. After measurement, there may be delays or data may not sync immediately. If this happens, measure again and wait for the data to be read.';
474 430
475 @override 431 @override
476 - String get todayHrvMeasurementWarning =>  
477 - 'Note: Health permissions must be enabled, and Low Power Mode must be turned off.'; 432 + String get todayHrvMeasurementWarning => 'Note: Health permissions must be enabled, and Low Power Mode must be turned off.';
478 433
479 @override 434 @override
480 String get todayStressStatusWhatTitle => 'What is overall stress status?'; 435 String get todayStressStatusWhatTitle => 'What is overall stress status?';
481 436
482 @override 437 @override
483 - String get todayStressStatusWhatDescription1 =>  
484 - 'DoubleFeel combines your HRV (heart rate variability), resting heart rate, and body-state changes from the past 30 days to assess your overall stress level.'; 438 + String get todayStressStatusWhatDescription1 => 'DoubleFeel combines your HRV (heart rate variability), resting heart rate, and body-state changes from the past 30 days to assess your overall stress level.';
485 439
486 @override 440 @override
487 - String get todayStressStatusWhatDescription2 =>  
488 - 'Because HRV fluctuates with emotions, exercise, sleep, and fatigue, a single reading has limited value. We recommend focusing on your overall stress status across the day, which is more stable and useful. It helps you understand your body state and helps close contacts notice changes in time.'; 441 + String get todayStressStatusWhatDescription2 => 'Because HRV fluctuates with emotions, exercise, sleep, and fatigue, a single reading has limited value. We recommend focusing on your overall stress status across the day, which is more stable and useful. It helps you understand your body state and helps close contacts notice changes in time.';
489 442
490 @override 443 @override
491 - String get todayStressStatusWhyHrvTitle =>  
492 - 'Why use HRV (heart rate variability)?'; 444 + String get todayStressStatusWhyHrvTitle => 'Why use HRV (heart rate variability)?';
493 445
494 @override 446 @override
495 - String get todayStressStatusWhyHrvDescription =>  
496 - 'HRV is an important metric for measuring body stress and recovery capacity.'; 447 + String get todayStressStatusWhyHrvDescription => 'HRV is an important metric for measuring body stress and recovery capacity.';
497 448
498 @override 449 @override
499 String get todayStressStatusUsually => 'In general:'; 450 String get todayStressStatusUsually => 'In general:';
500 451
501 @override 452 @override
502 - String get todayStressStatusHrvHigher =>  
503 - '· Higher HRV usually means better recovery'; 453 + String get todayStressStatusHrvHigher => '· Higher HRV usually means better recovery';
504 454
505 @override 455 @override
506 - String get todayStressStatusHrvLower =>  
507 - '· Lower HRV may indicate fatigue, stress, or insufficient sleep'; 456 + String get todayStressStatusHrvLower => '· Lower HRV may indicate fatigue, stress, or insufficient sleep';
508 457
509 @override 458 @override
510 - String get todayStressStatusHrvChangesFast =>  
511 - '· HRV changes quickly, making it useful for short-term body-state changes.'; 459 + String get todayStressStatusHrvChangesFast => '· HRV changes quickly, making it useful for short-term body-state changes.';
512 460
513 @override 461 @override
514 - String get todayStressStatusAppWatchDifferenceTitle =>  
515 - 'How are stress statuses on the phone app and Apple Watch different?'; 462 + String get todayStressStatusAppWatchDifferenceTitle => 'How are stress statuses on the phone app and Apple Watch different?';
516 463
517 @override 464 @override
518 - String get todayStressStatusAppWatchDifferenceApp =>  
519 - 'The phone app home page shows the day\'s overall stress status, combining HRV, resting heart rate, and overall trends.'; 465 + String get todayStressStatusAppWatchDifferenceApp => 'The phone app home page shows the day\'s overall stress status, combining HRV, resting heart rate, and overall trends.';
520 466
521 @override 467 @override
522 - String get todayStressStatusAppWatchDifferenceWatch =>  
523 - 'Apple Watch shows the most recent real-time stress status, which is better for quickly checking your current body changes.'; 468 + String get todayStressStatusAppWatchDifferenceWatch => 'Apple Watch shows the most recent real-time stress status, which is better for quickly checking your current body changes.';
524 469
525 @override 470 @override
526 - String get todayStressStatusWaitingDataTitle =>  
527 - 'Why does Waiting for data appear?'; 471 + String get todayStressStatusWaitingDataTitle => 'Why does Waiting for data appear?';
528 472
529 @override 473 @override
530 - String get todayStressStatusWaitingDataDescription1 =>  
531 - 'Waiting for data means the current amount of collected data is not enough to generate a reliable stress assessment.'; 474 + String get todayStressStatusWaitingDataDescription1 => 'Waiting for data means the current amount of collected data is not enough to generate a reliable stress assessment.';
532 475
533 @override 476 @override
534 - String get todayStressStatusWaitingDataDescription2 =>  
535 - 'Please keep wearing your Apple Watch and wait for the system to collect data automatically.'; 477 + String get todayStressStatusWaitingDataDescription2 => 'Please keep wearing your Apple Watch and wait for the system to collect data automatically.';
536 478
537 @override 479 @override
538 - String get todayStressStatusWaitingDataReasonsIntro =>  
539 - 'Possible reasons include:'; 480 + String get todayStressStatusWaitingDataReasonsIntro => 'Possible reasons include:';
540 481
541 @override 482 @override
542 String get todayStressStatusWaitingDataReason1 => '1. Not enough HRV samples'; 483 String get todayStressStatusWaitingDataReason1 => '1. Not enough HRV samples';
543 484
544 @override 485 @override
545 - String get todayStressStatusWaitingDataReason2 =>  
546 - '2. Missing resting heart rate data'; 486 + String get todayStressStatusWaitingDataReason2 => '2. Missing resting heart rate data';
547 487
548 @override 488 @override
549 - String get todayStressStatusWaitingDataReason3 =>  
550 - '3. Apple Watch has not been worn long enough'; 489 + String get todayStressStatusWaitingDataReason3 => '3. Apple Watch has not been worn long enough';
551 490
552 @override 491 @override
553 - String get todayStressStatusWaitingDataReason4 =>  
554 - '4. Apple Health permissions are not enabled'; 492 + String get todayStressStatusWaitingDataReason4 => '4. Apple Health permissions are not enabled';
555 493
556 @override 494 @override
557 - String get todayHrvPrincipleHowMeasureTitle =>  
558 - 'How does DoubleFeel measure stress status?'; 495 + String get todayHrvPrincipleHowMeasureTitle => 'How does DoubleFeel measure stress status?';
559 496
560 @override 497 @override
561 - String get todayHrvPrincipleHowMeasureDescription1 =>  
562 - 'When you wear Apple Watch normally, the system automatically collects your heart rate data and syncs it to Apple Health.'; 498 + String get todayHrvPrincipleHowMeasureDescription1 => 'When you wear Apple Watch normally, the system automatically collects your heart rate data and syncs it to Apple Health.';
563 499
564 @override 500 @override
565 - String get todayHrvPrincipleHowMeasureDescription2 =>  
566 - 'DoubleFeel calculates HRV (heart rate variability) indicators based on this data to assess your body stress and recovery state.'; 501 + String get todayHrvPrincipleHowMeasureDescription2 => 'DoubleFeel calculates HRV (heart rate variability) indicators based on this data to assess your body stress and recovery state.';
567 502
568 @override 503 @override
569 - String get todayHrvPrincipleHowMeasureDescription3 =>  
570 - 'HRV is sensitive to stress, fatigue, sleep, emotions, and recovery, so it helps us notice body-state changes earlier.'; 504 + String get todayHrvPrincipleHowMeasureDescription3 => 'HRV is sensitive to stress, fatigue, sleep, emotions, and recovery, so it helps us notice body-state changes earlier.';
571 505
572 @override 506 @override
573 - String get todayHrvPrincipleHowMeasureDescription4 =>  
574 - 'To make results more accurate, DoubleFeel compares your current HRV state with your own 30-day average instead of comparing it directly with other people.'; 507 + String get todayHrvPrincipleHowMeasureDescription4 => 'To make results more accurate, DoubleFeel compares your current HRV state with your own 30-day average instead of comparing it directly with other people.';
575 508
576 @override 509 @override
577 String get todayRealtimeStressWhatTitle => 'What is real-time stress?'; 510 String get todayRealtimeStressWhatTitle => 'What is real-time stress?';
578 511
579 @override 512 @override
580 - String get todayRealtimeStressWhatDescription1 =>  
581 - 'Real-time stress is a body stress indicator dynamically generated by DoubleFeel based on your current HRV, heart rate state, and changes in your personal history.'; 513 + String get todayRealtimeStressWhatDescription1 => 'Real-time stress is a body stress indicator dynamically generated by DoubleFeel based on your current HRV, heart rate state, and changes in your personal history.';
582 514
583 @override 515 @override
584 - String get todayRealtimeStressWhatDescription2 =>  
585 - 'A higher stress value means your body state is deviating more from your usual baseline and may reflect fatigue, insufficient recovery, or high stress.'; 516 + String get todayRealtimeStressWhatDescription2 => 'A higher stress value means your body state is deviating more from your usual baseline and may reflect fatigue, insufficient recovery, or high stress.';
586 517
587 @override 518 @override
588 - String get todayRealtimeStressWhatDescription3 =>  
589 - 'It helps you notice body changes faster and adjust rest, exercise, and daily rhythm in time.'; 519 + String get todayRealtimeStressWhatDescription3 => 'It helps you notice body changes faster and adjust rest, exercise, and daily rhythm in time.';
590 520
591 @override 521 @override
592 - String get todayRealtimeStressDivisionTitle =>  
593 - 'How is real-time stress divided?'; 522 + String get todayRealtimeStressDivisionTitle => 'How is real-time stress divided?';
594 523
595 @override 524 @override
596 - String get todayRealtimeStressDivisionIntro =>  
597 - 'Real-time stress is shown as a percentage:'; 525 + String get todayRealtimeStressDivisionIntro => 'Real-time stress is shown as a percentage:';
598 526
599 @override 527 @override
600 String get todayRealtimeStressExcellentRange => 'Excellent: 1%-20%'; 528 String get todayRealtimeStressExcellentRange => 'Excellent: 1%-20%';
@@ -609,103 +537,79 @@ class AppLocalizationsEn extends AppLocalizations { @@ -609,103 +537,79 @@ class AppLocalizationsEn extends AppLocalizations {
609 String get todayRealtimeStressOverloadRange => 'Stress overload: 81%-100%'; 537 String get todayRealtimeStressOverloadRange => 'Stress overload: 81%-100%';
610 538
611 @override 539 @override
612 - String get todayRealtimeStressExcellentDescription =>  
613 - 'Your recovery state is good and you are generally relaxed.'; 540 + String get todayRealtimeStressExcellentDescription => 'Your recovery state is good and you are generally relaxed.';
614 541
615 @override 542 @override
616 - String get todayRealtimeStressNormalDescription =>  
617 - 'Your body is within the normal fluctuation range.'; 543 + String get todayRealtimeStressNormalDescription => 'Your body is within the normal fluctuation range.';
618 544
619 @override 545 @override
620 - String get todayRealtimeStressCautionDescription =>  
621 - 'Your body may be accumulating stress and needs proper rest and recovery.'; 546 + String get todayRealtimeStressCautionDescription => 'Your body may be accumulating stress and needs proper rest and recovery.';
622 547
623 @override 548 @override
624 - String get todayRealtimeStressOverloadDescription =>  
625 - 'Your body stress is clearly high. Reduce load and pay attention to sleep and recovery.'; 549 + String get todayRealtimeStressOverloadDescription => 'Your body stress is clearly high. Reduce load and pay attention to sleep and recovery.';
626 550
627 @override 551 @override
628 - String get todayRealtimeStressDivisionBaseline =>  
629 - 'These ranges are adjusted dynamically based on your personal baseline and should not be directly compared between users.'; 552 + String get todayRealtimeStressDivisionBaseline => 'These ranges are adjusted dynamically based on your personal baseline and should not be directly compared between users.';
630 553
631 @override 554 @override
632 - String get todayRealtimeStressDivisionAwake =>  
633 - 'Real-time stress mainly reflects body stress changes while awake.'; 555 + String get todayRealtimeStressDivisionAwake => 'Real-time stress mainly reflects body stress changes while awake.';
634 556
635 @override 557 @override
636 - String get todayRealtimeStressLowBetterTitle =>  
637 - 'Is lower real-time stress always better?'; 558 + String get todayRealtimeStressLowBetterTitle => 'Is lower real-time stress always better?';
638 559
639 @override 560 @override
640 String get todayRealtimeStressLowBetterNo => 'Not necessarily.'; 561 String get todayRealtimeStressLowBetterNo => 'Not necessarily.';
641 562
642 @override 563 @override
643 - String get todayRealtimeStressLowBetterType =>  
644 - 'Body stress can be normal or abnormal.'; 564 + String get todayRealtimeStressLowBetterType => 'Body stress can be normal or abnormal.';
645 565
646 @override 566 @override
647 - String get todayRealtimeStressLowBetterExample =>  
648 - 'For example, real-time stress rising briefly during or after exercise is a normal recovery response. It can also rise temporarily during focused work or emotional excitement, which are normal body adjustments.'; 567 + String get todayRealtimeStressLowBetterExample => 'For example, real-time stress rising briefly during or after exercise is a normal recovery response. It can also rise temporarily during focused work or emotional excitement, which are normal body adjustments.';
649 568
650 @override 569 @override
651 - String get todayRealtimeStressLowBetterHighStress =>  
652 - 'But if stress remains high while resting, sitting for a long time, or after poor sleep, it may indicate physical fatigue, mental stress, insufficient sleep recovery, incomplete exercise recovery, too much caffeine, alcohol, stimulants, or possible discomfort.'; 570 + String get todayRealtimeStressLowBetterHighStress => 'But if stress remains high while resting, sitting for a long time, or after poor sleep, it may indicate physical fatigue, mental stress, insufficient sleep recovery, incomplete exercise recovery, too much caffeine, alcohol, stimulants, or possible discomfort.';
653 571
654 @override 572 @override
655 - String get todayRealtimeStressLowBetterTrend =>  
656 - 'DoubleFeel focuses more on your long-term trend than on a single fluctuation.'; 573 + String get todayRealtimeStressLowBetterTrend => 'DoubleFeel focuses more on your long-term trend than on a single fluctuation.';
657 574
658 @override 575 @override
659 - String get todayRealtimeStressScenarioTitle =>  
660 - 'When should HRV and real-time stress be used?'; 576 + String get todayRealtimeStressScenarioTitle => 'When should HRV and real-time stress be used?';
661 577
662 @override 578 @override
663 - String get todayRealtimeStressScenarioHrvDefault =>  
664 - 'With Apple Watch default settings, HRV updates every 2-5 hours.'; 579 + String get todayRealtimeStressScenarioHrvDefault => 'With Apple Watch default settings, HRV updates every 2-5 hours.';
665 580
666 @override 581 @override
667 - String get todayRealtimeStressScenarioRegionLimit =>  
668 - 'In some regions, Apple Watch breathing features may be limited, which can affect HRV update frequency. Turning on breathing features may also consume more battery.'; 582 + String get todayRealtimeStressScenarioRegionLimit => 'In some regions, Apple Watch breathing features may be limited, which can affect HRV update frequency. Turning on breathing features may also consume more battery.';
669 583
670 @override 584 @override
671 - String get todayRealtimeStressScenarioIntro =>  
672 - 'To address the long interval between HRV updates, DoubleFeel designed real-time stress:'; 585 + String get todayRealtimeStressScenarioIntro => 'To address the long interval between HRV updates, DoubleFeel designed real-time stress:';
673 586
674 @override 587 @override
675 - String get todayRealtimeStressScenarioUpdateEvery6Min =>  
676 - '· Real-time stress updates every 6 minutes'; 588 + String get todayRealtimeStressScenarioUpdateEvery6Min => '· Real-time stress updates every 6 minutes';
677 589
678 @override 590 @override
679 - String get todayRealtimeStressScenarioTimely =>  
680 - '· It can reflect body-state changes more promptly'; 591 + String get todayRealtimeStressScenarioTimely => '· It can reflect body-state changes more promptly';
681 592
682 @override 593 @override
683 - String get todayRealtimeStressScenarioConsistentTrend =>  
684 - '· In most cases, the real-time stress trend is consistent with the HRV trend'; 594 + String get todayRealtimeStressScenarioConsistentTrend => '· In most cases, the real-time stress trend is consistent with the HRV trend';
685 595
686 @override 596 @override
687 - String get todayRealtimeStressScenarioSummary =>  
688 - 'This lets users see long-term HRV trends while also using real-time stress as a short-term body-state reference.'; 597 + String get todayRealtimeStressScenarioSummary => 'This lets users see long-term HRV trends while also using real-time stress as a short-term body-state reference.';
689 598
690 @override 599 @override
691 - String get todayFaqNoDataTitle =>  
692 - 'What if the app or watch face has no data?'; 600 + String get todayFaqNoDataTitle => 'What if the app or watch face has no data?';
693 601
694 @override 602 @override
695 - String get todayFaqNoDataDescription1 =>  
696 - '1. Confirm that Apple Watch is on watchOS 10.0 or above and iPhone is on iOS 14 or above. You can check system versions in About.'; 603 + String get todayFaqNoDataDescription1 => '1. Confirm that Apple Watch is on watchOS 10.0 or above and iPhone is on iOS 14 or above. You can check system versions in About.';
697 604
698 @override 605 @override
699 - String get todayFaqNoDataDescription2 =>  
700 - '2. Confirm all permissions are enabled: iPhone Health > Sharing > Apps > DoubleFeel > Turn On All Permissions.'; 606 + String get todayFaqNoDataDescription2 => '2. Confirm all permissions are enabled: iPhone Health > Sharing > Apps > DoubleFeel > Turn On All Permissions.';
701 607
702 @override 608 @override
703 - String get todayFaqNoDataDescription3 =>  
704 - '3. Confirm the device is not in Low Power Mode, low battery, or worn too loosely, as these can affect data collection.'; 609 + String get todayFaqNoDataDescription3 => '3. Confirm the device is not in Low Power Mode, low battery, or worn too loosely, as these can affect data collection.';
705 610
706 @override 611 @override
707 - String get todayFaqContactPrefix =>  
708 - 'If everything above is correct, you can '; 612 + String get todayFaqContactPrefix => 'If everything above is correct, you can ';
709 613
710 @override 614 @override
711 String get todayFaqContactAction => 'contact us'; 615 String get todayFaqContactAction => 'contact us';
@@ -714,90 +618,70 @@ class AppLocalizationsEn extends AppLocalizations { @@ -714,90 +618,70 @@ class AppLocalizationsEn extends AppLocalizations {
714 String get todayFaqContactSuffix => '.'; 618 String get todayFaqContactSuffix => '.';
715 619
716 @override 620 @override
717 - String get todayFaqWatchNoNotificationTitle =>  
718 - 'Watch cannot receive status notifications?'; 621 + String get todayFaqWatchNoNotificationTitle => 'Watch cannot receive status notifications?';
719 622
720 @override 623 @override
721 - String get todayFaqWatchNoNotificationDescription1 =>  
722 - 'Apple Watch and iPhone notifications have priority rules: when your iPhone is unlocked and the screen is on, notifications only appear on the phone and will not appear on the watch.'; 624 + String get todayFaqWatchNoNotificationDescription1 => 'Apple Watch and iPhone notifications have priority rules: when your iPhone is unlocked and the screen is on, notifications only appear on the phone and will not appear on the watch.';
723 625
724 @override 626 @override
725 - String get todayFaqWatchNoNotificationDescription2 =>  
726 - 'If stress data displays and updates normally but your watch does not receive notifications, try the following:'; 627 + String get todayFaqWatchNoNotificationDescription2 => 'If stress data displays and updates normally but your watch does not receive notifications, try the following:';
727 628
728 @override 629 @override
729 - String get todayFaqWatchNoNotificationCheckPhoneNotification =>  
730 - '1. Check whether iPhone notifications are enabled (Settings > DoubleFeel > Notifications).'; 630 + String get todayFaqWatchNoNotificationCheckPhoneNotification => '1. Check whether iPhone notifications are enabled (Settings > DoubleFeel > Notifications).';
731 631
732 @override 632 @override
733 - String get todayFaqWatchNoNotificationCheckPhoneBackgroundRefresh =>  
734 - '2. Check whether iPhone Background App Refresh is enabled (Settings > DoubleFeel > Background App Refresh).'; 633 + String get todayFaqWatchNoNotificationCheckPhoneBackgroundRefresh => '2. Check whether iPhone Background App Refresh is enabled (Settings > DoubleFeel > Background App Refresh).';
735 634
736 @override 635 @override
737 - String get todayFaqWatchNoNotificationCheckWatchBackgroundRefresh =>  
738 - '3. Check whether Apple Watch Background App Refresh is enabled (Settings > General > Background App Refresh, and make sure DoubleFeel is enabled).'; 636 + String get todayFaqWatchNoNotificationCheckWatchBackgroundRefresh => '3. Check whether Apple Watch Background App Refresh is enabled (Settings > General > Background App Refresh, and make sure DoubleFeel is enabled).';
739 637
740 @override 638 @override
741 - String get todayFaqWatchNoNotificationCheckModes =>  
742 - '4. Make sure Low Power, Focus, Do Not Disturb, Theater, Sleep, and similar modes are off.'; 639 + String get todayFaqWatchNoNotificationCheckModes => '4. Make sure Low Power, Focus, Do Not Disturb, Theater, Sleep, and similar modes are off.';
743 640
744 @override 641 @override
745 - String get todayFaqWatchNoNotificationReinstall =>  
746 - '5. Reinstall DoubleFeel and restart Apple Watch and iPhone.'; 642 + String get todayFaqWatchNoNotificationReinstall => '5. Reinstall DoubleFeel and restart Apple Watch and iPhone.';
747 643
748 @override 644 @override
749 - String get todayFaqWatchFaceDelayTitle =>  
750 - 'Watch face data not updating or delayed?'; 645 + String get todayFaqWatchFaceDelayTitle => 'Watch face data not updating or delayed?';
751 646
752 @override 647 @override
753 - String get todayFaqWatchFaceDelayDescription1 =>  
754 - 'Due to Apple system limits, all watch faces, third-party or official, may have delays from a few minutes to half an hour. Developers cannot control the refresh frequency.'; 648 + String get todayFaqWatchFaceDelayDescription1 => 'Due to Apple system limits, all watch faces, third-party or official, may have delays from a few minutes to half an hour. Developers cannot control the refresh frequency.';
755 649
756 @override 650 @override
757 - String get todayFaqWatchFaceDelayIfOverOneHour =>  
758 - 'If the phone data refreshes but the watch face still has not updated after more than 1 hour:'; 651 + String get todayFaqWatchFaceDelayIfOverOneHour => 'If the phone data refreshes but the watch face still has not updated after more than 1 hour:';
759 652
760 @override 653 @override
761 - String get todayFaqWatchFaceDelayOpenWatchApp =>  
762 - 'Manually open DoubleFeel on Apple Watch and wait about 1 minute.'; 654 + String get todayFaqWatchFaceDelayOpenWatchApp => 'Manually open DoubleFeel on Apple Watch and wait about 1 minute.';
763 655
764 @override 656 @override
765 String get todayFaqWatchFaceDelayIfStill => 'If it still does not update:'; 657 String get todayFaqWatchFaceDelayIfStill => 'If it still does not update:';
766 658
767 @override 659 @override
768 - String get todayFaqWatchFaceDelayRestartApp =>  
769 - 'Close the DoubleFeel background process and restart it.'; 660 + String get todayFaqWatchFaceDelayRestartApp => 'Close the DoubleFeel background process and restart it.';
770 661
771 @override 662 @override
772 - String get todayFaqWatchFaceDelayCheckIntro =>  
773 - 'If it still does not work, check:'; 663 + String get todayFaqWatchFaceDelayCheckIntro => 'If it still does not work, check:';
774 664
775 @override 665 @override
776 - String get todayFaqWatchFaceDelayCheckData =>  
777 - '· Whether both phone and watch apps can show HRV data normally.'; 666 + String get todayFaqWatchFaceDelayCheckData => '· Whether both phone and watch apps can show HRV data normally.';
778 667
779 @override 668 @override
780 - String get todayFaqWatchFaceDelayCheckPhoneHealth =>  
781 - '· Make sure all permissions are enabled on iPhone: iOS Settings > Privacy & Security > Health > DoubleFeel.'; 669 + String get todayFaqWatchFaceDelayCheckPhoneHealth => '· Make sure all permissions are enabled on iPhone: iOS Settings > Privacy & Security > Health > DoubleFeel.';
782 670
783 @override 671 @override
784 - String get todayFaqWatchFaceDelayCheckWatchHealth =>  
785 - '· Make sure all permissions are enabled on Apple Watch: Settings > Health > Data Sources & Access > DoubleFeel.'; 672 + String get todayFaqWatchFaceDelayCheckWatchHealth => '· Make sure all permissions are enabled on Apple Watch: Settings > Health > Data Sources & Access > DoubleFeel.';
786 673
787 @override 674 @override
788 - String get todayFaqWatchFaceDelayCheckBackgroundRefresh =>  
789 - '· Confirm DoubleFeel is enabled in Apple Watch > Settings > General > Background App Refresh.'; 675 + String get todayFaqWatchFaceDelayCheckBackgroundRefresh => '· Confirm DoubleFeel is enabled in Apple Watch > Settings > General > Background App Refresh.';
790 676
791 @override 677 @override
792 - String get todayFaqWatchFaceDelayRestartWatch =>  
793 - '· If it still does not refresh automatically, restart Apple Watch. Long runtimes or high background usage may cause watch face updates to pause.'; 678 + String get todayFaqWatchFaceDelayRestartWatch => '· If it still does not refresh automatically, restart Apple Watch. Long runtimes or high background usage may cause watch face updates to pause.';
794 679
795 @override 680 @override
796 String get todayFaqWatchFaceBlackScreenTitle => 'Watch face turns black?'; 681 String get todayFaqWatchFaceBlackScreenTitle => 'Watch face turns black?';
797 682
798 @override 683 @override
799 - String get todayFaqWatchFaceBlackScreenDescription =>  
800 - 'If the custom interactive watch face turns black after being added and only shows time and date, long-press the watch face, tap Edit, swipe left to Complications, choose DoubleFeel, and add each component again as needed.'; 684 + String get todayFaqWatchFaceBlackScreenDescription => 'If the custom interactive watch face turns black after being added and only shows time and date, long-press the watch face, tap Edit, swipe left to Complications, choose DoubleFeel, and add each component again as needed.';
801 685
802 @override 686 @override
803 String get today => 'Today'; 687 String get today => 'Today';
@@ -815,19 +699,16 @@ class AppLocalizationsEn extends AppLocalizations { @@ -815,19 +699,16 @@ class AppLocalizationsEn extends AppLocalizations {
815 String get allPlans => 'All Plans'; 699 String get allPlans => 'All Plans';
816 700
817 @override 701 @override
818 - String get clickToAddTheHrvThemedWatchFace =>  
819 - 'Click to add the HRV-themed watch face'; 702 + String get clickToAddTheHrvThemedWatchFace => 'Click to add the HRV-themed watch face';
820 703
821 @override 704 @override
822 - String get stayOnTopOfYourHealthFluctuations =>  
823 - 'Stay on top of your health fluctuations'; 705 + String get stayOnTopOfYourHealthFluctuations => 'Stay on top of your health fluctuations';
824 706
825 @override 707 @override
826 String get addACloseContact => 'Add a close contact'; 708 String get addACloseContact => 'Add a close contact';
827 709
828 @override 710 @override
829 - String get oneMorePersonLookingOutForYourHealth =>  
830 - 'One more person looking out for your health'; 711 + String get oneMorePersonLookingOutForYourHealth => 'One more person looking out for your health';
831 712
832 @override 713 @override
833 String get addAFriend => 'Add a friend'; 714 String get addAFriend => 'Add a friend';
@@ -884,8 +765,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -884,8 +765,7 @@ class AppLocalizationsEn extends AppLocalizations {
884 String get questionsAndFeedback => 'Questions and Feedback'; 765 String get questionsAndFeedback => 'Questions and Feedback';
885 766
886 @override 767 @override
887 - String get ifYouWouldLikeUsToReplyPleaseProvideYourEmailAddress =>  
888 - 'If you would like us to reply, please provide your email address'; 768 + String get ifYouWouldLikeUsToReplyPleaseProvideYourEmailAddress => 'If you would like us to reply, please provide your email address';
889 769
890 @override 770 @override
891 String get uploadProof => 'Upload Proof'; 771 String get uploadProof => 'Upload Proof';
@@ -894,8 +774,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -894,8 +774,7 @@ class AppLocalizationsEn extends AppLocalizations {
894 String get frequentlyAskedQuestions => 'Frequently Asked Questions'; 774 String get frequentlyAskedQuestions => 'Frequently Asked Questions';
895 775
896 @override 776 @override
897 - String get areYouSureYouWantToDeleteYourAccount =>  
898 - 'Are you sure you want to delete your account?'; 777 + String get areYouSureYouWantToDeleteYourAccount => 'Are you sure you want to delete your account?';
899 778
900 @override 779 @override
901 String get accountSettings => 'Account Settings'; 780 String get accountSettings => 'Account Settings';
@@ -1286,8 +1165,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1286,8 +1165,7 @@ class AppLocalizationsEn extends AppLocalizations {
1286 String get sleepLowest => 'Lowest'; 1165 String get sleepLowest => 'Lowest';
1287 1166
1288 @override 1167 @override
1289 - String get sleepQualityDescription =>  
1290 - 'DoubleFeel calculates your daily sleep quality score from sleep duration, sleep stages, deep sleep and recovery, nighttime heart rate, and HRV changes.\nThis score helps you understand your recovery and sleep performance more clearly.'; 1168 + String get sleepQualityDescription => 'DoubleFeel calculates your daily sleep quality score from sleep duration, sleep stages, deep sleep and recovery, nighttime heart rate, and HRV changes.\nThis score helps you understand your recovery and sleep performance more clearly.';
1291 1169
1292 @override 1170 @override
1293 String get sleepQualityAttentionRange => '<60 pts'; 1171 String get sleepQualityAttentionRange => '<60 pts';
@@ -1299,8 +1177,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1299,8 +1177,7 @@ class AppLocalizationsEn extends AppLocalizations {
1299 String get sleepQualityExcellentRange => '>85 pts'; 1177 String get sleepQualityExcellentRange => '>85 pts';
1300 1178
1301 @override 1179 @override
1302 - String get friendsAddCloseContactDescription =>  
1303 - 'Add a close contact so someone else can look out for your health'; 1180 + String get friendsAddCloseContactDescription => 'Add a close contact so someone else can look out for your health';
1304 1181
1305 @override 1182 @override
1306 String get friendsLimitReached => 'Friend limit reached'; 1183 String get friendsLimitReached => 'Friend limit reached';
@@ -1402,12 +1279,10 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1402,12 +1279,10 @@ class AppLocalizationsEn extends AppLocalizations {
1402 String get friendsPromptSelfIdTitle => 'You can\'t add yourself'; 1279 String get friendsPromptSelfIdTitle => 'You can\'t add yourself';
1403 1280
1404 @override 1281 @override
1405 - String get friendsPromptIdNotFoundMessage =>  
1406 - 'This ID doesn\'t exist. Check it and try again.'; 1282 + String get friendsPromptIdNotFoundMessage => 'This ID doesn\'t exist. Check it and try again.';
1407 1283
1408 @override 1284 @override
1409 - String get friendsPromptAlreadyFriendMessage =>  
1410 - 'You\'re already close contacts.'; 1285 + String get friendsPromptAlreadyFriendMessage => 'You\'re already close contacts.';
1411 1286
1412 @override 1287 @override
1413 String get friendsPromptSelfIdMessage => 'Enter your close contact\'s ID.'; 1288 String get friendsPromptSelfIdMessage => 'Enter your close contact\'s ID.';
@@ -1427,8 +1302,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1427,8 +1302,7 @@ class AppLocalizationsEn extends AppLocalizations {
1427 } 1302 }
1428 1303
1429 @override 1304 @override
1430 - String get friendsDeleteConfirmMessage =>  
1431 - 'You will no longer be able to view their mood or health status.'; 1305 + String get friendsDeleteConfirmMessage => 'You will no longer be able to view their mood or health status.';
1432 1306
1433 @override 1307 @override
1434 String get friendsDeleteConfirmAction => 'Remove'; 1308 String get friendsDeleteConfirmAction => 'Remove';
@@ -1437,15 +1311,13 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1437,15 +1311,13 @@ class AppLocalizationsEn extends AppLocalizations {
1437 String get privacySettingsTitle => 'Privacy Settings'; 1311 String get privacySettingsTitle => 'Privacy Settings';
1438 1312
1439 @override 1313 @override
1440 - String get privacySettingsDisableAddById =>  
1441 - 'Don\'t allow others to add me by ID'; 1314 + String get privacySettingsDisableAddById => 'Don\'t allow others to add me by ID';
1442 1315
1443 @override 1316 @override
1444 String get premiumActivatedTitle => 'DoubleFeel Pro is now active'; 1317 String get premiumActivatedTitle => 'DoubleFeel Pro is now active';
1445 1318
1446 @override 1319 @override
1447 - String get premiumActivatedDescription =>  
1448 - 'You can now monitor stress, sleep, and HRV in real time, build healthier habits, and share health updates with close contacts so the people who matter can stay informed.'; 1320 + String get premiumActivatedDescription => 'You can now monitor stress, sleep, and HRV in real time, build healthier habits, and share health updates with close contacts so the people who matter can stay informed.';
1449 1321
1450 @override 1322 @override
1451 String get premiumActivatedContinue => 'Continue'; 1323 String get premiumActivatedContinue => 'Continue';
@@ -1490,12 +1362,10 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1490,12 +1362,10 @@ class AppLocalizationsEn extends AppLocalizations {
1490 String get purchaseCurrencySymbol => '¥'; 1362 String get purchaseCurrencySymbol => '¥';
1491 1363
1492 @override 1364 @override
1493 - String get purchaseProductInfoUnavailable =>  
1494 - 'Product information is unavailable. Please try again later.'; 1365 + String get purchaseProductInfoUnavailable => 'Product information is unavailable. Please try again later.';
1495 1366
1496 @override 1367 @override
1497 - String get purchaseOrderInfoUnavailable =>  
1498 - 'Order information is unavailable. Please try again later.'; 1368 + String get purchaseOrderInfoUnavailable => 'Order information is unavailable. Please try again later.';
1499 1369
1500 @override 1370 @override
1501 String purchaseMonthlyUnitPrice(String unitPrice) { 1371 String purchaseMonthlyUnitPrice(String unitPrice) {
@@ -1506,15 +1376,13 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1506,15 +1376,13 @@ class AppLocalizationsEn extends AppLocalizations {
1506 String get purchaseApplePaymentInvalidOrder => 'Invalid UUID format.'; 1376 String get purchaseApplePaymentInvalidOrder => 'Invalid UUID format.';
1507 1377
1508 @override 1378 @override
1509 - String get purchaseApplePaymentProductNotFound =>  
1510 - 'Failed to find product by product ID.'; 1379 + String get purchaseApplePaymentProductNotFound => 'Failed to find product by product ID.';
1511 1380
1512 @override 1381 @override
1513 String get purchaseApplePaymentCancelled => 'The user cancelled the payment.'; 1382 String get purchaseApplePaymentCancelled => 'The user cancelled the payment.';
1514 1383
1515 @override 1384 @override
1516 - String get purchaseApplePaymentVerificationFailed =>  
1517 - 'Payment verification failed.'; 1385 + String get purchaseApplePaymentVerificationFailed => 'Payment verification failed.';
1518 1386
1519 @override 1387 @override
1520 String get purchaseApplePaymentFailed => 'Unknown error.'; 1388 String get purchaseApplePaymentFailed => 'Unknown error.';
@@ -1523,23 +1391,19 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1523,23 +1391,19 @@ class AppLocalizationsEn extends AppLocalizations {
1523 String get purchaseBenefitRealtimeStress => 'Real-time stress monitoring'; 1391 String get purchaseBenefitRealtimeStress => 'Real-time stress monitoring';
1524 1392
1525 @override 1393 @override
1526 - String get purchaseBenefitStressTrends =>  
1527 - 'Weekly, monthly, and yearly stress trends'; 1394 + String get purchaseBenefitStressTrends => 'Weekly, monthly, and yearly stress trends';
1528 1395
1529 @override 1396 @override
1530 - String get purchaseBenefitActivityTrends =>  
1531 - 'Weekly, monthly, and yearly activity trends'; 1397 + String get purchaseBenefitActivityTrends => 'Weekly, monthly, and yearly activity trends';
1532 1398
1533 @override 1399 @override
1534 - String get purchaseBenefitSleepReports =>  
1535 - 'Weekly, monthly, and yearly sleep reports'; 1400 + String get purchaseBenefitSleepReports => 'Weekly, monthly, and yearly sleep reports';
1536 1401
1537 @override 1402 @override
1538 String get purchaseBenefitHealthSync => 'Real-time health data sync'; 1403 String get purchaseBenefitHealthSync => 'Real-time health data sync';
1539 1404
1540 @override 1405 @override
1541 - String get purchaseBenefitContactNotifications =>  
1542 - 'Real-time health updates for close contacts'; 1406 + String get purchaseBenefitContactNotifications => 'Real-time health updates for close contacts';
1543 1407
1544 @override 1408 @override
1545 String get purchaseBenefitCustomWatchFace => 'Exclusive custom watch faces'; 1409 String get purchaseBenefitCustomWatchFace => 'Exclusive custom watch faces';
@@ -1548,23 +1412,19 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1548,23 +1412,19 @@ class AppLocalizationsEn extends AppLocalizations {
1548 String get purchaseBenefitSleepAnalysis => 'Sleep analysis'; 1412 String get purchaseBenefitSleepAnalysis => 'Sleep analysis';
1549 1413
1550 @override 1414 @override
1551 - String get purchaseBenefitFutureFeatures =>  
1552 - 'Free access to future premium features'; 1415 + String get purchaseBenefitFutureFeatures => 'Free access to future premium features';
1553 1416
1554 @override 1417 @override
1555 String get purchaseNotesTitle => 'Notes'; 1418 String get purchaseNotesTitle => 'Notes';
1556 1419
1557 @override 1420 @override
1558 - String get purchaseNoteSubscription =>  
1559 - 'After you confirm and pay, the subscription will renew automatically through your iTunes account. Your Apple account will be charged within 24 hours before the current period ends, and the subscription will renew for another period. To cancel, turn off auto-renewal in your iTunes/Apple ID subscription settings at least 24 hours before the current period ends.\n\nDoubleFeel Pro is a virtual product. Purchases are non-refundable except through the App Store refund process. Tap Learn More for additional information.'; 1421 + String get purchaseNoteSubscription => 'After you confirm and pay, the subscription will renew automatically through your iTunes account. Your Apple account will be charged within 24 hours before the current period ends, and the subscription will renew for another period. To cancel, turn off auto-renewal in your iTunes/Apple ID subscription settings at least 24 hours before the current period ends.\n\nDoubleFeel Pro is a virtual product. Purchases are non-refundable except through the App Store refund process. Tap Learn More for additional information.';
1560 1422
1561 @override 1423 @override
1562 - String get purchaseNoteRestore =>  
1563 - 'If your purchase does not take effect, tap Restore Purchases.'; 1424 + String get purchaseNoteRestore => 'If your purchase does not take effect, tap Restore Purchases.';
1564 1425
1565 @override 1426 @override
1566 - String get purchaseNoteContact =>  
1567 - 'Contact us if you have any other questions.'; 1427 + String get purchaseNoteContact => 'Contact us if you have any other questions.';
1568 1428
1569 @override 1429 @override
1570 String get reportBottomSlogan => 'FEEL MORE, STRESS LESS'; 1430 String get reportBottomSlogan => 'FEEL MORE, STRESS LESS';
@@ -1573,114 +1433,91 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1573,114 +1433,91 @@ class AppLocalizationsEn extends AppLocalizations {
1573 String get refundExplanationTitle => 'Refund Information'; 1433 String get refundExplanationTitle => 'Refund Information';
1574 1434
1575 @override 1435 @override
1576 - String get refundAppStoreReviewTitle =>  
1577 - 'Refunds are reviewed by the App Store'; 1436 + String get refundAppStoreReviewTitle => 'Refunds are reviewed by the App Store';
1578 1437
1579 @override 1438 @override
1580 - String get refundAppStoreReviewDescription =>  
1581 - 'All subscriptions and virtual products are purchased through the official App Store payment system. DoubleFeel cannot directly process payments or refunds.'; 1439 + String get refundAppStoreReviewDescription => 'All subscriptions and virtual products are purchased through the official App Store payment system. DoubleFeel cannot directly process payments or refunds.';
1582 1440
1583 @override 1441 @override
1584 String get refundAppleRulesIntroduction => 'Under Apple\'s platform rules:'; 1442 String get refundAppleRulesIntroduction => 'Under Apple\'s platform rules:';
1585 1443
1586 @override 1444 @override
1587 - String get refundAppleCollectsPayments =>  
1588 - ' · All payments are collected by the App Store'; 1445 + String get refundAppleCollectsPayments => ' · All payments are collected by the App Store';
1589 1446
1590 @override 1447 @override
1591 - String get refundAppleReviewsRequests =>  
1592 - ' · All refund requests are reviewed by Apple'; 1448 + String get refundAppleReviewsRequests => ' · All refund requests are reviewed by Apple';
1593 1449
1594 @override 1450 @override
1595 - String get refundDeveloperCannotSubmit =>  
1596 - ' · Developers cannot submit requests for users'; 1451 + String get refundDeveloperCannotSubmit => ' · Developers cannot submit requests for users';
1597 1452
1598 @override 1453 @override
1599 - String get refundDeveloperCannotIntervene =>  
1600 - ' · Developers cannot influence Apple\'s decision'; 1454 + String get refundDeveloperCannotIntervene => ' · Developers cannot influence Apple\'s decision';
1601 1455
1602 @override 1456 @override
1603 - String get refundAppStoreFinalDecision =>  
1604 - 'Your refund request will therefore be decided by the App Store.'; 1457 + String get refundAppStoreFinalDecision => 'Your refund request will therefore be decided by the App Store.';
1605 1458
1606 @override 1459 @override
1607 String get refundMayBeRejectedTitle => 'The App Store may reject a refund'; 1460 String get refundMayBeRejectedTitle => 'The App Store may reject a refund';
1608 1461
1609 @override 1462 @override
1610 - String get refundNoUnconditionalRefunds =>  
1611 - 'Apple\'s refund policy does not provide unconditional refunds in every situation.'; 1463 + String get refundNoUnconditionalRefunds => 'Apple\'s refund policy does not provide unconditional refunds in every situation.';
1612 1464
1613 @override 1465 @override
1614 - String get refundAppleTermsDescription =>  
1615 - 'By using the App Store, you agree to Apple\'s terms of service and refund rules. https://www.apple.com/legal/internet-services/itunes/'; 1466 + String get refundAppleTermsDescription => 'By using the App Store, you agree to Apple\'s terms of service and refund rules. https://www.apple.com/legal/internet-services/itunes/';
1616 1467
1617 @override 1468 @override
1618 - String get refundAppleReviewsCircumstances =>  
1619 - 'Apple reviews the order, account history, and actual usage when deciding whether to approve a refund.'; 1469 + String get refundAppleReviewsCircumstances => 'Apple reviews the order, account history, and actual usage when deciding whether to approve a refund.';
1620 1470
1621 @override 1471 @override
1622 String get refundRejectionReasonsTitle => 'Why might a refund be rejected?'; 1472 String get refundRejectionReasonsTitle => 'Why might a refund be rejected?';
1623 1473
1624 @override 1474 @override
1625 - String get refundRejectionReasonsIntroduction =>  
1626 - 'The App Store may reject a request for reasons including, but not limited to:'; 1475 + String get refundRejectionReasonsIntroduction => 'The App Store may reject a request for reasons including, but not limited to:';
1627 1476
1628 @override 1477 @override
1629 - String get refundReasonPurchaseTooOld =>  
1630 - ' · Too much time has passed since purchase'; 1478 + String get refundReasonPurchaseTooOld => ' · Too much time has passed since purchase';
1631 1479
1632 @override 1480 @override
1633 - String get refundReasonFrequentRequests =>  
1634 - ' · Frequent requests from the same account'; 1481 + String get refundReasonFrequentRequests => ' · Frequent requests from the same account';
1635 1482
1636 @override 1483 @override
1637 - String get refundReasonAbnormalHistory =>  
1638 - ' · A history of unusual refund activity'; 1484 + String get refundReasonAbnormalHistory => ' · A history of unusual refund activity';
1639 1485
1640 @override 1486 @override
1641 String get refundReasonInsufficient => ' · An insufficient refund reason'; 1487 String get refundReasonInsufficient => ' · An insufficient refund reason';
1642 1488
1643 @override 1489 @override
1644 - String get refundReasonLongTermUse =>  
1645 - ' · Extended normal use of membership features'; 1490 + String get refundReasonLongTermUse => ' · Extended normal use of membership features';
1646 1491
1647 @override 1492 @override
1648 - String get refundReasonPriceChange =>  
1649 - ' · Promotions, discounts, or price changes'; 1493 + String get refundReasonPriceChange => ' · Promotions, discounts, or price changes';
1650 1494
1651 @override 1495 @override
1652 - String get refundReasonNoReceipt =>  
1653 - ' · No valid order receipt can be provided'; 1496 + String get refundReasonNoReceipt => ' · No valid order receipt can be provided';
1654 1497
1655 @override 1498 @override
1656 - String get refundOfficialDecision =>  
1657 - 'The App Store\'s final decision applies.'; 1499 + String get refundOfficialDecision => 'The App Store\'s final decision applies.';
1658 1500
1659 @override 1501 @override
1660 String get refundRejectedNextStepsTitle => 'What if my request is rejected?'; 1502 String get refundRejectedNextStepsTitle => 'What if my request is rejected?';
1661 1503
1662 @override 1504 @override
1663 - String get refundTryAgain =>  
1664 - 'If your refund request is rejected, you can try submitting it to the App Store again.'; 1505 + String get refundTryAgain => 'If your refund request is rejected, you can try submitting it to the App Store again.';
1665 1506
1666 @override 1507 @override
1667 - String get refundFinalReview =>  
1668 - 'If it is rejected again, the App Store has completed its final review. Neither DoubleFeel nor Apple Support can change the result.'; 1508 + String get refundFinalReview => 'If it is rejected again, the App Store has completed its final review. Neither DoubleFeel nor Apple Support can change the result.';
1669 1509
1670 @override 1510 @override
1671 - String get refundNoAlternativeChannel =>  
1672 - 'DoubleFeel cannot process refund requests outside the App Store system.'; 1511 + String get refundNoAlternativeChannel => 'DoubleFeel cannot process refund requests outside the App Store system.';
1673 1512
1674 @override 1513 @override
1675 - String get refundMembershipCancellation =>  
1676 - 'After a successful refund, your DoubleFeel Pro benefits will also be canceled.'; 1514 + String get refundMembershipCancellation => 'After a successful refund, your DoubleFeel Pro benefits will also be canceled.';
1677 1515
1678 @override 1516 @override
1679 String get refundHelpTitle => 'Need help?'; 1517 String get refundHelpTitle => 'Need help?';
1680 1518
1681 @override 1519 @override
1682 - String get refundHelpDescription =>  
1683 - 'If you have questions about refunds or experience payment errors, duplicate charges, or a missing order, contact DoubleFeel Support and we will do our best to assist.'; 1520 + String get refundHelpDescription => 'If you have questions about refunds or experience payment errors, duplicate charges, or a missing order, contact DoubleFeel Support and we will do our best to assist.';
1684 1521
1685 @override 1522 @override
1686 String get refundFaqTitle => 'DoubleFeel FAQs'; 1523 String get refundFaqTitle => 'DoubleFeel FAQs';
@@ -1689,8 +1526,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1689,8 +1526,7 @@ class AppLocalizationsEn extends AppLocalizations {
1689 String get appReviewPromptTitle => 'Enjoying DoubleFeel?'; 1526 String get appReviewPromptTitle => 'Enjoying DoubleFeel?';
1690 1527
1691 @override 1528 @override
1692 - String get appReviewPromptMessage =>  
1693 - 'Hi! Is DoubleFeel helping you better understand\nyour stress and sleep? 💜'; 1529 + String get appReviewPromptMessage => 'Hi! Is DoubleFeel helping you better understand\nyour stress and sleep? 💜';
1694 1530
1695 @override 1531 @override
1696 String get appReviewPromptLikeAction => '😍 Love it'; 1532 String get appReviewPromptLikeAction => '😍 Love it';
@@ -1699,12 +1535,10 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1699,12 +1535,10 @@ class AppLocalizationsEn extends AppLocalizations {
1699 String get appReviewPromptFeedbackAction => 'I have feedback'; 1535 String get appReviewPromptFeedbackAction => 'I have feedback';
1700 1536
1701 @override 1537 @override
1702 - String get appReviewFeedbackTitle =>  
1703 - 'We\'re sorry DoubleFeel didn\'t give you\na good experience'; 1538 + String get appReviewFeedbackTitle => 'We\'re sorry DoubleFeel didn\'t give you\na good experience';
1704 1539
1705 @override 1540 @override
1706 - String get appReviewFeedbackMessage =>  
1707 - 'Would you tell us what went wrong?\nYour feedback helps us improve the stress and health experience. 💜'; 1541 + String get appReviewFeedbackMessage => 'Would you tell us what went wrong?\nYour feedback helps us improve the stress and health experience. 💜';
1708 1542
1709 @override 1543 @override
1710 String get appReviewFeedbackSendAction => 'Send Feedback'; 1544 String get appReviewFeedbackSendAction => 'Send Feedback';
1 -// ignore: unused_import  
2 -import 'package:intl/intl.dart' as intl;  
3 import 'app_localizations.dart'; 1 import 'app_localizations.dart';
4 2
5 // ignore_for_file: type=lint 3 // ignore_for_file: type=lint
@@ -72,8 +70,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -72,8 +70,7 @@ class AppLocalizationsZh extends AppLocalizations {
72 String get onboardingIntroTitle => 'DoubleFeel 是专为 Apple Watch 打造的健康陪伴app'; 70 String get onboardingIntroTitle => 'DoubleFeel 是专为 Apple Watch 打造的健康陪伴app';
73 71
74 @override 72 @override
75 - String get onboardingIntroBody =>  
76 - '我们希望可以帮助你\n<em>关注自己的身心变化,也让爱你的人</em>及时发现你的<em>疲惫与需要</em>'; 73 + String get onboardingIntroBody => '我们希望可以帮助你\n<em>关注自己的身心变化,也让爱你的人</em>及时发现你的<em>疲惫与需要</em>';
77 74
78 @override 75 @override
79 String get onboardingStateQuestion => '请问以下哪些描述,经常发生在你身上?'; 76 String get onboardingStateQuestion => '请问以下哪些描述,经常发生在你身上?';
@@ -163,8 +160,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -163,8 +160,7 @@ class AppLocalizationsZh extends AppLocalizations {
163 String get onboardingHrvSubtitle => '它能帮助我们衡量整体的压力和健康状态'; 160 String get onboardingHrvSubtitle => '它能帮助我们衡量整体的压力和健康状态';
164 161
165 @override 162 @override
166 - String get onboardingHrvDescription =>  
167 - '心率变异性(HRV, Heart Rate Variability)即心跳之间间隔时间的微小变化,反映了自主神经系统活动和身体对压力的反应能力'; 163 + String get onboardingHrvDescription => '心率变异性(HRV, Heart Rate Variability)即心跳之间间隔时间的微小变化,反映了自主神经系统活动和身体对压力的反应能力';
168 164
169 @override 165 @override
170 String get onboardingTellMeMore => '展开说说'; 166 String get onboardingTellMeMore => '展开说说';
@@ -188,12 +184,10 @@ class AppLocalizationsZh extends AppLocalizations { @@ -188,12 +184,10 @@ class AppLocalizationsZh extends AppLocalizations {
188 String get onboardingHealthPermissionTitle => '开启健康授权提醒、统计你的压力'; 184 String get onboardingHealthPermissionTitle => '开启健康授权提醒、统计你的压力';
189 185
190 @override 186 @override
191 - String get onboardingHealthPermissionBody =>  
192 - 'DoubleFeel需要连接健康穿戴设备数据,以提醒、统计压力时刻、提供建议。'; 187 + String get onboardingHealthPermissionBody => 'DoubleFeel需要连接健康穿戴设备数据,以提醒、统计压力时刻、提供建议。';
193 188
194 @override 189 @override
195 - String get onboardingHealthPermissionPrivacy =>  
196 - '请放心,你的健康数据仅储存在本地,我们不上传任何相关数据。'; 190 + String get onboardingHealthPermissionPrivacy => '请放心,你的健康数据仅储存在本地,我们不上传任何相关数据。';
197 191
198 @override 192 @override
199 String get onboardingNotificationTitle => '开启通知'; 193 String get onboardingNotificationTitle => '开启通知';
@@ -202,8 +196,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -202,8 +196,7 @@ class AppLocalizationsZh extends AppLocalizations {
202 String get onboardingNotificationSubtitle => '及时了解身体每一次异动'; 196 String get onboardingNotificationSubtitle => '及时了解身体每一次异动';
203 197
204 @override 198 @override
205 - String get onboardingNotificationBody =>  
206 - 'AppleWatch数据更新后会及时提醒你,帮助你及时行动,改善压力状态'; 199 + String get onboardingNotificationBody => 'AppleWatch数据更新后会及时提醒你,帮助你及时行动,改善压力状态';
207 200
208 @override 201 @override
209 String get onboardingMemberTitle => '获得年度会员优惠'; 202 String get onboardingMemberTitle => '获得年度会员优惠';
@@ -227,9 +220,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -227,9 +220,7 @@ class AppLocalizationsZh extends AppLocalizations {
227 String get healthCompanionIsNowAvailable => '健康陪伴已开启'; 220 String get healthCompanionIsNowAvailable => '健康陪伴已开启';
228 221
229 @override 222 @override
230 - String  
231 - get youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired =>  
232 - '你们现在可以查看彼此的 HRV、压力与睡眠变化,并在对方疲惫时及时送上关心。'; 223 + String get youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired => '你们现在可以查看彼此的 HRV、压力与睡眠变化,并在对方疲惫时及时送上关心。';
233 224
234 @override 225 @override
235 String get bindPartnerTitle => '添加亲密联系人\n多一个人关注你的健康'; 226 String get bindPartnerTitle => '添加亲密联系人\n多一个人关注你的健康';
@@ -342,8 +333,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -342,8 +333,7 @@ class AppLocalizationsZh extends AppLocalizations {
342 String get todayHealthDataAuthTitle => '无法获取心率健康数据'; 333 String get todayHealthDataAuthTitle => '无法获取心率健康数据';
343 334
344 @override 335 @override
345 - String get todayHealthDataAuthDescription =>  
346 - 'DoubleFeel 需要授权访问你的健康数据,才能提供压力提醒、实时压力统计和健康建议;否则应用功能可能无法正常使用。请放心,你的健康数据仅存储在本地,不会上传到任何服务器。'; 336 + String get todayHealthDataAuthDescription => 'DoubleFeel 需要授权访问你的健康数据,才能提供压力提醒、实时压力统计和健康建议;否则应用功能可能无法正常使用。请放心,你的健康数据仅存储在本地,不会上传到任何服务器。';
347 337
348 @override 338 @override
349 String get todayHealthDataAuthAction => '授权访问健康数据'; 339 String get todayHealthDataAuthAction => '授权访问健康数据';
@@ -370,8 +360,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -370,8 +360,7 @@ class AppLocalizationsZh extends AppLocalizations {
370 String get todayFaqLinkWatchNoStatusNotification => '手表为什么无法收到状态通知?'; 360 String get todayFaqLinkWatchNoStatusNotification => '手表为什么无法收到状态通知?';
371 361
372 @override 362 @override
373 - String get todayFaqLinkWatchNoStatusAndInteractionNotification =>  
374 - '手表为什么无法收到状态和互动通知?'; 363 + String get todayFaqLinkWatchNoStatusAndInteractionNotification => '手表为什么无法收到状态和互动通知?';
375 364
376 @override 365 @override
377 String get todayFaqLinkWatchFaceDataDelay => '手表表盘数据不更新或者有延迟?'; 366 String get todayFaqLinkWatchFaceDataDelay => '手表表盘数据不更新或者有延迟?';
@@ -404,27 +393,22 @@ class AppLocalizationsZh extends AppLocalizations { @@ -404,27 +393,22 @@ class AppLocalizationsZh extends AppLocalizations {
404 String get todayStressStatusInsufficientData => '数据不足'; 393 String get todayStressStatusInsufficientData => '数据不足';
405 394
406 @override 395 @override
407 - String get todayStressStatusOverloadDescription =>  
408 - '当前 HRV 明显低于你的长期平均水平,可能意味着身体疲劳、压力过高或恢复不足。建议及时休息。'; 396 + String get todayStressStatusOverloadDescription => '当前 HRV 明显低于你的长期平均水平,可能意味着身体疲劳、压力过高或恢复不足。建议及时休息。';
409 397
410 @override 398 @override
411 - String get todayStressStatusCautionDescription =>  
412 - '当前 HRV 低于正常范围,身体可能正在积累压力,需要注意作息与恢复。'; 399 + String get todayStressStatusCautionDescription => '当前 HRV 低于正常范围,身体可能正在积累压力,需要注意作息与恢复。';
413 400
414 @override 401 @override
415 String get todayStressStatusNormalDescription => '当前身体状态处于你的正常波动范围内。'; 402 String get todayStressStatusNormalDescription => '当前身体状态处于你的正常波动范围内。';
416 403
417 @override 404 @override
418 - String get todayStressStatusExcellentDescription =>  
419 - '当前 HRV 高于近期平均水平,代表身体恢复与整体状态较好。'; 405 + String get todayStressStatusExcellentDescription => '当前 HRV 高于近期平均水平,代表身体恢复与整体状态较好。';
420 406
421 @override 407 @override
422 - String get todayStressStatusInsufficientDataDescription =>  
423 - '当前可用数据不足,暂时无法准确判断压力状态。'; 408 + String get todayStressStatusInsufficientDataDescription => '当前可用数据不足,暂时无法准确判断压力状态。';
424 409
425 @override 410 @override
426 - String get todayHrvMeasurementIntro =>  
427 - 'AppleWatch默认每2-5小时测量一次HRV,如果你希望立即手动进行测量,可以参考以下方法:'; 411 + String get todayHrvMeasurementIntro => 'AppleWatch默认每2-5小时测量一次HRV,如果你希望立即手动进行测量,可以参考以下方法:';
428 412
429 @override 413 @override
430 String get todayHrvMeasurementStep1 => '1、戴紧AppleWatch,坐下来,保持心境平和'; 414 String get todayHrvMeasurementStep1 => '1、戴紧AppleWatch,坐下来,保持心境平和';
@@ -442,8 +426,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -442,8 +426,7 @@ class AppLocalizationsZh extends AppLocalizations {
442 String get todayHrvMeasurementStep5 => '5、等待一分钟左右,StressWatch会收到你的数据并展示'; 426 String get todayHrvMeasurementStep5 => '5、等待一分钟左右,StressWatch会收到你的数据并展示';
443 427
444 @override 428 @override
445 - String get todayHrvMeasurementHint =>  
446 - '提示:数据源来自AppleWatch,在测量之后可能存在延迟或是数据未能同步的情况。如若出现上述情况,请重新测量并等待数据读取。'; 429 + String get todayHrvMeasurementHint => '提示:数据源来自AppleWatch,在测量之后可能存在延迟或是数据未能同步的情况。如若出现上述情况,请重新测量并等待数据读取。';
447 430
448 @override 431 @override
449 String get todayHrvMeasurementWarning => '注意:需打开健康里的权限,同时关闭省电模式。'; 432 String get todayHrvMeasurementWarning => '注意:需打开健康里的权限,同时关闭省电模式。';
@@ -452,12 +435,10 @@ class AppLocalizationsZh extends AppLocalizations { @@ -452,12 +435,10 @@ class AppLocalizationsZh extends AppLocalizations {
452 String get todayStressStatusWhatTitle => '什么是综合压力状态?'; 435 String get todayStressStatusWhatTitle => '什么是综合压力状态?';
453 436
454 @override 437 @override
455 - String get todayStressStatusWhatDescription1 =>  
456 - 'DoubleFeel 会结合你过去 30 天的 HRV(心率变异性)、静息心率以及当天的身体状态变化,综合评估你的整体压力水平。'; 438 + String get todayStressStatusWhatDescription1 => 'DoubleFeel 会结合你过去 30 天的 HRV(心率变异性)、静息心率以及当天的身体状态变化,综合评估你的整体压力水平。';
457 439
458 @override 440 @override
459 - String get todayStressStatusWhatDescription2 =>  
460 - '由于 HRV 会随着情绪、运动、睡眠和疲劳不断波动,单次数据参考意义有限,因此我们更建议关注一整天的综合压力状态,让结果更稳定、更有参考价值。综合压力不仅能帮助你了解自己的身体状态,也能让亲密联系人更及时地关注你的变化。'; 441 + String get todayStressStatusWhatDescription2 => '由于 HRV 会随着情绪、运动、睡眠和疲劳不断波动,单次数据参考意义有限,因此我们更建议关注一整天的综合压力状态,让结果更稳定、更有参考价值。综合压力不仅能帮助你了解自己的身体状态,也能让亲密联系人更及时地关注你的变化。';
461 442
462 @override 443 @override
463 String get todayStressStatusWhyHrvTitle => '为什么要参考 HRV(心率变异性)?'; 444 String get todayStressStatusWhyHrvTitle => '为什么要参考 HRV(心率变异性)?';
@@ -478,27 +459,22 @@ class AppLocalizationsZh extends AppLocalizations { @@ -478,27 +459,22 @@ class AppLocalizationsZh extends AppLocalizations {
478 String get todayStressStatusHrvChangesFast => '· HRV 变化较快,更适合观察短时间内的身体状态变化。'; 459 String get todayStressStatusHrvChangesFast => '· HRV 变化较快,更适合观察短时间内的身体状态变化。';
479 460
480 @override 461 @override
481 - String get todayStressStatusAppWatchDifferenceTitle =>  
482 - '手机 App 与 Apple Watch 显示的压力状态有什么区别?'; 462 + String get todayStressStatusAppWatchDifferenceTitle => '手机 App 与 Apple Watch 显示的压力状态有什么区别?';
483 463
484 @override 464 @override
485 - String get todayStressStatusAppWatchDifferenceApp =>  
486 - '手机 App 首页显示的是当天的综合压力状态,会综合分析 HRV、静息心率与整体趋势。'; 465 + String get todayStressStatusAppWatchDifferenceApp => '手机 App 首页显示的是当天的综合压力状态,会综合分析 HRV、静息心率与整体趋势。';
487 466
488 @override 467 @override
489 - String get todayStressStatusAppWatchDifferenceWatch =>  
490 - 'Apple Watch 显示的是最近一次的实时压力状态,更适合快速查看当前身体变化。'; 468 + String get todayStressStatusAppWatchDifferenceWatch => 'Apple Watch 显示的是最近一次的实时压力状态,更适合快速查看当前身体变化。';
491 469
492 @override 470 @override
493 String get todayStressStatusWaitingDataTitle => '为什么会出现“等待数据”?'; 471 String get todayStressStatusWaitingDataTitle => '为什么会出现“等待数据”?';
494 472
495 @override 473 @override
496 - String get todayStressStatusWaitingDataDescription1 =>  
497 - '“等待数据”代表当前采集到的数据量不足,暂时无法生成可靠的压力评估。'; 474 + String get todayStressStatusWaitingDataDescription1 => '“等待数据”代表当前采集到的数据量不足,暂时无法生成可靠的压力评估。';
498 475
499 @override 476 @override
500 - String get todayStressStatusWaitingDataDescription2 =>  
501 - '请继续佩戴 Apple Watch,等待系统自动采集数据。'; 477 + String get todayStressStatusWaitingDataDescription2 => '请继续佩戴 Apple Watch,等待系统自动采集数据。';
502 478
503 @override 479 @override
504 String get todayStressStatusWaitingDataReasonsIntro => '可能原因包括:'; 480 String get todayStressStatusWaitingDataReasonsIntro => '可能原因包括:';
@@ -519,35 +495,28 @@ class AppLocalizationsZh extends AppLocalizations { @@ -519,35 +495,28 @@ class AppLocalizationsZh extends AppLocalizations {
519 String get todayHrvPrincipleHowMeasureTitle => 'DoubleFeel 如何测量压力状态?'; 495 String get todayHrvPrincipleHowMeasureTitle => 'DoubleFeel 如何测量压力状态?';
520 496
521 @override 497 @override
522 - String get todayHrvPrincipleHowMeasureDescription1 =>  
523 - '当你正常佩戴 Apple Watch 时,系统会自动采集你的心率数据,并同步至 Apple Health。'; 498 + String get todayHrvPrincipleHowMeasureDescription1 => '当你正常佩戴 Apple Watch 时,系统会自动采集你的心率数据,并同步至 Apple Health。';
524 499
525 @override 500 @override
526 - String get todayHrvPrincipleHowMeasureDescription2 =>  
527 - 'DoubleFeel 会基于这些数据计算 HRV(心率变异性)相关指标,用于评估你的身体压力与恢复状态。'; 501 + String get todayHrvPrincipleHowMeasureDescription2 => 'DoubleFeel 会基于这些数据计算 HRV(心率变异性)相关指标,用于评估你的身体压力与恢复状态。';
528 502
529 @override 503 @override
530 - String get todayHrvPrincipleHowMeasureDescription3 =>  
531 - 'HRV 对压力、疲劳、睡眠、情绪与身体恢复都非常敏感,因此它能够帮助我们更早发现身体状态变化。'; 504 + String get todayHrvPrincipleHowMeasureDescription3 => 'HRV 对压力、疲劳、睡眠、情绪与身体恢复都非常敏感,因此它能够帮助我们更早发现身体状态变化。';
532 505
533 @override 506 @override
534 - String get todayHrvPrincipleHowMeasureDescription4 =>  
535 - '为了让结果更准确,DoubleFeel 会将你当前的 HRV 状态与过去 30 天的个人平均水平进行对比,而不是直接与其他人比较。'; 507 + String get todayHrvPrincipleHowMeasureDescription4 => '为了让结果更准确,DoubleFeel 会将你当前的 HRV 状态与过去 30 天的个人平均水平进行对比,而不是直接与其他人比较。';
536 508
537 @override 509 @override
538 String get todayRealtimeStressWhatTitle => '什么是实时压力?'; 510 String get todayRealtimeStressWhatTitle => '什么是实时压力?';
539 511
540 @override 512 @override
541 - String get todayRealtimeStressWhatDescription1 =>  
542 - '实时压力是 DoubleFeel 根据你当前的 HRV、心率状态与个人历史数据变化,动态生成的身体压力指标。'; 513 + String get todayRealtimeStressWhatDescription1 => '实时压力是 DoubleFeel 根据你当前的 HRV、心率状态与个人历史数据变化,动态生成的身体压力指标。';
543 514
544 @override 515 @override
545 - String get todayRealtimeStressWhatDescription2 =>  
546 - '压力值越高,代表你的身体状态相比平时偏离越明显,可能正处于疲劳、恢复不足或高压力状态。'; 516 + String get todayRealtimeStressWhatDescription2 => '压力值越高,代表你的身体状态相比平时偏离越明显,可能正处于疲劳、恢复不足或高压力状态。';
547 517
548 @override 518 @override
549 - String get todayRealtimeStressWhatDescription3 =>  
550 - '它能够帮助你更快发现身体变化,并及时调整休息、运动与生活节奏。'; 519 + String get todayRealtimeStressWhatDescription3 => '它能够帮助你更快发现身体变化,并及时调整休息、运动与生活节奏。';
551 520
552 @override 521 @override
553 String get todayRealtimeStressDivisionTitle => '实时压力如何划分?'; 522 String get todayRealtimeStressDivisionTitle => '实时压力如何划分?';
@@ -577,12 +546,10 @@ class AppLocalizationsZh extends AppLocalizations { @@ -577,12 +546,10 @@ class AppLocalizationsZh extends AppLocalizations {
577 String get todayRealtimeStressCautionDescription => '身体可能正在积累压力,需要适当休息与恢复。'; 546 String get todayRealtimeStressCautionDescription => '身体可能正在积累压力,需要适当休息与恢复。';
578 547
579 @override 548 @override
580 - String get todayRealtimeStressOverloadDescription =>  
581 - '身体压力明显偏高,建议减少负荷、注意睡眠与恢复。'; 549 + String get todayRealtimeStressOverloadDescription => '身体压力明显偏高,建议减少负荷、注意睡眠与恢复。';
582 550
583 @override 551 @override
584 - String get todayRealtimeStressDivisionBaseline =>  
585 - '以上区间会结合你的个人基线动态调整,不同用户之间并不直接比较。'; 552 + String get todayRealtimeStressDivisionBaseline => '以上区间会结合你的个人基线动态调整,不同用户之间并不直接比较。';
586 553
587 @override 554 @override
588 String get todayRealtimeStressDivisionAwake => '此外,实时压力主要反映清醒状态下的身体压力变化。'; 555 String get todayRealtimeStressDivisionAwake => '此外,实时压力主要反映清醒状态下的身体压力变化。';
@@ -597,31 +564,25 @@ class AppLocalizationsZh extends AppLocalizations { @@ -597,31 +564,25 @@ class AppLocalizationsZh extends AppLocalizations {
597 String get todayRealtimeStressLowBetterType => '身体压力分为“正常压力”与“异常压力”。'; 564 String get todayRealtimeStressLowBetterType => '身体压力分为“正常压力”与“异常压力”。';
598 565
599 @override 566 @override
600 - String get todayRealtimeStressLowBetterExample =>  
601 - '例如:运动期间或运动后,实时压力短时间升高属于正常恢复反应;工作专注、情绪兴奋时,压力也可能暂时升高,这些都属于正常的身体调节。'; 567 + String get todayRealtimeStressLowBetterExample => '例如:运动期间或运动后,实时压力短时间升高属于正常恢复反应;工作专注、情绪兴奋时,压力也可能暂时升高,这些都属于正常的身体调节。';
602 568
603 @override 569 @override
604 - String get todayRealtimeStressLowBetterHighStress =>  
605 - '但如果在静息、久坐或睡眠不足的情况下,压力长期偏高,则可能意味着身体疲劳、心理压力较大、睡眠恢复不足、运动恢复不充分、摄入过多咖啡因、酒精或刺激物、身体可能处于不适状态。'; 570 + String get todayRealtimeStressLowBetterHighStress => '但如果在静息、久坐或睡眠不足的情况下,压力长期偏高,则可能意味着身体疲劳、心理压力较大、睡眠恢复不足、运动恢复不充分、摄入过多咖啡因、酒精或刺激物、身体可能处于不适状态。';
606 571
607 @override 572 @override
608 - String get todayRealtimeStressLowBetterTrend =>  
609 - 'DoubleFeel 更关注的是你的长期变化趋势,而不是单次波动。'; 573 + String get todayRealtimeStressLowBetterTrend => 'DoubleFeel 更关注的是你的长期变化趋势,而不是单次波动。';
610 574
611 @override 575 @override
612 String get todayRealtimeStressScenarioTitle => 'HRV 与实时压力适用场景?'; 576 String get todayRealtimeStressScenarioTitle => 'HRV 与实时压力适用场景?';
613 577
614 @override 578 @override
615 - String get todayRealtimeStressScenarioHrvDefault =>  
616 - '在 Apple Watch 的默认设置下,HRV 每 2~5 小时更新一次。'; 579 + String get todayRealtimeStressScenarioHrvDefault => '在 Apple Watch 的默认设置下,HRV 每 2~5 小时更新一次。';
617 580
618 @override 581 @override
619 - String get todayRealtimeStressScenarioRegionLimit =>  
620 - '在部分地区,由于 Apple Watch 的呼吸功能受限,HRV 的更新频率可能会受到影响,并且开启呼吸功能后也会消耗更多电量。'; 582 + String get todayRealtimeStressScenarioRegionLimit => '在部分地区,由于 Apple Watch 的呼吸功能受限,HRV 的更新频率可能会受到影响,并且开启呼吸功能后也会消耗更多电量。';
621 583
622 @override 584 @override
623 - String get todayRealtimeStressScenarioIntro =>  
624 - '为了解决 HRV 更新间隔较长的问题,DoubleFeel 设计了实时压力功能:'; 585 + String get todayRealtimeStressScenarioIntro => '为了解决 HRV 更新间隔较长的问题,DoubleFeel 设计了实时压力功能:';
625 586
626 @override 587 @override
627 String get todayRealtimeStressScenarioUpdateEvery6Min => '· 实时压力每 6 分钟更新一次'; 588 String get todayRealtimeStressScenarioUpdateEvery6Min => '· 实时压力每 6 分钟更新一次';
@@ -630,27 +591,22 @@ class AppLocalizationsZh extends AppLocalizations { @@ -630,27 +591,22 @@ class AppLocalizationsZh extends AppLocalizations {
630 String get todayRealtimeStressScenarioTimely => '· 可以更及时地反映身体状态变化'; 591 String get todayRealtimeStressScenarioTimely => '· 可以更及时地反映身体状态变化';
631 592
632 @override 593 @override
633 - String get todayRealtimeStressScenarioConsistentTrend =>  
634 - '· 在大多数情况下,实时压力趋势与 HRV 趋势是一致的'; 594 + String get todayRealtimeStressScenarioConsistentTrend => '· 在大多数情况下,实时压力趋势与 HRV 趋势是一致的';
635 595
636 @override 596 @override
637 - String get todayRealtimeStressScenarioSummary =>  
638 - '这样用户既能获得 HRV 的长期趋势,也能通过实时压力获得短时身体状态的参考。'; 597 + String get todayRealtimeStressScenarioSummary => '这样用户既能获得 HRV 的长期趋势,也能通过实时压力获得短时身体状态的参考。';
639 598
640 @override 599 @override
641 String get todayFaqNoDataTitle => 'APP或表盘有没有数据怎么办?'; 600 String get todayFaqNoDataTitle => 'APP或表盘有没有数据怎么办?';
642 601
643 @override 602 @override
644 - String get todayFaqNoDataDescription1 =>  
645 - '1. 确认苹果手表系统在10.0以上,手机系统在14以上,系统版本可在「关于本机」内查看。'; 603 + String get todayFaqNoDataDescription1 => '1. 确认苹果手表系统在10.0以上,手机系统在14以上,系统版本可在「关于本机」内查看。';
646 604
647 @override 605 @override
648 - String get todayFaqNoDataDescription2 =>  
649 - '2. 确认是否开启所有权限:手机「健康」-「共享」-「app」-「DoubleFeel」-「打开所有权限」。'; 606 + String get todayFaqNoDataDescription2 => '2. 确认是否开启所有权限:手机「健康」-「共享」-「app」-「DoubleFeel」-「打开所有权限」。';
650 607
651 @override 608 @override
652 - String get todayFaqNoDataDescription3 =>  
653 - '3. 确认设备是否处于省电模式、低电量状态或手表佩戴未贴紧,以上情况会影响手表数据采集。'; 609 + String get todayFaqNoDataDescription3 => '3. 确认设备是否处于省电模式、低电量状态或手表佩戴未贴紧,以上情况会影响手表数据采集。';
654 610
655 @override 611 @override
656 String get todayFaqContactPrefix => '如以上均检查无问题,可以'; 612 String get todayFaqContactPrefix => '如以上均检查无问题,可以';
@@ -665,46 +621,37 @@ class AppLocalizationsZh extends AppLocalizations { @@ -665,46 +621,37 @@ class AppLocalizationsZh extends AppLocalizations {
665 String get todayFaqWatchNoNotificationTitle => '手表无法收到状态通知?'; 621 String get todayFaqWatchNoNotificationTitle => '手表无法收到状态通知?';
666 622
667 @override 623 @override
668 - String get todayFaqWatchNoNotificationDescription1 =>  
669 - '苹果手表和手机的通知展示有优先级:当手机已解锁并亮屏时,通知只会在手机端展示,不会在手表上出现。'; 624 + String get todayFaqWatchNoNotificationDescription1 => '苹果手表和手机的通知展示有优先级:当手机已解锁并亮屏时,通知只会在手机端展示,不会在手表上出现。';
670 625
671 @override 626 @override
672 - String get todayFaqWatchNoNotificationDescription2 =>  
673 - '若压力数据可正常显示和自动更新,但手表未收到通知,可尝试以下操作:'; 627 + String get todayFaqWatchNoNotificationDescription2 => '若压力数据可正常显示和自动更新,但手表未收到通知,可尝试以下操作:';
674 628
675 @override 629 @override
676 - String get todayFaqWatchNoNotificationCheckPhoneNotification =>  
677 - '1. 检查手机是否打开通知(设置-DoubleFeel-通知)。'; 630 + String get todayFaqWatchNoNotificationCheckPhoneNotification => '1. 检查手机是否打开通知(设置-DoubleFeel-通知)。';
678 631
679 @override 632 @override
680 - String get todayFaqWatchNoNotificationCheckPhoneBackgroundRefresh =>  
681 - '2. 检查手机是否打开后台App刷新(设置-DoubleFeel-后台App刷新)。'; 633 + String get todayFaqWatchNoNotificationCheckPhoneBackgroundRefresh => '2. 检查手机是否打开后台App刷新(设置-DoubleFeel-后台App刷新)。';
682 634
683 @override 635 @override
684 - String get todayFaqWatchNoNotificationCheckWatchBackgroundRefresh =>  
685 - '3. 检查手表是否打开后台App刷新(设置-通用-后台App刷新,并确保DoubleFeel开启)。'; 636 + String get todayFaqWatchNoNotificationCheckWatchBackgroundRefresh => '3. 检查手表是否打开后台App刷新(设置-通用-后台App刷新,并确保DoubleFeel开启)。';
686 637
687 @override 638 @override
688 - String get todayFaqWatchNoNotificationCheckModes =>  
689 - '4. 确保未处于低电量/专注/勿扰/剧院/睡眠等模式。'; 639 + String get todayFaqWatchNoNotificationCheckModes => '4. 确保未处于低电量/专注/勿扰/剧院/睡眠等模式。';
690 640
691 @override 641 @override
692 - String get todayFaqWatchNoNotificationReinstall =>  
693 - '5. 重装DoubleFeel 并重启AppleWatch与iPhone。'; 642 + String get todayFaqWatchNoNotificationReinstall => '5. 重装DoubleFeel 并重启AppleWatch与iPhone。';
694 643
695 @override 644 @override
696 String get todayFaqWatchFaceDelayTitle => '手表表盘数据不更新或有延迟?'; 645 String get todayFaqWatchFaceDelayTitle => '手表表盘数据不更新或有延迟?';
697 646
698 @override 647 @override
699 - String get todayFaqWatchFaceDelayDescription1 =>  
700 - '由于苹果系统限制,所有手表表盘(第三方或官方)都会存在几分钟至半小时的延迟,开发者无法控制刷新频率。'; 648 + String get todayFaqWatchFaceDelayDescription1 => '由于苹果系统限制,所有手表表盘(第三方或官方)都会存在几分钟至半小时的延迟,开发者无法控制刷新频率。';
701 649
702 @override 650 @override
703 String get todayFaqWatchFaceDelayIfOverOneHour => '若手机数据刷新后超过1小时表盘仍未更新:'; 651 String get todayFaqWatchFaceDelayIfOverOneHour => '若手机数据刷新后超过1小时表盘仍未更新:';
704 652
705 @override 653 @override
706 - String get todayFaqWatchFaceDelayOpenWatchApp =>  
707 - '请在手表上手动打开DoubleFeel,等待约1分钟。'; 654 + String get todayFaqWatchFaceDelayOpenWatchApp => '请在手表上手动打开DoubleFeel,等待约1分钟。';
708 655
709 @override 656 @override
710 String get todayFaqWatchFaceDelayIfStill => '若仍未更新:'; 657 String get todayFaqWatchFaceDelayIfStill => '若仍未更新:';
@@ -719,27 +666,22 @@ class AppLocalizationsZh extends AppLocalizations { @@ -719,27 +666,22 @@ class AppLocalizationsZh extends AppLocalizations {
719 String get todayFaqWatchFaceDelayCheckData => '· 手机和手表app是否可正常看到HRV数据。'; 666 String get todayFaqWatchFaceDelayCheckData => '· 手机和手表app是否可正常看到HRV数据。';
720 667
721 @override 668 @override
722 - String get todayFaqWatchFaceDelayCheckPhoneHealth =>  
723 - '· 确保手机端「iOS设置-隐私与安全性-健康-DoubleFeel」全部授权。'; 669 + String get todayFaqWatchFaceDelayCheckPhoneHealth => '· 确保手机端「iOS设置-隐私与安全性-健康-DoubleFeel」全部授权。';
724 670
725 @override 671 @override
726 - String get todayFaqWatchFaceDelayCheckWatchHealth =>  
727 - '· 确保手表端「设置-健康-数据来源、App和服务-DoubleFeel」全部授权。'; 672 + String get todayFaqWatchFaceDelayCheckWatchHealth => '· 确保手表端「设置-健康-数据来源、App和服务-DoubleFeel」全部授权。';
728 673
729 @override 674 @override
730 - String get todayFaqWatchFaceDelayCheckBackgroundRefresh =>  
731 - '· 确认AppleWatch-设置-通用-后台App刷新中DoubleFeel已开启。'; 675 + String get todayFaqWatchFaceDelayCheckBackgroundRefresh => '· 确认AppleWatch-设置-通用-后台App刷新中DoubleFeel已开启。';
732 676
733 @override 677 @override
734 - String get todayFaqWatchFaceDelayRestartWatch =>  
735 - '· 若仍未自动刷新,请重启手表。长时间运行或后台占用过高可能导致表盘暂停更新。'; 678 + String get todayFaqWatchFaceDelayRestartWatch => '· 若仍未自动刷新,请重启手表。长时间运行或后台占用过高可能导致表盘暂停更新。';
736 679
737 @override 680 @override
738 String get todayFaqWatchFaceBlackScreenTitle => '手表表盘出现黑屏?'; 681 String get todayFaqWatchFaceBlackScreenTitle => '手表表盘出现黑屏?';
739 682
740 @override 683 @override
741 - String get todayFaqWatchFaceBlackScreenDescription =>  
742 - '若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。'; 684 + String get todayFaqWatchFaceBlackScreenDescription => '若添加专属互动表盘后出现黑屏(仅显示时间和日期),可长按表盘,点击「编辑」,左滑至「复杂功能」,选择 DoubleFeel,然后按需选择各组件重新添加。';
743 685
744 @override 686 @override
745 String get today => '今天'; 687 String get today => '今天';
@@ -823,8 +765,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -823,8 +765,7 @@ class AppLocalizationsZh extends AppLocalizations {
823 String get questionsAndFeedback => '问题和反馈'; 765 String get questionsAndFeedback => '问题和反馈';
824 766
825 @override 767 @override
826 - String get ifYouWouldLikeUsToReplyPleaseProvideYourEmailAddress =>  
827 - '如果需要我们回复,请填写联系邮箱'; 768 + String get ifYouWouldLikeUsToReplyPleaseProvideYourEmailAddress => '如果需要我们回复,请填写联系邮箱';
828 769
829 @override 770 @override
830 String get uploadProof => '上传凭证'; 771 String get uploadProof => '上传凭证';
@@ -1224,8 +1165,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1224,8 +1165,7 @@ class AppLocalizationsZh extends AppLocalizations {
1224 String get sleepLowest => '最低'; 1165 String get sleepLowest => '最低';
1225 1166
1226 @override 1167 @override
1227 - String get sleepQualityDescription =>  
1228 - 'DoubleFeel 会根据你的睡眠时长、睡眠阶段、深度睡眠与恢复状态、夜间心率与 HRV 变化等综合生成当天的睡眠质量评分。\n该评分能够帮助你更直观地了解身体恢复状态与睡眠表现。'; 1168 + String get sleepQualityDescription => 'DoubleFeel 会根据你的睡眠时长、睡眠阶段、深度睡眠与恢复状态、夜间心率与 HRV 变化等综合生成当天的睡眠质量评分。\n该评分能够帮助你更直观地了解身体恢复状态与睡眠表现。';
1229 1169
1230 @override 1170 @override
1231 String get sleepQualityAttentionRange => '<60分'; 1171 String get sleepQualityAttentionRange => '<60分';
@@ -1377,8 +1317,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1377,8 +1317,7 @@ class AppLocalizationsZh extends AppLocalizations {
1377 String get premiumActivatedTitle => '恭喜你已开通 DoubleFeel Pro'; 1317 String get premiumActivatedTitle => '恭喜你已开通 DoubleFeel Pro';
1378 1318
1379 @override 1319 @override
1380 - String get premiumActivatedDescription =>  
1381 - '你现在可以实时监测压力、睡眠与 HRV,养成健康生活习惯,同时把关心分享给亲密联系人,让重要的人及时了解你的状态。'; 1320 + String get premiumActivatedDescription => '你现在可以实时监测压力、睡眠与 HRV,养成健康生活习惯,同时把关心分享给亲密联系人,让重要的人及时了解你的状态。';
1382 1321
1383 @override 1322 @override
1384 String get premiumActivatedContinue => '继续'; 1323 String get premiumActivatedContinue => '继续';
@@ -1479,8 +1418,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1479,8 +1418,7 @@ class AppLocalizationsZh extends AppLocalizations {
1479 String get purchaseNotesTitle => '说明'; 1418 String get purchaseNotesTitle => '说明';
1480 1419
1481 @override 1420 @override
1482 - String get purchaseNoteSubscription =>  
1483 - '确认购买并支付后,将通过您的 iTunes 账号自动续订。苹果 iTunes 账户会在到期前24小时内扣费,扣费成功后订阅周期顺延一个订阅周期。如需取消续订,请在当前订阅周期到期前24小时以前,手动在 iTunes/Apple ID 设置管理中关闭自动续费功能。本服务由您自主选择是否取消,若您选择不取消,将为您开通下个计费周期的续费服务。\n\nDoubleFeel Pro 会员属于虚拟物品,购买后,除 App Store 渠道退款外,不支持其他形式退款。如有需要,可以点击了解更多。'; 1421 + String get purchaseNoteSubscription => '确认购买并支付后,将通过您的 iTunes 账号自动续订。苹果 iTunes 账户会在到期前24小时内扣费,扣费成功后订阅周期顺延一个订阅周期。如需取消续订,请在当前订阅周期到期前24小时以前,手动在 iTunes/Apple ID 设置管理中关闭自动续费功能。本服务由您自主选择是否取消,若您选择不取消,将为您开通下个计费周期的续费服务。\n\nDoubleFeel Pro 会员属于虚拟物品,购买后,除 App Store 渠道退款外,不支持其他形式退款。如有需要,可以点击了解更多。';
1484 1422
1485 @override 1423 @override
1486 String get purchaseNoteRestore => '如果购买后未生效,请点击恢复购买。'; 1424 String get purchaseNoteRestore => '如果购买后未生效,请点击恢复购买。';
@@ -1498,8 +1436,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1498,8 +1436,7 @@ class AppLocalizationsZh extends AppLocalizations {
1498 String get refundAppStoreReviewTitle => '退款由 App Store 审核处理'; 1436 String get refundAppStoreReviewTitle => '退款由 App Store 审核处理';
1499 1437
1500 @override 1438 @override
1501 - String get refundAppStoreReviewDescription =>  
1502 - '所有订阅与虚拟商品均通过 App Store 官方支付系统完成,DoubleFeel 无法直接处理付款或退款。'; 1439 + String get refundAppStoreReviewDescription => '所有订阅与虚拟商品均通过 App Store 官方支付系统完成,DoubleFeel 无法直接处理付款或退款。';
1503 1440
1504 @override 1441 @override
1505 String get refundAppleRulesIntroduction => '根据 Apple 的平台规则:'; 1442 String get refundAppleRulesIntroduction => '根据 Apple 的平台规则:';
@@ -1523,23 +1460,19 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1523,23 +1460,19 @@ class AppLocalizationsZh extends AppLocalizations {
1523 String get refundMayBeRejectedTitle => 'App Store 可能拒绝退款申请'; 1460 String get refundMayBeRejectedTitle => 'App Store 可能拒绝退款申请';
1524 1461
1525 @override 1462 @override
1526 - String get refundNoUnconditionalRefunds =>  
1527 - '根据 Apple 的退款政策,App Store 并不支持所有情况下的无条件退款。'; 1463 + String get refundNoUnconditionalRefunds => '根据 Apple 的退款政策,App Store 并不支持所有情况下的无条件退款。';
1528 1464
1529 @override 1465 @override
1530 - String get refundAppleTermsDescription =>  
1531 - '你在使用 App Store 时,已经同意 Apple 的相关服务条款与退款规则。https://www.apple.com/cn/legal/internet-services/itunes/'; 1466 + String get refundAppleTermsDescription => '你在使用 App Store 时,已经同意 Apple 的相关服务条款与退款规则。https://www.apple.com/cn/legal/internet-services/itunes/';
1532 1467
1533 @override 1468 @override
1534 - String get refundAppleReviewsCircumstances =>  
1535 - '退款是否通过,将由 Apple 根据订单情况、账号记录与实际使用情况综合审核。'; 1469 + String get refundAppleReviewsCircumstances => '退款是否通过,将由 Apple 根据订单情况、账号记录与实际使用情况综合审核。';
1536 1470
1537 @override 1471 @override
1538 String get refundRejectionReasonsTitle => '哪些情况下可能被拒绝退款?'; 1472 String get refundRejectionReasonsTitle => '哪些情况下可能被拒绝退款?';
1539 1473
1540 @override 1474 @override
1541 - String get refundRejectionReasonsIntroduction =>  
1542 - 'App Store 可能会根据以下情况拒绝退款申请,包括但不限于:'; 1475 + String get refundRejectionReasonsIntroduction => 'App Store 可能会根据以下情况拒绝退款申请,包括但不限于:';
1543 1476
1544 @override 1477 @override
1545 String get refundReasonPurchaseTooOld => ' · 订单距离购买时间过久'; 1478 String get refundReasonPurchaseTooOld => ' · 订单距离购买时间过久';
@@ -1572,23 +1505,19 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1572,23 +1505,19 @@ class AppLocalizationsZh extends AppLocalizations {
1572 String get refundTryAgain => '如果你的退款申请被拒绝,可以尝试再次向 App Store 提交申请。'; 1505 String get refundTryAgain => '如果你的退款申请被拒绝,可以尝试再次向 App Store 提交申请。';
1573 1506
1574 @override 1507 @override
1575 - String get refundFinalReview =>  
1576 - '若再次被拒绝,则代表 App Store 已完成最终审核,我们与 Apple 客服均无法修改该结果。'; 1508 + String get refundFinalReview => '若再次被拒绝,则代表 App Store 已完成最终审核,我们与 Apple 客服均无法修改该结果。';
1577 1509
1578 @override 1510 @override
1579 - String get refundNoAlternativeChannel =>  
1580 - 'DoubleFeel 也无法处理任何绕过 App Store 系统的退款请求。'; 1511 + String get refundNoAlternativeChannel => 'DoubleFeel 也无法处理任何绕过 App Store 系统的退款请求。';
1581 1512
1582 @override 1513 @override
1583 - String get refundMembershipCancellation =>  
1584 - '退款成功后,你的 DoubleFeel Pro 会员权益也会同步取消。'; 1514 + String get refundMembershipCancellation => '退款成功后,你的 DoubleFeel Pro 会员权益也会同步取消。';
1585 1515
1586 @override 1516 @override
1587 String get refundHelpTitle => '如需帮助'; 1517 String get refundHelpTitle => '如需帮助';
1588 1518
1589 @override 1519 @override
1590 - String get refundHelpDescription =>  
1591 - '如果你对退款规则存在疑问,或遇到支付异常、重复扣费、订单未到账等问题,可以联系 DoubleFeel 支持团队,我们会尽力协助你处理。'; 1520 + String get refundHelpDescription => '如果你对退款规则存在疑问,或遇到支付异常、重复扣费、订单未到账等问题,可以联系 DoubleFeel 支持团队,我们会尽力协助你处理。';
1592 1521
1593 @override 1522 @override
1594 String get refundFaqTitle => 'DoubleFeel 常见问题'; 1523 String get refundFaqTitle => 'DoubleFeel 常见问题';
@@ -1597,8 +1526,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1597,8 +1526,7 @@ class AppLocalizationsZh extends AppLocalizations {
1597 String get appReviewPromptTitle => '喜欢 DoubleFeel 吗?'; 1526 String get appReviewPromptTitle => '喜欢 DoubleFeel 吗?';
1598 1527
1599 @override 1528 @override
1600 - String get appReviewPromptMessage =>  
1601 - '嗨~想知道 DoubleFeel 是否正在帮助你\n更了解自己的压力与睡眠状态 💜'; 1529 + String get appReviewPromptMessage => '嗨~想知道 DoubleFeel 是否正在帮助你\n更了解自己的压力与睡眠状态 💜';
1602 1530
1603 @override 1531 @override
1604 String get appReviewPromptLikeAction => '😍 很喜欢'; 1532 String get appReviewPromptLikeAction => '😍 很喜欢';
@@ -1610,8 +1538,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -1610,8 +1538,7 @@ class AppLocalizationsZh extends AppLocalizations {
1610 String get appReviewFeedbackTitle => '很抱歉 DoubleFeel 没有带\n给你好的体验'; 1538 String get appReviewFeedbackTitle => '很抱歉 DoubleFeel 没有带\n给你好的体验';
1611 1539
1612 @override 1540 @override
1613 - String get appReviewFeedbackMessage =>  
1614 - '愿意告诉我们遇到了什么问题吗?\n你的反馈可以帮助我们持续改进压力与健康体验 💜'; 1541 + String get appReviewFeedbackMessage => '愿意告诉我们遇到了什么问题吗?\n你的反馈可以帮助我们持续改进压力与健康体验 💜';
1615 1542
1616 @override 1543 @override
1617 String get appReviewFeedbackSendAction => '发送反馈'; 1544 String get appReviewFeedbackSendAction => '发送反馈';
@@ -133,10 +133,10 @@ packages: @@ -133,10 +133,10 @@ packages:
133 dependency: transitive 133 dependency: transitive
134 description: 134 description:
135 name: characters 135 name: characters
136 - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 136 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
137 url: "https://pub.dev" 137 url: "https://pub.dev"
138 source: hosted 138 source: hosted
139 - version: "1.4.0" 139 + version: "1.3.0"
140 checked_yaml: 140 checked_yaml:
141 dependency: transitive 141 dependency: transitive
142 description: 142 description:
@@ -149,10 +149,10 @@ packages: @@ -149,10 +149,10 @@ packages:
149 dependency: transitive 149 dependency: transitive
150 description: 150 description:
151 name: clock 151 name: clock
152 - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 152 + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
153 url: "https://pub.dev" 153 url: "https://pub.dev"
154 source: hosted 154 source: hosted
155 - version: "1.1.2" 155 + version: "1.1.1"
156 code_builder: 156 code_builder:
157 dependency: transitive 157 dependency: transitive
158 description: 158 description:
@@ -165,10 +165,10 @@ packages: @@ -165,10 +165,10 @@ packages:
165 dependency: transitive 165 dependency: transitive
166 description: 166 description:
167 name: collection 167 name: collection
168 - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 168 + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
169 url: "https://pub.dev" 169 url: "https://pub.dev"
170 source: hosted 170 source: hosted
171 - version: "1.19.1" 171 + version: "1.19.0"
172 convert: 172 convert:
173 dependency: transitive 173 dependency: transitive
174 description: 174 description:
@@ -237,10 +237,10 @@ packages: @@ -237,10 +237,10 @@ packages:
237 dependency: transitive 237 dependency: transitive
238 description: 238 description:
239 name: fake_async 239 name: fake_async
240 - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" 240 + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
241 url: "https://pub.dev" 241 url: "https://pub.dev"
242 source: hosted 242 source: hosted
243 - version: "1.3.3" 243 + version: "1.3.1"
244 ffi: 244 ffi:
245 dependency: transitive 245 dependency: transitive
246 description: 246 description:
@@ -426,8 +426,8 @@ packages: @@ -426,8 +426,8 @@ packages:
426 dependency: transitive 426 dependency: transitive
427 description: 427 description:
428 path: image_cropper_for_web 428 path: image_cropper_for_web
429 - ref: "65c2c99891882ea59732959a672f3d5993a837bb"  
430 - resolved-ref: "65c2c99891882ea59732959a672f3d5993a837bb" 429 + ref: "br_v9.1.0_ohos"
  430 + resolved-ref: b1b45b1a5333571095569d53d01720c505fff983
431 url: "https://gitcode.com/openharmony-sig/fluttertpc_image_cropper.git" 431 url: "https://gitcode.com/openharmony-sig/fluttertpc_image_cropper.git"
432 source: git 432 source: git
433 version: "6.1.0" 433 version: "6.1.0"
@@ -435,8 +435,8 @@ packages: @@ -435,8 +435,8 @@ packages:
435 dependency: transitive 435 dependency: transitive
436 description: 436 description:
437 path: image_cropper_platform_interface 437 path: image_cropper_platform_interface
438 - ref: "65c2c99891882ea59732959a672f3d5993a837bb"  
439 - resolved-ref: "65c2c99891882ea59732959a672f3d5993a837bb" 438 + ref: "br_v9.1.0_ohos"
  439 + resolved-ref: b1b45b1a5333571095569d53d01720c505fff983
440 url: "https://gitcode.com/openharmony-sig/fluttertpc_image_cropper.git" 440 url: "https://gitcode.com/openharmony-sig/fluttertpc_image_cropper.git"
441 source: git 441 source: git
442 version: "7.1.0" 442 version: "7.1.0"
@@ -517,10 +517,10 @@ packages: @@ -517,10 +517,10 @@ packages:
517 dependency: "direct main" 517 dependency: "direct main"
518 description: 518 description:
519 name: intl 519 name: intl
520 - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" 520 + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
521 url: "https://pub.dev" 521 url: "https://pub.dev"
522 source: hosted 522 source: hosted
523 - version: "0.20.2" 523 + version: "0.19.0"
524 io: 524 io:
525 dependency: transitive 525 dependency: transitive
526 description: 526 description:
@@ -549,26 +549,26 @@ packages: @@ -549,26 +549,26 @@ packages:
549 dependency: transitive 549 dependency: transitive
550 description: 550 description:
551 name: leak_tracker 551 name: leak_tracker
552 - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" 552 + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
553 url: "https://pub.dev" 553 url: "https://pub.dev"
554 source: hosted 554 source: hosted
555 - version: "11.0.2" 555 + version: "10.0.7"
556 leak_tracker_flutter_testing: 556 leak_tracker_flutter_testing:
557 dependency: transitive 557 dependency: transitive
558 description: 558 description:
559 name: leak_tracker_flutter_testing 559 name: leak_tracker_flutter_testing
560 - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" 560 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
561 url: "https://pub.dev" 561 url: "https://pub.dev"
562 source: hosted 562 source: hosted
563 - version: "3.0.10" 563 + version: "3.0.8"
564 leak_tracker_testing: 564 leak_tracker_testing:
565 dependency: transitive 565 dependency: transitive
566 description: 566 description:
567 name: leak_tracker_testing 567 name: leak_tracker_testing
568 - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" 568 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
569 url: "https://pub.dev" 569 url: "https://pub.dev"
570 source: hosted 570 source: hosted
571 - version: "3.0.2" 571 + version: "3.0.1"
572 lints: 572 lints:
573 dependency: transitive 573 dependency: transitive
574 description: 574 description:
@@ -597,10 +597,10 @@ packages: @@ -597,10 +597,10 @@ packages:
597 dependency: transitive 597 dependency: transitive
598 description: 598 description:
599 name: matcher 599 name: matcher
600 - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 600 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
601 url: "https://pub.dev" 601 url: "https://pub.dev"
602 source: hosted 602 source: hosted
603 - version: "0.12.17" 603 + version: "0.12.16+1"
604 material_color_utilities: 604 material_color_utilities:
605 dependency: transitive 605 dependency: transitive
606 description: 606 description:
@@ -613,10 +613,10 @@ packages: @@ -613,10 +613,10 @@ packages:
613 dependency: transitive 613 dependency: transitive
614 description: 614 description:
615 name: meta 615 name: meta
616 - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" 616 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
617 url: "https://pub.dev" 617 url: "https://pub.dev"
618 source: hosted 618 source: hosted
619 - version: "1.17.0" 619 + version: "1.15.0"
620 mime: 620 mime:
621 dependency: transitive 621 dependency: transitive
622 description: 622 description:
@@ -645,10 +645,10 @@ packages: @@ -645,10 +645,10 @@ packages:
645 dependency: transitive 645 dependency: transitive
646 description: 646 description:
647 name: path 647 name: path
648 - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 648 + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
649 url: "https://pub.dev" 649 url: "https://pub.dev"
650 source: hosted 650 source: hosted
651 - version: "1.9.1" 651 + version: "1.9.0"
652 path_provider: 652 path_provider:
653 dependency: "direct overridden" 653 dependency: "direct overridden"
654 description: 654 description:
@@ -832,7 +832,7 @@ packages: @@ -832,7 +832,7 @@ packages:
832 dependency: transitive 832 dependency: transitive
833 description: 833 description:
834 path: "packages/share_plus/share_plus_platform_interface" 834 path: "packages/share_plus/share_plus_platform_interface"
835 - ref: "55de300a8627c55cd45ac86e6a26bcae8e0ca4cf" 835 + ref: "br_share_plus-v10.1.1_ohos"
836 resolved-ref: "55de300a8627c55cd45ac86e6a26bcae8e0ca4cf" 836 resolved-ref: "55de300a8627c55cd45ac86e6a26bcae8e0ca4cf"
837 url: "https://gitcode.com/CPF-Flutter/flutter_plus_plugins.git" 837 url: "https://gitcode.com/CPF-Flutter/flutter_plus_plugins.git"
838 source: git 838 source: git
@@ -984,18 +984,18 @@ packages: @@ -984,18 +984,18 @@ packages:
984 dependency: transitive 984 dependency: transitive
985 description: 985 description:
986 name: stack_trace 986 name: stack_trace
987 - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 987 + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
988 url: "https://pub.dev" 988 url: "https://pub.dev"
989 source: hosted 989 source: hosted
990 - version: "1.12.1" 990 + version: "1.12.0"
991 stream_channel: 991 stream_channel:
992 dependency: transitive 992 dependency: transitive
993 description: 993 description:
994 name: stream_channel 994 name: stream_channel
995 - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 995 + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
996 url: "https://pub.dev" 996 url: "https://pub.dev"
997 source: hosted 997 source: hosted
998 - version: "2.1.4" 998 + version: "2.1.2"
999 stream_transform: 999 stream_transform:
1000 dependency: transitive 1000 dependency: transitive
1001 description: 1001 description:
@@ -1024,10 +1024,10 @@ packages: @@ -1024,10 +1024,10 @@ packages:
1024 dependency: "direct main" 1024 dependency: "direct main"
1025 description: 1025 description:
1026 name: table_calendar 1026 name: table_calendar
1027 - sha256: "0c0c6219878b363a2d5f40c7afb159d845f253d061dc3c822aa0d5fe0f721982" 1027 + sha256: b2896b7c86adf3a4d9c911d860120fe3dbe03c85db43b22fd61f14ee78cdbb63
1028 url: "https://pub.dev" 1028 url: "https://pub.dev"
1029 source: hosted 1029 source: hosted
1030 - version: "3.2.0" 1030 + version: "3.1.3"
1031 term_glyph: 1031 term_glyph:
1032 dependency: transitive 1032 dependency: transitive
1033 description: 1033 description:
@@ -1040,10 +1040,10 @@ packages: @@ -1040,10 +1040,10 @@ packages:
1040 dependency: transitive 1040 dependency: transitive
1041 description: 1041 description:
1042 name: test_api 1042 name: test_api
1043 - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 1043 + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
1044 url: "https://pub.dev" 1044 url: "https://pub.dev"
1045 source: hosted 1045 source: hosted
1046 - version: "0.7.7" 1046 + version: "0.7.3"
1047 timing: 1047 timing:
1048 dependency: transitive 1048 dependency: transitive
1049 description: 1049 description:
@@ -1104,10 +1104,10 @@ packages: @@ -1104,10 +1104,10 @@ packages:
1104 dependency: transitive 1104 dependency: transitive
1105 description: 1105 description:
1106 name: vector_math 1106 name: vector_math
1107 - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b 1107 + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
1108 url: "https://pub.dev" 1108 url: "https://pub.dev"
1109 source: hosted 1109 source: hosted
1110 - version: "2.2.0" 1110 + version: "2.1.4"
1111 vm_service: 1111 vm_service:
1112 dependency: transitive 1112 dependency: transitive
1113 description: 1113 description:
@@ -1161,8 +1161,8 @@ packages: @@ -1161,8 +1161,8 @@ packages:
1161 dependency: transitive 1161 dependency: transitive
1162 description: 1162 description:
1163 path: "packages/webview_flutter/webview_flutter_android" 1163 path: "packages/webview_flutter/webview_flutter_android"
1164 - ref: de942e79c9057b32ad31106508bd87c0d60aef83  
1165 - resolved-ref: de942e79c9057b32ad31106508bd87c0d60aef83 1164 + ref: "br_webview_flutter-v4.13.0_ohos"
  1165 + resolved-ref: ecd3d0b6195945ee0660c324d45f1acbc6198cc3
1166 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" 1166 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
1167 source: git 1167 source: git
1168 version: "4.7.0" 1168 version: "4.7.0"
@@ -1170,8 +1170,8 @@ packages: @@ -1170,8 +1170,8 @@ packages:
1170 dependency: transitive 1170 dependency: transitive
1171 description: 1171 description:
1172 path: "packages/webview_flutter/webview_flutter_ohos" 1172 path: "packages/webview_flutter/webview_flutter_ohos"
1173 - ref: de942e79c9057b32ad31106508bd87c0d60aef83  
1174 - resolved-ref: de942e79c9057b32ad31106508bd87c0d60aef83 1173 + ref: "br_webview_flutter-v4.13.0_ohos"
  1174 + resolved-ref: ecd3d0b6195945ee0660c324d45f1acbc6198cc3
1175 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" 1175 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
1176 source: git 1176 source: git
1177 version: "4.7.0" 1177 version: "4.7.0"
@@ -1179,8 +1179,8 @@ packages: @@ -1179,8 +1179,8 @@ packages:
1179 dependency: transitive 1179 dependency: transitive
1180 description: 1180 description:
1181 path: "packages/webview_flutter/webview_flutter_platform_interface" 1181 path: "packages/webview_flutter/webview_flutter_platform_interface"
1182 - ref: de942e79c9057b32ad31106508bd87c0d60aef83  
1183 - resolved-ref: de942e79c9057b32ad31106508bd87c0d60aef83 1182 + ref: "br_webview_flutter-v4.13.0_ohos"
  1183 + resolved-ref: ecd3d0b6195945ee0660c324d45f1acbc6198cc3
1184 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" 1184 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
1185 source: git 1185 source: git
1186 version: "2.13.1" 1186 version: "2.13.1"
@@ -1188,8 +1188,8 @@ packages: @@ -1188,8 +1188,8 @@ packages:
1188 dependency: transitive 1188 dependency: transitive
1189 description: 1189 description:
1190 path: "packages/webview_flutter/webview_flutter_wkwebview" 1190 path: "packages/webview_flutter/webview_flutter_wkwebview"
1191 - ref: de942e79c9057b32ad31106508bd87c0d60aef83  
1192 - resolved-ref: de942e79c9057b32ad31106508bd87c0d60aef83 1191 + ref: "br_webview_flutter-v4.13.0_ohos"
  1192 + resolved-ref: ecd3d0b6195945ee0660c324d45f1acbc6198cc3
1193 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" 1193 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
1194 source: git 1194 source: git
1195 version: "3.22.0" 1195 version: "3.22.0"
@@ -1218,5 +1218,5 @@ packages: @@ -1218,5 +1218,5 @@ packages:
1218 source: hosted 1218 source: hosted
1219 version: "3.1.3" 1219 version: "3.1.3"
1220 sdks: 1220 sdks:
1221 - dart: ">=3.8.0-0 <4.0.0" 1221 + dart: ">=3.6.2 <4.0.0"
1222 flutter: ">=3.27.0" 1222 flutter: ">=3.27.0"
  1 +import 'package:doublefeel_flutter/app/modules/watch_theme/models/watch_theme_models.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +
  4 +void main() {
  5 + test('parses the watch theme API response fields', () {
  6 + final response = WatchThemeResponse.fromJson({
  7 + 'themes': [
  8 + {
  9 + 'id': 1000,
  10 + 'user_id': 129,
  11 + 'status': 1,
  12 + 'theme_name': '默认主题',
  13 + 'energetic_description': '状态优秀',
  14 + 'energetic_image': 'https://cdn.example.com/energetic.png',
  15 + 'normal_description': '状态正常',
  16 + 'normal_image': 'https://cdn.example.com/normal.png',
  17 + 'slight_stressful_description': '注意压力',
  18 + 'slight_stressful_image':
  19 + 'https://cdn.example.com/slight_stressful.png',
  20 + 'stressful_description': '压力过载',
  21 + 'stressful_image': 'https://cdn.example.com/stressful.png',
  22 + 'is_official': 1,
  23 + 'is_default_theme': 1,
  24 + 'official_theme_id': 1,
  25 + 'create_time': 1782185966,
  26 + 'update_time': 1782185966,
  27 + },
  28 + ],
  29 + });
  30 +
  31 + final theme = response.themes.single;
  32 + expect(theme.id, 1000);
  33 + expect(theme.userId, 129);
  34 + expect(theme.isOfficial, 1);
  35 + expect(theme.isCustomTheme, isFalse);
  36 + expect(theme.isDefaultTheme, 1);
  37 + expect(theme.officialThemeId, 1);
  38 + expect(theme.infoList.map((item) => item.title), [
  39 + '状态优秀',
  40 + '状态正常',
  41 + '注意压力',
  42 + '压力过载',
  43 + ]);
  44 + expect(
  45 + theme.toJson()['slight_stressful_image'],
  46 + 'https://cdn.example.com/slight_stressful.png',
  47 + );
  48 + });
  49 +}