Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/remove tx and remove localization #2561

Merged
merged 7 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 1 addition & 20 deletions src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { ReactComponent as LightIcon } from 'assets/svg/light.svg'
import { ReactComponent as RoadMapIcon } from 'assets/svg/roadmap.svg'
import { ButtonEmpty, ButtonPrimary } from 'components/Button'
import { AutoColumn } from 'components/Column'
import ArrowRight from 'components/Icons/ArrowRight'
import CampaignIcon from 'components/Icons/CampaignIcon'
import Faucet from 'components/Icons/Faucet'
import Icon from 'components/Icons/Icon'
Expand All @@ -28,7 +27,6 @@ import Toggle from 'components/Toggle'
import { TutorialIds } from 'components/Tutorial/TutorialSwap/constant'
import { ENV_LEVEL, TAG } from 'constants/env'
import { AGGREGATOR_ANALYTICS_URL, APP_PATHS, TERM_FILES_PATH } from 'constants/index'
import { getLocaleLabel } from 'constants/locales'
import { FAUCET_NETWORKS } from 'constants/networks'
import { ENV_TYPE } from 'constants/type'
import { useActiveWeb3React } from 'hooks'
Expand All @@ -39,7 +37,7 @@ import { PROFILE_MANAGE_ROUTES } from 'pages/NotificationCenter/const'
import { ApplicationModal } from 'state/application/actions'
import { useModalOpen, useToggleModal } from 'state/application/hooks'
import { useTutorialSwapGuide } from 'state/tutorial/hooks'
import { useHolidayMode, useUserLocale } from 'state/user/hooks'
import { useHolidayMode } from 'state/user/hooks'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { isChristmasTime } from 'utils'

Expand Down Expand Up @@ -207,7 +205,6 @@ export default function Menu() {
const [holidayMode, toggleHolidayMode] = useHolidayMode()
const [isSelectingLanguage, setIsSelectingLanguage] = useState(false)

const userLocale = useUserLocale()
const location = useLocation()

const { mixpanelHandler } = useMixpanel()
Expand Down Expand Up @@ -523,22 +520,6 @@ export default function Menu() {
<Trans>Notification Center</Trans>
<MailIcon size={17} color={theme.text} />
</NavLinkBetween>
<NavLinkBetween
onClick={() => {
setIsSelectingLanguage(true)
handlePreferenceClickMixpanel('Language')
}}
>
<Trans>Language</Trans>
<ButtonEmpty
padding="0"
width="fit-content"
style={{ color: theme.text, textDecoration: 'none', fontSize: '14px' }}
>
{getLocaleLabel(userLocale, true)}&nbsp;&nbsp;
<ArrowRight fill={theme.text} />
</ButtonEmpty>
</NavLinkBetween>

<Divider />

Expand Down
212 changes: 143 additions & 69 deletions src/components/WalletPopup/Transactions/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { Trans, t } from '@lingui/macro'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Info } from 'react-feather'
import { Info, X } from 'react-feather'
import { useMedia } from 'react-use'
import AutoSizer from 'react-virtualized-auto-sizer'
import { VariableSizeList } from 'react-window'
import { Flex, Text } from 'rebass'
import styled, { CSSProperties } from 'styled-components'

import { ButtonOutlined, ButtonPrimary } from 'components/Button'
import InfoHelper from 'components/InfoHelper'
import Modal from 'components/Modal'
import Row, { RowBetween } from 'components/Row'
import Tab from 'components/WalletPopup/Transactions/Tab'
import { NUMBERS } from 'components/WalletPopup/Transactions/helper'
import useCancellingOrders, { CancellingOrderInfo } from 'components/swapv2/LimitOrder/useCancellingOrders'
import { useActiveWeb3React } from 'hooks'
import { fetchListTokenByAddresses, findCacheToken, useIsLoadedTokenDefault } from 'hooks/Tokens'
import { isSupportKyberDao } from 'hooks/kyberdao'
import useTheme from 'hooks/useTheme'
import { useAppDispatch } from 'state/hooks'
import { clearAllPendingTransactions } from 'state/transactions/actions'
import { useSortRecentTransactions } from 'state/transactions/hooks'
import {
TRANSACTION_GROUP,
TransactionDetails,
TransactionExtraInfo1Token,
TransactionExtraInfo2Token,
} from 'state/transactions/type'
import { MEDIA_WIDTHS } from 'theme'

import TransactionItem from './TransactionItem'

Expand Down Expand Up @@ -50,6 +58,28 @@ const Wrapper = styled.div`
gap: 12px;
`

const ClearTxButton = styled.div`
cursor: pointer;
color: ${({ theme }) => theme.primary};
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
`

const ClearTxWrapper = styled.div`
padding: 20px;
border-radius: 20px;
background-color: ${({ theme }) => theme.tableHeader};
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
width: 100%;
color: ${({ theme }) => theme.subText};
`

function RowItem({
index,
style,
Expand Down Expand Up @@ -107,24 +137,23 @@ function RowItem({
// This is intentional, we don't need to persist in localStorage
let storedActiveTab = ''
function ListTransaction({ isMinimal }: { isMinimal: boolean }) {
const listTab = useMemo(
() => [
{ title: t`All`, value: '' },
{ title: t`Swaps`, value: TRANSACTION_GROUP.SWAP },
{ title: t`Liquidity`, value: TRANSACTION_GROUP.LIQUIDITY },
{ title: t`KyberDAO`, value: TRANSACTION_GROUP.KYBERDAO },
{ title: t`Others`, value: TRANSACTION_GROUP.OTHER },
],
[],
)

const transactions = useSortRecentTransactions(false)
const { chainId } = useActiveWeb3React()
const [activeTab, setActiveTab] = useState<TRANSACTION_GROUP | string>(storedActiveTab)
const theme = useTheme()
const cancellingOrderInfo = useCancellingOrders()
const dispatch = useAppDispatch()
const { chainId } = useActiveWeb3React()

const [activeTab, setActiveTab] = useState<TRANSACTION_GROUP | string>(storedActiveTab)
const [openClearTxModal, setOpenClearTxModal] = useState(false)
const upToExtraSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToExtraSmall}px)`)

const listTokenAddress = useRef<string[]>([])
const rowHeights = useRef<{ [key: string]: number }>({})
const listRef = useRef<any>(null)

const total = listTokenAddress.current
const isLoadedTokenDefault = useIsLoadedTokenDefault()

const pushAddress = (address: string) => {
if (address && !listTokenAddress.current.includes(address)) listTokenAddress.current.push(address)
}
Expand All @@ -147,22 +176,34 @@ function ListTransaction({ isMinimal }: { isMinimal: boolean }) {
return result
}, [transactions, activeTab])

const total = listTokenAddress.current
const isLoadedTokenDefault = useIsLoadedTokenDefault()
useEffect(() => {
if (!isLoadedTokenDefault) return
const list: string[] = listTokenAddress.current.filter(address => !findCacheToken(address))
if (list.length) fetchListTokenByAddresses(list, chainId).catch(console.error)
}, [total, isLoadedTokenDefault, chainId])
const pendingTransactions = formatTransactions.filter(tx => !tx.receipt)

const listTab = useMemo(
() => [
{ title: t`All`, value: '' },
{ title: t`Swaps`, value: TRANSACTION_GROUP.SWAP },
{ title: t`Liquidity`, value: TRANSACTION_GROUP.LIQUIDITY },
{ title: t`KyberDAO`, value: TRANSACTION_GROUP.KYBERDAO },
{ title: t`Others`, value: TRANSACTION_GROUP.OTHER },
],
[],
)

const filterTab = useMemo(() => {
return listTab.filter(tab => {
if (tab.value === TRANSACTION_GROUP.KYBERDAO) {
return isSupportKyberDao(chainId)
}
return true
})
}, [chainId, listTab])

const onRefChange = useCallback((node: HTMLDivElement) => {
if (!node?.classList.contains('scrollbar')) {
node?.classList.add('scrollbar')
}
}, [])

const rowHeights = useRef<{ [key: string]: number }>({})
const listRef = useRef<any>(null)
const setRowHeight = useCallback((index: number, size: number) => {
listRef.current?.resetAfterIndex(0)
rowHeights.current = { ...rowHeights.current, [index]: size }
Expand All @@ -172,59 +213,92 @@ function ListTransaction({ isMinimal }: { isMinimal: boolean }) {
return rowHeights.current[index] || 100
}

const toggleClearTxModal = () => setOpenClearTxModal(prev => !prev)
const onClearAllPendingTransactions = () => {
dispatch(clearAllPendingTransactions({ chainId }))
toggleClearTxModal()
}

useEffect(() => {
if (!isLoadedTokenDefault) return
const list: string[] = listTokenAddress.current.filter(address => !findCacheToken(address))
if (list.length) fetchListTokenByAddresses(list, chainId).catch(console.error)
}, [total, isLoadedTokenDefault, chainId])

useEffect(() => {
storedActiveTab = activeTab
}, [activeTab])

const filterTab = useMemo(() => {
return listTab.filter(tab => {
if (tab.value === TRANSACTION_GROUP.KYBERDAO) {
return isSupportKyberDao(chainId)
}
return true
})
}, [chainId, listTab])

return (
<Wrapper>
<Tab<TRANSACTION_GROUP | string> activeTab={activeTab} setActiveTab={setActiveTab} tabs={filterTab} />
<ContentWrapper>
{formatTransactions.length === 0 ? (
<Flex flexDirection="column" alignItems="center" color={theme.subText} sx={{ gap: 10, marginTop: '20px' }}>
<Info size={32} />
<Text fontSize={'14px'}>
<Trans>You have no Transaction History.</Trans>
<>
<Modal isOpen={openClearTxModal} onDismiss={toggleClearTxModal}>
<ClearTxWrapper>
<RowBetween align="start">
<Text fontSize={20} fontWeight={500} color={theme.text}>
{t`Clear All Pending Transactions`}
</Text>
<X color={theme.text} style={{ cursor: 'pointer' }} onClick={toggleClearTxModal} />
</RowBetween>
<Row gap="12px">
<Text fontSize={14} color={theme.text} lineHeight="16px">
{t`Are you sure you want to clear all pending transactions? This will remove them from your list but will not affect their status on-chain.`}
</Text>
</Flex>
) : (
<AutoSizer>
{({ height, width }) => (
<VariableSizeList
height={height}
width={width}
itemSize={getRowHeight}
ref={listRef}
outerRef={onRefChange}
itemCount={formatTransactions.length}
itemData={formatTransactions}
>
{({ data, index, style }) => (
<RowItem
isMinimal={isMinimal}
style={style}
transaction={data[index]}
index={index}
key={data[index].hash}
setRowHeight={setRowHeight}
cancellingOrderInfo={cancellingOrderInfo}
/>
)}
</VariableSizeList>
)}
</AutoSizer>
</Row>
<Row gap="16px" flexDirection={upToExtraSmall ? 'column' : 'row'}>
<ButtonOutlined onClick={toggleClearTxModal}>{t`Cancel`}</ButtonOutlined>
<ButtonPrimary onClick={onClearAllPendingTransactions}>{t`Clear All`}</ButtonPrimary>
</Row>
</ClearTxWrapper>
</Modal>
<Wrapper>
<Tab<TRANSACTION_GROUP | string> activeTab={activeTab} setActiveTab={setActiveTab} tabs={filterTab} />
<ContentWrapper>
{formatTransactions.length === 0 ? (
<Flex flexDirection="column" alignItems="center" color={theme.subText} sx={{ gap: 10, marginTop: '20px' }}>
<Info size={32} />
<Text fontSize={'14px'}>
<Trans>You have no Transaction History.</Trans>
</Text>
</Flex>
) : (
<AutoSizer>
{({ height, width }) => (
<VariableSizeList
height={height}
width={width}
itemSize={getRowHeight}
ref={listRef}
outerRef={onRefChange}
itemCount={formatTransactions.length}
itemData={formatTransactions}
>
{({ data, index, style }) => (
<RowItem
isMinimal={isMinimal}
style={style}
transaction={data[index]}
index={index}
key={data[index].hash}
setRowHeight={setRowHeight}
cancellingOrderInfo={cancellingOrderInfo}
/>
)}
</VariableSizeList>
)}
</AutoSizer>
)}
</ContentWrapper>
{pendingTransactions.length !== 0 && (
<ClearTxButton>
<Text fontSize={14} onClick={toggleClearTxModal}>{t`Clear Pending Transactions`}</Text>
<InfoHelper
color={theme.primary}
text={t`Manually clear this transaction from the pending list. This will not affect its on-chain status.`}
/>
</ClearTxButton>
)}
</ContentWrapper>
</Wrapper>
</Wrapper>
</>
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/WalletPopup/WalletView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ const Wrapper = styled.div.attrs<WrapperProps>(props => ({
'data-blur': props.$blur,
}))<WrapperProps>`
width: 100%;
height: 100%;
/* height: 100%; */
height: unset;
padding-top: 0px;

display: flex;
Expand All @@ -77,7 +78,6 @@ const Wrapper = styled.div.attrs<WrapperProps>(props => ({

${({ theme }) => theme.mediaWidth.upToMedium`
padding-bottom: 0;
height: unset;
`};
`

Expand Down
4 changes: 4 additions & 0 deletions src/state/transactions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export const addTransaction = createAction<TransactionPayload>('transactions/add

export const clearAllTransactions = createAction<{ chainId: ChainId }>('transactions/clearAllTransactions')

export const clearAllPendingTransactions = createAction<{ chainId: ChainId }>(
'transactions/clearAllPendingTransactions',
)

export const finalizeTransaction = createAction<{
chainId: ChainId
hash: string
Expand Down
9 changes: 9 additions & 0 deletions src/state/transactions/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getTransactionGroupByType } from 'utils/transaction'
import {
addTransaction,
checkedTransaction,
clearAllPendingTransactions,
clearAllTransactions,
finalizeTransaction,
modifyTransaction,
Expand Down Expand Up @@ -65,6 +66,14 @@ export default createReducer(initialState, builder =>
if (!transactions[chainId]) return
transactions[chainId] = {}
})
.addCase(clearAllPendingTransactions, (transactions, { payload: { chainId } }) => {
if (!transactions[chainId]) return
const pendingTxHash: string[] = []
Object.keys(transactions[chainId] || {}).forEach(txHash => {
if (!transactions[chainId]?.[txHash]?.find(tx => tx.receipt)) pendingTxHash.push(txHash)
})
pendingTxHash.forEach(txHash => delete transactions[chainId]?.[txHash])
})
.addCase(checkedTransaction, (transactions, { payload: { chainId, hash, blockNumber } }) => {
const tx = findTx(transactions[chainId], hash)
if (!tx) return
Expand Down
Loading
Loading