Browse Source

Merge #826

826: A few frontend improvements r=da-kami a=bonomat

1. fix: improves reference price being undefined

2. fix: moves the alert box below the grid to allow for longer messages
old: 
![image](https://user-images.githubusercontent.com/224613/145105460-e4f5263e-db5c-4eec-bf60-523b08c2e227.png)


3. fix: `@da-kami` thought this was a cashing problem 🙈

4. fix: make the input full width
5. fix: makes the button size fix width

new

![image](https://user-images.githubusercontent.com/224613/145107756-b374788d-d7fd-4c1d-9edd-5c3dcc85bae1.png)
![image](https://user-images.githubusercontent.com/224613/145107782-2154e201-5ced-42dd-9690-28954025eb9a.png)


Co-authored-by: bonomat <philipp@hoenisch.at>
release/0.3.1
bors[bot] 3 years ago
committed by GitHub
parent
commit
d668736c2a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      maker-frontend/src/MakerApp.tsx
  2. 21
      taker-frontend/src/App.tsx
  3. 37
      taker-frontend/src/components/CloseButton.tsx
  4. 10
      taker-frontend/src/components/History.tsx
  5. 256
      taker-frontend/src/components/Trade.tsx

4
maker-frontend/src/MakerApp.tsx

@ -47,8 +47,8 @@ export default function App() {
const toast = useToast();
let [minQuantity, setMinQuantity] = useState<string>("10");
let [maxQuantity, setMaxQuantity] = useState<string>("100");
let [minQuantity, setMinQuantity] = useState<string>("100");
let [maxQuantity, setMaxQuantity] = useState<string>("1000");
let [orderPrice, setOrderPrice] = useState<string>("0");
let [autoRefresh, setAutoRefresh] = useState(true);

21
taker-frontend/src/App.tsx

@ -43,22 +43,17 @@ export const App = () => {
const toast = useToast();
useBackendMonitor(toast, 5000, "Please start the taker again to reconnect..."); // 5s timeout
const {
lastMessage,
readyState,
} = useWebSocket("wss://www.bitmex.com/realtime?subscribe=instrument:.BXBT", {
// Will attempt to reconnect on all close events, such as server shutting down
let [referencePrice, setReferencePrice] = useState<number>();
useWebSocket("wss://www.bitmex.com/realtime?subscribe=instrument:.BXBT", {
shouldReconnect: () => true,
onMessage: (message) => {
const data: BXBTData[] = JSON.parse(message.data).data;
if (data && data[0]?.markPrice) {
setReferencePrice(data[0].markPrice);
}
},
});
let referencePrice;
if (readyState === 1 && lastMessage) {
const data: BXBTData[] = JSON.parse(lastMessage.data).data;
if (data && data[0]?.markPrice) {
referencePrice = data[0].markPrice;
}
}
let source = useEventSource({ source: "/api/feed" });
const walletInfo = useLatestEvent<WalletInfo>(source, "wallet");
const order = useLatestEvent<Order>(source, "order", intoOrder);

37
taker-frontend/src/components/CloseButton.tsx

@ -19,15 +19,34 @@ interface Props {
cfd: Cfd;
request: (req: any) => void;
status: boolean;
action: String;
isForceCloseButton: boolean;
buttonTitle: String;
}
/// Button that can be used to trigger non-collaborative close if the maker is offline and collaborative close if the
/// maker is online.
export default function CloseButton({ cfd, request, status, action }: Props) {
export default function CloseButton({ cfd, request, status, buttonTitle, isForceCloseButton }: Props) {
const disableCloseButton = cfd.state.getGroup() === StateGroupKey.CLOSED
|| !(cfd.state.key === StateKey.OPEN);
let popoverBody = <>
<Text>
This will close your position with the counterparty. The current exchange rate will determine your
profit/losses.
</Text>
</>;
if (isForceCloseButton) {
popoverBody = <>
<Text>
This will force close your position with the counterparty. The exchange rate at
</Text>
<Timestamp timestamp={cfd.expiry_timestamp} />
<Text>
will determine your profit/losses. It is likely that the rate will change until then.
</Text>
</>;
}
return <Box w={"45%"}>
<Popover
placement="bottom"
@ -35,22 +54,16 @@ export default function CloseButton({ cfd, request, status, action }: Props) {
>
{({ onClose }) => (<>
<PopoverTrigger>
<Button colorScheme={"blue"} disabled={disableCloseButton}>{action}</Button>
<Button colorScheme={"blue"} disabled={disableCloseButton}>{buttonTitle}</Button>
</PopoverTrigger>
<PopoverContent color="white" bg="blue.800" borderColor="blue.800">
<PopoverHeader pt={4} fontWeight="bold" border="0">
{action} your position
{buttonTitle} your position
</PopoverHeader>
<PopoverArrow />
<PopoverCloseButton />
<PopoverBody>
<Text>
This will {action.toLowerCase()} your position with the counterparty. The exchange rate at
</Text>
<Timestamp timestamp={cfd.expiry_timestamp} />
<Text>
will determine your profit/losses. It is likely that the rate will change until then.
</Text>
{popoverBody}
</PopoverBody>
<PopoverFooter
border="0"
@ -69,7 +82,7 @@ export default function CloseButton({ cfd, request, status, action }: Props) {
}}
isLoading={status}
>
{action}
{buttonTitle}
</Button>
</PopoverFooter>
</PopoverContent>

10
taker-frontend/src/components/History.tsx

@ -75,8 +75,14 @@ const CfdDetails = ({ cfd, connectedToMaker }: CfdDetailsProps) => {
let [commit, isCommiting] = usePostRequest(`/api/cfd/${cfd.order_id}/commit`);
const closeButton = connectedToMaker.online
? <CloseButton request={settle} status={isSettling} cfd={cfd} action="Close" />
: <CloseButton request={commit} status={isCommiting} cfd={cfd} action="Force Close" />;
? <CloseButton request={settle} status={isSettling} cfd={cfd} buttonTitle="Close" isForceCloseButton={false} />
: <CloseButton
request={commit}
status={isCommiting}
cfd={cfd}
buttonTitle="Force Close"
isForceCloseButton={true}
/>;
return (
<HStack bg={useColorModeValue("gray.100", "gray.700")} rounded={5} padding={2}>

256
taker-frontend/src/components/Trade.tsx

@ -156,133 +156,142 @@ export default function Trade({
}
return (
<Center>
<Grid
templateRows="repeat(1, 1fr)"
templateColumns="repeat(1, 1fr)"
gap={4}
>
<GridItem colSpan={1}>
<Center>
<MotionBox
variants={{
pulse: {
scale: [1, 1.05, 1],
},
}}
// @ts-ignore: lint is complaining but should be fine :)
transition={{
// type: "spring",
ease: "linear",
duration: 2,
repeat: Infinity,
}}
animate={"pulse"}
>
<Circle size="256px" bg={outerCircleBg}>
<Circle size="180px" bg={innerCircleBg}>
<MotionBox>
<Skeleton isLoaded={!!referencePriceAsNumber && referencePriceAsNumber > 0}>
<Text fontSize={"4xl"} as="b">{referencePrice}</Text>
</Skeleton>
</MotionBox>
<VStack>
<Center>
<Grid
templateRows="repeat(1, 1fr)"
templateColumns="repeat(1, 1fr)"
gap={4}
>
<GridItem colSpan={1}>
<Center>
<MotionBox
variants={{
pulse: {
scale: [1, 1.05, 1],
},
}}
// @ts-ignore: lint is complaining but should be fine :)
transition={{
// type: "spring",
ease: "linear",
duration: 2,
repeat: Infinity,
}}
animate={"pulse"}
>
<Circle size="256px" bg={outerCircleBg}>
<Circle size="180px" bg={innerCircleBg}>
<MotionBox>
<Skeleton isLoaded={!!referencePriceAsNumber && referencePriceAsNumber > 0}>
<Text fontSize={"4xl"} as="b">{referencePrice}</Text>
</Skeleton>
</MotionBox>
</Circle>
</Circle>
</Circle>
</MotionBox>
</Center>
</GridItem>
<GridItem colSpan={1}>
<Quantity
min={minQuantity}
max={maxQuantity}
quantity={quantity}
onChange={onQuantityChange}
quantityIncrement={quantityIncrement}
/>
</GridItem>
<GridItem colSpan={1}>
<Leverage leverage={leverage} />
</GridItem>
<GridItem colSpan={1}>
<Margin margin={margin} />
</GridItem>
<GridItem colSpan={1}>
<Center>
<ButtonGroup
variant="solid"
padding="3"
spacing="6"
>
<Button colorScheme="red" size="lg" disabled h={16}>
<VStack>
<Text as="b">Short</Text>
<Text fontSize={"sm"}>{quantity.replace("$", "")}@{askPrice}</Text>
</VStack>
</Button>
<Button disabled={!canSubmit} colorScheme="green" size="lg" onClick={onOpen} h={16}>
<VStack>
<Text as="b">Long</Text>
<Text fontSize={"sm"}>{quantity.replace("$", "")}@{askPrice}</Text>
</VStack>
</Button>
</MotionBox>
</Center>
</GridItem>
<GridItem colSpan={1}>
<Quantity
min={minQuantity}
max={maxQuantity}
quantity={quantity}
onChange={onQuantityChange}
quantityIncrement={quantityIncrement}
/>
</GridItem>
<GridItem colSpan={1}>
<Leverage leverage={leverage} />
</GridItem>
<GridItem colSpan={1}>
<Margin margin={margin} />
</GridItem>
<GridItem colSpan={1}>
<Center>
<ButtonGroup
variant="solid"
padding="3"
spacing="6"
>
<Button colorScheme="red" size="lg" disabled h={16} w={"40"}>
<VStack>
<Text as="b">Short</Text>
<Text fontSize={"sm"}>{quantity.replace("$", "")}@{askPrice}</Text>
</VStack>
</Button>
<Button
disabled={!canSubmit}
colorScheme="green"
size="lg"
onClick={onOpen}
h={16}
w={"40"}
>
<VStack>
<Text as="b">Long</Text>
<Text fontSize={"sm"}>{quantity.replace("$", "")}@{askPrice}</Text>
</VStack>
</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
Market buy <b>{quantity}</b> of BTC/USD @ <b>{askPrice}</b>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Table variant="striped" colorScheme="gray" size="sm">
<TableCaption>
By submitting, {margin} will be locked on-chain in a contract.
</TableCaption>
<Tbody>
<Tr>
<Td><Text as={"b"}>Margin</Text></Td>
<Td>{margin}</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Leverage</Text></Td>
<Td>{leverage}</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Liquidation Price</Text></Td>
<Td>{liquidationPrice}</Td>
</Tr>
</Tbody>
</Table>
</ModalBody>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
Market buy <b>{quantity}</b> of BTC/USD @ <b>{askPrice}</b>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Table variant="striped" colorScheme="gray" size="sm">
<TableCaption>
By submitting, {margin} will be locked on-chain in a contract.
</TableCaption>
<Tbody>
<Tr>
<Td><Text as={"b"}>Margin</Text></Td>
<Td>{margin}</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Leverage</Text></Td>
<Td>{leverage}</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Liquidation Price</Text></Td>
<Td>{liquidationPrice}</Td>
</Tr>
</Tbody>
</Table>
</ModalBody>
<ModalFooter>
<HStack>
<Button
colorScheme="teal"
isLoading={isLongSubmitting}
onClick={() => {
const quantityAsNumber = quantity.replace("$", "");
<ModalFooter>
<HStack>
<Button
colorScheme="teal"
isLoading={isLongSubmitting}
onClick={() => {
const quantityAsNumber = quantity.replace("$", "");
let payload: CfdOrderRequestPayload = {
order_id: orderId!,
quantity: Number.parseFloat(quantityAsNumber),
};
onLongSubmit(payload);
onClose();
}}
>
Confirm
</Button>
</HStack>
</ModalFooter>
</ModalContent>
</Modal>
</ButtonGroup>
</Center>
{alertBox}
</GridItem>
</Grid>
</Center>
let payload: CfdOrderRequestPayload = {
order_id: orderId!,
quantity: Number.parseFloat(quantityAsNumber),
};
onLongSubmit(payload);
onClose();
}}
>
Confirm
</Button>
</HStack>
</ModalFooter>
</ModalContent>
</Modal>
</ButtonGroup>
</Center>
</GridItem>
</Grid>
</Center>
{alertBox}
</VStack>
);
}
@ -307,6 +316,7 @@ function Quantity({ min, max, onChange, quantity, quantityIncrement }: QuantityP
step={quantityIncrement}
onChange={onChange}
value={quantity}
w={"100%"}
>
<NumberInputField />
<NumberInputStepper>

Loading…
Cancel
Save