From 5f116222fd46e905688dd4e724670671f47a0877 Mon Sep 17 00:00:00 2001 From: "xiaoqi.cxq" Date: Wed, 17 Aug 2022 13:15:03 +0800 Subject: [PATCH] support search file --- README.md | 1 + src/components/Explorer.vue | 124 +++++++++++++++++++++++++++++++- src/components/ExplorerNode.vue | 4 ++ src/icons/Search.vue | 3 + src/icons/index.js | 2 + src/styles/app.scss | 2 +- 6 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/icons/Search.vue diff --git a/README.md b/README.md index 0a478028..4696bb61 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ StackEdit中文版的docker镜像地址:[mafgwo/stackedit](https://hub.docker. - 支持GitHub图床粘贴/拖拽图片自动上传(2022-07-31) - 支持了右上角一键切换主题,补全了深色主题的样式(2022-08-07) - 编辑与预览区域样式优化(2022-08-10) +- 左边栏文件资源管理支持搜索文件(2022-08-17) ## 国外开源版本弊端: - 作者已经不维护了 diff --git a/src/components/Explorer.vue b/src/components/Explorer.vue index a8711904..8e28c1a6 100644 --- a/src/components/Explorer.vue +++ b/src/components/Explorer.vue @@ -1,7 +1,7 @@ @@ -30,11 +52,21 @@ import { mapState, mapGetters, mapActions } from 'vuex'; import ExplorerNode from './ExplorerNode'; import explorerSvc from '../services/explorerSvc'; import store from '../store'; +import MenuEntry from './menus/common/MenuEntry'; +import localDbSvc from '../services/localDbSvc'; export default { components: { ExplorerNode, + MenuEntry, }, + data: () => ({ + currentFileId: '', + showSearch: false, + searching: false, + searchText: '', + searchItems: [], + }), computed: { ...mapState([ 'light', @@ -46,6 +78,7 @@ export default { 'rootNode', 'selectedNode', ]), + workspaceId: () => store.getters['workspace/currentWorkspace'].id, }, methods: { ...mapActions('data', [ @@ -59,11 +92,62 @@ export default { store.commit('explorer/setEditingId', node.item.id); } }, + back() { + this.showSearch = false; + }, + toSearch() { + this.showSearch = true; + }, + search() { + this.searchItems = []; + if (!this.searchText) { + return; + } + this.searching = true; + const allFileById = {}; + const filterIds = []; + localDbSvc.getWorkspaceItems(this.workspaceId, (item) => { + if (item.type !== 'file' && item.type !== 'content') { + return; + } + if (item.type === 'file') { + allFileById[item.id] = item; + } + if (filterIds.length >= 50) { + return; + } + const fileId = item.id.split('/')[0]; + // 包含了直接跳过 + if (filterIds.indexOf(fileId) > -1) { + return; + } + if (item.name && item.name.indexOf(this.searchText) > -1) { + filterIds.push(fileId); + } + if (item.text && item.text.indexOf(this.searchText) > -1) { + filterIds.push(fileId); + } + }, () => { + filterIds.forEach((it) => { + const file = allFileById[it]; + if (file) { + this.searchItems.push(file); + } + }); + this.searching = false; + }); + }, + clickSearch(item) { + store.commit('explorer/setSelectedId', item.id); + store.commit('file/setCurrentId', item.id); + this.showSearch = false; + }, }, created() { this.$watch( () => store.getters['file/current'].id, (currentFileId) => { + this.currentFileId = currentFileId; store.commit('explorer/setSelectedId', currentFileId); store.dispatch('explorer/openNode', currentFileId); }, { @@ -75,6 +159,8 @@ export default { diff --git a/src/components/ExplorerNode.vue b/src/components/ExplorerNode.vue index 20ec317d..19a08b4d 100644 --- a/src/components/ExplorerNode.vue +++ b/src/components/ExplorerNode.vue @@ -215,6 +215,10 @@ $item-font-size: 14px; .explorer-node--selected > & { background-color: rgba(0, 0, 0, 0.2); + .app--dark & { + background-color: rgba(0, 0, 0, 0.4); + } + .explorer__tree:focus & { background-color: #39f; color: #fff; diff --git a/src/icons/Search.vue b/src/icons/Search.vue new file mode 100644 index 00000000..713fe6eb --- /dev/null +++ b/src/icons/Search.vue @@ -0,0 +1,3 @@ + diff --git a/src/icons/index.js b/src/icons/index.js index f54f34e7..46bfcaeb 100644 --- a/src/icons/index.js +++ b/src/icons/index.js @@ -56,6 +56,7 @@ import Key from './Key'; import DotsHorizontal from './DotsHorizontal'; import Seal from './Seal'; import SwitchTheme from './SwitchTheme'; +import Search from './Search'; Vue.component('iconProvider', Provider); Vue.component('iconFormatBold', FormatBold); @@ -114,3 +115,4 @@ Vue.component('iconKey', Key); Vue.component('iconDotsHorizontal', DotsHorizontal); Vue.component('iconSeal', Seal); Vue.component('iconSwitchTheme', SwitchTheme); +Vue.component('iconSearch', Search); diff --git a/src/styles/app.scss b/src/styles/app.scss index 5148dc32..b3356fe6 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -87,7 +87,7 @@ textarea { font-size: inherit; line-height: 1.5; color: inherit; - background-color: #fff; + background-color: rgba(255, 255, 255, 0.8); background-image: none; border: 0; border-radius: $border-radius-base;