From b5d18d8ab59d1a1bd2e67d431b649a8cbee32718 Mon Sep 17 00:00:00 2001 From: LTbinglingfeng Date: Mon, 15 Jun 2026 14:36:09 +0800 Subject: [PATCH] feat(pluginStore): add default plugin store source identification and update localization strings --- src/features/plugins/PluginStorePage.tsx | 14 ++++++++++---- .../plugins/components/PluginInstallGateModal.tsx | 6 +++++- src/features/plugins/pluginResources.ts | 8 ++++++++ src/i18n/locales/en.json | 1 + src/i18n/locales/ru.json | 1 + src/i18n/locales/zh-CN.json | 1 + src/i18n/locales/zh-TW.json | 1 + 7 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/features/plugins/PluginStorePage.tsx b/src/features/plugins/PluginStorePage.tsx index 8a23aab..d336cf8 100644 --- a/src/features/plugins/PluginStorePage.tsx +++ b/src/features/plugins/PluginStorePage.tsx @@ -20,7 +20,12 @@ import { pluginStoreApi } from '@/services/api'; import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores'; import { getErrorMessage, isRecord } from '@/utils/helpers'; import type { PluginStoreEntry, PluginStoreResponse } from '@/types'; -import { buildRepositoryURL, isOfficialPlugin, resolvePluginAssetURL } from './pluginResources'; +import { + buildRepositoryURL, + isDefaultPluginStoreSource, + isOfficialPlugin, + resolvePluginAssetURL, +} from './pluginResources'; import { PluginInstallGateModal } from './components/PluginInstallGateModal'; import styles from './PluginStorePage.module.scss'; @@ -327,9 +332,10 @@ export function PluginStorePage() { : entry.version ? `v${entry.version}` : ''; - const sourceText = entry.sourceName - ? t('plugin_store.source_name', { source: entry.sourceName }) - : ''; + const sourceName = isDefaultPluginStoreSource(entry) + ? t('plugin_store.cli_proxy_api_source') + : entry.sourceName; + const sourceText = sourceName ? t('plugin_store.source_name', { source: sourceName }) : ''; const metaItems = [versionText, sourceText, entry.author, entry.license].filter(Boolean); const isInstalling = installingKey === entryKey; const hasPendingInstall = Boolean(installingKey); diff --git a/src/features/plugins/components/PluginInstallGateModal.tsx b/src/features/plugins/components/PluginInstallGateModal.tsx index ccb0a1d..e0d32c2 100644 --- a/src/features/plugins/components/PluginInstallGateModal.tsx +++ b/src/features/plugins/components/PluginInstallGateModal.tsx @@ -9,6 +9,7 @@ import type { PluginStoreEntry } from '@/types'; import { getPluginConfirmToken, getPluginRepositorySlug, + isDefaultPluginStoreSource, resolvePluginAssetURL, } from '../pluginResources'; import styles from './PluginInstallGateModal.module.scss'; @@ -61,7 +62,10 @@ export function PluginInstallGateModal({ const repoSlug = getPluginRepositorySlug(entry.repository); const token = getPluginConfirmToken(entry); const logo = resolvePluginAssetURL(entry.logo, apiBase); - const sourceText = entry.sourceName || entry.sourceUrl; + const rawSourceText = entry.sourceName || entry.sourceUrl; + const sourceText = isDefaultPluginStoreSource(entry) + ? t('plugin_store.cli_proxy_api_source') + : rawSourceText; const tokenMatches = typed.trim() === token; const handleClose = () => { diff --git a/src/features/plugins/pluginResources.ts b/src/features/plugins/pluginResources.ts index b7b2f9b..a40e30e 100644 --- a/src/features/plugins/pluginResources.ts +++ b/src/features/plugins/pluginResources.ts @@ -46,6 +46,8 @@ export const buildRepositoryURL = (repository: string) => { // hosts like "https://github.com.evil.com/router-for-me/..." from being // mistaken for the official org. export const OFFICIAL_PLUGIN_REPO_PREFIX = 'https://github.com/router-for-me/'; +export const DEFAULT_PLUGIN_STORE_SOURCE_ID = 'official'; +const DEFAULT_PLUGIN_STORE_SOURCE_NAME = 'official'; // Normalize an "owner/repo" slug or repository URL to a bare "owner/repo". export const getPluginRepositorySlug = (repository: string): string => { @@ -72,6 +74,12 @@ export const isOfficialRepository = (repository: string): boolean => export const isOfficialPlugin = (entry: PluginStoreEntry): boolean => isOfficialRepository(entry.repository); +export const isDefaultPluginStoreSource = ( + entry: Pick +): boolean => + entry.sourceId.trim().toLowerCase() === DEFAULT_PLUGIN_STORE_SOURCE_ID || + entry.sourceName.trim().toLowerCase() === DEFAULT_PLUGIN_STORE_SOURCE_NAME; + // The string a user must retype to confirm a risky install: the repo slug when // available (most faithful to the source), otherwise the plugin id. export const getPluginConfirmToken = (entry: PluginStoreEntry): string => diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index a7864cd..eb97cb3 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1174,6 +1174,7 @@ "description_show_more": "Show more", "description_show_less": "Show less", "source_name": "Source: {{source}}", + "cli_proxy_api_source": "CLIProxyAPI source", "refresh": "Refresh", "retry": "Retry", "load_failed": "Failed to load the plugin store", diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 4547599..f1fcfc4 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -1161,6 +1161,7 @@ "description_show_more": "Показать больше", "description_show_less": "Свернуть", "source_name": "Источник: {{source}}", + "cli_proxy_api_source": "Источник CLIProxyAPI", "refresh": "Обновить", "retry": "Повторить", "load_failed": "Не удалось загрузить магазин плагинов", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 94ba9dd..2b7ec3a 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -1174,6 +1174,7 @@ "description_show_more": "展开描述", "description_show_less": "收起描述", "source_name": "来源:{{source}}", + "cli_proxy_api_source": "CLIProxyAPI源", "refresh": "刷新", "retry": "重试", "load_failed": "插件商店加载失败", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index f9068c0..68c2c1e 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -1200,6 +1200,7 @@ "description_show_more": "展開描述", "description_show_less": "收起描述", "source_name": "來源:{{source}}", + "cli_proxy_api_source": "CLIProxyAPI來源", "refresh": "重新整理", "retry": "重試", "load_failed": "插件商店載入失敗",