Skip to content

Commit

Permalink
Merge branch 'main' into widget-event-for-send-to-wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov authored Oct 17, 2024
2 parents 9ef5ce9 + cf48cf2 commit 21a02b0
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import type { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { useGasRefuel } from '../../hooks/useGasRefuel.js';
import { useSettings } from '../../stores/settings/useSettings.js';
import { useSettingsStore } from '../../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js';
import { AlertMessage } from '../AlertMessage/AlertMessage.js';
import { InfoMessageSwitch } from './GasMessage.style.js';

export const GasRefuelMessage: React.FC<BoxProps> = (props) => {
const { t } = useTranslation();
const setValue = useSettingsStore((state) => state.setValue);

const { setValue } = useSettingsActions();
const { enabledAutoRefuel } = useSettings(['enabledAutoRefuel']);

const { enabled, chain, isLoading: isRefuelLoading } = useGasRefuel();
Expand Down
4 changes: 2 additions & 2 deletions packages/widget/src/hooks/useLanguages.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useTranslation } from 'react-i18next';
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js';
import { useSettings } from '../stores/settings/useSettings.js';
import { useSettingsStore } from '../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../stores/settings/useSettingsActions.js';

export const useLanguages = () => {
const { t, i18n } = useTranslation();
const { languages } = useWidgetConfig();
const { language } = useSettings(['language']);
const setValue = useSettingsStore((state) => state.setValue);
const { setValue } = useSettingsActions();

const sortedLanguages = Object.keys(i18n.store.data).sort();

Expand Down
4 changes: 2 additions & 2 deletions packages/widget/src/hooks/useSettingMonitor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { shallow } from 'zustand/shallow';
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js';
import { useSettingsActions } from '../stores/settings/useSettingsActions.js';
import {
defaultConfigurableSettings,
setDefaultSettings,
useSettingsStore,
} from '../stores/settings/useSettingsStore.js';
import { useTools } from './useTools.js';
Expand All @@ -25,8 +25,8 @@ export const useSettingMonitor = () => {
shallow,
);
const { tools } = useTools();
const resetSettings = useSettingsStore((state) => state.reset);
const config = useWidgetConfig();
const { setDefaultSettings, resetSettings } = useSettingsActions();

const isSlippageChanged = config.slippage
? Number(slippage) !== config.slippage * 100
Expand Down
16 changes: 6 additions & 10 deletions packages/widget/src/pages/SelectEnabledToolsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { useDefaultElementId } from '../hooks/useDefaultElementId.js';
import { useHeader } from '../hooks/useHeader.js';
import { useScrollableContainer } from '../hooks/useScrollableContainer.js';
import { useTools } from '../hooks/useTools.js';
import { useSettingsActions } from '../stores/settings/useSettingsActions.js';
import { useSettingsStore } from '../stores/settings/useSettingsStore.js';

interface SelectAllCheckboxProps {
Expand Down Expand Up @@ -78,16 +79,11 @@ export const SelectEnabledToolsPage: React.FC<{
}> = ({ type }) => {
const typeKey = type.toLowerCase() as 'bridges' | 'exchanges';
const { tools } = useTools();
const [enabledTools, disabledTools, setToolValue, toggleToolKeys] =
useSettingsStore(
(state) => [
state[`_enabled${type}`],
state[`disabled${type}`],
state.setToolValue,
state.toggleToolKeys,
],
shallow,
);
const { setToolValue, toggleToolKeys } = useSettingsActions();
const [enabledTools, disabledTools] = useSettingsStore(
(state) => [state[`_enabled${type}`], state[`disabled${type}`]],
shallow,
);

const { t } = useTranslation();
const elementId = useDefaultElementId();
Expand Down
4 changes: 2 additions & 2 deletions packages/widget/src/pages/SettingsPage/GasPriceSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { useTranslation } from 'react-i18next';
import { CardTabs, Tab } from '../../components/Tabs/Tabs.style.js';
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js';
import { useSettings } from '../../stores/settings/useSettings.js';
import { useSettingsStore } from '../../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js';
import { BadgedValue } from './SettingsCard/BadgedValue.js';
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js';

export const GasPriceSettings: React.FC = () => {
const { t } = useTranslation();
const setValue = useSettingsStore((state) => state.setValue);
const { setValue } = useSettingsActions();
const { isGasPriceChanged } = useSettingMonitor();
const { gasPrice } = useSettings(['gasPrice']);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { useTranslation } from 'react-i18next';
import { CardTabs, Tab } from '../../components/Tabs/Tabs.style.js';
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js';
import { useSettings } from '../../stores/settings/useSettings.js';
import { useSettingsStore } from '../../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js';
import { BadgedValue } from './SettingsCard/BadgedValue.js';
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js';

const Priorities: Order[] = ['CHEAPEST', 'FASTEST'];

export const RoutePrioritySettings: React.FC = () => {
const { t } = useTranslation();
const setValue = useSettingsStore((state) => state.setValue);
const { setValue } = useSettingsActions();
const { isRoutePriorityChanged } = useSettingMonitor();
const { routePriority } = useSettings(['routePriority']);
const currentRoutePriority = routePriority ?? '';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { Percent, WarningRounded } from '@mui/icons-material';
import { Box, Typography } from '@mui/material';
import { Box, Typography, debounce } from '@mui/material';
import type { ChangeEventHandler, FocusEventHandler } from 'react';
import { useRef, useState } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js';
import { useSettings } from '../../../stores/settings/useSettings.js';
import {
defaultSlippage,
useSettingsStore,
} from '../../../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js';
import { defaultSlippage } from '../../../stores/settings/useSettingsStore.js';
import { formatSlippage } from '../../../utils/format.js';
import { BadgedValue } from '../SettingsCard/BadgedValue.js';
import { SettingCardExpandable } from '../SettingsCard/SettingCardExpandable.js';
Expand All @@ -24,36 +22,48 @@ export const SlippageSettings: React.FC = () => {
const { isSlippageOutsideRecommendedLimits, isSlippageChanged } =
useSettingMonitor();
const { slippage } = useSettings(['slippage']);
const setValue = useSettingsStore((state) => state.setValue);
const { setValue } = useSettingsActions();
const defaultValue = useRef(slippage);
const [focused, setFocused] = useState<'input' | 'button'>();

const customInputValue =
!slippage || slippage === defaultSlippage ? '' : slippage;

const [inputValue, setInputValue] = useState(customInputValue);

const handleDefaultClick = () => {
setValue('slippage', formatSlippage(defaultSlippage, defaultValue.current));
};

const handleInputUpdate: ChangeEventHandler<HTMLInputElement> = (event) => {
const { value } = event.target;
const debouncedSetValue = useMemo(() => debounce(setValue, 500), [setValue]);

setValue(
'slippage',
formatSlippage(value || defaultSlippage, defaultValue.current, true),
);
};
const handleInputUpdate: ChangeEventHandler<HTMLInputElement> = useCallback(
(event) => {
const { value } = event.target;

setInputValue(formatSlippage(value, defaultValue.current, true));

debouncedSetValue(
'slippage',
formatSlippage(value || defaultSlippage, defaultValue.current, true),
);
},
[debouncedSetValue],
);

const handleInputBlur: FocusEventHandler<HTMLInputElement> = (event) => {
setFocused(undefined);

const { value } = event.target;

setValue(
'slippage',
formatSlippage(value || defaultSlippage, defaultValue.current),
const formattedValue = formatSlippage(
value || defaultSlippage,
defaultValue.current,
);
};
setInputValue(formattedValue === defaultSlippage ? '' : formattedValue);

const customInputValue =
!slippage || slippage === defaultSlippage ? '' : slippage;
setValue('slippage', formattedValue);
};

const badgeColor = isSlippageOutsideRecommendedLimits
? 'warning'
Expand Down Expand Up @@ -98,7 +108,7 @@ export const SlippageSettings: React.FC = () => {
setFocused('input');
}}
onBlur={handleInputBlur}
value={customInputValue}
value={inputValue}
autoComplete="off"
/>
</SettingsFieldSet>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { config, createConfig, type SDKConfig } from '@lifi/sdk';
import { createContext, useContext, useId, useMemo } from 'react';
import { version } from '../../config/version.js';
import { setDefaultSettings } from '../../stores/settings/useSettingsStore.js';
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js';
import type { WidgetContextProps, WidgetProviderProps } from './types.js';

const initialContext: WidgetContextProps = {
Expand All @@ -20,6 +20,7 @@ export const WidgetProvider: React.FC<
React.PropsWithChildren<WidgetProviderProps>
> = ({ children, config: widgetConfig }) => {
const elementId = useId();
const { setDefaultSettings } = useSettingsActions();

if (!widgetConfig?.integrator) {
throw Error('Required property "integrator" is missing.');
Expand Down Expand Up @@ -68,7 +69,7 @@ export const WidgetProvider: React.FC<
integrator: widgetConfig.integrator,
};
}
}, [elementId, widgetConfig]);
}, [elementId, widgetConfig, setDefaultSettings]);
return (
<WidgetContext.Provider value={value}>{children}</WidgetContext.Provider>
);
Expand Down
9 changes: 7 additions & 2 deletions packages/widget/src/stores/settings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export type ValueSetter<S> = <K extends keyof S>(
value: S[Extract<K, string>],
) => void;

export type ValueGetter<S> = <K extends keyof S>(key: K) => S[K];

export type ValuesSetter<S> = <K extends keyof S>(
values: Record<K, S[Extract<K, string>]>,
) => void;
Expand All @@ -31,9 +33,10 @@ export interface SettingsProps {
_enabledExchanges: Record<string, boolean>;
}

export interface SettingsState extends SettingsProps {
export interface SettingsActions {
setValue: ValueSetter<SettingsProps>;
setValues: ValuesSetter<SettingsProps>;
getValue: ValueGetter<SettingsProps>;
getSettings: () => SettingsProps;
initializeTools(
toolType: SettingsToolType,
tools: string[],
Expand All @@ -44,6 +47,8 @@ export interface SettingsState extends SettingsProps {
reset(bridges: string[], exchanges: string[]): void;
}

export type SettingsState = SettingsProps & SettingsActions;

export interface SendToWalletState {
showSendToWallet: boolean;
}
Expand Down
24 changes: 11 additions & 13 deletions packages/widget/src/stores/settings/useAppearance.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { shallow } from 'zustand/shallow';
import type { Appearance } from '../../types/widget.js';
import { useSettingsStore } from './useSettingsStore.js';
import { useSettingsActions } from "../../stores/settings/useSettingsActions.js";
import type { Appearance } from "../../types/widget.js";
import { useSettingsStore } from "./useSettingsStore.js";

export const useAppearance = (): [
Appearance,
(appearance: Appearance) => void,
Appearance,
(appearance: Appearance) => void,
] => {
const [appearance, setValue] = useSettingsStore(
(state) => [state.appearance, state.setValue],
shallow,
);
const setAppearance = (appearance: Appearance) => {
setValue('appearance', appearance);
};
return [appearance, setAppearance];
const { setValue } = useSettingsActions();
const appearance = useSettingsStore((state) => state.appearance);
const setAppearance = (appearance: Appearance) => {
setValue("appearance", appearance);
};
return [appearance, setAppearance];
};
Loading

0 comments on commit 21a02b0

Please sign in to comment.