Files
photobooth-app/1_PROJECT_IMPLEMENT.md
T

7.2 KiB

📋 KẾ HOẠCH PHÁT TRIỂN DỰ ÁN: MOBILE PHOTOBOOTH (VINTAGE STYLE)

Dự án ứng dụng Photobooth di động đa nền tảng (Native iOS/Android), lưu trữ mã nguồn tập trung trên Debian Linux, ưu tiên phát triển, build và kiểm thử trên Android trước.


📁 1. Cấu Trúc Thư Mục Dự Án (Monorepo Structure)

Tạo cấu trúc thư mục này tại thư mục gốc trên Debian Server để quản lý chung toàn bộ tài nguyên và mã nguồn của cả hai nền tảng.

photobooth-project/
├── .gitignore
├── README.md
├── PLAN.md
├── assets/                          # Tài nguyên dùng chung cho cả iOS và Android
│   ├── fonts/                       # Font chữ vintage, viết tay (.ttf, .otf)
│   │   ├── CourierPrime-Regular.ttf
│   │   └── HomemadeApple-Regular.ttf
│   ├── frames/                      # Khung ảnh định dạng PNG-24 trong suốt
│   │   ├── instax_mini_single.png
│   │   └── photobooth_4strip.png
│   └── stickers/                    # Icon phụ kiện, smileys dạng vector/PNG cao cấp
│       ├── sunglasses.png
│       └── vintage_heart.svg
│
├── android-project/                 # Dự án Android Native (Mở bằng Android Studio)
│   ├── build.gradle.kts
│   ├── settings.gradle.kts
│   └── app/
│       ├── build.gradle.kts
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               └── java/com/photobooth/app/     # Mã nguồn Kotlin
│
└── ios-project/                     # Dự án iOS Native (Mở bằng Xcode trên Mac)
    ├── PhotoboothApp.xcodeproj
    └── PhotoboothApp/
        ├── Info.plist
        └── Assets.xcassets          # Nơi chứa LaunchScreen, AppIcon của iOS


🛠️ 2. Chuẩn Bị Các Tập Tin Cấu Hình Cốt Lõi

🔹 File 2.1. .gitignore (Đặt tại thư mục gốc)

Tập tin này giúp bỏ qua các file rác của hệ thống Linux, Android Studio và Xcode khi push code lên Debian Git Server.

# --- OS Files ---
.DS_Store
Thumbs.db
*.swp

# --- Android Studio / Gradle ---
.gradle/
build/
captures/
.externalNativeBuild/
.cxx/
local.properties
*.apk
*.aar
*.bms
.idea/workspace.xml
.idea/libraries/
.idea/caches/

# --- Xcode / iOS ---
build/
DerivedData/
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
*.xcworkspace/
!*.xcworkspace/contents.xcworkspacedata
.strongspace/
project.xcworkspace/
xcuserdata/
*.moved-aside
*.xccheckout
*.xcscmblueprint

🔹 File 2.2. AndroidManifest.xml (Cấu hình quyền Android)

Đặt tại android-project/app/src/main/AndroidManifest.xml. Cần khai báo sẵn các quyền về Camera, Lưu trữ và In ấn.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.photobooth.app">

    <!-- Quyền truy cập Camera -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    
    <!-- Quyền lưu ảnh (Android 10 trở xuống cần WRITE, Android 11+ dùng Scoped Storage) -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
                     android:maxSdkVersion="28" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <!-- Quyền Internet để in ấn qua mạng Local -->
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Retro Photobooth"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

🔹 File 2.3. Info.plist (Cấu hình quyền iOS)

Đặt sơ bộ tại ios-project/PhotoboothApp/Info.plist để khi chuyển sang Mac build không bị crash do thiếu giải trình quyền.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>com.photobooth.app</string>
    <key>CFBundleName</key>
    <string>Retro Photobooth</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    
    <!-- Giải trình quyền sử dụng Camera -->
    <key>NSCameraUsageDescription</key>
    <string>Ứng dụng cần sử dụng Camera để chụp ảnh Photobooth.</string>
    
    <!-- Giải trình quyền lưu trữ ảnh vào Thư viện -->
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Ứng dụng cần quyền lưu ảnh đã chụp và trang trí vào thư viện của bạn.</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>Ứng dụng cần quyền thêm ảnh vào thư viện của bạn.</string>
</dict>
</plist>


🏃‍♂️ 3. Các Lệnh Triển Khai Nhanh Trên Debian Terminal

Để tạo nhanh bộ khung này trên Debian mà không cần tạo thủ công từng thư mục, bạn có thể chạy đoạn script ngắn này:

# 1. Tạo thư mục gốc dự án
mkdir -p photobooth-project && cd photobooth-project

# 2. Tạo cấu trúc thư mục tài nguyên và các project con
mkdir -p assets/fonts assets/frames assets/stickers
mkdir -p android-project/app/src/main/java/com/photobooth/app
mkdir -p ios-project/PhotoboothApp/Assets.xcassets

# 3. Khởi tạo Git repository nội bộ
git init

---

## 📅 4. Kế Hoạch Chạy Thử Nghiệm Giai Đoạn 1 (Sprint 1 - Tuần 1-2)

* [ ] **Chuẩn bị dữ liệu mẫu:** Copy ít nhất 2 font `.ttf`, 2 khung hình `.png`3 sticker vào các thư mục tương ứng trong `assets/`.
* [ ] **Mở Android Studio trên Debian:** Import thư mục `android-project`.
* [ ] **Cấu hình Gradle:** Tích hợp các dependency cho CameraX (`androidx.camera:camera-camera2`).
* [ ] **Code kiểm thử:** Tạo màn hình Preview Camera cơ bản trên Android Emulator (đã bật KVM) để đảm bảo luồng hình ảnh phần cứng hoạt động ổn định.

> 💡 **Mẹo nhỏ:** Khi viết code xử lý tọa độ kéo thả sticker trên Android sau này, hãy thiết kế một cấu trúc dữ liệu kiểu JSON đại diện cho "vị trí tương đối" (tính theo %) để sau này đưa sang iOS đọc hiểu y hệt:
> ```json
> { "sticker_id": "sunglasses", "x_percent": 0.25, "y_percent": 0.40, "scale": 1.2, "rotation_degree": 45 }
> 
> ```