앱 공통 계층 — 데이터 저장소 · 서버 시계 · 푸시 · 결제·광고 · 다국어 5종 · 행성 표현 · 공통 UI · 화면 자산
This commit is contained in:
@@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../config/feature_flags.dart';
|
||||
import '../data/repositories.dart';
|
||||
import '../theme/tokens.dart';
|
||||
import '../ui/app_icons.dart';
|
||||
import '../../features/auth/auth_repository.dart';
|
||||
import '../../features/auth/login_screen.dart';
|
||||
import '../../features/galaxy/galaxy_screen.dart';
|
||||
import '../../features/auth/signup_screens.dart';
|
||||
import '../../features/galaxy/galaxy_home_screen.dart';
|
||||
import '../../features/home/home_screen.dart';
|
||||
import '../../features/inside/inside_screen.dart';
|
||||
import '../../features/my/my_screen.dart';
|
||||
@@ -35,7 +37,7 @@ class AppTab {
|
||||
final bool Function(FeatureFlags flags)? gatedBy;
|
||||
}
|
||||
|
||||
/// 계약 고정 5탭.
|
||||
/// 계약 고정 5탭 — 화면 대조 원장 F0 · Figma `350:215853` 「Bottom Navigation」.
|
||||
///
|
||||
/// 근거 2개가 서로 일치한다:
|
||||
/// - 견적서 v2.1 「5탭 네비게이션」
|
||||
@@ -76,20 +78,28 @@ List<AppTab> visibleTabs(FeatureFlags flags) => [
|
||||
];
|
||||
|
||||
const String loginPath = '/login';
|
||||
const String signupCompletePath = '/welcome';
|
||||
|
||||
/// 5탭 셸 라우트 + 온보딩(로그인) 라우트.
|
||||
///
|
||||
/// 온보딩 나머지 화면(S-A-INTRO · S-A-TERMS · S-A-PROFILE · S-A-ARTIST ·
|
||||
/// S-A-PLANET-NEW · S-A-PERMS)은 3주차 범위라 아직 라우트가 없다.
|
||||
GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
final featureFlags = flags ?? FeatureFlags();
|
||||
GoRouter buildRouter(AuthRepository auth, {Repositories? repositories}) {
|
||||
// 저장소 선택은 앱이 뜰 때 한 번만 한다. 탭을 옮길 때마다 다시 만들면
|
||||
// Firestore 커서 같은 화면 상태가 매번 초기화된다.
|
||||
final repos = repositories ?? Repositories();
|
||||
// 한 번만 만든다. 라우트 빌더 안에서 만들면 탭을 옮길 때마다 연결 상태가 초기화된다.
|
||||
final linker = repos.linker(auth.providers);
|
||||
return GoRouter(
|
||||
initialLocation: appTabs.first.path,
|
||||
refreshListenable: auth,
|
||||
redirect: (context, state) {
|
||||
final atLogin = state.matchedLocation == loginPath;
|
||||
if (!auth.isSignedIn) return atLogin ? null : loginPath;
|
||||
if (atLogin) return appTabs.first.path;
|
||||
final at = state.matchedLocation;
|
||||
if (!auth.isSignedIn) return at == loginPath ? null : loginPath;
|
||||
if (auth.justSignedUp)
|
||||
return at == signupCompletePath ? null : signupCompletePath;
|
||||
if (at == loginPath || at == signupCompletePath)
|
||||
return appTabs.first.path;
|
||||
return null;
|
||||
},
|
||||
routes: [
|
||||
@@ -97,14 +107,29 @@ GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
path: loginPath,
|
||||
builder: (_, _) => LoginScreen(auth: auth),
|
||||
),
|
||||
GoRoute(
|
||||
path: signupCompletePath,
|
||||
builder: (_, _) => SignupCompleteScreen(onStart: auth.finishSignup),
|
||||
),
|
||||
StatefulShellRoute.indexedStack(
|
||||
builder: (_, _, shell) => AppShell(shell: shell, flags: featureFlags),
|
||||
builder: (_, _, shell) => AppShell(shell: shell, flags: repos.flags),
|
||||
branches: [
|
||||
StatefulShellBranch(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: appTabs[0].path,
|
||||
builder: (_, _) => const HomeScreen(),
|
||||
builder: (_, _) => HomeScreen(
|
||||
watchPlanet: repos.watchPlanet,
|
||||
galaxyRepository: repos.galaxy,
|
||||
planetRepository: repos.planet,
|
||||
repository: repos.home,
|
||||
// 홈의 「오늘의 퀘스트」에서 F4 로 들어간다. 저장소 선택은
|
||||
// repositories.dart 한 곳이므로 화면이 표본을 직접 만들지 않는다.
|
||||
questRepository: repos.quest,
|
||||
campaignRepository: repos.campaign,
|
||||
notifications: repos.notifications,
|
||||
eclipse: repos.eclipse,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -112,7 +137,11 @@ GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: appTabs[1].path,
|
||||
builder: (_, _) => const InsideScreen(),
|
||||
builder: (_, _) => InsideScreen(
|
||||
repository: repos.inside,
|
||||
translation: repos.translation,
|
||||
notifications: repos.notifications,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -120,7 +149,15 @@ GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: appTabs[2].path,
|
||||
builder: (_, _) => const GalaxyScreen(),
|
||||
// 탭 루트는 시안(354:220228)의 「내 행성」 그리드. 궤도 맵은 그 안에서 연다.
|
||||
builder: (_, _) => GalaxyHomeScreen(
|
||||
home: repos.home,
|
||||
watchPlanet: repos.watchPlanet,
|
||||
repository: repos.galaxy,
|
||||
planetRepository: repos.planet,
|
||||
notifications: repos.notifications,
|
||||
eclipse: repos.eclipse,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -128,7 +165,7 @@ GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: appTabs[3].path,
|
||||
builder: (_, _) => const StationScreen(),
|
||||
builder: (_, _) => StationScreen(repository: repos.station),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -136,7 +173,13 @@ GoRouter buildRouter(AuthRepository auth, {FeatureFlags? flags}) {
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: appTabs[4].path,
|
||||
builder: (_, _) => const MyScreen(),
|
||||
builder: (_, _) => MyScreen(
|
||||
repository: repos.my,
|
||||
linker: linker,
|
||||
push: repos.push,
|
||||
auth: auth,
|
||||
campaigns: repos.campaign,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user