mirror of
https://github.com/irislib/iris-messenger.git
synced 2024-09-16 16:23:28 +00:00
add local state explorer
This commit is contained in:
parent
8edb276c9c
commit
e409d244d9
@ -36,7 +36,8 @@ export default class LocalForageAdapter extends Adapter {
|
||||
.keys()
|
||||
.then((keys) => {
|
||||
keys.forEach((key) => {
|
||||
if (key.startsWith(`${path}/`)) {
|
||||
const remainingPath = key.replace(`${path}/`, '');
|
||||
if (key.startsWith(`${path}/`) && !remainingPath.includes('/')) {
|
||||
localForage
|
||||
.getItem<NodeValue | null>(key)
|
||||
.then((result) => {
|
||||
|
@ -22,7 +22,8 @@ export default class MemoryAdapter extends Adapter {
|
||||
|
||||
list(path: string, callback: Callback): Unsubscribe {
|
||||
for (const [storedPath, storedValue] of this.storage) {
|
||||
if (storedPath.startsWith(`${path}/`)) {
|
||||
const remainingPath = storedPath.replace(`${path}/`, '');
|
||||
if (storedPath.startsWith(`${path}/`) && !remainingPath.includes('/')) {
|
||||
callback(storedValue.value, storedPath, storedValue.updatedAt, () => {});
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import localState from '@/state/LocalState.ts';
|
||||
import ExplorerNode from '@/views/explorer/ExplorerNode.tsx';
|
||||
import View from '@/views/View.tsx';
|
||||
|
||||
type Props = {
|
||||
@ -9,6 +11,9 @@ const Explorer = ({ p }: Props) => {
|
||||
return (
|
||||
<View hideSideBar={true}>
|
||||
<div>{p}</div>
|
||||
<div className="m-2 md:mx-4">
|
||||
<ExplorerNode expanded={true} name="Local state" node={localState} />
|
||||
</div>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
63
src/js/views/explorer/ExplorerNode.tsx
Normal file
63
src/js/views/explorer/ExplorerNode.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import Node from '@/state/Node';
|
||||
|
||||
type Props = {
|
||||
node: Node;
|
||||
level?: number;
|
||||
expanded?: boolean;
|
||||
name?: string;
|
||||
};
|
||||
|
||||
export default function ExplorerNode({ node, level = 0, expanded = false, name }: Props) {
|
||||
const [children, setChildren] = useState<{ [key: string]: Node }>({});
|
||||
const [isOpen, setIsOpen] = useState(expanded);
|
||||
|
||||
useEffect(() => {
|
||||
node.map((_value, key) => {
|
||||
if (!children[key]) {
|
||||
setChildren((prev) => {
|
||||
const childName = key.split('/').pop()!;
|
||||
return { ...prev, [key]: node.get(childName) };
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [node.id]);
|
||||
|
||||
const toggleOpen = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
const isEven = level % 2 === 0;
|
||||
const displayName = name || node.id.split('/').pop()!;
|
||||
|
||||
return (
|
||||
<div className={`relative ${isEven ? 'bg-gray-800' : 'bg-gray-700'}`}>
|
||||
<div className="flex items-center cursor-pointer text-white" onClick={toggleOpen}>
|
||||
<div className={`transition ${isOpen ? 'transform rotate-90' : ''}`}>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M9 5l7 7-7 7"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<span className="ml-2">{displayName}</span>
|
||||
</div>
|
||||
<div className={`ml-6 ${isOpen ? 'block' : 'hidden'}`}>
|
||||
{Object.values(children).map((child) => (
|
||||
<ExplorerNode key={node.id + child.id} node={child} level={level + 1} expanded={false} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user