mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-21 14:04:03 +01:00
feat: ✨ channel ui manager
This commit is contained in:
parent
8099a3919e
commit
35cf8db27f
12 changed files with 344 additions and 112 deletions
|
@ -41,7 +41,7 @@ const Wrapper: React.FC = ({ children }) => {
|
|||
return <>{children}</>;
|
||||
}
|
||||
if (hasAccount === 'false') {
|
||||
return <LoadingCard noCard={true} />;
|
||||
return <LoadingCard loadingHeight={'50vh'} noCard={true} />;
|
||||
}
|
||||
return <GridWrapper>{children}</GridWrapper>;
|
||||
};
|
||||
|
@ -100,19 +100,18 @@ const App = ({
|
|||
App.getInitialProps = async props => {
|
||||
const cookieParam = getUrlParam(props.router?.query?.token);
|
||||
const cookies = parseCookies(props.ctx.req);
|
||||
const defaultState = {};
|
||||
|
||||
if (!cookies?.config) {
|
||||
return { initialConfig: {}, ...defaultState };
|
||||
return { initialConfig: {} };
|
||||
}
|
||||
try {
|
||||
const config = JSON.parse(cookies.config);
|
||||
return {
|
||||
initialConfig: { ...config, ...defaultState },
|
||||
initialConfig: config,
|
||||
cookieParam,
|
||||
};
|
||||
} catch (error) {
|
||||
return { initialConfig: {}, cookieParam, ...defaultState };
|
||||
return { initialConfig: {}, cookieParam };
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -84,10 +84,9 @@ const BalanceView = () => {
|
|||
};
|
||||
|
||||
const renderChannels = (isOutgoing?: boolean) => {
|
||||
const channels = sortBy(data.getChannels, [
|
||||
(channel: any) =>
|
||||
getPercent(channel.remote_balance, channel.local_balance),
|
||||
]);
|
||||
const channels = sortBy(data.getChannels, channel =>
|
||||
getPercent(channel.remote_balance, channel.local_balance)
|
||||
);
|
||||
|
||||
const finalChannels = isOutgoing ? channels : channels.reverse();
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@ import React, { useState, useEffect } from 'react';
|
|||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetChannelAmountInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import styled from 'styled-components';
|
||||
import { Settings } from 'react-feather';
|
||||
import { IconCursor } from 'src/views/channels/channels/Channel.style';
|
||||
import { ChannelManage } from 'src/views/channels/channels/ChannelManage';
|
||||
import { Channels } from '../src/views/channels/channels/Channels';
|
||||
import { PendingChannels } from '../src/views/channels/pendingChannels/PendingChannels';
|
||||
import { ClosedChannels } from '../src/views/channels/closedChannels/ClosedChannels';
|
||||
|
@ -28,6 +31,7 @@ const ButtonRow = styled.div`
|
|||
`;
|
||||
|
||||
const ChannelView = () => {
|
||||
const [isOpen, isOpenSet] = useState<boolean>(false);
|
||||
const [view, setView] = useState<number>(1);
|
||||
const [amounts, setAmounts] = useState({
|
||||
active: 0,
|
||||
|
@ -94,8 +98,14 @@ const ChannelView = () => {
|
|||
<SmallButton onClick={() => setView(3)}>
|
||||
{`Closed (${amounts.closed})`}
|
||||
</SmallButton>
|
||||
{view === 1 && (
|
||||
<IconCursor>
|
||||
<Settings size={16} onClick={() => isOpenSet(p => !p)} />
|
||||
</IconCursor>
|
||||
)}
|
||||
</ButtonRow>
|
||||
</ChannelsCardTitle>
|
||||
{view === 1 && isOpen && <ChannelManage />}
|
||||
{getView()}
|
||||
</CardWithTitle>
|
||||
);
|
||||
|
|
|
@ -27,6 +27,8 @@ export const ProgressBar = styled.div<ProgressBar>`
|
|||
return chartColors.green;
|
||||
case 3:
|
||||
return chartColors.orange;
|
||||
case 4:
|
||||
return progressBackground;
|
||||
default:
|
||||
return chartColors.purple;
|
||||
}
|
||||
|
|
|
@ -81,13 +81,18 @@ interface SubCardProps {
|
|||
padding?: string;
|
||||
withMargin?: string;
|
||||
noCard?: boolean;
|
||||
noBackground?: boolean;
|
||||
}
|
||||
|
||||
export const SubCard = styled.div<SubCardProps>`
|
||||
margin: ${({ withMargin }) => (withMargin ? withMargin : '0 0 10px 0')};
|
||||
padding: ${({ padding }) => (padding ? padding : '16px')};
|
||||
background: ${subCardColor};
|
||||
border: 1px solid ${cardBorderColor};
|
||||
${({ noBackground }) =>
|
||||
!noBackground &&
|
||||
css`
|
||||
background: ${subCardColor};
|
||||
border: 1px solid ${cardBorderColor};
|
||||
`}
|
||||
border-left: ${({ color }) => (color ? `2px solid ${color}` : '')};
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -5,6 +5,11 @@ import Cookies from 'js-cookie';
|
|||
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 sortDirectionTypes = 'increase' | 'decrease';
|
||||
|
||||
type State = {
|
||||
currency: string;
|
||||
theme: string;
|
||||
|
@ -17,7 +22,10 @@ type State = {
|
|||
hideNonVerified: boolean;
|
||||
maxFee: number;
|
||||
chatPollingSpeed: number;
|
||||
channelBarType: 'normal' | 'partner';
|
||||
channelBarStyle: channelBarStyleTypes;
|
||||
channelBarType: channelBarTypeTypes;
|
||||
channelSort: channelSortTypes;
|
||||
sortDirection: sortDirectionTypes;
|
||||
};
|
||||
|
||||
type ConfigInitProps = {
|
||||
|
@ -37,7 +45,10 @@ type ActionType = {
|
|||
hideNonVerified?: boolean;
|
||||
maxFee?: number;
|
||||
chatPollingSpeed?: number;
|
||||
channelBarType?: 'normal' | 'partner';
|
||||
channelBarStyle?: channelBarStyleTypes;
|
||||
channelBarType?: channelBarTypeTypes;
|
||||
channelSort?: channelSortTypes;
|
||||
sortDirection?: sortDirectionTypes;
|
||||
};
|
||||
|
||||
type Dispatch = (action: ActionType) => void;
|
||||
|
@ -65,7 +76,10 @@ const initialState: State = {
|
|||
hideNonVerified: false,
|
||||
maxFee: 20,
|
||||
chatPollingSpeed: 1000,
|
||||
channelBarType: 'normal',
|
||||
channelBarStyle: 'normal',
|
||||
channelBarType: 'balance',
|
||||
channelSort: 'none',
|
||||
sortDirection: 'decrease',
|
||||
};
|
||||
|
||||
const stateReducer = (state: State, action: ActionType): State => {
|
||||
|
|
|
@ -34,10 +34,11 @@ export const ChannelColumnSection = styled.div`
|
|||
|
||||
export const ChannelLineSection = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 300px;
|
||||
flex-direction: column;
|
||||
width: 180px;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
align-items: center;
|
||||
max-width: unset;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
|
|
@ -62,7 +62,7 @@ export const BalanceCard = ({
|
|||
} = channel;
|
||||
const { alias } = partner_node_info;
|
||||
|
||||
const balancedness = getPercent(remote_balance, local_balance) / 100;
|
||||
const balancedness = getPercent(local_balance, remote_balance) / 100;
|
||||
const formatBalance = numeral(balancedness).format('0,0.00');
|
||||
|
||||
const props = withColor ? { color: themeColors.blue3 } : {};
|
||||
|
@ -72,9 +72,12 @@ export const BalanceCard = ({
|
|||
<MainInfo onClick={() => callback && callback()}>
|
||||
<ResponsiveLine withWrap={true}>
|
||||
<ChannelLineSection>
|
||||
{alias && alias !== ''
|
||||
? `${alias} - ${id}`
|
||||
: `${partner_public_key?.substring(0, 6)} - ${id}`}
|
||||
<div>
|
||||
{alias && alias !== ''
|
||||
? alias
|
||||
: partner_public_key?.substring(0, 6)}
|
||||
</div>
|
||||
<DarkSubTitle>{id}</DarkSubTitle>
|
||||
</ChannelLineSection>
|
||||
<ChannelColumnSection>
|
||||
<SingleLine>
|
||||
|
|
55
src/views/channels/channels/Channel.style.ts
Normal file
55
src/views/channels/channels/Channel.style.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import styled from 'styled-components';
|
||||
import { mediaWidths } from 'src/styles/Themes';
|
||||
|
||||
export const ChannelIconPadding = styled.div`
|
||||
display: flex;
|
||||
margin-left: 8px;
|
||||
`;
|
||||
|
||||
export const ChannelStatsColumn = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
`;
|
||||
|
||||
export const ChannelStatsLine = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const ChannelBarSide = styled.div`
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ChannelNodeTitle = styled.div`
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ChannelSingleLine = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
export const IconCursor = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin-left: 8px;
|
||||
`;
|
|
@ -1,8 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import styled from 'styled-components';
|
||||
import { ArrowDown, ArrowUp, EyeOff } from 'react-feather';
|
||||
import { mediaWidths } from 'src/styles/Themes';
|
||||
import { ChannelType } from 'src/graphql/types';
|
||||
import { getPercent, formatSeconds } from '../../../utils/helpers';
|
||||
import {
|
||||
|
@ -18,10 +16,7 @@ import {
|
|||
ResponsiveLine,
|
||||
DarkSubTitle,
|
||||
} from '../../../components/generic/Styled';
|
||||
import {
|
||||
useConfigState,
|
||||
useConfigDispatch,
|
||||
} from '../../../context/ConfigContext';
|
||||
import { useConfigState } from '../../../context/ConfigContext';
|
||||
import {
|
||||
getStatusDot,
|
||||
getTooltipType,
|
||||
|
@ -37,47 +32,14 @@ import { AdminSwitch } from '../../../components/adminSwitch/AdminSwitch';
|
|||
import { ColorButton } from '../../../components/buttons/colorButton/ColorButton';
|
||||
import { getPrice } from '../../../components/price/Price';
|
||||
import { usePriceState } from '../../../context/PriceContext';
|
||||
|
||||
const IconPadding = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 8px;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const StatsColumn = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
`;
|
||||
|
||||
const BarSide = styled.div`
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const NodeTitle = styled.div`
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
`;
|
||||
import {
|
||||
ChannelNodeTitle,
|
||||
ChannelBarSide,
|
||||
ChannelIconPadding,
|
||||
ChannelStatsColumn,
|
||||
ChannelSingleLine,
|
||||
ChannelStatsLine,
|
||||
} from './Channel.style';
|
||||
|
||||
const getSymbol = (status: boolean) => {
|
||||
return status ? <ArrowDown size={14} /> : <ArrowUp size={14} />;
|
||||
|
@ -115,8 +77,7 @@ export const ChannelCard = ({
|
|||
biggestBaseFee,
|
||||
biggestRateFee,
|
||||
}: ChannelCardProps) => {
|
||||
const { channelBarType } = useConfigState();
|
||||
const dispatch = useConfigDispatch();
|
||||
const { channelBarType, channelBarStyle } = useConfigState();
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
const { theme, currency, displayValues } = useConfigState();
|
||||
|
@ -180,13 +141,6 @@ export const ChannelCard = ({
|
|||
}
|
||||
};
|
||||
|
||||
const handleBarClick = () => {
|
||||
dispatch({
|
||||
type: 'change',
|
||||
channelBarType: channelBarType === 'normal' ? 'partner' : 'normal',
|
||||
});
|
||||
};
|
||||
|
||||
const renderPartner = () =>
|
||||
alias ? (
|
||||
<>
|
||||
|
@ -196,8 +150,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:', `${base_fee} msats`)}
|
||||
{renderLine('Fee Rate:', `${fee_rate} sats/Msats`)}
|
||||
{renderLine('CTLV Delta:', cltv_delta)}
|
||||
</>
|
||||
) : (
|
||||
|
@ -253,7 +207,7 @@ export const ChannelCard = ({
|
|||
switch (channelBarType) {
|
||||
case 'partner':
|
||||
return (
|
||||
<>
|
||||
<ChannelStatsColumn>
|
||||
<ProgressBar
|
||||
order={0}
|
||||
percent={getBar(Number(partnerNodeCapacity), biggestPartner)}
|
||||
|
@ -264,16 +218,35 @@ export const ChannelCard = ({
|
|||
/>
|
||||
<ProgressBar order={1} percent={getBar(base_fee, biggestBaseFee)} />
|
||||
<ProgressBar order={2} percent={getBar(fee_rate, biggestRateFee)} />
|
||||
</>
|
||||
</ChannelStatsColumn>
|
||||
);
|
||||
default:
|
||||
case 'details':
|
||||
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)} />
|
||||
</>
|
||||
</ChannelStatsColumn>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<ChannelStatsColumn>
|
||||
<ChannelStatsLine>
|
||||
<ProgressBar
|
||||
order={1}
|
||||
percent={getPercent(local_balance, remote_balance)}
|
||||
/>
|
||||
<ProgressBar
|
||||
order={4}
|
||||
percent={getPercent(remote_balance, local_balance)}
|
||||
/>
|
||||
</ChannelStatsLine>
|
||||
<ChannelStatsLine>
|
||||
<ProgressBar order={2} percent={getPercent(received, sent)} />
|
||||
<ProgressBar order={4} percent={getPercent(sent, received)} />
|
||||
</ChannelStatsLine>
|
||||
</ChannelStatsColumn>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -285,10 +258,11 @@ export const ChannelCard = ({
|
|||
<>
|
||||
<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>
|
||||
<div>{`Partner Base Fee: ${base_fee} msats`}</div>
|
||||
<div>{`Partner Fee Rate: ${fee_rate} sats/Msats`}</div>
|
||||
</>
|
||||
);
|
||||
case 'details':
|
||||
default:
|
||||
return (
|
||||
<>
|
||||
|
@ -301,34 +275,52 @@ export const ChannelCard = ({
|
|||
}
|
||||
};
|
||||
|
||||
const getSubCardProps = () => {
|
||||
switch (channelBarStyle) {
|
||||
case 'ultracompact':
|
||||
return {
|
||||
withMargin: '0 0 4px 0',
|
||||
padding: index === indexOpen ? '0 0 16px' : '2px 0',
|
||||
noBackground: true,
|
||||
};
|
||||
case 'compact':
|
||||
return {
|
||||
withMargin: '0 0 4px 0',
|
||||
padding: index === indexOpen ? '4px 8px 16px' : '4px 8px',
|
||||
};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SubCard key={`${index}-${id}`} noCard={true}>
|
||||
<StatusLine>
|
||||
{getStatusDot(is_active, 'active')}
|
||||
{getStatusDot(is_opening, 'opening')}
|
||||
{getStatusDot(is_closing, 'closing')}
|
||||
</StatusLine>
|
||||
<ResponsiveLine>
|
||||
<NodeTitle style={{ flexGrow: 2 }}>
|
||||
<MainInfo onClick={() => handleClick()}>
|
||||
<SubCard key={`${index}-${id}`} noCard={true} {...getSubCardProps()}>
|
||||
<MainInfo onClick={() => handleClick()}>
|
||||
{channelBarStyle === 'normal' && (
|
||||
<StatusLine>
|
||||
{getStatusDot(is_active, 'active')}
|
||||
{getStatusDot(is_opening, 'opening')}
|
||||
{getStatusDot(is_closing, 'closing')}
|
||||
</StatusLine>
|
||||
)}
|
||||
<ResponsiveLine>
|
||||
<ChannelNodeTitle style={{ flexGrow: 2 }}>
|
||||
{alias || partner_public_key?.substring(0, 6)}
|
||||
<DarkSubTitle>{formatBalance}</DarkSubTitle>
|
||||
</MainInfo>
|
||||
</NodeTitle>
|
||||
<BarSide>
|
||||
<StatsColumn
|
||||
data-tip
|
||||
data-for={`node_balance_tip_${index}`}
|
||||
onClick={handleBarClick}
|
||||
>
|
||||
{channelBarStyle !== 'ultracompact' && (
|
||||
<ChannelSingleLine>
|
||||
<DarkSubTitle>{formatBalance}</DarkSubTitle>
|
||||
<ChannelIconPadding>
|
||||
{getPrivate(is_private)}
|
||||
{getSymbol(is_partner_initiated)}
|
||||
</ChannelIconPadding>
|
||||
</ChannelSingleLine>
|
||||
)}
|
||||
</ChannelNodeTitle>
|
||||
<ChannelBarSide data-tip data-for={`node_balance_tip_${index}`}>
|
||||
{renderBars()}
|
||||
</StatsColumn>
|
||||
</BarSide>
|
||||
<IconPadding>
|
||||
{getPrivate(is_private)}
|
||||
{getSymbol(is_partner_initiated)}
|
||||
</IconPadding>
|
||||
</ResponsiveLine>
|
||||
</ChannelBarSide>
|
||||
</ResponsiveLine>
|
||||
</MainInfo>
|
||||
{index === indexOpen && renderDetails()}
|
||||
<ReactTooltip
|
||||
id={`node_balance_tip_${index}`}
|
||||
|
|
131
src/views/channels/channels/ChannelManage.tsx
Normal file
131
src/views/channels/channels/ChannelManage.tsx
Normal file
|
@ -0,0 +1,131 @@
|
|||
import * as React from 'react';
|
||||
import {
|
||||
SingleButton,
|
||||
MultiButton,
|
||||
} from 'src/components/buttons/multiButton/MultiButton';
|
||||
import {
|
||||
useConfigState,
|
||||
useConfigDispatch,
|
||||
channelBarStyleTypes,
|
||||
channelBarTypeTypes,
|
||||
channelSortTypes,
|
||||
sortDirectionTypes,
|
||||
} from 'src/context/ConfigContext';
|
||||
import { Card, SingleLine, Sub4Title } from 'src/components/generic/Styled';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const MarginLine = styled(SingleLine)`
|
||||
margin: 8px 0;
|
||||
`;
|
||||
|
||||
export const ChannelManage = () => {
|
||||
const {
|
||||
channelBarType,
|
||||
channelBarStyle,
|
||||
channelSort,
|
||||
sortDirection,
|
||||
} = useConfigState();
|
||||
const dispatch = useConfigDispatch();
|
||||
|
||||
const changeStyle = (style: channelBarStyleTypes) =>
|
||||
dispatch({ type: 'change', channelBarStyle: style });
|
||||
const changeType = (type: channelBarTypeTypes) =>
|
||||
dispatch({ type: 'change', channelBarType: type });
|
||||
const changeSort = (type: channelSortTypes) =>
|
||||
dispatch({ type: 'change', channelSort: type });
|
||||
const changeDirection = (type: sortDirectionTypes) =>
|
||||
dispatch({ type: 'change', sortDirection: type });
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<MarginLine>
|
||||
<Sub4Title>Card Type</Sub4Title>
|
||||
<MultiButton>
|
||||
<SingleButton
|
||||
selected={channelBarStyle === 'normal'}
|
||||
onClick={() => changeStyle('normal')}
|
||||
>
|
||||
Normal
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelBarStyle === 'compact'}
|
||||
onClick={() => changeStyle('compact')}
|
||||
>
|
||||
Compact
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelBarStyle === 'ultracompact'}
|
||||
onClick={() => changeStyle('ultracompact')}
|
||||
>
|
||||
Ultra-Compact
|
||||
</SingleButton>
|
||||
</MultiButton>
|
||||
</MarginLine>
|
||||
<MarginLine>
|
||||
<Sub4Title>Bar Types</Sub4Title>
|
||||
<MultiButton>
|
||||
<SingleButton
|
||||
selected={channelBarType === 'balance'}
|
||||
onClick={() => changeType('balance')}
|
||||
>
|
||||
Balance
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelBarType === 'details'}
|
||||
onClick={() => changeType('details')}
|
||||
>
|
||||
Proportional
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelBarType === 'partner'}
|
||||
onClick={() => changeType('partner')}
|
||||
>
|
||||
Partner
|
||||
</SingleButton>
|
||||
</MultiButton>
|
||||
</MarginLine>
|
||||
<MarginLine>
|
||||
<Sub4Title>Sort</Sub4Title>
|
||||
<MultiButton>
|
||||
<SingleButton
|
||||
selected={channelSort === 'none'}
|
||||
onClick={() => changeSort('none')}
|
||||
>
|
||||
None
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelSort === 'local'}
|
||||
onClick={() => changeSort('local')}
|
||||
>
|
||||
Local
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={channelSort === 'balance'}
|
||||
onClick={() => changeSort('balance')}
|
||||
>
|
||||
Balance
|
||||
</SingleButton>
|
||||
</MultiButton>
|
||||
</MarginLine>
|
||||
{channelSort !== 'none' && (
|
||||
<MarginLine>
|
||||
<Sub4Title>Direction</Sub4Title>
|
||||
<MultiButton>
|
||||
<SingleButton
|
||||
selected={sortDirection === 'increase'}
|
||||
onClick={() => changeDirection('increase')}
|
||||
>
|
||||
Increasing
|
||||
</SingleButton>
|
||||
<SingleButton
|
||||
selected={sortDirection === 'decrease'}
|
||||
onClick={() => changeDirection('decrease')}
|
||||
>
|
||||
Decreasing
|
||||
</SingleButton>
|
||||
</MultiButton>
|
||||
</MarginLine>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
};
|
|
@ -2,12 +2,16 @@ import React, { useState } from 'react';
|
|||
import { toast } from 'react-toastify';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetChannelsQuery } from 'src/graphql/queries/__generated__/getChannels.generated';
|
||||
import { useConfigState } from 'src/context/ConfigContext';
|
||||
import { sortBy } from 'underscore';
|
||||
import { getPercent } from 'src/utils/helpers';
|
||||
import { Card } from '../../../components/generic/Styled';
|
||||
import { getErrorContent } from '../../../utils/error';
|
||||
import { LoadingCard } from '../../../components/loading/LoadingCard';
|
||||
import { ChannelCard } from './ChannelCard';
|
||||
|
||||
export const Channels = () => {
|
||||
const { sortDirection, channelSort } = useConfigState();
|
||||
const [indexOpen, setIndexOpen] = useState(0);
|
||||
|
||||
const { auth } = useAccountState();
|
||||
|
@ -62,9 +66,26 @@ export const Channels = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const getChannels = () => {
|
||||
switch (channelSort) {
|
||||
case 'local': {
|
||||
const newArray = sortBy(data.getChannels, 'local_balance');
|
||||
return sortDirection === 'increase' ? newArray : newArray.reverse();
|
||||
}
|
||||
case 'balance': {
|
||||
const newArray = sortBy(data.getChannels, channel =>
|
||||
getPercent(channel.local_balance, channel.remote_balance)
|
||||
);
|
||||
return sortDirection === 'increase' ? newArray : newArray.reverse();
|
||||
}
|
||||
default:
|
||||
return data.getChannels;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{data.getChannels.map((channel, index: number) => (
|
||||
{getChannels().map((channel, index: number) => (
|
||||
<ChannelCard
|
||||
channelInfo={channel}
|
||||
index={index + 1}
|
||||
|
@ -74,7 +95,7 @@ export const Channels = () => {
|
|||
biggest={biggest}
|
||||
biggestPartner={biggestPartner}
|
||||
mostChannels={mostChannels}
|
||||
biggestBaseFee={biggestBaseFee * 2}
|
||||
biggestBaseFee={biggestBaseFee}
|
||||
biggestRateFee={biggestRateFee}
|
||||
/>
|
||||
))}
|
||||
|
|
Loading…
Add table
Reference in a new issue