퀘스트 일시 정지 · 이어하기 · 진행 상태 서버 저장 · 목록 보상받기
This commit is contained in:
@@ -14,6 +14,8 @@ import '../../features/home/coach_mark.dart';
|
||||
import '../../features/home/home_screen.dart';
|
||||
import '../../features/inside/inside_screen.dart';
|
||||
import '../../features/my/my_screen.dart';
|
||||
import '../../features/quest/quest_data.dart' show QuestRepository;
|
||||
import '../../features/quest/widgets/paused_quest_capsule.dart';
|
||||
import '../../features/station/station_screen.dart';
|
||||
|
||||
/// 하단 탭 하나.
|
||||
@@ -149,7 +151,8 @@ GoRouter buildRouter(AuthRepository auth, {Repositories? repositories}) {
|
||||
builder: (_, _) => SignupCompleteScreen(onStart: auth.finishSignup),
|
||||
),
|
||||
StatefulShellRoute.indexedStack(
|
||||
builder: (_, _, shell) => AppShell(shell: shell, flags: repos.flags),
|
||||
builder: (_, _, shell) =>
|
||||
AppShell(shell: shell, flags: repos.flags, quests: repos.quest),
|
||||
branches: [
|
||||
StatefulShellBranch(
|
||||
observers: [HomeRefreshObserver()],
|
||||
@@ -238,11 +241,19 @@ GoRouter buildRouter(AuthRepository auth, {Repositories? repositories}) {
|
||||
/// 사라져 딥링크·기존 경로가 죽고, 플래그를 켤 때 재배포가 필요해진다. 여기서는
|
||||
/// 하단 바에 그리는 목적지만 줄이고, 눌린 위치를 원래 브랜치 번호로 되돌린다.
|
||||
class AppShell extends StatelessWidget {
|
||||
const AppShell({super.key, required this.shell, required this.flags});
|
||||
const AppShell({
|
||||
super.key,
|
||||
required this.shell,
|
||||
required this.flags,
|
||||
this.quests,
|
||||
});
|
||||
|
||||
final StatefulNavigationShell shell;
|
||||
final FeatureFlags flags;
|
||||
|
||||
/// 일시 정지 Quest 캡슐(원장 C-83)을 읽는 저장소. null 이면 캡슐이 없다.
|
||||
final QuestRepository? quests;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => ListenableBuilder(
|
||||
listenable: flags,
|
||||
@@ -254,43 +265,50 @@ class AppShell extends StatelessWidget {
|
||||
return Scaffold(
|
||||
body: shell,
|
||||
// Figma 탭 줄은 좌우 16 을 비우고 칸을 나눈다(350:215853).
|
||||
bottomNavigationBar: ColoredBox(
|
||||
color: AppColors.cosmicVoid,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: NavigationBar(
|
||||
// 숨긴 탭에 머무는 동안(딥링크 등)에는 선택 표시를 첫 탭으로 둔다.
|
||||
selectedIndex: selected < 0 ? 0 : selected,
|
||||
onDestinationSelected: (i) {
|
||||
// 다른 탭에서 HOME 으로 돌아오면 다시 읽는다(HOME 은 탭 전환으로 다시 만들어지지 않는다).
|
||||
if (branches[i] == 0 && shell.currentIndex != 0)
|
||||
homeRefreshSignal.value++;
|
||||
final again = branches[i] == shell.currentIndex;
|
||||
shell.goBranch(
|
||||
branches[i],
|
||||
// initialLocation: true 를 주면 이미 열려 있는 탭을 다시 누를 때 루트로 되돌아간다.
|
||||
initialLocation: again,
|
||||
);
|
||||
// 설명 프레임 `2097:16427` 「HOME 화면에서 클릭 시, Y스크롤값 초기화」(INSIDE · GALAXY ·
|
||||
// MY 동일) — 열려 있는 탭을 다시 누르면 그 탭 루트 화면을 맨 위로 올린다.
|
||||
if (again) {
|
||||
scrollTabToTop(
|
||||
shell.route.branches[branches[i]].navigatorKey,
|
||||
);
|
||||
}
|
||||
},
|
||||
destinations: [
|
||||
for (final tab in tabs)
|
||||
NavigationDestination(
|
||||
// Coach Mark ② 가 MY 위치를 가리킨다(coach_mark.dart).
|
||||
icon: tab.path == appTabs.last.path
|
||||
? KeyedSubtree(key: coachMyTabKey, child: tab.icon)
|
||||
: tab.icon,
|
||||
label: tab.label,
|
||||
),
|
||||
],
|
||||
// 그 바로 위에 일시 정지 Quest 캡슐 한 줄(원장 C-83) — 없으면 높이 0.
|
||||
bottomNavigationBar: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (quests case final repo?) PausedQuestCapsule(repository: repo),
|
||||
ColoredBox(
|
||||
color: AppColors.cosmicVoid,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: NavigationBar(
|
||||
// 숨긴 탭에 머무는 동안(딥링크 등)에는 선택 표시를 첫 탭으로 둔다.
|
||||
selectedIndex: selected < 0 ? 0 : selected,
|
||||
onDestinationSelected: (i) {
|
||||
// 다른 탭에서 HOME 으로 돌아오면 다시 읽는다(HOME 은 탭 전환으로 다시 만들어지지 않는다).
|
||||
if (branches[i] == 0 && shell.currentIndex != 0)
|
||||
homeRefreshSignal.value++;
|
||||
final again = branches[i] == shell.currentIndex;
|
||||
shell.goBranch(
|
||||
branches[i],
|
||||
// initialLocation: true 를 주면 이미 열려 있는 탭을 다시 누를 때 루트로 되돌아간다.
|
||||
initialLocation: again,
|
||||
);
|
||||
// 설명 프레임 `2097:16427` 「HOME 화면에서 클릭 시, Y스크롤값 초기화」(INSIDE · GALAXY ·
|
||||
// MY 동일) — 열려 있는 탭을 다시 누르면 그 탭 루트 화면을 맨 위로 올린다.
|
||||
if (again) {
|
||||
scrollTabToTop(
|
||||
shell.route.branches[branches[i]].navigatorKey,
|
||||
);
|
||||
}
|
||||
},
|
||||
destinations: [
|
||||
for (final tab in tabs)
|
||||
NavigationDestination(
|
||||
// Coach Mark ② 가 MY 위치를 가리킨다(coach_mark.dart).
|
||||
icon: tab.path == appTabs.last.path
|
||||
? KeyedSubtree(key: coachMyTabKey, child: tab.icon)
|
||||
: tab.icon,
|
||||
label: tab.label,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user