diff --git a/client/app.json b/client/app.json index 6c4afd0..00ddbaf 100644 --- a/client/app.json +++ b/client/app.json @@ -1,11 +1,11 @@ { "expo": { - "name": "client", - "slug": "client", + "name": "Hey Mama", + "slug": "hey-mama", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/images/icon.png", - "scheme": "client", + "scheme": "heymama", "userInterfaceStyle": "automatic", "newArchEnabled": true, "splash": { @@ -15,7 +15,7 @@ }, "ios": { "supportsTablet": true, - "bundleIdentifier": "com.anonymous.client" + "bundleIdentifier": "com.heymama.app" }, "android": { "adaptiveIcon": { diff --git a/client/components/home/.ProfileModal.tsx.swp b/client/components/home/.ProfileModal.tsx.swp new file mode 100644 index 0000000..9e07e56 Binary files /dev/null and b/client/components/home/.ProfileModal.tsx.swp differ diff --git a/client/components/ui/.SheetModal.tsx.swp b/client/components/ui/.SheetModal.tsx.swp new file mode 100644 index 0000000..e0c938d Binary files /dev/null and b/client/components/ui/.SheetModal.tsx.swp differ diff --git a/client/ios/Podfile.lock b/client/ios/Podfile.lock index a555c69..87fc2f5 100644 --- a/client/ios/Podfile.lock +++ b/client/ios/Podfile.lock @@ -3,6 +3,9 @@ PODS: - ExpoModulesCore - EXConstants (18.0.13): - ExpoModulesCore + - EXJSONUtils (0.15.0) + - EXManifests (1.0.10): + - ExpoModulesCore - EXNotifications (0.32.16): - ExpoModulesCore - Expo (54.0.32): @@ -30,6 +33,177 @@ PODS: - ReactCommon/turbomodule/core - ReactNativeDependencies - Yoga + - expo-dev-client (6.0.20): + - EXManifests + - expo-dev-launcher + - expo-dev-menu + - expo-dev-menu-interface + - EXUpdatesInterface + - expo-dev-launcher (6.0.20): + - EXManifests + - expo-dev-launcher/Main (= 6.0.20) + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-NativeModulesApple + - React-RCTAppDelegate + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactAppDependencyProvider + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - expo-dev-launcher/Main (6.0.20): + - EXManifests + - expo-dev-launcher/Unsafe + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-NativeModulesApple + - React-RCTAppDelegate + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactAppDependencyProvider + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - expo-dev-launcher/Unsafe (6.0.20): + - EXManifests + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-NativeModulesApple + - React-RCTAppDelegate + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactAppDependencyProvider + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - expo-dev-menu (7.0.18): + - expo-dev-menu/Main (= 7.0.18) + - expo-dev-menu/ReactNativeCompatibles (= 7.0.18) + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - expo-dev-menu-interface (2.0.0) + - expo-dev-menu/Main (7.0.18): + - EXManifests + - expo-dev-menu-interface + - ExpoModulesCore + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - expo-dev-menu/ReactNativeCompatibles (7.0.18): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga - ExpoAsset (12.0.12): - ExpoModulesCore - ExpoFileSystem (19.0.21): @@ -74,6 +248,8 @@ PODS: - ExpoModulesCore - ExpoWebBrowser (15.0.10): - ExpoModulesCore + - EXUpdatesInterface (2.0.0): + - ExpoModulesCore - FBLazyVector (0.81.5) - hermes-engine (0.81.5): - hermes-engine/Pre-built (= 0.81.5) @@ -1798,6 +1974,28 @@ PODS: - ReactCommon/turbomodule/core - ReactNativeDependencies - Yoga + - RNGestureHandler (2.30.0): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga - RNReanimated (4.1.6): - hermes-engine - RCTRequired @@ -2040,12 +2238,18 @@ PODS: DEPENDENCIES: - "EXApplication (from `../node_modules/.pnpm/expo-application@7.0.8_expo@54.0.32/node_modules/expo-application/ios`)" - "EXConstants (from `../node_modules/.pnpm/expo-constants@18.0.13_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0_/node_modules/expo-constants/ios`)" + - "EXJSONUtils (from `../node_modules/.pnpm/expo-json-utils@0.15.0/node_modules/expo-json-utils/ios`)" + - "EXManifests (from `../node_modules/.pnpm/expo-manifests@1.0.10_expo@54.0.32/node_modules/expo-manifests/ios`)" - "EXNotifications (from `../node_modules/.pnpm/expo-notifications@0.32.16_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+r_758952db70529f49bda448def1c13c49/node_modules/expo-notifications/ios`)" - "Expo (from `../node_modules/.pnpm/expo@54.0.32_@babel+core@7.28.6_@expo+metro-runtime@6.1.2_expo-router@6.0.22_react-nati_18ad48ba284ee86e6eb1cb0f939697b0/node_modules/expo`)" + - "expo-dev-client (from `../node_modules/.pnpm/expo-dev-client@6.0.20_expo@54.0.32/node_modules/expo-dev-client/ios`)" + - "expo-dev-launcher (from `../node_modules/.pnpm/expo-dev-launcher@6.0.20_expo@54.0.32/node_modules/expo-dev-launcher`)" + - "expo-dev-menu (from `../node_modules/.pnpm/expo-dev-menu@7.0.18_expo@54.0.32/node_modules/expo-dev-menu`)" + - "expo-dev-menu-interface (from `../node_modules/.pnpm/expo-dev-menu-interface@2.0.0_expo@54.0.32/node_modules/expo-dev-menu-interface/ios`)" - "ExpoAsset (from `../node_modules/.pnpm/expo-asset@12.0.12_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-asset/ios`)" - "ExpoFileSystem (from `../node_modules/.pnpm/expo-file-system@19.0.21_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0_/node_modules/expo-file-system/ios`)" - "ExpoFont (from `../node_modules/.pnpm/expo-font@14.0.11_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-font/ios`)" - - "ExpoHead (from `../node_modules/.pnpm/expo-router@6.0.22_@expo+metro-runtime@6.1.2_@types+react@19.1.17_expo-constants@18.0.1_4eba8c13adbbc1edf57cc04c4adac5f6/node_modules/expo-router/ios`)" + - "ExpoHead (from `../node_modules/.pnpm/expo-router@6.0.22_@expo+metro-runtime@6.1.2_@types+react@19.1.17_expo-constants@18.0.1_bd9aa16746ed7110429f931eb008e6d2/node_modules/expo-router/ios`)" - "ExpoKeepAwake (from `../node_modules/.pnpm/expo-keep-awake@15.0.8_expo@54.0.32_react@19.1.0/node_modules/expo-keep-awake/ios`)" - "ExpoLinearGradient (from `../node_modules/.pnpm/expo-linear-gradient@15.0.8_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+_53aef72480df9baa4504f4743d9c64bb/node_modules/expo-linear-gradient/ios`)" - "ExpoLinking (from `../node_modules/.pnpm/expo-linking@8.0.11_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-linking/ios`)" @@ -2053,6 +2257,7 @@ DEPENDENCIES: - "ExpoModulesCore (from `../node_modules/.pnpm/expo-modules-core@3.0.29_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-modules-core`)" - "ExpoSplashScreen (from `../node_modules/.pnpm/expo-splash-screen@31.0.13_expo@54.0.32/node_modules/expo-splash-screen/ios`)" - "ExpoWebBrowser (from `../node_modules/.pnpm/expo-web-browser@15.0.10_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0_/node_modules/expo-web-browser/ios`)" + - "EXUpdatesInterface (from `../node_modules/.pnpm/expo-updates-interface@2.0.0_expo@54.0.32/node_modules/expo-updates-interface/ios`)" - "FBLazyVector (from `../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/Libraries/FBLazyVector`)" - "hermes-engine (from `../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)" - "RCTDeprecation (from `../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)" @@ -2122,6 +2327,7 @@ DEPENDENCIES: - "ReactCommon/turbomodule/core (from `../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/ReactCommon`)" - "ReactNativeDependencies (from `../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec`)" - "RNCAsyncStorage (from `../node_modules/.pnpm/@react-native-async-storage+async-storage@2.2.0_react-native@0.81.5_@babel+core@7.28.6__ce3c4972004f3d6791573ec5b64bee38/node_modules/@react-native-async-storage/async-storage`)" + - "RNGestureHandler (from `../node_modules/.pnpm/react-native-gesture-handler@2.30.0_react-native@0.81.5_@babel+core@7.28.6_@types+react_39cf7da47c9c8531caaa923ee740e293/node_modules/react-native-gesture-handler`)" - "RNReanimated (from `../node_modules/.pnpm/react-native-reanimated@4.1.6_@babel+core@7.28.6_react-native-worklets@0.5.1_@babel+cor_c7c888bd389fb93c9cfe2d3c1c8b0777/node_modules/react-native-reanimated`)" - "RNScreens (from `../node_modules/.pnpm/react-native-screens@4.16.0_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/react-native-screens`)" - "RNSVG (from `../node_modules/.pnpm/react-native-svg@15.12.1_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/react-native-svg`)" @@ -2133,10 +2339,22 @@ EXTERNAL SOURCES: :path: "../node_modules/.pnpm/expo-application@7.0.8_expo@54.0.32/node_modules/expo-application/ios" EXConstants: :path: "../node_modules/.pnpm/expo-constants@18.0.13_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0_/node_modules/expo-constants/ios" + EXJSONUtils: + :path: "../node_modules/.pnpm/expo-json-utils@0.15.0/node_modules/expo-json-utils/ios" + EXManifests: + :path: "../node_modules/.pnpm/expo-manifests@1.0.10_expo@54.0.32/node_modules/expo-manifests/ios" EXNotifications: :path: "../node_modules/.pnpm/expo-notifications@0.32.16_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+r_758952db70529f49bda448def1c13c49/node_modules/expo-notifications/ios" Expo: :path: "../node_modules/.pnpm/expo@54.0.32_@babel+core@7.28.6_@expo+metro-runtime@6.1.2_expo-router@6.0.22_react-nati_18ad48ba284ee86e6eb1cb0f939697b0/node_modules/expo" + expo-dev-client: + :path: "../node_modules/.pnpm/expo-dev-client@6.0.20_expo@54.0.32/node_modules/expo-dev-client/ios" + expo-dev-launcher: + :path: "../node_modules/.pnpm/expo-dev-launcher@6.0.20_expo@54.0.32/node_modules/expo-dev-launcher" + expo-dev-menu: + :path: "../node_modules/.pnpm/expo-dev-menu@7.0.18_expo@54.0.32/node_modules/expo-dev-menu" + expo-dev-menu-interface: + :path: "../node_modules/.pnpm/expo-dev-menu-interface@2.0.0_expo@54.0.32/node_modules/expo-dev-menu-interface/ios" ExpoAsset: :path: "../node_modules/.pnpm/expo-asset@12.0.12_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-asset/ios" ExpoFileSystem: @@ -2144,7 +2362,7 @@ EXTERNAL SOURCES: ExpoFont: :path: "../node_modules/.pnpm/expo-font@14.0.11_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/expo-font/ios" ExpoHead: - :path: "../node_modules/.pnpm/expo-router@6.0.22_@expo+metro-runtime@6.1.2_@types+react@19.1.17_expo-constants@18.0.1_4eba8c13adbbc1edf57cc04c4adac5f6/node_modules/expo-router/ios" + :path: "../node_modules/.pnpm/expo-router@6.0.22_@expo+metro-runtime@6.1.2_@types+react@19.1.17_expo-constants@18.0.1_bd9aa16746ed7110429f931eb008e6d2/node_modules/expo-router/ios" ExpoKeepAwake: :path: "../node_modules/.pnpm/expo-keep-awake@15.0.8_expo@54.0.32_react@19.1.0/node_modules/expo-keep-awake/ios" ExpoLinearGradient: @@ -2159,6 +2377,8 @@ EXTERNAL SOURCES: :path: "../node_modules/.pnpm/expo-splash-screen@31.0.13_expo@54.0.32/node_modules/expo-splash-screen/ios" ExpoWebBrowser: :path: "../node_modules/.pnpm/expo-web-browser@15.0.10_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0_/node_modules/expo-web-browser/ios" + EXUpdatesInterface: + :path: "../node_modules/.pnpm/expo-updates-interface@2.0.0_expo@54.0.32/node_modules/expo-updates-interface/ios" FBLazyVector: :path: "../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/Libraries/FBLazyVector" hermes-engine: @@ -2296,6 +2516,8 @@ EXTERNAL SOURCES: :podspec: "../node_modules/.pnpm/react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0/node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec" RNCAsyncStorage: :path: "../node_modules/.pnpm/@react-native-async-storage+async-storage@2.2.0_react-native@0.81.5_@babel+core@7.28.6__ce3c4972004f3d6791573ec5b64bee38/node_modules/@react-native-async-storage/async-storage" + RNGestureHandler: + :path: "../node_modules/.pnpm/react-native-gesture-handler@2.30.0_react-native@0.81.5_@babel+core@7.28.6_@types+react_39cf7da47c9c8531caaa923ee740e293/node_modules/react-native-gesture-handler" RNReanimated: :path: "../node_modules/.pnpm/react-native-reanimated@4.1.6_@babel+core@7.28.6_react-native-worklets@0.5.1_@babel+cor_c7c888bd389fb93c9cfe2d3c1c8b0777/node_modules/react-native-reanimated" RNScreens: @@ -2310,8 +2532,14 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: EXApplication: 1e98d4b1dccdf30627f92917f4b2c5a53c330e5f EXConstants: fce59a631a06c4151602843667f7cfe35f81e271 + EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd + EXManifests: a8d97683e5c7a3b026ffbd58559c64dc655b747b EXNotifications: 9eec98712cc814ceff916d876cb53859003b0597 Expo: 4e503a041c59c4e34c8be262a135848ad5cd3710 + expo-dev-client: 425ee077d6754a98cfe3a2e2410d29b440b24c9d + expo-dev-launcher: a4f4cdef064ab1fb8621e5b8c7c457cd6e9568c3 + expo-dev-menu: 05b18812110c175814c6af0d09dd658abcc5e00d + expo-dev-menu-interface: 600df12ea01efecdd822daaf13cc0ac091775533 ExpoAsset: f867e55ceb428aab99e1e8c082b5aee7c159ea18 ExpoFileSystem: 858a44267a3e6e9057e0888ad7c7cfbf55d52063 ExpoFont: f543ce20a228dd702813668b1a07b46f51878d47 @@ -2323,6 +2551,7 @@ SPEC CHECKSUMS: ExpoModulesCore: f3da4f1ab5a8375d0beafab763739dbee8446583 ExpoSplashScreen: bc3cffefca2716e5f22350ca109badd7e50ec14d ExpoWebBrowser: 17b064c621789e41d4816c95c93f429b84971f52 + EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734 FBLazyVector: e95a291ad2dadb88e42b06e0c5fb8262de53ec12 hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172 RCTDeprecation: 943572d4be82d480a48f4884f670135ae30bf990 @@ -2391,6 +2620,7 @@ SPEC CHECKSUMS: ReactCommon: 08810150b1206cc44aecf5f6ae19af32f29151a8 ReactNativeDependencies: 71ce9c28beb282aa720ea7b46980fff9669f428a RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4 + RNGestureHandler: e0d0bce5599f6120b7adf90c38d2805e2935795f RNReanimated: 9c6a550b41de91cf374e60afd79db93a362f1126 RNScreens: d8d6f1792f6e7ac12b0190d33d8d390efc0c1845 RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34 diff --git a/client/ios/client.xcodeproj/project.pbxproj b/client/ios/client.xcodeproj/project.pbxproj index 4a11c49..37c23a4 100644 --- a/client/ios/client.xcodeproj/project.pbxproj +++ b/client/ios/client.xcodeproj/project.pbxproj @@ -374,6 +374,8 @@ "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -387,6 +389,8 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevLauncher.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevMenu.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/client/ios/情绪小组件/EmotionWidget.swift b/client/ios/情绪小组件/EmotionWidget.swift index 3376cfa..510cc41 100644 --- a/client/ios/情绪小组件/EmotionWidget.swift +++ b/client/ios/情绪小组件/EmotionWidget.swift @@ -1,28 +1,54 @@ import WidgetKit import SwiftUI -// V1:写死文案的小组件(Small/Medium/Large + 点击跳转 Home) +// V2:纯色背景 + 随机文案小组件(Small/Medium/Large + 点击跳转 Home) struct EmotionProvider: TimelineProvider { + private let quotes = [ + "你已经很努力了,今天也值得被温柔对待。", + "轻轻呼吸,感受当下的每一刻。", + "所有的压力,都会在深呼吸中慢慢消散。", + "给生活一点留白,给自己一点温柔。", + "不要走得太快,等一等落下的灵魂。", + "世界虽嘈杂,但你可以拥有一颗宁静的心。", + "每一个瞬间,都是生命最好的安排。", + "抱抱自己,辛苦了,亲爱的。", + "慢一点也没关系,只要你在前行。", + "今天,你对自己微笑了吗?", + "愿你历经山河,仍觉得人间值得。", + "心简单,世界就简单;心平顺,生活就平顺。", + "即使生活偶尔晦暗,你也要成为自己的光。", + "别让琐事挤走生活的快乐,别让压力消磨奋斗的激情。" + ] + func placeholder(in context: Context) -> EmotionEntry { - EmotionEntry(date: Date()) + EmotionEntry(date: Date(), text: quotes[0]) } func getSnapshot(in context: Context, completion: @escaping (EmotionEntry) -> ()) { - completion(EmotionEntry(date: Date())) + let entry = EmotionEntry(date: Date(), text: quotes.randomElement() ?? quotes[0]) + completion(entry) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { - // V1:内容写死,不做数据更新;给一个较长的刷新间隔(系统仍可能自行调度) - let entry = EmotionEntry(date: Date()) - let nextUpdate = Calendar.current.date(byAdding: .day, value: 7, to: Date()) - ?? Date().addingTimeInterval(60 * 60 * 24 * 7) - completion(Timeline(entries: [entry], policy: .after(nextUpdate))) + var entries: [EmotionEntry] = [] + let currentDate = Date() + + // 生成未来 24 小时的 6 个条目,每 4 小时更换一次随机文案 + for hourOffset in 0..<6 { + let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset * 4, to: currentDate)! + let entry = EmotionEntry(date: entryDate, text: quotes.randomElement() ?? quotes[0]) + entries.append(entry) + } + + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) } } struct EmotionEntry: TimelineEntry { let date: Date + let text: String } struct EmotionWidgetView: View { @@ -30,160 +56,37 @@ struct EmotionWidgetView: View { @Environment(\.widgetFamily) var family private let title = "正念" - private let text = "你已经很努力了,今天也值得被温柔对待。" private let deepLink = URL(string: "client:///(app)/home") + + // 背景色 #F7D9BF + private let backgroundColor = Color(red: 247/255, green: 217/255, blue: 191/255) + // 文本颜色(深咖色,适合搭配浅橘色背景) + private let textColor = Color(red: 74/255, green: 52/255, blue: 40/255) var body: some View { - switch family { - case .systemSmall: - smallView() - case .systemMedium: - mediumView() - case .systemLarge: - largeView() - default: - smallView() - } - } - - // 统一的“卡片背景”风格(iOS 15 兼容) - private func cardBackground(colors: [Color]) -> some View { - ZStack { - LinearGradient( - colors: colors, - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - // 轻微光斑,增加层次 - RadialGradient( - gradient: Gradient(colors: [Color.white.opacity(0.16), Color.white.opacity(0.0)]), - center: .topTrailing, - startRadius: 10, - endRadius: 180 - ) - } - .overlay( - RoundedRectangle(cornerRadius: 18, style: .continuous) - .stroke(Color.white.opacity(0.14), lineWidth: 1) - ) - .cornerRadius(18) - } - - private func chip(_ text: String) -> some View { - Text(text) - .font(.system(size: 12, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.9)) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(Color.white.opacity(0.14)) - .cornerRadius(999) - } - - private func smallView() -> some View { - ZStack { - cardBackground(colors: [ - Color(red: 0.06, green: 0.08, blue: 0.12), - Color(red: 0.13, green: 0.16, blue: 0.22), - ]) - - VStack(alignment: .leading, spacing: 10) { - HStack { - chip(title) - Spacer(minLength: 0) - } - - Text(text) - .font(.system(size: 15, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.92)) - .lineSpacing(2) - .lineLimit(4) - - Spacer(minLength: 0) - - Text("点我回到 App") - .font(.system(size: 11, weight: .medium)) - .foregroundColor(Color.white.opacity(0.65)) + VStack(alignment: .center, spacing: 0) { + Spacer(minLength: 0) + + Text(entry.text) + .font(.system(size: family == .systemSmall ? 17 : 20, weight: .medium)) + .foregroundColor(textColor) + .lineSpacing(6) + .multilineTextAlignment(.center) + .minimumScaleFactor(0.7) + .fixedSize(horizontal: false, vertical: true) + + Spacer(minLength: 0) + + if family != .systemSmall { + Text("Hey Mama") + .font(.system(size: 10, weight: .semibold)) + .foregroundColor(textColor.opacity(0.3)) + .padding(.bottom, 4) } - .padding(14) - } - .widgetURL(deepLink) - } - - private func mediumView() -> some View { - ZStack { - cardBackground(colors: [ - Color(red: 0.06, green: 0.08, blue: 0.12), - Color(red: 0.09, green: 0.11, blue: 0.17), - ]) - - HStack(alignment: .top, spacing: 14) { - VStack(alignment: .leading, spacing: 10) { - chip(title) - Text(text) - .font(.system(size: 17, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.92)) - .lineSpacing(3) - .lineLimit(5) - - Spacer(minLength: 0) - - Text("轻轻呼吸,回到当下") - .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color.white.opacity(0.7)) - } - - // 右侧装饰区:让版面更饱满 - VStack(alignment: .trailing, spacing: 8) { - Text(entry.date, style: .time) - .font(.system(size: 12, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.8)) - Spacer(minLength: 0) - Text("今日") - .font(.system(size: 28, weight: .bold)) - .foregroundColor(Color.white.opacity(0.12)) - } - } - .padding(16) - } - .widgetURL(deepLink) - } - - private func largeView() -> some View { - ZStack { - cardBackground(colors: [ - Color(red: 0.06, green: 0.08, blue: 0.12), - Color(red: 0.14, green: 0.18, blue: 0.28), - ]) - - VStack(alignment: .leading, spacing: 14) { - HStack { - chip(title) - Spacer(minLength: 0) - Text(entry.date, style: .time) - .font(.system(size: 12, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.78)) - } - - Text(text) - .font(.system(size: 20, weight: .semibold)) - .foregroundColor(Color.white.opacity(0.92)) - .lineSpacing(4) - .lineLimit(8) - - Spacer(minLength: 0) - - HStack { - Text("点我回到 Home") - .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color.white.opacity(0.7)) - Spacer(minLength: 0) - Text("🌿") - .font(.system(size: 18)) - .opacity(0.9) - } - } - .padding(18) } + .padding(family == .systemSmall ? 16 : 24) + .frame(maxWidth: .infinity, maxHeight: .infinity) // 强制撑开容器 + .background(backgroundColor) // 将背景色直接应用到容器上 .widgetURL(deepLink) } } @@ -194,7 +97,13 @@ struct EmotionWidget: Widget { var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: EmotionProvider()) { entry in - EmotionWidgetView(entry: entry) + if #available(iOS 17.0, *) { + EmotionWidgetView(entry: entry) + .containerBackground(Color(red: 247/255, green: 217/255, blue: 191/255), for: .widget) + } else { + EmotionWidgetView(entry: entry) + .background(Color(red: 247/255, green: 217/255, blue: 191/255)) + } } .configurationDisplayName("情绪小组件") .description("一段温柔提醒,陪你回到当下。") diff --git a/client/package.json b/client/package.json index 2d0af39..4210b49 100644 --- a/client/package.json +++ b/client/package.json @@ -14,6 +14,7 @@ "@react-navigation/native": "^7.1.8", "expo": "~54.0.32", "expo-constants": "~18.0.13", + "expo-dev-client": "^6.0.20", "expo-font": "~14.0.11", "expo-linear-gradient": "^15.0.8", "expo-linking": "~8.0.11", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 06a100e..636504a 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: expo-constants: specifier: ~18.0.13 version: 18.0.13(expo@54.0.32)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0)) + expo-dev-client: + specifier: ^6.0.20 + version: 6.0.20(expo@54.0.32) expo-font: specifier: ~14.0.11 version: 14.0.11(expo@54.0.32)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -1306,6 +1309,9 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + anser@1.4.10: resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} @@ -1862,6 +1868,26 @@ packages: expo: '*' react-native: '*' + expo-dev-client@6.0.20: + resolution: {integrity: sha512-5XjoVlj1OxakNxy55j/AUaGPrDOlQlB6XdHLLWAw61w5ffSpUDHDnuZzKzs9xY1eIaogOqTOQaAzZ2ddBkdXLA==} + peerDependencies: + expo: '*' + + expo-dev-launcher@6.0.20: + resolution: {integrity: sha512-a04zHEeT9sB0L5EB38fz7sNnUKJ2Ar1pXpcyl60Ki8bXPNCs9rjY7NuYrDkP/irM8+1DklMBqHpyHiLyJ/R+EA==} + peerDependencies: + expo: '*' + + expo-dev-menu-interface@2.0.0: + resolution: {integrity: sha512-BvAMPt6x+vyXpThsyjjOYyjwfjREV4OOpQkZ0tNl+nGpsPfcY9mc6DRACoWnH9KpLzyIt3BOgh3cuy/h/OxQjw==} + peerDependencies: + expo: '*' + + expo-dev-menu@7.0.18: + resolution: {integrity: sha512-4kTdlHrnZCAWCT6tZRQHSSjZ7vECFisL4T+nsG/GJDo/jcHNaOVGV5qPV9wzlTxyMk3YOPggRw4+g7Ownrg5eA==} + peerDependencies: + expo: '*' + expo-file-system@19.0.21: resolution: {integrity: sha512-s3DlrDdiscBHtab/6W1osrjGL+C2bvoInPJD7sOwmxfJ5Woynv2oc+Fz1/xVXaE/V7HE/+xrHC/H45tu6lZzzg==} peerDependencies: @@ -1875,6 +1901,9 @@ packages: react: '*' react-native: '*' + expo-json-utils@0.15.0: + resolution: {integrity: sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==} + expo-keep-awake@15.0.8: resolution: {integrity: sha512-YK9M1VrnoH1vLJiQzChZgzDvVimVoriibiDIFLbQMpjYBnvyfUeHJcin/Gx1a+XgupNXy92EQJLgI/9ZuXajYQ==} peerDependencies: @@ -1900,6 +1929,11 @@ packages: expo: '*' react: '*' + expo-manifests@1.0.10: + resolution: {integrity: sha512-oxDUnURPcL4ZsOBY6X1DGWGuoZgVAFzp6PISWV7lPP2J0r8u1/ucuChBgpK7u1eLGFp6sDIPwXyEUCkI386XSQ==} + peerDependencies: + expo: '*' + expo-modules-autolinking@3.0.24: resolution: {integrity: sha512-TP+6HTwhL7orDvsz2VzauyQlXJcAWyU3ANsZ7JGL4DQu8XaZv/A41ZchbtAYLfozNA2Ya1Hzmhx65hXryBMjaQ==} hasBin: true @@ -1966,6 +2000,11 @@ packages: react: '*' react-native: '*' + expo-updates-interface@2.0.0: + resolution: {integrity: sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==} + peerDependencies: + expo: '*' + expo-web-browser@15.0.10: resolution: {integrity: sha512-fvDhW4bhmXAeWFNFiInmsGCK83PAqAcQaFyp/3pE/jbdKmFKoRCWr46uZGIfN4msLK/OODhaQ/+US7GSJNDHJg==} peerDependencies: @@ -1998,6 +2037,9 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -2339,6 +2381,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -5166,6 +5211,13 @@ snapshots: agent-base@7.1.4: {} + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + anser@1.4.10: {} ansi-escapes@4.3.2: @@ -5759,6 +5811,35 @@ snapshots: transitivePeerDependencies: - supports-color + expo-dev-client@6.0.20(expo@54.0.32): + dependencies: + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-dev-launcher: 6.0.20(expo@54.0.32) + expo-dev-menu: 7.0.18(expo@54.0.32) + expo-dev-menu-interface: 2.0.0(expo@54.0.32) + expo-manifests: 1.0.10(expo@54.0.32) + expo-updates-interface: 2.0.0(expo@54.0.32) + transitivePeerDependencies: + - supports-color + + expo-dev-launcher@6.0.20(expo@54.0.32): + dependencies: + ajv: 8.17.1 + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-dev-menu: 7.0.18(expo@54.0.32) + expo-manifests: 1.0.10(expo@54.0.32) + transitivePeerDependencies: + - supports-color + + expo-dev-menu-interface@2.0.0(expo@54.0.32): + dependencies: + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + + expo-dev-menu@7.0.18(expo@54.0.32): + dependencies: + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-dev-menu-interface: 2.0.0(expo@54.0.32) + expo-file-system@19.0.21(expo@54.0.32)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0)): dependencies: expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -5771,6 +5852,8 @@ snapshots: react: 19.1.0 react-native: 0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0) + expo-json-utils@0.15.0: {} + expo-keep-awake@15.0.8(expo@54.0.32)(react@19.1.0): dependencies: expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -5798,6 +5881,14 @@ snapshots: react: 19.1.0 rtl-detect: 1.1.2 + expo-manifests@1.0.10(expo@54.0.32): + dependencies: + '@expo/config': 12.0.13 + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-json-utils: 0.15.0 + transitivePeerDependencies: + - supports-color + expo-modules-autolinking@3.0.24: dependencies: '@expo/spawn-async': 1.7.2 @@ -5885,6 +5976,10 @@ snapshots: react-native: 0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0) react-native-is-edge-to-edge: 1.2.1(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-updates-interface@2.0.0(expo@54.0.32): + dependencies: + expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + expo-web-browser@15.0.10(expo@54.0.32)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0)): dependencies: expo: 54.0.32(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.22)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -5931,6 +6026,8 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-uri@3.1.0: {} + fb-watchman@2.0.2: dependencies: bser: 2.1.1 @@ -6301,6 +6398,8 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@1.0.0: {} + json5@2.2.3: {} kleur@3.0.3: {}