@@ -1,5 +1,5 @@
1−import React, { useCallback, useEffect, useState } from 'react';
1+import React, { useCallback, useEffect, useState, FormEvent } from 'react';
2−import { Box, Row } from '@tlon/indigo-react';
2+import { Box, Row, StatelessTextInput } from '@tlon/indigo-react';
3import { DEFAULT_GAS_PRICE_GWEI } from 'lib/constants';
3import { DEFAULT_GAS_PRICE_GWEI } from 'lib/constants';
4import useGasPrice from 'lib/useGasPrice';
4import useGasPrice from 'lib/useGasPrice';
@@ -10,20 +10,49 @@ const PRICE_LABELS = ['Fast', 'Average', 'Slow'];
11export interface GasPrice {
11export interface GasPrice {
12 price: number;
12 price: number;
13− wait: number;
13+ wait: string;
16−const formatPriceWait = ({ price, wait }: GasPrice) =>
17− `${price} gwei (${Math.round(wait * 100) / 100} min)`;
16+export const formatWait = (wait: number) => Math.round(wait * 100) / 100;
17+export const formatDisplay = ({ price, wait }: GasPrice) =>
18+ `${price} gwei (${wait} min)`;
20+export default function FeeDropdown({
19−const FeeDropdown = ({ setGasPrice }: { setGasPrice: (g: number) => void }) => {
23+ setGasPrice: (g: number) => void;
20 const { suggestedGasPrices } = useGasPrice(DEFAULT_GAS_PRICE_GWEI);
25 const { suggestedGasPrices } = useGasPrice(DEFAULT_GAS_PRICE_GWEI);
22− const [open, setOpen] = useState<boolean>(false);
27+ const [open, setOpen] = useState(false);
28+ const [custom, setCustom] = useState<string>('0');
23 const [selected, setSelected] = useState<GasPrice>(
29 const [selected, setSelected] = useState<GasPrice>(
24 suggestedGasPrices.average
30 suggestedGasPrices.average
33+ const handleCustom = (e: FormEvent) => {
34+ const cleanedValue = e.target.value.replace(/[^0-9]/g, '');
35+ const cleanedNum = Number(cleanedValue);
36+ setCustom(cleanedValue);
37+ setGasPrice(cleanedNum);
39+ let customWait = 'Unknown';
41+ const { fast, average, low } = suggestedGasPrices;
43+ if (cleanedNum < low.price) {
44+ customWait = `> ${low.wait}`;
45+ } else if (cleanedNum < average.price) {
46+ customWait = `~${low.wait}`;
47+ } else if (cleanedNum < fast.price) {
48+ customWait = `~${average.wait}`;
50+ customWait = `< ${fast.wait}`;
53+ setSelected({ price: cleanedValue, wait: customWait });
27 useEffect(() => {
56 useEffect(() => {
28 setSelected(suggestedGasPrices.average);
57 setSelected(suggestedGasPrices.average);
29 }, [suggestedGasPrices]);
58 }, [suggestedGasPrices]);
@@ -41,7 +70,7 @@ const FeeDropdown = ({ setGasPrice }: { setGasPrice: (g: number) => void }) => {
42 className="fee-dropdown"
71 className="fee-dropdown"
43 open={open}
72 open={open}
44− value={formatPriceWait(selected)}
73+ value={formatDisplay(selected)}
45 toggleOpen={() => setOpen(!open)}>
74 toggleOpen={() => setOpen(!open)}>
46 <Box className="prices">
75 <Box className="prices">
47 {Object.values(suggestedGasPrices).map(
76 {Object.values(suggestedGasPrices).map(
@@ -50,13 +79,21 @@ const FeeDropdown = ({ setGasPrice }: { setGasPrice: (g: number) => void }) => {
50 className="price"
79 className="price"
51 onClick={selectPrice(value)}
80 onClick={selectPrice(value)}
52 key={value.wait}>
81 key={value.wait}>
53− {PRICE_LABELS[ind]}: {formatPriceWait(value)}
82+ {PRICE_LABELS[ind]}: {formatDisplay(value)}
86+ <Row className="price">
87+ <Box className="label">Custom:</Box>
90+ className="custom-input"
92+ onChange={handleCustom}
94+ <Box className="unit">gwei</Box>
58 </Dropdown>
97 </Dropdown>
62−export default FeeDropdown;