Merge pull request 'Hao' (#8) from Hao into main
Reviewed-on: #8
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"expo": {
|
||||
"name": "Hey Mama",
|
||||
"slug": "hey-mama",
|
||||
"name": "client",
|
||||
"slug": "client",
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/images/icon.png",
|
||||
"scheme": "heymama",
|
||||
"scheme": "client",
|
||||
"userInterfaceStyle": "automatic",
|
||||
"newArchEnabled": true,
|
||||
"splash": {
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"bundleIdentifier": "com.heymama.app"
|
||||
"bundleIdentifier": "com.anonymous.client"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useLayoutEffect, useMemo, useState, useCallback, useRef } from 'react';
|
||||
import { StyleSheet, View, Dimensions, Text, Pressable, PanResponder, Animated as RNAnimated } from 'react-native';
|
||||
import { StyleSheet, View, Dimensions, Text, Pressable, PanResponder, Animated as RNAnimated, ImageBackground } from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation, useFocusEffect } from 'expo-router';
|
||||
import Animated, {
|
||||
@@ -39,6 +39,40 @@ import LikeIcon from '@/assets/images/icon/like_icon.svg';
|
||||
|
||||
const { height: SCREEN_HEIGHT } = Dimensions.get('window');
|
||||
|
||||
// 预定义风景图列表
|
||||
const NATURE_IMAGES = [
|
||||
require('@/assets/theme/nature/1.png'),
|
||||
require('@/assets/theme/nature/2.png'),
|
||||
require('@/assets/theme/nature/3.png'),
|
||||
require('@/assets/theme/nature/4.png'),
|
||||
require('@/assets/theme/nature/5.png'),
|
||||
require('@/assets/theme/nature/6.png'),
|
||||
require('@/assets/theme/nature/7.png'),
|
||||
require('@/assets/theme/nature/8.png'),
|
||||
require('@/assets/theme/nature/9.png'),
|
||||
require('@/assets/theme/nature/10.png'),
|
||||
require('@/assets/theme/nature/11.png'),
|
||||
require('@/assets/theme/nature/12.png'),
|
||||
require('@/assets/theme/nature/13.png'),
|
||||
require('@/assets/theme/nature/14.png'),
|
||||
require('@/assets/theme/nature/15.png'),
|
||||
require('@/assets/theme/nature/17.png'),
|
||||
require('@/assets/theme/nature/18.png'),
|
||||
require('@/assets/theme/nature/19.png'),
|
||||
require('@/assets/theme/nature/20.png'),
|
||||
require('@/assets/theme/nature/22.png'),
|
||||
];
|
||||
|
||||
// 预定义颜色列表
|
||||
const THEME_COLORS = [
|
||||
'#F7D9BF',
|
||||
'#CBF2D8',
|
||||
'#F5CDDE',
|
||||
'#F2ECCB',
|
||||
'#E2CBF2',
|
||||
'#CBD9F2',
|
||||
];
|
||||
|
||||
export default function HomeScreen() {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
@@ -126,12 +160,26 @@ export default function HomeScreen() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const backgroundColor = themeMode === 'color' ? '#F3D0E1' : '#F4D6C2';
|
||||
const backgroundColor = useMemo(() => {
|
||||
if (themeMode === 'color') {
|
||||
const colorIndex = Math.floor(index / 10) % THEME_COLORS.length;
|
||||
return THEME_COLORS[colorIndex];
|
||||
}
|
||||
return '#F4D6C2'; // 风景模式下的默认底色(图片加载前显示)
|
||||
}, [themeMode, index]);
|
||||
|
||||
// 计算当前应该显示的风景图索引(滑动 10 次切换一张)
|
||||
const natureImageIndex = useMemo(() => {
|
||||
return Math.floor(index / 10) % NATURE_IMAGES.length;
|
||||
}, [index]);
|
||||
|
||||
const currentNatureImage = NATURE_IMAGES[natureImageIndex];
|
||||
|
||||
useLayoutEffect(() => {
|
||||
navigation.setOptions({
|
||||
headerShadowVisible: false,
|
||||
headerStyle: { backgroundColor },
|
||||
headerStyle: { backgroundColor: themeMode === 'scenery' ? 'transparent' : backgroundColor },
|
||||
headerTransparent: themeMode === 'scenery',
|
||||
headerRight: () => (
|
||||
<View style={styles.headerRight}>
|
||||
<CircleIconButton
|
||||
@@ -149,7 +197,7 @@ export default function HomeScreen() {
|
||||
</View>
|
||||
),
|
||||
});
|
||||
}, [backgroundColor, navigation, t]);
|
||||
}, [backgroundColor, themeMode, navigation, t]);
|
||||
|
||||
const textAnimatedStyle = useAnimatedStyle(() => ({
|
||||
transform: [{ translateY: translateY.value }],
|
||||
@@ -241,10 +289,11 @@ export default function HomeScreen() {
|
||||
|
||||
// 2. 保存到收藏夹,包含当前背景信息
|
||||
await addFavorite({
|
||||
id: typeof currentContentId === 'number' ? String(currentContentId) : (item as any).id,
|
||||
favId: String(Date.now()), // 生成唯一 ID
|
||||
id: item.id,
|
||||
date: dateStr,
|
||||
themeMode: themeMode,
|
||||
background: backgroundColor, // 目前存储的是颜色值
|
||||
background: themeMode === 'scenery' ? String(natureImageIndex) : backgroundColor,
|
||||
});
|
||||
|
||||
// 3. 爱心缩放动画
|
||||
@@ -267,8 +316,15 @@ export default function HomeScreen() {
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor }]} {...panResponder.panHandlers}>
|
||||
<Animated.View style={[styles.card, textAnimatedStyle]}>
|
||||
<Text style={styles.text}>{item.text}</Text>
|
||||
{themeMode === 'scenery' && (
|
||||
<ImageBackground
|
||||
source={currentNatureImage}
|
||||
style={StyleSheet.absoluteFill}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
)}
|
||||
<Animated.View style={[styles.card, textAnimatedStyle, themeMode === 'scenery' && styles.sceneryCard]}>
|
||||
<Text style={[styles.text, themeMode === 'scenery' && styles.sceneryText]}>{item.text}</Text>
|
||||
</Animated.View>
|
||||
|
||||
<View style={styles.actions}>
|
||||
@@ -281,9 +337,13 @@ export default function HomeScreen() {
|
||||
style={styles.reactionInner}
|
||||
>
|
||||
{likeFilled ? (
|
||||
<LikeFilledIcon width={35} height={36} />
|
||||
<LikeFilledIcon width={35} height={36} style={{ color: '#EA6969' }} />
|
||||
) : (
|
||||
<LikeIcon width={35} height={36} />
|
||||
<LikeIcon
|
||||
width={35}
|
||||
height={36}
|
||||
style={{ color: themeMode === 'scenery' ? '#FFFFFF' : '#5E2A28' }}
|
||||
/>
|
||||
)}
|
||||
</Pressable>
|
||||
</Animated.View>
|
||||
@@ -342,9 +402,15 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
},
|
||||
card: {
|
||||
paddingHorizontal: 30,
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 30,
|
||||
zIndex: 5, // 降低层级,防止遮挡底部按钮
|
||||
},
|
||||
text: {
|
||||
fontSize: 22,
|
||||
@@ -353,6 +419,16 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '700',
|
||||
textAlign: 'center',
|
||||
},
|
||||
sceneryCard: {
|
||||
// 风景模式下稍微收窄文案宽度,增加呼吸感
|
||||
paddingHorizontal: 50,
|
||||
},
|
||||
sceneryText: {
|
||||
color: '#FFFFFF',
|
||||
textShadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||
textShadowOffset: { width: 0, height: 1 },
|
||||
textShadowRadius: 4,
|
||||
},
|
||||
actions: {
|
||||
position: 'absolute',
|
||||
bottom: SCREEN_HEIGHT * 0.16,
|
||||
@@ -360,6 +436,7 @@ const styles = StyleSheet.create({
|
||||
right: 0,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
zIndex: 20, // 提升层级,确保在最顶层可点击
|
||||
},
|
||||
reactionButton: {
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -140,14 +140,13 @@ export default function OnboardingScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
const onSkip = () => {
|
||||
const onSkip = async () => {
|
||||
// 跳过整个 Onboarding:仍生成一个“全跳过”的最小画像,保证下游可用
|
||||
const scoringProfile = buildUserProfileFromQuestionnaire({});
|
||||
void setUserProfileScoring(scoringProfile);
|
||||
await setUserProfileScoring(scoringProfile);
|
||||
|
||||
// 标记已完成,避免下次启动再次进入 Onboarding
|
||||
void setOnboardingCompleted(true);
|
||||
|
||||
await setOnboardingCompleted(true);
|
||||
router.replace('/(app)/home');
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
import { useRouter } from 'expo-router';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
import { getOnboardingCompleted, getConsentAccepted, setOnboardingCompleted, setConsentAccepted } from '@/src/storage/appStorage';
|
||||
import { getOnboardingCompleted, getConsentAccepted } from '@/src/storage/appStorage';
|
||||
|
||||
/**
|
||||
* 启动分发:根据 consent 和 onboarding 状态跳转
|
||||
@@ -14,9 +13,6 @@ export default function Index() {
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
// 注意:不要在启动时无条件清空存储,否则 Onboarding/画像等数据无法持久化。
|
||||
// 如需调试重置,请在开发期手动清空或自行加调试开关。
|
||||
|
||||
// 1. 检查是否同意协议
|
||||
const consentAccepted = await getConsentAccepted();
|
||||
if (cancelled) return;
|
||||
@@ -26,9 +22,17 @@ export default function Index() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 检查 Onboarding
|
||||
// 2. 检查 Onboarding 是否已完成
|
||||
const completed = await getOnboardingCompleted();
|
||||
router.replace(completed ? '/(app)/home' : '/(onboarding)/onboarding');
|
||||
if (cancelled) return;
|
||||
|
||||
if (completed) {
|
||||
// 如果已经完成过流程,直接进 Home
|
||||
router.replace('/(app)/home');
|
||||
} else {
|
||||
// 如果是首次进入(或未完成流程),进入 Onboarding
|
||||
router.replace('/(onboarding)/onboarding');
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
@@ -45,4 +49,3 @@ export default function Index() {
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
|
||||
});
|
||||
|
||||
|
||||
BIN
client/assets/theme/nature/1.png
Normal file
|
After Width: | Height: | Size: 358 KiB |
BIN
client/assets/theme/nature/10.png
Normal file
|
After Width: | Height: | Size: 629 KiB |
BIN
client/assets/theme/nature/11.png
Normal file
|
After Width: | Height: | Size: 532 KiB |
BIN
client/assets/theme/nature/12.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
client/assets/theme/nature/13.png
Normal file
|
After Width: | Height: | Size: 449 KiB |
BIN
client/assets/theme/nature/14.png
Normal file
|
After Width: | Height: | Size: 525 KiB |
BIN
client/assets/theme/nature/15.png
Normal file
|
After Width: | Height: | Size: 693 KiB |
BIN
client/assets/theme/nature/17.png
Normal file
|
After Width: | Height: | Size: 458 KiB |
BIN
client/assets/theme/nature/18.png
Normal file
|
After Width: | Height: | Size: 593 KiB |
BIN
client/assets/theme/nature/19.png
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
client/assets/theme/nature/2.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
client/assets/theme/nature/20.png
Normal file
|
After Width: | Height: | Size: 461 KiB |
BIN
client/assets/theme/nature/22.png
Normal file
|
After Width: | Height: | Size: 606 KiB |
BIN
client/assets/theme/nature/3.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
client/assets/theme/nature/4.png
Normal file
|
After Width: | Height: | Size: 388 KiB |
BIN
client/assets/theme/nature/5.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
client/assets/theme/nature/6.png
Normal file
|
After Width: | Height: | Size: 721 KiB |
BIN
client/assets/theme/nature/7.png
Normal file
|
After Width: | Height: | Size: 358 KiB |
BIN
client/assets/theme/nature/8.png
Normal file
|
After Width: | Height: | Size: 415 KiB |
BIN
client/assets/theme/nature/9.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
@@ -50,6 +50,29 @@ type Props = {
|
||||
type Page = 'root' | 'favorites' | 'dailyReminder' | 'widget' | 'language' | 'widgetHowTo';
|
||||
type NavDirection = 'forward' | 'back';
|
||||
|
||||
const NATURE_IMAGES = [
|
||||
require('@/assets/theme/nature/1.png'),
|
||||
require('@/assets/theme/nature/2.png'),
|
||||
require('@/assets/theme/nature/3.png'),
|
||||
require('@/assets/theme/nature/4.png'),
|
||||
require('@/assets/theme/nature/5.png'),
|
||||
require('@/assets/theme/nature/6.png'),
|
||||
require('@/assets/theme/nature/7.png'),
|
||||
require('@/assets/theme/nature/8.png'),
|
||||
require('@/assets/theme/nature/9.png'),
|
||||
require('@/assets/theme/nature/10.png'),
|
||||
require('@/assets/theme/nature/11.png'),
|
||||
require('@/assets/theme/nature/12.png'),
|
||||
require('@/assets/theme/nature/13.png'),
|
||||
require('@/assets/theme/nature/14.png'),
|
||||
require('@/assets/theme/nature/15.png'),
|
||||
require('@/assets/theme/nature/17.png'),
|
||||
require('@/assets/theme/nature/18.png'),
|
||||
require('@/assets/theme/nature/19.png'),
|
||||
require('@/assets/theme/nature/20.png'),
|
||||
require('@/assets/theme/nature/22.png'),
|
||||
];
|
||||
|
||||
export default function ProfileModal({ visible, name: propName, onClose }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -260,11 +283,11 @@ function FavoritesPage({ visible, page }: { visible: boolean; page: Page }) {
|
||||
setFavorites(list);
|
||||
}
|
||||
|
||||
async function handleRemove(id: string) {
|
||||
async function handleRemove(favId: string) {
|
||||
// 1. 调用存储层移除收藏
|
||||
await removeFavorite(id);
|
||||
await removeFavorite(favId);
|
||||
// 2. 更新本地状态
|
||||
setFavorites(prev => prev.filter(item => item.id !== id));
|
||||
setFavorites(prev => prev.filter(item => item.favId !== favId));
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -274,7 +297,7 @@ function FavoritesPage({ visible, page }: { visible: boolean; page: Page }) {
|
||||
) : (
|
||||
<FlatList
|
||||
data={favorites}
|
||||
keyExtractor={(it) => it.id}
|
||||
keyExtractor={(it) => it.favId}
|
||||
contentContainerStyle={styles.favList}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
@@ -290,11 +313,30 @@ function FavoritesPage({ visible, page }: { visible: boolean; page: Page }) {
|
||||
<View style={styles.favRight}>
|
||||
<View style={[
|
||||
styles.favThumb,
|
||||
{ backgroundColor: item.background } // 动态同步 Home 页的背景
|
||||
item.themeMode === 'scenery' ? {} : { backgroundColor: item.background }
|
||||
]}>
|
||||
<Text style={styles.favThumbText} numberOfLines={4}>{item.text}</Text>
|
||||
{item.themeMode === 'scenery' ? (
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
<Image
|
||||
source={NATURE_IMAGES[parseInt(item.background)]}
|
||||
style={{
|
||||
width: width * 0.6,
|
||||
height: 800, // 假设原图较高,设置一个较大的高度
|
||||
position: 'absolute',
|
||||
bottom: 0, // 关键:将图片底部对齐容器底部
|
||||
}}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
<Text style={[
|
||||
styles.favThumbText,
|
||||
item.themeMode === 'scenery' && { color: '#FFFFFF', textShadowColor: 'rgba(0,0,0,0.5)', textShadowOffset: {width:0, height:1}, textShadowRadius: 3 }
|
||||
]} numberOfLines={4}>
|
||||
{item.text}
|
||||
</Text>
|
||||
<Pressable
|
||||
onPress={() => handleRemove(item.id)}
|
||||
onPress={() => handleRemove(item.favId)}
|
||||
style={styles.favRemoveBtn}
|
||||
hitSlop={10}
|
||||
>
|
||||
@@ -765,6 +807,7 @@ const styles = StyleSheet.create({
|
||||
position: 'relative',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(119, 47, 0, 0.05)',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
favThumbText: {
|
||||
fontSize: 15,
|
||||
|
||||
@@ -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,19 +2238,26 @@ 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`)"
|
||||
- "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+react@1_nvlvke5tn7wk5pigfsu7j4ieeq/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-native@0.8_7rhpxisdkrzvrgzbu7ct455kta/node_modules/expo`)"
|
||||
- "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.13_expo_rjurfbyy5kjn57nkkfxix5iqea/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+react@_e6k2hjkd5k4lph2ersbp3gfshy/node_modules/expo-linear-gradient/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`)"
|
||||
- "ExpoLocalization (from `../node_modules/.pnpm/expo-localization@17.0.8_expo@54.0.32_react@19.1.0/node_modules/expo-localization/ios`)"
|
||||
- "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`)"
|
||||
@@ -2089,7 +2294,7 @@ DEPENDENCIES:
|
||||
- "React-logger (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/logger`)"
|
||||
- "React-Mapbuffer (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`)"
|
||||
- "React-microtasksnativemodule (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/react/nativemodule/microtasks`)"
|
||||
- "react-native-safe-area-context (from `../node_modules/.pnpm/react-native-safe-area-context@5.6.2_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1_azuxgonsvxb2yngtegtuvyxcpi/node_modules/react-native-safe-area-context`)"
|
||||
- "react-native-safe-area-context (from `../node_modules/.pnpm/react-native-safe-area-context@5.6.2_react-native@0.81.5_@babel+core@7.28.6_@types+reac_14122a3aa345cfabcc022a0f638ef16d/node_modules/react-native-safe-area-context`)"
|
||||
- "React-NativeModulesApple (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/react/nativemodule/core/platform/ios`)"
|
||||
- "React-oscompat (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/oscompat`)"
|
||||
- "React-perflogger (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/reactperflogger`)"
|
||||
@@ -2121,11 +2326,12 @@ DEPENDENCIES:
|
||||
- ReactCodegen (from `build/generated/ios`)
|
||||
- "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_@types_fp4qq3a7mejmut52v6jrlvxlzi/node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNReanimated (from `../node_modules/.pnpm/react-native-reanimated@4.1.6_@babel+core@7.28.6_react-native-worklets@0.5.1_@babel+core@7.28_ky3sbxf6i7nkyacc2hzg3xcz4q/node_modules/react-native-reanimated`)"
|
||||
- "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`)"
|
||||
- "RNWorklets (from `../node_modules/.pnpm/react-native-worklets@0.5.1_@babel+core@7.28.6_react-native@0.81.5_@babel+core@7.28.6_@types+_5atwepuw3zy3crkgvetf35tkve/node_modules/react-native-worklets`)"
|
||||
- "RNWorklets (from `../node_modules/.pnpm/react-native-worklets@0.5.1_@babel+core@7.28.6_react-native@0.81.5_@babel+core@7.28.6_@_40f69326ce21d3f9f6d74d3965fd9adf/node_modules/react-native-worklets`)"
|
||||
- "Yoga (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/yoga`)"
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -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+react@1_nvlvke5tn7wk5pigfsu7j4ieeq/node_modules/expo-notifications/ios"
|
||||
: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-native@0.8_7rhpxisdkrzvrgzbu7ct455kta/node_modules/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,11 +2362,11 @@ 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.13_expo_rjurfbyy5kjn57nkkfxix5iqea/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:
|
||||
:path: "../node_modules/.pnpm/expo-linear-gradient@15.0.8_expo@54.0.32_react-native@0.81.5_@babel+core@7.28.6_@types+react@_e6k2hjkd5k4lph2ersbp3gfshy/node_modules/expo-linear-gradient/ios"
|
||||
:path: "../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:
|
||||
:path: "../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"
|
||||
ExpoLocalization:
|
||||
@@ -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:
|
||||
@@ -2231,7 +2451,7 @@ EXTERNAL SOURCES:
|
||||
React-microtasksnativemodule:
|
||||
: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/ReactCommon/react/nativemodule/microtasks"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/.pnpm/react-native-safe-area-context@5.6.2_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1_azuxgonsvxb2yngtegtuvyxcpi/node_modules/react-native-safe-area-context"
|
||||
:path: "../node_modules/.pnpm/react-native-safe-area-context@5.6.2_react-native@0.81.5_@babel+core@7.28.6_@types+reac_14122a3aa345cfabcc022a0f638ef16d/node_modules/react-native-safe-area-context"
|
||||
React-NativeModulesApple:
|
||||
: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/ReactCommon/react/nativemodule/core/platform/ios"
|
||||
React-oscompat:
|
||||
@@ -2295,34 +2515,43 @@ EXTERNAL SOURCES:
|
||||
ReactNativeDependencies:
|
||||
: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_@types_fp4qq3a7mejmut52v6jrlvxlzi/node_modules/@react-native-async-storage/async-storage"
|
||||
: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+core@7.28_ky3sbxf6i7nkyacc2hzg3xcz4q/node_modules/react-native-reanimated"
|
||||
: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:
|
||||
:path: "../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:
|
||||
:path: "../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"
|
||||
RNWorklets:
|
||||
:path: "../node_modules/.pnpm/react-native-worklets@0.5.1_@babel+core@7.28.6_react-native@0.81.5_@babel+core@7.28.6_@types+_5atwepuw3zy3crkgvetf35tkve/node_modules/react-native-worklets"
|
||||
:path: "../node_modules/.pnpm/react-native-worklets@0.5.1_@babel+core@7.28.6_react-native@0.81.5_@babel+core@7.28.6_@_40f69326ce21d3f9f6d74d3965fd9adf/node_modules/react-native-worklets"
|
||||
Yoga:
|
||||
: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/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
EXApplication: 13420f8139864183f8a04fd6099077bdf8cfb186
|
||||
EXConstants: 3feb66fd1d94202fc1f0946d74e029d8b224b60e
|
||||
EXNotifications: 2a3feb7af6194828d9aafda72f63a9a03866230a
|
||||
Expo: b8d64eb9a496ebe8c71e3dae7eeb7f394b146b80
|
||||
ExpoAsset: d999f3bbd998a750f3b74cb913229848901b926b
|
||||
ExpoFileSystem: aefcd337b94b874f88752ebefc52813b84992fad
|
||||
ExpoFont: c625dbd97ed57e9089b172b2a7bb99003d074664
|
||||
ExpoHead: b691a2ed7ab02ed820b6c6468941832d34969c29
|
||||
ExpoKeepAwake: 44bf6715bc1d2ddb17afe19d927cd039cda123f0
|
||||
ExpoLinearGradient: 814a21fc4056c3cf606e4f19e31e47074c5b5a86
|
||||
ExpoLinking: ebf543fd411d56375cb4eee07f6ab4e31c7ad959
|
||||
ExpoLocalization: 6ac6f326210f0a3141ef6f58ab8f8f4ed003b485
|
||||
ExpoModulesCore: 77496909fd3c800f97f7f2007dd26aeac4bb3798
|
||||
ExpoSplashScreen: 72fbc6dd9d6404dd9d0725a56c9ac1383bc0b14f
|
||||
ExpoWebBrowser: 88b116cd378d9609c776c0903fe4070fca461588
|
||||
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
|
||||
ExpoHead: 4425246bc93411f0fe7f6945f95f698e91db8780
|
||||
ExpoKeepAwake: 55f75eca6499bb9e4231ebad6f3e9cb8f99c0296
|
||||
ExpoLinearGradient: 809102bdb979f590083af49f7fa4805cd931bd58
|
||||
ExpoLinking: 8f0aaf69aa56f832913030503b6263dc6f647f37
|
||||
ExpoLocalization: d9168d5300a5b03e5e78b986124d11fb6ec3ebbd
|
||||
ExpoModulesCore: f3da4f1ab5a8375d0beafab763739dbee8446583
|
||||
ExpoSplashScreen: bc3cffefca2716e5f22350ca109badd7e50ec14d
|
||||
ExpoWebBrowser: 17b064c621789e41d4816c95c93f429b84971f52
|
||||
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
|
||||
FBLazyVector: e95a291ad2dadb88e42b06e0c5fb8262de53ec12
|
||||
hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172
|
||||
RCTDeprecation: 943572d4be82d480a48f4884f670135ae30bf990
|
||||
@@ -2330,71 +2559,72 @@ SPEC CHECKSUMS:
|
||||
RCTTypeSafety: 16a4144ca3f959583ab019b57d5633df10b5e97c
|
||||
React: 914f8695f9bf38e6418228c2ffb70021e559f92f
|
||||
React-callinvoker: 1c0808402aee0c6d4a0d8e7220ce6547af9fba71
|
||||
React-Core: 4ae98f9e8135b8ddbd7c98730afb6fdae883db90
|
||||
React-Core-prebuilt: 8f4cca589c14e8cf8fc6db4587ef1c2056b5c151
|
||||
React-CoreModules: e878a90bb19b8f3851818af997dbae3b3b0a27ac
|
||||
React-cxxreact: 28af9844f6dc87be1385ab521fbfb3746f19563c
|
||||
React-Core: c61410ef0ca6055e204a963992e363227e0fd1c5
|
||||
React-Core-prebuilt: 02f0ad625ddd47463c009c2d0c5dd35c0d982599
|
||||
React-CoreModules: 1f6d1744b5f9f2ec684a4bb5ced25370f87e5382
|
||||
React-cxxreact: 3af79478e8187b63ffc22b794cd42d3fc1f1f2da
|
||||
React-debug: 6328c2228e268846161f10082e80dc69eac2e90a
|
||||
React-defaultsnativemodule: afc9d809ec75780f39464a6949c07987fbea488c
|
||||
React-domnativemodule: 91a233260411d41f27f67aa1358b7f9f0bfd101d
|
||||
React-Fabric: 21f349b5e93f305a3c38c885902683a9c79cf983
|
||||
React-FabricComponents: 47ac634cc9ecc64b30a9997192f510eebe4177e4
|
||||
React-FabricImage: 21873acd6d4a51a0b97c133141051c7acb11cc86
|
||||
React-featureflags: 653f469f0c3c9dc271d610373e3b6e66a9fd847d
|
||||
React-featureflagsnativemodule: c91a8a3880e0f4838286402241ead47db43aed28
|
||||
React-graphics: b4bdb0f635b8048c652a5d2b73eb8b1ddd950f24
|
||||
React-hermes: fcfad3b917400f49026f3232561e039c9d1c34bf
|
||||
React-idlecallbacksnativemodule: 8cb83207e39f8179ac1d344b6177c6ab3ccebcdc
|
||||
React-ImageManager: 396128004783fc510e629124dce682d38d1088e7
|
||||
React-jserrorhandler: b58b788d788cdbf8bda7db74a88ebfcffc8a0795
|
||||
React-jsi: d2c3f8555175371c02da6dfe7ed1b64b55a9d6c0
|
||||
React-jsiexecutor: ba537434eb45ee018b590ed7d29ee233fddb8669
|
||||
React-jsinspector: f21b6654baf96cb9f71748844a32468a5f73ad51
|
||||
React-jsinspectorcdp: 3f8be4830694c3c1c39442e50f8db877966d43f0
|
||||
React-jsinspectornetwork: 70e41469565712ad60e11d9c8b8f999b9f7f61eb
|
||||
React-jsinspectortracing: eccf9bfa4ec7f130d514f215cfb2222dc3c0e270
|
||||
React-jsitooling: b376a695f5a507627f7934748533b24eed1751ca
|
||||
React-jsitracing: 5c8c3273dda2d95191cc0612fb5e71c4d9018d2a
|
||||
React-logger: c3e2f8a2e284341205f61eef3d4677ab5a309dfd
|
||||
React-Mapbuffer: 603c18db65844bb81dbe62fee8fcc976eaeb7108
|
||||
React-microtasksnativemodule: d77e0c426fce34c23227394c96ca1033b30c813c
|
||||
react-native-safe-area-context: 53f796cb6c814661bbe99fbdfd0585d07b996cdd
|
||||
React-NativeModulesApple: 1664340b8750d64e0ef3907c5e53d9481f74bcbd
|
||||
React-defaultsnativemodule: d635ef36d755321e5d6fc065bd166b2c5a0e9833
|
||||
React-domnativemodule: dd28f6d96cd21236e020be2eff6fe0b7d4ec3b66
|
||||
React-Fabric: 2e32c3fdbb1fbcf5fde54607e3abe453c6652ce2
|
||||
React-FabricComponents: 5ed0cdb81f6b91656cb4d3be432feaa28a58071a
|
||||
React-FabricImage: 2bc714f818cb24e454f5d3961864373271b2faf8
|
||||
React-featureflags: 847642f41fa71ad4eec5e0351badebcad4fe6171
|
||||
React-featureflagsnativemodule: c868a544b2c626fa337bcbd364b1befe749f0d3f
|
||||
React-graphics: 192ec701def5b3f2a07db2814dfba5a44986cff6
|
||||
React-hermes: e875778b496c86d07ab2ccaa36a9505d248a254b
|
||||
React-idlecallbacksnativemodule: 4d57965cdf82c14ee3b337189836cd8491632b76
|
||||
React-ImageManager: bd0b99e370b13de82c9cd15f0f08144ff3de079e
|
||||
React-jserrorhandler: a2fdef4cbcfdcdf3fa9f5d1f7190f7fd4535248d
|
||||
React-jsi: 89d43d1e7d4d0663f8ba67e0b39eb4e4672c27de
|
||||
React-jsiexecutor: abe4874aaab90dfee5dec480680220b2f8af07e3
|
||||
React-jsinspector: a0b3e051aef842b0b2be2353790ae2b2a5a65a8f
|
||||
React-jsinspectorcdp: 6346013b2247c6263fbf5199adf4a8751e53bd89
|
||||
React-jsinspectornetwork: 26281aa50d49fc1ec93abf981d934698fa95714f
|
||||
React-jsinspectortracing: 55eedf6d57540507570259a778663b90060bbd6e
|
||||
React-jsitooling: 0e001113fa56d8498aa8ac28437ac0d36348e51a
|
||||
React-jsitracing: b713793eb8a5bbc4d86a84e9d9e5023c0f58cbaf
|
||||
React-logger: 50fdb9a8236da90c0b1072da5c32ee03aeb5bf28
|
||||
React-Mapbuffer: 9050ee10c19f4f7fca8963d0211b2854d624973e
|
||||
React-microtasksnativemodule: f775db9e991c6f3b8ccbc02bfcde22770f96e23b
|
||||
react-native-safe-area-context: 37e680fc4cace3c0030ee46e8987d24f5d3bdab2
|
||||
React-NativeModulesApple: 8969913947d5b576de4ed371a939455a8daf28aa
|
||||
React-oscompat: ce47230ed20185e91de62d8c6d139ae61763d09c
|
||||
React-perflogger: b1af3cfb3f095f819b2814910000392a8e17ba9f
|
||||
React-performancetimeline: f9ec65b77bcadbc7bd8b47a6f4b4b697da7b1490
|
||||
React-perflogger: 02b010e665772c7dcb859d85d44c1bfc5ac7c0e4
|
||||
React-performancetimeline: 130db956b5a83aa4fb41ddf5ae68da89f3fb1526
|
||||
React-RCTActionSheet: 0b14875b3963e9124a5a29a45bd1b22df8803916
|
||||
React-RCTAnimation: 60f6eca214a62b9673f64db6df3830cee902b5af
|
||||
React-RCTAppDelegate: 37734b39bac108af30a0fd9d3e1149ec68b82c28
|
||||
React-RCTBlob: 83fbcbd57755caf021787324aac2fe9b028cc264
|
||||
React-RCTFabric: a05cb1df484008db3753c8b4a71e4c6d9f1e43a6
|
||||
React-RCTFBReactNativeSpec: d58d7ae9447020bbbac651e3b0674422aba18266
|
||||
React-RCTImage: 47aba3be7c6c64f956b7918ab933769602406aac
|
||||
React-RCTLinking: 2dbaa4df2e4523f68baa07936bd8efdfa34d5f31
|
||||
React-RCTNetwork: 1fca7455f9dedf7de2b95bec438da06680f3b000
|
||||
React-RCTRuntime: 17819dd1dfc8613efaf4cbb9d8686baae4a83e5b
|
||||
React-RCTSettings: 01bf91c856862354d3d2f642ccb82f3697a4284a
|
||||
React-RCTText: cb576a3797dcb64933613c522296a07eaafc0461
|
||||
React-RCTVibration: 560af8c086741f3525b8456a482cdbe27f9d098e
|
||||
React-RCTAnimation: a7b90fd2af7bb9c084428867445a1481a8cb112e
|
||||
React-RCTAppDelegate: 3262bedd01263f140ec62b7989f4355f57cec016
|
||||
React-RCTBlob: c17531368702f1ebed5d0ada75a7cf5915072a53
|
||||
React-RCTFabric: 6409edd8cfdc3133b6cc75636d3b858fdb1d11ea
|
||||
React-RCTFBReactNativeSpec: c004b27b4fa3bd85878ad2cf53de3bbec85da797
|
||||
React-RCTImage: c68078a120d0123f4f07a5ac77bea3bb10242f32
|
||||
React-RCTLinking: cf8f9391fe7fe471f96da3a5f0435235eca18c5b
|
||||
React-RCTNetwork: ca31f7c879355760c2d9832a06ee35f517938a20
|
||||
React-RCTRuntime: a6cf4a1e42754fc87f493e538f2ac6b820e45418
|
||||
React-RCTSettings: e0e140b2ff4bf86d34e9637f6316848fc00be035
|
||||
React-RCTText: 75915bace6f7877c03a840cc7b6c622fb62bfa6b
|
||||
React-RCTVibration: 25f26b85e5e432bb3c256f8b384f9269e9529f25
|
||||
React-rendererconsistency: 2dac03f448ff337235fd5820b10f81633328870d
|
||||
React-renderercss: c5c6b7a15948dd28facca39a18ac269073718490
|
||||
React-rendererdebug: 3c9d5e1634273f5a24d84cc5669f290ce0bdc812
|
||||
React-RuntimeApple: 887637d1e12ea8262df7d32bc100467df2302613
|
||||
React-RuntimeCore: 91f779835dc4f8f84777fe5dd24f1a22f96454e4
|
||||
React-runtimeexecutor: 8bb6b738f37b0ada4a6269e6f8ab1133dea0285c
|
||||
React-RuntimeHermes: 4cb93de9fa8b1cc753d200dbe61a01b9ec5f5562
|
||||
React-runtimescheduler: 83dc28f530bfbd2fce84ed13aa7feebdc24e5af7
|
||||
React-timing: 03c7217455d2bff459b27a3811be25796b600f47
|
||||
React-utils: 6d46795ae0444ec8a5d9a5f201157b286bf5250a
|
||||
ReactAppDependencyProvider: c277c5b231881ad4f00cd59e3aa0671b99d7ebee
|
||||
ReactCodegen: 88a1f4643f15841573f833b895bfa2a0c6cb4e7f
|
||||
ReactCommon: e6e232202a447d353e5531f2be82f50f47cbaa9a
|
||||
React-renderercss: 477da167bb96b5ac86d30c5d295412fb853f5453
|
||||
React-rendererdebug: 2a1798c6f3ef5f22d466df24c33653edbabb5b89
|
||||
React-RuntimeApple: 28cf4d8eb18432f6a21abbed7d801ab7f6b6f0b4
|
||||
React-RuntimeCore: 41bf0fd56a00de5660f222415af49879fa49c4f0
|
||||
React-runtimeexecutor: 1afb774dde3011348e8334be69d2f57a359ea43e
|
||||
React-RuntimeHermes: f3b158ea40e8212b1a723a68b4315e7a495c5fc6
|
||||
React-runtimescheduler: 3e1e2bec7300bae512533107d8e54c6e5c63fe0f
|
||||
React-timing: 6fa9883de2e41791e5dc4ec404e5e37f3f50e801
|
||||
React-utils: 6e2035b53d087927768649a11a26c4e092448e34
|
||||
ReactAppDependencyProvider: 1bcd3527ac0390a1c898c114f81ff954be35ed79
|
||||
ReactCodegen: fffa79906f5866f6a5ab5d98480b375191190271
|
||||
ReactCommon: 08810150b1206cc44aecf5f6ae19af32f29151a8
|
||||
ReactNativeDependencies: 71ce9c28beb282aa720ea7b46980fff9669f428a
|
||||
RNCAsyncStorage: e85a99325df9eb0191a6ee2b2a842644c7eb29f4
|
||||
RNReanimated: 10415bc8396eaeac0d7b2c9a1538eae7e607ec9c
|
||||
RNScreens: dd61bc3a3e6f6901ad833efa411917d44827cf51
|
||||
RNSVG: 2825ee146e0f6a16221e852299943e4cceef4528
|
||||
RNWorklets: 9ccdc8112b17af6eee2c85a233891cb80db150ad
|
||||
RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4
|
||||
RNGestureHandler: e0d0bce5599f6120b7adf90c38d2805e2935795f
|
||||
RNReanimated: 9c6a550b41de91cf374e60afd79db93a362f1126
|
||||
RNScreens: d8d6f1792f6e7ac12b0190d33d8d390efc0c1845
|
||||
RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34
|
||||
RNWorklets: 1b50cb7595142f95e70518196ba247ad7f46a52e
|
||||
Yoga: 5934998fbeaef7845dbf698f698518695ab4cd1a
|
||||
|
||||
PODFILE CHECKSUM: dfe3cc75dee014a0abd367bc9e1bdbab0ba64ee3
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,54 +1,28 @@
|
||||
import WidgetKit
|
||||
import SwiftUI
|
||||
|
||||
// V2:纯色背景 + 随机文案小组件(Small/Medium/Large + 点击跳转 Home)
|
||||
// V1:写死文案的小组件(Small/Medium/Large + 点击跳转 Home)
|
||||
|
||||
struct EmotionProvider: TimelineProvider {
|
||||
private let quotes = [
|
||||
"你已经很努力了,今天也值得被温柔对待。",
|
||||
"轻轻呼吸,感受当下的每一刻。",
|
||||
"所有的压力,都会在深呼吸中慢慢消散。",
|
||||
"给生活一点留白,给自己一点温柔。",
|
||||
"不要走得太快,等一等落下的灵魂。",
|
||||
"世界虽嘈杂,但你可以拥有一颗宁静的心。",
|
||||
"每一个瞬间,都是生命最好的安排。",
|
||||
"抱抱自己,辛苦了,亲爱的。",
|
||||
"慢一点也没关系,只要你在前行。",
|
||||
"今天,你对自己微笑了吗?",
|
||||
"愿你历经山河,仍觉得人间值得。",
|
||||
"心简单,世界就简单;心平顺,生活就平顺。",
|
||||
"即使生活偶尔晦暗,你也要成为自己的光。",
|
||||
"别让琐事挤走生活的快乐,别让压力消磨奋斗的激情。"
|
||||
]
|
||||
|
||||
func placeholder(in context: Context) -> EmotionEntry {
|
||||
EmotionEntry(date: Date(), text: quotes[0])
|
||||
EmotionEntry(date: Date())
|
||||
}
|
||||
|
||||
func getSnapshot(in context: Context, completion: @escaping (EmotionEntry) -> ()) {
|
||||
let entry = EmotionEntry(date: Date(), text: quotes.randomElement() ?? quotes[0])
|
||||
completion(entry)
|
||||
completion(EmotionEntry(date: Date()))
|
||||
}
|
||||
|
||||
func getTimeline(in context: Context, completion: @escaping (Timeline<EmotionEntry>) -> ()) {
|
||||
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)
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
|
||||
struct EmotionEntry: TimelineEntry {
|
||||
let date: Date
|
||||
let text: String
|
||||
}
|
||||
|
||||
struct EmotionWidgetView: View {
|
||||
@@ -56,37 +30,160 @@ 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 {
|
||||
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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
.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)
|
||||
}
|
||||
}
|
||||
@@ -97,13 +194,7 @@ struct EmotionWidget: Widget {
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
StaticConfiguration(kind: kind, provider: EmotionProvider()) { entry in
|
||||
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))
|
||||
}
|
||||
EmotionWidgetView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("情绪小组件")
|
||||
.description("一段温柔提醒,陪你回到当下。")
|
||||
|
||||
@@ -105,6 +105,7 @@ export async function setReaction(contentId: string, reaction: Reaction): Promis
|
||||
}
|
||||
|
||||
export type FavoriteItem = {
|
||||
favId: string; // 唯一标识,支持重复点赞同一文案
|
||||
id: string;
|
||||
date: string;
|
||||
themeMode: ThemeMode;
|
||||
@@ -117,15 +118,15 @@ export async function getFavorites(): Promise<FavoriteItem[]> {
|
||||
|
||||
export async function addFavorite(item: FavoriteItem): Promise<void> {
|
||||
const list = await getFavorites();
|
||||
if (list.some(i => i.id === item.id)) return;
|
||||
// 允许重复点赞,不再根据 id 去重
|
||||
const newList = [item, ...list];
|
||||
console.log('Adding to favorites, new list size:', newList.length);
|
||||
await setJson(KEY_FAVORITES_ITEMS, newList);
|
||||
}
|
||||
|
||||
export async function removeFavorite(contentId: string): Promise<void> {
|
||||
export async function removeFavorite(favId: string): Promise<void> {
|
||||
const list = await getFavorites();
|
||||
const next = list.filter(item => item.id !== contentId);
|
||||
const next = list.filter(item => item.favId !== favId);
|
||||
await setJson(KEY_FAVORITES_ITEMS, next);
|
||||
}
|
||||
|
||||
|
||||