import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:maibu_satabot_v2/core/localization/locale_cubit.dart'; /// 可选语言项:tag 对应 assets/languages/{tag}.json,nativeName 用该语言本地写法展示。 class LanguageItem { final Locale locale; final String nativeName; const LanguageItem(this.locale, this.nativeName); String get tag => locale.countryCode == null || locale.countryCode!.isEmpty ? locale.languageCode : '${locale.languageCode}-${locale.countryCode}'; } /// 全局唯一的“可选语言列表”来源。 /// 后续接入“接口下载语言包”时,只需在这里扩展(例如把已下载的语言追加进来), /// 登录强制弹窗与设置页入口都会自动同步,无需改多处。 class AppLanguages { AppLanguages._(); static final AppLanguages instance = AppLanguages._(); final List items = const [ LanguageItem(Locale('zh', 'CN'), '简体中文'), LanguageItem(Locale('en', 'US'), 'English'), ]; String nameOf(Locale locale) { final tag = locale.countryCode == null || locale.countryCode!.isEmpty ? locale.languageCode : '${locale.languageCode}-${locale.countryCode}'; for (final item in items) { if (item.tag == tag) return item.nativeName; } return tag; } } /// 语言选择弹窗。 /// [mandatory] = true:登录时强制弹出,拦截系统返回键;可点某个语言即时切换,或点“继续”确认当前默认语言后关闭。 /// [mandatory] = false:设置页中普通选择,可取消。 class LanguageSelectionDialog extends StatelessWidget { final bool mandatory; const LanguageSelectionDialog({super.key, this.mandatory = true}); Future _onSelect(BuildContext context, Locale locale) async { await context.read().setLocale(locale); if (context.mounted) Navigator.of(context).pop(); } /// “继续”:不改变当前(默认)语言,仅确认已选并关闭,后续启动不再弹。 Future _onContinue(BuildContext context, Locale current) async { await context.read().setLocale(current); if (context.mounted) Navigator.of(context).pop(); } @override Widget build(BuildContext context) { final current = context.select( (c) => c.state, ); return PopScope( // 强制弹窗时拦截返回键,必须选一个才能继续使用 canPop: !mandatory, child: AlertDialog( title: const Text('选择语言 / Select Language'), content: SizedBox( width: 300, child: Column( mainAxisSize: MainAxisSize.min, children: [ for (final item in AppLanguages.instance.items) RadioListTile( value: item.tag, // 高亮当前语言:按 languageCode 匹配,兼容国家码为空的历史值 groupValue: current.countryCode == null || current.countryCode!.isEmpty ? current.languageCode : '${current.languageCode}-${current.countryCode}', title: Text(item.nativeName), onChanged: (_) => _onSelect(context, item.locale), ), ], ), ), actions: [ // 强制弹窗:提供“继续”出口,保持当前默认语言并确认后关闭;非强制:取消 TextButton( onPressed: () => mandatory ? _onContinue(context, current) : Navigator.of(context).pop(), child: Text(mandatory ? '继续 / Continue' : '取消'), ), ], ), ); } }