wip(mobile): checkpoint experience round three in progress

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VVYRAqiQj9Y1V9ZfG1RcDH
This commit is contained in:
Claude committed 2026-10-23 07:52:23 +00:00
1 parent 5aba6bab58
commit e0fd7acead
4 files changed
+54 -7

No files matched your search

+28 -4
View File
@@ -678,12 +678,21 @@ globeReady
}
const subj = s.moment?.subject;
const c = subj
? { lon: subj.lon, lat: subj.lat - 0.004, height: 4200 }
? { lon: subj.lon, lat: subj.lat, height: 4200 }
: s.camera || {};
const height = Math.max(2500, Math.min(c.height || 3000, 6000));
// On a phone the room sheet covers the lower half: lift the place
// into the visible top of the map so the hearts rise in view.
let lat = c.lat ?? s.lat;
if (!isTwoPane()) {
const r = stage.getBoundingClientRect();
const mPerPx = (height * 0.364) / (Math.min(r.width, r.height) / 2);
lat -= (mPerPx * r.height * 0.27) / 111320;
}
g.flyTo({
lon: c.lon ?? s.lon,
lat: c.lat ?? s.lat,
height: Math.max(2500, Math.min(c.height || 3000, 6000)),
lat,
height,
pitch: -40,
duration: 1.8,
});
@@ -1003,7 +1012,22 @@ function buildDirector(g) {
run: async () => {
closeAll();
const m = await hero();
const ok = (await callSocial('openRoom', m, { lane: 'live' })).ok;
// Show the globe first, then the Live lane over it.
const sit =
(await getSituations()).find((x) => x.momentId === m.id) || m;
if (!isTwoPane()) selectTab('live');
await g.flyTo({
lon: m.lon,
lat: m.lat - 0.004,
height: 4200,
duration: 1.2,
});
const ok = (
await callSocial('openRoom', sit, {
lane: 'live',
detent: 'medium',
})
).ok;
if (!ok) await openRoom(m, { lane: 'live' });
for (let i = 0; i < 6; i += 1)
setTimeout(
+2 -2
View File
@@ -170,7 +170,7 @@
}
.mp-pops {
width: 230px;
width: min(230px, calc(46% - 14px));
}
.app.is-moment .gc-attr {
@@ -178,7 +178,7 @@
}
.mp-legend {
width: 250px;
width: min(250px, calc(50% - 14px));
}
.mp-title {
+23 -1
View File
@@ -85,6 +85,14 @@ export function normMoment(m) {
media: c.media || c.kind || 'photo',
live: c.live || c.kind === 'live',
distanceM: c.distanceM ?? c.rangeM ?? Math.round(dist(c)),
headingDeg: Number.isFinite(c.headingDeg)
? c.headingDeg
: (Math.atan2(
(subject.lon - c.lon) * Math.cos((c.lat * Math.PI) / 180),
subject.lat - c.lat,
) *
180) /
Math.PI,
})),
chat: (m.chat || []).map((c) => ({ ...c, handle: at(c.handle) })),
posts: (m.posts || []).map((p) => ({
@@ -556,7 +564,21 @@ export function createMomentPlayer({
if (!m) return;
cancelAnimationFrame(raf);
raf = 0;
globe.exitMoment();
// Stop the clock and let a frame render before the engine tears the
// Moment's primitives down (exiting mid-frame can stop Cesium's render).
globe.playback.stop();
const leaving = m;
requestAnimationFrame(() =>
requestAnimationFrame(() => {
if (m === null || m === leaving) globe.exitMoment();
}),
);
try {
ext?.destroy?.();
} catch {
/* ignore */
}
ext = null;
offOwn?.();
offOwn = null;
const was = m;
+1
View File
@@ -552,6 +552,7 @@ export function createTimeRibbon(
function goLive() {
haptic('tick');
stopPlay();
if (clipMode) setClipMode(false);
if (custom) {
animateTo(custom.start, () => emit(true));
return;