From 567184b061fb95e6ee593bac4103ce20c4b54ec9 Mon Sep 17 00:00:00 2001 From: Ap_Tx <3045929398@qq.com> Date: Sun, 13 Sep 2026 13:41:58 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=B8=B8=E6=88=8F=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E8=87=AA=E5=8A=A8=E7=BD=AE=E9=A1=B6+=E8=81=9A?= =?UTF-8?q?=E7=84=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/app-frontend/package.json | 3 +- .../src/data/about/avatars/xiao-no-love.png | Bin 0 -> 1239 bytes .../src/data/about/contributors.json | 1459 +---------------- apps/app-frontend/src/data/about/index.ts | 10 +- apps/app/capabilities/core.json | 3 + apps/app/src/lightweight_mode.rs | 3 +- scripts/axolotl/sync-contributors.mjs | 114 -- tools/icon_work/fix_fg.py | 28 + tools/icon_work/fix_pkg.py | 22 + 9 files changed, 68 insertions(+), 1574 deletions(-) create mode 100644 apps/app-frontend/src/data/about/avatars/xiao-no-love.png delete mode 100644 scripts/axolotl/sync-contributors.mjs create mode 100644 tools/icon_work/fix_fg.py create mode 100644 tools/icon_work/fix_pkg.py diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json index fad9ba2..841746d 100644 --- a/apps/app-frontend/package.json +++ b/apps/app-frontend/package.json @@ -5,8 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "pnpm contributors:sync && vue-tsc --noEmit && vite build", - "contributors:sync": "node ../../scripts/axolotl/sync-contributors.mjs", + "build": "vue-tsc --noEmit && vite build", "tsc:check": "vue-tsc --noEmit", "lint": "eslint . && prettier --check .", "fix": "eslint . --fix && prettier --write .", diff --git a/apps/app-frontend/src/data/about/avatars/xiao-no-love.png b/apps/app-frontend/src/data/about/avatars/xiao-no-love.png new file mode 100644 index 0000000000000000000000000000000000000000..6194d9ec643957d503626fc0e24ffcdd59c9c920 GIT binary patch literal 1239 zcmeAS@N?(olHy`uVBq!ia0vp^DImG4kchxDKIImN7EOgSvThuW9KjAV zta}8Q1eY}!luIbGDETlZzB6#*aGAk$=uTpbK!*Wq%g)0b5Ce{XD`^k|;;F*qI^mi#sQgNC7| z%&o)BKQcZZc_IH+z2gg8=6ZfE&X#`{7Z$#)c-N8eqMY^7*T44l&h@8eWyU#kvOl<+#hmJ^GThez;ZbSUEM_0A3{ah%1 z-LiONTk5hr!{9rIZhc(jr;xS>WX_bO-IDv=J?=CGd`Pdk!}|7LUX1w)Q^&ssS-k<* z6|;B)*2nLZ%sz3%VqJGs*8an)ug*E#T9=z<=@|tKIa@(D4&@fj)9X#2RQ}c8asN`K z;03#($ zHz_9t7N9d`GmCS1FR->w7Twb9{PB;YZT^dYW=SST%kG~#RO)-b;o{d=)BJ;V1sMXj z-rC*y9mFmk@62%|!_ERowK&Y!R8s6zV1p;+U-ZV&_J&25q7F zvVL(>7{4vNSiIow*RR4`ij6m<9d&;kH`9Nkef6IUSDc)7-ukvy`0^B2g%u2q22NiD z&rM1F{Qg^>#mvQ_e}WFWzIe}ne;9*KUbxAWpRPk$W=?=Yu$8i@QehPXK zKYaqjTjA{K(rcYxMOh!%_vWs2#{Jv%0UwX^zJ1d2)p&QCK!@GZpL^Q`I2zBqo07V< z^wQ<-^lR)|`ppTEOSc;?uQphI|Ky#NFQ#hSkFkG?Z~Iu=|LM)*3-_ml^SqUxTj6H^ z_}eCqBj+`{1(QS$Ozz3mf5oE2bE13I^r-$T#;>;2dM3zETXKK4(cc}8a(`!5I7Ex{ z{9M6tK3VN=(2 ({ + ...contributor, + avatarUrl: teamAvatarModules[`./avatars/${contributor.avatar}`], +})) diff --git a/apps/app/capabilities/core.json b/apps/app/capabilities/core.json index 245e1c7..6b48c22 100644 --- a/apps/app/capabilities/core.json +++ b/apps/app/capabilities/core.json @@ -26,7 +26,10 @@ "core:window:allow-set-effects", "core:window:allow-set-cursor-grab", "core:window:allow-set-cursor-visible", + "core:window:allow-start-dragging", + "core:window:allow-set-always-on-top", + "core:window:allow-set-focus", "core:webview:allow-set-webview-zoom" ] } diff --git a/apps/app/src/lightweight_mode.rs b/apps/app/src/lightweight_mode.rs index 33704f5..fba37e7 100644 --- a/apps/app/src/lightweight_mode.rs +++ b/apps/app/src/lightweight_mode.rs @@ -354,7 +354,7 @@ unsafe extern "system" fn maximize_if_owned_by_process( _: windows::Win32::Foundation::LPARAM, ) -> windows::core::BOOL { use windows::Win32::UI::WindowsAndMessaging::{ - GetWindowThreadProcessId, IsWindowVisible, SW_MAXIMIZE, ShowWindow, + GetWindowThreadProcessId, IsWindowVisible, SW_MAXIMIZE, SetForegroundWindow, ShowWindow, }; use windows::core::BOOL; @@ -363,6 +363,7 @@ unsafe extern "system" fn maximize_if_owned_by_process( if window_pid == MAXIMIZE_PROCESS_ID.load(Ordering::Relaxed) && unsafe { IsWindowVisible(hwnd).as_bool() } { + let _ = unsafe { SetForegroundWindow(hwnd) }; let _ = unsafe { ShowWindow(hwnd, SW_MAXIMIZE) }; MAXIMIZE_WINDOW_FOUND.store(true, Ordering::Relaxed); return BOOL(0); diff --git a/scripts/axolotl/sync-contributors.mjs b/scripts/axolotl/sync-contributors.mjs deleted file mode 100644 index 1a428e6..0000000 --- a/scripts/axolotl/sync-contributors.mjs +++ /dev/null @@ -1,114 +0,0 @@ -import fs from 'node:fs/promises' -import { existsSync } from 'node:fs' -import { fileURLToPath } from 'node:url' - -const REPOSITORY = 'Mystic-Stars/Axolotl' -const PER_PAGE = 100 -const MAX_PAGES = 10 -const OUTPUT_PATH = fileURLToPath( - new URL('../../apps/app-frontend/src/data/about/contributors.json', import.meta.url), -) - -function requestHeaders() { - const headers = { - Accept: 'application/vnd.github+json', - 'User-Agent': 'Axolotl-Launcher-Contributors-Sync', - } - const token = process.env.AXOLOTL_GITHUB_TOKEN || process.env.GITHUB_TOKEN - if (token) { - headers.Authorization = `Bearer ${token}` - } - return headers -} - -async function fetchPage(page) { - const url = new URL(`https://api.github.com/repos/${REPOSITORY}/contributors`) - url.searchParams.set('per_page', String(PER_PAGE)) - url.searchParams.set('page', String(page)) - - let failure - for (let attempt = 1; attempt <= 3; attempt++) { - try { - const response = await fetch(url, { - headers: requestHeaders(), - signal: AbortSignal.timeout(30_000), - }) - if (!response.ok) throw new Error(`HTTP ${response.status}`) - return await response.json() - } catch (error) { - failure = error - if (attempt < 3) await new Promise((resolve) => setTimeout(resolve, attempt * 1_000)) - } - } - throw new Error(`Unable to fetch contributors from ${url}`, { cause: failure }) -} - -function normalizeContributor(contributor) { - if (!contributor || typeof contributor !== 'object' || Array.isArray(contributor)) - return undefined - if (typeof contributor.login !== 'string' || !contributor.login) return undefined - if (typeof contributor.html_url !== 'string' || !contributor.html_url) return undefined - if (typeof contributor.avatar_url !== 'string' || !contributor.avatar_url) return undefined - if (!Number.isInteger(contributor.contributions) || contributor.contributions < 1) - return undefined - - const avatarUrl = new URL(contributor.avatar_url) - avatarUrl.searchParams.set('s', '96') - - return { - name: contributor.login, - avatarUrl: avatarUrl.toString(), - url: contributor.html_url, - contributions: contributor.contributions, - } -} - -async function fetchContributors() { - const pages = [] - for (let page = 1; page <= MAX_PAGES; page++) { - const contributors = await fetchPage(page) - if (!Array.isArray(contributors)) throw new Error(`Page ${page} did not contain an array`) - pages.push(contributors) - if (contributors.length < PER_PAGE) break - } - - const contributors = pages - .flat() - .map(normalizeContributor) - .filter((contributor) => contributor !== undefined) - .sort( - (left, right) => - right.contributions - left.contributions || left.name.localeCompare(right.name), - ) - - if (contributors.length === 0) - throw new Error('The contributors response did not contain any people') - return contributors -} - -async function main() { - let contributors - try { - contributors = await fetchContributors() - } catch (error) { - if (existsSync(OUTPUT_PATH)) { - console.warn( - `Unable to refresh contributors, keeping the existing snapshot: ${error.message}`, - ) - return - } - throw error - } - - const nextText = `${JSON.stringify(contributors, null, '\t')}\n` - const currentText = existsSync(OUTPUT_PATH) ? await fs.readFile(OUTPUT_PATH, 'utf8') : '' - - if (currentText === nextText) { - console.log(`Contributors are up to date (${contributors.length} people).`) - return - } - - await fs.writeFile(OUTPUT_PATH, nextText) - console.log(`Synchronized ${contributors.length} contributors from ${REPOSITORY}.`) -} -await main() diff --git a/tools/icon_work/fix_fg.py b/tools/icon_work/fix_fg.py new file mode 100644 index 0000000..6ec9a2f --- /dev/null +++ b/tools/icon_work/fix_fg.py @@ -0,0 +1,28 @@ + +p = r"D:\Project\Starlight_Lancher\apps\app\src\lightweight_mode.rs" +t = open(p, encoding="utf-8").read() + +# 1) import 加 SetForegroundWindow +old_import = """ use windows::Win32::UI::WindowsAndMessaging::{ + GetWindowThreadProcessId, IsWindowVisible, SW_MAXIMIZE, ShowWindow, + };""" +new_import = """ use windows::Win32::UI::WindowsAndMessaging::{ + GetWindowThreadProcessId, IsWindowVisible, SW_MAXIMIZE, SetForegroundWindow, ShowWindow, + };""" +assert old_import in t, "找不到 import 块" +t = t.replace(old_import, new_import, 1) + +# 2) 最大化前先聚焦到前台 +old_show = " let _ = unsafe { ShowWindow(hwnd, SW_MAXIMIZE) };" +new_show = ( + " let _ = unsafe { SetForegroundWindow(hwnd) };\n" + " let _ = unsafe { ShowWindow(hwnd, SW_MAXIMIZE) };" +) +assert old_show in t, "找不到 ShowWindow 行" +t = t.replace(old_show, new_show, 1) + +open(p, "w", encoding="utf-8", newline="\n").write(t) +print("done") +l = t.split("\n") +for i in range(354, 372): + print(f"{i+1}: {l[i]}") diff --git a/tools/icon_work/fix_pkg.py b/tools/icon_work/fix_pkg.py new file mode 100644 index 0000000..d5bd30f --- /dev/null +++ b/tools/icon_work/fix_pkg.py @@ -0,0 +1,22 @@ + +p = r"D:\Project\Starlight_Lancher\apps\app-frontend\package.json" +t = open(p, encoding="utf-8").read() + +# 1) build 去掉 contributors:sync +t = t.replace( + '"build": "pnpm contributors:sync && vue-tsc --noEmit && vite build",', + '"build": "vue-tsc --noEmit && vite build",', +) +# 2) 删除 contributors:sync 那一行 +t = t.replace( + '\t\t"contributors:sync": "node ../../scripts/axolotl/sync-contributors.mjs",\n', + "", +) +open(p, "w", encoding="utf-8", newline="\n").write(t) + +import json +json.load(open(p, encoding="utf-8")) # 校验合法 +print("done") +l = t.split("\n") +for i in range(5, 13): + print(f"{i+1}: {l[i]}")