diff --git a/components.d.ts b/components.d.ts index 72d5c4c7..695f372a 100644 --- a/components.d.ts +++ b/components.d.ts @@ -67,7 +67,6 @@ declare module "@vue/runtime-core" { ElTooltip: typeof import("element-plus/es")["ElTooltip"] ElTreeSelect: typeof import("element-plus/es")["ElTreeSelect"] } - export interface ComponentCustomProperties { vLoading: typeof import("element-plus/es")["ElLoadingDirective"] } diff --git a/components/picgo/setting/PicgoPluginSetting.vue b/components/picgo/setting/PicgoPluginSetting.vue index c28ee153..c1b397e1 100644 --- a/components/picgo/setting/PicgoPluginSetting.vue +++ b/components/picgo/setting/PicgoPluginSetting.vue @@ -42,82 +42,92 @@ - - -
-
- CLI -
- -
+
+ {{ "当前共有" + pluginData.pluginList.length + "个插件。" }} +
+
+ + -
- {{ item.name }} {{ " " + item.version }} -
-
- {{ item.description }} -
-
- - {{ item.author }} - - - - - +
+
-
- -
-
+ + + + @@ -125,9 +135,10 @@ import picgoUtil from "~/utils/otherlib/picgoUtil" import { LogFactory } from "~/utils/logUtil" import { ElMessage } from "element-plus" -import { onBeforeMount, ref } from "vue" +import { computed, onBeforeMount, reactive, ref, watch } from "vue" import { goToPage } from "~/utils/otherlib/ChromeUtil" import sysUtil from "~/utils/otherlib/sysUtil" +import { debounce, DebouncedFunc } from "lodash" const logger = LogFactory.getLogger( "components/picgo/setting/PicgoPluginSetting.vue" @@ -137,13 +148,38 @@ const logger = LogFactory.getLogger( const __static = "" const loading = ref(false) const searchText = ref("") -const pluginList = ref([]) +const pluginData = reactive({ + pluginList: [], + pluginNameList: [], +}) const os = ref("") const defaultLogo = ref( `this.src="file://${__static.replace(/\\/g, "/")}/roundLogo.png"` ) +const npmSearchText = computed(() => { + return searchText.value.match("picgo-plugin-") + ? searchText.value + : searchText.value !== "" + ? `picgo-plugin-${searchText.value}` + : searchText.value +}) +let getSearchResult: DebouncedFunc<(val: string) => void> + +watch(npmSearchText, (val: string) => { + if (val) { + loading.value = true + pluginData.pluginList = [] + getSearchResult(val) + } else { + getPluginList() + } +}) // handles +function getPluginList() { + picgoUtil.ipcHandleEvent("getPluginList") +} + function openHomepage(url: string) { if (url) { goToPage(url) @@ -167,6 +203,66 @@ async function buildContextMenu(plugin: IPicGoPlugin) { alert("buildContextMenu") } +function _getSearchResult(val: string) { + // this.$http.get(`https://api.npms.io/v2/search?q=${val}`) + fetch(`https://registry.npmjs.com/-/v1/search?text=${val}`) + .then((res) => res.json()) + .then((res: INPMSearchResult) => { + pluginData.pluginList = res.data.objects + .filter((item: INPMSearchResultObject) => { + return item.package.name.includes("picgo-plugin-") + }) + .map((item: INPMSearchResultObject) => { + return handleSearchResult(item) + }) + loading.value = false + }) + .catch((err) => { + console.log(err) + loading.value = false + }) +} + +/** + * streamline the full plugin name to a simple one + * for example: + * 1. picgo-plugin-xxx -> xxx + * 2. @xxx/picgo-plugin-yyy -> yyy + * @param name pluginFullName + */ +const handleStreamlinePluginName = (name: string) => { + if (/^@[^/]+\/picgo-plugin-/.test(name)) { + return name.replace(/^@[^/]+\/picgo-plugin-/, "") + } else { + return name.replace(/picgo-plugin-/, "") + } +} + +function handleSearchResult(item: INPMSearchResultObject) { + const name = handleStreamlinePluginName(item.package.name) + let gui = false + if (item.package.keywords && item.package.keywords.length > 0) { + if (item.package.keywords.includes("picgo-gui-plugin")) { + gui = true + } + } + return { + name, + fullName: item.package.name, + author: item.package.author.name, + description: item.package.description, + logo: `https://cdn.jsdelivr.net/npm/${item.package.name}/logo.png`, + config: {}, + homepage: item.package.links ? item.package.links.homepage : "", + hasInstall: pluginData.pluginNameList.some( + (plugin) => plugin === item.package.name + ), + version: item.package.version, + gui, + ing: false, // installing or uninstalling + } +} + // register events onBeforeMount(() => { os.value = sysUtil.getOS() @@ -176,15 +272,18 @@ onBeforeMount(() => { const rawArgs = data.rawArgs if (rawArgs.success) { - // const list = rawArgs.list - // pluginList.value = list - // pluginNameList.value = list.map(item => item.fullName) + const list = rawArgs.data + pluginData.pluginList = list + pluginData.pluginNameList = list.map((item) => item.fullName) - logger.info("插件已经成功安装.") + logger.info("插件列表已经成功加载.", list) } else { ElMessage.error(rawArgs.error) } }) + + getPluginList() + getSearchResult = debounce(_getSearchResult, 50) }) @@ -197,6 +296,9 @@ $darwinBg = #172426 .el-loading-mask background-color rgba(0, 0, 0, 0.8) + .plugin-list-tip + padding: 8px 15px; + .plugin-list align-content flex-start height: 339px; @@ -204,8 +306,8 @@ $darwinBg = #172426 padding: 8px 15px; overflow-y: auto; overflow-x: hidden; - position: absolute; - top: 70px; + position: relative; + top: 10px; left: 5px; transition: all 0.2s ease-in-out 0.1s; width: 100% diff --git a/typings/picgo.d.ts b/typings/picgo.d.ts index 0da5d3ea..9cef9e52 100644 --- a/typings/picgo.d.ts +++ b/typings/picgo.d.ts @@ -128,4 +128,25 @@ interface IConfig { [configOptions: string]: any } -declare let __static: string +interface INPMSearchResult { + data: { + objects: INPMSearchResultObject[] + } +} + +interface INPMSearchResultObject { + package: { + name: string + scope: string + version: string + description: string + keywords: string[] + author: { + name: string + } + links: { + npm: string + homepage: string + } + } +}