chore: 🔧 more bar types in channel view

This commit is contained in:
AP 2020-05-26 20:25:20 +02:00
parent bb90fbfe50
commit 9c657a416a
10 changed files with 165 additions and 63 deletions

View file

@ -1,12 +1,13 @@
import React, { useState } from 'react';
import { toast } from 'react-toastify';
import { ChevronRight, X } from 'react-feather';
import { ChevronRight, ChevronUp, ChevronDown } from 'react-feather';
import { useAccountState } from 'src/context/AccountContext';
import { useChannelFeesQuery } from 'src/graphql/queries/__generated__/getChannelFees.generated';
import { useUpdateFeesMutation } from 'src/graphql/mutations/__generated__/updateFees.generated';
import { InputWithDeco } from 'src/components/input/InputWithDeco';
import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
import { withApollo } from 'config/client';
import styled from 'styled-components';
import {
Card,
CardWithTitle,
@ -21,7 +22,10 @@ import { LoadingCard } from '../src/components/loading/LoadingCard';
import { FeeCard } from '../src/views/fees/FeeCard';
import { SecureButton } from '../src/components/buttons/secureButton/SecureButton';
import { AdminSwitch } from '../src/components/adminSwitch/AdminSwitch';
import { ColorButton } from '../src/components/buttons/colorButton/ColorButton';
const WithPointer = styled.div`
cursor: pointer;
`;
const FeesView = () => {
const [indexOpen, setIndexOpen] = useState(0);
@ -58,26 +62,28 @@ const FeesView = () => {
<CardWithTitle>
<SubTitle>Update Channel Fees</SubTitle>
<Card>
<SingleLine>
<Sub4Title>Channel Fees</Sub4Title>
<ColorButton onClick={() => setIsEdit(prev => !prev)}>
{isEdit ? <X size={18} /> : 'Update'}
</ColorButton>
</SingleLine>
<WithPointer>
<SingleLine onClick={() => setIsEdit(prev => !prev)}>
<Sub4Title>Channel Fees</Sub4Title>
{isEdit ? <ChevronUp /> : <ChevronDown />}
</SingleLine>
</WithPointer>
{isEdit && (
<>
<Separation />
<InputWithDeco
title={'BaseFee'}
placeholder={'Sats'}
placeholder={'sats'}
amount={baseFee}
override={'sat'}
inputType={'number'}
inputCallback={value => setBaseFee(Number(value))}
/>
<InputWithDeco
title={'Fee Rate'}
placeholder={'MilliSats/Million'}
placeholder={'msats/million'}
amount={feeRate / 1000}
override={'sat'}
inputType={'number'}
inputCallback={value => setFeeRate(Number(value))}
/>

View file

@ -29,6 +29,10 @@ export const ProgressBar = styled.div<ProgressBar>`
return chartColors.orange;
case 4:
return progressBackground;
case 5:
return chartColors.orange2;
case 6:
return chartColors.darkyellow;
default:
return chartColors.purple;
}

View file

@ -39,6 +39,7 @@ type InputWithDecoProps = {
title: string;
noInput?: boolean;
amount?: number;
override?: string;
customAmount?: string;
color?: string;
placeholder?: string;
@ -49,6 +50,7 @@ type InputWithDecoProps = {
export const InputWithDeco: React.FC<InputWithDecoProps> = ({
title,
amount,
override,
customAmount,
children,
placeholder,
@ -65,7 +67,11 @@ export const InputWithDeco: React.FC<InputWithDecoProps> = ({
<InputTitle>{title}</InputTitle>
{showAmount && (
<AmountText>
{customAmount ? customAmount : <Price amount={amount} />}
{customAmount ? (
customAmount
) : (
<Price amount={amount} override={override} />
)}
</AmountText>
)}
</InputTitleRow>

View file

@ -12,10 +12,12 @@ type PriceProps = {
export const Price = ({
amount,
breakNumber = false,
override,
}: {
amount: number | string;
breakNumber?: boolean;
}) => {
override?: string;
}): JSX.Element => {
const { currency, displayValues } = useConfigState();
const { prices, dontShow } = usePriceState();
@ -42,12 +44,13 @@ export const Price = ({
};
}
return <>{getValue({ amount, ...priceProps, breakNumber })}</>;
return <>{getValue({ amount, ...priceProps, breakNumber, override })}</>;
};
interface GetPriceProps {
amount: number | string;
breakNumber?: boolean;
override?: string;
}
export const getPrice = (
@ -57,7 +60,7 @@ export const getPrice = (
dontShow: boolean;
prices?: { [key: string]: { last: number; symbol: string } };
}
) => ({ amount, breakNumber = false }: GetPriceProps): string => {
) => ({ amount, breakNumber = false, override }: GetPriceProps): string => {
const { prices, dontShow } = priceContext;
if (!displayValues) {
@ -83,5 +86,5 @@ export const getPrice = (
};
}
return getValue({ amount, ...priceProps, breakNumber });
return getValue({ amount, ...priceProps, breakNumber, override });
};

View file

@ -6,8 +6,8 @@ const themeTypes = ['dark', 'light'];
const currencyTypes = ['sat', 'btc', 'EUR', 'USD'];
export type channelBarStyleTypes = 'normal' | 'compact' | 'ultracompact';
export type channelBarTypeTypes = 'balance' | 'details' | 'partner';
export type channelSortTypes = 'none' | 'local' | 'balance';
export type channelBarTypeTypes = 'balance' | 'fees' | 'size' | 'proportional';
export type channelSortTypes = 'none' | 'local' | 'balance' | 'feeRate';
export type sortDirectionTypes = 'increase' | 'decrease';
type State = {

View file

@ -16,6 +16,7 @@ interface GetNumberProps {
symbol: string;
currency: string;
breakNumber?: boolean;
override?: string;
}
export const getValue = ({
@ -24,7 +25,9 @@ export const getValue = ({
symbol,
currency,
breakNumber,
override,
}: GetNumberProps): string => {
const correctCurrency = override || currency;
let value = 0;
if (typeof amount === 'string') {
value = Number(amount);
@ -32,14 +35,14 @@ export const getValue = ({
value = amount;
}
if (currency === 'btc') {
if (correctCurrency === 'btc') {
if (!value) return 'â‚¿0.0';
const amountInBtc = value / 100000000;
const rounded = Math.round(amountInBtc * 10000) / 10000;
return `â‚¿${rounded}`;
}
if (currency === 'sat') {
if (correctCurrency === 'sat') {
const breakAmount = breakNumber
? getValueString(value)
: numeral(value).format('0,0.[000]');

View file

@ -66,7 +66,7 @@ interface ChannelCardProps {
biggestRateFee: number;
}
export const ChannelCard = ({
export const ChannelCard: React.FC<ChannelCardProps> = ({
channelInfo,
index,
setIndexOpen,
@ -76,7 +76,7 @@ export const ChannelCard = ({
mostChannels,
biggestBaseFee,
biggestRateFee,
}: ChannelCardProps) => {
}) => {
const { channelBarType, channelBarStyle } = useConfigState();
const [modalOpen, setModalOpen] = useState(false);
@ -133,6 +133,9 @@ export const ChannelCard = ({
const remoteReserve = format({ amount: remote_reserve });
const nodeCapacity = format({ amount: partnerNodeCapacity });
const baseFee = format({ amount: base_fee / 1000, override: 'sat' });
const feeRate = format({ amount: fee_rate, override: 'sat' });
const handleClick = () => {
if (indexOpen === index) {
setIndexOpen(0);
@ -150,8 +153,8 @@ export const ChannelCard = ({
'Last Update:',
`${getDateDif(updated_at)} ago (${getFormatDate(updated_at)})`
)}
{renderLine('Base Fee:', `${base_fee} msats`)}
{renderLine('Fee Rate:', `${fee_rate} sats/Msats`)}
{renderLine('Base Fee:', baseFee)}
{renderLine('Fee Rate:', `${feeRate}/million`)}
{renderLine('CTLV Delta:', cltv_delta)}
</>
) : (
@ -205,28 +208,79 @@ export const ChannelCard = ({
const renderBars = () => {
switch (channelBarType) {
case 'partner':
case 'fees':
return (
<ChannelStatsColumn>
<ProgressBar
order={0}
percent={getBar(Number(partnerNodeCapacity), biggestPartner)}
/>
<ProgressBar
order={3}
percent={getBar(channel_count, mostChannels)}
/>
<ProgressBar order={1} percent={getBar(base_fee, biggestBaseFee)} />
<ProgressBar order={2} percent={getBar(fee_rate, biggestRateFee)} />
<ChannelStatsLine>
<ProgressBar
order={3}
percent={getBar(fee_rate, biggestRateFee)}
/>
<ProgressBar
order={4}
percent={getBar(biggestRateFee - fee_rate, biggestRateFee)}
/>
</ChannelStatsLine>
<ChannelStatsLine>
<ProgressBar
order={1}
percent={getBar(base_fee, biggestBaseFee)}
/>
<ProgressBar
order={4}
percent={getBar(biggestBaseFee - base_fee, biggestBaseFee)}
/>
</ChannelStatsLine>
</ChannelStatsColumn>
);
case 'details':
case 'size':
return (
<ChannelStatsColumn>
<ProgressBar order={0} percent={getBar(local_balance, biggest)} />
<ProgressBar order={1} percent={getBar(remote_balance, biggest)} />
<ProgressBar order={2} percent={getBar(received, biggest)} />
<ProgressBar order={3} percent={getBar(sent, biggest)} />
<ChannelStatsLine>
<ProgressBar
order={0}
percent={getBar(Number(partnerNodeCapacity), biggestPartner)}
/>
<ProgressBar
order={4}
percent={getBar(
biggestPartner - Number(partnerNodeCapacity),
biggestPartner
)}
/>
</ChannelStatsLine>
<ChannelStatsLine>
<ProgressBar
order={6}
percent={getBar(channel_count, mostChannels)}
/>
<ProgressBar
order={4}
percent={getBar(mostChannels - channel_count, mostChannels)}
/>
</ChannelStatsLine>
</ChannelStatsColumn>
);
case 'proportional':
return (
<ChannelStatsColumn>
<ChannelStatsLine>
<ProgressBar order={1} percent={getBar(local_balance, biggest)} />
<ProgressBar
order={4}
percent={getBar(biggest - local_balance, biggest)}
/>
</ChannelStatsLine>
<ChannelStatsLine>
<ProgressBar
order={2}
percent={getBar(remote_balance, biggest)}
/>
<ProgressBar
order={4}
percent={getBar(biggest - remote_balance, biggest)}
/>
</ChannelStatsLine>
</ChannelStatsColumn>
);
default:
@ -253,16 +307,27 @@ export const ChannelCard = ({
const renderBarsInfo = () => {
switch (channelBarType) {
case 'partner':
case 'fees':
return (
<>
<div>{`Partner Fee Rate: ${feeRate}/million`}</div>
<div>{`Partner Base Fee: ${baseFee}`}</div>
</>
);
case 'size':
return (
<>
<div>{`Partner Capacity: ${nodeCapacity}`}</div>
<div>{`Partner Channels: ${channel_count}`}</div>
<div>{`Partner Base Fee: ${base_fee} msats`}</div>
<div>{`Partner Fee Rate: ${fee_rate} sats/Msats`}</div>
</>
);
case 'details':
case 'proportional':
return (
<>
<div>{`Local Balance: ${formatLocal}`}</div>
<div>{`Remote Balance: ${formatRemote}`}</div>
</>
);
default:
return (
<>

View file

@ -71,16 +71,22 @@ export const ChannelManage = () => {
Balance
</SingleButton>
<SingleButton
selected={channelBarType === 'details'}
onClick={() => changeType('details')}
selected={channelBarType === 'proportional'}
onClick={() => changeType('proportional')}
>
Proportional
</SingleButton>
<SingleButton
selected={channelBarType === 'partner'}
onClick={() => changeType('partner')}
selected={channelBarType === 'size'}
onClick={() => changeType('size')}
>
Partner
Partner Size
</SingleButton>
<SingleButton
selected={channelBarType === 'fees'}
onClick={() => changeType('fees')}
>
Partner Fees
</SingleButton>
</MultiButton>
</MarginLine>
@ -105,6 +111,12 @@ export const ChannelManage = () => {
>
Balance
</SingleButton>
<SingleButton
selected={channelSort === 'feeRate'}
onClick={() => changeSort('feeRate')}
>
Fee Rate
</SingleButton>
</MultiButton>
</MarginLine>
{channelSort !== 'none' && (

View file

@ -10,7 +10,7 @@ import { getErrorContent } from '../../../utils/error';
import { LoadingCard } from '../../../components/loading/LoadingCard';
import { ChannelCard } from './ChannelCard';
export const Channels = () => {
export const Channels: React.FC = () => {
const { sortDirection, channelSort } = useConfigState();
const [indexOpen, setIndexOpen] = useState(0);
@ -35,19 +35,13 @@ export const Channels = () => {
for (let i = 0; i < data.getChannels.length; i++) {
const channel = data.getChannels[i];
const {
local_balance,
remote_balance,
sent,
received,
partner_node_info = {},
} = channel;
const { local_balance, remote_balance, partner_node_info = {} } = channel;
const { capacity, channel_count, base_fee, fee_rate } = partner_node_info;
const partner = Number(capacity) || 0;
const channels = Number(channel_count) || 0;
const max = Math.max(local_balance, remote_balance, sent, received);
const max = Math.max(local_balance, remote_balance);
if (max > biggest) {
biggest = max;
@ -78,6 +72,13 @@ export const Channels = () => {
);
return sortDirection === 'increase' ? newArray : newArray.reverse();
}
case 'feeRate': {
const newArray = sortBy(
data.getChannels,
channel => channel.partner_node_info.fee_rate
);
return sortDirection === 'increase' ? newArray : newArray.reverse();
}
default:
return data.getChannels;
}
@ -95,8 +96,8 @@ export const Channels = () => {
biggest={biggest}
biggestPartner={biggestPartner}
mostChannels={mostChannels}
biggestBaseFee={biggestBaseFee}
biggestRateFee={biggestRateFee}
biggestBaseFee={Math.max(biggestBaseFee, 100000)}
biggestRateFee={Math.max(biggestRateFee, 2000)}
/>
))}
</Card>

View file

@ -28,12 +28,12 @@ interface FeeCardProps {
indexOpen: number;
}
export const FeeCard = ({
export const FeeCard: React.FC<FeeCardProps> = ({
channelInfo,
index,
setIndexOpen,
indexOpen,
}: FeeCardProps) => {
}) => {
const [newBaseFee, setBaseFee] = useState(0);
const [newFeeRate, setFeeRate] = useState(0);
@ -78,15 +78,17 @@ export const FeeCard = ({
<AdminSwitch>
<InputWithDeco
title={'BaseFee'}
placeholder={'Sats'}
placeholder={'sats'}
amount={newBaseFee}
override={'sat'}
inputType={'number'}
inputCallback={value => setBaseFee(Number(value))}
/>
<InputWithDeco
title={'Fee Rate'}
placeholder={'MilliSats/Million'}
placeholder={'msats/million'}
amount={newFeeRate / 1000}
override={'sat'}
inputType={'number'}
inputCallback={value => setFeeRate(Number(value))}
/>