Spaces:
Runtime error
Runtime error
Commit History
-
Feat: capture inbox (Phase B) β phone captures merge into the libraryβ
/capture with a token enqueues place(s) into an ephemeral, TTL'd in-memory inbox. New POST /capture-inbox/{token} drains a token's captures and merges them into the caller's library (reuses the living-library _merge_rows) β returns a fresh job like /import. Client _pullCaptureInbox() drains on load and shows "π² N places captured from your phone" with β¨ New badges; a #capture-setup card in the import card surfaces the token (localStorage). Fixes an empty-multipart-body 400 by always sending merge_into (even ""). tests/test_capture.py extended (enqueue, drain+merge, idempotency, status preserved); visual review of the setup card + full round-trip at mobile/desktop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>eda6c91 -
Feat: living-library merge polish (Phase 3)β
- /import returns added_urls + kept; merge_rows now returns the added rows. - Client tags freshly-merged places (row._isNew) β a "β¨ New" card badge, floats them to the top of Browse (stable, transient β resets on reload). - Merge banner reports "N new Β· M already in your library". - Import card gains a Merge/Replace radio (#import-mode), shown only when a cached library exists; a zero-overlap merge still offers Replace inline. Completes the living-library feature (Phases 1β3). Visual review at mobile + desktop; tests/test_merge.py extended (added_urls/kept) and green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>f981d71 -
Feat: client-side library persistence (localStorage restore card)β
Cache the canonical CSV in the browser after load and write-through on every edit (status, fields, coords). A returning visitor with no live job sees a #restore-card that replays the cached CSV through /import β a pure reconstruction-cache, so status/coords/edits round-trip losslessly with no new data shape and no server change. Stored only on-device; Download stays the durable backup. Works in both deployment modes (no HOSTED branch). - app.js: importPlacesFile() refactored out of handleImportFile; cacheLibrary/ cacheLibrarySoon/maybeShowRestore + restore/forget handlers; quota note - index.html + app.css: #restore-card above the import card - tests/test_persistence.py: cache/restore round-trip is lossless (CI guardrail) - docs: README, CLAUDE.md, TODO (item marked done; IndexedDB deferred) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1c43cdb
-
Docs: split Instagram export guide into desktop + mobile stepsβ
Harshith Belagur +1: ClaudeThe "How to get your Instagram file" guide, FAQ entry, and README only documented one entry path (phrased for the app). Split each into a π» computer (instagram.com) flow and a π± Instagram app flow, sharing the common Accounts Center β Download your information steps. Adds an .export-platform heading style for the two labeled blocks in the Extract tab. Co-Authored-By: Claude <noreply@anthropic.com>08d1d42 -
Feat: single Instagram URL extraction via CAPTION_PROXY_URLβ
Re-adds the URL input on the Extract tab. Caption fetch now routes through a configurable proxy (CAPTION_PROXY_URL) on hosted builds β default allorigins.win requires no account. Local Docker skips the proxy and uses yt-dlp + direct OG scraping instead. pipeline/transcribe.py: fetch_post_metadata gains proxy_url param; _fetch_via_proxy handles allorigins.win JSON response format. web/app.py: _run_url_pipeline + /extract-url + /url-chatbot-prepare restored; reads CAPTION_PROXY_URL from env. deploy/hosted.env.example: CAPTION_PROXY_URL=https://api.allorigins.win/get TODO.md: P0 item for server-side video transcription; URL item updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>56b50ce -
Revert: remove single Instagram post URL featureβ
Removed the URL input from the Extract tab, all backend routes (/extract-url, /url-chatbot-prepare), JS logic, CSS, and the fetch_post_metadata/OG scraping helpers from transcribe.py. Root cause: yt-dlp needs --cookies-from-browser for Instagram auth (works locally, not on a hosted server). Tracked in TODO.md as a potential local-only CLI flag (--url) instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>425566e -
Feature: extract a single place from an Instagram post URLβ
Users can now paste any https://www.instagram.com/p/β¦ URL directly in the upload card as an alternative to the full export ZIP. yt-dlp fetches the post caption and optional geotag server-side, the same LLM extraction + geocode + KML export pipeline runs on the result, and progress is streamed via the existing SSE flow β no new UI states needed. - pipeline/transcribe.py: fetch_post_metadata() uses yt-dlp --dump-json - web/app.py: _run_url_pipeline() + POST /extract-url route - index.html: URL input field + "or paste a single post URL" divider - app.js: URL mode β typing a valid IG URL enables the run button, clears any pending file; selecting a file exits URL mode - app.css: .url-or-divider and .url-input-row styles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>714e84b
-
UX: footer copy, mobile hero stack, visual review workflowβ
- Footer: "Open source β star it, fork it, break it, fix it, make it yours. Contribute on GitHub β" - Hero stacks vertically on mobile (β€480px): full-width Watch demo button below copy - CLAUDE.md: document required visual review (Playwright 390/768/1280px) before every front-end commit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bc8eb05 -
Fix: footer centering and visited link colorβ
Add max-width + margin:auto so footer aligns with card content, not the page edge. Add a:visited rule to prevent browser-default purple link color. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>311b263 -
UX: remove docker note from hero, add OSS footerβ
- Hero card is back to clean copy + button only; Docker info lives in the FAQ where it belongs - Add #site-footer: "Open source β contribute on GitHub β", border-top, muted text, full-width Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fada9fe -
Fix: demo hero layout β nested structure fixes copy collapse and docker note rowβ
Wraps copy+button in .demo-hero-main (flex row) inside #demo-hero (flex column) so the docker note reliably sits below as its own full-width row. Previously all three siblings were in a flat flex row, causing the copy to collapse into a narrow word-wrap column. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8822e0c -
UX: fix demo hero font sizes and docker note copyβ
- Remove hardcoded 0.85rem from strong (inherits body default), bump span to 0.88rem and docker note to 0.82rem so the hero reads consistently with the rest of the UI - Reword docker strip to "Want to run it locally? Docker version on GitHub" β avoids implying only Docker is free Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bdaa9fe -
UX: Docker nudge on landing, FAQ item, Ollama-aware tour stepβ
- Add `.demo-docker-note` strip inside `#demo-hero` linking to GitHub repo for self-hosting with Docker - Add FAQ item "Can I run this fully offline and free with Docker?" (after AI models FAQ) - Tour model-picker step (`model-card`) is now Ollama-aware: on hosted (`OLLAMA_ENABLED=false`) the Ollama option is omitted; `body` can be string or function - Update README.md and CLAUDE.md to document all three changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7d20eac -
UX: floating feature-request button β pre-filled GitHub issueβ
- Floating π‘ pill button (bottom-right, z-index 9000, safe-area-inset aware for iOS) - Click opens a modal (title + details fields, slide-in animation, Escape / overlay-click to dismiss) - Submit constructs issues/new?labels=enhancement&title=β¦&body=β¦ and opens in new tab - Collapses to emoji-only below 480 px so it doesn't crowd mobile screens Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9f1919e -
UX: demo tour with dummy data, hero placement on landing pageβ
- tour.js: inject 8 real-world demo places (Tokyo/London/Paris/LA/Bangkokβ¦) into allRows so users see a fully populated Roulette pick, Browse grid with Leaflet map, and download bar β no upload needed - HTML: move tour trigger from FAQ tab to a #demo-hero card between the header and the nav (βΆ Watch demo) - app.css: replace .tour-cta-card with #demo-hero styles; tour state is fully restored on exit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3e19b3d -
UX: add guided tour, pipeline timing noteβ
- tour.js: 6-step spotlight tour (upload β model β run β reimport β roulette β pipeline diagram); simulates tab navigation and temporarily reveals sub-tab-bar in demo mode; triggered by βΆ Take the tour button in FAQ - Progress card: static timing note ("usually 5β10 min β may appear stuck") so users don't abandon a running job - app.css: tour overlay/spotlight/tooltip styles + .progress-timing-note + .tour-cta-card/.btn-tour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5c44de2 -
UX: add FAQ tab with pipeline diagram, About, and accordion FAQβ
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>23dabb1 -
UX: remove quality scores from model cardsβ
Scores were mostly dashes (β) for newer models and added noise rather than signal. Cards now show only the cost estimate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2a30ad3 -
Fix: remove #roulette-section { display:none } β roulette panel was blankβ
Leftover CSS rule permanently hid the roulette card content regardless of the sub-panel active state. Visibility is handled by .sub-panel.active now. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ccd6e8c -
UX: drop Exports tab, auto-spin Roulette on first visitβ
- Remove the Exports sub-tab entirely β it was a one-shot action poorly placed as a dedicated tab. Download buttons (KML / GeoJSON / CSV) and the Google My Maps instructions now live in a #download-bar at the top of Browse, revealed when showSubTabBar() fires. - Roulette now auto-spins on first visit: showSubTab('roulette') triggers spin-btn.click() if #pick-card is still hidden. Subsequent tab switches don't re-spin (card is already visible). - Clean up orphaned success-block / success-ring CSS (no longer used). - Update test_routes.py: assert no exports tab, assert download-bar is inside the explore panel. - CLAUDE.md + README.md updated to reflect two-sub-tab nav. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>36362ca
-
Web UI: two-tier nav β Extract / Explore tabs visible from landingβ
Top nav (always sticky): [π₯ Extract] [πΊ Explore] - Extract tab: full pipeline UI (upload, model picker, run, progress) - Explore tab: KML/CSV import card; once data loads a sub-tab bar appears with [β¬ Exports] [π² Roulette] [π Browse] After extraction β auto-jump to Explore β Roulette (nudge toast). After KML/CSV import β Explore β Browse. οΌ New button switches back to Extract tab (no page reload). Clean up TASKS.md (remove completed phases) and TODO.md (remove all completed items, keep only open work). All 24 e2e + 14 structural + 2 guardrail tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>383680a -
Revert session restore: import card is the right returning-user flowβ
The server-ping restore banner was over-engineered β job data expires after 24h anyway and returning users naturally drop their KML/CSV into the always- visible import card to get straight to Roulette/Browse. Removed _restoreSession IIFE, #restore-banner HTML, and all associated CSS/JS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>519bd6d -
Web UI: session restore for returning users + food-only filterβ
Returning users: showTabBar() now persists lastJobId to localStorage. On page load, _restoreSession() pings /results/{id}; if data is alive a #restore-banner offers Resume / Start fresh β no re-upload needed. Food-only filter: FOOD_CATEGORIES (Restaurant, Bar, Cafe, Bakery, Market) defined in both app.js and web/app.py. filterState.foodOnly defaults ON (persisted in localStorage). applyFilters() gates the Browse grid + map; /roulette accepts food_only=true and filters server-side. Toggle chip #food-toggle in the filter bar; active state kept in sync by applyFilters(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>facc20d -
Web UI: Phase 4 tab-bar UX polishβ
- Tab badges: gradient pill (ig1βig3), hidden via CSS :empty + explicit display:none when count is 0 so empty pills never render - Stat strip: shows ~$X.XX cost alongside places/pinned when non-zero - Mobile: -webkit-overflow-scrolling:touch on .tab-bar-inner for iOS momentum scroll Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>89f8c84 -
Web UI: tab-bar SPA, KML/CSV import, refactor index.htmlβ
Three-tab SPA (Exports | Roulette | Browse) replaces the post-extraction long scroll. Roulette is the default tab after extraction (with nudge toast); Browse is the default after import. Tab badges show unvisited/total counts. KML/CSV import card (always visible before extraction) lets returning users skip re-extraction entirely β POST /import parses places_map.kml or places_full.csv and returns a job immediately at step "done". Refactored index.html: CSS β web/static/app.css, JS β web/static/app.js. Template drops from 2553 β 465 lines; Jinja vars passed via body data-* attributes. FastAPI serves static/ via StaticFiles mount. All 24 e2e tests pass; deployment-mode and prefilter guardrails unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>74aafdd