No description
Find a file
Your Name 06dd2b597c fix: half-open boundaries, per-mark lane interaction, unified :at addressing
Fixes the resize-drift and boundary bugs found while exercising the marks-first
flow, plus Chunk 7 (orphan polish). Frame model made consistent rather than
patched.

- Boundaries are half-open [start,end) everywhere; drop the merge-bars ≤1-frame
  fudge and the independent from-otio rounding that created the gaps it papered
  over. Clips stay EXACT (they tile at shared boundaries); frame-accuracy is
  applied at the mark the user creates (selection->marks rounds :at) and at
  display, never by rounding clips or bars.
- Unify the ref :at <-> source conversion: at->local / at->src / src->at, all via
  the target's full resolution, correct for scattered multi-clip (nested) proxy
  targets. Delete target-range (the lossy single-segment [xs xe] shortcut that
  made selection->marks / point-frame / at->frame / seg-point wrong when nested).
  This is what fixed the resize dragging one handle moving the other.
- Lane interaction is per-MARK, not per-visual-bar: one draggable unit + two
  end-handles at the mark's exact extent (scene/mark-extent), driven so the
  dragged endpoint rounds and the fixed one stays exact. Timeline drag-select;
  click = scrub. Visible edge grips.
- Share display-point between the editor rows and the jump popover (context-local
  whole frame). Drawing autocommits; toolbar moved off the video.
- Chunk 7: broken annotations greyed + sorted down + per-mark warnings.

Suite green except the pre-existing annotations-survive-json-roundtrip; app
compiles clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 12:22:17 -04:00
scenes fix: live-sync drawings/notes; cut per-frame sub cost; pen color+size 2026-07-01 19:29:32 -04:00
server feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00
tl fix: half-open boundaries, per-mark lane interaction, unified :at addressing 2026-07-05 12:22:17 -04:00
.dockerignore feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00
.gitignore feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00
DEPLOY.md feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00
Dockerfile feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00
fly.toml fix: thumbnail parser overflow, autostop-killed jobs, unified playhead 2026-06-30 09:48:08 -04:00
manage.py Add Django backend: users, admin, OTIO + scene persistence 2026-06-28 23:45:49 -04:00
README.md feat: timeline links, network error handling, Tailscale access, mobile fixes 2026-06-29 19:24:40 -04:00
requirements.txt feat: production deploy (Fly + R2) + frame controls and picker glow 2026-06-30 00:56:09 -04:00

scene_analysis

  • tl/ — the lumet frontend (ClojureScript / reagent / re-frame). See tl/.
  • Django backend (this folder) — users, admin, and persistence of OTIO + the timeline scene.

Backend

The backend stores one Project per editing session: the uploaded OTIO source file, the playback fps, and the live scene (the {:tracks :groups} mark-group map the frontend keeps in app-db) as a JSON dump.

Run

python -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py migrate
DJANGO_SUPERUSER_PASSWORD=admin .venv/bin/python manage.py createsuperuser --noinput --username admin --email admin@example.com
.venv/bin/python manage.py seed_demo          # demo project from tl/.../one_two_three.otio
.venv/bin/python manage.py runserver 0.0.0.0:9001   # 0.0.0.0 so it's reachable over Tailscale/LAN

Admin: http://127.0.0.1:9001/admin/ (admin / admin). Upload OTIO and inspect the scene JSON there.

API (session auth; 401 if not logged in)

Method Path Purpose
GET /api/projects/ the current user's projects
GET /api/projects/<id>/scene/ {fps, scene}
PUT /api/projects/<id>/scene/ replace scene and/or fps (JSON body)
GET /api/projects/<id>/otio/ serve the uploaded OTIO file
GET /api/projects/<id>/revisions/ save history (who / when / summary)

Attribution

Annotations are the authored unit, so that's what's attributed — and the server is the authority (client-sent stamps are ignored, so authorship can't be forged). On each scene PUT the server diffs incoming annotation groups against the stored ones and stamps createdBy/editedBy (+ timestamps) from request.user; it also writes a Revision (user, time, +N ~N −N summary, snapshot of the annotation layer). A project is editable by its owner and any collaborators (managed in the admin), so different users get distinct stamps.

The frontend currently loads /one_two_three.otio and persists annotations to localStorage; pointing it at /api/projects/<id>/otio/ and the scene endpoints is the next wiring step (CORS/credentials needed across the dev ports).