ReviewOS

also looking at this

stacks/wildloop

feat: native trail maps and complete native mobile screens

#1017
Draft chris wants to merge codex/trail-experience into main
60 files +2505 -823

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

resources/native/Record.stxmodified+15-3
Changes to resources/native/Record.stx
@@ -77,13 +77,25 @@ async function recover() {
7777 if (!alive) return
7878 owner=cached?.id ?? (Number(me?.body?.user?.id)||0)
7979 const saved=await craft.storage.get<NativeRecording>(KEY)
80 const host=await craft.location?.getRecordingState()
81 if (!alive) return
8280 if (saved && saved.userId !== owner) {
8381 recording.set(null);running.set(false)
8482 error.set('Log in as the account that started the saved recording before resuming or uploading it.')
8583 return
8684 }
85 if (saved && !saved.id) {
86 recording.set(saved);running.set(false);paused.set(false)
87 error.set('This saved track has no verifiable native recording identity. Its checkpoint has been retained; it cannot be attached to another recording.')
88 return
89 }
90 // A finished checkpoint is sufficient for an offline retry. Do not read
91 // the shared GPS slot, which may now belong to another recording.
92 if (saved?.pending) {
93 recording.set(saved);running.set(false);paused.set(false)
94 notice.set('Your finished recording is saved on this device. Retry the upload when connected.')
95 return
96 }
97 const host=await craft.location?.getRecordingState(saved?.id ? {expectedId:saved.id} : undefined)
98 if (!alive) return
8799 if (host?.active && (!saved || (saved.id && saved.id !== host.id))) {
88100 error.set('A device recording is already active. Its account checkpoint could not be verified, so it has been retained without starting another recording.')
89101 return
@@ -92,7 +104,7 @@ async function recover() {
92104 running.set(Boolean(host?.active))
93105 paused.set(Boolean(host?.paused))
94106 if (saved && host?.active && !saved.pending) {
95 append(await craft.location!.readRecording())
107 append(await craft.location!.readRecording({expectedId:saved.id!}))
96108 await persist(recording()!)
97109 attachWatch()
98110 notice.set('Your recording has been recovered from this device.');updateLive(true)
tests/unit/native-record-screen.test.tsmodified+0-2
Changes to tests/unit/native-record-screen.test.ts
@@ -7,8 +7,6 @@ async function recover(userId=7, keychain=new Map([['auth_token','record-token']
77 const screen=await start('Record',{},['fetch','secureStorage','storage','geolocation','lifecycle','liveActivity'],keychain)
88 const stored=await waitForRequest(screen,0,r=>r.payload.module==='Storage' && r.payload.method==='get')
99 answer(screen,stored,checkpoint)
10 const host=await waitForRequest(screen,0,r=>r.payload.method==='getRecordingState')
11 answer(screen,host,{active:false,paused:false,locations:[]})
1210 return screen
1311}
1412describe('native Record checkpoint recovery',()=>{