Skip to content

Commit

Permalink
feat: discover explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
originalix committed Oct 20, 2023
1 parent 0cbefa8 commit 46eada0
Show file tree
Hide file tree
Showing 13 changed files with 930 additions and 11 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"eslint": "^8.25.0",
"expo": "~49.0.13",
"expo-status-bar": "~1.6.0",
"jotai": "^2.4.3",
"memoizee": "^0.4.15",
"natsort": "^2.0.3",
"prettier": "^2.8.1",
Expand Down
32 changes: 32 additions & 0 deletions packages/kit/src/components/DebugRenderTracker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { type ComponentType, type FC, type ReactElement, useRef } from 'react';

import platformEnv from '@onekeyhq/shared/src/platformEnv';

const css1 = 'debug-render-tracker-animated-bg';
const css2 = 'debug-render-tracker-animated-bg0';

function DebugRenderTracker(props: { children: ReactElement }): ReactElement {
const { children } = props;
const cls = useRef<typeof css1 | typeof css2>(css1);
if (process.env.NODE_ENV !== 'production') {
if (platformEnv.isRuntimeBrowser) {
cls.current = cls.current === css1 ? css2 : css1;
return <div className={cls.current}>{children}</div>;
}
}

return children;
}

const withDebugRenderTracker = <P extends object>(
WrappedComponent: ComponentType<P>,
) => {
const WithRenderTracker: FC<P> = (props) => (
<DebugRenderTracker>
<WrappedComponent {...props} />
</DebugRenderTracker>
);

return WithRenderTracker;
};
export { withDebugRenderTracker, DebugRenderTracker };
10 changes: 10 additions & 0 deletions packages/kit/src/components/WebView/mock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ export const backgroundApiProxy = {
connectBridge: (jsBridge: any) => {},
bridgeReceiveHandler: (_: any): Promise<any> => Promise.resolve({}),
};

export const simpleDb = {
discoverWebTabs: {
getRawData: () =>
Promise.resolve({
tabs: [],
}),
setRawData: (_: any) => {},
},
};
14 changes: 14 additions & 0 deletions packages/kit/src/hooks/useIsMounted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useEffect, useRef } from 'react';

function useIsMounted() {
const isMountedRef = useRef(true);
useEffect(() => {
isMountedRef.current = true;
return () => {
isMountedRef.current = false;
};
}, []);
return isMountedRef;
}

export { useIsMounted };
155 changes: 155 additions & 0 deletions packages/kit/src/hooks/usePromiseResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { useEffect, useMemo, useRef, useState } from 'react';

import { useIsFocused } from '@react-navigation/core';
import { debounce } from 'lodash';

import { wait } from '../utils/helper';

import { useIsMounted } from './useIsMounted';

type IRunnerConfig = { triggerByDeps?: boolean };

type IPromiseResultOptions<T> = {
initResult?: T; // TODO rename to initData
watchLoading?: boolean; // make isLoading work, which cause more once render
loadingDelay?: number;
checkIsMounted?: boolean;
checkIsFocused?: boolean;
debounced?: number;
};

export function usePromiseResult<T>(
method: (...args: any[]) => Promise<T>,
deps: any[],
options: { initResult: T } & IPromiseResultOptions<T>,
): { result: T; isLoading: boolean | undefined };

export function usePromiseResult<T>(
method: (...args: any[]) => Promise<T>,
deps: any[],
options?: IPromiseResultOptions<T>,
): {
result: T | undefined;
isLoading: boolean | undefined;
run: (config?: IRunnerConfig) => Promise<void>;
};

export function usePromiseResult<T>(
method: (...args: any[]) => Promise<T>,
deps: any[] = [],
options: IPromiseResultOptions<T> = {},
): {
result: T | undefined;
isLoading: boolean | undefined;
run: (config?: IRunnerConfig) => Promise<void>;
} {
const [result, setResult] = useState<T | undefined>(
options.initResult as any,
);
const [isLoading, setIsLoading] = useState<boolean | undefined>();
const isMountedRef = useIsMounted();
const isFocused = useIsFocused();
const isFocusedRef = useRef<boolean>(isFocused);
isFocusedRef.current = isFocused;
const methodRef = useRef<typeof method>(method);
methodRef.current = method;
const optionsRef = useRef(options);
optionsRef.current = {
watchLoading: false,
loadingDelay: 0,
checkIsMounted: true,
checkIsFocused: true,
...options,
};
const isDepsChangedOnBlur = useRef(false);

const run = useMemo(
() => {
const { watchLoading, loadingDelay, checkIsMounted, checkIsFocused } =
optionsRef.current;

const setLoadingTrue = () => {
if (watchLoading) setIsLoading(true);
};
const setLoadingFalse = () => {
if (watchLoading) setIsLoading(false);
};
const shouldSetState = () => {
let flag = true;
if (checkIsMounted && !isMountedRef.current) {
flag = false;
}
if (checkIsFocused && !isFocusedRef.current) {
flag = false;
}
return flag;
};

const runner = async (config?: IRunnerConfig) => {
if (config?.triggerByDeps && !isFocusedRef.current) {
isDepsChangedOnBlur.current = true;
}
try {
if (shouldSetState()) {
setLoadingTrue();
const r = await methodRef?.current?.();
if (shouldSetState()) {
setResult(r);
}
}
} finally {
if (loadingDelay && watchLoading) {
await wait(loadingDelay);
}
if (shouldSetState()) {
setLoadingFalse();
}
}
};

if (optionsRef.current.debounced) {
const runnderDebounced = debounce(
runner,
optionsRef.current.debounced,
{
leading: false,
trailing: true,
},
);
return async (config?: IRunnerConfig) => {
if (shouldSetState()) {
setLoadingTrue();
}
await runnderDebounced(config);
};
}

return runner;
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);

useEffect(() => {
run({ triggerByDeps: true });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);

useEffect(() => {
if (
isFocused &&
optionsRef.current.checkIsFocused &&
isDepsChangedOnBlur.current
) {
isDepsChangedOnBlur.current = false;
run();
}
}, [isFocused, run]);

// TODO rename result to data
return { result, isLoading, run };
}

export const useAsyncCall = usePromiseResult;
export const useAsyncResult = usePromiseResult;
export const useAsyncData = usePromiseResult;
28 changes: 17 additions & 11 deletions packages/kit/src/views/Components/stories/Webview.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import WebView from '@onekeyhq/kit/src/components/WebView';

const WebviewGallery = () => (
<WebView
src="https://dapp-example.onekeytest.com"
containerProps={{
w: '100%',
h: '100%',
}}
/>
);
// import WebView from '@onekeyhq/kit/src/components/WebView';

// const WebviewGallery = () => (
// <WebView
// src="https://dapp-example.onekeytest.com"
// containerProps={{
// w: '100%',
// h: '100%',
// }}
// />
// );

// export default WebviewGallery;

import Explorer from '@onekeyhq/kit/src/views/Discover/Explorer';

const WebviewGallery = () => <Explorer />;

export default WebviewGallery;
Loading

0 comments on commit 46eada0

Please sign in to comment.