You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
6.8 KiB
237 lines
6.8 KiB
import React from 'react'; |
|
import { makeStyles } from '@material-ui/core/styles'; |
|
import List from '@material-ui/core/List'; |
|
import ListItem from '@material-ui/core/ListItem'; |
|
import ListItemText from '@material-ui/core/ListItemText'; |
|
import ListSubheader from '@material-ui/core/ListSubheader'; |
|
import ExpandLess from '@material-ui/icons/ExpandLess'; |
|
import ExpandMore from '@material-ui/icons/ExpandMore'; |
|
import Collapse from '@material-ui/core/Collapse'; |
|
|
|
import { user_query_from_browsed_album, user_query_from_browsed_tag } from './queries'; |
|
|
|
class NavTreeItem { |
|
display_name = false; |
|
data = false; |
|
children = []; |
|
|
|
constructor(display_name, data, children) { |
|
this.display_name = display_name; |
|
this.data = data; |
|
this.children = children; |
|
} |
|
} |
|
|
|
export function split_path(path) { |
|
var r = path.split("/"); |
|
if(path[0] === '/') { r.shift(); } |
|
return r; |
|
} |
|
|
|
export function insert_into_album_tree(treebaseitem, treeitem) { |
|
var parts = split_path(treeitem.data); |
|
var current_item = treebaseitem; |
|
for (var i = 0; i < parts.length; i++) { |
|
var part = parts[i]; |
|
var subitem = false; |
|
var required_path = (current_item.data === "/") ? |
|
current_item.data + part : |
|
current_item.data + "/" + part; |
|
|
|
for (var j = 0; j < current_item.children.length; j++) { |
|
var child = current_item.children[j]; |
|
if (child.data === required_path) { |
|
subitem = child; |
|
break; |
|
} |
|
} |
|
if (!subitem) { |
|
var new_sub = new NavTreeItem( |
|
part, |
|
required_path, |
|
[] |
|
); |
|
current_item.children.push(new_sub); |
|
subitem = new_sub; |
|
} |
|
current_item = subitem; |
|
}; |
|
} |
|
|
|
export function build_albums_tree(all_db_albums) { |
|
var tree = new NavTreeItem("", "/", []); |
|
for (var i = 0; i < all_db_albums.length; i++) { |
|
var album = all_db_albums[i]; |
|
if (album.state.relative_path !== "/") { // we already made the base, skip that one |
|
var item = new NavTreeItem( |
|
album.state.name, |
|
album.state.relative_path, |
|
[] |
|
); |
|
insert_into_album_tree(tree, item); |
|
} |
|
}; |
|
return tree; |
|
} |
|
|
|
export function insert_into_tag_tree(treebaseitem, treeitem) { |
|
var parts = split_path(treeitem.data); |
|
var current_item = treebaseitem; |
|
for (var i = 0; i < parts.length; i++) { |
|
var part = parts[i]; |
|
var subitem = false; |
|
var required_path = (current_item.data === "") ? |
|
current_item.data + part : |
|
current_item.data + "/" + part; |
|
|
|
for (var j = 0; j < current_item.children.length; j++) { |
|
var child = current_item.children[j]; |
|
if (child.data === required_path) { |
|
subitem = child; |
|
break; |
|
} |
|
} |
|
if (!subitem) { |
|
var new_sub = new NavTreeItem( |
|
part, |
|
required_path, |
|
[] |
|
); |
|
current_item.children.push(new_sub); |
|
subitem = new_sub; |
|
} |
|
current_item = subitem; |
|
}; |
|
} |
|
|
|
export function build_tags_tree(all_db_tags) { |
|
var tree = new NavTreeItem("", "", []); |
|
for (var i = 0; i < all_db_tags.length; i++) { |
|
var tag = all_db_tags[i]; |
|
var item = new NavTreeItem( |
|
tag.state.name, |
|
tag.state.fullname, |
|
[] |
|
); |
|
insert_into_tag_tree(tree, item); |
|
}; |
|
|
|
return tree; |
|
} |
|
|
|
const useStyles = makeStyles(theme => ({ |
|
root: { |
|
width: '100%', |
|
maxWidth: 360, |
|
color: theme.color, |
|
}, |
|
nested: { |
|
paddingLeft: theme.spacing(4), |
|
color: theme.color, |
|
}, |
|
})); |
|
|
|
export function NavListItem(props) { |
|
const classes = useStyles(); |
|
const [open, setOpen] = React.useState(false); |
|
const { navitem, onSelect } = props; |
|
|
|
const handleExpandClick = () => { |
|
setOpen(!open); |
|
} |
|
|
|
const handleClick = () => { |
|
if (onSelect) { |
|
onSelect(navitem); |
|
} |
|
} |
|
|
|
if (navitem.children.length === 0) { |
|
return ( |
|
<ListItem button onClick={handleClick}> |
|
<ListItemText primary={navitem.display_name} /> |
|
</ListItem> |
|
) |
|
} else { |
|
return ( |
|
<> |
|
<ListItem button > |
|
<ListItemText primary={navitem.display_name} onClick={handleClick} /> |
|
{open ? <ExpandLess onClick={handleExpandClick} /> : <ExpandMore onClick={handleExpandClick} />} |
|
</ListItem> |
|
<Collapse in={open} timeout="auto" unmountOnExit> |
|
<List component="nav" className={classes.nested}> |
|
{ |
|
navitem.children.map(elem => { |
|
return <NavListItem navitem={elem} onSelect={onSelect} /> |
|
}) |
|
} |
|
</List> |
|
</Collapse> |
|
</> |
|
) |
|
} |
|
} |
|
|
|
export function Browser(props) { |
|
const classes = useStyles(); |
|
const { albums, tags, onNewQuery } = props; |
|
|
|
const propagateQuery = (query) => { |
|
if (onNewQuery) { |
|
onNewQuery(query); |
|
} |
|
} |
|
|
|
const propagateAlbumQuery = (navitem) => { |
|
propagateQuery( |
|
user_query_from_browsed_album(navitem.data) |
|
); |
|
} |
|
|
|
const propagateTagQuery = (navitem) => { |
|
propagateQuery( |
|
user_query_from_browsed_tag(navitem.data) |
|
); |
|
} |
|
|
|
const albums_tree = build_albums_tree(albums); |
|
const tags_tree = build_tags_tree(tags); |
|
|
|
return ( |
|
<> |
|
<List |
|
component="nav" |
|
aria-labelledby="nested-list-subheader" |
|
subheader={ |
|
<ListSubheader component="div" id="nested-list-subheader"> |
|
Album Navigation |
|
</ListSubheader> |
|
} |
|
className={classes.root} |
|
> |
|
{ |
|
albums_tree.children.map(elem => { |
|
return <NavListItem navitem={elem} onSelect={propagateAlbumQuery} /> |
|
}) |
|
} |
|
</List> |
|
<List |
|
component="nav" |
|
aria-labelledby="nested-list-subheader" |
|
subheader={ |
|
<ListSubheader component="div" id="nested-list-subheader"> |
|
Tag Navigation |
|
</ListSubheader> |
|
} |
|
className={classes.root} |
|
> |
|
{ |
|
tags_tree.children.map(elem => { |
|
return <NavListItem navitem={elem} onSelect={propagateTagQuery} /> |
|
}) |
|
} |
|
</List> |
|
</> |
|
) |
|
} |