Files
customer-im-client-dev/apps/im_app/lib/app/router/app_route_name.dart
pp-bot 8744e2c0b7 feat(settings): 收藏列表 + 最近呼叫全量实现(#42~#45)
## 收藏(Gitea #42~#45)
- `FetchFavoritesRequest` / `DeleteFavoriteRequest`:ApiRequestable,对齐 iOS FavouriteService
- `FetchFavoritesUseCase`:GET 分页拉取 → upsert FavoriteRepository
- `DeleteFavoriteUseCase`:POST delete → 同步删本地 DB
- `FavoritesViewModel`:分页/刷新/加载更多/删除,DB Stream 驱动
- `FavoritesPage`:列表 + RefreshIndicator + Dismissible 左滑删除 + 类型图标 + 空状态
- `AppRouteName.settingsFavorites` + 路由注册 + auth guard
- `settings_page.dart` 收藏行 onTap 接入导航

## 最近呼叫(框架,API 对接待续)
- `CallLogRequest` / `FetchCallLogsUseCase` / `RecentCallsViewModel`
- `RecentCallsPage`:双 Tab(全部/未接)+ _CallLogTile(图标/时长/时间)
- `AppRouteName.settingsRecentCalls` + 路由注册

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:30:56 +09:00

106 lines
4.4 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.
/// 应用路由枚举
///
/// 每个枚举值对应一个注册路由及其绝对路径。
///
/// ## 为什么用枚举而不是常量类
///
/// `auth_guard.dart` 对路由做 switch 分析Dart 的枚举 switch 是穷举的:
/// 新增路由时若没在 switch 里补 case编译器直接报错而不是等运行时漏掉。
///
/// ## 使用方式
///
/// ```dart
/// // 无参数导航
/// context.push(AppRouteName.settingsTheme.path);
/// context.go(AppRouteName.chat.path);
///
/// // 带参数导航extra 传对象,适合列表点入详情等已有数据的场景)
/// context.push(
/// AppRouteName.chatDetail.path,
/// extra: (conversationId: '42', title: '技术支持'),
/// );
///
/// // 带路径参数导航(路径中内嵌 id适合需要直接链接或分享的场景
/// context.push(AppRouteName.chatDetailByIdPath('99'));
///
/// // 路由表定义
/// GoRoute(path: AppRouteName.chat.path, ...)
/// ```
///
/// ## 注意:子路由 path 是相对路径片段
///
/// go_router 在子路由中使用相对路径片段(不含父路径前缀),
/// 这是框架规定,不是硬编码字符串:
/// ```dart
/// GoRoute(
/// path: AppRouteName.settings.path, // '/settings'
/// routes: [
/// GoRoute(path: AppRouteName.settingsTheme.segment, ...), // 'theme'
/// ],
/// )
/// ```
/// 导航时仍用 `AppRouteName.settingsTheme.path`,与枚举保持一致。
///
/// 子路由声明使用 [segment](相对路径片段),避免在路由表中硬编码字符串:
/// ```dart
/// GoRoute(path: AppRouteName.settingsTheme.segment, ...) // 'theme'
/// ```
///
/// ## 注意:含路径参数的路由
///
/// [chatDetailById] 的 [path] 包含占位符 `:id`,不能直接用于导航。
/// 导航时使用 [chatDetailByIdPath] 传入实际 id
/// ```dart
/// context.push(AppRouteName.chatDetailByIdPath('99'));
/// ```
enum AppRouteName {
// ── Tab 根路由 ────────────────────────────────────────────────────────────
chat('/chat'),
contact('/contact'),
settings('/settings'),
// ── Chat 子路由 ──────────────────────────────────────────────────────────
// extra: ({String conversationId, String title})
chatDetail('/chat/detail'),
// 路径参数形式:导航用 AppRouteName.chatDetailByIdPath(id),不直接用 .path
chatDetailById('/chat/:id'),
chatDBTest('/chat/dbTest'),
// ── Settings 子路由 ───────────────────────────────────────────────────────
settingsTheme('/settings/theme'),
settingsEditProfile('/settings/edit-profile'),
settingsBlocklist('/settings/blocklist'),
settingsLanguage('/settings/language'),
settingsNetworkDiagnostics('/settings/network-diagnostics'),
settingsAbout('/settings/about'),
settingsFavorites('/settings/favorites'),
settingsRecentCalls('/settings/recent-calls'),
// ── 全屏页面(无底部导航栏)──────────────────────────────────────────────
login('/login');
const AppRouteName(this.path);
/// 绝对路径,用于 [context.push] / [context.go] 导航及顶层路由表声明
///
/// 注意:[chatDetailById] 的 path 含占位符 `:id`,导航时用 [chatDetailByIdPath]。
final String path;
/// 相对路径片段path 的最后一段),用于 go_router 子路由的 [GoRoute.path] 声明
///
/// 例:`AppRouteName.settingsTheme.segment` → `'theme'`
String get segment => path.split('/').last;
/// 从绝对路径查找枚举值,路径未注册时返回 null
///
/// 注意:含路径参数的路由(如 `/chat/99`)无法匹配,返回 null
/// auth_guard 会按受保护路由处理(未登录重定向到登录页)。
static AppRouteName? fromPath(String path) =>
AppRouteName.values.where((r) => r.path == path).firstOrNull;
/// 生成 [chatDetailById] 的实际导航路径,将 `:id` 替换为真实 id
///
/// 例:`AppRouteName.chatDetailByIdPath('99')` → `'/chat/99'`
static String chatDetailByIdPath(String id) => '/chat/$id';
}