feat: Enhance Oxygen Saturation Card with health permissions and loading state management
feat(i18n): Add common translations and mood-related strings in English and Chinese fix(i18n): Update metabolism titles for consistency in health translations chore: Update Podfile.lock to include SDWebImage 5.21.4 and other dependency versions refactor(moodCheckins): Improve mood configuration retrieval with optional translation support refactor(sleepHealthKit): Replace useI18n with direct i18n import for sleep quality descriptions
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { fetchOxygenSaturation } from '@/utils/health';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { ensureHealthPermissions, fetchOxygenSaturation } from '@/utils/health';
|
||||
import { HealthKitUtils } from '@/utils/healthKit';
|
||||
import { useIsFocused } from '@react-navigation/native';
|
||||
import dayjs from 'dayjs';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import HealthDataCard from './HealthDataCard';
|
||||
|
||||
@@ -15,42 +16,52 @@ const OxygenSaturationCard: React.FC<OxygenSaturationCardProps> = ({
|
||||
selectedDate
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const isFocused = useIsFocused();
|
||||
const [oxygenSaturation, setOxygenSaturation] = useState<number | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const loadingRef = useRef(false);
|
||||
|
||||
// 获取血氧饱和度数据 - 在页面聚焦、日期变化时触发
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
const loadOxygenSaturationData = async () => {
|
||||
const dateToUse = selectedDate || new Date();
|
||||
useEffect(() => {
|
||||
const loadOxygenSaturationData = async () => {
|
||||
const dateToUse = selectedDate || new Date();
|
||||
|
||||
// 防止重复请求
|
||||
if (loadingRef.current) return;
|
||||
if (!isFocused) return;
|
||||
if (!HealthKitUtils.isAvailable()) {
|
||||
setOxygenSaturation(null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
loadingRef.current = true;
|
||||
setLoading(true);
|
||||
// 防止重复请求
|
||||
if (loadingRef.current) return;
|
||||
|
||||
const options = {
|
||||
startDate: dayjs(dateToUse).startOf('day').toDate().toISOString(),
|
||||
endDate: dayjs(dateToUse).endOf('day').toDate().toISOString()
|
||||
};
|
||||
try {
|
||||
loadingRef.current = true;
|
||||
setLoading(true);
|
||||
|
||||
const data = await fetchOxygenSaturation(options);
|
||||
setOxygenSaturation(data);
|
||||
} catch (error) {
|
||||
console.error('OxygenSaturationCard: Failed to get blood oxygen data:', error);
|
||||
const hasPermission = await ensureHealthPermissions();
|
||||
if (!hasPermission) {
|
||||
setOxygenSaturation(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
loadingRef.current = false;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
loadOxygenSaturationData();
|
||||
}, [selectedDate])
|
||||
);
|
||||
const options = {
|
||||
startDate: dayjs(dateToUse).startOf('day').toDate().toISOString(),
|
||||
endDate: dayjs(dateToUse).endOf('day').toDate().toISOString()
|
||||
};
|
||||
|
||||
const data = await fetchOxygenSaturation(options);
|
||||
setOxygenSaturation(data);
|
||||
} catch (error) {
|
||||
console.error('OxygenSaturationCard: Failed to get blood oxygen data:', error);
|
||||
setOxygenSaturation(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
loadingRef.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
loadOxygenSaturationData();
|
||||
}, [isFocused, selectedDate]);
|
||||
|
||||
return (
|
||||
<HealthDataCard
|
||||
@@ -62,4 +73,4 @@ const OxygenSaturationCard: React.FC<OxygenSaturationCardProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default OxygenSaturationCard;
|
||||
export default OxygenSaturationCard;
|
||||
|
||||
Reference in New Issue
Block a user