feat: enhance styling and layout for toolbar, map components, and editor

- Updated toolbar styles for improved layout and appearance, including padding and margin adjustments.
- Introduced new styles for scale menu and compact dropdowns.
- Enhanced map pin tooltips with better positioning and hover effects.
- Added new styles for map sheet filters, including search and date range controls.
- Improved editor styles for a more cohesive look and feel, including transport controls for video editing.
- Expanded GeoLocation interface to include additional address fields and formatted address.
- Updated MediaItem interface to include storage reference and uploadedBy fields.
- Enhanced MediaComment interface with author details for better user identification.
- Introduced GalleryUser interface to represent signed-in users in the host app.
This commit is contained in:
2026-07-23 07:34:20 +05:30
parent bc8bf2007d
commit 7673fc63ea
35 changed files with 3130 additions and 394 deletions
+33 -8
View File
@@ -55,9 +55,10 @@ what it needs. The full, living checklist is in [`docs/ROADMAP.md`](docs/ROADMAP
### Platform
| Area | Details |
| --- | --- |
| **Backend** | Pluggable `StorageAdapter` — zeroconfig localStorage/IndexedDB default, or **Supabase** (Postgres + Storage) adapter included |
| **Search** | Name / place / tag / object / **OCR text** / **semantic** — blended and relevanceranked |
| **Theming** | `accentColor` + `borderRadius` props; Light / Dark / SemiDark / System |
| **Backend** | Pluggable `StorageAdapter` — zeroconfig localStorage/IndexedDB default, or **Supabase** (Postgres + Storage) adapter included; optional **incremental** `applyChanges` + durable `putMedia` for backendfriendly partial writes |
| **Embedding** | Drop into a host app: `embedded` layout, `chrome` suppression, `hiddenViews`, host **`currentUser`** identity (identitystamped comments / uploads / versions), `shareBaseUrl`, serverbacked **`lockProvider`**, fullscreen mode — live config (no remount) |
| **Search** | Name / place / tag / object / **OCR text** / caption / note / **semantic** — blended and relevanceranked |
| **Theming** | `accentColor` + `borderRadius` props **and a full `ThemeTokens` map (50+ keys)** → CSS variables; Light / Dark / SemiDark / System |
| **A11y / responsive** | Keyboard nav, focus traps, reducedmotion, ARIA; works down to ~280 px |
| **Security** | Perrequest **nonce CSP**, security headers, filename sanitisation, URLscheme allowlist, serveronly API keys |
@@ -149,14 +150,29 @@ export default function Gallery() {
| --- | --- | --- | --- |
| `photos` | `MediaItem[] \| { src, … }[]` | `[]` | Initial library; loose inputs are normalised + autoclassified |
| `albums` | `Album[]` | `[]` | Initial user albums |
| `adapter` | `StorageAdapter` | localStorage | Persistence backend (swap for S3/DB/REST) |
| `adapter` | `StorageAdapter` | localStorage | Persistence backend (swap for S3/DB/REST); supports incremental `applyChanges` + durable `putMedia` |
| `ai` | `AIProvider \| boolean` | `false` | Object/face/caption/search/generative provider |
| `theme` | `'system' \| 'light' \| 'dark'` | `'system'` | Appearance |
| `theme` | `'system' \| 'light' \| 'dark' \| 'semi-dark'` | `'system'` | Appearance |
| `accentColor` | `string` | `#0a84ff` | Accent colour |
| `borderRadius` | `number` | `10` | Base corner radius (px) for all rounded UI |
| `themeTokens` | `ThemeTokens` | | Pertheme background / gradient / opacity / sidebar colour + radius overrides |
| `themeTokens` | `ThemeTokens` | | Full pertheme token map (50+ keys) → CSS variables (backgrounds, cards, glass, separators, text tiers, shadows, radii, sidebar/toolbar sizing…) |
| `features` | `Partial<GalleryFeatures>` | all on | Toggle editor / camera / ai / map / import / export / sharing |
| `showWindowChrome` | `boolean` | `false` | Render the macOS trafficlight title bar |
| `showWindowChrome` | `boolean` | `false` | Render the macOS trafficlight title bar (legacy alias of `chrome.titlebar`) |
**Embedding into a host app** — these props let the gallery drop into an existing product shell instead of running standalone. Full guide, token table and adapter contract: **[`packages/photo-sdk/README.md` → “Embedding in a host app”](packages/photo-sdk/README.md#embedding-in-a-host-app)**.
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `embedded` | `boolean` | `false` | Lay out at `height:100%` inside the host container (not a full viewport); `cursor:pointer` on controls |
| `chrome` | `Partial<GalleryChrome>` | `DEFAULT_CHROME` | Suppress the gallery's own `{ titlebar, sidebar, toolbar, themeSwitcher }` when the host provides them |
| `hiddenViews` | `ViewId[]` | `[]` | Hide sidebar rows + Collections cards, e.g. `['screenshots', 'sys:documents']` |
| `keyboardShortcuts` | `boolean` | `true` | Bind global shortcuts (⌘A, Delete, F, Esc, Enter) to `window` |
| `currentUser` | `GalleryUser` | | Host's signedin user; stamps comments / uploads / versions with real identity |
| `shareBaseUrl` | `string` | `${origin}/gallery` | Base URL for generated share links |
| `defaultFullscreen` | `boolean` | `false` | Start maximised over the host page (`apg--fullscreen`) |
| `lockProvider` | `LockProvider` | | Serverbacked, peruser RecentlyDeleted lock (replaces the devicelocal hash) |
The live config is applied on every render, so changing `theme`, `themeTokens`, `currentUser` or `chrome` reapplies without remounting the gallery.
### 🎨 Customization (props **or** env)
@@ -188,6 +204,14 @@ const myApiAdapter: StorageAdapter = {
<PhotoGallery adapter={myApiAdapter} />;
```
Two optional members make an adapter backendfriendly (both additive — `save`/`putBlob`only adapters keep working):
`applyChanges(changes: StateChanges)` — called *instead of* `save()` on each debounced change, sending only
`{ upsertMedia?, removeMedia?, upsertAlbums?, removeAlbums?, upsertPeople?, removePeople?, labelAliases?, deletedLabels? }`
(a rejection rolls the snapshot back and the next persist retries the same diff); and
`putMedia(id, blob, { name, mime }): Promise<{ ref, url }>` — durable byte storage preferred over `putBlob`, where
`url``MediaItem.src` (renderable now, may be a signed URL) and `ref``MediaItem.storageRef` (survives a reload).
See [`packages/photo-sdk/README.md` → “Incremental storage adapters”](packages/photo-sdk/README.md#incremental-storage-adapters).
### Custom AI provider
Every method is optional and the UI degrades gracefully. Implement object detection clientside
@@ -250,7 +274,8 @@ Still planned / not yet implemented:
- **Auth & multiuser sharing** (real recipients, permissions). Sharing today creates devicelocal links.
- **Captions** (transformers.js BLIP) and a firstclass Hugging Face Inference provider option.
- **Map** heatmaps / trips / reversegeocode place names; true grid **virtualization** for millions of items.
- **Map** heatmaps / trips; true grid **virtualization** for millions of items. (Fulladdress **reversegeocoding**
— road → city → country via OpenStreetMap Nominatim, shown in the Info panel — is now live.)
- **Serverside** 30day purge (pg_cron), Storage blob deletion on permanentdelete.
- Storybook + API docs, Docker/K8s, automated CI.