feat: 百人赛和小程序福利图标移动到首页右侧
This commit is contained in:
parent
b183bf7e08
commit
3d8a7bbdc4
|
|
@ -26,6 +26,8 @@ export default class CloudRiseView extends cc.Component {
|
|||
private queuedElimination = "";
|
||||
private eliminationDone: () => void = null;
|
||||
private expiryPending = false;
|
||||
private dailyReminderQueued = false;
|
||||
private nextDailyReminderAt = 0;
|
||||
|
||||
/** All win continuations present pending results; only the activity overview starts another stage. */
|
||||
static async continueFromNextLevel(host: cc.Node): Promise<boolean> {
|
||||
|
|
@ -165,6 +167,35 @@ export default class CloudRiseView extends cc.Component {
|
|||
void this.open("result").then(() => { if (!this.overlay) this.finishPopup(); }, () => this.finishPopup());
|
||||
});
|
||||
}
|
||||
this.queueDailyReminder();
|
||||
}
|
||||
|
||||
private queueDailyReminder(): void {
|
||||
if (this.map || !this.entry.active || this.busy || this.overlay || this.dailyReminderQueued
|
||||
|| Date.now() < this.nextDailyReminderAt || CloudRiseService.elimination()
|
||||
|| CloudRiseService.hasPendingLoss() || CloudRiseService.unseenResult()) return;
|
||||
const reminder = ActivityScheduleService.cloudRiseReminder();
|
||||
if (!reminder) return;
|
||||
this.dailyReminderQueued = true;
|
||||
HomePopupQueue.get(this.host).enqueue("cloudRiseDailyReminder", 10, done => {
|
||||
void (async () => {
|
||||
try {
|
||||
const current = ActivityScheduleService.cloudRiseReminder();
|
||||
if (!cc.isValid(this.node, true) || !this.entry.active || !current
|
||||
|| current.key !== reminder.key || current.day !== reminder.day
|
||||
|| CloudRiseService.elimination() || CloudRiseService.hasPendingLoss() || CloudRiseService.unseenResult()) return;
|
||||
await this.open("overview");
|
||||
if (this.overlay && cc.isValid(this.node, true)) {
|
||||
ActivityScheduleService.markCloudRiseReminderShown(reminder);
|
||||
this.popupDone = done;
|
||||
}
|
||||
} finally {
|
||||
this.dailyReminderQueued = false;
|
||||
this.nextDailyReminderAt = Date.now() + 30000;
|
||||
if (this.popupDone !== done) done();
|
||||
}
|
||||
})().catch(error => cc.warn(error));
|
||||
});
|
||||
}
|
||||
|
||||
private async showElimination(reuseCurrent = false): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/** One owner for home activity positions; visibility is still decided by each activity. */
|
||||
export default class HomeActivityEntryLayout {
|
||||
private static signatures = new WeakMap<cc.Node, string>();
|
||||
private static leftNames = ["shop", "yicon", "redeemBtn", "passBtn", "jungle", "xinshou", "chengxu", "cloudRise"];
|
||||
private static leftNames = ["shop", "yicon", "redeemBtn", "passBtn", "jungle", "xinshou"];
|
||||
private static rightNames = ["rank", "gacha", "day", "hammer"];
|
||||
|
||||
static refresh(top: cc.Node): void {
|
||||
|
|
@ -10,26 +10,44 @@ export default class HomeActivityEntryLayout {
|
|||
const footer = top.parent.getChildByName("shezhiBtn");
|
||||
if (!first || !right || !footer) return;
|
||||
const left = this.leftNames.map(name => top.getChildByName(name)).filter(node => !!node);
|
||||
const rightActivities = ["cloudRise", "chengxu"].map(name => top.getChildByName(name)).filter(node => !!node);
|
||||
const fixedRight = this.rightNames.map(name => top.getChildByName(name)).filter(node => !!node);
|
||||
// Adaptation sets the same steady scale on Load and the side buttons. Ignore temporary button press zoom.
|
||||
const scale = Math.abs(top.parent.scaleY) || 1;
|
||||
const signature = JSON.stringify([first.x, first.y, right.x, top.y, scale, footer.y, footer.height,
|
||||
...left.map(n => [n.name, n.active, n.width, n.height]),
|
||||
...rightActivities.map(n => [n.name, n.active, n.width, n.height]),
|
||||
...fixedRight.map(n => [n.name, n.active, n.x, n.y, n.width, n.height])]);
|
||||
if (this.signatures.get(top) === signature) return;
|
||||
this.signatures.set(top, signature);
|
||||
|
||||
const footerTop = footer.y + footer.height * (1 - footer.anchorY) * scale - top.y + 16;
|
||||
let leftY = first.y + 220, leftBottom = Infinity;
|
||||
const visibleLeft = left.filter(n => n.active);
|
||||
const leftBounds = visibleLeft.map(n => this.extent(n));
|
||||
const minimumSteps = leftBounds.slice(1).map((bounds, i) =>
|
||||
(bounds.top - leftBounds[i].bottom) * scale + 16);
|
||||
const minimumSpan = minimumSteps.reduce((sum, step) => sum + step, 0);
|
||||
const extraSpan = minimumSteps.reduce((sum, step) => sum + Math.max(0, 220 - step), 0);
|
||||
const availableSpan = leftBounds.length ? first.y + leftBounds[leftBounds.length - 1].bottom * scale - footerTop : 0;
|
||||
// Tighten only the spare gaps when all left entries are visible, keeping the bottom controls clear.
|
||||
const gapRatio = extraSpan ? Math.max(0, Math.min(1, (availableSpan - minimumSpan) / extraSpan)) : 1;
|
||||
let leftY = first.y;
|
||||
const occupiedRight = fixedRight.filter(n => n.active);
|
||||
let rightY = occupiedRight.length ? Math.min(...occupiedRight.map(n => n.y)) : first.y + 220;
|
||||
let rightBottom = occupiedRight.length
|
||||
? Math.min(...occupiedRight.map(n => n.y + this.extent(n).bottom * scale)) : Infinity;
|
||||
for (const node of left.filter(n => n.active)) {
|
||||
const extent = this.extent(node), above = extent.top * scale, below = extent.bottom * scale;
|
||||
const y = Math.min(leftY - 220, leftBottom - 16 - above);
|
||||
for (const node of rightActivities.filter(n => n.active)) {
|
||||
const bounds = this.extent(node);
|
||||
rightY = Math.min(rightY - 220, rightBottom - 16 - bounds.top * scale);
|
||||
node.setPosition(right.x, rightY);
|
||||
rightBottom = rightY + bounds.bottom * scale;
|
||||
}
|
||||
for (let i = 0; i < visibleLeft.length; i++) {
|
||||
const node = visibleLeft[i], extent = leftBounds[i], above = extent.top * scale, below = extent.bottom * scale;
|
||||
const step = i ? minimumSteps[i - 1] : 0;
|
||||
const y = i ? leftY - step - Math.max(0, 220 - step) * gapRatio : first.y;
|
||||
if (y + below >= footerTop) {
|
||||
node.setPosition(first.x, y); leftY = y; leftBottom = y + below;
|
||||
node.setPosition(first.x, y); leftY = y;
|
||||
} else {
|
||||
// Use the free lower right slots instead of covering the bottom-left Settings button.
|
||||
const nextY = Math.min(rightY - 220, rightBottom - 16 - above);
|
||||
|
|
|
|||
|
|
@ -1389,14 +1389,14 @@ export default class JiaZai extends cc.Component {
|
|||
"rank",
|
||||
"day",
|
||||
"hammer",
|
||||
"cloudRise",
|
||||
"chengxu",
|
||||
"Coin"
|
||||
];
|
||||
const rightElements2 = [
|
||||
"shop",
|
||||
"yicon",
|
||||
"passBtn",
|
||||
"chengxu",
|
||||
"cloudRise",
|
||||
"redeemBtn",
|
||||
"xinshou",
|
||||
"jungle",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,20 @@ export default class ActivityScheduleService {
|
|||
private static cacheKey(): string { return "activitySchedule:v2:" + this.environment + ":" + this.uid; }
|
||||
static now(): number { this.ensure(); return Date.now() + this.offset; }
|
||||
static hasSchedule(): boolean { return !!this.data(); }
|
||||
/** One successfully displayed home reminder per account/environment and Beijing calendar day. */
|
||||
static cloudRiseReminder(): { key: string; day: number } {
|
||||
const period = this.active("cloudRise");
|
||||
if (!this.uid || !period || Number(cc.fx.GameConfig.GM_INFO.level) < period.unlockLevel) return null;
|
||||
const key = "cloudRiseDailyReminder:" + this.environment + ":" + this.uid;
|
||||
const day = Math.floor((this.now() + 8 * 3600000) / 86400000);
|
||||
try { if (cc.fx.StorageMessage.getStorage(key) === day) return null; } catch (_) {}
|
||||
return { key, day };
|
||||
}
|
||||
static markCloudRiseReminderShown(reminder: { key: string; day: number }): void {
|
||||
const current = this.cloudRiseReminder();
|
||||
if (!current || current.key !== reminder.key || current.day !== reminder.day) return;
|
||||
try { cc.fx.StorageMessage.setStorage(reminder.key, reminder.day); } catch (_) {}
|
||||
}
|
||||
private static data(): Schedule {
|
||||
this.ensure();
|
||||
return this.snapshot && this.now() < this.snapshot.windowEndsAt ? this.snapshot : null;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
//@ts-ignore
|
||||
//最大工具类 各种公共方法,以及处理上传,获取后端接口数据
|
||||
var GameTool = {
|
||||
MAX_NORMAL_LEVEL: 2000,
|
||||
MAX_NORMAL_LEVEL: 1980,
|
||||
starterPackReactivationUid: "",
|
||||
starterPackQueuedReason: "",
|
||||
MEMORY_WARNING_EVENT: "game-memory-warning",
|
||||
|
|
|
|||
|
|
@ -12401,8 +12401,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 235,
|
||||
"height": 218
|
||||
"width": 300,
|
||||
"height": 209
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -12454,10 +12454,10 @@
|
|||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "895c2c81-f34c-4d7a-880d-e1eaabfafc41"
|
||||
"__uuid__": "7ce90c89-a092-48a9-b22c-5f0431746477"
|
||||
},
|
||||
"_type": 0,
|
||||
"_sizeMode": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -12762,8 +12762,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 23.207450980392156,
|
||||
"height": 62
|
||||
"width": 50,
|
||||
"height": 57
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -12774,7 +12774,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
11.603725490196078,
|
||||
25,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -12869,8 +12869,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 23.207450980392156,
|
||||
"height": 62
|
||||
"width": 50,
|
||||
"height": 57
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -12881,7 +12881,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
11.603725490196078,
|
||||
75,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -12976,8 +12976,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 23.207450980392156,
|
||||
"height": 62
|
||||
"width": 50,
|
||||
"height": 57
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -12988,7 +12988,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
11.603725490196078,
|
||||
125,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -13083,8 +13083,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 23.207450980392156,
|
||||
"height": 62
|
||||
"width": 50,
|
||||
"height": 57
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -13095,7 +13095,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
11.603725490196078,
|
||||
175,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -13190,8 +13190,8 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 23.207450980392156,
|
||||
"height": 62
|
||||
"width": 50,
|
||||
"height": 57
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
|
|
@ -13202,7 +13202,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
11.603725490196078,
|
||||
225,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -19628,7 +19628,7 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 31.200000000000003,
|
||||
"width": 37.787234042553195,
|
||||
"height": 48
|
||||
},
|
||||
"_anchorPoint": {
|
||||
|
|
@ -19640,7 +19640,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
-19.893617021276597,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -19681,7 +19681,7 @@
|
|||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "8144ce9e-4873-45df-9859-929000facf8e"
|
||||
"__uuid__": "1aa86b1f-52b9-4891-af59-1b41872ca1bd"
|
||||
},
|
||||
"_type": 0,
|
||||
"_sizeMode": 0,
|
||||
|
|
@ -19735,7 +19735,7 @@
|
|||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 31.200000000000003,
|
||||
"width": 37.787234042553195,
|
||||
"height": 48
|
||||
},
|
||||
"_anchorPoint": {
|
||||
|
|
@ -19747,7 +19747,7 @@
|
|||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
19.893617021276597,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -19788,7 +19788,7 @@
|
|||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "8144ce9e-4873-45df-9859-929000facf8e"
|
||||
"__uuid__": "1aa86b1f-52b9-4891-af59-1b41872ca1bd"
|
||||
},
|
||||
"_type": 0,
|
||||
"_sizeMode": 0,
|
||||
|
|
@ -19823,7 +19823,7 @@
|
|||
"__id__": 523
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 531
|
||||
|
|
@ -22563,4 +22563,4 @@
|
|||
"fileId": "",
|
||||
"sync": false
|
||||
}
|
||||
]
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -47,6 +47,26 @@ function fixture(storage = new Map()) {
|
|||
}
|
||||
const flush = async () => {for (let i = 0; i < 12; i++) await Promise.resolve();};
|
||||
|
||||
test('CloudRise daily reminder uses server Beijing date and persists separately per account/environment',async()=>{
|
||||
const f=fixture();f.cc.fx.GameConfig.GM_INFO.level=100;
|
||||
const serverNow=16*3600000-1000;
|
||||
async function sync(){const task=f.service.sync(true);f.requests.at(-1).resolve(response([period('cloudRise',0,3*86400000)],serverNow));await task;}
|
||||
assert.equal(f.service.cloudRiseReminder(),null);await sync();
|
||||
const first=f.service.cloudRiseReminder();assert.equal(first.day,0);
|
||||
f.service.markCloudRiseReminderShown(first);assert.equal(f.service.cloudRiseReminder(),null);
|
||||
await sync();assert.equal(f.service.cloudRiseReminder(),null,'refresh does not repeat today');
|
||||
const restarted=fixture(f.storage);restarted.cc.fx.GameConfig.GM_INFO.level=100;
|
||||
const task=restarted.service.sync();restarted.requests[0].resolve(response([period('cloudRise',0,3*86400000)],serverNow));await task;
|
||||
assert.equal(restarted.service.cloudRiseReminder(),null,'relogin keeps daily marker');
|
||||
f.setNow(11000);assert.equal(f.service.cloudRiseReminder().day,1,'server midnight opens the next day');
|
||||
f.cc.fx.GameConfig.GM_INFO.level=99;assert.equal(f.service.cloudRiseReminder(),null);
|
||||
f.cc.fx.GameConfig.GM_INFO.level=100;f.cc.fx.GameConfig.GM_INFO.userId=1002;await sync();
|
||||
assert.notEqual(f.service.cloudRiseReminder().key,first.key);
|
||||
f.service.markCloudRiseReminderShown(first);assert(f.service.cloudRiseReminder(),'stale account cannot mark current account');
|
||||
f.cc.fx.GameConfig.GM_INFO.userId=1001;f.setEnv('production/');await sync();assert.notEqual(f.service.cloudRiseReminder().key,first.key);
|
||||
f.setNow(4*86400000);assert.equal(f.service.cloudRiseReminder(),null,'expired activity is not promoted');
|
||||
});
|
||||
|
||||
test('cache environment resolver exactly matches POST routing in development, trial and production', () => {
|
||||
let version, opened;
|
||||
const cc = {fx: {GameTool: {getWechatGameVersion: () => version}, GameConfig: {GM_INFO: {}}}, loader: {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function fixture() {
|
|||
String, isValid:()=>true, warn(){}, view:{getVisibleSize:()=>({width:720,height:1280})},
|
||||
fx:{GameConfig:{GM_INFO:{userId:1001,coin:0}}}};
|
||||
function load(file, imports) {
|
||||
imports = {'./module/Config/ActivityScheduleService': {default:{active:()=>null,hasSchedule:()=>false,now:()=>now}}, ...imports};
|
||||
imports = {'./module/Config/ActivityScheduleService': {default:{active:()=>null,hasSchedule:()=>false,now:()=>now,cloudRiseReminder:()=>null}}, ...imports};
|
||||
const exports={};
|
||||
vm.runInNewContext(ts.transpileModule(fs.readFileSync(file,'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,
|
||||
target:ts.ScriptTarget.ES2017,experimentalDecorators:true}}).outputText,
|
||||
|
|
@ -74,6 +74,30 @@ function continuationFixture() {
|
|||
return {...f,View,view,host,popups,notices,setMatch:fn=>match=fn};
|
||||
}
|
||||
|
||||
test('daily home reminder waits in the queue, marks only a displayed overview and releases on close',async()=>{
|
||||
const f=fixture(),tasks=[];let marked=0,done=0;
|
||||
const reminder={key:'account',day:1};let due=reminder;
|
||||
const View=f.load('assets/Script/CloudRiseView.ts',{
|
||||
'./module/Config/CloudRiseService':{default:f.bridge},
|
||||
'./module/Config/ActivityScheduleService':{default:{cloudRiseReminder:()=>due,markCloudRiseReminderShown:()=>{marked++;due=null;}}},
|
||||
'./Sdk/MiniGameSdk':{MiniGameSdk:{}},
|
||||
'../home_popup_queue/HomePopupQueue':{default:{get:()=>({enqueue:(key,priority,run)=>tasks.push({key,priority,run})})}}
|
||||
});
|
||||
const view=new View();view.node={};view.entry={active:true};view.host={};
|
||||
let opens=0,succeed=false;view.open=async mode=>{assert.equal(mode,'overview');opens++;if(succeed)view.overlay={destroy(){}};};
|
||||
view.queueDailyReminder();view.queueDailyReminder();assert.equal(tasks.length,1);assert.equal(opens,0);
|
||||
tasks[0].run(()=>done++);for(let i=0;i<8;i++)await Promise.resolve();
|
||||
assert.equal(marked,0);assert.equal(done,1,'failed load releases the queue');
|
||||
view.queueDailyReminder();assert.equal(tasks.length,1,'failed requests are throttled');
|
||||
f.setNow(40000);succeed=true;view.queueDailyReminder();tasks[1].run(()=>done++);
|
||||
for(let i=0;i<8;i++)await Promise.resolve();assert.equal(marked,1);assert.equal(done,1,'visible reminder retains queue');
|
||||
view.close();assert.equal(done,2);f.setNow(80000);view.queueDailyReminder();assert.equal(tasks.length,2);
|
||||
due=reminder;view.map={};view.queueDailyReminder();assert.equal(tasks.length,2,'never enqueue in GameScene');
|
||||
view.map=null;f.service.hasPendingLoss=()=>true;view.queueDailyReminder();assert.equal(tasks.length,2,'settlement goes first');
|
||||
f.service.hasPendingLoss=()=>false;view.queueDailyReminder();due=null;tasks[2].run(()=>done++);
|
||||
for(let i=0;i<8;i++)await Promise.resolve();assert.equal(opens,2,'expired queued activity is skipped');assert.equal(done,3);
|
||||
});
|
||||
|
||||
test('Next never automatically matches another stage, including waiting stages 1 and 2',async()=>{
|
||||
for(const stage of [1,2]) {
|
||||
const f=continuationFixture();f.run('waiting');f.data.run.stage=stage;
|
||||
|
|
@ -637,7 +661,7 @@ test('home icon appears at cached start without relogin or a successful private
|
|||
const View=f.load('assets/Script/CloudRiseView.ts',{
|
||||
'./module/Config/CloudRiseService':{default:f.bridge},
|
||||
'./module/Config/ActivityScheduleService':{default:schedules},
|
||||
'./Sdk/MiniGameSdk':{MiniGameSdk:{API:{showToast(){}}}},'../home_popup_queue/HomePopupQueue':{default:{}}});
|
||||
'./Sdk/MiniGameSdk':{MiniGameSdk:{API:{showToast(){}}}},'../home_popup_queue/HomePopupQueue':{default:{get:()=>({enqueue(){}})}}});
|
||||
const view=new View();view.node={};view.entry={};view.displayedCoin=0;
|
||||
const unsubscribe=schedules.subscribe(()=>view.tick());
|
||||
view.tick();assert.equal(view.entry.active,false);const initial=f.calls.sync;
|
||||
|
|
@ -745,7 +769,7 @@ test('home countdown follows the personal deadline, refreshes on resume and expi
|
|||
const View=f.load('assets/Script/CloudRiseView.ts',{
|
||||
'./module/Config/CloudRiseService':{default:f.bridge},
|
||||
'./module/Config/ActivityScheduleService':{default:{
|
||||
active:()=>hasSchedule&&f.service.now()<period.endsAt?period:null,hasSchedule:()=>hasSchedule,now:()=>f.service.now()}},
|
||||
active:()=>hasSchedule&&f.service.now()<period.endsAt?period:null,hasSchedule:()=>hasSchedule,now:()=>f.service.now(),cloudRiseReminder:()=>null}},
|
||||
'./Sdk/MiniGameSdk':{MiniGameSdk:{}},'../home_popup_queue/HomePopupQueue':{default:{}}
|
||||
});
|
||||
const view=new View();view.node={};view.entry={};view.entryCountdown={string:''};view.displayedCoin=0;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,13 @@ test('every visibility combination fits without overlap, including both columns
|
|||
for(let mask=0;mask<4096;mask++){
|
||||
[...left,...right].forEach((name,i)=>f.top.getChildByName(name).active=!!(mask&(1<<i)));
|
||||
f.layout.refresh(f.top);f.check();
|
||||
const cloud=f.top.getChildByName('cloudRise');
|
||||
if(cloud.active)assert.equal(cloud.x,f.top.getChildByName('rank').x,'CloudRise always stays on the right');
|
||||
const benefit=f.top.getChildByName('chengxu');
|
||||
if(benefit.active){
|
||||
assert.equal(benefit.x,f.top.getChildByName('rank').x,'benefits always stays on the right');
|
||||
if(cloud.active)assert(benefit.y<cloud.y,'benefits follows CloudRise');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -46,12 +53,14 @@ test('benefits and cloudRise occupy distinct slots and async hide/show immediate
|
|||
const benefit=f.top.getChildByName('chengxu'),cloud=f.top.getChildByName('cloudRise');
|
||||
assert.notDeepEqual([benefit.x,benefit.y],[cloud.x,cloud.y]);
|
||||
assert.equal(cloud.x,f.top.getChildByName('rank').x,'overflow uses the free right slot');
|
||||
const old={x:benefit.x,y:benefit.y};benefit.active=false;f.layout.refresh(f.top);f.check();
|
||||
// The countdown makes CloudRise taller than benefits; only reclaim a slot if the whole entry fits.
|
||||
const old={x:cloud.x,y:cloud.y};benefit.active=false;f.layout.refresh(f.top);f.check();
|
||||
f.top.getChildByName('xinshou').active=false;f.layout.refresh(f.top);f.check();
|
||||
assert.equal(cloud.x,old.x);assert(cloud.y>old.y);
|
||||
assert.equal(cloud.x,old.x);assert.equal(cloud.y,old.y,'left column changes do not move CloudRise');
|
||||
const writes=f.writes;for(let i=0;i<20;i++)f.layout.refresh(f.top);assert.equal(f.writes,writes,'unchanged frames do not reposition buttons');
|
||||
benefit.active=true;f.layout.refresh(f.top);f.check();
|
||||
const benefitY=benefit.y;cloud.active=false;f.layout.refresh(f.top);f.check();
|
||||
assert(benefit.y>benefitY,'benefits moves up when CloudRise is hidden');
|
||||
cloud.active=true;f.layout.refresh(f.top);f.check();assert.equal(benefit.y,benefitY);
|
||||
});
|
||||
|
||||
test('home lays out late in the frame after asynchronous entry visibility changes',()=>{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user