mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: compress singleton folder
This commit is contained in:
parent
568221171d
commit
6c7823097b
3 changed files with 67 additions and 21 deletions
|
|
@ -30,12 +30,12 @@ const tasksAfterRender = []
|
|||
const visibleNodesGenerator = new VisibleNodesGenerator()
|
||||
|
||||
const init = dispatch => () => dispatch(async (state, { treeData, metaData, accessToken }) => {
|
||||
const { root, nodes } = treeParser.parse(treeData, metaData)
|
||||
visibleNodesGenerator.plantTree(root, nodes)
|
||||
const { root } = treeParser.parse(treeData, metaData)
|
||||
await visibleNodesGenerator.plantTree(root)
|
||||
const currentPath = URLHelper.getCurrentPath(true)
|
||||
tasksAfterRender.push(DOMHelper.focusSearchInput)
|
||||
if (currentPath.length) {
|
||||
const nodeExpandedTo = visibleNodesGenerator.expandTo(currentPath)
|
||||
const nodeExpandedTo = visibleNodesGenerator.expandTo(currentPath.join('/'))
|
||||
if (nodeExpandedTo) {
|
||||
visibleNodesGenerator.focusNode(nodeExpandedTo)
|
||||
const { nodes } = visibleNodesGenerator.visibleNodes
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const nodeTemplate = {
|
|||
|
||||
function sortFoldersToFront(root) {
|
||||
const isFolder = node => node.type === 'tree'
|
||||
const isNotFolder = (...args) => !isFolder(...args)
|
||||
const isNotFolder = node => !isFolder(node)
|
||||
function depthFirstSearch(root) {
|
||||
const nodes = root.contents
|
||||
if (nodes) {
|
||||
|
|
@ -73,7 +73,6 @@ function parse(treeData, metaData) {
|
|||
setParentNode(root)
|
||||
return {
|
||||
root: sortFoldersToFront(root),
|
||||
nodes: Array.from(pathToNode.values()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ function getFilterFunc(keyRegex) {
|
|||
}
|
||||
|
||||
function search(treeNodes, searchKey) {
|
||||
if (!searchKey) return
|
||||
if (!searchKey) return treeNodes
|
||||
/**
|
||||
* if searchKey is 'abcd'
|
||||
* then keyRegex will be /a.*?b.*?c.*?d/i
|
||||
|
|
@ -53,27 +53,67 @@ function debounce(func, delay) {
|
|||
|
||||
export const debouncedSearch = debounce(search, 250)
|
||||
|
||||
function getNodes(root) {
|
||||
if (!root.contents) return []
|
||||
return [].concat(
|
||||
...root.contents.map(node => [node, ...getNodes(node)])
|
||||
)
|
||||
}
|
||||
|
||||
function compressTree(root, prefix = []) {
|
||||
if (root.contents) {
|
||||
if (root.contents.length === 1) {
|
||||
const singleton = root.contents[0]
|
||||
if (singleton.type === 'tree') {
|
||||
return compressTree(singleton, [...prefix, root.name])
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
...root,
|
||||
name: [...prefix, root.name].join('/'),
|
||||
contents: root.contents
|
||||
? root.contents.map(node => compressTree(node))
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export default class VisibleNodesGenerator {
|
||||
// LEVEL 1
|
||||
root = null
|
||||
nodes = null
|
||||
plantTree(root, nodes) {
|
||||
this.root = root
|
||||
this.nodes = nodes
|
||||
compressed = false
|
||||
|
||||
// a simplified sync 'search'
|
||||
this.searchedNodes = this.root.contents
|
||||
this.generateVisibleNodes()
|
||||
getRoot() {
|
||||
return this.compress && this.compressed
|
||||
? this.compressedRoot
|
||||
: this.root
|
||||
}
|
||||
|
||||
async plantTree(root) {
|
||||
this.root = root
|
||||
this.nodes = getNodes(root)
|
||||
this.compressedRoot = compressTree(root)
|
||||
|
||||
await this.search()
|
||||
}
|
||||
|
||||
// LEVEL 2
|
||||
searchedNodes = null
|
||||
async search(searchKey) {
|
||||
this.searchedNodes = (await debouncedSearch(this.nodes, searchKey)) || this.root.contents
|
||||
this.compressed = !Boolean(searchKey)
|
||||
this.searchedNodes = searchKey
|
||||
? await debouncedSearch(this.nodes, searchKey)
|
||||
: this.getRoot().contents
|
||||
|
||||
this.expandedNodes.clear()
|
||||
this.generateVisibleNodes()
|
||||
}
|
||||
|
||||
setCompress(compress) {
|
||||
this.compress = compress
|
||||
}
|
||||
|
||||
// LEVEL 3
|
||||
expandedNodes = new Set()
|
||||
depths = new Map()
|
||||
|
|
@ -92,15 +132,22 @@ export default class VisibleNodesGenerator {
|
|||
}
|
||||
|
||||
expandTo(path) {
|
||||
let rootNode = this.root
|
||||
let targetPath
|
||||
for (const step of path) {
|
||||
targetPath = rootNode.path ? `${rootNode.path}/${step}` : step
|
||||
rootNode = rootNode.contents.find(node => node.path === targetPath)
|
||||
if (!rootNode) return
|
||||
this.setExpand(rootNode, true)
|
||||
let root = this.getRoot()
|
||||
const findNode = (root) => {
|
||||
if (path.indexOf(root.path) === 0) {
|
||||
if (root.path === path) return root
|
||||
this.setExpand(root, true)
|
||||
if (root.contents) {
|
||||
for (const content of root.contents) {
|
||||
const node = findNode(content)
|
||||
if (node) return node
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rootNode
|
||||
const node = findNode(root)
|
||||
this.focusNode(node)
|
||||
return node
|
||||
}
|
||||
|
||||
visibleNodes = null
|
||||
|
|
|
|||
Loading…
Reference in a new issue