add: channel switch

This commit is contained in:
Vick Scarlet
2026-08-16 20:06:16 +08:00
committed by 神戸小鳥
parent ce74c5221f
commit 4307904239
16 changed files with 484 additions and 524 deletions
+6
View File
@@ -4,6 +4,12 @@
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Launch Editor Browser",
"request": "launch",
"type": "editor-browser",
"url": "http://localhost:5173",
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
+1 -9
View File
@@ -15,21 +15,13 @@
<meta name="laya" screenorientation ="landscape"/> <meta name="laya" screenorientation ="landscape"/>
<meta http-equiv="expires" content="0"/> <meta http-equiv="expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-siteapp"/> <meta http-equiv="Cache-Control" content="no-siteapp"/>
<font-face font-family="方正像素12" src="fonts/方正像素12.ttf"/>
<title>Life Restart</title> <title>Life Restart</title>
<!--
<script type="text/javascript" src="libs/laya/laya.core.js"></script>
<script type="text/javascript" src="libs/laya/laya.webgl.js"></script>
<script type="text/javascript" src="libs/laya/laya.filter.js"></script>
<script type="text/javascript" src="libs/laya/laya.html.js"></script>
<script type="text/javascript" src="libs/laya/laya.particle.js"></script>
<script type="text/javascript" src="libs/laya/laya.ui.js"></script>
-->
<script type="text/javascript" src="libs/laya/min/laya.core.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.core.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.webgl.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.webgl.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.filter.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.filter.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.particle.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.particle.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script>
<script type="module" src="public/channel.js"></script>
<script type="module" src="src/index.js"></script> <script type="module" src="src/index.js"></script>
</head> </head>
<body style="background:black"></body> <body style="background:black"></body>
+1
View File
@@ -0,0 +1 @@
globalThis.$channel = {}
+83 -86
View File
@@ -1,47 +1,45 @@
import './ui/laya.patch.js'; import './ui/laya.patch.js'
import './ui/runtime.js'; import './ui/runtime.js'
import './ui/pluginFunction.js' import './ui/pluginFunction.js'
import './ui/promisesLaya.js' import './ui/promisesLaya.js'
import './ui/layaUI.max.all.js'; import './ui/layaUI.max.all.js'
import UIManager from './ui/uiManager.js'; import UIManager from './ui/uiManager.js'
import * as utils from './functions/util.js'; import * as utils from './functions/util.js'
globalThis.UIManager = globalThis.UIManager = globalThis.UI = UIManager
globalThis.UI =
UIManager;
globalThis.$_ = utils; globalThis.$_ = utils
globalThis.goto = async tag => { globalThis.goto = async tag => {
let url; let url
switch (tag) { switch (tag) {
case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break; case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break
case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break; case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break
case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break; case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break
case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break; case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break
} }
try { try {
if (Laya.Browser.onIOS) { if (Laya.Browser.onIOS) {
window.location.href = url; window.location.href = url
} else { } else {
window.open(url, '_blank'); window.open(url, '_blank')
} }
} catch (error) { } catch (error) {
console.error(error); console.error(error)
} }
} }
class App { class App {
name = 'lifeRestart'
version = '2.1.0'
constructor() { constructor() {
this.name = 'lifeRestart'; console.log(`${this.name} ${this.version}`)
this.version = '2.0.0';
console.log(`${this.name} ${this.version}`);
} }
#language; #language
static languages = { static languages = {
'zh-cn': 'zh-cn', 'zh-cn': 'zh-cn',
'en-us': 'en-us', 'en-us': 'en-us',
}; }
#initLaya() { #initLaya() {
/** /**
@@ -49,131 +47,130 @@ class App {
*/ */
//class laya.webgl.text.CharSegment //class laya.webgl.text.CharSegment
class CharSegment { class CharSegment {
constructor() { _sourceStr = null
this._sourceStr = null; constructor() {}
}
textToSpit(str) { textToSpit(str) {
this._sourceStr = str; this._sourceStr = str
var texLen = str.length; const texLen = str.length
var idx = -1; let idx = -1
this._words = []; this._words = []
while (++idx < texLen) { while (++idx < texLen) {
var character = str.charAt(idx); const character = str.charAt(idx)
var code = str.charCodeAt(idx); const code = str.codePointAt(idx)
if (code >= 0xD800 && code <= 0xDBFF) { if (code >= 0xd800 && code <= 0xdbff) {
this._words.push(character + str.charAt(++idx)); this._words.push(character + str.charAt(++idx))
} else { } else {
this._words.push(character); this._words.push(character)
} }
} }
} }
getChar(i) { getChar(i) {
return this._words; return this._words
} }
getCharCode(i) { getCharCode(i) {
return this._words[i].codePointAt(0); return this._words[i].codePointAt(0)
} }
length() { length() {
return this._words.length; return this._words.length
} }
} }
Laya.class(CharSegment, 'laya.webgl.text.CharSegment'); Laya.class(CharSegment, 'laya.webgl.text.CharSegment')
Laya.imps(CharSegment.prototype, { "laya.webgl.text.ICharSegment": true }) Laya.imps(CharSegment.prototype, { 'laya.webgl.text.ICharSegment': true })
// Laya.init(1125, 2436, Laya.WebGL); // Laya.init(1125, 2436, Laya.WebGL);
Laya.Config.isAntialias = true; Laya.Config.isAntialias = true
Laya.init(...this.#fitScreen, Laya.WebGL); Laya.init(...this.#fitScreen, Laya.WebGL)
Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE; Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE
Laya.stage.alignH = Laya.Stage.ALIGN_CENTER; Laya.stage.alignH = Laya.Stage.ALIGN_CENTER
Laya.stage.scaleMode = "showall"; Laya.stage.scaleMode = 'showall'
Laya.stage.bgColor = "#000000"; Laya.stage.bgColor = '#000000'
window.onresize = () => Laya.stage.size(...this.#fitScreen); window.onresize = () => Laya.stage.size(...this.#fitScreen)
} }
get #fitScreen() { get #fitScreen() {
const designWidth = 1125; const designWidth = 1125
const designHeight = 2436; const designHeight = 2436
const maxWidth = designHeight * 3 / 4; const maxWidth = (designHeight * 3) / 4
const maxHeight = designWidth * 24 / 9; const maxHeight = (designWidth * 24) / 9
const designRatio = designWidth / designHeight; const designRatio = designWidth / designHeight
const screenWidth = window.innerWidth; const screenWidth = window.innerWidth
const screenHeight = window.innerHeight; const screenHeight = window.innerHeight
const screenRatio = screenWidth / screenHeight; const screenRatio = screenWidth / screenHeight
if (screenRatio > designRatio) { if (screenRatio > designRatio) {
return [ return [
Math.min(screenWidth * designHeight / screenHeight, maxWidth), Math.min((screenWidth * designHeight) / screenHeight, maxWidth),
designHeight designHeight,
] ]
} else { } else {
return [ return [
designWidth, designWidth,
Math.min(screenHeight * designWidth / screenWidth, maxHeight) Math.min((screenHeight * designWidth) / screenWidth, maxHeight),
] ]
} }
} }
async setLanguage(language) { async setLanguage(language) {
return this.#setLanguage(language); return this.#setLanguage(language)
} }
async #setLanguage(language) { async #setLanguage(language) {
switch (language) { switch (language) {
case App.languages['en-us']: case App.languages['en-us']:
case App.languages['zh-cn']: case App.languages['zh-cn']:
this.#language = language; this.#language = language
break; break
default: default:
this.#language = App.languages['zh-cn']; this.#language = App.languages['zh-cn']
break; break
} }
globalThis.$lang = globalThis.$lang =
Laya.Text.langPacks = Laya.Text.langPacks =
(await import(`./i18n/${this.#language}.js`)).default; (await import(`./i18n/${this.#language}.js`)).default
} }
resigterEvent() { resigterEvent() {
$$on('achievement', achievement => { $$on('achievement', achievement => {
$ui.popup(UI.popups.ACHIEVEMENT, { achievement }); $ui.popup(UI.popups.ACHIEVEMENT, { achievement })
}) })
$$on('message', ([message, ...args]) => { $$on('message', ([message, ...args]) => {
if (Array.isArray(message)) { if (Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n'); message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n')
} else { } else {
message = $_.format( message = $_.format($lang[message], ...args)
$lang[message], ...args
);
} }
$ui.popup(UI.popups.MESSAGE, { message }); $ui.popup(UI.popups.MESSAGE, { message })
}) })
} }
async start({ async start(
language = App.languages['zh-cn'], { language = App.languages['zh-cn'], theme = 'default' },
theme = 'default', features = [],
}) { ) {
this.resigterEvent(); this.resigterEvent()
this.#initLaya(); this.#initLaya()
globalThis.$ui = UIManager.getInstance(); globalThis.$ui = UIManager.getInstance()
if (theme == 'default') { if (theme == 'default') {
theme = localStorage.getItem('theme') || 'default'; theme = localStorage.getItem('theme') || 'default'
} }
$ui.theme = theme; $ui.theme = theme
await this.#setLanguage(language); await this.#setLanguage(language)
await $ui.setLoading(UI.pages.LOADING); await $ui.setLoading(UI.pages.LOADING)
await $ui.switchView(UI.pages.LOADING); await $ui.switchView(UI.pages.LOADING)
await core.initial( await core.initial(
dataSet => Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON), dataSet => Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON), dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON),
); )
await $ui.switchView(UI.pages.MAIN); await $ui.switchView(UI.pages.MAIN)
for (const { feature, options } of features) {
const f = await import(`./features/${feature}.js`)
await f.default(options)
}
} }
} }
export default App; export default App
+68 -71
View File
@@ -1,127 +1,124 @@
function parseCondition(condition) { function parseCondition(condition) {
const conditions = []
const conditions = []; const length = condition.length
const length = condition.length; const stack = []
const stack = []; stack.unshift(conditions)
stack.unshift(conditions); let cursor = 0
let cursor = 0;
const catchString = i => { const catchString = i => {
const str = condition.substring(cursor, i).trim(); const str = condition.substring(cursor, i).trim()
cursor = i; cursor = i
if(str) stack[0].push(str); if (str) stack[0].push(str)
}; }
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
switch (condition[i]) { switch (condition[i]) {
case ' ': continue; case ' ': continue
case '(':
catchString(i);
cursor ++;
const sub = [];
stack[0].push(sub);
stack.unshift(sub);
break;
case '(': {
catchString(i)
cursor++
const sub = []
stack[0].push(sub)
stack.unshift(sub)
break
}
case ')': case ')':
catchString(i); catchString(i)
cursor ++; cursor++
stack.shift(); stack.shift()
break; break
case '|': case '|':
case '&': case '&':
catchString(i); catchString(i)
catchString(i+1); catchString(i + 1)
break; break
default: continue; default: continue
} }
} }
catchString(length); catchString(length)
return conditions; return conditions
} }
export function checkCondition(property, condition) { export function checkCondition(property, condition) {
const conditions = parseCondition(condition); const conditions = parseCondition(condition)
return checkParsedConditions(property, conditions); return checkParsedConditions(property, conditions)
} }
function checkParsedConditions(property, conditions) { function checkParsedConditions(property, conditions) {
if(!Array.isArray(conditions)) return checkProp(property, conditions); if (!Array.isArray(conditions)) return checkProp(property, conditions)
if(conditions.length == 0) return true; if (conditions.length == 0) return true
if(conditions.length == 1) return checkParsedConditions(property, conditions[0]); if (conditions.length == 1) return checkParsedConditions(property, conditions[0])
let ret = checkParsedConditions(property, conditions[0]); let ret = checkParsedConditions(property, conditions[0])
for (let i = 1; i < conditions.length; i += 2) { for (let i = 1; i < conditions.length; i += 2) {
switch (conditions[i]) { switch (conditions[i]) {
case '&': case '&':
if(ret) ret = checkParsedConditions(property, conditions[i+1]); if (ret) ret = checkParsedConditions(property, conditions[i + 1])
break; break
case '|': case '|':
if(ret) return true; if (ret) return true
ret = checkParsedConditions(property, conditions[i+1]); ret = checkParsedConditions(property, conditions[i + 1])
break; break
default: return false; default: return false
} }
} }
return ret; return ret
} }
function checkProp(property, condition) { function checkProp(property, condition) {
const length = condition.length
let i = condition.search(/[><!?=]/)
const length = condition.length; const prop = condition.substring(0, i)
let i = condition.search(/[><\!\?=]/); const symbol = condition.substring(i, (i += condition[i + 1] == '=' ? 2 : 1))
const d = condition.substring(i, length)
const prop = condition.substring(0,i); const propData = property.get(prop)
const symbol = condition.substring(i, i+=(condition[i+1]=='='?2:1)); const conditionData = d[0] == '[' ? JSON.parse(d) : Number(d)
const d = condition.substring(i, length);
const propData = property.get(prop);
const conditionData = d[0]=='['? JSON.parse(d): Number(d);
switch (symbol) { switch (symbol) {
case '>': return propData > conditionData; case '>': return propData > conditionData
case '<': return propData < conditionData; case '<': return propData < conditionData
case '>=': return propData >= conditionData; case '>=': return propData >= conditionData
case '<=': return propData <= conditionData; case '<=': return propData <= conditionData
case '=': case '=':
if(Array.isArray(propData)) if (Array.isArray(propData)) return propData.includes(conditionData)
return propData.includes(conditionData); return propData == conditionData
return propData == conditionData;
case '!=': case '!=':
if (Array.isArray(propData)) if (Array.isArray(propData))
return !propData.includes(conditionData); return !propData.includes(conditionData)
return propData != conditionData; return propData != conditionData
case '?': case '?':
if (Array.isArray(propData)) { if (Array.isArray(propData)) {
for (const p of propData) for (const p of propData)
if(conditionData.includes(p)) return true; if (conditionData.includes(p)) return true
return false; return false
} }
return conditionData.includes(propData); return conditionData.includes(propData)
case '!': case '!':
if (Array.isArray(propData)) { if (Array.isArray(propData)) {
for (const p of propData) for (const p of propData)
if(conditionData.includes(p)) return false; if (conditionData.includes(p)) return false
return true; return true
} }
return !conditionData.includes(propData); return !conditionData.includes(propData)
default: return false; default: return false
} }
} }
export function extractMaxTriggers(condition) { export function extractMaxTriggers(condition) {
// Assuming only age related talents can be triggered multiple times. // Assuming only age related talents can be triggered multiple times.
const RE_AGE_CONDITION = /AGE\?\[([0-9\,]+)\]/; const RE_AGE_CONDITION = /AGE\?\[([0-9,]+)\]/
const match_object = RE_AGE_CONDITION.exec(condition); const match_object = RE_AGE_CONDITION.exec(condition)
if (match_object == null) { if (match_object == null) {
// Not age related, single trigger. // Not age related, single trigger.
return 1; return 1
} }
const age_list = match_object[1].split(","); const age_list = match_object[1].split(',')
return age_list.length; return age_list.length
} }
+6 -6
View File
@@ -1,4 +1,4 @@
export default ({ export default {
UI_Next: 'Next', UI_Next: 'Next',
UI_Back: 'Back', UI_Back: 'Back',
UI_Skip: 'Skip', UI_Skip: 'Skip',
@@ -26,7 +26,7 @@ export default ({
UI_Property_Spirit: 'SPR', UI_Property_Spirit: 'SPR',
UI_Title_Remake: 'Remake Simulate', UI_Title_Remake: 'Remake Simulate',
UI_Title_Subsequent: 'The rubbish life doesn\'t want to stay for a second', UI_Title_Subsequent: "The rubbish life doesn't want to stay for a second",
UI_Remake: '↻Remake Now', UI_Remake: '↻Remake Now',
UI_Thanks: 'Thx', UI_Thanks: 'Thx',
UI_Achievement: 'Achv', UI_Achievement: 'Achv',
@@ -146,11 +146,11 @@ export default ({
UI_UniqueWaTaShiContent: '\nUnique character card different from other 60 million player\nAll property, All talent, All random\nAll has only one chance', UI_UniqueWaTaShiContent: '\nUnique character card different from other 60 million player\nAll property, All talent, All random\nAll has only one chance',
UI_GenerateNow: 'Generate Now', UI_GenerateNow: 'Generate Now',
M_NoRank: 'There is no rank', M_NoRank: 'There is no rank',
M_PleaseSelectOne: 'Please Select One', M_PleaseSelectOne: 'Please Select One',
M_UnGenerate: 'Unique Character no generate', M_UnGenerate: 'Unique Character no generate',
M_DisableExtendTalent: 'Celebrity mode can\'t extends talent', M_DisableExtendTalent: "Celebrity mode can't extends talent",
M_SponsorThanks: 'Thanks for your support',
F_RemakeTimes: 'Remake {0} Times', F_RemakeTimes: 'Remake {0} Times',
F_AchievementCount: 'Achievement {0}', F_AchievementCount: 'Achievement {0}',
@@ -160,5 +160,5 @@ export default ({
F_TalentSelectNotComplect: 'Please select {0} talent', F_TalentSelectNotComplect: 'Please select {0} talent',
F_PropertyPointLeft: 'You have left {0} property point', F_PropertyPointLeft: 'You have left {0} property point',
F_TalentReplace: 'Talent replace [{source.name}] -> [{target.name}]', F_TalentReplace: 'Talent replace [{source.name}] -> [{target.name}]',
F_PropertyStr: 'CHR{CHR} INT{INT} STR{STR} MNY{MNY}' F_PropertyStr: 'CHR{CHR} INT{INT} STR{STR} MNY{MNY}',
}); }
+4 -3
View File
@@ -1,4 +1,4 @@
export default ({ export default {
UI_Next: '下一步', UI_Next: '下一步',
UI_Back: '返回', UI_Back: '返回',
UI_Skip: '跳过', UI_Skip: '跳过',
@@ -152,6 +152,7 @@ export default ({
M_PleaseSelectOne: '请选择一个名人', M_PleaseSelectOne: '请选择一个名人',
M_UnGenerate: '独一无二的我还没有生成', M_UnGenerate: '独一无二的我还没有生成',
M_DisableExtendTalent: '名人模式不能继承天赋', M_DisableExtendTalent: '名人模式不能继承天赋',
M_SponsorThanks: '感谢支持',
F_RemakeTimes: '已重开{0}次', F_RemakeTimes: '已重开{0}次',
F_AchievementCount: '成就达成{0}个', F_AchievementCount: '成就达成{0}个',
@@ -161,5 +162,5 @@ export default ({
F_TalentSelectNotComplect: '要选满{0}个天赋', F_TalentSelectNotComplect: '要选满{0}个天赋',
F_PropertyPointLeft: '你还有 {0} 属性点没有分配完', F_PropertyPointLeft: '你还有 {0} 属性点没有分配完',
F_TalentReplace: '天赋替换【{source.name}】->【{target.name}】', F_TalentReplace: '天赋替换【{source.name}】->【{target.name}】',
F_PropertyStr: '颜值{CHR} 智力{INT} 体质{STR} 家境{MNY}' F_PropertyStr: '颜值{CHR} 智力{INT} 体质{STR} 家境{MNY}',
}); }
+38 -47
View File
@@ -1,72 +1,63 @@
import App from './app.js'; import App from './app.js'
import Life from './modules/life.js'; import Life from './modules/life.js'
globalThis.$$eventMap = new Map(); if (!globalThis.$channel) globalThis.$channel = {}
globalThis.$$eventMap = new Map()
globalThis.$$event = (tag, data) => { globalThis.$$event = (tag, data) => {
const listener = $$eventMap.get(tag); const listener = $$eventMap.get(tag)
if(listener) listener.forEach(fn=>fn(data)); if (listener) listener.forEach(fn => fn(data))
} }
globalThis.$$on = (tag, fn) => { globalThis.$$on = (tag, fn) => {
let listener = $$eventMap.get(tag); let listener = $$eventMap.get(tag)
if (!listener) { if (!listener) {
listener = new Set(); listener = new Set()
$$eventMap.set(tag, listener); $$eventMap.set(tag, listener)
} }
listener.add(fn); listener.add(fn)
} }
globalThis.$$off = (tag, fn) => { globalThis.$$off = (tag, fn) => {
const listener = $$eventMap.get(tag); const listener = $$eventMap.get(tag)
if(listener) listener.delete(fn); if (listener) listener.delete(fn)
} }
globalThis.$$copy = async text => { globalThis.$$copy = async text => {
const result = await navigator.permissions.query({ name: "clipboard-write" }) const result = await navigator.permissions.query({ name: 'clipboard-write' })
if (result.state == "granted" || result.state == "prompt") { if (result.state == 'granted' || result.state == 'prompt') {
navigator.clipboard.writeText(text) navigator.clipboard.writeText(text)
return true; return true
} }
const input = document.createElement('input'); return false
input.setAttribute('style', 'opacity: 0;');
document.body.appendChild(input);
input.value = text;
input.select();
const r = document.execCommand("copy");
document.body.removeChild(input);
return r;
} }
globalThis.$$read = async () => { globalThis.$$read = async () => {
const result = await navigator.permissions.query({ name: "clipboard-read" }) const result = await navigator.permissions.query({ name: 'clipboard-read' })
if (result.state == "granted" || result.state == "prompt") { if (result.state == 'granted' || result.state == 'prompt') {
return await navigator.clipboard.readText(); return await navigator.clipboard.readText()
}
return null
} }
const input = document.createElement('input');
input.setAttribute('style', 'opacity: 0;');
document.body.appendChild(input);
input.focus();
const r = document.execCommand("paste");
const text = input.value;
document.body.removeChild(input);
return r?text:r;
};
const core = new Life(); const core = new Life()
const game = new App(); const game = new App()
globalThis.core = core; globalThis.core = core
globalThis.game = game; globalThis.game = game
const query = {}; const query = {}
location.search.substr(1).split('&').forEach(item => { location.search
const parts = item.split('='); .substring(1)
query[parts[0]] = parts[1]; .split('&')
}); .forEach(item => {
const parts = item.split('=')
query[parts[0]] = parts[1]
})
core.config({ core.config({
defaultPropertyPoints: 20, // default number of points for a property defaultPropertyPoints: 20, // default number of points for a property
talentSelectLimit: 3, // max number of talents that can be selected talentSelectLimit: 3, // max number of talents that can be selected
propertyAllocateLimit: [0, 10], // scoop of properties that can be allocated, propertyAllocateLimit: [0, 10], // scoop of properties that can be allocated,
defaultPropertys: { SPR: 5 }, // default properties defaultPropertys: { SPR: 5 }, // default properties
talentConfig: { // config for talent talentConfig: {
// config for talent
talentPullCount: 10, // number of talents to pull from the talent pool talentPullCount: 10, // number of talents to pull from the talent pool
talentRate: { 1: 100, 2: 10, 3: 1, total: 1000 }, // rate of talent pull talentRate: { 1: 100, 2: 10, 3: 1, total: 1000 }, // rate of talent pull
additions: { additions: {
@@ -83,7 +74,7 @@ core.config({
[ 50, { 2: 3 }], [ 50, { 2: 3 }],
[ 70, { 2: 4 }], [ 70, { 2: 4 }],
[100, { 2: 5 }], [100, { 2: 5 }],
] ],
}, },
}, },
propertyConfig: { // config for property propertyConfig: { // config for property
@@ -220,5 +211,5 @@ core.config({
[5, 1], [5, 1],
], ],
}, },
}); })
game.start(query); game.start(query, globalThis.$channel.features ?? [])
+2 -2
View File
@@ -1,8 +1,8 @@
// 滚动条太灵敏 // 滚动条太灵敏
const SCROLL_START_DISTANCE = 30; const SCROLL_START_DISTANCE = 30;
Laya.ScrollBar.prototype.loop=function(){ Laya.ScrollBar.prototype.loop=function(){
var mouseY=Laya.stage.mouseY; let mouseY=Laya.stage.mouseY;
var mouseX=Laya.stage.mouseX; let mouseX=Laya.stage.mouseX;
this._lastOffset=this.isVertical ? (mouseY-this._lastPoint.y):(mouseX-this._lastPoint.x); this._lastOffset=this.isVertical ? (mouseY-this._lastPoint.y):(mouseX-this._lastPoint.x);
if (this._clickOnly){ if (this._clickOnly){
if (Math.abs(this._lastOffset *(this.isVertical ? Laya.stage._canvasTransform.getScaleY():Laya.stage._canvasTransform.getScaleX()))> SCROLL_START_DISTANCE){ if (Math.abs(this._lastOffset *(this.isVertical ? Laya.stage._canvasTransform.getScaleY():Laya.stage._canvasTransform.getScaleX()))> SCROLL_START_DISTANCE){
+1 -1
View File
@@ -12,7 +12,7 @@ plugin.extractComponents = function(uiView, componentNames) {
uiView.child.splice(i, 1); uiView.child.splice(i, 1);
continue; continue;
} }
deepSearch(child, componentNames, components); deepSearch(child, componentNames);
} }
}; };
deepSearch(uiView, componentNames); deepSearch(uiView, componentNames);
+8 -33
View File
@@ -3,16 +3,12 @@ Laya.runtime = {};
runtime.ColorFilterItem = runtime.ColorFilterItem =
class ColorFilterItem extends Laya.Image { class ColorFilterItem extends Laya.Image {
constructor() {
super();
}
#hexToRgba = (hex) => { #hexToRgba = (hex) => {
const rgba = []; const rgba = [];
hex = hex.replace('#', ''); hex = hex.replace('#', '');
hex = hex.match(new RegExp('(.{2})(.{2})(.{2})(.{2})', 'i')); hex = hex.match(/(.{2})(.{2})(.{2})(.{2})/i);
hex.forEach((item, index) => { hex.forEach((item, index) => {
rgba[index] = parseInt(item, 16); rgba[index] = Number.parseInt(item, 16);
}); });
rgba.shift(); rgba.shift();
return rgba; return rgba;
@@ -47,26 +43,9 @@ class ColorFilterItem extends Laya.Image {
} }
} }
} }
runtime.UIBase = runtime.UIBase = class UIBase extends Laya.View {}
class UIBase extends Laya.View { runtime.ViewBase = class ViewBase extends runtime.UIBase {}
constructor() { runtime.DialogBase = class DialogBase extends runtime.UIBase {}
super();
}
}
runtime.ViewBase =
class ViewBase extends runtime.UIBase {
constructor() {
super();
}
}
runtime.DialogBase =
class DialogBase extends runtime.UIBase {
constructor() {
super();
}
}
runtime.ScaleButton = runtime.ScaleButton =
class ScaleButton extends Laya.Button { class ScaleButton extends Laya.Button {
@@ -156,12 +135,12 @@ class RGBAItem {
} }
#hex(v) { #hex(v) {
v = parseInt(v).toString(16); v = Number.parseInt(v).toString(16);
return v.length == 1 ? '0' + v : v; return v.length == 1 ? '0' + v : v;
} }
#dec(v) { #dec(v) {
return parseInt(v, 16); return Number.parseInt(v, 16);
} }
get hex() { get hex() {
@@ -303,7 +282,7 @@ class ColorfulBox extends Laya.Box {
const tween = (colorItem, target, last) => { const tween = (colorItem, target, last) => {
Laya.Tween.clearAll(colorItem); Laya.Tween.clearAll(colorItem);
const distance = colorItem.distance(target, last); const distance = colorItem.distance(target, last);
if(!isFinite(distance)) { if(!Number.isFinite(distance)) {
colorItem.hex = target; colorItem.hex = target;
return; return;
} }
@@ -544,10 +523,6 @@ class BlankBox extends Laya.Box {
runtime.ColorAgentLabel = runtime.ColorAgentLabel =
class ColorAgentLabel extends Laya.Label { class ColorAgentLabel extends Laya.Label {
constructor(...args) {
super(...args);
}
get #brothers() { get #brothers() {
const brothers = []; const brothers = [];
if(!this.parent) return brothers; if(!this.parent) return brothers;
+28 -23
View File
@@ -1,38 +1,43 @@
export default class CyberMain extends ui.view.CyberTheme.CyberMainUI { export default class CyberMain extends ui.view.CyberTheme.CyberMainUI {
constructor() { constructor() {
super(); super()
this.btnRemake.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.MODE)); this.btnRemake.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.MODE))
this.btnAchievement.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.ACHIEVEMENT)); this.btnAchievement.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.ACHIEVEMENT))
this.btnThanks.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.THANKS)); this.btnThanks.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.THANKS))
this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github']); this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github'])
this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord']); this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord'])
this.btnThemes.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.THEMES)); this.btnThemes.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.THEMES))
this.btnSaveLoad.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.SAVELOAD)); this.btnSaveLoad.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.SAVELOAD))
this.on(Laya.Event.RESIZE, this, () => { this.on(Laya.Event.RESIZE, this, () => {
const scale = Math.max( const scale = Math.max(
this.width / this.imgBg.width, this.width / this.imgBg.width,
this.height / this.imgBg.height this.height / this.imgBg.height,
); )
this.imgBg.scale(scale, scale); this.imgBg.scale(scale, scale)
}); })
} }
static load() { static load() {
return [ return [
"fonts/方正像素12.ttf", 'fonts/方正像素12.ttf',
"images/atlas/images/accessories.atlas", 'images/atlas/images/accessories.atlas',
"images/atlas/images/border.atlas", 'images/atlas/images/border.atlas',
"images/atlas/images/button.atlas", 'images/atlas/images/button.atlas',
"images/atlas/images/icons.atlas", 'images/atlas/images/icons.atlas',
"images/atlas/images/progress.atlas", 'images/atlas/images/progress.atlas',
"images/atlas/images/slider.atlas", 'images/atlas/images/slider.atlas',
] ]
} }
init() { init() {
this.banner.visible = const leastOnce = !!core.times
this.btnDiscord.visible = this.banner.visible = leastOnce
this.btnAchievement.visible = this.btnAchievement.visible = leastOnce
this.btnThanks.visible = !!core.times; this.btnThanks.visible = leastOnce
const disabled = globalThis.$channel?.disabled || {}
this.btnDiscord.visible = leastOnce && !disabled.discord
this.btnGithub.visible = !disabled.github
this.btnSaveLoad.visible = !disabled.saveload
} }
} }
+22 -18
View File
@@ -1,28 +1,32 @@
export default class Main extends ui.view.DefaultTheme.MainUI { export default class Main extends ui.view.DefaultTheme.MainUI {
constructor() { constructor() {
super(); super()
this.btnRemake.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.MODE)); this.btnRemake.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.MODE))
this.btnAchievement.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.ACHIEVEMENT)); this.btnAchievement.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.ACHIEVEMENT))
this.btnThanks.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.THANKS)); this.btnThanks.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.THANKS))
this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github']); this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github'])
this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord']); this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord'])
this.btnThemes.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.THEMES)); this.btnThemes.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.THEMES))
this.btnSaveLoad.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.SAVELOAD)); this.btnSaveLoad.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.SAVELOAD))
} }
static load() { static load() {
return [ return ['images/atlas/images/icons.atlas']
"images/atlas/images/icons.atlas",
]
} }
init() { init() {
this.banner.visible = const text = this.labSubTitle.text
this.btnDiscord.visible = this.labSubTitle.text = ' '
this.btnAchievement.visible = this.labSubTitle.text = text
this.btnThanks.visible = !!core.times;
const text = this.labSubTitle.text; const leastOnce = !!core.times
this.labSubTitle.text = ' '; this.banner.visible = leastOnce
this.labSubTitle.text = text; this.btnAchievement.visible = leastOnce
this.btnThanks.visible = leastOnce
const disabled = globalThis.$channel?.disabled || {}
this.btnDiscord.visible = leastOnce && !disabled.discord
this.btnGithub.visible = !disabled.github
this.btnSaveLoad.visible = !disabled.saveload
} }
} }
+6 -1
View File
@@ -5,8 +5,13 @@ export default class Thanks extends ui.view.DefaultTheme.ThanksUI {
this.listSupports.renderHandler = Laya.Handler.create(this, this.renderSupport, null, false); this.listSupports.renderHandler = Laya.Handler.create(this, this.renderSupport, null, false);
this.panelTopSupports.vScrollBar.elasticDistance = 150; this.panelTopSupports.vScrollBar.elasticDistance = 150;
this.listSupports.scrollBar.elasticDistance = 150; this.listSupports.scrollBar.elasticDistance = 150;
if (globalThis.$channel?.disabled?.sponsor) {
this.btnAFD.on(Laya.Event.CLICK, this, $$event, ['message', ['M_SponsorThanks']]);
} else {
this.btnAFD.on(Laya.Event.CLICK, this, goto, ['sponsor_afd']); this.btnAFD.on(Laya.Event.CLICK, this, goto, ['sponsor_afd']);
this.btnDDF.on(Laya.Event.CLICK, this, goto, ['sponsor_ddf']); // this.btnDDF.on(Laya.Event.CLICK, this, goto, ['sponsor_ddf']);
}
this.btnDDF.on(Laya.Event.CLICK, this, $$event, ['message', ['M_SponsorThanks']]);
} }
static #createComponent = Laya.plugin.extractComponents(Thanks.uiView, ['boxTopSupport']); static #createComponent = Laya.plugin.extractComponents(Thanks.uiView, ['boxTopSupport']);
+79 -86
View File
@@ -1,78 +1,77 @@
export default class SaveLoad extends ui.view.SaveLoadUI { export default class SaveLoad extends ui.view.SaveLoadUI {
constructor() { constructor() {
super(); super()
this.btnClose.on(Laya.Event.CLICK, this, async () => { this.btnClose.on(Laya.Event.CLICK, this, async () => {
await this.close(); await this.close()
$ui.switchView(UI.pages.MAIN); $ui.switchView(UI.pages.MAIN)
}); })
this.btnRead.on(Laya.Event.CLICK, this, async () => { this.btnRead.on(Laya.Event.CLICK, this, async () => {
const result = await $$copy(this.input.text = this.data); this.input.text = this.data
$$event('message', [result? 'UI_CopySuccess': 'UI_CopyFailed']); const result = await $$copy(this.data)
}); $$event('message', [result ? 'UI_CopySuccess' : 'UI_CopyFailed'])
})
this.btnWrite.on(Laya.Event.CLICK, this, async () => { this.btnWrite.on(Laya.Event.CLICK, this, async () => {
const text = await $$read(); const text = await $$read()
if(text == false) { if (text == null) {
this.data = [ this.data = [
this.input.text, this.input.text,
'UI_PasteFailedDecodeSuccess', 'UI_PasteFailedDecodeSuccess',
'UI_PasteFailedDecodeFailed' 'UI_PasteFailedDecodeFailed',
]; ]
} else { } else {
this.input.text = text; this.input.text = text
this.data = [ this.data = [
text, text,
'UI_PasteSuccessDecodeSuccess', 'UI_PasteSuccessDecodeSuccess',
'UI_PasteSuccessDecodeFailed' 'UI_PasteSuccessDecodeFailed',
]; ]
} }
}); })
this.btnSave.on(Laya.Event.CLICK, this, () => { this.btnSave.on(Laya.Event.CLICK, this, () => {
let blob = new Blob([this.data], { type: 'application/json' }); let blob = new Blob([this.data], { type: 'application/json' })
const slice = blob.slice || blob.webkitSlice || blob.mozSlice; const slice = blob.slice || blob.webkitSlice || blob.mozSlice
blob = slice.call(blob, 0, blob.size, 'application/octet-stream'); blob = slice.call(blob, 0, blob.size, 'application/octet-stream')
const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a'); const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
a.href = URL.createObjectURL(blob); a.href = URL.createObjectURL(blob)
a.download = `Remake_save_${new Date().toISOString().replace(':','.')}.json`; a.download = `Remake_save_${new Date().toISOString().replace(':', '.')}.json`
document.body.appendChild(a); document.body.appendChild(a)
a.click(); a.click()
document.body.removeChild(a); a.remove()
URL.revokeObjectURL(a.href); URL.revokeObjectURL(a.href)
}); })
this.btnLoad.on(Laya.Event.CLICK, this, () => { this.btnLoad.on(Laya.Event.CLICK, this, () => {
const file = document.createElement('input'); const file = document.createElement('input')
file.setAttribute('type', 'file'); file.setAttribute('type', 'file')
file.setAttribute('name', 'file'); file.setAttribute('name', 'file')
file.setAttribute('accept', 'application/json'); file.setAttribute('accept', 'application/json')
file.setAttribute('style', 'display: none;'); file.setAttribute('style', 'display: none;')
document.body.appendChild(file); document.body.appendChild(file)
file.click(); file.click()
file.onchange = (e)=>{ file.onchange = async e => {
const file = e.target.files[0]; const f = e.target.files[0]
if(!file) return; if (!f) return
const reader = new FileReader(); this.data = [await f.text()]
reader.onload = () => this.data = [reader.result]; file.remove()
reader.readAsText(file); }
document.body.removeChild(file); })
};
});
this.input.on(Laya.Event.MOUSE_DOWN, this, () => { this.input.on(Laya.Event.MOUSE_DOWN, this, () => {
this.input.setSelection(0, this.input.text.length); this.input.setSelection(0, this.input.text.length)
}) })
this.btnBackup.on(Laya.Event.CLICK, this, () => { this.btnBackup.on(Laya.Event.CLICK, this, () => {
const board = document.createElement("div"); const board = document.createElement('div')
document.body.appendChild(board); document.body.appendChild(board)
board.style = ` board.style = `
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
opacity: 0.95`; opacity: 0.95`
const bg = document.createElement("div"); const bg = document.createElement('div')
bg.style = ` bg.style = `
position: absolute; position: absolute;
top: 0; top: 0;
@@ -80,18 +79,14 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
right: 0; right: 0;
bottom: 0; bottom: 0;
background: #fff; background: #fff;
opacity: 0.95`; opacity: 0.95`
document.body.appendChild(board); document.body.appendChild(board)
board.appendChild(bg); board.appendChild(bg)
const textarea = document.createElement("textarea"); const textarea = document.createElement('textarea')
textarea.style = `position: absolute; width: ${window.innerWidth}px; height: ${window.innerHeight}px;` textarea.style = `position: absolute; width: ${window.innerWidth}px; height: ${window.innerHeight}px;`
textarea.value = JSON.stringify( textarea.value = JSON.stringify(JSON.parse(this.data), null, 4)
JSON.parse(this.data), board.appendChild(textarea)
null, const close = document.createElement('div')
4
);
board.appendChild(textarea);
const close = document.createElement("div");
close.style = ` close.style = `
position: absolute; position: absolute;
top: 0; top: 0;
@@ -103,12 +98,12 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
padding: 0; padding: 0;
line-height: 100px; line-height: 100px;
color: white; color: white;
opacity: 0.7`; opacity: 0.7`
close.innerHTML = '×'; close.innerHTML = '×'
board.appendChild(close); board.appendChild(close)
close.onclick = ()=>board.remove(); close.onclick = () => board.remove()
const load = document.createElement("div"); const load = document.createElement('div')
load.style = ` load.style = `
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@@ -120,43 +115,41 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
padding: 0; padding: 0;
line-height: 50px; line-height: 50px;
color: white; color: white;
opacity: 0.7`; opacity: 0.7`
load.innerHTML = 'LOAD<br>读取'; load.innerHTML = 'LOAD<br>读取'
board.appendChild(load); board.appendChild(load)
load.onclick = ()=>this.data = [textarea.value, '成功/success', '失败/failed', true]; load.onclick = () => (this.data = [textarea.value, '成功/success', '失败/failed', true])
}); })
} }
static load() { static load() {
return ["images/atlas/images/radio.atlas"]; return ['images/atlas/images/radio.atlas']
} }
init() { init() {
this.input.text = this.data; this.input.text = this.data
} }
get data() { get data() {
const data = {}; const data = {}
Object Object.keys(localStorage)
.keys(localStorage) .filter(v => !v.startsWith('goog'))
.filter(v=>v.substr(0,4)!='goog') .forEach(key => (data[key] = localStorage[key]))
.forEach(key=>data[key] = localStorage[key]); return JSON.stringify(data)
return JSON.stringify(data);
} }
set data([v, success = 'UI_LoadSuccess', failed = 'UI_LoadFailed', altMsg]) { set data([v, success = 'UI_LoadSuccess', failed = 'UI_LoadFailed', altMsg]) {
try { try {
const data = JSON.parse(v); const data = JSON.parse(v)
for(const key in data) for (const key in data) localStorage.setItem(key, data[key])
localStorage.setItem(key, data[key]); if (altMsg) alert(success)
if(altMsg) alert(success); else $$event('message', [success])
else $$event('message', [success]); $ui.theme = $ui.theme ?? null
$ui.theme = $ui.theme; this.btnClose.event(Laya.Event.CLICK)
this.btnClose.event(Laya.Event.CLICK);
} catch (e) { } catch (e) {
console.error(e); console.error(e)
if(altMsg) alert(`${failed}\n${e}`); if (altMsg) alert(`${failed}\n${e}`)
else $$event('message', [failed]); else $$event('message', [failed])
} }
} }
} }
+25 -32
View File
@@ -34,7 +34,7 @@ export default class UIManager {
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000') this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000')
this.#dialogMask.alpha = 0.4 this.#dialogMask.alpha = 0.4
this.#dialogMask.on(Laya.Event.CLICK, this, () => { this.#dialogMask.on(Laya.Event.CLICK, this, () => {
this.#dialogStack[this.#dialogStack.length - 1]?.close?.() this.#dialogStack.at(-1)?.close?.()
}) })
} }
@@ -86,7 +86,7 @@ export default class UIManager {
args, args,
actions?.load, actions?.load,
viewName, viewName,
'pages' 'pages',
) )
view.top = view.bottom = view.left = view.right = 0 view.top = view.bottom = view.left = view.right = 0
@@ -115,7 +115,7 @@ export default class UIManager {
if (this.#loading) { if (this.#loading) {
timeout = setTimeout( timeout = setTimeout(
() => this.#stage.addChild(this.#loading), () => this.#stage.addChild(this.#loading),
3000 3000,
) )
} }
const onProgress = this.#loading?.onProgress const onProgress = this.#loading?.onProgress
@@ -128,7 +128,7 @@ export default class UIManager {
? this.scanResource(ViewClass.uiView) ? this.scanResource(ViewClass.uiView)
: [] : []
if (preload) { if (preload) {
preload = [].concat(preload).concat(scanedResourceList) preload = preload.concat(scanedResourceList)
} else { } else {
preload = scanedResourceList preload = scanedResourceList
} }
@@ -162,19 +162,19 @@ export default class UIManager {
async loadRes(resourceList, preload, onProgress) { async loadRes(resourceList, preload, onProgress) {
const cnt = (resourceList?.length || 0) + (preload?.length || 0) const cnt = (resourceList?.length || 0) + (preload?.length || 0)
if (resourceList && resourceList.length) { if (resourceList?.length) {
const s = resourceList.length / cnt const s = resourceList.length / cnt
await Laya.promises.loader.load( await Laya.promises.loader.load(
resourceList, resourceList,
Laya.Handler.create(null, prg => onProgress?.(prg * s)) Laya.Handler.create(null, prg => onProgress?.(prg * s)),
) )
} }
if (preload && preload.length) { if (preload?.length) {
const s = 1 - preload.length / cnt const s = 1 - preload.length / cnt
const l = preload.length / cnt const l = preload.length / cnt
await Laya.promises.loader.load( await Laya.promises.loader.load(
preload, preload,
Laya.Handler.create(null, prg => onProgress?.(prg * l + s)) Laya.Handler.create(null, prg => onProgress?.(prg * l + s)),
) )
} }
} }
@@ -202,7 +202,7 @@ export default class UIManager {
args, args,
actions?.load, actions?.load,
dialogName, dialogName,
'pages' 'pages',
) )
const index = this.#dialogStack.indexOf(dialog) const index = this.#dialogStack.indexOf(dialog)
@@ -223,7 +223,7 @@ export default class UIManager {
dialog, dialog,
{ scaleX: 1, scaleY: 1 }, { scaleX: 1, scaleY: 1 },
300, 300,
Laya.Ease.backOut Laya.Ease.backOut,
) )
}) })
await open(dialog) await open(dialog)
@@ -237,7 +237,7 @@ export default class UIManager {
dialog, dialog,
{ scaleX: 0, scaleY: 0 }, { scaleX: 0, scaleY: 0 },
300, 300,
Laya.Ease.strongIn Laya.Ease.strongIn,
) )
} }
const index = this.#dialogStack.indexOf(dialog) const index = this.#dialogStack.indexOf(dialog)
@@ -255,7 +255,7 @@ export default class UIManager {
const popup = await this.getView(className, args, null, type, 'popups') const popup = await this.getView(className, args, null, type, 'popups')
this.#popupLayer.addChild(popup) this.#popupLayer.addChild(popup)
await popup.popup(args, this.#popupLayer) await popup.popup(args, this.#popupLayer)
this.#popupLayer.removeChild(popup) popup.removeSelf()
} }
clearAllDialog() { clearAllDialog() {
@@ -266,7 +266,7 @@ export default class UIManager {
#config(view, key, type) { #config(view, key, type) {
const config = this.#configs?.[type]?.[key] const config = this.#configs?.[type]?.[key]
if (!config) return if (!config) return
if (view.config && view.config(config)) return if (view.config?.(config)) return
const applyConfig = (target, config) => { const applyConfig = (target, config) => {
if (!target) return if (!target) return
if (typeof config == 'string') { if (typeof config == 'string') {
@@ -278,7 +278,7 @@ export default class UIManager {
if (config.names) if (config.names)
for (const name in config.names) for (const name in config.names)
this.#deepGetChildsByName(view, name).forEach(child => this.#deepGetChildsByName(view, name).forEach(child =>
applyConfig(child, config.names[name]) applyConfig(child, config.names[name]),
) )
if (config.vars) if (config.vars)
@@ -288,7 +288,7 @@ export default class UIManager {
#deepGetChildsByName(parent, name) { #deepGetChildsByName(parent, name) {
const list = [] const list = []
if (!parent || !parent._childs) return list if (!parent?._childs) return list
for (const child of parent._childs) { for (const child of parent._childs) {
if (child.name == name) list.push(child) if (child.name == name) list.push(child)
@@ -311,7 +311,7 @@ export default class UIManager {
} }
#subSkin(skin, type) { #subSkin(skin, type) {
if (!skin || !skin.replace(/\s/g, '')) return [] if (!skin?.replace(/\s/g, '')) return []
switch (type) { switch (type) {
case 'ProgressBar': case 'ProgressBar':
return [skin, ...this.#progressBarSkin(skin)] return [skin, ...this.#progressBarSkin(skin)]
@@ -340,21 +340,14 @@ export default class UIManager {
scanResource(uiView) { scanResource(uiView) {
if (!uiView) return [] if (!uiView) return []
const resourceList = [] return [
this.#subSkin(uiView.props?.skin, uiView.type),
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type)) this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar'),
resourceList.push( this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar'),
...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar') uiView.child?.flatMap(child => this.scanResource(child)),
) ]
resourceList.push( .flat()
...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar') .filter(item => !!item)
)
uiView.child?.forEach(child => {
resourceList.push(...this.scanResource(child))
})
return resourceList
} }
get currentView() { get currentView() {
@@ -362,7 +355,7 @@ export default class UIManager {
} }
get currentDialog() { get currentDialog() {
return this.#dialogStack[this.#dialogStack.length - 1] return this.#dialogStack.at(-1)
} }
get theme() { get theme() {