为多个组件和API添加用户登录状态检查,确保只有在用户登录后才能查询和修改收藏状态
This commit is contained in:
@@ -5,6 +5,7 @@ import { IconSymbol, IconSymbolName } from "@/components/ui/icon-symbol";
|
|||||||
import { Colors } from "@/constants/theme";
|
import { Colors } from "@/constants/theme";
|
||||||
import { useTheme } from "@/context/ThemeContext";
|
import { useTheme } from "@/context/ThemeContext";
|
||||||
import { fetchFavorites, removeFavorite } from "@/lib/api";
|
import { fetchFavorites, removeFavorite } from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { FavoriteItem, Match } from "@/types/api";
|
import { FavoriteItem, Match } from "@/types/api";
|
||||||
import { Image } from "expo-image";
|
import { Image } from "expo-image";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
@@ -67,6 +68,13 @@ export default function FavoriteScreen() {
|
|||||||
if (loading) return;
|
if (loading) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) {
|
||||||
|
setFavorites([]);
|
||||||
|
setHasMore(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const currentPage = isRefresh ? 1 : page;
|
const currentPage = isRefresh ? 1 : page;
|
||||||
const res = await fetchFavorites(activeTab, currentPage);
|
const res = await fetchFavorites(activeTab, currentPage);
|
||||||
if (isRefresh) {
|
if (isRefresh) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
fetchSports,
|
fetchSports,
|
||||||
fetchTodayMatches,
|
fetchTodayMatches,
|
||||||
} from "@/lib/api";
|
} from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { League, Match, Sport } from "@/types/api";
|
import { League, Match, Sport } from "@/types/api";
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -316,18 +317,23 @@ export default function HomeScreen() {
|
|||||||
deviceTimeZone
|
deviceTimeZone
|
||||||
);
|
);
|
||||||
|
|
||||||
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
const token = await storage.getAccessToken();
|
||||||
const listWithFavStatus = await Promise.all(
|
let listWithFavStatus = list;
|
||||||
list.map(async (m) => {
|
|
||||||
try {
|
if (token) {
|
||||||
const favRes = await checkFavorite("match", m.id);
|
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
||||||
return { ...m, fav: favRes.isFavorite };
|
listWithFavStatus = await Promise.all(
|
||||||
} catch (error) {
|
list.map(async (m) => {
|
||||||
console.error(`Check favorite failed for match ${m.id}:`, error);
|
try {
|
||||||
return m;
|
const favRes = await checkFavorite("match", m.id);
|
||||||
}
|
return { ...m, fav: favRes.isFavorite };
|
||||||
})
|
} catch (error) {
|
||||||
);
|
console.error(`Check favorite failed for match ${m.id}:`, error);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 将收藏的比赛置顶
|
// 将收藏的比赛置顶
|
||||||
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
fetchSports,
|
fetchSports,
|
||||||
fetchTodayMatches,
|
fetchTodayMatches,
|
||||||
} from "@/lib/api";
|
} from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { League, Match, Sport } from "@/types/api";
|
import { League, Match, Sport } from "@/types/api";
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -316,19 +317,24 @@ export default function HomeScreen() {
|
|||||||
deviceTimeZone
|
deviceTimeZone
|
||||||
);
|
);
|
||||||
|
|
||||||
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
const token = await storage.getAccessToken();
|
||||||
const listWithFavStatus = await Promise.all(
|
let listWithFavStatus = list;
|
||||||
list.map(async (m) => {
|
|
||||||
try {
|
if (token) {
|
||||||
// 查询比赛是否已被收藏
|
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
||||||
const favRes = await checkFavorite("match", m.id);
|
listWithFavStatus = await Promise.all(
|
||||||
return { ...m, fav: favRes.isFavorite };
|
list.map(async (m) => {
|
||||||
} catch (error) {
|
try {
|
||||||
console.error(`Check favorite failed for match ${m.id}:`, error);
|
// 查询比赛是否已被收藏
|
||||||
return m;
|
const favRes = await checkFavorite("match", m.id);
|
||||||
}
|
return { ...m, fav: favRes.isFavorite };
|
||||||
})
|
} catch (error) {
|
||||||
);
|
console.error(`Check favorite failed for match ${m.id}:`, error);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 将收藏的比赛置顶
|
// 将收藏的比赛置顶
|
||||||
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Colors } from "@/constants/theme";
|
|||||||
import { useAppState } from "@/context/AppStateContext";
|
import { useAppState } from "@/context/AppStateContext";
|
||||||
import { useTheme } from "@/context/ThemeContext";
|
import { useTheme } from "@/context/ThemeContext";
|
||||||
import { checkFavorite, fetchLiveScore } from "@/lib/api";
|
import { checkFavorite, fetchLiveScore } from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { LiveScoreMatch, Match } from "@/types/api";
|
import { LiveScoreMatch, Match } from "@/types/api";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
@@ -66,18 +67,23 @@ export default function LiveScreen() {
|
|||||||
isLive: true,
|
isLive: true,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
const token = await storage.getAccessToken();
|
||||||
const listWithFavStatus = await Promise.all(
|
let listWithFavStatus = converted;
|
||||||
converted.map(async (m) => {
|
|
||||||
try {
|
if (token) {
|
||||||
const favRes = await checkFavorite("match", m.id);
|
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
||||||
return { ...m, fav: favRes.isFavorite };
|
listWithFavStatus = await Promise.all(
|
||||||
} catch (error) {
|
converted.map(async (m) => {
|
||||||
console.error(`Check favorite failed for match ${m.id}:`, error);
|
try {
|
||||||
return m;
|
const favRes = await checkFavorite("match", m.id);
|
||||||
}
|
return { ...m, fav: favRes.isFavorite };
|
||||||
})
|
} catch (error) {
|
||||||
);
|
console.error(`Check favorite failed for match ${m.id}:`, error);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 将收藏的比赛置顶
|
// 将收藏的比赛置顶
|
||||||
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
fetchSports,
|
fetchSports,
|
||||||
fetchUpcomingMatches,
|
fetchUpcomingMatches,
|
||||||
} from "@/lib/api";
|
} from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { League, Sport, UpcomingMatch } from "@/types/api";
|
import { League, Sport, UpcomingMatch } from "@/types/api";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -261,7 +262,8 @@ export default function HomeScreen() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadMatches = async () => {
|
const loadMatches = async () => {
|
||||||
if (selectedSportId === null) return;
|
const token = await storage.getAccessToken();
|
||||||
|
if (selectedSportId === null || !token) return;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
@@ -271,18 +273,23 @@ export default function HomeScreen() {
|
|||||||
selectedLeagueKey || ""
|
selectedLeagueKey || ""
|
||||||
);
|
);
|
||||||
|
|
||||||
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
const token = await storage.getAccessToken();
|
||||||
const listWithFavStatus = await Promise.all(
|
let listWithFavStatus = list;
|
||||||
list.map(async (m) => {
|
|
||||||
try {
|
if (token) {
|
||||||
const favRes = await checkFavorite("match", m.id.toString());
|
// 直接传递 match.id 查询是否收藏,并更新列表状态
|
||||||
return { ...m, fav: favRes.isFavorite };
|
listWithFavStatus = await Promise.all(
|
||||||
} catch (error) {
|
list.map(async (m) => {
|
||||||
console.error(`Check favorite failed for match ${m.id}:`, error);
|
try {
|
||||||
return m;
|
const favRes = await checkFavorite("match", m.id.toString());
|
||||||
}
|
return { ...m, fav: favRes.isFavorite };
|
||||||
})
|
} catch (error) {
|
||||||
);
|
console.error(`Check favorite failed for match ${m.id}:`, error);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 将收藏的比赛置顶
|
// 将收藏的比赛置顶
|
||||||
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
const sortedList = [...listWithFavStatus].sort((a, b) => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ThemedText } from "@/components/themed-text";
|
import { ThemedText } from "@/components/themed-text";
|
||||||
import { IconSymbol } from "@/components/ui/icon-symbol";
|
import { IconSymbol } from "@/components/ui/icon-symbol";
|
||||||
import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api";
|
import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { LiveScoreMatch } from "@/types/api";
|
import { LiveScoreMatch } from "@/types/api";
|
||||||
import { LinearGradient } from "expo-linear-gradient";
|
import { LinearGradient } from "expo-linear-gradient";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
@@ -46,6 +47,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
|
|||||||
// 检查收藏状态
|
// 检查收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadFavStatus = async () => {
|
const loadFavStatus = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("match", match.event_key.toString());
|
const res = await checkFavorite("match", match.event_key.toString());
|
||||||
setIsFav(res.isFavorite);
|
setIsFav(res.isFavorite);
|
||||||
@@ -59,6 +62,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
|
|||||||
// 检查主队收藏状态
|
// 检查主队收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadHomeFav = async () => {
|
const loadHomeFav = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("team", match.home_team_key.toString());
|
const res = await checkFavorite("team", match.home_team_key.toString());
|
||||||
setIsHomeFav(res.isFavorite);
|
setIsHomeFav(res.isFavorite);
|
||||||
@@ -74,6 +79,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
|
|||||||
// 检查客队收藏状态
|
// 检查客队收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadAwayFav = async () => {
|
const loadAwayFav = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("team", match.away_team_key.toString());
|
const res = await checkFavorite("team", match.away_team_key.toString());
|
||||||
setIsAwayFav(res.isFavorite);
|
setIsAwayFav(res.isFavorite);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ThemedText } from "@/components/themed-text";
|
import { ThemedText } from "@/components/themed-text";
|
||||||
import { IconSymbol } from "@/components/ui/icon-symbol";
|
import { IconSymbol } from "@/components/ui/icon-symbol";
|
||||||
import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api";
|
import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api";
|
||||||
|
import { storage } from "@/lib/storage";
|
||||||
import { MatchDetailData } from "@/types/api";
|
import { MatchDetailData } from "@/types/api";
|
||||||
import { LinearGradient } from "expo-linear-gradient";
|
import { LinearGradient } from "expo-linear-gradient";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
@@ -30,6 +31,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
|
|||||||
// 检查比赛收藏状态
|
// 检查比赛收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadFavStatus = async () => {
|
const loadFavStatus = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("match", match.eventKey.toString());
|
const res = await checkFavorite("match", match.eventKey.toString());
|
||||||
setIsFav(res.isFavorite);
|
setIsFav(res.isFavorite);
|
||||||
@@ -45,6 +48,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
|
|||||||
// 检查主队收藏状态
|
// 检查主队收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadHomeFav = async () => {
|
const loadHomeFav = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("team", match.homeTeamKey.toString());
|
const res = await checkFavorite("team", match.homeTeamKey.toString());
|
||||||
setIsHomeFav(res.isFavorite);
|
setIsHomeFav(res.isFavorite);
|
||||||
@@ -60,6 +65,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
|
|||||||
// 检查客队收藏状态
|
// 检查客队收藏状态
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const loadAwayFav = async () => {
|
const loadAwayFav = async () => {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) return;
|
||||||
try {
|
try {
|
||||||
const res = await checkFavorite("team", match.awayTeamKey.toString());
|
const res = await checkFavorite("team", match.awayTeamKey.toString());
|
||||||
setIsAwayFav(res.isFavorite);
|
setIsAwayFav(res.isFavorite);
|
||||||
|
|||||||
10
lib/api.ts
10
lib/api.ts
@@ -431,6 +431,11 @@ export const fetchUserProfile = async (): Promise<UserProfile> => {
|
|||||||
|
|
||||||
export const addFavorite = async (request: FavoriteRequest): Promise<any> => {
|
export const addFavorite = async (request: FavoriteRequest): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) {
|
||||||
|
// throw new Error("Please login first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// console.log("Adding favorite with request:", request);
|
// console.log("Adding favorite with request:", request);
|
||||||
const response = await apiClient.post<ApiResponse<any>>(
|
const response = await apiClient.post<ApiResponse<any>>(
|
||||||
API_ENDPOINTS.FAVORITES,
|
API_ENDPOINTS.FAVORITES,
|
||||||
@@ -451,6 +456,11 @@ export const removeFavorite = async (request: {
|
|||||||
typeId: string;
|
typeId: string;
|
||||||
}): Promise<any> => {
|
}): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
|
const token = await storage.getAccessToken();
|
||||||
|
if (!token) {
|
||||||
|
// throw new Error("Please login first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log("Removing favorite with request:", request);
|
console.log("Removing favorite with request:", request);
|
||||||
const response = await apiClient.delete<ApiResponse<any>>(
|
const response = await apiClient.delete<ApiResponse<any>>(
|
||||||
API_ENDPOINTS.FAVORITES,
|
API_ENDPOINTS.FAVORITES,
|
||||||
|
|||||||
Reference in New Issue
Block a user