Files
customer-im-client-dev/apps/im_app/lib/features/settings/view/language_page.dart
pp-bot aeeda6f059 feat(mine): 我的 Tab 全量实现 (#5~#13)
从 im-client-ios-swift-demo 搬运 Settings 逻辑,对齐 Gitea issue #5–#13

## 基础设施
- AuthNotifier 新增 currentUid 字段,login() 接受 uid 参数 (#5)
- LoginViewModel 登录成功后传入 user.uid
- ApiPaths 补充 account/block/store 系列路径
- Tab 重命名"设置"→"我的",icon 改为 person_outline (#5)
- AppRouteName 新增5条子路由 (edit-profile/blocklist/language/network-diagnostics/about)
- app_router + auth_guard 同步注册新路由

## Settings Feature
- SettingsViewModel 重写为 NotifierProvider(去除 @riverpod 依赖)
  - build() 自动触发 loadProfile()
  - logout() 完整流程:API → WS 断开 → DB 关闭 → AuthNotifier
  - 6 个 navigateTo* 方法
- SettingsPage 完整 UI:资料卡 / 偏好设置 / 工具 / 关于 / 退出登录按钮 (#5 #7)
- FetchProfileUseCase: GET /app/api/user/profile (#5)
- LogoutUseCase: logout + disconnect + closeDatabase (#7)
- UpdateProfileUseCase + UpdateProfileRequest: POST /app/api/user/update-profile (#6)
- EditProfilePage + EditProfileViewModel: 昵称/bio 编辑 (#6)
- LanguagePage: 语言选择 UI 框架,l10n_sdk 待接入 (#9)
- BlocklistPage: 黑名单框架,API 待实现 (#10)
- NetworkDiagnosticsPage + ViewModel: 四步诊断(连通/TCP/DNS/HTTPS)(#12)
- AboutPage: 版本号 + 服务条款/隐私政策入口 (#13)
- settings_providers.dart: 扩展 DI 装配

## 文档
- Doc/mine_tab_architecture.md: 架构说明、数据流、路由、待完成事项

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 17:20:51 +09:00

65 lines
2.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
/// 语言设置页
///
/// 对应 Gitea issue #9
/// TODO: 接入 l10n_sdk实现语言切换持久化
class LanguagePage extends StatefulWidget {
const LanguagePage({super.key});
@override
State<LanguagePage> createState() => _LanguagePageState();
}
class _LanguagePageState extends State<LanguagePage> {
/// TODO: 从 l10n_sdk / Locale 读取当前语言
String _selected = 'zh';
static const _languages = [
_LangOption(code: 'zh', label: '简体中文', nativeLabel: '简体中文'),
_LangOption(code: 'en', label: '英文', nativeLabel: 'English'),
_LangOption(code: 'zh-TW', label: '繁体中文', nativeLabel: '繁體中文'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('语言')),
body: ListView.separated(
itemCount: _languages.length,
separatorBuilder: (_, __) => const Divider(height: 1, indent: 16),
itemBuilder: (context, index) {
final lang = _languages[index];
final isSelected = _selected == lang.code;
return ListTile(
title: Text(lang.nativeLabel),
subtitle: lang.label != lang.nativeLabel ? Text(lang.label) : null,
trailing: isSelected
? Icon(Icons.check, color: Theme.of(context).colorScheme.primary)
: null,
onTap: () {
setState(() => _selected = lang.code);
// TODO: ref.read(localeProvider.notifier).setLocale(lang.code)
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('语言已切换为 ${lang.nativeLabel}(持久化待接入)')),
);
},
);
},
),
);
}
}
class _LangOption {
const _LangOption({
required this.code,
required this.label,
required this.nativeLabel,
});
final String code;
final String label;
final String nativeLabel;
}