diff --git a/src/App.tsx b/src/App.tsx
index bb06ea0..e601378 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,15 +4,17 @@ import { KeyTree } from './KeyTree';
import { Settings } from './Settings';
import { AllPaths } from './AllPaths';
import { store } from './store';
+import { getDefaultHashState } from './utils';
const queryClient = new QueryClient();
+const defaultState = getDefaultHashState();
function App() {
return (
-
-
+
+
diff --git a/src/KeyTree.tsx b/src/KeyTree.tsx
index bd2277b..6cbe123 100644
--- a/src/KeyTree.tsx
+++ b/src/KeyTree.tsx
@@ -1,16 +1,20 @@
-import { useAbciQuery, useToggleKeys } from './utils';
+import { useAbciQuery, useToggleKeys, useTrackKeys } from './utils';
import { DataViewer } from './DataViewer';
import * as s from './KeyTree.module.css';
type Props = {
path: string;
+ defaultOpenKeys: { [path: string]: string[] };
+ defaultDataKeys: { [path: string]: string[] };
};
-export function KeyTree({ path }: Props) {
- const [openKeys, toggleOpenKey] = useToggleKeys();
- const [dataKeys, toggleDataKey] = useToggleKeys();
+export function KeyTree({ path, defaultOpenKeys, defaultDataKeys }: Props) {
+ const [openKeys, toggleOpenKey] = useToggleKeys(defaultOpenKeys[path]);
+ const [dataKeys, toggleDataKey] = useToggleKeys(defaultDataKeys[path]);
const { isLoading, error, data } = useAbciQuery(`/custom/vstorage/children/${path}`);
+ useTrackKeys(path, openKeys, dataKeys);
+
if (isLoading) {
return
Loading...
;
}
@@ -44,7 +48,13 @@ export function KeyTree({ path }: Props) {
a
- {openKeys.includes(k) && }
+ {openKeys.includes(k) && (
+
+ )}
{dataKeys.includes(k) && }
);
diff --git a/src/Settings.tsx b/src/Settings.tsx
index 85d23b9..c36b086 100644
--- a/src/Settings.tsx
+++ b/src/Settings.tsx
@@ -2,9 +2,13 @@ import { useState, FormEvent } from 'react';
import { useStore } from './store';
import * as s from './Settings.module.css';
-export function Settings() {
+type Props = {
+ newNode: string;
+};
+
+export function Settings({ newNode }: Props) {
const { node, foldAmountObject, dispatch } = useStore('node', 'foldAmountObject');
- const [currentNode, setCurrentNode] = useState(node);
+ const [currentNode, setCurrentNode] = useState(newNode || node);
const saveNode = (e: FormEvent) => {
e.preventDefault();
diff --git a/src/utils.ts b/src/utils.ts
index 7269d59..c80468d 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,4 +1,4 @@
-import { useState, useCallback } from 'react';
+import { useEffect, useState, useCallback } from 'react';
import { useQuery } from 'react-query';
import { useStore } from './store';
@@ -26,8 +26,8 @@ export const useAbciQuery = (path: string, height?: number) => {
return useQuery(`${node}:${path}:${height}`, () => abciQuery(node, path, height));
};
-export const useToggleKeys = (): [string[], (k: string) => void] => {
- const [keys, setKeys] = useState([]);
+export const useToggleKeys = (defaultValues?: string[]): [string[], (k: string) => void] => {
+ const [keys, setKeys] = useState(defaultValues || []);
const toggle = useCallback((key: string) => {
setKeys((ks) => {
@@ -40,3 +40,50 @@ export const useToggleKeys = (): [string[], (k: string) => void] => {
return [keys, toggle];
};
+
+type HashState = {
+ // node
+ n: string;
+ // open keys
+ o: { [key: string]: string[] };
+ // data
+ d: { [key: string]: string[] };
+};
+
+export const getDefaultHashState = () => {
+ const currentHash = atob(window.location.hash.substr(1));
+
+ if (currentHash) {
+ return JSON.parse(currentHash) as HashState;
+ }
+
+ return {
+ n: '',
+ o: {},
+ d: {},
+ };
+};
+
+export const useTrackKeys = (path: string, openKeys: string[], dataKeys: string[]) => {
+ const data = getDefaultHashState();
+
+ data.n = useNode();
+
+ if (openKeys.length > 0) {
+ data.o = { ...data.o, [path]: openKeys };
+ } else {
+ delete data.o[path];
+ }
+
+ if (dataKeys.length > 0) {
+ data.d = { ...data.d, [path]: dataKeys };
+ } else {
+ delete data.d[path];
+ }
+
+ const newLocation = btoa(JSON.stringify(data));
+
+ if (newLocation !== window.location.hash.substr(1)) {
+ window.location.hash = newLocation;
+ }
+};