feat(ui): UI 화면 골격 + store + composite/maskSplit hook (v0-plan Task 9/10/11)

새 의존성:
- expo-image-picker ~56.0.13 (PhotoCapture)
- expo-media-library ~56.0.6 (CaptureResult 저장)
- expo-file-system ~56.0.7 (generateRegionMask 파일 저장 — Mac 구현 시)

새 파일:
- src/store/useAppStore.ts: zustand store (photoUri/maskUri/pose/mode + reset)
- src/features/segmentation/index.ts: SegmentationModule TS wrapper (Mac Swift 빌드 대기)
- src/features/composite/shaders.ts: Skia RuntimeEffect 셰이더 소스 (마스크 흰색 → 카메라, 그 외 → 베이스)
- src/features/composite/CompositeView.tsx: 합성 컴포넌트 골격 (Skia v2 API Mac 검증 대기)
- src/features/composite/useCameraFrameUri.ts: 카메라 프레임 URI hook 골격 (vision-camera v5 API Mac 검증 대기)
- src/features/maskSplit/generateRegionMask.ts: region 마스크 생성 골격 (Skia v2 API Mac 검증 대기)
- src/features/maskSplit/useModeMask.ts: mode 전환 시 마스크 자동 재생성 hook + cleanup race 처리
- src/screens/OnboardingScreen.tsx: 3장 슬라이드 (정상 동작)
- src/screens/PhotoCaptureScreen.tsx: 갤러리 선택 + 자세 검증 (PoseModule Mac 빌드 후 동작)
- src/screens/CaptureResultScreen.tsx: 결과 + 저장 + 공유 (expo-media-library)
- src/screens/LiveFittingScreen.tsx: 모드 전환 + 핀치/팬 + Composite 골격 (Camera는 v5 API Mac 검증 대기)
- App.tsx: 4화면 state-based navigation (onboarding → photo → live → result) + GestureHandlerRootView 감싸기

핵심 결정:
- vision-camera v5는 v4와 완전 다른 Nitro 기반 (takeSnapshot 미존재 / usePhotoOutput/usePreviewOutput hook 패턴).
  v0-plan v4 코드 그대로 옮길 수 없어 Camera 부분 골격 + Mac TODO 명시.
- Skia v2 child shader API도 v1과 다를 가능성 → CompositeView 골격 + Mac TODO.
- 모드 전환/핀치 줌/네비게이션/store/검증 로직은 골격 단계에서 정상 동작.

검증 (Windows 가능 범위):
- npx tsc --noEmit: 무에러
- npm test: 6 suites / 17 tests passed (UI 골격 추가가 기존 테스트 영향 없음 확인)

Mac에서 채울 부분 (정리):
- vision-camera v5 Camera + photoOutput + previewOutput 통합
- Skia v2 RuntimeEffect child shader 패턴 (ImageShader / useShader)
- expo-file-system v56 writeAsStringAsync(base64) 동작 확인
- generateRegionMask 본 구현 (Surface.MakeOffscreen + clipRect + encode PNG)
- 실기기 manual test 5종 (각 화면 전환 + 핀치 줌 + 캡쳐 + 저장 + 공유)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-25 16:38:44 +09:00
parent 69d61231b9
commit 1081a3a85e
18 changed files with 561 additions and 24 deletions

54
package-lock.json generated
View File

@@ -10,6 +10,9 @@
"dependencies": {
"@shopify/react-native-skia": "2.6.2",
"expo": "~56.0.4",
"expo-file-system": "~56.0.7",
"expo-image-picker": "~56.0.13",
"expo-media-library": "~56.0.6",
"expo-status-bar": "~56.0.4",
"react": "19.2.3",
"react-native": "0.85.3",
@@ -4529,6 +4532,47 @@
}
}
},
"node_modules/expo-file-system": {
"version": "56.0.7",
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-56.0.7.tgz",
"integrity": "sha512-dcKzo8ShPloM7jgfnMcJStgQebhP8owVjCkNI/aX6NMFV1CYB8bxKGMdnzJ3mXk5nfaiW+F/lSKr2UIJ02WAUA==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react-native": "*"
}
},
"node_modules/expo-image-loader": {
"version": "56.0.3",
"resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-56.0.3.tgz",
"integrity": "sha512-JgUo4fUeU1ZC+z8iBFj8v7yoGQnZrLbOVPyNE+DWVrld55F2F6R1ck+rmdm/8TNWLz1LhNQfD7c3XYP1ZikxXA==",
"license": "MIT",
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-image-picker": {
"version": "56.0.13",
"resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-56.0.13.tgz",
"integrity": "sha512-eLO6t3jTRE2tOmCGR6tQIYAdvxj66KanyRmIOH/aISx5Zb4AG5B5VHuOXx9+1T5PtNAoXwsHML0G5+vB4OgI3w==",
"license": "MIT",
"dependencies": {
"expo-image-loader": "~56.0.3"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-media-library": {
"version": "56.0.6",
"resolved": "https://registry.npmjs.org/expo-media-library/-/expo-media-library-56.0.6.tgz",
"integrity": "sha512-UsyVcxP7Op9ErFFLW1xImjoKFgKi7XSw8hrCfzf2yIG+OgVb9dsQth0mVRPgfRxdELagsUslXc1QXTiW8dpbaQ==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react-native": "*"
}
},
"node_modules/expo-modules-autolinking": {
"version": "56.0.12",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-56.0.12.tgz",
@@ -4900,16 +4944,6 @@
"react-native": "*"
}
},
"node_modules/expo/node_modules/expo-file-system": {
"version": "56.0.7",
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-56.0.7.tgz",
"integrity": "sha512-dcKzo8ShPloM7jgfnMcJStgQebhP8owVjCkNI/aX6NMFV1CYB8bxKGMdnzJ3mXk5nfaiW+F/lSKr2UIJ02WAUA==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react-native": "*"
}
},
"node_modules/expo/node_modules/expo-font": {
"version": "56.0.5",
"resolved": "https://registry.npmjs.org/expo-font/-/expo-font-56.0.5.tgz",