feat(i18n): 全面实现应用核心功能模块的国际化支持
- 新增 i18n 翻译资源,覆盖睡眠、饮水、体重、锻炼、用药 AI 识别、步数、健身圆环、基础代谢及设置等核心模块 - 重构相关页面及组件(如 SleepDetail, WaterDetail, WorkoutHistory 等)使用 `useI18n` 钩子替换硬编码文本 - 升级 `utils/date` 工具库与 `DateSelector` 组件,支持基于语言环境的日期格式化与显示 - 完善登录页、注销流程及权限申请弹窗的双语提示信息 - 优化部分页面的 UI 细节与字体样式以适配多语言显示
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import type { RankingItem } from '@/store/challengesSlice';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { Image } from 'expo-image';
|
||||
@@ -18,34 +19,34 @@ const formatNumber = (value: number): string => {
|
||||
return value.toFixed(2).replace(/0+$/, '').replace(/\.$/, '');
|
||||
};
|
||||
|
||||
const formatMinutes = (value: number): string => {
|
||||
const safeValue = Math.max(0, Math.round(value));
|
||||
const hours = safeValue / 60;
|
||||
return `${hours.toFixed(1)} 小时`;
|
||||
};
|
||||
|
||||
const formatValueWithUnit = (value: number | undefined, unit?: string): string | undefined => {
|
||||
if (typeof value !== 'number' || Number.isNaN(value)) {
|
||||
return undefined;
|
||||
}
|
||||
if (unit === 'min') {
|
||||
return formatMinutes(value);
|
||||
}
|
||||
const formatted = formatNumber(value);
|
||||
return unit ? `${formatted} ${unit}` : formatted;
|
||||
};
|
||||
|
||||
export function ChallengeRankingItem({ item, index, showDivider = false, unit }: ChallengeRankingItemProps) {
|
||||
console.log('unit', unit);
|
||||
const { t } = useI18n();
|
||||
|
||||
const formatMinutes = (value: number): string => {
|
||||
const safeValue = Math.max(0, Math.round(value));
|
||||
const hours = safeValue / 60;
|
||||
return `${hours.toFixed(1)} ${t('challengeDetail.ranking.hour')}`;
|
||||
};
|
||||
|
||||
const formatValueWithUnit = (value: number | undefined, unit?: string): string | undefined => {
|
||||
if (typeof value !== 'number' || Number.isNaN(value)) {
|
||||
return undefined;
|
||||
}
|
||||
if (unit === 'min') {
|
||||
return formatMinutes(value);
|
||||
}
|
||||
const formatted = formatNumber(value);
|
||||
return unit ? `${formatted} ${unit}` : formatted;
|
||||
};
|
||||
|
||||
const reportedLabel = formatValueWithUnit(item.todayReportedValue, unit);
|
||||
const targetLabel = formatValueWithUnit(item.todayTargetValue, unit);
|
||||
const progressLabel = reportedLabel && targetLabel
|
||||
? `今日 ${reportedLabel} / ${targetLabel}`
|
||||
? `${t('challengeDetail.ranking.today')} ${reportedLabel} / ${targetLabel}`
|
||||
: reportedLabel
|
||||
? `今日 ${reportedLabel}`
|
||||
? `${t('challengeDetail.ranking.today')} ${reportedLabel}`
|
||||
: targetLabel
|
||||
? `今日目标 ${targetLabel}`
|
||||
? `${t('challengeDetail.ranking.todayGoal')} ${targetLabel}`
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user