✨ feat: 推荐插件页面
This commit is contained in:
@@ -10,6 +10,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
highlight: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
// 定义要发送到父组件的事件
|
||||
@@ -62,7 +66,8 @@ const viewHandlers = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card class="mx-auto d-flex flex-column" :style="{ height: $vuetify.display.xs ? '250px' : '220px' }">
|
||||
<v-card class="mx-auto d-flex flex-column" :elevation="highlight ? 0 : 1"
|
||||
:style="{ height: $vuetify.display.xs ? '250px' : '220px', backgroundColor: highlight ? '#FAF0DB' : '#ffffff', color: highlight ? '#000' : '#000000' }">
|
||||
<v-card-text style="padding: 16px; padding-bottom: 0px; display: flex; justify-content: space-between;">
|
||||
|
||||
<div class="flex-grow-1">
|
||||
@@ -99,47 +104,40 @@ const viewHandlers = () => {
|
||||
</v-chip>
|
||||
</div>
|
||||
|
||||
<div class="text-medium-emphasis mt-2" :class="{ 'text-caption': $vuetify.display.xs }">
|
||||
<div class="mt-2" :class="{ 'text-caption': $vuetify.display.xs }">
|
||||
{{ extension.desc }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="extension-image-container" v-if="extension.logo">
|
||||
<img
|
||||
:src="extension.logo"
|
||||
:style="{
|
||||
height: $vuetify.display.xs ? '75px' : '100px',
|
||||
width: $vuetify.display.xs ? '75px' : '100px',
|
||||
borderRadius: '8px',
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'center'
|
||||
}"
|
||||
alt="logo"
|
||||
/>
|
||||
<img :src="extension.logo" :style="{
|
||||
height: $vuetify.display.xs ? '75px' : '100px',
|
||||
width: $vuetify.display.xs ? '75px' : '100px',
|
||||
borderRadius: '8px',
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'center'
|
||||
}" alt="logo" />
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions style="padding: 0px; margin-top: auto;">
|
||||
<v-btn color="teal-accent-4" text="帮助" variant="text" @click="open(extension.repo)"></v-btn>
|
||||
<v-btn v-if="!marketMode" color="teal-accent-4" text="操作" variant="text" @click="reveal = true"></v-btn>
|
||||
<v-btn v-if="marketMode && !extension?.installed" color="teal-accent-4" text="安装" variant="text" @click="emit('install', extension)"></v-btn>
|
||||
<v-btn v-if="marketMode && !extension?.installed" color="teal-accent-4" text="安装" variant="text"
|
||||
@click="emit('install', extension)"></v-btn>
|
||||
<v-btn v-if="marketMode && extension?.installed" color="teal-accent-4" text="已安装" variant="text" disabled></v-btn>
|
||||
</v-card-actions>
|
||||
</v-card-actions>
|
||||
|
||||
<v-expand-transition v-if="!marketMode">
|
||||
<v-card v-if="reveal" class="position-absolute w-100" height="100%"
|
||||
style="bottom: 0; display: flex; flex-direction: column;">
|
||||
<v-card-text style="overflow-y: auto;">
|
||||
<div class="d-flex align-center mb-4">
|
||||
<img
|
||||
v-if="extension.logo"
|
||||
:src="extension.logo"
|
||||
style="height: 50px; width: 50px; border-radius: 8px; margin-right: 16px;"
|
||||
alt="扩展图标"
|
||||
/>
|
||||
<img v-if="extension.logo" :src="extension.logo"
|
||||
style="height: 50px; width: 50px; border-radius: 8px; margin-right: 16px;" alt="扩展图标" />
|
||||
<h3>{{ extension.name }}</h3>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mt-4" :style="{
|
||||
justifyContent: 'center',
|
||||
display: 'flex',
|
||||
|
||||
@@ -72,7 +72,9 @@ export const useCommonStore = defineStore({
|
||||
"installed": false,
|
||||
"version": res.data.data[key]?.version ? res.data.data[key].version : "未知",
|
||||
"social_link": res.data.data[key]?.social_link,
|
||||
"tags": res.data.data[key]?.tags ? res.data.data[key].tags : []
|
||||
"tags": res.data.data[key]?.tags ? res.data.data[key].tags : [],
|
||||
"logo": res.data.data[key]?.logo ? res.data.data[key].logo : "",
|
||||
"pinned": res.data.data[key]?.pinned ? res.data.data[key].pinned : false,
|
||||
})
|
||||
}
|
||||
this.pluginMarketData = data;
|
||||
|
||||
@@ -16,83 +16,101 @@ import { useCommonStore } from '@/stores/common';
|
||||
|
||||
<v-col cols="12" md="12">
|
||||
<v-card>
|
||||
<v-card-title class="d-flex align-center pe-2">
|
||||
|
||||
🧩 插件市场
|
||||
<v-card-title>
|
||||
<div class="pl-2 pt-2 d-flex align-center pe-2">
|
||||
<h2>✨ 插件市场</h2>
|
||||
<v-btn icon size="small" style="margin-left: 8px" variant="plain" @click="jumpToPluginMarket()">
|
||||
<v-icon size="small">mdi-help</v-icon>
|
||||
<v-tooltip activator="parent" location="start">
|
||||
<span>
|
||||
如无法显示,请单击此按钮跳转至插件市场,复制想安装插件对应的
|
||||
`repo`
|
||||
链接然后点击右下角 + 号安装,或打开链接下载压缩包安装。
|
||||
|
||||
<v-btn icon size="small" style="margin-left: 8px" variant="plain" @click="jumpToPluginMarket()">
|
||||
<v-icon size="small">mdi-help</v-icon>
|
||||
<v-tooltip activator="parent" location="start">
|
||||
<span>
|
||||
如无法显示,请单击此按钮跳转至插件市场,复制想安装插件对应的
|
||||
`repo`
|
||||
链接然后点击右下角 + 号安装,或打开链接下载压缩包安装。
|
||||
如果因为网络问题安装失败,点击设置页选择 GitHub 加速地址。或前往仓库下载压缩包然后本地上传。
|
||||
</span>
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
如果因为网络问题安装失败,点击设置页选择 GitHub 加速地址。或前往仓库下载压缩包然后本地上传。
|
||||
</span>
|
||||
<v-btn icon @click="isListView = !isListView" size="small" style="margin-left: auto;"
|
||||
variant="plain">
|
||||
<v-icon>{{ isListView ? 'mdi-view-grid' : 'mdi-view-list' }}</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
<v-text-field v-model="marketSearch" density="compact" label="Search"
|
||||
prepend-inner-icon="mdi-magnify" variant="solo-filled" flat hide-details
|
||||
single-line></v-text-field>
|
||||
</div>
|
||||
|
||||
<v-btn icon @click="isListView = !isListView" size="small" style="margin-left: auto;"
|
||||
variant="plain">
|
||||
<v-icon>{{ isListView ? 'mdi-view-grid' : 'mdi-view-list' }}</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-text-field v-model="marketSearch" density="compact" label="Search"
|
||||
prepend-inner-icon="mdi-magnify" variant="solo-filled" flat hide-details
|
||||
single-line></v-text-field>
|
||||
</v-card-title>
|
||||
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
|
||||
<template v-if="isListView">
|
||||
<v-col cols="12" md="12">
|
||||
<v-data-table :headers="pluginMarketHeaders" :items="pluginMarketData" item-key="name"
|
||||
:loading="loading_" v-model:search="marketSearch" :filter-keys="['name', 'desc', 'author']">
|
||||
<template v-slot:item.name="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<img v-if="item.logo" :src="item.logo"
|
||||
style="height: 80px; width: 80px; margin-right: 8px; border-radius: 8px; margin-top: 8px; margin-bottom: 8px;"
|
||||
alt="logo">
|
||||
<span v-if="item?.repo"><a :href="item?.repo"
|
||||
style="color: #000; text-decoration:none">{{
|
||||
item.name }}</a></span>
|
||||
<span v-else>{{ item.name }}</span>
|
||||
<div v-if="pinnedPlugins.length > 0" class="mt-4">
|
||||
<h2>🥳 推荐</h2>
|
||||
|
||||
</div>
|
||||
<v-row style="margin-top: 8px;">
|
||||
<v-col cols="12" md="6" lg="6" v-for="plugin in pinnedPlugins">
|
||||
<ExtensionCard :extension="plugin" market-mode="true" :highlight="true">
|
||||
</ExtensionCard>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template v-slot:item.author="{ item }">
|
||||
<span v-if="item?.social_link"><a :href="item?.social_link">{{ item.author }}</a></span>
|
||||
<span v-else>{{ item.author }}</span>
|
||||
</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="primary" size="small">{{ tag
|
||||
}}</v-chip>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn v-if="!item.installed" class="text-none mr-2" size="small" text="Read"
|
||||
variant="flat" border @click="extension_url = item.repo; newExtension()">安装</v-btn>
|
||||
<v-btn v-else class="text-none mr-2" size="small" text="Read" variant="flat" border
|
||||
disabled>已安装</v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-col>
|
||||
</template>
|
||||
<template v-else>
|
||||
<v-row style="margin: 8px;">
|
||||
<v-col cols="12" md="6" lg="6" v-for="plugin in filteredPluginMarketData">
|
||||
<ExtensionCard :extension="plugin" market-mode="true">
|
||||
</ExtensionCard>
|
||||
|
||||
|
||||
<div v-if="isListView" class="mt-4">
|
||||
<h2>📦 全部插件</h2>
|
||||
<v-col cols="12" md="12" style="padding: 0px;">
|
||||
<v-data-table :headers="pluginMarketHeaders" :items="pluginMarketData" item-key="name"
|
||||
:loading="loading_" v-model:search="marketSearch"
|
||||
:filter-keys="['name', 'desc', 'author']">
|
||||
<template v-slot:item.name="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<img v-if="item.logo" :src="item.logo"
|
||||
style="height: 80px; width: 80px; margin-right: 8px; border-radius: 8px; margin-top: 8px; margin-bottom: 8px;"
|
||||
alt="logo">
|
||||
<span v-if="item?.repo"><a :href="item?.repo"
|
||||
style="color: #000; text-decoration:none">{{
|
||||
item.name }}</a></span>
|
||||
<span v-else>{{ item.name }}</span>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template v-slot:item.author="{ item }">
|
||||
<span v-if="item?.social_link"><a :href="item?.social_link">{{ item.author
|
||||
}}</a></span>
|
||||
<span v-else>{{ item.author }}</span>
|
||||
</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="primary" size="small">{{ tag
|
||||
}}</v-chip>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn v-if="!item.installed" class="text-none mr-2" size="small" text="Read"
|
||||
variant="flat" border
|
||||
@click="extension_url = item.repo; newExtension()">安装</v-btn>
|
||||
<v-btn v-else class="text-none mr-2" size="small" text="Read" variant="flat" border
|
||||
disabled>已安装</v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="mt-4">
|
||||
<h2>📦 全部插件</h2>
|
||||
<v-row style="margin-top: 16px;">
|
||||
<v-col cols="12" md="6" lg="6" v-for="plugin in filteredPluginMarketData">
|
||||
<ExtensionCard :extension="plugin" market-mode="true">
|
||||
</ExtensionCard>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
</v-card>
|
||||
|
||||
@@ -215,6 +233,9 @@ export default {
|
||||
return this.pluginMarketData.filter(plugin =>
|
||||
plugin.name.toLowerCase().includes(search)
|
||||
);
|
||||
},
|
||||
pinnedPlugins() {
|
||||
return this.pluginMarketData.filter(plugin => plugin?.pinned);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
Reference in New Issue
Block a user