Skip to content

Commit

Permalink
feat: save key states to location.hash
Browse files Browse the repository at this point in the history
  • Loading branch information
alexesDev committed Jul 28, 2023
1 parent 01905ec commit d1ff25c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<QueryClientProvider client={queryClient}>
<StoreContext.Provider value={store}>
<Settings />
<KeyTree path="" />
<Settings newNode={defaultState.n} />
<KeyTree path="" defaultOpenKeys={defaultState.o} defaultDataKeys={defaultState.d} />
<AllPaths />
</StoreContext.Provider>
</QueryClientProvider>
Expand Down
20 changes: 15 additions & 5 deletions src/KeyTree.tsx
Original file line number Diff line number Diff line change
@@ -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 <div>Loading...</div>;
}
Expand Down Expand Up @@ -44,7 +48,13 @@ export function KeyTree({ path }: Props) {
a
</button>
</div>
{openKeys.includes(k) && <KeyTree path={path ? `${path}.${k}` : k} />}
{openKeys.includes(k) && (
<KeyTree
path={path ? `${path}.${k}` : k}
defaultOpenKeys={defaultOpenKeys}
defaultDataKeys={defaultDataKeys}
/>
)}
{dataKeys.includes(k) && <DataViewer path={path ? `${path}.${k}` : k} />}
</div>
);
Expand Down
8 changes: 6 additions & 2 deletions src/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
53 changes: 50 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { useQuery } from 'react-query';
import { useStore } from './store';

Expand Down Expand Up @@ -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<string[]>([]);
export const useToggleKeys = (defaultValues?: string[]): [string[], (k: string) => void] => {
const [keys, setKeys] = useState<string[]>(defaultValues || []);

const toggle = useCallback((key: string) => {
setKeys((ks) => {
Expand All @@ -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;
}
};

0 comments on commit d1ff25c

Please sign in to comment.