Restructure ORA editor into modular blueprints with browse dialog

- Split app.py into route blueprints (files, layers, images, polygon, mask, krita)
- Create services layer (polygon_storage, comfyui, file_browser)
- Extract config constants to config.py
- Split templates into Jinja partials (base, components, modals)
- Add browse dialog for visual file navigation
- Add /api/browse endpoint for directory listing
This commit is contained in:
2026-03-27 21:29:27 -07:00
parent 17da8c475e
commit fb812e57bc
21 changed files with 2269 additions and 1794 deletions

View File

@@ -65,11 +65,82 @@ All file paths are relative to the project root: `/home/noti/dev/ai-game-2`
- **PNG**: Auto-converted to ORA on open
### Open Flow
1. User enters path relative to project root (e.g., `scenes/kq4_010/pic.png`)
2. Backend checks if file exists
3. If PNG: auto-create ORA with single `base` layer
4. Parse ORA structure, extract layers
5. Return layer list + image data URLs
1. User clicks "Browse" button to open file browser dialog
2. Backend lists directories and files (PNG, ORA) from project root
3. User navigates directories, selects file
4. Backend checks if file exists
5. If PNG: auto-create ORA with single `base` layer
6. Parse ORA structure, extract layers
7. Return layer list + image data URLs
---
## Browse Dialog
### Purpose
Allows users to visually navigate the project directory and select PNG/ORA files without manually typing paths.
### UI Layout
```
┌─────────────────────────────────────────────────────────┐
│ OPEN FILE │
│ ───────────────────────────────────────────────────── │
│ 📁 .. │
│ 📁 scenes/ │
│ 📁 tools/ │
│ 🖼️ pic_010.ora │
│ 🖼️ pic_011.png │
│ │
│ Current: scenes/kq4_010/ │
│ │
│ [Cancel] [Open Selected] │
└─────────────────────────────────────────────────────────┘
```
### Behavior
- **Double-click folder**: Navigate into folder
- **Double-click file**: Select and open immediately
- **Single-click + Enter**: Select and open
- ** ".." entry**: Navigate to parent directory
- **File types**: Only show `.png` and `.ora` files
- **Hidden files**: Excluded (dot-prefixed)
### Backend Implementation
#### `GET /api/browse`
List directory contents for browsing.
**Query params:**
- `path`: Directory path relative to project root (default: "")
**Response:**
```json
{
"current_path": "scenes/kq4_010",
"parent_path": "scenes",
"directories": [
{"name": "subdir1", "path": "scenes/kq4_010/subdir1"}
],
"files": [
{"name": "pic.png", "path": "scenes/kq4_010/pic.png", "type": "png"},
{"name": "scene.ora", "path": "scenes/kq4_010/scene.ora", "type": "ora"}
]
}
```
### Frontend State
```javascript
// Added to main store
browseModal: false,
browsePath: '', // Current directory being browsed
browseDirectories: [], // List of {name, path}
browseFiles: [], // List of {name, path, type}
browseSelected: null, // Currently selected file path
```
### Entry Point
- Button next to path input: `[Browse...]`
- Or clicking into the path input field (if empty)
---
@@ -247,6 +318,29 @@ Since browser cannot detect when Krita saves:
## API Reference
### File Browser
#### `GET /api/browse`
List directory contents for file browsing.
**Query params:**
- `path`: Directory path relative to project root (default: "")
**Response:**
```json
{
"current_path": "scenes/kq4_010",
"parent_path": "scenes",
"directories": [
{"name": "subdir1", "path": "scenes/kq4_010/subdir1"}
],
"files": [
{"name": "pic.png", "path": "scenes/kq4_010/pic.png", "type": "png"},
{"name": "scene.ora", "path": "scenes/kq4_010/scene.ora", "type": "ora"}
]
}
```
### File Operations
#### `POST /api/open`
@@ -525,7 +619,7 @@ Check if temp file was modified.
```
┌──────────────────────────────────────────────────────────────────────┐
│ [Open: ________________________] [🌀 Open] [Settings ⚙]
│ [Open: ________________________] [📁 Browse] [🌀 Open] [Settings ⚙] │
├───────────────────┬──────────────────────────────────────────────────┤
│ LAYERS │ │
│ ☑ □ base │ │
@@ -584,6 +678,31 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
---
## Browse Modal
```
┌─────────────────────────────────────────────────────────┐
│ OPEN FILE │
│ ───────────────────────────────────────────────────── │
│ 📁 .. (parent directory) │
│ 📁 scenes/ │
│ 📁 tools/ │
│ 🖼️ pic_010.ora │
│ 🖼️ pic_011.png │
│ │
│ Path: scenes/kq4_010/ │
│ │
│ [Cancel] [Open Selected] │
└─────────────────────────────────────────────────────────┘
```
- Double-click folder to navigate
- Double-click file to open immediately
- Single-click to select, then click "Open Selected"
- Only shows `.png` and `.ora` files
---
## Settings Modal
```
@@ -622,6 +741,7 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
- [ ] `get_layer_image(ora_path, layer_name)` - Extract PNG
- [ ] `get_base_image(ora_path)` - Get merged/composited base
- [ ] Create `app.py` with Flask routes:
- [ ] File browser (`/api/browse`)
- [ ] File operations (`/api/open`, `/api/save`)
- [ ] Layer operations (all `/api/layer/*`)
- [ ] Image serving (`/api/image/*`)
@@ -632,6 +752,7 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
### Phase 3: Frontend UI
- [ ] Create `editor.html` with Tailwind + Alpine.js
- [ ] File open input and handler
- [ ] Browse modal for file selection
- [ ] Layer list with visibility toggles
- [ ] Canvas area with stacked layer images
- [ ] Layer operations (rename, delete, reorder buttons)