Skip to content

Commit

Permalink
🎨 优化拓展商店侧边栏实现
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyomotoi committed Jan 17, 2024
1 parent 81c5a15 commit 940a12a
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 180 deletions.
22 changes: 16 additions & 6 deletions frontend/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
CheckProjectTomlResponse,
AddProjectData,
ModuleConfigResponse,
SearchTag,
} from "@/api/schemas";

class API extends CustomAPI {
Expand Down Expand Up @@ -128,15 +129,24 @@ class API extends CustomAPI {
async searchStore(
projectID: string,
moduleType: string,
tags: SearchTag[],
content: string,
): Promise<StoreListResponse> {
return await this.request.post("/store/nonebot/search", undefined, {
params: {
project_id: projectID,
module_type: moduleType,
content: content,
return await this.request.post(
"/store/nonebot/search",
{
data: {
module_type: moduleType,
tags: tags,
content: content,
},
},
});
{
params: {
project_id: projectID,
},
},
);
}

async runProject(projectID: string): Promise<GenericResponse<string>> {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/api/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,8 @@ export interface AddProjectData {
plugin_dirs: string[];
builtin_plugins: string[];
}

export interface SearchTag {
label: "official" | "valid" | "latest" | "downloaded" | "author" | "tag";
text?: string;
}
88 changes: 57 additions & 31 deletions frontend/src/components/NonebotStore/FilterNav.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { nonebotExtensionStore } from "@/store/extensionStore";
import { SearchTag } from "@/api/schemas";
import { appStore } from "@/store/global";
interface CustomDetail {
Expand All @@ -8,67 +9,92 @@ interface CustomDetail {
icon: any;
}
const classList: CustomDetail[] = [
interface FilterDetail extends CustomDetail {
tag: SearchTag;
}
const moduleList: CustomDetail[] = [
{ tip: "插件", name: "plugin", icon: "extension" },
{ tip: "适配器", name: "adapter", icon: "lan" },
{ tip: "驱动器", name: "driver", icon: "electrical_services" },
];
const filterList: CustomDetail[] = [
{ tip: "官方认证", name: "official", icon: "verified" },
{ tip: "测试通过", name: "valid", icon: "check_circle" },
{ tip: "已下载", name: "downloaded", icon: "download" },
{ tip: "近期新增", name: "new", icon: "shadow_add" },
const filterList: FilterDetail[] = [
{
tip: "官方认证",
name: "official",
icon: "verified",
tag: {
label: "official",
},
},
{
tip: "测试通过",
name: "valid",
icon: "check_circle",
tag: {
label: "valid",
},
},
{
tip: "已下载",
name: "downloaded",
icon: "download",
tag: {
label: "downloaded",
},
},
{
tip: "近期新增",
name: "latest",
icon: "shadow_add",
tag: {
label: "latest",
},
},
];
const setActiveClass = (cls: string) => {
nonebotExtensionStore().nowPage = 0;
nonebotExtensionStore().turnPage(0);
nonebotExtensionStore().assignClass(cls);
if (appStore().choiceProject.project_id) {
nonebotExtensionStore().updateData(appStore().choiceProject.project_id);
}
nonebotExtensionStore().updateData(appStore().choiceProject.project_id);
};
const addFilter = (item: CustomDetail) => {
nonebotExtensionStore().nowPage = 0;
let beforeInput;
const ft = `is:${item.name}`;
if (nonebotExtensionStore().searchInput.includes(ft)) {
const beforeInput = nonebotExtensionStore().searchInput;
nonebotExtensionStore().searchInput = beforeInput.replace(ft, "").trim();
const addFilter = (item: FilterDetail) => {
nonebotExtensionStore().turnPage(0);
if (nonebotExtensionStore().searchTags.includes(item.tag)) {
nonebotExtensionStore().removeSearchTag(item.tag);
} else {
beforeInput = nonebotExtensionStore().searchInput;
nonebotExtensionStore().searchInput = `${ft} ${beforeInput}`;
nonebotExtensionStore().addSearchTag(item.tag);
}
};
const checkFilter = (item: CustomDetail) => {
const ft = `is:${item.name}`;
if (nonebotExtensionStore().searchInput.includes(ft)) {
return true;
} else {
return false;
}
const checkModule = (module: string) => {
return nonebotExtensionStore().choiceModule === module;
};
const checkFilter = (item: FilterDetail) => {
return nonebotExtensionStore().searchTags.includes(item.tag);
};
</script>

<template>
<div class="w-full mt-6">
<div class="w-full">
<ul class="menu w-full">
<li>
<div class="text-sm font-bold pointer-events-none">分类</div>
</li>
<li v-for="i in classList" @click="setActiveClass(i.name)">
<li v-for="m in moduleList" @click="setActiveClass(m.name)">
<a
:class="{
'pl-6': true,
active: nonebotExtensionStore().choiceClass === i.name,
active: checkModule(m.name),
}"
>
<span class="material-symbols-outlined text-xl leading-5">
{{ i.icon }}
{{ m.icon }}
</span>
{{ i.tip }}
{{ m.tip }}
</a>
</li>
</ul>
Expand Down
36 changes: 0 additions & 36 deletions frontend/src/components/NonebotStore/StoreSearch.vue

This file was deleted.

121 changes: 119 additions & 2 deletions frontend/src/components/NonebotStore/StoreSideNav.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,61 @@
<script setup lang="ts">
import StoreSearch from "@/components/NonebotStore/StoreSearch.vue";
import FilterNav from "@/components/NonebotStore/FilterNav.vue";
import { ref, watch } from "vue";
import { appStore } from "@/store/global";
import { nonebotExtensionStore } from "@/store/extensionStore";
const tagOfAuthorInput = ref(""),
tagOfLabelInput = ref("");
const extStore = nonebotExtensionStore();
const checkDelete = (e: KeyboardEvent) => {
const { searchTags, removeSearchTag } = nonebotExtensionStore();
if (e.key === "Backspace" && !extStore.searchInput) {
const lastTag = searchTags[searchTags.length - 1];
removeSearchTag(lastTag);
}
};
const checkTagOfAuthorInput = (e: KeyboardEvent) => {
if (e.key === "Enter") {
nonebotExtensionStore().addSearchTag({
label: "author",
text: tagOfAuthorInput.value,
});
tagOfAuthorInput.value = "";
}
};
const checkTagOfLabelInput = (e: KeyboardEvent) => {
if (e.key === "Enter") {
nonebotExtensionStore().addSearchTag({
label: "tag",
text: tagOfLabelInput.value,
});
tagOfLabelInput.value = "";
}
};
const doSearch = async () => {
await nonebotExtensionStore().updateDataBySearch(appStore().choiceProject.project_id);
};
watch(
() => extStore.searchInput,
async () => {
await doSearch();
},
);
watch(
() => nonebotExtensionStore().searchTags.length,
async () => {
await doSearch();
},
);
</script>

<template>
Expand Down Expand Up @@ -42,7 +94,72 @@ import { nonebotExtensionStore } from "@/store/extensionStore";
</div>
</div>

<StoreSearch />
<div class="p-2">
<div
class="w-full p-1.5 flex flex-wrap items-center bg-white rounded-lg gap-x-0.5 gap-y-0.5"
>
<div
role="button"
v-for="tag in nonebotExtensionStore().searchTags"
class="badge badge-primary"
@click="nonebotExtensionStore().removeSearchTag(tag)"
>
<span v-if="tag.label === 'author'">author:@{{ tag.text }}</span>
<span v-else-if="tag.label === 'tag'">tag:{{ tag.text }}</span>
<span v-else>is:{{ tag.label }}</span>
</div>
<input
v-model="extStore.searchInput"
@keydown="checkDelete"
type="text"
placeholder="键入以搜索"
class="input input-xs input-ghost !outline-none flex-1 text-sm p-0 min-w-1"
/>
</div>
</div>

<div class="p-2 flex gap-2">
<div class="dropdown">
<div tabindex="0" role="button" class="btn btn-xs btn-outline btn-primary">
<div class="flex gap-1 items-center">
<span class="material-symbols-outlined text-base"> person </span>
作者
</div>
</div>
<div
tabindex="0"
class="dropdown-content z-[1] p-2 shadow bg-base-100 rounded-lg"
>
<input
@keydown="checkTagOfAuthorInput"
v-model="tagOfAuthorInput"
placeholder="请键入"
class="input input-sm input-bordered"
/>
</div>
</div>

<div class="dropdown">
<div tabindex="0" role="button" class="btn btn-xs btn-outline btn-primary">
<div class="flex gap-1 items-center">
<span class="material-symbols-outlined text-base"> sell </span>
标签
</div>
</div>
<div
tabindex="0"
class="dropdown-content z-[1] p-2 shadow bg-base-100 rounded-lg"
>
<input
@keydown="checkTagOfLabelInput"
v-model="tagOfLabelInput"
placeholder="请键入"
class="input input-sm input-bordered"
/>
</div>
</div>
</div>

<FilterNav />
</div>
</template>
Loading

0 comments on commit 940a12a

Please sign in to comment.