diff --git a/docs/images/release-1.0.0/firmware-tracker-card-native.png b/docs/images/release-1.0.0/firmware-tracker-card-native.png index 883ced64..20e9b348 100644 Binary files a/docs/images/release-1.0.0/firmware-tracker-card-native.png and b/docs/images/release-1.0.0/firmware-tracker-card-native.png differ diff --git a/docs/uiux/pages/tracker_item_cards.md b/docs/uiux/pages/tracker_item_cards.md index 43a5949b..21c66696 100644 --- a/docs/uiux/pages/tracker_item_cards.md +++ b/docs/uiux/pages/tracker_item_cards.md @@ -21,6 +21,12 @@ Clicking the card also opens its existing action menu. Touch gestures and keyboard selection remain available. The title has at most two lines; the region can scroll within its row. +![Wio L2 Tracker route card](../../images/release-1.0.0/firmware-tracker-card-native.png) + +This full-page native LVGL capture uses the CI-built Wio L2 preview, sample KML +and simulated GPS. No administrative map dataset is installed in the preview, +so it shows an unknown region. It is not a physical-device screenshot. + Title extraction shares the current selected-file read (at most 64 KiB) with first-position extraction. Its bounded XML workspace is transient PSRAM and is freed after the read. No per-route metadata cache or geometry collection is @@ -31,3 +37,7 @@ against LVGL at 320×240, 480×222 and 240×320, checks control bounds and Actio and exercises title decoding, UTF-8 truncation, hash fallback and combined title/coordinate reads. The surrounding native page is a test scaffold, not a physical device capture. Physical acceptance of this revision is pending. + +The full-page native tests also exercise recording, KML document titles, Actions, +previous/next selection and widget reuse on Pager, T-Deck and Wio L2. The shorter +Pager recording card hides the format row to keep location and controls visible. diff --git a/tests/site/tracker-page.test.mjs b/tests/site/tracker-page.test.mjs index 2c3793f2..482fe769 100644 --- a/tests/site/tracker-page.test.mjs +++ b/tests/site/tracker-page.test.mjs @@ -21,7 +21,9 @@ for(const device of ['pager','tdeck','wio-tracker-l2']) { const stop=snapshot().find(item=>item.button&&item.text==='Stop recording'); assert.equal(stop.w,action.w,'Start and stop share a stable button width'); assert.equal(stop.x,action.x,'Start and stop share a stable right-aligned position'); - assert.ok(snapshot().some(item=>item.text==='GPX | Recording'),'New recording appears with readable file type/status'); + assert.ok(snapshot().some(item=>!item.button&&/^track-\d+$/.test(item.text)),`${device}: new recording has a readable title without the file extension`); + if(device!=='pager')assert.ok(snapshot().some(item=>item.text==='GPX | Recording'),`${device}: recording card shows file type/status`); + else assert.ok(!snapshot().some(item=>item.text==='GPX | Recording'),'Short Pager recording card preserves room for location and actions by hiding the format row'); click('Routes'); assert.ok(!snapshot().some(item=>['Recording','Stop recording'].includes(item.text)),'Route mode has its own status and actions'); click('Tracks'); diff --git a/tests/site/two-pane-layout.test.mjs b/tests/site/two-pane-layout.test.mjs index 1ad85cb2..5a8ee971 100644 --- a/tests/site/two-pane-layout.test.mjs +++ b/tests/site/two-pane-layout.test.mjs @@ -12,7 +12,7 @@ for(const [device,width,height] of [['pager',480,222],['tdeck',320,240],['wio-tr onFrame(pointer){framePointer=pointer;},print(){},printErr(){}, }); runtime._native_init(device==='pager'?0:1); - for(const [page,filterText,contentText,maxTextGap] of [[5,'Direct','Alex',16],[12,'Contacts','No contacts yet',6],[14,'Tracks','Not recording',5]]) { + for(const [page,filterText,contentText,maxTextGap] of [[5,'Direct','Alex',16],[12,'Contacts','No nodes',14],[14,'Tracks','Not recording',5]]) { runtime._native_open_page(page); for(let i=0;i<5;i++)runtime._native_tick(50); const snapshot=JSON.parse(runtime.UTF8ToString(runtime._native_snapshot())); @@ -23,14 +23,16 @@ for(const [device,width,height] of [['pager',480,222],['tdeck',320,240],['wio-tr // Message text includes the card's own inset; compare actual rendered geometry. const limit=device==='tdeck'&&page===5?24:maxTextGap; assert.ok(gap>=0&&gap<=limit,`${device}:${page}: content lost width to a ${gap}px gap`); + // Contacts deliberately places its heading eight pixels inside the card. + const verticalInset=page===12?8:0; // T-Deck's message name is vertically inset inside its richer info card. - if(device!=='tdeck'||page!==5)assert.ok(Math.abs(content.y-filter.y)<=3,`${device}:${page}: first rows align`); + if(device!=='tdeck'||page!==5)assert.ok(Math.abs(content.y-filter.y-verticalInset)<=3,`${device}:${page}: first rows align with their intended inset`); const pixels=new Uint16Array(runtime.HEAPU8.buffer,framePointer,width*height); const y=height-50; const background=pixels[y*width+10]; - // Tracker now deliberately uses colored item cards. Its seam must remain + // Contacts and Tracker deliberately use colored item cards. Their seam must remain // continuous, while the content card may contrast with the pane background. - const seamEnd=page===14?content.x:width-10; + const seamEnd=page===12?content.x-11:page===14?content.x:width-10; for(let x=10;x