mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: loading indicator when expanding node
This commit is contained in:
parent
5b1a7c6b89
commit
48e213a158
2 changed files with 55 additions and 5 deletions
|
|
@ -4,6 +4,7 @@ import Icon from './Icon'
|
|||
|
||||
import cx from '../utils/cx'
|
||||
import DOMHelper from '../utils/DOMHelper'
|
||||
import LoadingIndicator from './LoadingIndicator';
|
||||
|
||||
function getIconType(node) {
|
||||
switch (node.type) {
|
||||
|
|
@ -26,7 +27,18 @@ export default class Node extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const { node, depth, expanded, focused } = this.props
|
||||
const { name, path } = node
|
||||
const { name, path, virtual } = node
|
||||
if (virtual) {
|
||||
// this is not a real node
|
||||
// for now, all virtual nodes are indicators for pending state
|
||||
return (
|
||||
<div className={cx(`node-item-row`, { focused })}>
|
||||
<div className={'node-item'}>
|
||||
<LoadingIndicator text={name} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className={cx(`node-item-row`, { focused })} title={path}>
|
||||
<a href={node.url} onClick={this.onClick}>
|
||||
|
|
|
|||
|
|
@ -143,16 +143,38 @@ const handleSearchKeyChange = dispatch => async event => {
|
|||
dispatch(updateVisibleNodes)
|
||||
}
|
||||
|
||||
const delayExpandThreshold = 400
|
||||
function shouldDelayExpand(node) {
|
||||
return visibleNodesGenerator.visibleNodes.expandedNodes.has(node)
|
||||
&& node.contents.length > delayExpandThreshold
|
||||
}
|
||||
|
||||
const setExpand = dispatch => (node, expand) => {
|
||||
visibleNodesGenerator.setExpand(node, expand)
|
||||
dispatch(focusNode, node)
|
||||
tasksAfterRender.push(DOMHelper.focusSearchInput)
|
||||
const applyChanges = () => {
|
||||
dispatch(focusNode, node)
|
||||
tasksAfterRender.push(DOMHelper.focusSearchInput)
|
||||
}
|
||||
if (shouldDelayExpand(node)) {
|
||||
dispatch(mountExpandingIndicator, node)
|
||||
tasksAfterRender.push(() => setTimeout(applyChanges, 0))
|
||||
} else {
|
||||
applyChanges()
|
||||
}
|
||||
}
|
||||
|
||||
const toggleNodeExpansion = dispatch => (node, skipScrollToNode) => {
|
||||
visibleNodesGenerator.toggleExpand(node)
|
||||
dispatch(focusNode, node, skipScrollToNode)
|
||||
tasksAfterRender.push(DOMHelper.focusFileExplorer)
|
||||
const applyChanges = () => {
|
||||
dispatch(focusNode, node, skipScrollToNode)
|
||||
tasksAfterRender.push(DOMHelper.focusFileExplorer)
|
||||
}
|
||||
if (shouldDelayExpand(node)) {
|
||||
dispatch(mountExpandingIndicator, node)
|
||||
tasksAfterRender.push(() => setTimeout(applyChanges, 0))
|
||||
} else {
|
||||
applyChanges()
|
||||
}
|
||||
}
|
||||
|
||||
const focusNode = dispatch => (node, skipScroll) => dispatch(({ visibleNodes: { nodes } }) => {
|
||||
|
|
@ -177,6 +199,21 @@ const onNodeClick = dispatch => (node) => {
|
|||
}
|
||||
}
|
||||
|
||||
const mountExpandingIndicator = dispatch => node => dispatch(({ visibleNodes }) => {
|
||||
const dummyVisibleNodes = {
|
||||
...visibleNodes,
|
||||
nodes: visibleNodes.nodes.slice(),
|
||||
}
|
||||
dummyVisibleNodes.nodes.splice(
|
||||
dummyVisibleNodes.nodes.indexOf(node) + 1,
|
||||
0,
|
||||
{ virtual: true, name: 'Loading' },
|
||||
)
|
||||
return {
|
||||
visibleNodes: dummyVisibleNodes
|
||||
}
|
||||
})
|
||||
|
||||
const updateVisibleNodes = dispatch => () => {
|
||||
const { visibleNodes } = visibleNodesGenerator
|
||||
dispatch({ visibleNodes })
|
||||
|
|
@ -193,4 +230,5 @@ export default {
|
|||
focusNode,
|
||||
onNodeClick,
|
||||
updateVisibleNodes,
|
||||
mountExpandingIndicator,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue