从 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>
88 lines
2.8 KiB
Dart
88 lines
2.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:im_app/core/foundation/config.dart';
|
|
|
|
/// 关于本应用页
|
|
///
|
|
/// 对应 Gitea issue #13
|
|
class AboutPage extends StatelessWidget {
|
|
const AboutPage({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('关于')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
// App 图标 + 名称
|
|
const SizedBox(height: 24),
|
|
Center(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
width: 72,
|
|
height: 72,
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.primary,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: const Icon(Icons.chat_bubble, color: Colors.white, size: 40),
|
|
),
|
|
const SizedBox(height: 12),
|
|
Text(
|
|
'IM',
|
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'版本 ${AppConfig.appVersion}',
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 32),
|
|
// 链接列表
|
|
Card(
|
|
child: Column(
|
|
children: [
|
|
ListTile(
|
|
leading: const Icon(Icons.description_outlined),
|
|
title: const Text('服务条款'),
|
|
trailing: const Icon(Icons.chevron_right, color: Colors.grey),
|
|
onTap: () {
|
|
// TODO: 跳转服务条款页面或 WebView
|
|
},
|
|
),
|
|
const Divider(height: 1, indent: 52),
|
|
ListTile(
|
|
leading: const Icon(Icons.privacy_tip_outlined),
|
|
title: const Text('隐私政策'),
|
|
trailing: const Icon(Icons.chevron_right, color: Colors.grey),
|
|
onTap: () {
|
|
// TODO: 跳转隐私政策页面或 WebView
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 32),
|
|
Center(
|
|
child: Text(
|
|
'© 2025 IM. All rights reserved.',
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|