timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#362 · A timeline's own image: settings, cards, previews and oEmbed (#339)

  • timeline-app
  • pull request
  • sharing

Closes #339 ## What changed - **Storage**: the image is one of the document's settings (`image: {url, alt, width?, height?}`, validated by `validateTimelineImage` in `src/timeline-image.ts`: HTTPS without credentials, alt text up to 1000 characters). Stored in `oc_timelines.image` and in the history settings JSON, so saved history, `.ochx` exports, forks (shared-index column list), duplicates, merges, pull requests and retention's saves keep it. Like every other image it is a **link**, never a copy on the server (docs/images.md); the editor's **Export** embeds a copy with the other images. - **API**: `PATCH /api/timelines/{id}/settings` takes `image` (object, or `null` to remove), owner only, saved as a revision of the settings alone (via `applyMerge`) in the same locked transaction; 409 for comparisons and copies still being prepared. Writers can also change it through the document (`PUT …/changes` settings or a whole-document save); editors' saves merge it like other settings. OpenAPI updated (`TimelineImage` schema, settings, metadata, documents). - **Web UI**: an **Image** section in Sharing & settings (preview cropped as on cards, link, alt text, Set/Replace/Remove; the preview's natural size is sent for oEmbed). - **Cards** (`platform/components/timeline-image.jsx`, one line in `timeline-list.jsx`): image at the top, 16:9 crop (capped at 220px tall), `loading="lazy"`, `referrerpolicy="no-referrer"`, placeholder when none or when the timeline is labelled. Search results come from `searchTimelines`, which now selects `t.image`. - **Editor / reader header**: the image above the title (cropped 16:9, up to 420px wide), from the embedded copy when offline, blurred on labelled timelines like their other images. - **Link previews**: the timeline page's `og:image` / `twitter:image` (with alt and size) is the image when the timeline is public and unlabelled; moment and duration pages keep the drawn preview. oEmbed's `thumbnail_url` is the image when its size is known (oEmbed requires width/height), otherwise the drawn preview. - **CSP**: unchanged. `img-src https:` already allows linked images. - Docs: images.md (new "A timeline's own image" section), sharing.md, collaboration.md, architecture.md. ## Tests - `test/timeline-image.test.mjs` (new): validation, documents, the editor's index and export, merges, retention and sparse-save settings. - `test/timeline-image-postgres.mjs` (new, added to CI): set/replace/remove through settings, validation 400s, owner-only, history versions, fork and duplicate, search cards, changes through `/changes` and whole-document saves, merge with an editor's base, comparison 409. - `test/sharing-postgres.mjs`: the settings UI in a browser (set, then remove), og/twitter meta, oEmbed thumbnail (with and without size), the card's lazy ` `, the editor heading, and the fallbacks for labelled timelines. - Passing locally: `npm run typecheck`, `npm test` (337 pass), prettier, the Postgres suites (timeline-image, image-links, history, shared-history, save-merge, merge, incremental, retention, openapi, labels, optional-history, fork-read-through, document-stream, pull-history, next-postgres), and in chromium `sharing-postgres`, `test:platform` and `test:browser`. ## Notes - "Uploaded image": the server does not store image files (docs/images.md, #109), so the image is set as a link. Exports carry an embedded copy. - Another PR for #337/#338 is reworking `timeline-list.jsx`. The card change here is one import plus one ` ` line, and `searchTimelines` gains `t.image`. Both should be easy to carry over.

Sources

Open #362 · A timeline's own image: settings, cards, previews and oEmbed (#339) in the timeline