mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(mobile): Today brief, time machine, Moment player, dossiers, watch and director
Tabs become Today, Live, Capture, Rooms and You. Today opens with the daily brief (since you last looked, Today's Moment, your sky now, overhead tonight, your watch) above the feed. The time ribbon becomes a time machine with recorded and forecast ranges, event pips, playback speeds and clipping. Moments play full-screen with captures, chat and record on one clock. Any entity opens a dossier with receipts and a link graph; search, watch places and alert rules, and a presenter director with deterministic demo beats round it out. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VVYRAqiQj9Y1V9ZfG1RcDH
This commit is contained in:
3 files changed
+2957
-5
No files matched your search
+14
-5
@@ -62,7 +62,13 @@ const ID_LABEL = {
|
||||
mmsi: 'MMSI',
|
||||
};
|
||||
|
||||
const cap = (x) => (x ? `${x[0].toUpperCase()}${x.slice(1)}` : x);
|
||||
const capFirst = (x) => (x ? `${x[0].toUpperCase()}${x.slice(1)}` : x);
|
||||
const cap = (x) => {
|
||||
const t = String(x || '')
|
||||
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
||||
.toLowerCase();
|
||||
return t ? `${t[0].toUpperCase()}${t.slice(1)}` : t;
|
||||
};
|
||||
|
||||
function liveRows(d) {
|
||||
const L = d.live;
|
||||
@@ -219,9 +225,12 @@ export function createDossier({
|
||||
function bodyHtml() {
|
||||
const rows = liveRows(d);
|
||||
const followed = store.isFollowed(followKey());
|
||||
const ident = Object.entries(d.identity || {}).filter(
|
||||
([, v]) => v != null && v !== '',
|
||||
);
|
||||
const ident = Object.entries(d.identity || {})
|
||||
.filter(
|
||||
([, v]) =>
|
||||
v != null && v !== '' && v !== false && typeof v !== 'object',
|
||||
)
|
||||
.map(([k, v]) => [k, v === true ? 'Yes' : v]);
|
||||
const L = d.live;
|
||||
const isMoment = d.kind === 'moment';
|
||||
return `
|
||||
@@ -258,7 +267,7 @@ export function createDossier({
|
||||
.slice(0, 12)
|
||||
.map(
|
||||
(l) =>
|
||||
`<button class="ds-link" type="button" data-link="${esc(l.id)}" data-band="${bandOfKind(l.kind)}"><span class="ds-link-ic">${icon(KIND_ICON[l.kind] || 'scope')}</span><span class="ds-link-main"><b>${esc(l.title)}</b><small>${esc(cap(l.relation || ''))}${Number.isFinite(l.distanceKm) ? ` · ${esc(l.distanceKm < 1 ? `${Math.round(l.distanceKm * 1000)} m` : `${fmtNum(l.distanceKm, l.distanceKm < 10 ? 1 : 0)} km`)}` : ''}</small></span>${icon('chevronRight', { cls: 'chev' })}</button>`,
|
||||
`<button class="ds-link" type="button" data-link="${esc(l.id)}" data-band="${bandOfKind(l.kind)}"><span class="ds-link-ic">${icon(KIND_ICON[l.kind] || 'scope')}</span><span class="ds-link-main"><b>${esc(l.title)}</b><small>${esc(capFirst(l.relation || ''))}${Number.isFinite(l.distanceKm) ? ` · ${esc(l.distanceKm < 1 ? `${Math.round(l.distanceKm * 1000)} m` : `${fmtNum(l.distanceKm, l.distanceKm < 10 ? 1 : 0)} km`)}` : ''}</small></span>${icon('chevronRight', { cls: 'chev' })}</button>`,
|
||||
)
|
||||
.join('')}</div></section>`
|
||||
: ''
|
||||
|
||||
Reference in new issue
Block a user