flow: resource tree
This commit is contained in:
parent
b6b715dc87
commit
36fd1184f6
|
@ -49,6 +49,7 @@ html {
|
|||
background-color: #212121;
|
||||
color: #FFFFFF;
|
||||
--active-color: rgb(0, 180, 204);
|
||||
--title-font-family: Ubuntu, "Droid Sans", sans-serif;
|
||||
}
|
||||
body {
|
||||
scrollbar-width: thin;
|
||||
|
@ -152,7 +153,7 @@ select {
|
|||
|
||||
.react-tabs__tab-list {
|
||||
background-color: #272727;
|
||||
font-family: Ubuntu, "Droid Sans", sans-serif;
|
||||
font-family: var(--title-font-family);
|
||||
font-size: 0.9em;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import classnames from 'classnames';
|
||||
import contempo from 'contempo';
|
||||
import React, {useState} from 'react';
|
||||
import {useDispatch} from 'react-redux';
|
||||
import SortableTree, {changeNodeAtPath, getTreeFromFlatData} from 'react-sortable-tree';
|
||||
import SortableTree, {changeNodeAtPath, getTreeFromFlatData, toggleExpandedForAll} from 'react-sortable-tree';
|
||||
|
||||
import ResourcesPacket from '~/common/packets/resources.packet';
|
||||
|
||||
|
@ -18,18 +19,56 @@ const decorate = compose(
|
|||
|
||||
const rootUri = '/resources/cha0s/initial';
|
||||
|
||||
const sortTree = (tree) => {
|
||||
tree.sort((l, r) => l.title.localeCompare(r.title));
|
||||
if (tree.children) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
tree.children = sortTree(tree.children);
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
const sortTree = (tree) => tree
|
||||
.sort((l, r) => l.title.localeCompare(r.title))
|
||||
.map((node) => {
|
||||
if (node.children) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
node.children = sortTree(node.children);
|
||||
}
|
||||
return node;
|
||||
});
|
||||
|
||||
const mapComponents = (tree) => tree.map((node) => ({
|
||||
...node,
|
||||
children: node.children ? mapComponents(node.children) : [],
|
||||
rawTitle: node.title,
|
||||
title: (
|
||||
<span
|
||||
className={classnames(
|
||||
'title',
|
||||
node.uri ? 'resource' : 'directory',
|
||||
)}
|
||||
>
|
||||
{node.uri && (
|
||||
<svg
|
||||
height="1em"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M 511.867188 247.648438 C 511.859375 247.4375 511.832031 247.230469 511.816406 247.015625 C 509.542969 181.140625 482.460938 119.558594 435.269531 73.253906 C 387.125 26.015625 323.460938 0 256 0 C 187.621094 0 123.332031 26.628906 74.980469 74.980469 C 26.628906 123.332031 0 187.621094 0 256 C 0 290.847656 28.351562 319.199219 63.199219 319.199219 C 98.050781 319.199219 126.398438 290.847656 126.398438 256 C 126.398438 157.960938 206.160156 78.199219 304.199219 78.199219 C 401.40625 78.199219 479.480469 154.28125 481.941406 251.402344 C 481.941406 251.449219 481.949219 251.496094 481.953125 251.542969 C 481.980469 253.027344 482 254.519531 482 256 C 482 380.617188 380.617188 482 256 482 C 247.714844 482 241 488.714844 241 497 C 241 505.285156 247.714844 512 256 512 C 324.378906 512 388.667969 485.371094 437.019531 437.019531 C 485.371094 388.667969 512 324.378906 512 256 C 512 253.21875 511.957031 250.410156 511.867188 247.648438 Z M 511.867188 247.648438 "
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<span className="text">{node.title}</span>
|
||||
</span>
|
||||
),
|
||||
}));
|
||||
|
||||
const unmapComponents = (tree) => tree.map((node) => ({
|
||||
...node,
|
||||
children: node.children ? unmapComponents(node.children) : [],
|
||||
title: node.rawTitle || node.title,
|
||||
}));
|
||||
|
||||
const Sidebar = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [treeData, setTreeData] = useState([]);
|
||||
const [treeData, setTreeDataInternal] = useState([]);
|
||||
// eslint-disable-next-line no-shadow
|
||||
const setTreeData = (treeData) => {
|
||||
setTreeDataInternal(sortTree(unmapComponents(treeData)));
|
||||
};
|
||||
useSocket((socket) => socket.send(new ResourcesPacket(), (uris) => {
|
||||
const visited = {};
|
||||
const nodes = uris
|
||||
|
@ -60,17 +99,17 @@ const Sidebar = () => {
|
|||
visited[node.id] = true;
|
||||
return true;
|
||||
});
|
||||
setTreeData(sortTree(getTreeFromFlatData({
|
||||
setTreeData(getTreeFromFlatData({
|
||||
flatData: nodes,
|
||||
rootKey: '',
|
||||
})));
|
||||
}));
|
||||
}));
|
||||
return (
|
||||
<div className="sidebar">
|
||||
<SortableTree
|
||||
canNodeHaveChildren={(node) => !node.uri}
|
||||
generateNodeProps={({node}) => ({
|
||||
onClick: () => {
|
||||
onClick: (event) => {
|
||||
if (node.uri) {
|
||||
dispatch(setActiveResourceUri(node.uri));
|
||||
}
|
||||
|
@ -81,17 +120,21 @@ const Sidebar = () => {
|
|||
path: node.id.split('/'),
|
||||
newNode: {
|
||||
...node,
|
||||
children: (event.ctrlKey && event.altKey)
|
||||
? toggleExpandedForAll({treeData: node.children, expanded: !isExpanded})
|
||||
: node.children,
|
||||
expanded: !isExpanded,
|
||||
},
|
||||
getNodeKey: ({node: {id}}) => id,
|
||||
getNodeKey: ({node: {title}}) => title,
|
||||
}));
|
||||
}
|
||||
},
|
||||
})}
|
||||
// eslint-disable-next-line no-shadow
|
||||
onChange={(treeData) => setTreeData(sortTree(treeData))}
|
||||
onChange={(treeData) => setTreeData(treeData)}
|
||||
scaffoldBlockPxWidth={20}
|
||||
theme={FileExplorerTheme}
|
||||
treeData={treeData}
|
||||
treeData={mapComponents(treeData)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
:scope {
|
||||
background-color: #242424;
|
||||
padding: 1em;
|
||||
padding: 0.5em;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -9,6 +9,68 @@
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
.rstcustom__lineBlock {
|
||||
border-left: 1px solid #666666;
|
||||
height: 1.6em;
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
.rstcustom__row {
|
||||
left: -1.5em;
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
|
||||
.rstcustom__rowWrapper {
|
||||
cursor: pointer;
|
||||
padding-left: 0.5em;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
> div > .rstcustom__lineBlock:nth-last-of-type(2) {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.rstcustom__rowLabel {
|
||||
font-size: 0.9em;
|
||||
.title {
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
font-family: var(--title-font-family);
|
||||
padding: 0.25em 0 0;
|
||||
svg {
|
||||
fill: #aaaaaa;
|
||||
}
|
||||
&.directory {
|
||||
left: 1.5em;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.resource .text {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.rstcustom__node {
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
button {
|
||||
top: 0.75em;
|
||||
transform: translate3d(-33%, -50%, 0) scale(0.75);
|
||||
}
|
||||
}
|
||||
|
||||
.rstcustom__collapseButton,
|
||||
.rstcustom__expandButton {
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
&::after {
|
||||
border-top-color: #999999;
|
||||
&:hover {
|
||||
border-top-color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user