feat(challenges): 新增挑战鼓励提醒后台任务与通知支持

- 在 backgroundTaskManager 中增加 executeChallengeReminderTask,每日检查已加入且未打卡的挑战并发送鼓励通知
- 扩展 ChallengeNotificationHelpers 提供 sendEncouragementNotification 方法
- 新增 NotificationTypes.CHALLENGE_ENCOURAGEMENT 及对应点击跳转处理
- challengesApi 补充 checkedInToday 字段用于判断今日是否已打卡
- 临时注释掉挑战列表与详情页头部的礼物/分享按钮,避免干扰主流程
This commit is contained in:
richarjiang
2025-09-29 17:24:07 +08:00
parent d74bd214ed
commit 8f847465ef
6 changed files with 95 additions and 10 deletions

View File

@@ -1,5 +1,4 @@
import ChallengeProgressCard from '@/components/challenges/ChallengeProgressCard';
import { IconSymbol } from '@/components/ui/IconSymbol';
import { Colors } from '@/constants/Colors';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
@@ -127,7 +126,7 @@ export default function ChallengesScreen() {
<Text style={[styles.title, { color: colorTokens.text }]}></Text>
<Text style={[styles.subtitle, { color: colorTokens.textSecondary }]}></Text>
</View>
<TouchableOpacity activeOpacity={0.9} style={styles.giftShadow}>
{/* <TouchableOpacity activeOpacity={0.9} style={styles.giftShadow}>
<LinearGradient
colors={[colorTokens.primary, colorTokens.accentPurple]}
start={{ x: 0, y: 0 }}
@@ -136,7 +135,7 @@ export default function ChallengesScreen() {
>
<IconSymbol name="gift.fill" size={18} color={colorTokens.onPrimary} />
</LinearGradient>
</TouchableOpacity>
</TouchableOpacity> */}
</View>
{ongoingChallenge ? (

View File

@@ -139,6 +139,7 @@ export default function ChallengeDetailScreen() {
const progress = challenge?.progress;
const rankingData = useMemo(() => challenge?.rankings ?? [], [challenge?.rankings]);
const participantAvatars = useMemo(
() => rankingData.filter((item) => item.avatar).map((item) => item.avatar as string).slice(0, 6),
[rankingData],
@@ -296,11 +297,11 @@ export default function ChallengeDetailScreen() {
tone="light"
transparent
withSafeTop={false}
right={
<TouchableOpacity style={styles.circularButton} activeOpacity={0.85} onPress={handleShare}>
<Ionicons name="share-social-outline" size={20} color="#ffffff" />
</TouchableOpacity>
}
// right={
// <TouchableOpacity style={styles.circularButton} activeOpacity={0.85} onPress={handleShare}>
// <Ionicons name="share-social-outline" size={20} color="#ffffff" />
// </TouchableOpacity>
// }
/>
</View>