From e21a9db070ef0a9ebf6f99385bf3dfa4ea49231d Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 04:56:53 +0800 Subject: [PATCH 1/6] Change settingsContainer to define api --- src/components/settings-panel/index.ts | 110 +++++++++++++------------ 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/src/components/settings-panel/index.ts b/src/components/settings-panel/index.ts index bf3ac9594..bf806f9bb 100644 --- a/src/components/settings-panel/index.ts +++ b/src/components/settings-panel/index.ts @@ -4,7 +4,8 @@ import { TextColor } from '@/core/text-color' import { CdnTypes } from '@/core/cdn-types' import { addComponentListener } from '@/core/settings' import { DownloadPackageEmitMode } from '@/core/download-mode' -import { ComponentEntry, ComponentMetadata, componentsTags } from '../types' +import { ComponentEntry, componentsTags } from '../types' +import { defineOptionsMetadata, defineComponentMetadata } from '../define' import { provideActions } from './external-actions' import description from './desc.md' @@ -14,7 +15,57 @@ export enum SettingsPanelDockSide { Right = '右侧', } -const entry: ComponentEntry = async ({ metadata }) => { +const options = defineOptionsMetadata({ + themeColor: { + defaultValue: '#00A0D8', + displayName: '主题颜色', + color: true, + }, + scriptLoadingMode: { + defaultValue: LoadingMode.Delay, + displayName: '功能加载模式', + dropdownEnum: LoadingMode, + }, + styleLoadingMode: { + defaultValue: LoadingMode.Race, + displayName: '样式加载模式', + dropdownEnum: LoadingMode, + }, + textColor: { + defaultValue: TextColor.Auto, + displayName: '文本颜色', + dropdownEnum: TextColor, + }, + cdnRoot: { + defaultValue: CdnTypes.jsDelivr, + displayName: '更新源', + dropdownEnum: CdnTypes, + }, + dockSide: { + defaultValue: SettingsPanelDockSide.Left, + displayName: '设置面板停靠', + dropdownEnum: SettingsPanelDockSide, + }, + filenameFormat: { + defaultValue: '[title][ - ep]', + displayName: '文件命名格式', + }, + batchFilenameFormat: { + defaultValue: '[n - ][ep]', + displayName: '批量命名格式', + }, + downloadPackageEmitMode: { + defaultValue: DownloadPackageEmitMode.Packed, + displayName: '文件下载模式', + dropdownEnum: DownloadPackageEmitMode, + }, + devMode: { + defaultValue: false, + displayName: '开发者模式', + }, +}) + +const entry: ComponentEntry = async ({ metadata }) => { const { isIframe } = await import('@/core/utils') if (isIframe()) { return @@ -28,61 +79,14 @@ const entry: ComponentEntry = async ({ metadata }) => { document.body.insertAdjacentElement('beforeend', instance.$el) }) } -export const component: ComponentMetadata = { + +export const component = defineComponentMetadata({ name: 'settingsPanel', displayName: '通用设置', configurable: false, description, entry, - options: { - themeColor: { - defaultValue: '#00A0D8', - displayName: '主题颜色', - color: true, - }, - scriptLoadingMode: { - defaultValue: LoadingMode.Delay, - displayName: '功能加载模式', - dropdownEnum: LoadingMode, - }, - styleLoadingMode: { - defaultValue: LoadingMode.Race, - displayName: '样式加载模式', - dropdownEnum: LoadingMode, - }, - textColor: { - defaultValue: TextColor.Auto, - displayName: '文本颜色', - dropdownEnum: TextColor, - }, - cdnRoot: { - defaultValue: CdnTypes.jsDelivr, - displayName: '更新源', - dropdownEnum: CdnTypes, - }, - dockSide: { - defaultValue: SettingsPanelDockSide.Left, - displayName: '设置面板停靠', - dropdownEnum: SettingsPanelDockSide, - }, - filenameFormat: { - defaultValue: '[title][ - ep]', - displayName: '文件命名格式', - }, - batchFilenameFormat: { - defaultValue: '[n - ][ep]', - displayName: '批量命名格式', - }, - downloadPackageEmitMode: { - defaultValue: DownloadPackageEmitMode.Packed, - displayName: '文件下载模式', - dropdownEnum: DownloadPackageEmitMode, - }, - devMode: { - defaultValue: false, - displayName: '开发者模式', - }, - }, + options, tags: [componentsTags.general], i18n: { 'en-US': { @@ -103,4 +107,4 @@ export const component: ComponentMetadata = { provideActions() }, }, -} +}) From 2cbebd7d95f65e008b54b6bacdae50eae92d4f82 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 13:10:58 +0800 Subject: [PATCH 2/6] Change launchBar to define api --- src/components/launch-bar/index.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/launch-bar/index.ts b/src/components/launch-bar/index.ts index eecdb3976..54c4b7353 100644 --- a/src/components/launch-bar/index.ts +++ b/src/components/launch-bar/index.ts @@ -1,16 +1,14 @@ import { none } from '@/core/utils' -import { ComponentMetadata, componentsTags } from '../types' +import { defineComponentMetadata } from '@/components/define' +import { componentsTags } from '../types' import { plugin } from './plugin' -export const component: ComponentMetadata = { +export const component = defineComponentMetadata({ name: 'launchBar', displayName: '搜索栏', configurable: false, entry: none, plugin, hidden: true, - tags: [ - componentsTags.general, - componentsTags.utils, - ], -} + tags: [componentsTags.general, componentsTags.utils], +}) From cf9ac6f8496c7a546039773662fc199b48d656a5 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:26:50 +0800 Subject: [PATCH 3/6] Change i18n to define api --- src/components/i18n/index.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/i18n/index.ts b/src/components/i18n/index.ts index b14571a4d..4da067062 100644 --- a/src/components/i18n/index.ts +++ b/src/components/i18n/index.ts @@ -1,9 +1,13 @@ import { defaultLanguageCode, languageCodeToName } from '@/core/utils/i18n' -import { ComponentMetadata, componentsTags } from '../types' -import { translateProviderNames, translateProviders } from './machine-translator/translators' +import { defineComponentMetadata } from '@/components/define' +import { componentsTags } from '../types' +import { + translateProviderNames, + translateProviders, +} from './machine-translator/translators' import { startTranslate } from './dom-translator' -export const component: ComponentMetadata = { +export const component = defineComponentMetadata({ name: 'i18n', displayName: '多语言', configurable: false, @@ -14,7 +18,8 @@ export const component: ComponentMetadata = { componentsTags.general, ], description: { - 'zh-CN': '安装其他语言包可以更换界面语言, 机器翻译选择可以设定其他一些功能如`动态翻译`, `评论翻译`使用的翻译器. 机器翻译的选择不影响界面语言.', + 'zh-CN': + '安装其他语言包可以更换界面语言, 机器翻译选择可以设定其他一些功能如`动态翻译`, `评论翻译`使用的翻译器. 机器翻译的选择不影响界面语言.', }, options: { language: { @@ -30,4 +35,4 @@ export const component: ComponentMetadata = { }, // 相关功能好像全挂了, 先隐藏了 hidden: true, -} +}) From c68acc079d7b7ef88aeaebe7739ecc126c0218eb Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 18:58:51 +0800 Subject: [PATCH 4/6] Change autoUpdate to define api --- src/components/auto-update/index.ts | 190 ++++++++++++++++------------ 1 file changed, 107 insertions(+), 83 deletions(-) diff --git a/src/components/auto-update/index.ts b/src/components/auto-update/index.ts index 2d2fbce14..74a0ff5a7 100644 --- a/src/components/auto-update/index.ts +++ b/src/components/auto-update/index.ts @@ -1,11 +1,16 @@ -import { ComponentMetadata, componentsTags } from '@/components/types' +import { ComponentEntry, componentsTags } from '@/components/types' import { meta } from '@/core/meta' import { - getGeneralSettings, getComponentSettings, + getGeneralSettings, isUserComponent, } from '@/core/settings' import { Version } from '@/core/version' +import { + defineComponentMetadata, + defineOptionsMetadata, + OptionsOfMetadata, +} from '@/components/define' import { LaunchBarActionProvider } from '../launch-bar/launch-bar-action' import { ComponentAction } from '../settings-panel/component-actions/component-actions' import { isLocalItem, name, UpdateCheckItem } from './utils' @@ -19,68 +24,78 @@ const { silentCheckUpdate, } = checkerMethods -export const component: ComponentMetadata = { +const optionsMetadata = defineOptionsMetadata({ + lastUpdateCheck: { + displayName: '最后检查更新日期', + defaultValue: 0, + hidden: true, + }, + lastInstalledVersion: { + displayName: '最后安装版本', + defaultValue: '2.0.0', + hidden: true, + }, + localPortOverride: { + displayName: '本地组件链接端口', + defaultValue: '', + hidden: true, + }, + minimumDuration: { + displayName: '更新间隔 (ms)', + defaultValue: 1000 * 3600 * 24, + }, + urls: { + displayName: '更新链接', + defaultValue: { + components: {} as Record, + plugins: {} as Record, + styles: {} as Record, + }, + hidden: true, + }, + maxUpdateCount: { + displayName: '单次最大更新量 (个)', + defaultValue: 4, + // hidden: true, + }, +}) + +const entry: ComponentEntry = async ({ + settings: { options: opt }, +}) => { + const now = Number(new Date()) + const duration = now - opt.lastUpdateCheck + + const isDurationExceeded = duration >= opt.minimumDuration + const isVersionOutdated = new Version(meta.version).greaterThan( + new Version(opt.lastInstalledVersion), + ) + if (isDurationExceeded) { + coreApis.lifeCycle.fullyLoaded(() => silentCheckUpdate()) + } else if (isVersionOutdated) { + coreApis.lifeCycle.fullyLoaded(() => forceCheckUpdate()) + } + + return checkerMethods +} + +type Options = OptionsOfMetadata + +export const component = defineComponentMetadata({ name, displayName: '自动更新器', description: { 'zh-CN': '自动检查组件, 插件和样式的更新. (仅限从设置面板中安装的)', }, tags: [componentsTags.utils], - options: { - lastUpdateCheck: { - displayName: '最后检查更新日期', - defaultValue: 0, - hidden: true, - }, - lastInstalledVersion: { - displayName: '最后安装版本', - defaultValue: '2.0.0', - hidden: true, - }, - localPortOverride: { - displayName: '本地组件链接端口', - defaultValue: '', - hidden: true, - }, - minimumDuration: { - displayName: '更新间隔 (ms)', - defaultValue: 1000 * 3600 * 24, - }, - urls: { - displayName: '更新链接', - defaultValue: { - components: {}, - plugins: {}, - styles: {}, - }, - hidden: true, - }, - maxUpdateCount: { - displayName: '单次最大更新量 (个)', - defaultValue: 4, - // hidden: true, - }, - }, + options: optionsMetadata, extraOptions: () => import('./ExtraOptions.vue').then(m => m.default), - entry: async ({ settings: { options } }) => { - const now = Number(new Date()) - const duration = now - options.lastUpdateCheck - - const isDurationExceeded = duration >= options.minimumDuration - const isVersionOutdated = new Version(meta.version) - .greaterThan(new Version(options.lastInstalledVersion)) - if (isDurationExceeded) { - coreApis.lifeCycle.fullyLoaded(() => silentCheckUpdate()) - } else if (isVersionOutdated) { - coreApis.lifeCycle.fullyLoaded(() => forceCheckUpdate()) - } - - return checkerMethods - }, + entry, plugin: { displayName: '自动更新器 - 功能扩展', description: { - 'zh-CN': '记录在设置面板中的功能安装/卸载数据供自动更新使用; 并在组件详情中支持手动检查该组件的更新.', + 'zh-CN': + '记录在设置面板中的功能安装/卸载数据供自动更新使用; 并在组件详情中支持手动检查该组件的更新.', }, // 非设置面板的组件如果也对能功能进行修改, 建议调用此处的 Hooks 同步状态. setup: ({ addData, addHook }) => { @@ -90,7 +105,9 @@ export const component: ComponentMetadata = { after: (_, url: string, metadata: { name: string }) => { // console.log('hook', `user${lodash.startCase(type)}.add`, metadata.name, url) const { options } = getComponentSettings('autoUpdate') - const existingItem = options.urls[type][metadata.name] as UpdateCheckItem + const existingItem = options.urls[type][ + metadata.name + ] as UpdateCheckItem if (!existingItem) { options.urls[type][metadata.name] = { url, @@ -116,32 +133,36 @@ export const component: ComponentMetadata = { }, }) }) - addData('settingsPanel.componentActions', (actions: ComponentAction[]) => { - const { options } = getComponentSettings('autoUpdate') - actions.push(metadata => { - const item = options.urls.components[metadata.name] as UpdateCheckItem - if (!item) { - return undefined - } - return { - name: 'checkUpdate', - displayName: '检查更新', - icon: isLocalItem(item.url) ? 'mdi-file-download-outline' : 'mdi-cloud-download-outline', - condition: () => isUserComponent(metadata), - title: item.url, - action: async () => { - const { Toast } = await import('@/core/toast') - const toast = Toast.info('检查更新中...', '检查更新') - const result = await checkComponentsUpdate({ - filterNames: [metadata.name], - force: true, - }) - toast.message = result - toast.duration = 3000 - }, - } - }) - }) + addData( + 'settingsPanel.componentActions', + (actions: ComponentAction[]) => { + const { options } = getComponentSettings('autoUpdate') + actions.push(metadata => { + const item = options.urls.components[metadata.name] + if (!item) { + return undefined + } + return { + name: 'checkUpdate', + displayName: '检查更新', + icon: isLocalItem(item.url) + ? 'mdi-file-download-outline' + : 'mdi-cloud-download-outline', + condition: () => isUserComponent(metadata), + title: item.url, + action: async () => { + const { Toast } = await import('@/core/toast') + const toast = Toast.info('检查更新中...', '检查更新') + toast.message = await checkComponentsUpdate({ + filterNames: [metadata.name], + force: true, + }) + toast.duration = 3000 + }, + } + }) + }, + ) const icon = 'mdi-cloud-sync-outline' addData('launchBar.actions', (actions: LaunchBarActionProvider[]) => { @@ -172,7 +193,10 @@ export const component: ComponentMetadata = { description: 'Check Last Update', action: async () => { const { Toast } = await import('@/core/toast') - const toast = Toast.info('正在检查更新...', '检查最近更新的功能') + const toast = Toast.info( + '正在检查更新...', + '检查最近更新的功能', + ) await checkLastFeature() toast.dismiss() }, @@ -184,4 +208,4 @@ export const component: ComponentMetadata = { } }, }, -} +}) From 5678c19868f6989c57ecdbfebf872b67b343f074 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 19:06:32 +0800 Subject: [PATCH 5/6] Specify the return type of method getGeneralSettings --- src/components/settings-panel/index.ts | 22 ++++++++++++++++++---- src/core/settings/helpers.ts | 13 ++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/components/settings-panel/index.ts b/src/components/settings-panel/index.ts index bf806f9bb..bd19c8845 100644 --- a/src/components/settings-panel/index.ts +++ b/src/components/settings-panel/index.ts @@ -5,11 +5,16 @@ import { CdnTypes } from '@/core/cdn-types' import { addComponentListener } from '@/core/settings' import { DownloadPackageEmitMode } from '@/core/download-mode' import { ComponentEntry, componentsTags } from '../types' -import { defineOptionsMetadata, defineComponentMetadata } from '../define' +import { + defineComponentMetadata, + defineOptionsMetadata, + OptionsOfMetadata, +} from '../define' import { provideActions } from './external-actions' import description from './desc.md' export const WidgetsPlugin = 'widgets' + export enum SettingsPanelDockSide { Left = '左侧', Right = '右侧', @@ -65,14 +70,23 @@ const options = defineOptionsMetadata({ }, }) +export type Options = OptionsOfMetadata + const entry: ComponentEntry = async ({ metadata }) => { const { isIframe } = await import('@/core/utils') if (isIframe()) { return } - addComponentListener(`${metadata.name}.dockSide`, (value: SettingsPanelDockSide) => { - document.body.classList.toggle('settings-panel-dock-right', value === SettingsPanelDockSide.Right) - }, true) + addComponentListener( + `${metadata.name}.dockSide`, + (value: SettingsPanelDockSide) => { + document.body.classList.toggle( + 'settings-panel-dock-right', + value === SettingsPanelDockSide.Right, + ) + }, + true, + ) requestIdleCallback(async () => { const Container = await import('./SettingsContainer.vue') const instance = mountVueComponent(Container) diff --git a/src/core/settings/helpers.ts b/src/core/settings/helpers.ts index 7c1ecc0e5..6874740e1 100644 --- a/src/core/settings/helpers.ts +++ b/src/core/settings/helpers.ts @@ -8,7 +8,8 @@ import { } from '@/components/component' import { PluginMetadata } from '@/plugins/plugin' // import serialize from 'serialize-javascript' -import { settings, ComponentSettings } from '../settings' +import type { Options as SettingsPanelOptions } from '@/components/settings-panel' +import { ComponentSettings, settings } from '../settings' import { matchUrlPattern } from '../utils' /** @@ -23,11 +24,9 @@ export const metadataToOptions = ( * 生成组件设置 * @param component 组件定义 */ -export const componentToSettings = < - Om extends OptionalOptionsMetadata ->(component: ComponentMetadata): ( - ComponentSettings> -) => { +export const componentToSettings = ( + component: ComponentMetadata, +): ComponentSettings> => { const { options: meta } = component return { enabled: component.enabledByDefault ?? true, @@ -99,7 +98,7 @@ export const getComponentSettings = ( /** * 获取通用设置 (`settingsPanel`组件的`options`) */ -export const getGeneralSettings = () => getComponentSettings('settingsPanel').options +export const getGeneralSettings = () => getComponentSettings('settingsPanel').options /** * 判断此组件是否启用, 启用的条件为: * - 若定义了排除列表, 当前URL必须不匹配其排除列表中任意一项(`Component.urlExclude`) From fae9a7eeb334d1e658ee88088a090bc233e83fb4 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 21 Mar 2022 19:33:19 +0800 Subject: [PATCH 6/6] Change notifyNewVersion to define api --- src/components/notify-new-version/index.ts | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/components/notify-new-version/index.ts b/src/components/notify-new-version/index.ts index 4020647b4..8a8f8fd85 100644 --- a/src/components/notify-new-version/index.ts +++ b/src/components/notify-new-version/index.ts @@ -1,13 +1,12 @@ import { cdnRoots } from '@/core/cdn-types' -import { ComponentMetadata, componentsTags } from '../types' +import { defineComponentMetadata } from '@/components/define' +import { componentsTags } from '../types' -export const component: ComponentMetadata = { +export const component = defineComponentMetadata({ name: 'notifyNewVersion', displayName: '新版本提示', description: '定期检查脚本本体的更新, 并弹出提示.', - tags: [ - componentsTags.utils, - ], + tags: [componentsTags.utils], options: { lastUpdateCheck: { displayName: '最后检查更新日期', @@ -28,19 +27,28 @@ export const component: ComponentMetadata = { const { getGeneralSettings } = await import('@/core/settings') const now = Number(new Date()) const duration = now - options.lastUpdateCheck - if (duration < options.minimumDuration) { // 未到间隔期 + if (duration < options.minimumDuration) { + // 未到间隔期 return } // 本地调试版不检查 if (!GM_info.scriptUpdateURL) { return } - const updateUrl = `${cdnRoots[getGeneralSettings().cdnRoot](meta.compilationInfo.branch)}dist/${meta.originalFilename}` - const scriptText: string = await monkey({ url: updateUrl, responseType: 'text' }) + const updateUrl = `${cdnRoots[getGeneralSettings().cdnRoot]( + meta.compilationInfo.branch, + )}dist/${meta.originalFilename}` + const scriptText: string = await monkey({ + url: updateUrl, + responseType: 'text', + }) options.lastUpdateCheck = Number(new Date()) - const versionMatch = scriptText.match(/^\/\/ @version\s*([\d\.]+)$/m) + const versionMatch = scriptText.match(/^\/\/ @version\s*([\d.]+)$/m) if (!versionMatch?.[1]) { - console.warn('[新版本提示] 未能检测出脚本版本, scriptText.length =', scriptText.length) + console.warn( + '[新版本提示] 未能检测出脚本版本, scriptText.length =', + scriptText.length, + ) return } const latestVersion = new Version(versionMatch[1]) @@ -48,9 +56,12 @@ export const component: ComponentMetadata = { if (!latestVersion.greaterThan(currentVersion)) { return } - Toast.info(/* html */`新版本 ${latestVersion.versionString} 已发布. 更新说明安装`, '检查更新') + Toast.info( + /* html */ `新版本 ${latestVersion.versionString} 已发布. 更新说明安装`, + '检查更新', + ) } catch (error) { console.warn('[新版本提示] 检查更新时发生错误: ', error) } }, -} +})