Skip to content

Commit

Permalink
Merge pull request #477 from DeXter-on-Radix/add-last-trades
Browse files Browse the repository at this point in the history
Add recent trades
  • Loading branch information
fliebenberg authored Jul 15, 2024
2 parents 4393a54 + 79a3cf3 commit 770ac60
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 8 deletions.
123 changes: 117 additions & 6 deletions src/app/components/OrderBook.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CSSProperties } from "react";
import { CSSProperties, useState } from "react";

import "../styles/orderbook.css";
import * as utils from "../utils";
import { OrderBookRowProps, orderBookSlice } from "../state/orderBookSlice";
import { useAppDispatch, useAppSelector, useTranslations } from "../hooks";
import { Calculator } from "services/Calculator";

// For all intents, we can round all numbers to 8 decimals for Dexter.
// Alphadex will not accept any numbers with more than 8 decimals
Expand Down Expand Up @@ -123,7 +124,49 @@ function CurrentPriceRow() {
}
}

enum OrderBookTabOptions {
ORDER_BOOK = "ORDER_BOOK",
RECENT_TRADES = "RECENT_TRADES",
}

export function OrderBook() {
const t = useTranslations();
const [currentTab, setCurrentTab] = useState(OrderBookTabOptions.ORDER_BOOK);

return (
<div className="h-[700px]">
<div className="flex space-x-5 p-4">
{[
[t("order_book"), OrderBookTabOptions.ORDER_BOOK],
[t("recent_trades"), OrderBookTabOptions.RECENT_TRADES],
].map(([title, tab], indx) => {
const isActive = tab === currentTab;
return (
<div
key={indx}
className={`text-base p-2 ${
isActive
? "text-dexter-green-OG border-b border-[#cafc40]"
: "text-[#768089]"
} cursor-pointer`}
onClick={() => setCurrentTab(tab as OrderBookTabOptions)}
>
{title}
</div>
);
})}
</div>
<div>
{currentTab === OrderBookTabOptions.ORDER_BOOK && <OrderBookTab />}
{currentTab === OrderBookTabOptions.RECENT_TRADES && (
<RecentTradesTab />
)}
</div>
</div>
);
}

export function OrderBookTab() {
const t = useTranslations();
const dispatch = useAppDispatch();
const token1Symbol = useAppSelector(
Expand All @@ -134,16 +177,15 @@ export function OrderBook() {
);
const sells = useAppSelector((state) => state.orderBook.sells);
const buys = useAppSelector((state) => state.orderBook.buys);
//const grouping = useAppSelector((state) => state.orderBook.grouping);

return (
<div className="p-2 text-sx text-primary-content">
<div className="grid grid-cols-2 m-1 text-secondary-content font-bold text-sm uppercase">
<div className="justify-self-start">{t("order_book")}</div>
<div className="p-2 !pt-0 text-sx text-primary-content">
<div className="grid grid-cols-2 m-1 text-secondary-content text-sm">
<div className="justify-self-start"></div>
<div className="flex justify-end join">
<span className="join-item mr-2">{t("grouping")} </span>
<input
className="input-xs w-16 join-item"
className="input-xs w-16 join-item !bg-[#222629] !rounded"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
const grouping = Number(event.target.value);
dispatch(orderBookSlice.actions.setGrouping(grouping));
Expand Down Expand Up @@ -184,3 +226,72 @@ export function OrderBook() {
</div>
);
}

function RecentTradesTab() {
const t = useTranslations();
const { recentTrades } = useAppSelector((state) => state.orderBook);
const lastTrades = recentTrades.slice(0, 34);
const { token1, token2 } = useAppSelector((state) => state.pairSelector);
return (
<div>
<table className="table-auto mb-4 !mt-2">
<thead className="border-b-0 text-secondary-content uppercase align-top">
<tr className="text-xs">
<td className="pl-4">
{t("price")}
<br />({token2.symbol})
</td>
<td className="text-right">
{t("amount")} <br />({token1.symbol})
</td>
<td className="pl-8">{t("time")}</td>
</tr>
</thead>

{lastTrades.map((trade, indx) => {
const price = Calculator.divide(
trade.token2Amount,
trade.token1Amount
);
const time = trade.timestamp.split("T").join(" ").split(":00.")[0];
const amount = Math.round(trade.token1Amount);
return (
<RecentTradeRow
key={indx}
price={price}
side={trade.side}
time={time}
amount={amount}
/>
);
})}
</table>
</div>
);
}

function RecentTradeRow({
price,
side,
time,
amount,
}: {
price: number;
side: string;
time: string;
amount: number;
}) {
return (
<tr className="text-xs">
<td
className={`${
side === "BUY" ? "text-dexter-green" : "text-dexter-red"
} pl-4`}
>
{price.toFixed(4)}
</td>
<td className="text-right">{amount.toLocaleString("en")}</td>
<td className="pl-8">{time}</td>
</tr>
);
}
4 changes: 3 additions & 1 deletion src/app/state/locales/en/trade.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,7 @@
"cancel_1_order": "Cancel 1 Order",
"submitting_batch_cancel": "Submitting batch cancel",
"failed_to_cancel_orders": "Failed to cancel orders",
"connect_wallet_to_batch_delete": "Connect wallet to batch delete"
"connect_wallet_to_batch_delete": "Connect wallet to batch delete",
"recent_trades": "Recent Trades",
"time": "Time"
}
4 changes: 3 additions & 1 deletion src/app/state/locales/pt/trade.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,7 @@
"cancel_1_order": "Cancelar 1 Orden",
"submitting_batch_cancel": "Enviando cancelamento em lote",
"failed_to_cancel_orders": "Falha ao cancelar pedidos",
"connect_wallet_to_batch_delete": "Conectar carteira para exclusão em lote"
"connect_wallet_to_batch_delete": "Conectar carteira para exclusão em lote",
"recent_trades": "Negocia. Recentes",
"time": "Hora"
}
5 changes: 5 additions & 0 deletions src/app/state/orderBookSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface OrderBookState {
spread: number | null;
spreadPercent: number | null;
grouping: number | null;
recentTrades: adex.Trade[];
}

const initialState: OrderBookState = {
Expand All @@ -35,6 +36,7 @@ const initialState: OrderBookState = {
spread: null,
spreadPercent: null,
grouping: 0,
recentTrades: [],
};

export const MAX_ROWS = 13;
Expand Down Expand Up @@ -202,6 +204,9 @@ export const orderBookSlice = createSlice({
state.bestSell = bestSell;
state.bestBuy = bestBuy;
},
updateRecentTrades(state, action: PayloadAction<adex.Trade[]>) {
state.recentTrades = action.payload;
},
},
});

Expand Down
5 changes: 5 additions & 0 deletions src/app/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ export function initializeSubscriptions(store: AppStore) {
store.dispatch(
rewardSlice.actions.updatePairsList(serializedState.pairsList)
);
store.dispatch(
orderBookSlice.actions.updateRecentTrades(
serializedState.currentPairTrades
)
);
})
);
}
Expand Down

0 comments on commit 770ac60

Please sign in to comment.