From 3ba51fd6fed3bd0e9cae57b045ffdf52d5f8045d Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 25 Nov 2023 12:19:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=BA=90=E5=88=97?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=BA=90=E7=89=88=E6=9C=AC=E5=8F=B7=E3=80=81?= =?UTF-8?q?=E4=BD=9C=E8=80=85=E5=90=8D=E5=AD=97=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=BA=90=E8=84=9A=E6=9C=AC=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/common/types/user_api.d.ts | 4 +- src/main/modules/userApi/config/index.ts | 2 +- src/main/modules/userApi/index.ts | 4 +- src/main/modules/userApi/main.ts | 7 +- src/main/modules/userApi/utils.ts | 84 ++++++++++++++++--- .../views/Setting/components/UserApiModal.vue | 12 ++- 7 files changed, 94 insertions(+), 20 deletions(-) diff --git a/publish/changeLog.md b/publish/changeLog.md index 848219e6..0c9260a7 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -15,6 +15,7 @@ ### 优化 - 更新zh-tw翻译 +- 自定义源列显示源版本号、作者名字 ### 修复 diff --git a/src/common/types/user_api.d.ts b/src/common/types/user_api.d.ts index 264e55ab..e39ece72 100644 --- a/src/common/types/user_api.d.ts +++ b/src/common/types/user_api.d.ts @@ -13,7 +13,7 @@ declare namespace LX { type UserApiSources = Record - interface UserApiInfo { + interface UserApiInfoFull { id: string name: string description: string @@ -25,6 +25,8 @@ declare namespace LX { sources?: UserApiSources } + type UserApiInfo = Omit + interface UserApiStatus { status: boolean message?: string diff --git a/src/main/modules/userApi/config/index.ts b/src/main/modules/userApi/config/index.ts index 20618225..9433e68e 100644 --- a/src/main/modules/userApi/config/index.ts +++ b/src/main/modules/userApi/config/index.ts @@ -1,2 +1,2 @@ -export const userApis: LX.UserApi.UserApiInfo[] = [] +export const userApis: LX.UserApi.UserApiInfoFull[] = [] diff --git a/src/main/modules/userApi/index.ts b/src/main/modules/userApi/index.ts index c3ee6165..fe26d396 100644 --- a/src/main/modules/userApi/index.ts +++ b/src/main/modules/userApi/index.ts @@ -6,9 +6,9 @@ let userApiId: string | null export const getApiList = getUserApis -export const importApi = (script: string): LX.UserApi.ImportUserApi => { +export const importApi = async(script: string): Promise => { return { - apiInfo: handleImportApi(script), + apiInfo: await handleImportApi(script), apiList: getUserApis(), } } diff --git a/src/main/modules/userApi/main.ts b/src/main/modules/userApi/main.ts index d1561cc4..50cb6834 100644 --- a/src/main/modules/userApi/main.ts +++ b/src/main/modules/userApi/main.ts @@ -5,6 +5,7 @@ import path from 'node:path' import { openDevTools as handleOpenDevTools } from '@main/utils' import { encodePath } from '@common/utils/electron' import USER_API_RENDERER_EVENT_NAME from './rendererEvent/name' +import { getScript } from './utils' let browserWindow: Electron.BrowserWindow | null = null @@ -91,8 +92,8 @@ export const createWindow = async(userApi: LX.UserApi.UserApiInfo) => { // const randomNum = Math.random().toString().substring(2, 10) await browserWindow.loadURL('data:text/html;charset=UTF-8,' + encodeURIComponent(html)) - browserWindow.on('ready-to-show', () => { - sendEvent(USER_API_RENDERER_EVENT_NAME.initEnv, userApi) + browserWindow.on('ready-to-show', async() => { + sendEvent(USER_API_RENDERER_EVENT_NAME.initEnv, { ...userApi, script: await getScript(userApi.id) }) }) // global.modules.userApiWindow.loadFile(join(dir, 'renderer/user-api.html')) @@ -106,7 +107,7 @@ export const closeWindow = async() => { browserWindow.webContents.session.clearStorageData(), browserWindow.webContents.session.clearCache(), ]) - browserWindow.destroy() + browserWindow?.destroy() browserWindow = null } diff --git a/src/main/modules/userApi/utils.ts b/src/main/modules/userApi/utils.ts index 0d695f6d..1bc358c5 100644 --- a/src/main/modules/userApi/utils.ts +++ b/src/main/modules/userApi/utils.ts @@ -1,20 +1,52 @@ import { userApis as defaultUserApis } from './config' import { STORE_NAMES } from '@common/constants' import getStore from '@main/utils/store' +import zlib from 'node:zlib' let userApis: LX.UserApi.UserApiInfo[] | null +let scripts = new Map() + +const saveData = () => { + getStore(STORE_NAMES.USER_API).set('userApis', userApis!.map(api => { + return { + ...api, + script: scripts.get(api.id), + } + })) +} export const getUserApis = (): LX.UserApi.UserApiInfo[] => { - const electronStore_userApi = getStore(STORE_NAMES.USER_API) if (userApis) return userApis - userApis = electronStore_userApi.get('userApis') as LX.UserApi.UserApiInfo[] - if (!userApis) { - userApis = defaultUserApis + + const electronStore_userApi = getStore(STORE_NAMES.USER_API) + let infoFull = electronStore_userApi.get('userApis') as LX.UserApi.UserApiInfoFull[] + let requiredUpdate = false + if (infoFull) { + for (let i = 0; i < infoFull.length; i++) { + const api = infoFull[i] + if (api.version != null) continue + requiredUpdate ||= true + try { + infoFull.splice(i, 1, { + ...parseScriptInfo(api.script), + ...api, + }) + } catch (e) { + infoFull.splice(i, 1) + i-- + } + } + } else { + infoFull = defaultUserApis electronStore_userApi.set('userApis', userApis) } - for (const api of userApis) { + userApis = infoFull.map(api => { if (api.allowShowUpdateAlert == null) api.allowShowUpdateAlert = false - } + const { script, ...info } = api + scripts.set(api.id, script) + return info + }) + if (requiredUpdate) saveData() return userApis } @@ -46,22 +78,47 @@ const matchInfo = (scriptInfo: string) => { return infos as Record } -export const importApi = (script: string): LX.UserApi.UserApiInfo => { +const parseScriptInfo = (script: string) => { const result = /^\/\*[\S|\s]+?\*\//.exec(script) if (!result) throw new Error('无效的自定义源文件') let scriptInfo = matchInfo(result[0]) scriptInfo.name ||= `user_api_${new Date().toLocaleString()}` + return scriptInfo +} +const deflateScript = async(script: string) => new Promise((resolve, reject) => { + zlib.deflate(Buffer.from(script, 'utf8'), (err, buf) => { + if (err) { + reject(err) + return + } + resolve('gz_' + buf.toString('base64')) + }) +}) +const inflateScript = async(script: string) => new Promise((resolve, reject) => { + if (script.startsWith('gz_')) { + zlib.inflate(Buffer.from(script.substring(3), 'base64'), (err, buf) => { + if (err) { + reject(err) + return + } + resolve(buf.toString('utf8')) + }) + } else resolve(script) +}) +export const importApi = async(scriptRaw: string): Promise => { + let scriptInfo = parseScriptInfo(scriptRaw) const apiInfo = { id: `user_api_${Math.random().toString().substring(2, 5)}_${Date.now()}`, ...scriptInfo, - script, allowShowUpdateAlert: true, } userApis ??= [] userApis.push(apiInfo) - getStore(STORE_NAMES.USER_API).set('userApis', userApis) + const script = await deflateScript(scriptRaw) + scripts.set(apiInfo.id, script) + saveData() return apiInfo } @@ -69,16 +126,21 @@ export const removeApi = (ids: string[]) => { if (!userApis) return for (let index = userApis.length - 1; index > -1; index--) { if (ids.includes(userApis[index].id)) { + scripts.delete(userApis[index].id) userApis.splice(index, 1) ids.splice(index, 1) } } - getStore(STORE_NAMES.USER_API).set('userApis', userApis) + saveData() } export const setAllowShowUpdateAlert = (id: string, enable: boolean) => { const targetApi = userApis?.find(api => api.id == id) if (!targetApi) return targetApi.allowShowUpdateAlert = enable - getStore(STORE_NAMES.USER_API).set('userApis', userApis) + saveData() +} + +export const getScript = async(id: string) => { + return inflateScript(scripts.get(id) ?? '') } diff --git a/src/renderer/views/Setting/components/UserApiModal.vue b/src/renderer/views/Setting/components/UserApiModal.vue index 1ee6fbb3..70361d8e 100644 --- a/src/renderer/views/Setting/components/UserApiModal.vue +++ b/src/renderer/views/Setting/components/UserApiModal.vue @@ -5,7 +5,10 @@ material-modal(:show="modelValue" bg-close teleport="#view" @close="handleClose" ul.scroll(v-if="apiList.length" :class="$style.content") li(v-for="(api, index) in apiList" :key="api.id" :class="[$style.listItem, {[$style.active]: appSetting['common.apiSource'] == api.id}]") div(:class="$style.listLeft") - h3 {{ api.name }} + h3 + | {{ api.name }} + span(v-if="api.version") {{ /^\d/.test(api.version) ? `v${api.version}` : api.version }} + span(v-if="api.author") {{ api.author }} p {{ api.description }} div base-checkbox(:id="`user_api_${api.id}`" v-model="api.allowShowUpdateAlert" :class="$style.checkbox" :label="$t('user_api__allow_show_update_alert')" @change="handleChangeAllowUpdateAlert(api, $event)") @@ -145,7 +148,7 @@ export default { flex-flow: row nowrap; align-items: center; transition: background-color 0.2s ease; - padding: 10px; + padding: 15px 10px; border-radius: @radius-border; &:hover { background-color: var(--color-primary-background-hover); @@ -157,6 +160,11 @@ export default { font-size: 15px; color: var(--color-font); word-break: break-all; + span { + font-size: 12px; + color: var(--color-font-label); + margin-left: 6px; + } } p { margin-top: 5px;