diff --git a/app/basicComponents/AutocompleteDropdown.tsx b/app/basicComponents/AutocompleteDropdown.tsx index 6caac3cec..a520af136 100644 --- a/app/basicComponents/AutocompleteDropdown.tsx +++ b/app/basicComponents/AutocompleteDropdown.tsx @@ -1,4 +1,5 @@ import React, { useState, useRef, useEffect } from 'react'; +// import styled from 'styled-components'; import styled from 'styled-components'; import { getAbbreviatedAddress } from '../infra/utils'; import { chevronBottomBlack, chevronBottomWhite } from '../assets/images'; @@ -68,7 +69,7 @@ const InputField = styled.div<{ }) => ` color: ${isDarkSkin ? light.states.normal.color : dark.states.normal.color}; - + &:hover { color: ${ isDarkSkin ? light.states.normal.color : dark.states.normal.color @@ -157,7 +158,7 @@ const ActualInput = styled.input<{ }) => ` color: ${isDarkSkin ? light.states.normal.color : dark.states.normal.color}; - + &:hover { color: ${ isDarkSkin ? light.states.normal.color : dark.states.normal.color @@ -214,7 +215,7 @@ const AutocompleteList = styled.div<{ isDarkSkin ? light.states.hover.backgroundColor : dark.states.hover.backgroundColor - }; + }; color: ${ isDarkSkin ? light.states.hover.color : dark.states.hover.color }; @@ -293,11 +294,13 @@ type Props = { export type AutocompleteDropdownProps = Props; +type TimeoutOrNull = NodeJS.Timeout | null; + const AutocompleteDropdown = (props: Props) => { const { value, autofocus, autocomplete = true } = props; - let inputBlurTimer: any; + let inputBlurTimer: TimeoutOrNull; const [isOpen, setIsOpen] = useState(false); - const [list, setList] = useState>([]); + const [list, setList] = useState([]); const [isFocus, setIsFocus] = useState(-1); const [editField, setEditField] = useState(value || ''); const [move, setMove] = useState(null); @@ -317,7 +320,7 @@ const AutocompleteDropdown = (props: Props) => { // @ts-ignore const { value } = inputField.current || {}; - let list: any = []; + let list: typeof data = []; // typeof data = [] if (value && value.trim() && autocomplete) { list = data.filter( @@ -363,7 +366,7 @@ const AutocompleteDropdown = (props: Props) => { setIsOpen(!isOpen); }; - const pressEnterKey = (e: KeyboardEvent) => { + const pressEnterKey = (e: React.KeyboardEvent) => { const { onChange, getItemValue, onEnter } = props; const data = list[isFocus]; @@ -374,11 +377,13 @@ const AutocompleteDropdown = (props: Props) => { setList([]); setIsOpen(false); + const genericEvent: React.KeyboardEvent = e as React.KeyboardEvent; + // @ts-ignore - onEnter(e.target.value); + onEnter(genericEvent); }; - const handleInputKeyUp = (e: any) => { + const handleInputKeyUp = (e: React.KeyboardEvent) => { const { keyCode } = e; e.stopPropagation(); @@ -437,7 +442,12 @@ const AutocompleteDropdown = (props: Props) => { } }; - const renderItem = (item: any) => ( + interface ItemType { + nickname: string; + address: string; + } + + const renderItem = (item: ItemType) => (
{item.nickname} - {getAbbreviatedAddress(item.address)}
@@ -461,7 +471,7 @@ const AutocompleteDropdown = (props: Props) => { return menus; }; - const handleInputChange = (e: any) => { + const handleInputChange = (e: React.ChangeEvent) => { const { target } = e; const { value } = target; const { onChange } = props; diff --git a/app/basicComponents/CopyButton.tsx b/app/basicComponents/CopyButton.tsx index d87eae23e..d44b0359e 100644 --- a/app/basicComponents/CopyButton.tsx +++ b/app/basicComponents/CopyButton.tsx @@ -31,6 +31,8 @@ const CopyIcon = styled.img.attrs<{ secondary?: boolean }>( } `; +type TypeOrNumber = NodeJS.Timeout | number; + const CopyButton = ({ secondary, children, @@ -38,7 +40,7 @@ const CopyButton = ({ value, onClick, }: Props) => { - let t: NodeJS.Timeout | number = 0; + let t: TypeOrNumber = 0; const handleCopy = async (e: React.MouseEvent) => { e.stopPropagation(); diff --git a/app/basicComponents/DropDown.tsx b/app/basicComponents/DropDown.tsx index 674bb655c..1f6f9bca6 100644 --- a/app/basicComponents/DropDown.tsx +++ b/app/basicComponents/DropDown.tsx @@ -109,7 +109,7 @@ const HeaderWrapper = styled.div<{ } color: ${isDarkMode ? dark.states.normal.color : light.states.normal.color}; - + &:hover { color: ${ isDarkMode ? dark.states.hover.color : light.states.hover.color @@ -157,7 +157,7 @@ const DropdownRow = styled.div<{ isDarkMode ? dark.states.hover.backgroundColor : light.states.hover.backgroundColor - }; + }; color: ${ isDarkMode ? dark.states.hover.color : light.states.hover.color }; @@ -241,17 +241,17 @@ const ItemsWrapper = styled.div<{ }, }, }) => ` - + > div:first-child { border-top: 1px solid ${isDarkMode ? dark.borderColor : light.borderColor}; } - + > div:last-child { border-bottom: none; - } - + } + > div { - + border-bottom: 1px solid ${ isDarkMode ? dark.borderColor : light.borderColor }; @@ -352,12 +352,14 @@ const DropDownItem: React.FC = ({ ); +type NumberOrString = number | string; + type Props = { onClick: ({ index }: { index: number }) => void | Promise; onClose?: () => void; data: Partial[]; selectedItemIndex: number; - rowHeight?: number | string; + rowHeight?: NumberOrString; isOpened?: boolean; isDisabled?: boolean; bold?: boolean; diff --git a/app/basicComponents/Input.tsx b/app/basicComponents/Input.tsx index 67712590b..ba5f71a22 100644 --- a/app/basicComponents/Input.tsx +++ b/app/basicComponents/Input.tsx @@ -70,8 +70,8 @@ const ActualInput = styled.input<{ }) => !isDisabled && `&:hover, &:focus, &:active { - background-color: ${states.focus.backgroundColor}; - color: ${states.focus.color}; + background-color: ${states.focus.backgroundColor}; + color: ${states.focus.color}; } `} font-size: 14px; line-height: 16px; @@ -155,22 +155,22 @@ const Input = ({ }; }); - const handleEnterPress = (event: any) => { + const handleEnterPress = (event: React.KeyboardEvent) => { if (event.key === 'Enter' && !!onEnterPress) { onEnterPress(); onPaste(); } }; - const handleOnBlur = ({ target }: { target: any }) => { + const handleOnBlur = ({ target }: { target: HTMLInputElement }) => { setIsFocused(false); const { value } = target; onBlur?.({ value }); }; - const handleChange = ({ target }: { target: any }) => { - const { value } = target; + const handleChange = (event: React.ChangeEvent) => { + const { value } = event.currentTarget; onChange?.({ value }); if (onChangeDebounced) { diff --git a/app/components/common/Feedback.tsx b/app/components/common/Feedback.tsx index e8f42ffa2..913b97f49 100644 --- a/app/components/common/Feedback.tsx +++ b/app/components/common/Feedback.tsx @@ -277,7 +277,7 @@ const FeedbackButton = () => { const formData = { event_id: captureReactMessage(` - User has submitted an issue and asked to check it. Discord handle: ${userData.name} and email: ${userData.email}, + User has submitted an issue and asked to check it. Discord handle: ${userData.name} and email: ${userData.email}, `), ...userData, }; diff --git a/app/components/common/Version.tsx b/app/components/common/Version.tsx index ec4face74..d3afd861b 100644 --- a/app/components/common/Version.tsx +++ b/app/components/common/Version.tsx @@ -253,10 +253,10 @@ const CheckForUpdates = () => { const network = useSelector(getNetworkInfo); enum CheckState { Idle = 0, - Checking, - NoUpdates, - HasUpdate, - ManualUpdate, + Checking = 1, + NoUpdates = 2, + HasUpdate = 3, + ManualUpdate = 4, } const [curState, setCurState] = useState(CheckState.Idle); const [manualUpdateSmappVersion, setManualUpdateSmappVersion] = useState(''); diff --git a/app/components/settings/SignMessage.tsx b/app/components/settings/SignMessage.tsx index 3f6a69215..70dcd1588 100644 --- a/app/components/settings/SignMessage.tsx +++ b/app/components/settings/SignMessage.tsx @@ -49,7 +49,7 @@ type Props = { }; const SignMessage = ({ index, close }: Props) => { - let copiedTimeout: any = null; + let copiedTimeout: NodeJS.Timeout; const [message, setMessage] = useState(''); const [isCopied, setIsCopied] = useState(false); const [lastResult, setLastResult] = useState(''); diff --git a/app/components/transactions/TransactionsMeta.tsx b/app/components/transactions/TransactionsMeta.tsx index 37b9a0838..f1e501b67 100644 --- a/app/components/transactions/TransactionsMeta.tsx +++ b/app/components/transactions/TransactionsMeta.tsx @@ -1,4 +1,10 @@ +import { RewardView, TxView } from 'app/redux/wallet/selectors'; +import { TIME_SPANS } from 'app/screens/transactions/Transactions'; import React from 'react'; +import { DAY } from 'shared/constants'; +import { SingleSigMethods } from 'shared/templateConsts'; +import { Bech32Address, TxState } from 'shared/types'; +import { isReward, isTx } from 'shared/types/guards'; import styled from 'styled-components'; import { formatSmidge } from '../../infra/utils'; import { smColors } from '../../vars'; @@ -69,25 +75,84 @@ const Progress = styled.div<{ total: number; coins: number }>` type Props = { filterName: string; - mined: number; - sent: number; - received: number; - totalMined: number; - totalSent: number; - totalReceived: number; nonce: number; + transactions: (TxView | RewardView)[]; + address: Bech32Address; + selectedTimeSpan: number; }; const TransactionsMeta = ({ - mined, - sent, - received, - totalMined, - totalSent, - totalReceived, filterName, nonce, + transactions, + address, + selectedTimeSpan, }: Props) => { + const getNumOfCoinsFromTransactions = ( + address: Bech32Address, + transactions: (TxView | RewardView)[] + ) => { + const coins = { mined: 0, sent: 0, received: 0 }; + return transactions.reduce((coins, txOrReward: TxView | RewardView) => { + if (isTx(txOrReward)) { + const { status, principal: sender, method, payload } = txOrReward; + const amount = + method === SingleSigMethods.Spend + ? parseInt(payload?.Arguments?.Amount || 0, 10) + : 0; + if ( + status !== TxState.REJECTED && + status !== TxState.INSUFFICIENT_FUNDS && + status !== TxState.CONFLICTING && + status !== TxState.FAILURE + ) { + return sender === address + ? { ...coins, sent: coins.sent + amount } + : { ...coins, received: coins.received + amount }; + } + } else if (isReward(txOrReward)) { + const { amount } = txOrReward; + return { ...coins, mined: coins.mined + amount }; + } + return coins; + }, coins); + }; + + const filterLastDays = (txs: (TxView | RewardView)[], days = 1) => { + const startDate = Date.now() - days * DAY; + return txs.filter( + (tx) => (tx.timestamp && tx.timestamp >= startDate) || !tx.timestamp + ); + }; + const filteredTransactions = filterLastDays( + transactions, + TIME_SPANS[selectedTimeSpan].days + ); + const getCoinStatistics = (filteredTransactions: (TxView | RewardView)[]) => { + const coins = getNumOfCoinsFromTransactions(address, filteredTransactions); + const totalCoins = getNumOfCoinsFromTransactions( + address, + transactions || [] + ); + return { + ...coins, + totalMined: totalCoins.mined, + totalSent: totalCoins.sent, + totalReceived: totalCoins.received, + }; + }; + + const coinStats = getCoinStatistics(filteredTransactions); + + const { + mined, + sent, + received, + totalMined, + totalSent, + totalReceived, + } = coinStats; + const totalFilteredCoins = mined + sent + received; const coinsMeta = [ { title: 'SMESHED', coins: mined }, diff --git a/app/screens/auth/SwitchNetwork.tsx b/app/screens/auth/SwitchNetwork.tsx index 14dd50b07..aa6fa48a6 100644 --- a/app/screens/auth/SwitchNetwork.tsx +++ b/app/screens/auth/SwitchNetwork.tsx @@ -108,7 +108,9 @@ const SwitchNetwork = ({ history, location }: AuthRouterParams) => { return [{ label: 'NO NETWORKS AVAILABLE', isDisabled: true }]; }; - const goNext = (genesisID: string | undefined) => { + type GoNextType = string | undefined; + + const goNext = (genesisID: GoNextType) => { if (creatingWallet) { if (isWalletOnly && genesisID?.length) { return history.push(AuthPath.ConnectToAPI, { diff --git a/app/screens/backup/FileBackup.tsx b/app/screens/backup/FileBackup.tsx index 8f09daced..96c8b9459 100644 --- a/app/screens/backup/FileBackup.tsx +++ b/app/screens/backup/FileBackup.tsx @@ -27,14 +27,15 @@ const BottomRow = styled(MiddleSectionRow)` justify-content: space-between; `; -const FileBackup = ({ - history, - location, -}: RouteComponentProps< - Record, - StaticContext, - { filePath: string } ->) => { +interface FileBackupProps { + filePath: string; +} + +const FileBackup: React.FC< + RouteComponentProps, StaticContext, FileBackupProps> +> = (props) => { + const { history, location } = props; + const showBackupFile = () => { eventsService.showFileInFolder({ filePath: location.state.filePath }); }; diff --git a/app/screens/contacts/Contacts.tsx b/app/screens/contacts/Contacts.tsx index 38c60b2c3..96d9a8065 100644 --- a/app/screens/contacts/Contacts.tsx +++ b/app/screens/contacts/Contacts.tsx @@ -305,7 +305,7 @@ const Contacts = ({ history }: RouteComponentProps) => { return 0; }; - const openAddNewContactModal = (e: any, contact: Contact) => { + const openAddNewContactModal = (e: React.MouseEvent, contact: Contact) => { e.stopPropagation(); setAddressToAdd(contact.address); setShowCreateNewContactModal(true); diff --git a/app/screens/main/Main.tsx b/app/screens/main/Main.tsx index be65dddbb..5172cd844 100644 --- a/app/screens/main/Main.tsx +++ b/app/screens/main/Main.tsx @@ -202,8 +202,10 @@ const Main = () => { const handleOpenLink = (url: string) => window.open(url); + type LabelStringOrNode = string | ReactNode; + const renderNavBarLink = ( - label: string | ReactNode, + label: LabelStringOrNode, tooltip: string, route: string ) => { diff --git a/app/screens/node/Node.tsx b/app/screens/node/Node.tsx index fd4ff230a..088884eb6 100644 --- a/app/screens/node/Node.tsx +++ b/app/screens/node/Node.tsx @@ -251,13 +251,15 @@ const ERR_MESSAGE_ERR_STATE = const ERR_MESSAGE_NODE_ERROR = 'The Node is not syncing. Please check the Network tab'; +type NodeOrNull = NodeStatus | null; + const SmesherStatus = ({ smesherId, status, networkName, }: { smesherId: HexString; - status: NodeStatus | null; + status: NodeOrNull; networkName: string; }) => ( diff --git a/app/screens/node/NodeSetup.tsx b/app/screens/node/NodeSetup.tsx index 08f2c0762..1adb54ece 100644 --- a/app/screens/node/NodeSetup.tsx +++ b/app/screens/node/NodeSetup.tsx @@ -38,12 +38,12 @@ const Bold = styled.div` enum SetupMode { Modify = 0, - Directory, - Profiler, - Size, - Processor, - RewardsAddress, - Summary, + Directory = 1, + Profiler = 2, + Size = 3, + Processor = 4, + RewardsAddress = 5, + Summary = 6, } const headers = { diff --git a/app/screens/transactions/Transactions.tsx b/app/screens/transactions/Transactions.tsx index ceffe6f6e..9f6c390f2 100644 --- a/app/screens/transactions/Transactions.tsx +++ b/app/screens/transactions/Transactions.tsx @@ -1,38 +1,37 @@ import React, { useState } from 'react'; -import styled from 'styled-components'; +import useVirtual from 'react-cool-virtual'; import { useSelector } from 'react-redux'; import { RouteComponentProps } from 'react-router-dom'; -import useVirtual from 'react-cool-virtual'; -import { MainPath } from '../../routerPaths'; +import styled from 'styled-components'; +import { ExternalLinks } from '../../../shared/constants'; +import { Bech32Address } from '../../../shared/types'; +import { isReward } from '../../../shared/types/guards'; +import { + CorneredWrapper, + DropDown, + Link, + WrapperWith2SideBars, +} from '../../basicComponents'; import { BackButton } from '../../components/common'; +import { CreateNewContact } from '../../components/contacts'; import { - TxRow, RewardRow, TransactionsMeta, + TxRow, } from '../../components/transactions'; -import { CreateNewContact } from '../../components/contacts'; -import { - Link, - WrapperWith2SideBars, - CorneredWrapper, - DropDown, -} from '../../basicComponents'; -import { RootState } from '../../types'; +import { setRef } from '../../infra/utils'; import { + RewardView, + TxView, getContacts, + getReceivedTransactions, getRewards, - getTransactions, getSentTransactions, - getReceivedTransactions, + getTransactions, getTxAndRewards, - RewardView, - TxView, } from '../../redux/wallet/selectors'; -import { TxState, Bech32Address } from '../../../shared/types'; -import { isReward, isTx } from '../../../shared/types/guards'; -import { DAY, ExternalLinks } from '../../../shared/constants'; -import { SingleSigMethods } from '../../../shared/templateConsts'; -import { setRef } from '../../infra/utils'; +import { MainPath } from '../../routerPaths'; +import { RootState } from '../../types'; const Wrapper = styled.div` display: flex; @@ -73,37 +72,7 @@ const FilterDropDownWrapper = styled(DropDownWrapper)` right: 30px; `; -const getNumOfCoinsFromTransactions = ( - address: Bech32Address, - transactions: (TxView | RewardView)[] -) => { - const coins = { mined: 0, sent: 0, received: 0 }; - return transactions.reduce((coins, txOrReward: TxView | RewardView) => { - if (isTx(txOrReward)) { - const { status, principal: sender, method, payload } = txOrReward; - const amount = - method === SingleSigMethods.Spend - ? parseInt(payload?.Arguments?.Amount || 0, 10) - : 0; - if ( - status !== TxState.REJECTED && - status !== TxState.INSUFFICIENT_FUNDS && - status !== TxState.CONFLICTING && - status !== TxState.FAILURE - ) { - return sender === address - ? { ...coins, sent: coins.sent + amount } - : { ...coins, received: coins.received + amount }; - } - } else if (isReward(txOrReward)) { - const { amount } = txOrReward; - return { ...coins, mined: coins.mined + amount }; - } - return coins; - }, coins); -}; - -const TIME_SPANS = [ +export const TIME_SPANS = [ { label: 'daily', days: 1 }, { label: 'monthly', days: 30 }, { label: 'yearly', days: 365 }, @@ -128,18 +97,17 @@ const TX_FILTERS = [ const TransactionList = ({ address, transactions, - contacts, setAddressToAdd, }: { address: Bech32Address; transactions: (TxView | RewardView)[]; - contacts: Record; setAddressToAdd: (a: Bech32Address) => void; }) => { const { outerRef, innerRef, items } = useVirtual({ itemCount: transactions.length, itemSize: 60, }); + const contacts = useSelector(getContacts); return ( @@ -211,22 +179,6 @@ const Transactions = ({ history }: RouteComponentProps) => { } }); - const contacts = useSelector(getContacts); - - const getCoinStatistics = (filteredTransactions: (TxView | RewardView)[]) => { - const coins = getNumOfCoinsFromTransactions(address, filteredTransactions); - const totalCoins = getNumOfCoinsFromTransactions( - address, - transactions || [] - ); - return { - ...coins, - totalMined: totalCoins.mined, - totalSent: totalCoins.sent, - totalReceived: totalCoins.received, - }; - }; - const handleCompleteAction = () => { setAddressToAdd(''); }; @@ -235,41 +187,15 @@ const Transactions = ({ history }: RouteComponentProps) => { setSelectedTimeSpan(index); }; - const filterLastDays = (txs: (TxView | RewardView)[], days = 1) => { - const startDate = Date.now() - days * DAY; - return txs.filter( - (tx) => (tx.timestamp && tx.timestamp >= startDate) || !tx.timestamp - ); - }; - const cancelCreatingNewContact = () => { setAddressToAdd(''); }; const navigateToGuide = () => window.open(ExternalLinks.WalletGuide); - const filteredTransactions = filterLastDays( - transactions, - TIME_SPANS[selectedTimeSpan].days - ); - const coinStats = getCoinStatistics(filteredTransactions); - - const { - mined, - sent, - received, - totalMined, - totalSent, - totalReceived, - } = coinStats; - return ( - history.replace(MainPath.Wallet)} - width={7} - height={10} - /> + history.replace(MainPath.Wallet)} /> { @@ -313,14 +238,11 @@ const Transactions = ({ history }: RouteComponentProps) => { /> )} diff --git a/app/screens/wallet/SendCoins.tsx b/app/screens/wallet/SendCoins.tsx index 00c2ed5da..a21a64fa5 100644 --- a/app/screens/wallet/SendCoins.tsx +++ b/app/screens/wallet/SendCoins.tsx @@ -81,7 +81,7 @@ const SendCoins = ({ history, location }: Props) => { })(); }, [currentAccountIndex, address, amount, currentAccount]); - const updateTxNote = ({ value }: { value: any }) => { + const updateTxNote = ({ value }: { value: string }) => { setNote(value); };