Browse Source

Display Skeleton for P/L and Payout if not available

In case we fail to calculate the profit or this data is otherwise not
available, we still want to display as much as possible and only
blank out the data we cannot compute.
feature/supervised-connection
Thomas Eizinger 3 years ago
parent
commit
d356f7d1d6
No known key found for this signature in database GPG Key ID: 651AC83A6C6C8B96
  1. 27
      daemon/src/projection.rs
  2. 45
      taker-frontend/src/components/History.tsx
  3. 4
      taker-frontend/src/types.ts

27
daemon/src/projection.rs

@ -488,9 +488,9 @@ pub struct Cfd {
#[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")]
pub margin_counterparty: Amount,
#[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")]
pub profit_btc: SignedAmount,
pub profit_percent: String,
#[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc::opt")]
pub profit_btc: Option<SignedAmount>,
pub profit_percent: Option<String>,
pub state: CfdState,
pub actions: Vec<CfdAction>,
@ -511,14 +511,17 @@ impl From<CfdsWithAuxData> for Vec<Cfd> {
.cfds
.iter()
.map(|cfd| {
let (profit_btc, profit_percent) =
cfd.profit(current_price).unwrap_or_else(|error| {
tracing::warn!(
"Calculating profit/loss failed. Falling back to 0. {:#}",
error
);
(SignedAmount::ZERO, Decimal::ZERO.into())
});
let (profit_btc, profit_percent) = match cfd.profit(current_price) {
Ok((profit_btc, profit_percent)) => (
Some(profit_btc),
Some(profit_percent.round_dp(1).to_string()),
),
Err(e) => {
tracing::warn!("Failed to calculate profit/loss {:#}", e);
(None, None)
}
};
let pending_proposal = input.pending_proposals.get(&cfd.order.id);
let state = to_cfd_state(&cfd.state, pending_proposal);
@ -532,7 +535,7 @@ impl From<CfdsWithAuxData> for Vec<Cfd> {
liquidation_price: cfd.order.liquidation_price.into(),
quantity_usd: cfd.quantity_usd.into(),
profit_btc,
profit_percent: profit_percent.round_dp(1).to_string(),
profit_percent,
state: state.clone(),
actions: available_actions(state, cfd.role()),
state_transition_timestamp: cfd.state.get_transition_timestamp().seconds(),

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

@ -8,6 +8,7 @@ import {
HStack,
Link,
SimpleGrid,
Skeleton,
Spinner,
Table,
Tbody,
@ -60,11 +61,6 @@ const CfdDetails = ({ cfd, connectedToMaker }: CfdDetailsProps) => {
const margin = `${Math.round((cfd.margin) * 1_000_000) / 1_000_000}`;
const liquidationPrice = `$${cfd.liquidation_price}`;
const pAndLNumber = Math.round((cfd.profit_btc) * 1_000_000) / 1_000_000;
const pAndL = pAndLNumber < 0 ? `-₿${Math.abs(pAndLNumber)}` : `${Math.abs(pAndLNumber)}`;
const payout = `${Math.round((cfd.margin + cfd.profit_btc) * 1_000_000) / 1_000_000}`;
const txLock = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Lock);
const txCommit = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Commit);
const txRefund = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Refund);
@ -102,11 +98,19 @@ const CfdDetails = ({ cfd, connectedToMaker }: CfdDetailsProps) => {
</Tr>
<Tr>
<Td><Text as={"b"}>Unrealized P/L</Text></Td>
<Td textAlign="right">{pAndL}</Td>
<Td textAlign="right">
<Skeleton isLoaded={cfd.profit_btc != null}>
<ProfitAndLoss profitBtc={cfd.profit_btc!} />
</Skeleton>
</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Payout</Text></Td>
<Td textAlign="right">{payout}</Td>
<Td textAlign="right">
<Skeleton isLoaded={cfd.profit_btc != null}>
<Payout profitBtc={cfd.profit_btc!} margin={cfd.margin} />
</Skeleton>
</Td>
</Tr>
</Tbody>
</Table>
@ -158,6 +162,33 @@ const CfdDetails = ({ cfd, connectedToMaker }: CfdDetailsProps) => {
);
};
interface ProfitAndLossProps {
profitBtc: number;
}
function ProfitAndLoss({ profitBtc }: ProfitAndLossProps) {
const pAndLNumber = Math.round((profitBtc) * 1_000_000) / 1_000_000;
const absPAndL = Math.abs(pAndLNumber);
const negativeSign = pAndLNumber < 0 ? "-" : "";
return <Text>
{negativeSign}{absPAndL}
</Text>;
}
interface PayoutProps {
profitBtc: number;
margin: number;
}
function Payout({ profitBtc, margin }: PayoutProps) {
let payoutBtc = Math.round((margin + profitBtc) * 1_000_000) / 1_000_000;
return <Text>
{payoutBtc}
</Text>;
}
const CircleIcon = (props: any) => (
<Icon viewBox="0 0 200 200" {...props}>
<path

4
taker-frontend/src/types.ts

@ -52,8 +52,8 @@ export interface Cfd {
margin: number;
profit_btc: number;
profit_percent: number;
profit_btc?: number;
profit_percent?: number;
state: State;
state_transition_timestamp: number;

Loading…
Cancel
Save