Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions astrbot/dashboard/routes/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ async def process_plugin(plugin):
for plugin, logo_url, pages in results:
_t = {
"name": plugin.name,
"marketplace_name": (plugin.name or "").replace("_", "-"),
"repo": "" if plugin.repo is None else str(plugin.repo),
"author": plugin.author,
"desc": plugin.desc,
Expand Down Expand Up @@ -1332,6 +1333,7 @@ async def get_plugin_detail(self):
.ok(
{
"name": plugin.name,
"marketplace_name": (plugin.name or "").replace("_", "-"),
"repo": "" if plugin.repo is None else str(plugin.repo),
"author": plugin.author,
"desc": plugin.desc,
Expand Down Expand Up @@ -1384,6 +1386,7 @@ async def get_plugin_page_components(self, plugin) -> list[dict]:
"i18n_key": page["i18n_key"],
"description": "Plugin Page entry",
"plugin_name": plugin.name,
"plugin_marketplace_name": (plugin.name or "").replace("_", "-"),
}
for page in pages
]
Expand Down
34 changes: 23 additions & 11 deletions dashboard/src/views/extension/useExtensionPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ export const useExtensionPage = () => {
const failRes = await axios.get("/api/plugin/source/get-failed-plugins");
failedPluginsDict.value = failRes.data.data || {};

checkUpdate();
// checkUpdate() is called after pluginMarketData is loaded in onMounted
} catch (err) {
toast(err, "error");
} finally {
Expand Down Expand Up @@ -642,14 +642,20 @@ export const useExtensionPage = () => {
if (plugin.repo) {
onlinePluginsMap.set(normalizeInstallUrl(plugin.repo).toLowerCase(), plugin);
}
onlinePluginsNameMap.set(plugin.name, plugin);
const normalizedName = normalizeStr(plugin.name);
onlinePluginsNameMap.set(normalizedName, plugin);
});

const data = Array.isArray(extension_data?.data) ? extension_data.data : [];

data.forEach((extension) => {
const repoKey = extension.repo ? normalizeInstallUrl(extension.repo).toLowerCase() : undefined;
const onlinePlugin = repoKey ? onlinePluginsMap.get(repoKey) : null;
const onlinePluginByName = onlinePluginsNameMap.get(extension.name);

// 使用 marketplace_name 进行市场匹配(后端已统一为减号格式)
const normalizedExtensionName = normalizeStr(extension.marketplace_name);
const onlinePluginByName = onlinePluginsNameMap.get(normalizedExtensionName);

const matchedPlugin = onlinePlugin || onlinePluginByName;

if (matchedPlugin) {
Expand Down Expand Up @@ -1233,17 +1239,22 @@ export const useExtensionPage = () => {

const checkAlreadyInstalled = () => {
const data = Array.isArray(extension_data?.data) ? extension_data.data : [];
// repo 匹配:两边统一使用 normalizeInstallUrl
const installedRepos = new Set(
data
.filter((ext) => ext.repo)
.map((ext) => normalizeInstallUrl(ext.repo).toLowerCase()),
);
// 使用 marketplace_name 进行市场匹配(后端已统一为减号格式)
const installedNames = new Set(data.map((ext) => normalizeStr(ext.marketplace_name)));
// 创建映射用于查询已安装插件的详细信息
const installedByRepo = new Map(
data
.filter((ext) => ext.repo)
.map((ext) => [normalizeInstallUrl(ext.repo).toLowerCase(), ext]),
);
const installedRepos = new Set(installedByRepo.keys());
const installedNames = new Set(
data.map((ext) => normalizeStr(ext.name).replace(/_/g, "-")),
); //统一格式,以防下面的匹配不生效
const installedByName = new Map(data.map((ext) => [ext.name, ext]));

const installedByName = new Map(data.map((ext) => [ext.marketplace_name, ext]));

for (let i = 0; i < pluginMarketData.value.length; i++) {
const plugin = pluginMarketData.value[i];
const matchedInstalled =
Expand All @@ -1265,8 +1276,8 @@ export const useExtensionPage = () => {
}

plugin.installed =
(plugin.repo && installedRepos.has(normalizeInstallUrl(plugin.repo).toLowerCase())) ||
installedNames.has(normalizeStr(plugin.name).replace(/_/g, "-")); //统一格式,防止匹配失败
installedRepos.has(normalizeInstallUrl(plugin.repo).toLowerCase()) ||
installedNames.has(normalizeStr(plugin.name));
}

let installed = [];
Expand Down Expand Up @@ -1477,6 +1488,7 @@ export const useExtensionPage = () => {
selectedMarketInstallPlugin.value = null;
await getExtensions();
checkAlreadyInstalled();
checkUpdate();

viewReadme({
name: resData.data.name,
Expand Down
1 change: 1 addition & 0 deletions tests/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ async def test_plugin_detail_includes_scanned_page_component(
"i18n_key": f"pages.{PLUGIN_PAGE_DEMO_PAGE_NAME}",
"description": "Plugin Page entry",
"plugin_name": PLUGIN_PAGE_DEMO_NAME,
"plugin_marketplace_name": PLUGIN_PAGE_DEMO_NAME.replace("_", "-"),
}
]

Expand Down
Loading