From 28496b35f3a4006bd0e712c6cb6644b01702efb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ACT=E4=B8=B6=E6=B5=81=E6=98=9F=E9=9B=A8?= <1340145680@qq.com> Date: Tue, 7 Apr 2026 02:48:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/web/index.html | 1542 +++++++++++++++++++++---------------------- scripts/main.ts | 54 +- 2 files changed, 821 insertions(+), 775 deletions(-) diff --git a/data/web/index.html b/data/web/index.html index 8374469..aeb382d 100644 --- a/data/web/index.html +++ b/data/web/index.html @@ -5,27 +5,27 @@ Toonflow - - + `),tNs=/enable|requires|diagnostic/,Cvn=new RegExp("[_\\p{XID_Start}]\\p{XID_Continue}*","u"),dF="variable.predefined",nNs={tokenPostfix:".wgsl",defaultToken:"invalid",unicode:!0,atoms:$Fs,keywords:XFs,reserved:GFs,predeclared_enums:YFs,predeclared_types:ZFs,predeclared_type_generators:qFs,predeclared_type_aliases:KFs,predeclared_intrinsics:JFs,operators:eNs,symbols:/[!%&*+\-\.\/:;<=>^|_~,]+/,tokenizer:{root:[[tNs,"keyword","@directive"],[Cvn,{cases:{"@atoms":dF,"@keywords":"keyword","@reserved":"invalid","@predeclared_enums":dF,"@predeclared_types":dF,"@predeclared_type_generators":dF,"@predeclared_type_aliases":dF,"@predeclared_intrinsics":dF,"@default":"identifier"}}],{include:"@commentOrSpace"},{include:"@numbers"},[/[{}()\[\]]/,"@brackets"],["@","annotation","@attribute"],[/@symbols/,{cases:{"@operators":"operator","@default":"delimiter"}}],[/./,"invalid"]],commentOrSpace:[[/\s+/,"white"],[/\/\*/,"comment","@blockComment"],[/\/\/.*$/,"comment"]],blockComment:[[/[^\/*]+/,"comment"],[/\/\*/,"comment","@push"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],attribute:[{include:"@commentOrSpace"},[/\w+/,"annotation","@pop"]],directive:[{include:"@commentOrSpace"},[/[()]/,"@brackets"],[/,/,"delimiter"],[Cvn,"meta.content"],[/;/,"delimiter","@pop"]],numbers:[[/0[fh]/,"number.float"],[/[1-9][0-9]*[fh]/,"number.float"],[/[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[fh]?/,"number.float"],[/[0-9]+\.[0-9]*([eE][+-]?[0-9]+)?[fh]?/,"number.float"],[/[0-9]+[eE][+-]?[0-9]+[fh]?/,"number.float"],[/0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+(?:[pP][+-]?[0-9]+[fh]?)?/,"number.hex"],[/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*(?:[pP][+-]?[0-9]+[fh]?)?/,"number.hex"],[/0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?/,"number.hex"],[/0[xX][0-9a-fA-F]+[iu]?/,"number.hex"],[/[1-9][0-9]*[iu]?/,"number"],[/0[iu]?/,"number"]]}},iNs=Object.freeze(Object.defineProperty({__proto__:null,conf:HFs,language:nNs},Symbol.toStringTag,{value:"Module"})),rNs={comments:{blockComment:["\x3C!--","-->"]},brackets:[["<",">"]],autoClosingPairs:[{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}],surroundingPairs:[{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}],onEnterRules:[{beforeText:new RegExp("<([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$","i"),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:Tt.IndentAction.IndentOutdent}},{beforeText:new RegExp("<(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$","i"),action:{indentAction:Tt.IndentAction.Indent}}]},oNs={defaultToken:"",tokenPostfix:".xml",ignoreCase:!0,qualifiedName:/(?:[\w\.\-]+:)?[\w\.\-]+/,tokenizer:{root:[[/[^<&]+/,""],{include:"@whitespace"},[/(<)(@qualifiedName)/,[{token:"delimiter"},{token:"tag",next:"@tag"}]],[/(<\/)(@qualifiedName)(\s*)(>)/,[{token:"delimiter"},{token:"tag"},"",{token:"delimiter"}]],[/(<\?)(@qualifiedName)/,[{token:"delimiter"},{token:"metatag",next:"@tag"}]],[/(<\!)(@qualifiedName)/,[{token:"delimiter"},{token:"metatag",next:"@tag"}]],[/<\!\[CDATA\[/,{token:"delimiter.cdata",next:"@cdata"}],[/&\w+;/,"string.escape"]],cdata:[[/[^\]]+/,""],[/\]\]>/,{token:"delimiter.cdata",next:"@pop"}],[/\]/,""]],tag:[[/[ \t\r\n]+/,""],[/(@qualifiedName)(\s*=\s*)("[^"]*"|'[^']*')/,["attribute.name","","attribute.value"]],[/(@qualifiedName)(\s*=\s*)("[^">?\/]*|'[^'>?\/]*)(?=[\?\/]\>)/,["attribute.name","","attribute.value"]],[/(@qualifiedName)(\s*=\s*)("[^">]*|'[^'>]*)/,["attribute.name","","attribute.value"]],[/@qualifiedName/,"attribute.name"],[/\?>/,{token:"delimiter",next:"@pop"}],[/(\/)(>)/,[{token:"tag"},{token:"delimiter",next:"@pop"}]],[/>/,{token:"delimiter",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/\x3C!--/,{token:"comment",next:"@comment"}]],comment:[[/[^<\-]+/,"comment.content"],[/-->/,{token:"comment",next:"@pop"}],[/\x3C!--/,"comment.content.invalid"],[/[<\-]/,"comment.content"]]}},sNs=Object.freeze(Object.defineProperty({__proto__:null,conf:rNs,language:oNs},Symbol.toStringTag,{value:"Module"})),aNs={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{offSide:!0},onEnterRules:[{beforeText:/:\s*$/,action:{indentAction:Tt.IndentAction.Indent}}]},lNs={tokenPostfix:".yaml",brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.square",open:"[",close:"]"}],keywords:["true","True","TRUE","false","False","FALSE","null","Null","Null","~"],numberInteger:/(?:0|[+-]?[0-9]+)/,numberFloat:/(?:0|[+-]?[0-9]+)(?:\.[0-9]+)?(?:e[-+][1-9][0-9]*)?/,numberOctal:/0o[0-7]+/,numberHex:/0x[0-9a-fA-F]+/,numberInfinity:/[+-]?\.(?:inf|Inf|INF)/,numberNaN:/\.(?:nan|Nan|NAN)/,numberDate:/\d{4}-\d\d-\d\d([Tt ]\d\d:\d\d:\d\d(\.\d+)?(( ?[+-]\d\d?(:\d\d)?)|Z)?)?/,escapes:/\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,tokenizer:{root:[{include:"@whitespace"},{include:"@comment"},[/%[^ ]+.*$/,"meta.directive"],[/---/,"operators.directivesEnd"],[/\.{3}/,"operators.documentEnd"],[/[-?:](?= )/,"operators"],{include:"@anchor"},{include:"@tagHandle"},{include:"@flowCollections"},{include:"@blockStyle"},[/@numberInteger(?![ \t]*\S+)/,"number"],[/@numberFloat(?![ \t]*\S+)/,"number.float"],[/@numberOctal(?![ \t]*\S+)/,"number.octal"],[/@numberHex(?![ \t]*\S+)/,"number.hex"],[/@numberInfinity(?![ \t]*\S+)/,"number.infinity"],[/@numberNaN(?![ \t]*\S+)/,"number.nan"],[/@numberDate(?![ \t]*\S+)/,"number.date"],[/(".*?"|'.*?'|[^#'"]*?)([ \t]*)(:)( |$)/,["type","white","operators","white"]],{include:"@flowScalars"},[/.+?(?=(\s+#|$))/,{cases:{"@keywords":"keyword","@default":"string"}}]],object:[{include:"@whitespace"},{include:"@comment"},[/\}/,"@brackets","@pop"],[/,/,"delimiter.comma"],[/:(?= )/,"operators"],[/(?:".*?"|'.*?'|[^,\{\[]+?)(?=: )/,"type"],{include:"@flowCollections"},{include:"@flowScalars"},{include:"@tagHandle"},{include:"@anchor"},{include:"@flowNumber"},[/[^\},]+/,{cases:{"@keywords":"keyword","@default":"string"}}]],array:[{include:"@whitespace"},{include:"@comment"},[/\]/,"@brackets","@pop"],[/,/,"delimiter.comma"],{include:"@flowCollections"},{include:"@flowScalars"},{include:"@tagHandle"},{include:"@anchor"},{include:"@flowNumber"},[/[^\],]+/,{cases:{"@keywords":"keyword","@default":"string"}}]],multiString:[[/^( +).+$/,"string","@multiStringContinued.$1"]],multiStringContinued:[[/^( *).+$/,{cases:{"$1==$S2":"string","@default":{token:"@rematch",next:"@popall"}}}]],whitespace:[[/[ \t\r\n]+/,"white"]],comment:[[/#.*$/,"comment"]],flowCollections:[[/\[/,"@brackets","@array"],[/\{/,"@brackets","@object"]],flowScalars:[[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/'[^']*'/,"string"],[/"/,"string","@doubleQuotedString"]],doubleQuotedString:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],blockStyle:[[/[>|][0-9]*[+-]?$/,"operators","@multiString"]],flowNumber:[[/@numberInteger(?=[ \t]*[,\]\}])/,"number"],[/@numberFloat(?=[ \t]*[,\]\}])/,"number.float"],[/@numberOctal(?=[ \t]*[,\]\}])/,"number.octal"],[/@numberHex(?=[ \t]*[,\]\}])/,"number.hex"],[/@numberInfinity(?=[ \t]*[,\]\}])/,"number.infinity"],[/@numberNaN(?=[ \t]*[,\]\}])/,"number.nan"],[/@numberDate(?=[ \t]*[,\]\}])/,"number.date"]],tagHandle:[[/\![^ ]*/,"tag"]],anchor:[[/[&*][^ ]+/,"namespace"]]}},cNs=Object.freeze(Object.defineProperty({__proto__:null,conf:aNs,language:lNs},Symbol.toStringTag,{value:"Module"})); +
diff --git a/scripts/main.ts b/scripts/main.ts index 0881c71..873c506 100644 --- a/scripts/main.ts +++ b/scripts/main.ts @@ -19,14 +19,60 @@ function copyDir(src: string, dest: string): void { } } +declare const __APP_VERSION__: string; + +function compareVersions(a: string, b: string): number { + const pa = a + .split(".") + .map((n) => Number.parseInt(n, 10)) + .filter((n) => Number.isFinite(n)); + const pb = b + .split(".") + .map((n) => Number.parseInt(n, 10)) + .filter((n) => Number.isFinite(n)); + const len = Math.max(pa.length, pb.length); + for (let i = 0; i < len; i++) { + const va = pa[i] ?? 0; + const vb = pb[i] ?? 0; + if (va > vb) return 1; + if (va < vb) return -1; + } + return 0; +} + function initializeData(): void { const srcDir = path.join(process.resourcesPath, "data"); const destDir = path.join(app.getPath("userData"), "data"); - for (const dir of TARGET_ENTRIES) { - if (!fs.existsSync(path.join(destDir, dir))) { - copyDir(path.join(srcDir, dir), path.join(destDir, dir)); + const versionFilePath = path.join(destDir, "version.txt"); + + let shouldForceReplace = false; + if (!fs.existsSync(versionFilePath)) { + shouldForceReplace = true; + } else { + const localVersion = fs.readFileSync(versionFilePath, "utf-8").trim(); + if (compareVersions(localVersion, __APP_VERSION__) < 0) { + shouldForceReplace = true; } } + + console.log("%c Line:55 🍕 shouldForceReplace", "background:#2eafb0", shouldForceReplace); + + for (const dir of TARGET_ENTRIES) { + const targetDir = path.join(destDir, dir); + if (shouldForceReplace) { + fs.rmSync(targetDir, { recursive: true, force: true }); + copyDir(path.join(srcDir, dir), targetDir); + continue; + } + if (!fs.existsSync(targetDir)) { + copyDir(path.join(srcDir, dir), targetDir); + } + } + + if (shouldForceReplace) { + fs.mkdirSync(destDir, { recursive: true }); + fs.writeFileSync(versionFilePath, `${__APP_VERSION__}\n`, "utf-8"); + } } //获取全部依赖路径,优先从 unpacked 加载原生模块,其他模块从 asar 加载 @@ -206,7 +252,7 @@ app.whenReady().then(async () => { const url = new URL(request.url); const pathname = url.hostname.toLowerCase(); const handlers: Record object> = { - getport: () => ({ port: port }), + getappurl: () => ({ url: process.env.URL ?? `http://localhost:${port}/api` }), windowminimize: () => { mainWindow?.minimize(); return { ok: true };