From c2d2dc8e36065633541c4f1454b089735cd25936 Mon Sep 17 00:00:00 2001 From: Anthony Potdevin <31413433+apotdevin@users.noreply.github.com> Date: Sat, 23 May 2020 18:45:28 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20style=20changes=20(#48)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ✨ style changes * chore: 🔧 number format * fix: 🐛 partner capacity * fix: 🐛 small change * chore: 🔧 add channel status * refactor: ♻️ bar width --- .eslintrc.js | 2 + api/schemas/query/channels/channels.ts | 132 ++++++----- api/schemas/types/QueryType.ts | 3 + package.json | 2 +- pages/balance.tsx | 2 +- pages/channels.tsx | 46 ++-- pages/fees.tsx | 2 +- pages/forwards.tsx | 21 +- pages/peers.tsx | 2 +- pages/settings.tsx | 11 +- pages/trading.tsx | 2 +- pages/transactions.tsx | 2 +- src/components/accounts/AuthSSOCheck.tsx | 2 +- src/components/accounts/ServerAccounts.tsx | 2 +- src/components/chat/ChatInit.tsx | 2 +- src/components/generic/CardGeneric.tsx | 26 ++- src/components/generic/Styled.tsx | 59 +++-- src/components/generic/helpers.tsx | 12 +- .../modal/removePeer/RemovePeer.tsx | 2 +- src/components/statusCheck/StatusCheck.tsx | 6 +- src/context/ConfigContext.tsx | 3 + .../__generated__/getChannels.generated.tsx | 12 +- src/graphql/queries/getChannels.ts | 3 + src/graphql/types.ts | 3 + src/layouts/header/Header.tsx | 2 +- src/utils/helpers.tsx | 12 +- .../chain/transactions/ChainTransactions.tsx | 2 +- src/views/chain/utxos/ChainUtxos.tsx | 2 +- src/views/channels/channels/ChannelCard.tsx | 213 +++++++++++++----- src/views/channels/channels/Channels.tsx | 48 +++- .../channels/closedChannels/ClosedCard.tsx | 3 +- .../closedChannels/ClosedChannels.tsx | 4 +- .../channels/pendingChannels/PendingCard.tsx | 31 +-- .../pendingChannels/PendingChannels.tsx | 4 +- src/views/chat/ChatBubble.tsx | 2 +- src/views/chat/ChatInput.tsx | 2 +- src/views/chat/Contacts.tsx | 2 +- src/views/home/account/AccountInfo.tsx | 58 +++-- src/views/home/connect/Connect.tsx | 18 +- src/views/home/quickActions/QuickActions.tsx | 6 +- src/views/home/reports/flow/FlowReport.tsx | 63 +----- .../home/reports/forwardReport/Buttons.tsx | 6 +- .../forwardReport/ForwardChannelReport.tsx | 16 +- .../reports/liquidReport/LiquidReport.tsx | 2 +- src/views/homepage/Accounts.tsx | 2 +- src/views/settings/Danger.tsx | 11 +- src/views/settings/index.tsx | 11 +- 47 files changed, 508 insertions(+), 371 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 17569680..3193a17f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,8 +39,10 @@ module.exports = { ], rules: { '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', 'import/no-unresolved': 'off', 'import/order': 2, + 'no-unused-vars': 2, camelcase: 'off', '@typescript-eslint/camelcase': 'off', 'react/prop-types': 'off', diff --git a/api/schemas/query/channels/channels.ts b/api/schemas/query/channels/channels.ts index 260610d2..704d9f0e 100644 --- a/api/schemas/query/channels/channels.ts +++ b/api/schemas/query/channels/channels.ts @@ -1,6 +1,12 @@ import { GraphQLList, GraphQLBoolean } from 'graphql'; -import { getChannels as getLnChannels, getNode } from 'ln-service'; +import { + getChannels as getLnChannels, + getNode, + getChannel, + getWalletInfo, +} from 'ln-service'; import { ContextType } from 'api/types/apiTypes'; +import { toWithError } from 'api/helpers/async'; import { logger } from '../../../helpers/logger'; import { requestLimiter } from '../../../helpers/rateLimiter'; import { @@ -11,36 +17,6 @@ import { import { defaultParams } from '../../../helpers/defaultProps'; import { ChannelType } from '../../types/QueryType'; -interface ChannelListProps { - channels: ChannelProps[]; -} - -interface ChannelProps { - capacity: number; - commit_transaction_fee: number; - commit_transaction_weight: number; - id: string; - is_active: boolean; - is_closing: boolean; - is_opening: boolean; - is_partner_initiated: boolean; - is_private: boolean; - is_static_remote_key: boolean; - local_balance: number; - local_reserve: number; - partner_public_key: string; - pending_payments: []; - received: number; - remote_balance: number; - remote_reserve: number; - sent: number; - time_offline: number; - time_online: number; - transaction_id: string; - transaction_vout: number; - unsettled_balance: number; -} - export const getChannels = { type: new GraphQLList(ChannelType), args: { @@ -53,37 +29,83 @@ export const getChannels = { const auth = getCorrectAuth(params.auth, context); const lnd = getAuthLnd(auth); - try { - const channelList: ChannelListProps = await getLnChannels({ + const [walletInfo, walletError] = await toWithError(getWalletInfo({ lnd })); + const publicKey = walletInfo?.public_key; + + walletError && + logger.debug('Error getting wallet info in getChannels: %o', walletError); + + const [channelList, channelListError] = await toWithError( + getLnChannels({ lnd, is_active: params.active, - }); + }) + ); - const getChannelList = () => - Promise.all( - channelList.channels.map(async channel => { - const nodeInfo = await getNode({ + if (channelListError) { + logger.error('Error getting channels: %o', channelListError); + throw new Error(getErrorMsg(channelListError)); + } + + const getChannelList = () => + Promise.all( + channelList.channels.map(async channel => { + const [nodeInfo, nodeError] = await toWithError( + getNode({ lnd, is_omitting_channels: true, public_key: channel.partner_public_key, - }); + }) + ); - return { - ...channel, - time_offline: Math.round((channel.time_offline || 0) / 1000), - time_online: Math.round((channel.time_online || 0) / 1000), - partner_node_info: { - ...nodeInfo, - }, - }; - }) - ); + const [channelInfo, channelError] = await toWithError( + getChannel({ + lnd, + id: channel.id, + }) + ); - const channels = await getChannelList(); - return channels; - } catch (error) { - logger.error('Error getting channels: %o', error); - throw new Error(getErrorMsg(error)); - } + nodeError && + logger.debug( + `Error getting node with public key ${channel.partner_public_key}: %o`, + nodeError + ); + + channelError && + logger.debug( + `Error getting channel with id ${channel.id}: %o`, + channelError + ); + + let partnerFees = {}; + if (!channelError && publicKey) { + const partnerPolicy = channelInfo.policies.filter( + policy => policy.public_key !== publicKey + ); + if (partnerPolicy && partnerPolicy.length >= 1) { + partnerFees = { + base_fee: partnerPolicy[0].base_fee_mtokens || 0, + fee_rate: partnerPolicy[0].fee_rate || 0, + cltv_delta: partnerPolicy[0].cltv_delta || 0, + }; + } + } + + const partner_node_info = { + ...(!nodeError && nodeInfo), + ...partnerFees, + }; + + return { + ...channel, + time_offline: Math.round((channel.time_offline || 0) / 1000), + time_online: Math.round((channel.time_online || 0) / 1000), + partner_node_info, + }; + }) + ); + + const channels = await getChannelList(); + return channels; }, }; diff --git a/api/schemas/types/QueryType.ts b/api/schemas/types/QueryType.ts index 18775568..e3a441d8 100644 --- a/api/schemas/types/QueryType.ts +++ b/api/schemas/types/QueryType.ts @@ -84,6 +84,9 @@ export const PartnerNodeType = new GraphQLObjectType({ channel_count: { type: GraphQLInt }, color: { type: GraphQLString }, updated_at: { type: GraphQLString }, + base_fee: { type: GraphQLInt }, + fee_rate: { type: GraphQLInt }, + cltv_delta: { type: GraphQLInt }, }; }, }); diff --git a/package.json b/package.json index 684e2982..cbeccf75 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "start:two": "cross-env NODE_OPTIONS='--insecure-http-parser' next start -p 3001", "start:compatible": "next start", "start:compatible:two": "next start -p 3001", - "lint": "eslint */**/*.{js,ts,tsx} --quiet --fix", + "lint": "eslint */**/*.{js,ts,tsx} --fix", "prettier": "prettier --write **/*.{ts,tsx,js,css,html}", "release": "standard-version", "release:push": "standard-version && git push --follow-tags origin master", diff --git a/pages/balance.tsx b/pages/balance.tsx index 729083a3..2bac30fa 100644 --- a/pages/balance.tsx +++ b/pages/balance.tsx @@ -161,7 +161,7 @@ const BalanceView = () => { Channel Balancing - + {renderOutgoing()} {renderIncoming()} diff --git a/pages/channels.tsx b/pages/channels.tsx index ae8b34c1..54bb97de 100644 --- a/pages/channels.tsx +++ b/pages/channels.tsx @@ -1,18 +1,31 @@ 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 { Channels } from '../src/views/channels/channels/Channels'; import { PendingChannels } from '../src/views/channels/pendingChannels/PendingChannels'; import { ClosedChannels } from '../src/views/channels/closedChannels/ClosedChannels'; import { CardWithTitle, SubTitle, - CardTitle, - SingleLine, - ColorButton, + SmallButton, } from '../src/components/generic/Styled'; -import { useConfigState } from '../src/context/ConfigContext'; -import { textColorMap } from '../src/styles/Themes'; +import { mediaWidths } from '../src/styles/Themes'; + +const ChannelsCardTitle = styled.div` + display: flex; + justify-content: space-between; + + @media (${mediaWidths.mobile}) { + flex-direction: column; + align-items: center; + } +`; + +const ButtonRow = styled.div` + display: flex; + flex-wrap: wrap; +`; const ChannelView = () => { const [view, setView] = useState(1); @@ -22,7 +35,6 @@ const ChannelView = () => { closed: 0, }); - const { theme } = useConfigState(); const { auth } = useAccountState(); const { data } = useGetChannelAmountInfoQuery({ @@ -31,7 +43,7 @@ const ChannelView = () => { }); useEffect(() => { - if (data?.getNodeInfo) { + if (data && data.getNodeInfo) { const { active_channels_count, closed_channels_count, @@ -70,20 +82,20 @@ const ChannelView = () => { return ( - + {getTitle()} - - setView(1)}> + + setView(1)}> {`Open (${amounts.active})`} - - setView(2)}> + + setView(2)}> {`Pending (${amounts.pending})`} - - setView(3)}> + + setView(3)}> {`Closed (${amounts.closed})`} - - - + + + {getView()} ); diff --git a/pages/fees.tsx b/pages/fees.tsx index 9cdc5a18..52cee43d 100644 --- a/pages/fees.tsx +++ b/pages/fees.tsx @@ -110,7 +110,7 @@ const FeesView = () => { Channel Fees - + {data.getChannelFees.map((channel: any, index: number) => ( { const [time, setTime] = useState('week'); const [indexOpen, setIndexOpen] = useState(0); - const { theme } = useConfigState(); const { auth } = useAccountState(); const { loading, data } = useGetForwardsQuery({ @@ -42,17 +39,13 @@ const ForwardsView = () => { } const renderButton = (selectedTime: string, title: string) => ( - setTime(selectedTime)} - selected={time === selectedTime} - > - {title} - + setTime(selectedTime)}>{title} ); const renderNoForwards = () => ( -

{`Your node has not forwarded any payments ${timeMap[time]}.`}

+ +

{`Your node has not forwarded any payments ${timeMap[time]}.`}

+
); return ( @@ -68,8 +61,8 @@ const ForwardsView = () => { {renderButton('threeMonths', '3M')} - - {data.getForwards.forwards.length <= 0 && renderNoForwards()} + {data.getForwards.forwards.length <= 0 && renderNoForwards()} + {data.getForwards.forwards.map((forward: any, index: number) => ( { Peers - + {data.getPeers.map((peer: any, index: number) => ( { return ( <> diff --git a/pages/trading.tsx b/pages/trading.tsx index a5d949e7..98bb4f90 100644 --- a/pages/trading.tsx +++ b/pages/trading.tsx @@ -99,7 +99,7 @@ const TradingView = () => { - + {amountOfOffers <= 0 && No Offers Found} {data.getOffers.map((offer: any, index: number) => ( { Transactions - + {resumeList.map((entry: any, index: number) => { if (entry.type === 'invoice') { return ( diff --git a/src/components/accounts/AuthSSOCheck.tsx b/src/components/accounts/AuthSSOCheck.tsx index 0fa33b3a..23fcfbf3 100644 --- a/src/components/accounts/AuthSSOCheck.tsx +++ b/src/components/accounts/AuthSSOCheck.tsx @@ -25,7 +25,7 @@ export const AuthSSOCheck = ({ cookieParam }: AuthCheckProps) => { }); React.useEffect(() => { - if (cookieParam && !loading && data?.getAuthToken && !ssoSaved) { + if (cookieParam && !loading && data && data.getAuthToken && !ssoSaved) { Cookies.set('SSOAuth', data.getAuthToken, { sameSite: 'strict', }); diff --git a/src/components/accounts/ServerAccounts.tsx b/src/components/accounts/ServerAccounts.tsx index f163e7fe..00d1ede3 100644 --- a/src/components/accounts/ServerAccounts.tsx +++ b/src/components/accounts/ServerAccounts.tsx @@ -40,7 +40,7 @@ export const ServerAccounts = () => { }, [dispatch]); React.useEffect(() => { - if (!loading && data?.getServerAccounts) { + if (!loading && data && data.getServerAccounts) { const accountsToAdd = data.getServerAccounts.map(a => { const type = a?.id === SSO_ACCOUNT ? SSO_ACCOUNT : SERVER_ACCOUNT; return { diff --git a/src/components/chat/ChatInit.tsx b/src/components/chat/ChatInit.tsx index 06a10679..0af889d1 100644 --- a/src/components/chat/ChatInit.tsx +++ b/src/components/chat/ChatInit.tsx @@ -42,7 +42,7 @@ export const ChatInit = () => { }, [dispatch, getMessages, account]); React.useEffect(() => { - if (!initLoading && !initError && initData?.getMessages) { + if (!initLoading && !initError && initData && initData.getMessages) { const { messages } = initData.getMessages; if (messages.length <= 0) { diff --git a/src/components/generic/CardGeneric.tsx b/src/components/generic/CardGeneric.tsx index a8cb6ab0..37b14a92 100644 --- a/src/components/generic/CardGeneric.tsx +++ b/src/components/generic/CardGeneric.tsx @@ -1,11 +1,10 @@ import styled from 'styled-components'; import { progressBackground, - progressFirst, - progressSecond, mediaWidths, cardColor, cardBorderColor, + chartColors, } from '../../styles/Themes'; export const Progress = styled.div` @@ -20,13 +19,18 @@ interface ProgressBar { export const ProgressBar = styled.div` height: 10px; - background-image: linear-gradient( - to bottom, - rgba(255, 255, 255, 0.3), - rgba(0, 0, 0, 0.05) - ); - background-color: ${({ order }) => - order === 2 ? progressFirst : progressSecond}; + background-color: ${({ order }) => { + switch (order) { + case 1: + return chartColors.lightblue; + case 2: + return chartColors.green; + case 3: + return chartColors.orange; + default: + return chartColors.purple; + } + }}; width: ${({ percent }) => `${percent}%`}; `; @@ -47,8 +51,8 @@ export const NodeTitle = styled.div` export const StatusLine = styled.div` width: 100%; position: relative; - right: -8px; - top: -8px; + right: -12px; + top: -12px; display: flex; justify-content: flex-end; margin: 0 0 -8px 0; diff --git a/src/components/generic/Styled.tsx b/src/components/generic/Styled.tsx index 0e74af59..197700cf 100644 --- a/src/components/generic/Styled.tsx +++ b/src/components/generic/Styled.tsx @@ -7,11 +7,13 @@ import { smallLinkColor, unSelectedNavButton, textColor, - buttonBorderColor, chartLinkColor, inverseTextColor, separationColor, mediaWidths, + colorButtonBackground, + colorButtonBorder, + hoverTextColor, } from '../../styles/Themes'; export const CardWithTitle = styled.div` @@ -29,6 +31,7 @@ export interface CardProps { bottom?: string; cardPadding?: string; mobileCardPadding?: string; + mobileNoBackground?: boolean; } export const Card = styled.div` @@ -41,6 +44,13 @@ export const Card = styled.div` width: 100%; @media (${mediaWidths.mobile}) { + ${({ mobileNoBackground }) => + mobileNoBackground && + css` + background: unset; + border: none; + box-shadow: none; + `} ${({ cardPadding, mobileCardPadding }) => mobileCardPadding ? css` @@ -70,6 +80,7 @@ interface SubCardProps { color?: string; padding?: string; withMargin?: string; + noCard?: boolean; } export const SubCard = styled.div` @@ -146,27 +157,6 @@ export const ColumnLine = styled.div` } `; -export const SimpleButton = styled.button<{ enabled?: boolean }>` - cursor: pointer; - outline: none; - padding: 5px; - margin: 5px; - text-decoration: none; - background-color: transparent; - color: ${({ enabled = true }) => (enabled ? textColor : unSelectedNavButton)}; - border: 1px solid ${buttonBorderColor}; - display: flex; - align-items: center; - justify-content: center; - border-radius: 5px; - white-space: nowrap; -`; - -export const SimpleInverseButton = styled(SimpleButton)` - color: ${({ enabled = true }: { enabled?: boolean }) => - enabled ? inverseTextColor : unSelectedNavButton}; -`; - interface DarkProps { fontSize?: string; withMargin?: string; @@ -178,17 +168,24 @@ export const DarkSubTitle = styled.div` margin: ${({ withMargin }) => (withMargin ? withMargin : '0')}; `; -interface ColorProps { - color: string; - selected?: boolean; -} -export const ColorButton = styled(SimpleButton)` - color: ${({ selected }) => (selected ? textColor : chartLinkColor)}; - border: ${({ selected, color }) => (selected ? `1px solid ${color}` : '')}; +export const SmallButton = styled.button` + cursor: pointer; + outline: none; + padding: 5px; + margin: 5px; + text-decoration: none; + border: none; + display: flex; + align-items: center; + justify-content: center; + border-radius: 5px; + white-space: nowrap; + color: ${chartLinkColor}; + background-color: ${colorButtonBackground}; &:hover { - border: 1px solid ${({ color }: ColorProps) => color}; - color: ${textColor}; + color: ${hoverTextColor}; + background-color: ${colorButtonBorder}; } `; diff --git a/src/components/generic/helpers.tsx b/src/components/generic/helpers.tsx index 2e3c0c7d..823c3452 100644 --- a/src/components/generic/helpers.tsx +++ b/src/components/generic/helpers.tsx @@ -9,11 +9,19 @@ import { X } from 'react-feather'; import { SmallLink, DarkSubTitle, OverflowText, SingleLine } from './Styled'; import { StatusDot, DetailLine } from './CardGeneric'; +const shorten = (text: string): string => { + const amount = 6; + const beginning = text.slice(0, amount); + const end = text.slice(text.length - amount); + + return `${beginning}...${end}`; +}; + export const getTransactionLink = (transaction: string) => { const link = `https://www.blockchain.com/btc/tx/${transaction}`; return ( - {transaction} + {shorten(transaction)} ); }; @@ -22,7 +30,7 @@ export const getNodeLink = (publicKey: string) => { const link = `https://1ml.com/node/${publicKey}`; return ( - {publicKey} + {shorten(publicKey)} ); }; diff --git a/src/components/modal/removePeer/RemovePeer.tsx b/src/components/modal/removePeer/RemovePeer.tsx index 4ba921d5..db081327 100644 --- a/src/components/modal/removePeer/RemovePeer.tsx +++ b/src/components/modal/removePeer/RemovePeer.tsx @@ -27,7 +27,7 @@ export const RemovePeerModal = ({ peerAlias, }: RemovePeerProps) => { const [removePeer, { loading }] = useRemovePeerMutation({ - onCompleted: data => { + onCompleted: () => { toast.success('Peer Removed'); }, onError: error => { diff --git a/src/components/statusCheck/StatusCheck.tsx b/src/components/statusCheck/StatusCheck.tsx index 742429ca..578895d8 100644 --- a/src/components/statusCheck/StatusCheck.tsx +++ b/src/components/statusCheck/StatusCheck.tsx @@ -3,7 +3,7 @@ import { useRouter } from 'next/router'; import { toast } from 'react-toastify'; import { useAccountState } from 'src/context/AccountContext'; import { useGetNodeInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated'; -import { useStatusDispatch, useStatusState } from '../../context/StatusContext'; +import { useStatusDispatch } from '../../context/StatusContext'; import { appendBasePath } from '../../utils/basePath'; export const StatusCheck = () => { @@ -11,10 +11,8 @@ export const StatusCheck = () => { const { push } = useRouter(); const { account, auth } = useAccountState(); - const { connected } = useStatusState(); - const { data, loading, error, stopPolling } = useGetNodeInfoQuery({ - skip: !auth || !connected, + skip: !auth, fetchPolicy: 'network-only', variables: { auth }, pollInterval: 10000, diff --git a/src/context/ConfigContext.tsx b/src/context/ConfigContext.tsx index b64c50c9..74816ffe 100644 --- a/src/context/ConfigContext.tsx +++ b/src/context/ConfigContext.tsx @@ -17,6 +17,7 @@ type State = { hideNonVerified: boolean; maxFee: number; chatPollingSpeed: number; + channelBarType: 'normal' | 'partner'; }; type ConfigInitProps = { @@ -36,6 +37,7 @@ type ActionType = { hideNonVerified?: boolean; maxFee?: number; chatPollingSpeed?: number; + channelBarType?: 'normal' | 'partner'; }; type Dispatch = (action: ActionType) => void; @@ -63,6 +65,7 @@ const initialState: State = { hideNonVerified: false, maxFee: 20, chatPollingSpeed: 1000, + channelBarType: 'normal', }; const stateReducer = (state: State, action: ActionType): State => { diff --git a/src/graphql/queries/__generated__/getChannels.generated.tsx b/src/graphql/queries/__generated__/getChannels.generated.tsx index 9a7cd7aa..e9617cfd 100644 --- a/src/graphql/queries/__generated__/getChannels.generated.tsx +++ b/src/graphql/queries/__generated__/getChannels.generated.tsx @@ -40,7 +40,14 @@ export type GetChannelsQuery = { __typename?: 'Query' } & { partner_node_info?: Types.Maybe< { __typename?: 'partnerNodeType' } & Pick< Types.PartnerNodeType, - 'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at' + | 'alias' + | 'capacity' + | 'channel_count' + | 'color' + | 'updated_at' + | 'base_fee' + | 'fee_rate' + | 'cltv_delta' > >; } @@ -80,6 +87,9 @@ export const GetChannelsDocument = gql` channel_count color updated_at + base_fee + fee_rate + cltv_delta } } } diff --git a/src/graphql/queries/getChannels.ts b/src/graphql/queries/getChannels.ts index 68d51998..b7be6415 100644 --- a/src/graphql/queries/getChannels.ts +++ b/src/graphql/queries/getChannels.ts @@ -31,6 +31,9 @@ export const GET_CHANNELS = gql` channel_count color updated_at + base_fee + fee_rate + cltv_delta } } } diff --git a/src/graphql/types.ts b/src/graphql/types.ts index 3e79735f..472198db 100644 --- a/src/graphql/types.ts +++ b/src/graphql/types.ts @@ -261,6 +261,9 @@ export type PartnerNodeType = { channel_count?: Maybe; color?: Maybe; updated_at?: Maybe; + base_fee?: Maybe; + fee_rate?: Maybe; + cltv_delta?: Maybe; }; export type ClosedChannelType = { diff --git a/src/layouts/header/Header.tsx b/src/layouts/header/Header.tsx index 6e97efa2..71d58deb 100644 --- a/src/layouts/header/Header.tsx +++ b/src/layouts/header/Header.tsx @@ -61,7 +61,7 @@ export const Header = () => { - + ThunderHub diff --git a/src/utils/helpers.tsx b/src/utils/helpers.tsx index 99507a47..cb2f9e10 100644 --- a/src/utils/helpers.tsx +++ b/src/utils/helpers.tsx @@ -35,7 +35,9 @@ export const getValue = ({ if (currency === 'btc') { if (!value) return '₿0.0'; const amountInBtc = value / 100000000; - return `₿${amountInBtc}`; + const rounded = Math.round(amountInBtc * 10000) / 10000; + + return `₿${rounded}`; } if (currency === 'sat') { const breakAmount = breakNumber @@ -107,9 +109,9 @@ export const formatSeconds = (seconds: number): string | null => { const m = Math.floor((seconds % 3600) / 60); const s = Math.floor(seconds % 60); - const dDisplay = d > 0 ? d + (d == 1 ? ' day, ' : ' days, ') : ''; - const hDisplay = h > 0 ? h + (h == 1 ? ' hour, ' : ' hours, ') : ''; - const mDisplay = m > 0 ? m + (m == 1 ? ' minute, ' : ' minutes, ') : ''; - const sDisplay = s > 0 ? s + (s == 1 ? ' second' : ' seconds') : ''; + const dDisplay = d > 0 ? `${d}d ` : ''; + const hDisplay = h > 0 ? `${h}h ` : ''; + const mDisplay = m > 0 ? `${m}m ` : ''; + const sDisplay = s > 0 ? `${s}s` : ''; return dDisplay + hDisplay + mDisplay + sDisplay; }; diff --git a/src/views/chain/transactions/ChainTransactions.tsx b/src/views/chain/transactions/ChainTransactions.tsx index b10e5b39..e6c66c6a 100644 --- a/src/views/chain/transactions/ChainTransactions.tsx +++ b/src/views/chain/transactions/ChainTransactions.tsx @@ -28,7 +28,7 @@ export const ChainTransactions = () => { return ( Chain Transactions - + {data.getChainTransactions.map((transaction: any, index: number) => ( { return ( Unspent Utxos - + {data.getUtxos.map((utxo: any, index: number) => ( { - return status ? : ; + return status ? : ; }; const getPrivate = (status: boolean) => { - return status && ; + return status && ; +}; + +const getBar = (top: number, bottom: number) => { + const percent = (top / bottom) * 100; + return Math.min(percent, 100); }; interface ChannelCardProps { - channelInfo: any; + channelInfo: ChannelType; index: number; setIndexOpen: (index: number) => void; indexOpen: number; + biggest: number; + biggestPartner: number; + mostChannels: number; + biggestBaseFee: number; + biggestRateFee: number; } export const ChannelCard = ({ @@ -61,7 +109,14 @@ export const ChannelCard = ({ index, setIndexOpen, indexOpen, + biggest, + biggestPartner, + mostChannels, + biggestBaseFee, + biggestRateFee, }: ChannelCardProps) => { + const { channelBarType } = useConfigState(); + const dispatch = useConfigDispatch(); const [modalOpen, setModalOpen] = useState(false); const { theme, currency, displayValues } = useConfigState(); @@ -98,10 +153,12 @@ export const ChannelCard = ({ const { alias, - capacity: partnerNodeCapacity, + capacity: partnerNodeCapacity = 0, channel_count, - color: nodeColor, updated_at, + base_fee, + fee_rate, + cltv_delta, } = partner_node_info; const formatBalance = format({ amount: capacity }); @@ -123,10 +180,20 @@ export const ChannelCard = ({ } }; + const handleBarClick = () => { + dispatch({ + type: 'change', + channelBarType: channelBarType === 'normal' ? 'partner' : 'normal', + }); + }; + const renderDetails = () => { return ( <> + {renderLine('Status:', is_active ? 'Active' : 'Not Active')} + {renderLine('Is Opening:', is_opening ? 'True' : 'False')} + {renderLine('Is Closing:', is_closing ? 'True' : 'False')} {renderLine( 'Balancedness:', getPercent(local_balance, remote_balance) / 100 @@ -154,6 +221,9 @@ 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('CTLV Delta:', cltv_delta)} @@ -170,37 +240,86 @@ export const ChannelCard = ({ ); }; + const renderBars = () => { + switch (channelBarType) { + case 'partner': + return ( + <> + + + + + + ); + default: + return ( + <> + + + + + + ); + } + }; + + const renderBarsInfo = () => { + switch (channelBarType) { + case 'partner': + return ( + <> +
{`Partner Capacity: ${nodeCapacity}`}
+
{`Partner Channels: ${channel_count}`}
+
{`Partner Base Fee: ${base_fee} mSats`}
+
{`Partner Fee Rate: ${fee_rate} sats/MSats`}
+ + ); + default: + return ( + <> +
{`Local Balance: ${formatLocal}`}
+
{`Remote Balance: ${formatRemote}`}
+
{`Received: ${formatReceived}`}
+
{`Sent: ${formatSent}`}
+ + ); + } + }; + return ( - - handleClick()}> - - {getStatusDot(is_active, 'active')} - {getStatusDot(is_opening, 'opening')} - {getStatusDot(is_closing, 'closing')} - - - + + + {getStatusDot(is_active, 'active')} + {getStatusDot(is_opening, 'opening')} + {getStatusDot(is_closing, 'closing')} + + + + handleClick()}> {alias || partner_public_key?.substring(0, 6)} - - - {formatBalance} - - {getPrivate(is_private)} - {getSymbol(is_partner_initiated)} - - - - - - - - - - - - + {formatBalance} + + + + + {renderBars()} + + + + {getPrivate(is_private)} + {getSymbol(is_partner_initiated)} + +
{index === indexOpen && renderDetails()} -
{`Local Balance: ${formatLocal}`}
-
{`Remote Balance: ${formatRemote}`}
-
- -
{`Received: ${formatReceived}`}
-
{`Sent: ${formatSent}`}
+ {renderBarsInfo()}
setModalOpen(false)}> { return ; } + let biggest = 0; + let biggestPartner = 0; + let mostChannels = 0; + let biggestBaseFee = 0; + let biggestRateFee = 0; + + 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 { 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); + + if (max > biggest) { + biggest = max; + } + if (partner > biggestPartner) { + biggestPartner = partner; + } + if (channels > mostChannels) { + mostChannels = channels; + } + if (base_fee > biggestBaseFee) { + biggestBaseFee = base_fee; + } + if (fee_rate > biggestRateFee) { + biggestRateFee = fee_rate; + } + } + return ( - - {data.getChannels.map((channel: any, index: number) => ( + + {data.getChannels.map((channel, index: number) => ( ))} diff --git a/src/views/channels/closedChannels/ClosedCard.tsx b/src/views/channels/closedChannels/ClosedCard.tsx index 38a09e9d..275f4772 100644 --- a/src/views/channels/closedChannels/ClosedCard.tsx +++ b/src/views/channels/closedChannels/ClosedCard.tsx @@ -1,5 +1,6 @@ import React from 'react'; import styled from 'styled-components'; +import { ClosedChannelType } from 'src/graphql/types'; import { NodeTitle, MainInfo } from '../../../components/generic/CardGeneric'; import { SubCard, @@ -20,7 +21,7 @@ const Padding = styled.div` `; interface PendingCardProps { - channelInfo: any; + channelInfo: ClosedChannelType; index: number; setIndexOpen: (index: number) => void; indexOpen: number; diff --git a/src/views/channels/closedChannels/ClosedChannels.tsx b/src/views/channels/closedChannels/ClosedChannels.tsx index 415854f5..d171d9ba 100644 --- a/src/views/channels/closedChannels/ClosedChannels.tsx +++ b/src/views/channels/closedChannels/ClosedChannels.tsx @@ -23,8 +23,8 @@ export const ClosedChannels = () => { } return ( - - {data.getClosedChannels.map((channel: any, index: number) => ( + + {data.getClosedChannels.map((channel, index: number) => ( void; indexOpen: number; @@ -93,7 +70,7 @@ export const PendingCard = ({ const { alias, capacity, - channelCount, + channel_count, color: nodeColor, updated_at, } = partner_node_info; @@ -132,7 +109,7 @@ export const PendingCard = ({ {renderLine('Remote Reserve:', remote_reserve)} Partner Node Info {renderLine('Node Capacity:', capacity)} - {renderLine('Channels:', channelCount)} + {renderLine('Channels:', channel_count)} {renderLine( 'Last Update:', `${getDateDif(updated_at)} ago (${getFormatDate(updated_at)})` diff --git a/src/views/channels/pendingChannels/PendingChannels.tsx b/src/views/channels/pendingChannels/PendingChannels.tsx index 11dc5edf..2bb0c4e0 100644 --- a/src/views/channels/pendingChannels/PendingChannels.tsx +++ b/src/views/channels/pendingChannels/PendingChannels.tsx @@ -23,8 +23,8 @@ export const PendingChannels = () => { } return ( - - {data.getPendingChannels.map((channel: any, index: number) => ( + + {data.getPendingChannels.map((channel, index: number) => ( { }); React.useEffect(() => { - if (!loading && data?.sendMessage >= 0) { + if (!loading && data && data.sendMessage >= 0) { dispatch({ type: 'newChat', newChat: { diff --git a/src/views/chat/ChatInput.tsx b/src/views/chat/ChatInput.tsx index c379b083..0c8e1280 100644 --- a/src/views/chat/ChatInput.tsx +++ b/src/views/chat/ChatInput.tsx @@ -35,7 +35,7 @@ export const ChatInput = ({ ); React.useEffect(() => { - if (!loading && data?.sendMessage >= 0) { + if (!loading && data && data.sendMessage >= 0) { setMessage(''); dispatch({ type: 'newChat', diff --git a/src/views/chat/Contacts.tsx b/src/views/chat/Contacts.tsx index 9cf0d2fb..f1ef063b 100644 --- a/src/views/chat/Contacts.tsx +++ b/src/views/chat/Contacts.tsx @@ -52,7 +52,7 @@ export const ContactCard = ({ }, [contact, sender, alias, contactSender, getInfo, setUser, user]); React.useEffect(() => { - if (!loading && data?.getNode) { + if (!loading && data && data.getNode) { const { alias } = data.getNode; const name = alias && alias !== '' ? alias : contactSender.substring(0, 6); diff --git a/src/views/home/account/AccountInfo.tsx b/src/views/home/account/AccountInfo.tsx index b429b41a..f55d07e6 100644 --- a/src/views/home/account/AccountInfo.tsx +++ b/src/views/home/account/AccountInfo.tsx @@ -1,13 +1,13 @@ import React, { useState } from 'react'; import styled from 'styled-components'; -import { ArrowUp, Zap, Anchor, Pocket, ArrowDown, X } from 'react-feather'; +import { Zap, Anchor, Pocket } from 'react-feather'; +import { ColorButton } from 'src/components/buttons/colorButton/ColorButton'; import { Card, CardWithTitle, SubTitle, Separation, DarkSubTitle, - ColorButton, ResponsiveLine, } from '../../../components/generic/Styled'; import { LoadingCard } from '../../../components/loading/LoadingCard'; @@ -35,8 +35,14 @@ const Tile = styled.div` } `; -const ButtonRow = styled.div` +const AccountButtonWrapper = styled.div` display: flex; + flex-direction: column; + + @media (${mediaWidths.mobile}) { + flex-direction: row; + width: 100%; + } `; const sectionColor = '#FFD300'; @@ -118,14 +124,24 @@ export const AccountInfo = () => { ); const renderButtons = (send: string, receive: string) => ( - <> - setState(send)}> - + + setState(send)} + > + Send - setState(receive)}> - + setState(receive)} + > + Receive - + ); const renderLnAccount = () => ( @@ -137,14 +153,10 @@ export const AccountInfo = () => { {renderBalances(formatCCB, formatPCB)} - - {showLn && showChain && renderButtons('send_ln', 'receive_ln')} - {showLn && !showChain && ( - setState('none')}> - - - )} - + {showLn && showChain && renderButtons('send_ln', 'receive_ln')} + {showLn && !showChain && ( + setState('none')}>Cancel + )} ); @@ -158,14 +170,10 @@ export const AccountInfo = () => { {renderBalances(formatCB, formatPB)} - - {showLn && showChain && renderButtons('send_chain', 'receive_chain')} - {!showLn && showChain && ( - setState('none')}> - - - )} - + {showLn && showChain && renderButtons('send_chain', 'receive_chain')} + {!showLn && showChain && ( + setState('none')}>Cancel + )} ); diff --git a/src/views/home/connect/Connect.tsx b/src/views/home/connect/Connect.tsx index effa15e2..b9053ea5 100644 --- a/src/views/home/connect/Connect.tsx +++ b/src/views/home/connect/Connect.tsx @@ -5,6 +5,7 @@ import styled from 'styled-components'; import CopyToClipboard from 'react-copy-to-clipboard'; import { useAccountState } from 'src/context/AccountContext'; import { useGetCanConnectInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated'; +import { ColorButton } from 'src/components/buttons/colorButton/ColorButton'; import { getErrorContent } from '../../../utils/error'; import { LoadingCard } from '../../../components/loading/LoadingCard'; import { @@ -14,7 +15,6 @@ import { Card, SingleLine, DarkSubTitle, - ColorButton, } from '../../../components/generic/Styled'; import { mediaWidths } from '../../../styles/Themes'; @@ -52,6 +52,14 @@ const TextPadding = styled.span` margin-left: 5px; `; +const ButtonRow = styled.div` + display: flex; + + @media (${mediaWidths.mobile}) { + width: 100%; + } +`; + const sectionColor = '#fa541c'; export const ConnectCard = () => { @@ -84,13 +92,13 @@ export const ConnectCard = () => { Public Key {public_key} - + {onionAddress ? ( toast.success('Onion Address Copied')} > - + Onion @@ -101,12 +109,12 @@ export const ConnectCard = () => { text={normalAddress} onCopy={() => toast.success('Public Address Copied')} > - + ) : null} - + diff --git a/src/views/home/quickActions/QuickActions.tsx b/src/views/home/quickActions/QuickActions.tsx index cc82c5ba..f427fd14 100644 --- a/src/views/home/quickActions/QuickActions.tsx +++ b/src/views/home/quickActions/QuickActions.tsx @@ -6,7 +6,7 @@ import { SubTitle, Card, CardTitle, - ColorButton, + SmallButton, } from '../../../components/generic/Styled'; import { unSelectedNavButton } from '../../../styles/Themes'; import { AdminSwitch } from '../../../components/adminSwitch/AdminSwitch'; @@ -87,9 +87,9 @@ export const QuickActions = () => { {getTitle()} {openCard !== 'none' && ( - setOpenCard('none')} color={sectionColor}> + setOpenCard('none')}> - + )} {renderContent()} diff --git a/src/views/home/reports/flow/FlowReport.tsx b/src/views/home/reports/flow/FlowReport.tsx index 3aebe17e..9c561e2a 100644 --- a/src/views/home/reports/flow/FlowReport.tsx +++ b/src/views/home/reports/flow/FlowReport.tsx @@ -1,46 +1,28 @@ import React from 'react'; -import numeral from 'numeral'; -import { - VictoryBar, - VictoryChart, - VictoryAxis, - VictoryVoronoiContainer, - VictoryGroup, -} from 'victory'; +import { VictoryBar, VictoryChart, VictoryAxis, VictoryGroup } from 'victory'; import { useConfigState } from '../../../../context/ConfigContext'; import { chartAxisColor, chartGridColor, - // chartColors, flowBarColor, flowBarColor2, } from '../../../../styles/Themes'; import { getPrice } from '../../../../components/price/Price'; import { usePriceState } from '../../../../context/PriceContext'; -// import { WaterfallProps } from '.'; - -// const beforeMap = { -// amount: 'amountBefore', -// tokens: 'tokensBefore', -// }; interface Props { isTime: string; isType: string; - // isGraph: string; parsedData: {}[]; parsedData2: {}[]; - // waterfall: WaterfallProps[]; } export const FlowReport = ({ isTime, isType, - // isGraph, parsedData, parsedData2, -}: // waterfall, -Props) => { +}: Props) => { const { theme, currency, displayValues } = useConfigState(); const priceContext = usePriceState(); const format = getPrice(currency, displayValues, priceContext); @@ -55,13 +37,6 @@ Props) => { barWidth = 3; } - const getLabelString = (value: number) => { - if (isType === 'amount') { - return numeral(value).format('0,0'); - } - return format({ amount: value }); - }; - return ( { right: 50, bottom: 10, }} - containerComponent={ - `${getLabelString(datum[isType])}`} - /> - } > { grid: { stroke: chartGridColor[theme] }, axis: { stroke: 'transparent' }, }} - tickFormat={a => (isType === 'tokens' ? format({ amount: a }) : a)} + tickFormat={a => + isType === 'tokens' ? format({ amount: a, breakNumber: true }) : a + } /> { }, }} /> - {/* {isGraph === 'graph' && ( - { - console.log(data, index); - return data[index][isType] - - data[index][beforeMap[isType]] > - 0 - ? chartColors.green - : 'red'; - }, - width: barWidth, - }, - labels: { - fontSize: '12px', - }, - }} - /> - )} */} ); diff --git a/src/views/home/reports/forwardReport/Buttons.tsx b/src/views/home/reports/forwardReport/Buttons.tsx index 09923bc9..43d6fb20 100644 --- a/src/views/home/reports/forwardReport/Buttons.tsx +++ b/src/views/home/reports/forwardReport/Buttons.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { CardTitle, ColorButton } from '../../../../components/generic/Styled'; +import { CardTitle, SmallButton } from '../../../../components/generic/Styled'; interface ButtonProps { isTime: string; @@ -44,12 +44,12 @@ ButtonProps) => { index: number ) => { return ( - setFn(toggleButtons(array, index))} > {mapped[index]} - + ); }; diff --git a/src/views/home/reports/forwardReport/ForwardChannelReport.tsx b/src/views/home/reports/forwardReport/ForwardChannelReport.tsx index cbc11fe3..552a9916 100644 --- a/src/views/home/reports/forwardReport/ForwardChannelReport.tsx +++ b/src/views/home/reports/forwardReport/ForwardChannelReport.tsx @@ -1,13 +1,13 @@ import React, { useState } from 'react'; import { toast } from 'react-toastify'; import { GitCommit, ArrowDown, ArrowUp } from 'react-feather'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import { useAccountState } from 'src/context/AccountContext'; import { useGetForwardChannelsReportQuery } from 'src/graphql/queries/__generated__/getForwardChannelsReport.generated'; import { getErrorContent } from '../../../../utils/error'; import { DarkSubTitle, - ColorButton, + SmallButton, SingleLine, } from '../../../../components/generic/Styled'; import { LoadingCard } from '../../../../components/loading/LoadingCard'; @@ -28,9 +28,19 @@ const ButtonRow = styled.div` margin-bottom: 5px; `; -const TriButton = styled(ColorButton)` +type TriButtonProps = { + selected: boolean; +}; + +const TriButton = styled(SmallButton)` margin: 0; border-radius: 0; + + ${({ selected }) => + selected && + css` + color: white; + `} `; const LeftButton = styled(TriButton)` diff --git a/src/views/home/reports/liquidReport/LiquidReport.tsx b/src/views/home/reports/liquidReport/LiquidReport.tsx index 7de549fa..a8951a1d 100644 --- a/src/views/home/reports/liquidReport/LiquidReport.tsx +++ b/src/views/home/reports/liquidReport/LiquidReport.tsx @@ -91,7 +91,7 @@ export const LiquidReport = () => { grid: { stroke: chartGridColor[theme] }, axis: { stroke: 'transparent' }, }} - tickFormat={a => `${format({ amount: a })}`} + tickFormat={a => `${format({ amount: a, breakNumber: true })}`} /> { }); React.useEffect(() => { - if (!loading && data?.getNodeInfo && newAccount) { + if (!loading && data && data.getNodeInfo && newAccount) { dispatch({ type: 'changeAccount', changeId: newAccount }); dispatchStatus({ type: 'connected' }); push(appendBasePath('/home')); diff --git a/src/views/settings/Danger.tsx b/src/views/settings/Danger.tsx index b688ea73..8b57c289 100644 --- a/src/views/settings/Danger.tsx +++ b/src/views/settings/Danger.tsx @@ -12,10 +12,9 @@ import { CardWithTitle, SubTitle, SingleLine, - SimpleButton, Sub4Title, } from '../../components/generic/Styled'; -import { textColor, fontColors } from '../../styles/Themes'; +import { fontColors } from '../../styles/Themes'; import { ColorButton } from '../../components/buttons/colorButton/ColorButton'; import { MultiButton, @@ -40,14 +39,6 @@ export const SettingsLine = styled(SingleLine)` margin: 10px 0; `; -export const SettingsButton = styled(SimpleButton)` - padding: 10px; - - &:hover { - border: 1px solid ${textColor}; - } -`; - export const CheckboxText = styled.div` font-size: 13px; color: ${fontColors.grey7}; diff --git a/src/views/settings/index.tsx b/src/views/settings/index.tsx index 563f921e..b1df4bcb 100644 --- a/src/views/settings/index.tsx +++ b/src/views/settings/index.tsx @@ -1,7 +1,6 @@ import React from 'react'; import styled from 'styled-components'; -import { SingleLine, SimpleButton } from '../../components/generic/Styled'; -import { textColor } from '../../styles/Themes'; +import { SingleLine } from '../../components/generic/Styled'; import { InterfaceSettings } from './Interface'; import { AccountSettings } from './Account'; import { DangerView } from './Danger'; @@ -17,14 +16,6 @@ export const SettingsLine = styled(SingleLine)` margin: 8px 0; `; -export const SettingsButton = styled(SimpleButton)` - padding: 8px; - - &:hover { - border: 1px solid ${textColor}; - } -`; - const SettingsView = () => { return ( <>