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>
This commit is contained in:
pp-bot
2026-03-24 20:30:56 +09:00
parent db10d1fcd2
commit 8744e2c0b7
16 changed files with 1389 additions and 2 deletions

View File

@@ -73,6 +73,8 @@ enum AppRouteName {
settingsLanguage('/settings/language'),
settingsNetworkDiagnostics('/settings/network-diagnostics'),
settingsAbout('/settings/about'),
settingsFavorites('/settings/favorites'),
settingsRecentCalls('/settings/recent-calls'),
// ── 全屏页面(无底部导航栏)──────────────────────────────────────────────
login('/login');

View File

@@ -15,6 +15,8 @@ import 'package:im_app/features/settings/view/blocklist_page.dart';
import 'package:im_app/features/settings/view/language_page.dart';
import 'package:im_app/features/settings/view/network_diagnostics_page.dart';
import 'package:im_app/features/settings/view/about_page.dart';
import 'package:im_app/features/settings/view/favorites_page.dart';
import 'package:im_app/features/settings/view/recent_calls_page.dart';
import 'package:im_app/app/di/app_providers.dart';
import 'package:im_app/app/router/app_route_name.dart';
import 'package:im_app/app/router/guards/auth_guard.dart';
@@ -182,6 +184,16 @@ final routerProvider = Provider<GoRouter>((ref) {
path: AppRouteName.settingsAbout.path,
builder: (context, state) => const AboutPage(),
),
GoRoute(
parentNavigatorKey: _rootKey,
path: AppRouteName.settingsFavorites.path,
builder: (context, state) => const FavoritesPage(),
),
GoRoute(
parentNavigatorKey: _rootKey,
path: AppRouteName.settingsRecentCalls.path,
builder: (context, state) => const RecentCallsPage(),
),
GoRoute(
parentNavigatorKey: _rootKey,
path: AppRouteName.login.path,

View File

@@ -45,6 +45,8 @@ String? authGuard(AuthNotifier authNotifier, GoRouterState state) {
case AppRouteName.settingsLanguage:
case AppRouteName.settingsNetworkDiagnostics:
case AppRouteName.settingsAbout:
case AppRouteName.settingsFavorites:
case AppRouteName.settingsRecentCalls:
case AppRouteName.chatDBTest:
// 受保护路由 → 未登录跳登录页
return isLoggedIn ? null : AppRouteName.login.path;