flow: resource tree
This commit is contained in:
parent
b6b715dc87
commit
36fd1184f6
|
@ -49,6 +49,7 @@ html {
|
||||||
background-color: #212121;
|
background-color: #212121;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
--active-color: rgb(0, 180, 204);
|
--active-color: rgb(0, 180, 204);
|
||||||
|
--title-font-family: Ubuntu, "Droid Sans", sans-serif;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
@ -152,7 +153,7 @@ select {
|
||||||
|
|
||||||
.react-tabs__tab-list {
|
.react-tabs__tab-list {
|
||||||
background-color: #272727;
|
background-color: #272727;
|
||||||
font-family: Ubuntu, "Droid Sans", sans-serif;
|
font-family: var(--title-font-family);
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import {compose} from '@avocado/core';
|
import {compose} from '@avocado/core';
|
||||||
|
import classnames from 'classnames';
|
||||||
import contempo from 'contempo';
|
import contempo from 'contempo';
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {useDispatch} from 'react-redux';
|
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';
|
import ResourcesPacket from '~/common/packets/resources.packet';
|
||||||
|
|
||||||
|
@ -18,18 +19,56 @@ const decorate = compose(
|
||||||
|
|
||||||
const rootUri = '/resources/cha0s/initial';
|
const rootUri = '/resources/cha0s/initial';
|
||||||
|
|
||||||
const sortTree = (tree) => {
|
const sortTree = (tree) => tree
|
||||||
tree.sort((l, r) => l.title.localeCompare(r.title));
|
.sort((l, r) => l.title.localeCompare(r.title))
|
||||||
if (tree.children) {
|
.map((node) => {
|
||||||
|
if (node.children) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
tree.children = sortTree(tree.children);
|
node.children = sortTree(node.children);
|
||||||
}
|
}
|
||||||
return tree;
|
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 Sidebar = () => {
|
||||||
const dispatch = useDispatch();
|
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) => {
|
useSocket((socket) => socket.send(new ResourcesPacket(), (uris) => {
|
||||||
const visited = {};
|
const visited = {};
|
||||||
const nodes = uris
|
const nodes = uris
|
||||||
|
@ -60,17 +99,17 @@ const Sidebar = () => {
|
||||||
visited[node.id] = true;
|
visited[node.id] = true;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
setTreeData(sortTree(getTreeFromFlatData({
|
setTreeData(getTreeFromFlatData({
|
||||||
flatData: nodes,
|
flatData: nodes,
|
||||||
rootKey: '',
|
rootKey: '',
|
||||||
})));
|
}));
|
||||||
}));
|
}));
|
||||||
return (
|
return (
|
||||||
<div className="sidebar">
|
<div className="sidebar">
|
||||||
<SortableTree
|
<SortableTree
|
||||||
canNodeHaveChildren={(node) => !node.uri}
|
canNodeHaveChildren={(node) => !node.uri}
|
||||||
generateNodeProps={({node}) => ({
|
generateNodeProps={({node}) => ({
|
||||||
onClick: () => {
|
onClick: (event) => {
|
||||||
if (node.uri) {
|
if (node.uri) {
|
||||||
dispatch(setActiveResourceUri(node.uri));
|
dispatch(setActiveResourceUri(node.uri));
|
||||||
}
|
}
|
||||||
|
@ -81,17 +120,21 @@ const Sidebar = () => {
|
||||||
path: node.id.split('/'),
|
path: node.id.split('/'),
|
||||||
newNode: {
|
newNode: {
|
||||||
...node,
|
...node,
|
||||||
|
children: (event.ctrlKey && event.altKey)
|
||||||
|
? toggleExpandedForAll({treeData: node.children, expanded: !isExpanded})
|
||||||
|
: node.children,
|
||||||
expanded: !isExpanded,
|
expanded: !isExpanded,
|
||||||
},
|
},
|
||||||
getNodeKey: ({node: {id}}) => id,
|
getNodeKey: ({node: {title}}) => title,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
onChange={(treeData) => setTreeData(sortTree(treeData))}
|
onChange={(treeData) => setTreeData(treeData)}
|
||||||
|
scaffoldBlockPxWidth={20}
|
||||||
theme={FileExplorerTheme}
|
theme={FileExplorerTheme}
|
||||||
treeData={treeData}
|
treeData={mapComponents(treeData)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
:scope {
|
:scope {
|
||||||
background-color: #242424;
|
background-color: #242424;
|
||||||
padding: 1em;
|
padding: 0.5em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,68 @@
|
||||||
box-shadow: none;
|
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 {
|
.rstcustom__rowWrapper {
|
||||||
cursor: pointer;
|
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