fix: reduce transparent stream live row churn
This commit is contained in:
parent
312d3faba4
commit
badb93d472
2 changed files with 94 additions and 3 deletions
34
static/ui.js
34
static/ui.js
|
|
@ -10945,6 +10945,7 @@ function _renderLiveAnchorActivitySceneTransparent(streamId, scene, opts){
|
|||
});
|
||||
const liveFooter=blocks.querySelector('#liveRunStatus');
|
||||
let wrote=false;
|
||||
const targetRenderedRows=[];
|
||||
for(const row of rows){
|
||||
const node=_anchorSceneTransparentNodeForRow(row,{
|
||||
live:true,
|
||||
|
|
@ -10960,10 +10961,35 @@ function _renderLiveAnchorActivitySceneTransparent(streamId, scene, opts){
|
|||
: node;
|
||||
if(existing) preserveByKey.delete(key);
|
||||
if(!renderedNode) continue;
|
||||
if(liveFooter&&liveFooter.parentElement===blocks) blocks.insertBefore(renderedNode,liveFooter);
|
||||
else blocks.appendChild(renderedNode);
|
||||
targetRenderedRows.push(renderedNode);
|
||||
wrote=true;
|
||||
}
|
||||
const transparentLiveRowNextSibling=(node)=>{
|
||||
if(!node) return null;
|
||||
if(typeof node.nextSibling!=='undefined') return node.nextSibling;
|
||||
const parent=node.parentElement||node.parentNode;
|
||||
if(parent&&parent.children&&typeof parent.children.length==='number'){
|
||||
const index=Array.prototype.indexOf.call(parent.children,node);
|
||||
return index>=0 ? (parent.children[index+1]||null) : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const transparentLiveRowAlreadyPositioned=(node, expectedNextSibling)=>!!(
|
||||
node &&
|
||||
node.parentElement===blocks &&
|
||||
transparentLiveRowNextSibling(node)===expectedNextSibling
|
||||
);
|
||||
let expectedNextSibling=(liveFooter&&liveFooter.parentElement===blocks) ? liveFooter : null;
|
||||
for(let i=targetRenderedRows.length-1;i>=0;i--){
|
||||
const renderedNode=targetRenderedRows[i];
|
||||
if(transparentLiveRowAlreadyPositioned(renderedNode,expectedNextSibling)){
|
||||
expectedNextSibling=renderedNode;
|
||||
continue;
|
||||
}
|
||||
if(expectedNextSibling&&expectedNextSibling.parentElement===blocks) blocks.insertBefore(renderedNode,expectedNextSibling);
|
||||
else blocks.appendChild(renderedNode);
|
||||
expectedNextSibling=renderedNode;
|
||||
}
|
||||
preserveByKey.forEach(stale=>stale.remove());
|
||||
if(wrote) _syncTransparentEventControls(turn);
|
||||
if(typeof _moveLiveRunStatusToTurnEnd==='function') _moveLiveRunStatusToTurnEnd();
|
||||
|
|
@ -11067,7 +11093,9 @@ function _refreshTransparentLiveRow(existing, node){
|
|||
existing.setAttribute(name, value);
|
||||
}
|
||||
existing.className = node.className || '';
|
||||
existing.innerHTML = node.innerHTML || '';
|
||||
const newHtml = node.innerHTML || '';
|
||||
const htmlChanged = existing.innerHTML !== newHtml;
|
||||
if(htmlChanged) existing.innerHTML = newHtml;
|
||||
_rehydrateTransparentLiveRow(existing, node, preservedState);
|
||||
return existing;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ class FakeElement {{
|
|||
}}
|
||||
get parentElement(){{ return this.parentNode; }}
|
||||
get firstChild(){{ return this.children[0]||null; }}
|
||||
get nextSibling(){{
|
||||
if(!this.parentNode) return null;
|
||||
const siblings = this.parentNode.children;
|
||||
const idx = siblings.indexOf(this);
|
||||
return idx >= 0 ? (siblings[idx + 1] || null) : null;
|
||||
}}
|
||||
get className(){{
|
||||
return Array.from(this._classes).join(' ');
|
||||
}}
|
||||
|
|
@ -123,6 +129,7 @@ class FakeElement {{
|
|||
}}
|
||||
}}
|
||||
appendChild(child){{
|
||||
this.appendChildCount = (this.appendChildCount || 0) + 1;
|
||||
if(child && child.parentNode) child.remove();
|
||||
if(!child) return null;
|
||||
child.parentNode = this;
|
||||
|
|
@ -130,6 +137,7 @@ class FakeElement {{
|
|||
return child;
|
||||
}}
|
||||
insertBefore(child, refNode){{
|
||||
this.insertBeforeCount = (this.insertBeforeCount || 0) + 1;
|
||||
if(child && child.parentNode) child.remove();
|
||||
if(!child) return null;
|
||||
const idx = this.children.indexOf(refNode);
|
||||
|
|
@ -299,7 +307,11 @@ const keptAfterFirst = turn.querySelector('.transparent-event-row[data-anchor-ro
|
|||
const staleAfterFirst = turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-stale\"]');
|
||||
const firstFooter = turn.querySelector('#liveRunStatus');
|
||||
|
||||
turn.insertBeforeCount = 0;
|
||||
turn.appendChildCount = 0;
|
||||
const secondRender = _renderLiveAnchorActivitySceneTransparent('stream-1', secondScene, {{ sessionId:'session-1' }});
|
||||
const secondInsertBeforeCount = turn.insertBeforeCount || 0;
|
||||
const secondAppendChildCount = turn.appendChildCount || 0;
|
||||
const keptAfterSecond = turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-kept\"]');
|
||||
const staleAfterSecond = turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-stale\"]');
|
||||
const newAfterSecond = turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-new\"]');
|
||||
|
|
@ -314,6 +326,39 @@ const idxs = {{
|
|||
stale: rows.findIndex((child) => child.getAttribute('data-anchor-row-id') === 'row-stale'),
|
||||
}};
|
||||
|
||||
turn.insertBeforeCount = 0;
|
||||
turn.appendChildCount = 0;
|
||||
_renderLiveAnchorActivitySceneTransparent('stream-1', secondScene, {{ sessionId:'session-1' }});
|
||||
const stableInsertBeforeCount = turn.insertBeforeCount || 0;
|
||||
const stableAppendChildCount = turn.appendChildCount || 0;
|
||||
|
||||
const reorderedScene = {{
|
||||
version:'activity_scene_v1',
|
||||
activity_rows:[
|
||||
{{ row_id:'row-new', role:'prose', source_event_type:'process_prose', text:'new row appears' }},
|
||||
{{ row_id:'row-kept', role:'prose', source_event_type:'process_prose', text:'updated progress line' }},
|
||||
],
|
||||
}};
|
||||
turn.insertBeforeCount = 0;
|
||||
turn.appendChildCount = 0;
|
||||
_renderLiveAnchorActivitySceneTransparent('stream-1', reorderedScene, {{ sessionId:'session-1' }});
|
||||
const reorderInsertBeforeCount = turn.insertBeforeCount || 0;
|
||||
const reorderedIds = turn.children
|
||||
.filter((child) => child.classList.contains('transparent-event-row'))
|
||||
.map((child) => child.getAttribute('data-anchor-row-id'));
|
||||
|
||||
firstFooter.remove();
|
||||
turn.insertBefore(firstFooter, turn.children[0] || null);
|
||||
turn.insertBeforeCount = 0;
|
||||
turn.appendChildCount = 0;
|
||||
_renderLiveAnchorActivitySceneTransparent('stream-1', reorderedScene, {{ sessionId:'session-1' }});
|
||||
const footerRepairInsertBeforeCount = turn.insertBeforeCount || 0;
|
||||
const footerRepairIdxs = {{
|
||||
newRow: turn.children.indexOf(turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-new\"]')),
|
||||
keptRow: turn.children.indexOf(turn.querySelector('.transparent-event-row[data-anchor-row-id=\"row-kept\"]')),
|
||||
footer: turn.children.indexOf(firstFooter),
|
||||
}};
|
||||
|
||||
_renderLiveAnchorActivitySceneTransparent('stream-1', thirdScene, {{ sessionId:'session-1' }});
|
||||
const keylessRowsAfterThird = turn.querySelectorAll('.transparent-event-row[data-anchor-row-id=\"\"]');
|
||||
_renderLiveAnchorActivitySceneTransparent('stream-1', fourthScene, {{ sessionId:'session-1' }});
|
||||
|
|
@ -329,6 +374,14 @@ process.stdout.write(JSON.stringify({{
|
|||
staleGone: staleAfterSecond === null,
|
||||
staleAfterFirst: staleAfterFirst !== null,
|
||||
idxs,
|
||||
secondInsertBeforeCount,
|
||||
secondAppendChildCount,
|
||||
stableInsertBeforeCount,
|
||||
stableAppendChildCount,
|
||||
reorderInsertBeforeCount,
|
||||
reorderedIds,
|
||||
footerRepairInsertBeforeCount,
|
||||
footerRepairIdxs,
|
||||
hasNewRow: !!newAfterSecond,
|
||||
newRowSession: newAfterSecond && newAfterSecond.getAttribute('data-session-id'),
|
||||
keylessAfterThird: keylessRowsAfterThird.length,
|
||||
|
|
@ -355,6 +408,16 @@ process.stdout.write(JSON.stringify({{
|
|||
assert data["idxs"]["rowNew"] == 1
|
||||
assert data["idxs"]["stale"] == -1
|
||||
assert data["idxs"]["staleInVisibleRows"] == -1
|
||||
assert data["secondInsertBeforeCount"] >= 1
|
||||
assert data["secondAppendChildCount"] == 0
|
||||
assert data["stableInsertBeforeCount"] == 0
|
||||
assert data["stableAppendChildCount"] == 0
|
||||
assert data["reorderInsertBeforeCount"] >= 1
|
||||
assert data["reorderedIds"] == ["row-new", "row-kept"]
|
||||
assert data["footerRepairInsertBeforeCount"] >= 1
|
||||
assert data["footerRepairIdxs"]["newRow"] == 0
|
||||
assert data["footerRepairIdxs"]["keptRow"] == 1
|
||||
assert data["footerRepairIdxs"]["footer"] > data["footerRepairIdxs"]["keptRow"]
|
||||
assert data["hasNewRow"] is True
|
||||
assert data["newRowSession"] == "session-1"
|
||||
assert data["keylessAfterThird"] == 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue