also looking at this
feat: native trail maps and complete native mobile screens
#1017
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.
| @@ -77,13 +77,25 @@ async function recover() { | ||
| 77 | 77 | if (!alive) return |
| 78 | 78 | owner=cached?.id ?? (Number(me?.body?.user?.id)||0) |
| 79 | 79 | const saved=await craft.storage.get<NativeRecording>(KEY) |
| 80 | const host=await craft.location?.getRecordingState() | |
| 81 | if (!alive) return | |
| 82 | 80 | if (saved && saved.userId !== owner) { |
| 83 | 81 | recording.set(null);running.set(false) |
| 84 | 82 | error.set('Log in as the account that started the saved recording before resuming or uploading it.') |
| 85 | 83 | return |
| 86 | 84 | } |
| 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 | |
| 87 | 99 | if (host?.active && (!saved || (saved.id && saved.id !== host.id))) { |
| 88 | 100 | error.set('A device recording is already active. Its account checkpoint could not be verified, so it has been retained without starting another recording.') |
| 89 | 101 | return |
| @@ -92,7 +104,7 @@ async function recover() { | ||
| 92 | 104 | running.set(Boolean(host?.active)) |
| 93 | 105 | paused.set(Boolean(host?.paused)) |
| 94 | 106 | if (saved && host?.active && !saved.pending) { |
| 95 | append(await craft.location!.readRecording()) | |
| 107 | append(await craft.location!.readRecording({expectedId:saved.id!})) | |
| 96 | 108 | await persist(recording()!) |
| 97 | 109 | attachWatch() |
| 98 | 110 | notice.set('Your recording has been recovered from this device.');updateLive(true) |
| @@ -7,8 +7,6 @@ async function recover(userId=7, keychain=new Map([['auth_token','record-token'] | ||
| 7 | 7 | const screen=await start('Record',{},['fetch','secureStorage','storage','geolocation','lifecycle','liveActivity'],keychain) |
| 8 | 8 | const stored=await waitForRequest(screen,0,r=>r.payload.module==='Storage' && r.payload.method==='get') |
| 9 | 9 | 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:[]}) | |
| 12 | 10 | return screen |
| 13 | 11 | } |
| 14 | 12 | describe('native Record checkpoint recovery',()=>{ |