feat: wire lobby task and VIP prefab flows and sync UI assets

This commit is contained in:
2026-09-06 18:46:37 +08:00
parent 842c68ef55
commit 9c4510697c
184 changed files with 8348 additions and 19133 deletions
@@ -0,0 +1,40 @@
/** Execute in an isolated Creator browser preview, never a live player session. */
export async function verifyTaskListPreview() {
const e=await System.import('cc');
const service=e.director.getScene().getChildByName('PlatformServices');
const owner=service?.getComponent('PlatformStartup');
if(owner){owner.unsubscribe?.();owner.runtime?.stop();owner.panel?.dispose();owner.panel=null;}
await new Promise((resolve,reject)=>e.director.loadScene('PlatformLobby',err=>err?reject(err):resolve()));
const prefab=await new Promise((resolve,reject)=>e.assetManager.loadAny('4b529d70-7a96-479e-b8bc-0a92a5dc33c2',(err,a)=>err?reject(err):resolve(a)));
const root=e.instantiate(prefab);root.parent=e.director.getScene().getChildByName('Canvas');
const list=root.getComponent('TaskListView'),checks=[];
const assert=(condition,message)=>{if(!condition)throw Error(message);checks.push(message);};
const data=Array.from({length:6},(_,i)=>({taskid:i+1,title:'完成今日首次对局任务',award:i+2,finish:1,total:4,state:i===1?1:i===2?2:0}));
list.render(data,'房卡');
const content=list.scrollView.content,items=content.children.map(n=>n.getComponent('TaskItemView'));
assert(items.length===6,'six prefab instances');
assert(content.getComponent(e.UITransform).width===1776,'content measures all six items');
assert(list.scrollView.getMaxScrollOffset().x===592,'two additional items scroll horizontally');
assert(list.scrollView.horizontal&&!list.scrollView.vertical,'horizontal only');
assert(content.parent.getComponent(e.Mask)?.enabled,'viewport mask enabled');
assert(root.getChildByPath('group-10/Spirit176').position.x===0,'viewport centered');
assert(items[0].progressBar.progress===0.25,'progress uses finish divided by total');
assert(items[0].progressBar.barSprite.node.getComponent(e.UITransform).width===50.5,'progress scales bar from left');
assert(items[0].doButton.node.active&&!items[3].doButton.node.active,'only first unfinished entry shows do button');
assert(items[1].claimButton.node.active&&!items[1].progressBar.node.active,'claimable entry replaces progress');
assert(items[2].claimedMark.active&&!items[2].claimButton.node.active,'claimed entry replaces claim button');
const events=[];root.on('task-claim',id=>events.push(['claim',id]));root.on('task-do',id=>events.push(['do',id]));
items[0].doButton.node.emit(e.Button.EventType.CLICK);items[1].claimButton.node.emit(e.Button.EventType.CLICK);
items[2].claimButton.node.emit(e.Button.EventType.CLICK);items[3].doButton.node.emit(e.Button.EventType.CLICK);
assert(JSON.stringify(events)===JSON.stringify([['do',1],['claim',2]]),'only visible actions emit correct task ids');
const old=content.children[0];list.render(data.slice(0,1),'房卡');
assert(content.children.length===1&&old.parent===null,'refresh replaces previous entries');
list.render([],'房卡');assert(content.children.length===0&&content.getComponent(e.UITransform).width===0,'empty list clears extent');
list.render(data,'房卡');
// Destruction is deferred until the end of the frame; include that boundary.
await new Promise(resolve=>e.director.once(e.Director.EVENT_AFTER_DRAW,resolve));
await new Promise(resolve=>e.director.once(e.Director.EVENT_AFTER_DRAW,resolve));
assert(!document.body.innerText.includes('TypeError:'),'refresh finishes without deferred destruction errors');
globalThis.__taskQA={e,root,list,data,events,checks};
return {checks};
}