Skip to content

Commit

Permalink
feat: implement WidgetProvider & useWidget for accessing specific wid…
Browse files Browse the repository at this point in the history
…get data
  • Loading branch information
samobasquiat authored and yeager-eren committed Nov 18, 2023
1 parent 52fcd52 commit 65f1824
Show file tree
Hide file tree
Showing 19 changed files with 225 additions and 149 deletions.
6 changes: 3 additions & 3 deletions widget/embedded/src/QueueManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useWalletsStore } from './store/wallets';
import { getConfig } from './utils/configs';
import { walletAndSupportedChainsNames } from './utils/wallets';

function QueueManager(props: PropsWithChildren) {
function QueueManager(props: PropsWithChildren<{ apiKey?: string }>) {
const {
providers,
getSigners,
Expand All @@ -29,9 +29,9 @@ function QueueManager(props: PropsWithChildren) {

const swapQueueDef = useMemo(() => {
return makeQueueDefinition({
API_KEY: getConfig('API_KEY'),
API_KEY: props.apiKey || getConfig('API_KEY'),
});
}, []);
}, [props.apiKey]);

const blockchains = useAppStore().blockchains();
const connectedWallets = useWalletsStore.use.connectedWallets();
Expand Down
106 changes: 0 additions & 106 deletions widget/embedded/src/Widget.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions widget/embedded/src/containers/App/App.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { styled } from '@rango-dev/ui';

export const MainContainer = styled('div', {
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
fontFamily: '$widget',
boxSizing: 'border-box',
'& *, *::before, *::after': {
boxSizing: 'inherit',
listStyleType: 'none',
},
'& *:focus-visible': {
outlineColor: '$info500',
transition: 'none',
},
});
65 changes: 65 additions & 0 deletions widget/embedded/src/containers/App/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type { WalletType } from '@rango-dev/wallets-shared';

import { I18nManager } from '@rango-dev/ui';
import React, { useContext, useEffect, useMemo, useState } from 'react';

import { AppRouter } from '../../components/AppRouter';
import { AppRoutes } from '../../components/AppRoutes';
import { WidgetEvents } from '../../components/WidgetEvents';
import { globalFont } from '../../globalStyles';
import { useLanguage } from '../../hooks/useLanguage';
import { useTheme } from '../../hooks/useTheme';
import { useAppStore } from '../../store/AppStore';
import { useNotificationStore } from '../../store/notification';
import { useSettingsStore } from '../../store/settings';
import { initConfig } from '../../utils/configs';
import { WidgetContext } from '../Wallets';

import { MainContainer } from './App.styles';

export function Main() {
globalFont();

const { fetch: fetchMeta, config } = useAppStore();
const { activeTheme } = useTheme(config?.theme || {});
const { activeLanguage, changeLanguage } = useLanguage();
const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] =
useState<string>('');
const [disconnectedWallet, setDisconnectedWallet] = useState<WalletType>();
const widgetContext = useContext(WidgetContext);

useMemo(() => {
if (config?.apiKey) {
initConfig({
API_KEY: config?.apiKey,
});
}
}, [config]);
useEffect(() => {
void fetchMeta().catch();
void useSettingsStore.persist.rehydrate();
void useNotificationStore.persist.rehydrate();
widgetContext.onConnectWallet(setLastConnectedWalletWithNetwork);
}, []);
useEffect(() => {
if (config?.language) {
changeLanguage(config.language);
}
}, [config?.language]);

return (
<I18nManager language={activeLanguage}>
<MainContainer id="swap-container" className={activeTheme()}>
<WidgetEvents />
<AppRouter
lastConnectedWallet={lastConnectedWalletWithNetwork}
disconnectedWallet={disconnectedWallet}
clearDisconnectedWallet={() => {
setDisconnectedWallet(undefined);
}}>
<AppRoutes />
</AppRouter>
</MainContainer>
</I18nManager>
);
}
1 change: 1 addition & 0 deletions widget/embedded/src/containers/App/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Main } from './App';
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import type { WidgetConfig } from './types';
import type { ProvidersOptions } from './utils/providers';
import type {
OnConnectHandler,
PropTypes,
WidgetContextInterface,
} from './Wallets.types';
import type { ProvidersOptions } from '../../utils/providers';
import type { EventHandler } from '@rango-dev/wallets-react';
import type { Network } from '@rango-dev/wallets-shared';
import type { PropsWithChildren } from 'react';
Expand All @@ -8,37 +12,28 @@ import { Events, Provider } from '@rango-dev/wallets-react';
import { isEvmBlockchain } from 'rango-sdk';
import React, { createContext, useEffect, useRef } from 'react';

import { useWalletProviders } from './hooks/useWalletProviders';
import { AppStoreProvider, useAppStore } from './store/AppStore';
import { useWalletsStore } from './store/wallets';
import { useWalletProviders } from '../../hooks/useWalletProviders';
import { AppStoreProvider, useAppStore } from '../../store/AppStore';
import { useWalletsStore } from '../../store/wallets';
import {
prepareAccountsForWalletStore,
walletAndSupportedChainsNames,
} from './utils/wallets';

type OnConnectHandler = (key: string) => void;
interface WidgetContextInterface {
onConnectWallet(handler: OnConnectHandler): void;
}
} from '../../utils/wallets';

export const WidgetContext = createContext<WidgetContextInterface>({
onConnectWallet: () => {
return;
},
});

function Main(
props: PropsWithChildren<{
providers: WidgetConfig['wallets'];
options?: ProvidersOptions;
onUpdateState?: EventHandler;
config: WidgetConfig;
}>
) {
function Main(props: PropsWithChildren<PropTypes>) {
const updateConfig = useAppStore().updateConfig;
const blockchains = useAppStore().blockchains();
const tokens = useAppStore().tokens();
const { providers } = useWalletProviders(props.providers, props?.options);
const walletOptions: ProvidersOptions = {
walletConnectProjectId: props.config?.walletConnectProjectId,
};
const { providers } = useWalletProviders(props.config.wallets, walletOptions);
const disconnectWallet = useWalletsStore.use.disconnectWallet();
const connectWallet = useWalletsStore.use.connectWallet();
const onConnectWalletHandler = useRef<OnConnectHandler>();
Expand Down Expand Up @@ -117,14 +112,7 @@ function Main(
);
}

export function WidgetWallets(
props: PropsWithChildren<{
providers: WidgetConfig['wallets'];
options?: ProvidersOptions;
onUpdateState?: EventHandler;
config: WidgetConfig;
}>
) {
export function WidgetWallets(props: PropsWithChildren<PropTypes>) {
const { config, ...otherProps } = props;
return (
<AppStoreProvider config={config}>
Expand Down
12 changes: 12 additions & 0 deletions widget/embedded/src/containers/Wallets/Wallets.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { WidgetConfig } from '../../types';
import type { EventHandler } from '@rango-dev/wallets-react';

export type OnConnectHandler = (key: string) => void;
export interface WidgetContextInterface {
onConnectWallet(handler: OnConnectHandler): void;
}

export interface PropTypes {
onUpdateState?: EventHandler;
config: WidgetConfig;
}
1 change: 1 addition & 0 deletions widget/embedded/src/containers/Wallets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { WidgetWallets, WidgetContext } from './Wallets';
19 changes: 19 additions & 0 deletions widget/embedded/src/containers/Widget/Widget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { WidgetProps } from './Widget.types';
import type { PropsWithChildren } from 'react';

import React from 'react';

import { DEFAULT_CONFIG } from '../../store/slices/config';
import { Main } from '../App';
import { WidgetProvider } from '../WidgetProvider';

export function Widget(props: PropsWithChildren<WidgetProps>) {
if (!props.config?.externalWallets) {
return (
<WidgetProvider config={props.config ?? DEFAULT_CONFIG}>
<Main />
</WidgetProvider>
);
}
return <Main />;
}
5 changes: 5 additions & 0 deletions widget/embedded/src/containers/Widget/Widget.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { WidgetConfig } from '../../types';

export type WidgetProps = {
config?: WidgetConfig;
};
2 changes: 2 additions & 0 deletions widget/embedded/src/containers/Widget/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Widget } from './Widget';
export type { WidgetProps } from './Widget.types';
36 changes: 36 additions & 0 deletions widget/embedded/src/containers/WidgetInfo/WidgetInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { WidgetInfoContextInterface } from './WidgetInfo.types';

import { useManager } from '@rango-dev/queue-manager-react';
import React, { createContext, useContext, useMemo } from 'react';

import { getPendingSwaps } from '../../utils/queue';

export const WidgetInfoContext = createContext<
WidgetInfoContextInterface | undefined
>(undefined);

export function WidgetInfo(props: React.PropsWithChildren) {
const { manager } = useManager();
const swaps = getPendingSwaps(manager);
const value = useMemo(() => {
return {
swaps,
};
}, [manager, swaps]);

return (
<WidgetInfoContext.Provider value={value}>
{props.children}
</WidgetInfoContext.Provider>
);
}

export function useWidget(): WidgetInfoContextInterface {
const context = useContext(WidgetInfoContext);
if (!context) {
throw new Error(
'useWidget can only be used within the WidgetProvider component'
);
}
return context;
}
5 changes: 5 additions & 0 deletions widget/embedded/src/containers/WidgetInfo/WidgetInfo.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { PendingSwapWithQueueID } from '@rango-dev/queue-manager-rango-preset';

export interface WidgetInfoContextInterface {
swaps?: PendingSwapWithQueueID[];
}
1 change: 1 addition & 0 deletions widget/embedded/src/containers/WidgetInfo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { WidgetInfo, useWidget } from './WidgetInfo';
19 changes: 19 additions & 0 deletions widget/embedded/src/containers/WidgetProvider/WidgetProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { PropTypes } from './WidgetProvider.types';
import type { PropsWithChildren } from 'react';

import React from 'react';

import QueueManager from '../../QueueManager';
import { WidgetWallets } from '../Wallets';
import { WidgetInfo } from '../WidgetInfo';

export function WidgetProvider(props: PropsWithChildren<PropTypes>) {
const { onUpdateState, config } = props;
return (
<WidgetWallets config={config} onUpdateState={onUpdateState}>
<QueueManager apiKey={config.apiKey}>
<WidgetInfo>{props.children}</WidgetInfo>
</QueueManager>
</WidgetWallets>
);
}
Loading

0 comments on commit 65f1824

Please sign in to comment.