@rr0/ufoathome 0.37.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -79,6 +79,18 @@ The lightweight component (~9KB): a canvas plus Play/Pause/Loop/seek controls. U
79
79
  | `loadFromSrc(url)` | method (async) | What the `src` attribute triggers internally; can be called directly too |
80
80
  | `enableClickToPlay` | property (get/set, default `true`) | Whether clicking the canvas toggles Play/Pause (see below). Composing elements that need the canvas's own click for something else set this to `false` — see `<rr0-ufo-recorder>`. |
81
81
  | `fullscreenTarget` | property (get/set, default: the component's own stage) | The element the fullscreen button requests fullscreen on. Composing elements that need a *different* element fullscreened set this — see `<rr0-scene>`. |
82
+ | `play()` / `pause()` | method | Start or stop playback. Alongside `togglePlayPause()` because a caller sequencing several recordings needs to say which state it wants, not flip whatever the current one happens to be |
83
+ | `autoReplayEnabled` | property (get/set, default `true`) | Looping. A page playing recordings in turn has to turn it **off**, or the first one never ends |
84
+ | `playbackState` | property (readonly) | `"stopped"`, `"playing"` or `"paused"` |
85
+ | `currentTime` / `seekableDuration` | property | The playhead and its range, in the timeline's own units (see `positionLabel` for why those are not real milliseconds) |
86
+
87
+ Three events. `ended` fires once, when playback runs off the end of a recording **without** looping — not on a
88
+ pause, and not on a scrub to the end (`Player.onEnded` is the hook, precisely so that neither of those can be
89
+ mistaken for one: a single tick can carry the playhead from well inside the recording to past its end, so there is
90
+ no "last playing frame" to compare against). It is `bubbles`/`composed`, unlike `timeupdate`, so a page can listen
91
+ for it on the outermost element — that is how ufoathome.org's front page plays one reconstruction after another.
92
+ `timeupdate` fires on every playback tick and every seek, with `detail.time`, and is meant for the composing
93
+ elements. `timedisplaychange` fires when the counters switch between clock time and elapsed time.
82
94
 
83
95
  Playback matches the observation's *real reported duration* when it's known: set `time`/`endTime`, or `time`/
84
96
  `durationSeconds`, in the [data format](#data-format) (`durationSeconds` takes precedence over `endTime` if both are
@@ -94,9 +106,13 @@ While playing, the toolbar and the fullscreen button (top-right, semi-transparen
94
106
  only reappear on hover — always shown while paused/stopped. The fullscreen button uses the standard Fullscreen API
95
107
  (`requestFullscreen`/`exitFullscreen`); exiting with Escape is native browser behavior, nothing custom.
96
108
 
97
- Labels (Play/Pause, Auto-replay, Current position, Duration, Fullscreen) are translated (English/French) based on
98
- the visitor's `navigator.languages`, falling back to English — there's no language-picker UI, this is the only
99
- mechanism.
109
+ Labels (Play/Pause, Auto-replay, Current position, Duration, Fullscreen) are translated (English/French) by
110
+ detection, falling back to English — there's no language-picker UI, and there deliberately isn't one. What is
111
+ detected is the **host page's own declared language first** (the nearest `lang` attribute, so `<html lang="fr">`
112
+ gets French labels), then `navigator.languages` — see `HostLocale.preferencesFor`. A page states what language its
113
+ reader is reading it in, and a bilingual site that serves the same article at two URLs states it per URL, which
114
+ `navigator.languages` cannot know. A page that declares nothing falls through to the browser's list exactly as
115
+ before.
100
116
 
101
117
  ## `<rr0-ufo-recorder>` — full editor
102
118
 
@@ -136,7 +152,7 @@ fires a native "click" on the canvas, which would otherwise spuriously toggle pl
136
152
 
137
153
  All of the toolbar's own labels (shape presets, Color/Transparency/Halo, Add shape, Record/Stop, Export JSON,
138
154
  Duration) are translated (English/French) the same way `<rr0-ufo>`'s own labels are — based on
139
- `navigator.languages`, no picker UI.
155
+ the host page's own `lang` then `navigator.languages`, no picker UI.
140
156
 
141
157
  | Member | Kind | Description |
142
158
  |---|---|---|
@@ -335,6 +351,8 @@ cross-check). Each file now carries its own witness's account.
335
351
  |---|---|---|
336
352
  | `src` | attribute | URL of a single `sighting.json` or a witness manifest (above), fetched automatically on connect and whenever the attribute changes |
337
353
  | `witnessUrls` | property (get/set) | The manifest as a plain array of URLs, for programmatic use instead of `src` |
354
+ | `sightingData` | property (get/set) | One witness's recording, set directly instead of fetched — for a page holding one in memory (text pasted into a form, a file the reader picked). Its entry carries no URL, so the info panel's editor link and embed lines fall back to the bare application, which is the honest answer for something published nowhere |
355
+ | `scene` | property (readonly) | The `<rr0-scene>` this composes — and through `scene.ufoElement`, the playback members above |
338
356
  | `loadFromSrc(url)` | method (async) | What the `src` attribute triggers internally; can be called directly too |
339
357
 
340
358
  A toolbar row sits above the scene: a "Testimony by &lt;witness&gt;" sentence on the left, and a round "?" info
@@ -804,10 +822,29 @@ npm run build:embed-ufo # build dist-embed-ufo/rr0-ufo.mjs
804
822
  npm run build:embed-scene # build dist-embed-scene/rr0-scene.mjs
805
823
  npm run build:embed-eyewitness # build dist-embed-eyewitness/rr0-eyewitness.mjs
806
824
  npm run build:all # all four
825
+ npm run build:site # ufoathome.org, into dist-site/
807
826
  npm run build:comets # regenerate the comet catalog from JPL Horizons
808
827
  npm run build:satellites # regenerate the satellite catalog from CelesTrak's SATCAT
809
828
  ```
810
829
 
830
+ ## The site
831
+
832
+ [`ufoathome.org`](https://ufoathome.org) is built from `site/` in this repository, so the tool's documentation, its
833
+ demo catalogue and its roadmap stay in step with the version they describe. `npm run build:site` builds the four
834
+ embed bundles, then generates the pages into `dist-site/`, which is what Netlify deploys.
835
+
836
+ It is **not** a Vite build. Its pages import the bundles `build:embed*` already produces and have nothing else to
837
+ bundle; running them through Vite would re-emit those bundles under hashed names, which is the opposite of what a
838
+ page handing out a copy-pasteable `<script src>` needs. So `site/build.ts` generates the HTML, copies the bundles
839
+ as they are, and copies `public/demo-data/` alongside them. The one exception is `site/scripts/jsonEditor.ts` (the
840
+ Player page's paste panel, which pulls in CodeMirror): it gets its own Vite config, and the page loads it lazily.
841
+
842
+ Each page is one module under `site/content/` holding **both** languages, because they are translations of each
843
+ other and keeping a sentence next to its counterpart is what stops the two from drifting. English is at the root
844
+ and is the fallback; French lives under `/fr/` with its own slugs. Like the components, the site detects and never
845
+ offers a picker — Netlify's own `Language=` rules do the detection, and `hreflang` declares the pairing to search
846
+ engines.
847
+
811
848
  ## License
812
849
 
813
850
  MIT