perf: extension ui

This commit is contained in:
Soulter
2025-07-21 15:16:49 +08:00
parent e92fbb0443
commit 3ccbef141e
2 changed files with 68 additions and 95 deletions
+1 -1
View File
@@ -163,7 +163,7 @@ class PluginManager:
plugins.extend(_p)
return plugins
async def _check_plugin_dept_update(self, target_plugin: str = None):
async def _check_plugin_dept_update(self, target_plugin: str | None = None):
"""检查插件的依赖
如果 target_plugin 为 None,则检查所有插件的依赖
"""
+67 -94
View File
@@ -30,12 +30,12 @@ const extension_config = reactive({
config: {}
});
const pluginMarketData = ref([]);
const loadingDialog = reactive({
show: false,
title: "",
statusCode: 0, // 0: loading, 1: success, 2: error,
result: ""
});
const loadingDialog = reactive({
show: false,
title: "",
statusCode: 0, // 0: loading, 1: success, 2: error,
result: ""
});
const showPluginInfoDialog = ref(false);
const selectedPlugin = ref({});
const curr_namespace = ref("");
@@ -185,8 +185,8 @@ const checkUpdate = () => {
if (matchedPlugin) {
extension.online_version = matchedPlugin.version;
extension.has_update = extension.version !== matchedPlugin.version &&
matchedPlugin.version !== tm('status.unknown');
extension.has_update = extension.version !== matchedPlugin.version &&
matchedPlugin.version !== tm('status.unknown');
} else {
extension.has_update = false;
}
@@ -623,27 +623,12 @@ onMounted(async () => {
<!-- 搜索栏 - 在移动端时独占一行 -->
<v-row class="mb-2">
<v-col cols="12" sm="6" md="4" lg="3">
<v-text-field
v-if="activeTab == 'market'"
v-model="marketSearch"
density="compact"
:label="tm('search.marketPlaceholder')"
prepend-inner-icon="mdi-magnify"
variant="solo-filled"
flat
hide-details
single-line>
<v-text-field v-if="activeTab == 'market'" v-model="marketSearch" density="compact"
:label="tm('search.marketPlaceholder')" prepend-inner-icon="mdi-magnify" variant="solo-filled" flat
hide-details single-line>
</v-text-field>
<v-text-field
v-else
v-model="pluginSearch"
density="compact"
:label="tm('search.placeholder')"
prepend-inner-icon="mdi-magnify"
variant="solo-filled"
flat
hide-details
single-line>
<v-text-field v-else v-model="pluginSearch" density="compact" :label="tm('search.placeholder')"
prepend-inner-icon="mdi-magnify" variant="solo-filled" flat hide-details single-line>
</v-text-field>
</v-col>
</v-row>
@@ -679,33 +664,32 @@ onMounted(async () => {
<v-icon>mdi-plus</v-icon>
{{ tm('buttons.install') }}
</v-btn>
</v-col>
<v-col cols="12" sm="auto" md="6" class="ml-auto">
<v-dialog max-width="500px" v-if="extension_data.message">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" icon size="small" color="error" class="ml-2" variant="tonal">
<v-icon>mdi-alert-circle</v-icon>
<v-badge dot color="error" floating></v-badge>
</v-btn>
</template>
<template v-slot:default="{ isActive }">
<v-card class="rounded-lg">
<v-card-title class="headline d-flex align-center">
<v-icon color="error" class="mr-2">mdi-alert-circle</v-icon>
{{ tm('dialogs.error.title') }}
</v-card-title>
<v-card-text>
<p class="text-body-1">{{ extension_data.message }}</p>
<p class="text-caption mt-2">{{ tm('dialogs.error.checkConsole') }}</p>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="isActive.value = false">{{ tm('buttons.close') }}</v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
<v-col cols="12" sm="auto" class="ml-auto">
<v-dialog max-width="500px" v-if="extension_data.message">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" icon size="small" color="error" class="ml-2" variant="tonal">
<v-icon>mdi-alert-circle</v-icon>
</v-btn>
</template>
<template v-slot:default="{ isActive }">
<v-card class="rounded-lg">
<v-card-title class="headline d-flex align-center">
<v-icon color="error" class="mr-2">mdi-alert-circle</v-icon>
{{ tm('dialogs.error.title') }}
</v-card-title>
<v-card-text>
<p class="text-body-1">{{ extension_data.message }}</p>
<p class="text-caption mt-2">{{ tm('dialogs.error.checkConsole') }}</p>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="isActive.value = false">{{ tm('buttons.close') }}</v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
</v-col>
</v-col>
</v-row>
@@ -727,7 +711,8 @@ onMounted(async () => {
<div>
<div class="text-subtitle-1 font-weight-medium">{{ item.name }}</div>
<div v-if="item.reserved" class="d-flex align-center mt-1">
<v-chip color="primary" size="x-small" class="font-weight-medium">{{ tm('status.system') }}</v-chip>
<v-chip color="primary" size="x-small" class="font-weight-medium">{{ tm('status.system')
}}</v-chip>
</div>
</div>
</div>
@@ -848,8 +833,8 @@ onMounted(async () => {
<!-- <small style="color: var(--v-theme-secondaryText);">每个插件都是作者无偿提供的的劳动成果如果您喜欢某个插件 Star</small> -->
<v-btn icon="mdi-plus" size="x-large" style="position: fixed; right: 52px; bottom: 52px; z-index: 10000" @click="dialog = true"
color="darkprimary">
<v-btn icon="mdi-plus" size="x-large" style="position: fixed; right: 52px; bottom: 52px; z-index: 10000"
@click="dialog = true" color="darkprimary">
</v-btn>
<div v-if="pinnedPlugins.length > 0" class="mt-4">
@@ -866,8 +851,8 @@ onMounted(async () => {
<div class="mt-4">
<div class="d-flex align-center mb-2" style="justify-content: space-between;">
<h2>{{ tm('market.allPlugins') }}</h2>
<v-switch v-model="showPluginFullName" :label="tm('market.showFullName')" hide-details density="compact"
style="margin-left: 12px" />
<v-switch v-model="showPluginFullName" :label="tm('market.showFullName')" hide-details density="compact"
style="margin-left: 12px" />
</div>
<v-col cols="12" md="12" style="padding: 0px;">
@@ -905,7 +890,8 @@ onMounted(async () => {
</template>
<template v-slot:item.tags="{ item }">
<span v-if="item.tags.length === 0">-</span>
<v-chip v-for="tag in item.tags" :key="tag" :color="tag === 'danger' ? 'error' : 'primary'" size="x-small" v-show="tag !== 'danger'">
<v-chip v-for="tag in item.tags" :key="tag" :color="tag === 'danger' ? 'error' : 'primary'"
size="x-small" v-show="tag !== 'danger'">
{{ tag }}</v-chip>
</template>
<template v-slot:item.actions="{ item }">
@@ -959,7 +945,8 @@ onMounted(async () => {
<v-icon icon="mdi-alert" color="warning" size="64" class="mb-4"></v-icon>
<div class="text-h5 mb-2">{{ tm('dialogs.platformConfig.noAdapters') }}</div>
<div class="text-body-1 mb-4">{{ tm('dialogs.platformConfig.noAdaptersDesc') }}</div>
<v-btn color="primary" to="/platforms" variant="elevated">{{ tm('dialogs.platformConfig.goPlatforms') }}</v-btn>
<v-btn color="primary" to="/platforms" variant="elevated">{{ tm('dialogs.platformConfig.goPlatforms')
}}</v-btn>
</div>
<v-sheet v-else class="rounded-lg overflow-hidden">
@@ -994,7 +981,7 @@ onMounted(async () => {
</v-list-item>
</v-list>
</v-menu>
</div>
</div>
</th>
</tr>
</thead>
@@ -1003,7 +990,8 @@ onMounted(async () => {
<td>
<div class="d-flex align-center">
{{ plugin.name }}
<v-chip v-if="plugin.reserved" color="primary" size="x-small" class="ml-2">{{ tm('status.system') }}</v-chip>
<v-chip v-if="plugin.reserved" color="primary" size="x-small" class="ml-2">{{ tm('status.system')
}}</v-chip>
</div>
<div class="text-caption text-grey">{{ plugin.desc }}</div>
</td>
@@ -1019,8 +1007,8 @@ onMounted(async () => {
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" text @click="platformEnableDialog = false">{{ tm('buttons.close') }}</v-btn>
<v-btn v-if="platformEnableData.platforms.length > 0" color="primary"
@click="savePlatformEnableConfig">{{ tm('buttons.save') }}</v-btn>
<v-btn v-if="platformEnableData.platforms.length > 0" color="primary" @click="savePlatformEnableConfig">{{
tm('buttons.save') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
@@ -1059,12 +1047,13 @@ onMounted(async () => {
<div style="margin-top: 32px;">
<h3>{{ tm('dialogs.loading.logs') }}</h3>
<ConsoleDisplayer historyNum="10" style="height: 200px; margin-top: 16px; margin-bottom: 24px;"></ConsoleDisplayer>
<ConsoleDisplayer historyNum="10" style="height: 200px; margin-top: 16px; margin-bottom: 24px;">
</ConsoleDisplayer>
</div>
</v-card-text>
<v-divider></v-divider>
<v-card-actions class="pa-4">
<v-spacer></v-spacer>
<v-btn color="blue-darken-1" variant="text" @click="resetLoadingDialog">{{ tm('buttons.close') }}</v-btn>
@@ -1100,7 +1089,8 @@ onMounted(async () => {
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue-darken-1" variant="text" @click="showPluginInfoDialog = false">{{ tm('buttons.close') }}</v-btn>
<v-btn color="blue-darken-1" variant="text" @click="showPluginInfoDialog = false">{{ tm('buttons.close')
}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
@@ -1147,25 +1137,13 @@ onMounted(async () => {
<v-window v-model="uploadTab" class="mt-4">
<v-window-item value="file">
<div class="d-flex flex-column align-center justify-center pa-4">
<v-file-input
ref="fileInput"
v-model="upload_file"
:label="tm('upload.selectFile')"
accept=".zip"
hide-details
hide-input
class="d-none"
></v-file-input>
<v-btn
color="primary"
size="large"
prepend-icon="mdi-upload"
@click="$refs.fileInput.click()"
>
<v-file-input ref="fileInput" v-model="upload_file" :label="tm('upload.selectFile')" accept=".zip"
hide-details hide-input class="d-none"></v-file-input>
<v-btn color="primary" size="large" prepend-icon="mdi-upload" @click="$refs.fileInput.click()">
{{ tm('buttons.selectFile') }}
</v-btn>
<div class="text-body-2 text-medium-emphasis mt-2">
{{ tm('messages.supportedFormats') }}
</div>
@@ -1183,14 +1161,9 @@ onMounted(async () => {
<v-window-item value="url">
<div class="pa-4">
<v-text-field
v-model="extension_url"
:label="tm('upload.enterUrl')"
variant="outlined"
prepend-inner-icon="mdi-link"
hide-details
placeholder="https://github.com/username/repo"
></v-text-field>
<v-text-field v-model="extension_url" :label="tm('upload.enterUrl')" variant="outlined"
prepend-inner-icon="mdi-link" hide-details
placeholder="https://github.com/username/repo"></v-text-field>
<div class="mt-4">
<ProxySelector></ProxySelector>
</div>