3aeb2a8680
- AppLang enum 扩为 zh/en/ja/ko/ru/es;新增 strings_{ja,ko,ru,es}.dart
(各 161 条,照 strings_en.dart 结构逐条翻译,无红线词,scan-redline 过)
- app_providers: localeProvider 默认 AppLang.en(国际化默认);appTextProvider
三元改 switch 全覆盖 6 语
- AppLang.nativeLabel 扩展(各语言本地名);settings/account 两处 _LangSwitch
段控改下拉(6 语横排会挤)
- flutter analyze lib 仅剩 2 个既有 withOpacity deprecation info
注:节点/套餐名、错误消息等 ~11 处数据驱动的 zh/en 三元暂回退 en(非崩溃,
后续可扩多语字段)。localeProvider 暂无持久化(沿用原设计,后续可加)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
56 lines
2.2 KiB
Dart
56 lines
2.2 KiB
Dart
// app_providers.dart — 语言 / 主题 / 套餐视角等基础状态(Riverpod)
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../l10n/app_text.dart';
|
|
import '../l10n/strings_en.dart';
|
|
import '../l10n/strings_es.dart';
|
|
import '../l10n/strings_ja.dart';
|
|
import '../l10n/strings_ko.dart';
|
|
import '../l10n/strings_ru.dart';
|
|
import '../l10n/strings_zh.dart';
|
|
import 'account_providers.dart';
|
|
import 'auth_provider.dart';
|
|
|
|
/// 当前语言(单显)。设置/账户页切换。默认英文(国际化默认语种)。
|
|
final localeProvider = StateProvider<AppLang>((ref) => AppLang.en);
|
|
|
|
/// 由语言派生的文案资源——UI 一律通过它取文案,不写死字面量。
|
|
final appTextProvider = Provider<AppText>((ref) {
|
|
switch (ref.watch(localeProvider)) {
|
|
case AppLang.zh:
|
|
return const StringsZh();
|
|
case AppLang.en:
|
|
return const StringsEn();
|
|
case AppLang.ja:
|
|
return const StringsJa();
|
|
case AppLang.ko:
|
|
return const StringsKo();
|
|
case AppLang.ru:
|
|
return const StringsRu();
|
|
case AppLang.es:
|
|
return const StringsEs();
|
|
}
|
|
});
|
|
|
|
/// 主题模式。默认跟随系统;设置页可显式切深色。
|
|
final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.system);
|
|
|
|
/// 是否免费档——派生自真实账户(meProvider.plan == 'free')。
|
|
/// 免费版才显示额度卡与免费横幅;加载中默认按免费处理。
|
|
final isFreePlanProvider = Provider<bool>((ref) {
|
|
final me = ref.watch(meProvider).valueOrNull;
|
|
return me?.isFree ?? true;
|
|
});
|
|
|
|
/// 账户状态是否还没就绪——连接页据此先转圈再渲染,避免「先闪免费广告再跳会员」。
|
|
/// 覆盖两段窗口:① auth 还在从存储读 token(此时 isLoggedIn=false,me 会同步返回
|
|
/// 免费默认,故必须看 auth.isLoading);② 已登录但 me 还在拉真实值(此时 me 可能已有
|
|
/// 过期免费默认值,故看 me.isLoading 而非 !hasValue)。未登录(确定访客)不转圈。
|
|
final meLoadingProvider = Provider<bool>((ref) {
|
|
final auth = ref.watch(authProvider);
|
|
if (auth.isLoading) return true;
|
|
if (!auth.isLoggedIn) return false;
|
|
return ref.watch(meProvider).isLoading;
|
|
});
|