feat(flutter): 로그인 전에 받은 앱 링크를 로그인 뒤 이어서 연다

QR 을 기기 카메라로 찍어 앱이 열렸는데 로그인 전이면 인트로·로그인으로 가며 링크가 사라졌다.
링크를 기억해 두었다가 진입(인트로·로그인·온보딩)을 마치고 홈으로 갈 때 대신 연다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 23:48:00 +09:00
parent 65c2016ab5
commit be58689dff
3 changed files with 65 additions and 4 deletions
+17 -4
View File
@@ -15,6 +15,7 @@ import 'package:tma_app/features/diary/presentation/pages/diary_compose_page.dar
import 'package:tma_app/features/diary/presentation/pages/diary_page.dart';
import 'package:tma_app/features/diary/presentation/pages/diary_settings_page.dart';
import 'package:tma_app/features/diary/presentation/widgets/diary_join.dart';
import 'package:tma_app/features/entry/domain/entry_state.dart';
import 'package:tma_app/features/entry/presentation/providers/entry_provider.dart';
import 'package:tma_app/features/home/presentation/pages/home_page.dart';
import 'package:tma_app/features/intro/presentation/pages/intro_page.dart';
@@ -63,14 +64,26 @@ final appRouterProvider = Provider<GoRouter>((ref) {
// 탭바 위에 덮는 화면(등록 등)은 최상위 내비게이터에 올린다
final rootKey = GlobalKey<NavigatorState>();
// 로그인 전에 받은 앱 링크 — 진입(인트로·로그인·온보딩)을 마치고 홈으로 갈 때 대신 연다.
// 길 찾기 중에 바꾸므로 프로바이더 상태가 아니라 이 라우터만 쓰는 값으로 둔다
String? pendingLink;
final router = GoRouter(
navigatorKey: rootKey,
initialLocation: AppRoutes.splash,
refreshListenable: refresh,
redirect: (context, state) => AppRoutes.redirectFor(
ref.read(entryProvider).stage,
state.matchedLocation,
),
redirect: (context, state) {
final stage = ref.read(entryProvider).stage;
final location = state.matchedLocation;
final target = AppRoutes.redirectFor(stage, location);
if (target != null && stage != EntryStage.app && isAppLinkPath(location)) pendingLink = location;
if (stage == EntryStage.app && pendingLink != null && (target ?? location) == AppRoutes.home) {
final link = pendingLink;
pendingLink = null;
return link;
}
return target;
},
routes: [
GoRoute(
path: AppRoutes.splash,
@@ -153,6 +153,9 @@ class _LinkLandingPageState extends ConsumerState<LinkLandingPage> {
}
}
/// 앱 링크의 경로인지 — 로그인 전에 받은 링크를 기억할 때 (라우터가 쓴다)
bool isAppLinkPath(String path) => AppLinkKind.values.any((k) => path.startsWith(appLinkPattern(k).replaceAll(':code', '')));
/// 링크의 경로 → 무엇을 열지 (라우터가 쓴다)
String appLinkPattern(AppLinkKind kind) => switch (kind) {
AppLinkKind.petCard => '/$kCardLinkSegment/:code',