Files
video/app/lib/router.dart
T
2026-10-16 20:03:58 +08:00

132 lines
5.7 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';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../models/video_item.dart';
import '../providers/auth_provider.dart';
import '../screens/assets/assets_screen.dart';
import '../screens/assets/withdraw_screen.dart';
import '../screens/auth/login_screen.dart';
import '../screens/auth/register_screen.dart';
import '../screens/home/home_shell.dart';
import '../screens/membership/membership_screen.dart';
import '../screens/notification/notifications_screen.dart';
import '../screens/payment/recharge_screen.dart';
import '../screens/payment/usdt_pay_screen.dart';
import '../screens/player/simple_player_screen.dart';
import '../screens/profile/edit_video_screen.dart';
import '../screens/profile/invite_screen.dart';
import '../screens/profile/profile_edit_screen.dart';
import '../screens/profile/user_profile_screen.dart';
import '../screens/profile/video_list_screens.dart';
import '../screens/search/search_screen.dart';
import '../screens/search/tag_videos_screen.dart';
import '../screens/settings/settings_screen.dart';
import '../screens/splash/splash_screen.dart';
import '../screens/upload/upload_screen.dart';
import '../screens/wallet/wallet_screen.dart';
import '../services/payment_service.dart';
/// 声明式路由(02-技术文档:go_router)
/// /home 对游客开放(游客可浏览 Feed,观看超限 2002 时才引导登录);
/// 受保护页面(上传/钱包/会员等)在各自页面入口校验登录态并跳 /login。
final routerProvider = Provider<GoRouter>((ref) {
// 认证状态变化仅触发 redirect 重估(refreshListenable),
// 绝不能 watch 后重建 GoRouter —— 重建会把当前路由重置回启动页,
// 启动页再次执行 bootstrap → 状态再变化 → 无限循环(卡死在启动页)。
final refresh = ValueNotifier<int>(0);
ref.listen(authProvider, (_, __) => refresh.value++);
ref.onDispose(refresh.dispose);
return GoRouter(
initialLocation: '/',
refreshListenable: refresh,
redirect: (context, state) {
final auth = ref.read(authProvider);
final loggingIn = state.matchedLocation == '/login' ||
state.matchedLocation == '/register';
// 启动恢复未完成:停在 splash
if (!auth.restored && state.matchedLocation != '/') return '/';
// 已登录去登录页 → 回首页
if (auth.isLoggedIn && loggingIn) return '/home';
return null;
},
routes: [
GoRoute(path: '/', builder: (_, __) => const SplashScreen()),
GoRoute(path: '/login', builder: (_, __) => const LoginScreen()),
GoRoute(path: '/register', builder: (_, __) => const RegisterScreen()),
GoRoute(path: '/home', builder: (_, __) => const HomeShell()),
GoRoute(path: '/search', builder: (_, __) => const SearchScreen()),
// 标签视频页(游客可)
GoRoute(
path: '/tags/:name',
builder: (_, state) =>
TagVideosScreen(tagName: state.pathParameters['name']!),
),
// 搜索结果单视频播放(extra 传 VideoItem)
GoRoute(
path: '/search/play',
builder: (_, state) =>
SimplePlayerScreen(item: state.extra! as VideoItem),
),
// 通用单视频播放(extra 传 VideoItem)— 系列切换/Feed 点击等场景
GoRoute(
path: '/player',
builder: (_, state) =>
SimplePlayerScreen(item: state.extra! as VideoItem),
),
// 他人公开主页(游客可)
GoRoute(
path: '/user/:id',
builder: (_, state) =>
UserProfileScreen(userId: int.parse(state.pathParameters['id']!)),
),
// 我的:作品/收藏/历史(页面内需登录,未登录由入口守卫)
GoRoute(path: '/mine/works', builder: (_, __) => VideoGridScreen.works()),
// 编辑作品(extra 传 VideoItem,仅作者)
GoRoute(
path: '/mine/works/edit',
builder: (_, state) =>
EditVideoScreen(video: state.extra! as VideoItem),
),
GoRoute(
path: '/mine/favorites',
builder: (_, __) => VideoGridScreen.favorites(),
),
GoRoute(path: '/mine/history', builder: (_, __) => const HistoryScreen()),
// 编辑资料 / 头像(页面内兜底未登录引导)
GoRoute(
path: '/profile/edit',
builder: (_, __) => const ProfileEditScreen(),
),
// 钱包 / 会员中心(页面内兜底未登录引导)
GoRoute(path: '/wallet', builder: (_, __) => const WalletScreen()),
GoRoute(path: '/membership', builder: (_, __) => const MembershipScreen()),
// 消息通知(页面内兜底未登录引导)
GoRoute(
path: '/notifications',
builder: (_, __) => const NotificationsScreen(),
),
// 发布作品(页面内兜底未登录引导)
GoRoute(path: '/upload', builder: (_, __) => const UploadScreen()),
// 邀请好友(页面内需登录)
GoRoute(path: '/invite', builder: (_, __) => const InviteScreen()),
// 收益资产 / 提现(页面内兜底未登录引导)
GoRoute(path: '/assets', builder: (_, __) => const AssetsScreen()),
GoRoute(
path: '/assets/withdraw',
builder: (_, __) => const WithdrawScreen(),
),
// 充值 / USDT 支付(需登录,页面内兜底)
GoRoute(path: '/recharge', builder: (_, __) => const RechargeScreen()),
GoRoute(
path: '/recharge/usdt',
builder: (_, state) =>
UsdtPayScreen(order: state.extra! as RechargeOrderInfo),
),
// 设置
GoRoute(path: '/settings', builder: (_, __) => const SettingsScreen()),
],
);
});