WebView 위에서 웹 게임을 실행하며 네이티브 기능(햅틱, 영상 재생)과 연동하는 구조를 검증하기 위해 만든 데모입니다. Flutter + Firebase 기반의 미니게임 허브 형태로 구성했습니다.
flutter pub get
flutter runFirebase 설정:
flutterfire configure --project=centplay-demo- 테스트 환경: Flutter 3.35
- iOS + Android
| 패키지 | 용도 |
|---|---|
| flutter_riverpod | 상태 관리 (StreamProvider, Provider.family, StateProvider) |
| go_router | 라우팅 (ShellRoute + auth guard) |
| firebase_auth / cloud_firestore / firebase_messaging | 인증, 데이터, 푸시 |
| webview_flutter | 웹 게임 실행 |
| video_player | 트레일러 영상 재생 |
| share_plus | 공유 시트 |
| SBAggroOTF | 커스텀 폰트 |
lib/
├── core/theme.dart # 디자인 시스템 (SBAggroOTF + 퍼플/블루 액센트)
├── design_system/ # 공통 UI 컴포넌트
│ ├── primary_button.dart # debounce + 중복 호출 방지 + loading + error
│ ├── async_data_view.dart # loading/error/empty/data 4상태 강제
│ └── app_snackbar.dart # success/error/info 표준 토스트
├── models/ # Game, Video, Friend, ChatMessage
├── services/ # AuthService, FirestoreService, PushService
├── providers/ # Riverpod (auth, games, favorites, friends, theme)
├── screens/ # 12개 화면
├── widgets/ # GameCard, SectionHeader, Loading/Error/Empty
├── router.dart # GoRouter + ShellRoute + auth guard
└── main.dart # Firebase init + FCM background handler
- 홈: 추천 게임(가로 스크롤) + 랭킹(세로 리스트) + 검색
- 게임 상세: 썸네일, 설명, 게임플레이 트레일러, 찜/공유/상점, 비슷한 게임
- 게임 실행: 자체 호스팅 HTML5 게임 3종 + 외부 게임 2종. 풀스크린 WebView, 드래그 이동 가능한 나가기 버튼, iOS 스와이프백 차단
- 찜 목록: Firestore 서브컬렉션 기반 실시간 동기화
- 친구: 이메일 검색으로 추가, 상호 친구 등록
- 1:1 채팅: Firestore 실시간 메시징
- 알림: 읽음/미읽음 표시, 스와이프 삭제, 딥링크 라우팅
- 프로필: 테마 전환(라이트/시스템/다크), 컨트롤러 설정, 이용약관, 개인정보
- 상점: UI 데모
- 로그인: Google Sign-In + 게스트(익명) 로그인
- 푸시: FCM foreground 배너 + background/terminated 딥링크
- 게임패드: Bluetooth 컨트롤러 입력을 WebView JS 이벤트로 포워딩
여러 화면에서 반복되는 버튼과 비동기 화면의 동작 규칙을 컴포넌트 한 곳으로 모으고, 그 규칙을 위젯 테스트로 고정했습니다. 규칙을 문서로만 남기면 화면마다 다르게 구현되기 쉽기 때문에, 테스트로 고정해 규칙 위반이 리뷰가 아니라 빌드 실패로 드러나도록 구성했습니다.
| 컴포넌트 | 고정한 규칙 |
|---|---|
primary_button.dart |
액션 버튼의 연타/중복 호출 방지, 실행 중 로딩 표시 |
async_data_view.dart |
모든 비동기 화면이 loading, error(재시도), empty, data 4상태를 일관되게 처리 |
app_snackbar.dart |
토스트 메시지 디자인과 에러 재시도 액션 표준화 |
test/design_system/*_test.dart |
위 동작 규칙을 위젯 테스트로 고정. debounce가 빠지면 빌드 실패 |
analysis_options.yaml:avoid_print,use_build_context_synchronously를 에러로 승격.github/workflows/pr.yml: PR마다 format, analyze, test, debug 빌드를 자동 실행.github/CODEOWNERS,pull_request_template.md: 인증/CI 경로 변경 시 리뷰어 자동 지정, PR마다 시간/동시성 관련 확인 항목 유지
.github/workflows/rollback.yml: 이상 감지 시 Remote Config 플래그를 원격으로 off. 앱 재배포 없이 기능을 차단하는 롤백 경로를 준비
자체 호스팅 (centplay-demo.web.app):
| 게임 | 타입 |
|---|---|
| Brick Breaker | Canvas 2D, 터치 패들 |
| Snake | Canvas 2D, 스와이프 조종 |
| Flappy | Canvas 2D, 탭 플랩 |
Flutter 3.35 · Riverpod · GoRouter · Firebase (Auth/Firestore/FCM) · webview_flutter · video_player · share_plus · SBAggroOTF
