From e4e8a455f70b016bd363774323e6704e034ecfa0 Mon Sep 17 00:00:00 2001 From: Septs Date: Mon, 16 May 2022 22:49:43 +0800 Subject: [PATCH 1/6] chore: no-array-reduce --- packages/.eslintrc.json | 1 + packages/gun-utils/src/utils.ts | 1 + .../services/identity/profile/update.ts | 6 +- packages/mask/src/UIRoot.tsx | 1 + .../components/shared/ApplicationBoard.tsx | 44 +++---- .../shared/ApplicationSettingPluginList.tsx | 17 +-- .../shared/ApplicationSettingPluginSwitch.tsx | 20 ++- .../FindTruman/SNSAdaptor/OptionsCard.tsx | 6 +- .../FindTruman/SNSAdaptor/ResultCard.tsx | 7 +- .../plugins/ITO/SNSAdaptor/NftAirdropCard.tsx | 7 +- .../mask/src/plugins/ITO/Worker/apis/chain.ts | 115 +++++++++--------- .../hooks/useAvailabilityNftRedPacket.ts | 5 +- .../plugins/RedPacket/Worker/apis/chain.ts | 85 +++++++------ .../Savings/SNSAdaptor/SavingsDialog.tsx | 18 +-- .../Snapshot/SNSAdaptor/ResultCard.tsx | 14 ++- .../Snapshot/SNSAdaptor/hooks/useResults.ts | 1 + .../plugins/Tips/hooks/useTipsWalletsList.ts | 7 +- .../src/plugins/Trader/apis/balancer/index.ts | 1 + .../src/plugins/Trader/apis/trending/index.ts | 14 ++- .../src/plugins/Trader/apis/uniswap/index.ts | 10 +- .../trader/uniswap/useAllCommonPairs.ts | 28 ++--- .../trader/uniswap/useTradeBreakdown.ts | 2 + .../Trader/trader/uniswap/useV3BestTrade.ts | 2 + .../Trader/trader/uniswap/useV3SwapPools.ts | 12 +- .../src/hooks/useAllPluginsWeb3State.ts | 15 +-- .../plugin-infra/src/manager/sns-adaptor.ts | 15 +-- packages/shared-base/src/color/avatar.ts | 1 + packages/theme/src/Theme/Provider.tsx | 1 + .../typed-message/base/transformer/Flatten.ts | 1 + .../base/transformer/composed.ts | 1 + packages/web3-providers/src/debank/format.ts | 58 ++++----- packages/web3-shared/evm/utils/token.ts | 26 ++-- 32 files changed, 250 insertions(+), 292 deletions(-) diff --git a/packages/.eslintrc.json b/packages/.eslintrc.json index 329c14763de5..6f8b87732d82 100644 --- a/packages/.eslintrc.json +++ b/packages/.eslintrc.json @@ -59,6 +59,7 @@ "unicorn/no-new-buffer": "error", "unicorn/no-thenable": "error", "unicorn/no-useless-promise-resolve-reject": "error", + "unicorn/no-array-reduce": "error", "unicorn/prefer-add-event-listener": "error", "unicorn/prefer-date-now": "error", "unicorn/prefer-dom-node-dataset": "error", diff --git a/packages/gun-utils/src/utils.ts b/packages/gun-utils/src/utils.ts index ca0357ddc92d..4ca9392d60c8 100644 --- a/packages/gun-utils/src/utils.ts +++ b/packages/gun-utils/src/utils.ts @@ -2,6 +2,7 @@ import { EventIterator } from 'event-iterator' import { getGunInstance, OnCloseEvent } from './instance' function getGunNodeFromPath(path: string[]) { + // eslint-disable-next-line unicorn/no-array-reduce const resultNode = path.reduce((gun, path) => gun.get(path as never), getGunInstance()) return resultNode } diff --git a/packages/mask/background/services/identity/profile/update.ts b/packages/mask/background/services/identity/profile/update.ts index c82f7a8f5792..2a6189457780 100644 --- a/packages/mask/background/services/identity/profile/update.ts +++ b/packages/mask/background/services/identity/profile/update.ts @@ -58,10 +58,10 @@ export async function resolveUnknownLegacyIdentity(identifier: ProfileIdentifier const unknown = ProfileIdentifier.of(identifier.network, '$unknown').unwrap() const self = ProfileIdentifier.of(identifier.network, '$self').unwrap() - const r = await queryProfilesDB({ identifiers: [unknown, self] }) - if (!r.length) return + const records = await queryProfilesDB({ identifiers: [unknown, self] }) + if (!records.length) return const final = { - ...r.reduce((p, c) => ({ ...p, ...c })), + ...Object.assign({}, ...records), identifier, } try { diff --git a/packages/mask/src/UIRoot.tsx b/packages/mask/src/UIRoot.tsx index 7e0dabf1b201..9cae87e10383 100644 --- a/packages/mask/src/UIRoot.tsx +++ b/packages/mask/src/UIRoot.tsx @@ -17,6 +17,7 @@ import { MaskThemeProvider } from '@masknet/theme' const identity = (jsx: React.ReactNode) => jsx as JSX.Element function compose(init: React.ReactNode, ...f: ((children: React.ReactNode) => JSX.Element)[]) { + // eslint-disable-next-line unicorn/no-array-reduce return f.reduceRight((prev, curr) => curr(prev), <>{init}) } diff --git a/packages/mask/src/components/shared/ApplicationBoard.tsx b/packages/mask/src/components/shared/ApplicationBoard.tsx index ad043a459618..9f8b3016c9ae 100644 --- a/packages/mask/src/components/shared/ApplicationBoard.tsx +++ b/packages/mask/src/components/shared/ApplicationBoard.tsx @@ -4,7 +4,7 @@ import { Typography } from '@mui/material' import { useChainId } from '@masknet/web3-shared-evm' import { useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script' import { useCurrentWeb3NetworkPluginID, useAccount, NetworkPluginID } from '@masknet/plugin-infra/web3' -import { EMPTY_LIST, CrossIsolationMessages, formatPersonaPublicKey } from '@masknet/shared-base' +import { CrossIsolationMessages, formatPersonaPublicKey } from '@masknet/shared-base' import { getCurrentSNSNetwork } from '../../social-network-adaptor/utils' import { activatedSocialNetworkUI } from '../../social-network' import { useI18N } from '../../utils' @@ -122,33 +122,25 @@ function ApplicationBoardContent(props: Props) { const applicationList = useMemo( () => snsAdaptorPlugins - .reduce((acc, cur) => { - if (!cur.ApplicationEntries) return acc - const currentWeb3NetworkSupportedChainIds = cur.enableRequirement.web3?.[currentWeb3Network] + .flatMap(({ ID, ApplicationEntries, enableRequirement }) => { + if (!ApplicationEntries) return [] + const currentWeb3NetworkSupportedChainIds = enableRequirement.web3?.[currentWeb3Network] const isWalletConnectedRequired = currentWeb3NetworkSupportedChainIds !== undefined - const currentSNSIsSupportedNetwork = cur.enableRequirement.networks.networks[currentSNSNetwork] + const currentSNSIsSupportedNetwork = enableRequirement.networks.networks[currentSNSNetwork] const isSNSEnabled = currentSNSIsSupportedNetwork === undefined || currentSNSIsSupportedNetwork - - return acc.concat( - cur.ApplicationEntries.map((x) => { - return { - entry: x, - enabled: isSNSEnabled, - pluginId: cur.ID, - isWalletConnectedRequired: !account && isWalletConnectedRequired, - isWalletConnectedEVMRequired: Boolean( - account && - currentWeb3Network !== NetworkPluginID.PLUGIN_EVM && - isWalletConnectedRequired, - ), - } - }) ?? EMPTY_LIST, - ) - }, EMPTY_LIST) - .sort( - (a, b) => - (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0), - ) + return ApplicationEntries.map((entry) => ({ + entry, + enabled: isSNSEnabled, + pluginId: ID, + isWalletConnectedRequired: !account && isWalletConnectedRequired, + isWalletConnectedEVMRequired: Boolean( + account && currentWeb3Network !== NetworkPluginID.PLUGIN_EVM && isWalletConnectedRequired, + ), + })) + }) + .sort((a, b) => { + return (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0) + }) .filter((x) => Boolean(x.entry.RenderEntryComponent)), [snsAdaptorPlugins, currentWeb3Network, chainId, account], ) diff --git a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx index 60cce9311e2c..dcf5d050eba4 100644 --- a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx +++ b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx @@ -84,18 +84,11 @@ export function ApplicationSettingPluginList() { const applicationList = useMemo( () => snsAdaptorPlugins - .reduce((acc, cur) => { - if (!cur.ApplicationEntries) return acc - return acc.concat( - cur.ApplicationEntries.filter( - (x) => x.appBoardSortingDefaultPriority && !x.recommendFeature, - ).map((x) => { - return { - entry: x, - pluginId: cur.ID, - } - }) ?? EMPTY_LIST, - ) + .flatMap((plugin) => { + const entries = plugin.ApplicationEntries?.filter( + (entry) => entry.appBoardSortingDefaultPriority && !entry.recommendFeature, + ).map((entry) => ({ entry, pluginId: plugin.ID })) + return entries ?? EMPTY_LIST }, EMPTY_LIST) .sort( (a, b) => diff --git a/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx b/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx index e11d80d28614..f4f471ef3dae 100644 --- a/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx +++ b/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx @@ -1,7 +1,7 @@ import { List, ListItem, ListItemAvatar, Avatar, Typography, Box } from '@mui/material' import { openWindow } from '@masknet/shared-base-ui' import { TutorialIcon } from '@masknet/icons' -import { useActivatedPluginsSNSAdaptor, Plugin, PluginI18NFieldRender } from '@masknet/plugin-infra/content-script' +import { useActivatedPluginsSNSAdaptor, PluginI18NFieldRender } from '@masknet/plugin-infra/content-script' import { SettingSwitch } from '@masknet/shared' import { makeStyles, MaskColorVar } from '@masknet/theme' import { Services } from '../../extension/service' @@ -72,17 +72,13 @@ export function ApplicationSettingPluginSwitch(props: Props) { return ( {snsAdaptorPlugins - .reduce<{ entry: Plugin.SNSAdaptor.ApplicationEntry; pluginId: string }[]>((acc, cur) => { - if (!cur.ApplicationEntries) return acc - return acc.concat( - cur.ApplicationEntries.map((x) => { - return { - entry: x, - pluginId: cur.ID, - } - }) ?? [], - ) - }, []) + .flatMap((plugin) => { + const entries = plugin.ApplicationEntries?.map((entry) => ({ + entry, + pluginId: plugin.ID, + })) + return entries ?? [] + }) .filter((x) => x.entry.category === 'dapp') .sort((a, b) => (a.entry.marketListSortingPriority ?? 0) - (b.entry.marketListSortingPriority ?? 0)) .map((x) => ( diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx index ce66e9674eb6..8520baebbc93 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx @@ -92,11 +92,7 @@ export default function OptionsCard(props: OptionsViewProps) { const renderOptions = (userStatus: UserPollStatus) => { const showCount = !!userStatus.count - const total = userStatus.count - ? userStatus.count.reduce((total, e) => { - return { choice: -1, value: total.value + e.value } - }).value - : 0 + const total = userStatus.count?.reduce((total, status) => total + status.value, 0) ?? 0 return userStatus.options.map((option, index) => { const count = userStatus.count ? userStatus.count.find((e) => e.choice === index)?.value || 0 : 0 const percent = (total > 0 ? (count * 100) / total : 0).toFixed(2) diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx index 03d293bf378b..00b9a62b58b6 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx @@ -49,12 +49,7 @@ export default function ResultCard(props: ResultViewProps) { const { t } = useContext(FindTrumanContext) - const total = - result?.count && result.count.length > 0 - ? result.count.reduce((total, e) => { - return { choice: -1, value: total.value + e.value } - }).value - : 1 + const total = result?.count?.reduce((total, status) => total + status.value, 0) ?? 1 const answer = result ? type === PostType.PuzzleResult diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/NftAirdropCard.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/NftAirdropCard.tsx index 1ecf7565186f..7190867404a9 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/NftAirdropCard.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/NftAirdropCard.tsx @@ -186,12 +186,7 @@ export function NftAirdropCard(props: NftAirdropCardProps) { const currentChainId = useChainId() const { classes } = useStyles() - const claimableCount = campaignInfos - ? campaignInfos.reduce((acc, cur) => { - if (cur.claimableInfo.claimable) return acc + 1 - return acc - }, 0) - : 0 + const claimableCount = campaignInfos?.filter((info) => info.claimableInfo.claimable).length ?? 0 useEffect(() => { setCheckAddress('') diff --git a/packages/mask/src/plugins/ITO/Worker/apis/chain.ts b/packages/mask/src/plugins/ITO/Worker/apis/chain.ts index d856374686aa..302bbc539fed 100644 --- a/packages/mask/src/plugins/ITO/Worker/apis/chain.ts +++ b/packages/mask/src/plugins/ITO/Worker/apis/chain.ts @@ -69,56 +69,58 @@ export async function getAllPoolsAsSeller( _unlock_time: BigNumber } - const payloadList: { payload: JSON_PayloadFromChain; hash: string }[] = (await response.json()).result?.reduce( - (acc: { payload: JSON_PayloadFromChain; hash: string }[], cur: TxType) => { - if (!isSameAddress(cur.from, sellerAddress)) return acc - try { - const decodedInputParam = interFace.decodeFunctionData( - 'fill_pool', - cur.input, - ) as unknown as FillPoolInputParam - - const [sellerName = '', message = '', regions = '-'] = decodedInputParam._message.split(MSG_DELIMITER) - - const payload: JSON_PayloadFromChain = { - end_time: (decodedInputParam._end.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, - exchange_token_addresses: decodedInputParam._exchange_addrs, - limit: decodedInputParam._limit.toString(), - message, - qualification_address: decodedInputParam._qualification, - exchange_amounts: decodedInputParam._ratios.map((v) => v.toString()), - start_time: (decodedInputParam._start.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, - token_address: decodedInputParam._token_addr, - total: decodedInputParam._total_tokens.toString(), - unlock_time: - (decodedInputParam._unlock_time.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, - seller: { - address: cur.from, - name: sellerName, - }, - contract_address: cur.to, - chain_id: chainId, - regions, - block_number: Number(cur.blockNumber), - // #region Retrieve at step 3 - pid: '', - creation_time: 0, - // #endregion - // #region Retrieve at step 4 - total_remaining: '', - // #endregion - // #region Retrieve from database - password: '', - // #endregion - } + interface Payload { + result?: TxType[] + } + + const payload: Payload = await response.json() - return acc.concat({ payload, hash: cur.hash }) - } catch { - return acc + const payloadList = (payload.result ?? []).flatMap((txType: TxType) => { + if (!isSameAddress(txType.from, sellerAddress)) return [] + try { + const decodedInputParam = interFace.decodeFunctionData( + 'fill_pool', + txType.input, + ) as unknown as FillPoolInputParam + + const [sellerName = '', message = '', regions = '-'] = decodedInputParam._message.split(MSG_DELIMITER) + + const payload: JSON_PayloadFromChain = { + end_time: (decodedInputParam._end.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, + exchange_token_addresses: decodedInputParam._exchange_addrs, + limit: decodedInputParam._limit.toString(), + message, + qualification_address: decodedInputParam._qualification, + exchange_amounts: decodedInputParam._ratios.map((v) => v.toString()), + start_time: (decodedInputParam._start.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, + token_address: decodedInputParam._token_addr, + total: decodedInputParam._total_tokens.toString(), + unlock_time: (decodedInputParam._unlock_time.toNumber() + ITO_CONTRACT_BASE_TIMESTAMP / 1000) * 1000, + seller: { + address: txType.from, + name: sellerName, + }, + contract_address: txType.to, + chain_id: chainId, + regions, + block_number: Number(txType.blockNumber), + // #region Retrieve at step 3 + pid: '', + creation_time: 0, + // #endregion + // #region Retrieve at step 4 + total_remaining: '', + // #endregion + // #region Retrieve from database + password: '', + // #endregion } - }, - [], - ) + + return { payload, hash: txType.hash } + } catch { + return [] + } + }) // #endregion // #region @@ -212,18 +214,18 @@ export async function getClaimAllPools(chainId: ChainId, endBlock: number, swapp if (!Array.isArray(result)) return [] - const swapRawData: SwapRawType[] = result.reduce((acc: SwapRawType[], cur: TxType) => { - if (!isSameAddress(cur.from, swapperAddress)) return acc + const swapRawData: SwapRawType[] = result.flatMap((txType: TxType) => { + if (!isSameAddress(txType.from, swapperAddress)) return [] try { - const decodedInputParam = interFace.decodeFunctionData('swap', cur.input) as unknown as SwapInputParam - return acc.concat({ - txHash: cur.hash, + const decodedInputParam = interFace.decodeFunctionData('swap', txType.input) as unknown as SwapInputParam + return { + txHash: txType.hash, pid: decodedInputParam.id, - }) + } } catch { - return acc + return [] } - }, []) + }) // 3. filter out pools that have unlock_time. const swapRawFilteredData = ( @@ -273,6 +275,7 @@ export async function getClaimAllPools(chainId: ChainId, endBlock: number, swapp .filter((v) => Boolean(v)) as SwappedTokenType[] // 5. merge same swap token pools into one + // eslint-disable-next-line unicorn/no-array-reduce const swappedTokenList = swappedTokenUnmergedList.reduce((acc: SwappedTokenType[], cur) => { if (acc.some(checkClaimable(cur)) && cur.isClaimable) { // merge same claimable tokens to one diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useAvailabilityNftRedPacket.ts b/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useAvailabilityNftRedPacket.ts index 95a9b460db6d..1537455aa3d1 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useAvailabilityNftRedPacket.ts +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useAvailabilityNftRedPacket.ts @@ -19,10 +19,7 @@ export function useAvailabilityNftRedPacket(id: string, from: string) { const isClaimed = availability.claimed_id !== '0' const totalAmount = result.erc721_token_ids.length const bits = new BigNumber(result.bit_status).toString(2).split('') - const claimedAmount = bits.reduce((acc, cur) => { - if (cur === '1') return acc + 1 - return acc - }, 0) + const claimedAmount = bits.filter((bit) => bit === '1').length const isClaimedAll = totalAmount === claimedAmount const isCompleted = isClaimedAll && !isClaimed const isEnd = isCompleted || availability.expired diff --git a/packages/mask/src/plugins/RedPacket/Worker/apis/chain.ts b/packages/mask/src/plugins/RedPacket/Worker/apis/chain.ts index 6fda5d4d7125..66029ca049c1 100644 --- a/packages/mask/src/plugins/RedPacket/Worker/apis/chain.ts +++ b/packages/mask/src/plugins/RedPacket/Worker/apis/chain.ts @@ -64,53 +64,50 @@ export async function getRedPacketHistory( _total_tokens: BigNumber } - const { result } = await response.json() + const { result }: { result: TxType[] } = await response.json() if (!result.length) return [] - const payloadList: RedPacketJSONPayloadFromChain[] = result.reduce( - (acc: RedPacketJSONPayloadFromChain[], cur: TxType) => { - if (!isSameAddress(cur.from, senderAddress)) return acc - try { - const decodedInputParam = interFace.decodeFunctionData( - 'create_red_packet', - cur.input, - ) as unknown as CreateRedpacketParam - - const redpacketPayload: RedPacketJSONPayloadFromChain = { - contract_address: cur.to, - txid: cur.hash, - shares: decodedInputParam._number.toNumber(), - is_random: decodedInputParam._ifrandom, - total: decodedInputParam._total_tokens.toString(), - duration: decodedInputParam._duration.toNumber() * 1000, - block_number: Number(cur.blockNumber), - contract_version: 4, - network: getChainName(chainId), - token_address: decodedInputParam._token_addr, - sender: { - address: senderAddress, - name: decodedInputParam._name, - message: decodedInputParam._message, - }, - // #region Retrieve at step 3 - rpid: '', - creation_time: 0, - // #endregion - // #region Retrieve at step 4 - total_remaining: '', - claimers: [], - // #endregion - // #region Retrieve from database - password: '', - // #endregion - } - return acc.concat(redpacketPayload) - } catch { - return acc + const payloadList: RedPacketJSONPayloadFromChain[] = result.flatMap((txType: TxType) => { + if (!isSameAddress(txType.from, senderAddress)) return [] + try { + const decodedInputParam = interFace.decodeFunctionData( + 'create_red_packet', + txType.input, + ) as unknown as CreateRedpacketParam + + const redpacketPayload: RedPacketJSONPayloadFromChain = { + contract_address: txType.to, + txid: txType.hash, + shares: decodedInputParam._number.toNumber(), + is_random: decodedInputParam._ifrandom, + total: decodedInputParam._total_tokens.toString(), + duration: decodedInputParam._duration.toNumber() * 1000, + block_number: Number(txType.blockNumber), + contract_version: 4, + network: getChainName(chainId), + token_address: decodedInputParam._token_addr, + sender: { + address: senderAddress, + name: decodedInputParam._name, + message: decodedInputParam._message, + }, + // #region Retrieve at step 3 + rpid: '', + creation_time: 0, + // #endregion + // #region Retrieve at step 4 + total_remaining: '', + claimers: [], + // #endregion + // #region Retrieve from database + password: '', + // #endregion } - }, - [], - ) + return redpacketPayload + } catch { + return [] + } + }) // #endregion // #region diff --git a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx index 797928a50a45..86eadc23d02e 100644 --- a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx +++ b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx @@ -32,19 +32,7 @@ import { LidoProtocol } from '../protocols/LDOProtocol' import { AAVEProtocol } from '../protocols/AAVEProtocol' import { LDO_PAIRS } from '../constants' import type { AbiItem } from 'web3-utils' -import { flatten, compact } from 'lodash-unified' - -function splitToPair(a: FungibleTokenDetailed[] | undefined) { - if (!a) { - return [] - } - return a.reduce(function (result: any, value, index, array) { - if (index % 2 === 0) { - result.push(array.slice(index, index + 2)) - } - return result - }, []) -} +import { flatten, compact, chunk } from 'lodash-unified' export interface SavingsDialogProps { open: boolean @@ -100,7 +88,9 @@ export function SavingsDialog({ open, onClose }: SavingsDialogProps) { const protocols = useMemo( () => [ ...LDO_PAIRS.filter((x) => x[0].chainId === chainId).map((pair) => new LidoProtocol(pair)), - ...splitToPair(detailedAaveTokens).map((pair: any) => new AAVEProtocol(pair)), + ...chunk(detailedAaveTokens, 2).map( + (pair) => new AAVEProtocol(pair as [FungibleTokenDetailed, FungibleTokenDetailed]), + ), ], [chainId, detailedAaveTokens, tab], ) diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/ResultCard.tsx b/packages/mask/src/plugins/Snapshot/SNSAdaptor/ResultCard.tsx index efe8cc1910b9..83351e1e31f0 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/ResultCard.tsx +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/ResultCard.tsx @@ -125,11 +125,15 @@ function Content() { }} title={ - {result.powerDetail.reduce((sum, cur, i) => { - const name = - millify(cur.power, { precision: 2, lowercase: true }) + ' ' + cur.name - return `${sum} ${i === 0 ? '' : '+'} ${name}` - }, '')} + {result.powerDetail + .flatMap((detail, index) => { + const name = millify(detail.power, { + precision: 2, + lowercase: true, + }) + return [index === 0 ? '' : '+', name, detail.name] + }) + .join(' ')} } placement="top" diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts index 203516d92f52..1552f87eb4ea 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts @@ -26,6 +26,7 @@ async function Suspender(identifier: ProposalIdentifier) { const { payload: votes } = useVotes(identifier) const strategies = proposal.strategies const powerOfChoices = proposal.choices.map((_choice, i) => + // eslint-disable-next-line unicorn/no-array-reduce voteForChoice(votes, i).reduce((a, b) => { if (b.choiceIndex) { return a + b.balance diff --git a/packages/mask/src/plugins/Tips/hooks/useTipsWalletsList.ts b/packages/mask/src/plugins/Tips/hooks/useTipsWalletsList.ts index eb60dcb8551e..606b72c064d5 100644 --- a/packages/mask/src/plugins/Tips/hooks/useTipsWalletsList.ts +++ b/packages/mask/src/plugins/Tips/hooks/useTipsWalletsList.ts @@ -18,7 +18,7 @@ export function useTipsWalletsList( if (kv && kv.proofs.length > 0 && proofs.length > 0) { const kvCache = kv.proofs.find((x) => x.identity === identity) if (!kvCache) return EMPTY_LIST - const result = proofs.reduce((res, x) => { + const result = proofs.map((x) => { x.isDefault = 0 x.isPublic = 1 const matched = kvCache?.content[PluginId.Tips]?.find((proof) => isSameAddress(x.identity, proof.identity)) @@ -26,9 +26,8 @@ export function useTipsWalletsList( x.isDefault = matched.isDefault x.isPublic = matched.isPublic } - res.push(x) - return res - }, []) + return x + }) const idx = result.findIndex((i) => i.isDefault) if (idx !== -1) { result.unshift(result.splice(idx, 1)[0]) diff --git a/packages/mask/src/plugins/Trader/apis/balancer/index.ts b/packages/mask/src/plugins/Trader/apis/balancer/index.ts index 2777f93fe34d..6fe5b10b8520 100644 --- a/packages/mask/src/plugins/Trader/apis/balancer/index.ts +++ b/packages/mask/src/plugins/Trader/apis/balancer/index.ts @@ -73,6 +73,7 @@ export async function getSwaps( // compose routes // learn more: https://github.com/balancer-labs/balancer-frontend/blob/develop/src/components/swap/Routing.vue + // eslint-disable-next-line unicorn/no-array-reduce const totalSwapAmount = swaps.reduce((total, rawHops) => total.plus(first(rawHops)?.swapAmount || '0'), ZERO) const pools = sor.onChainCache.pools diff --git a/packages/mask/src/plugins/Trader/apis/trending/index.ts b/packages/mask/src/plugins/Trader/apis/trending/index.ts index 70a8db6d683c..a8fa0cd65138 100644 --- a/packages/mask/src/plugins/Trader/apis/trending/index.ts +++ b/packages/mask/src/plugins/Trader/apis/trending/index.ts @@ -224,11 +224,15 @@ async function getCoinTrending(id: string, currency: Currency, dataProvider: Dat ) ?? '' ], }, - market: Object.entries(info.market_data).reduce((accumulated, [key, value]) => { - if (value && typeof value === 'object') accumulated[key] = value[currency.id] ?? 0 - else accumulated[key] = value - return accumulated - }, {}), + market: (() => { + const entries = Object.entries(info.market_data).map(([key, value]) => { + if (value && typeof value === 'object') { + return [key, value[currency.id] ?? 0] + } + return [key, value] + }) + return Object.fromEntries(entries) + })(), tickers: info.tickers.slice(0, 30).map((x) => ({ logo_url: x.market.logo, trade_url: x.trade_url, diff --git a/packages/mask/src/plugins/Trader/apis/uniswap/index.ts b/packages/mask/src/plugins/Trader/apis/uniswap/index.ts index ea5dcce00b7a..dfc6a152cf90 100644 --- a/packages/mask/src/plugins/Trader/apis/uniswap/index.ts +++ b/packages/mask/src/plugins/Trader/apis/uniswap/index.ts @@ -310,7 +310,7 @@ export async function getBulkPairData(pairList: string[]) { const oneDayResult = await fetchPairsHistoricalBulk(pairList, oneDayBlock) - const oneDayData = oneDayResult.reduce>((obj, cur) => ({ ...obj, [cur.id]: cur }), {}) + const oneDayData = Object.fromEntries(oneDayResult.map((pair): [string, Data] => [pair.id, pair])) const pairsData = await Promise.all( current?.map(async (pair) => { @@ -340,9 +340,11 @@ export async function getBulkPairData(pairList: string[]) { }), ) - return pairsData.reduce>( - (obj, cur) => ({ ...obj, [cur.id]: cur }), - {}, + return Object.fromEntries( + pairsData.map((pair): [string, Data & { oneDayVolumeUSD: number; oneDayVolumeUntracked: number }] => [ + pair.id, + pair, + ]), ) } diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts index 204f8e3f5829..aebec276a4e8 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts @@ -71,22 +71,18 @@ export function useAllCommonPairs(tradeProvider: TradeProvider, currencyA?: Curr const { value: allPairs, ...asyncResult } = usePairs(tradeProvider, allCurrencyCombinations) // only pass along valid pairs, non-duplicated pairs - const allPairs_ = useMemo( - () => - Object.values( - allPairs - // filter out invalid pairs - .filter((result): result is [PairState.EXISTS, Pair] => - Boolean(result[0] === PairState.EXISTS && result[1]), - ) - // filter out duplicated pairs - .reduce>((memo, [, current]) => { - memo[current.liquidityToken.address] = memo[current.liquidityToken.address] ?? current - return memo - }, {}), - ), - [allPairs], - ) + const allPairs_ = useMemo(() => { + const filtered = new Map() + for (const [state, pair] of allPairs as [PairState.EXISTS, Pair][]) { + // filter out invalid pairs + if (!(state === PairState.EXISTS && pair)) continue + // filter out duplicated pairs + const { address } = pair.liquidityToken + if (filtered.has(address)) continue + filtered.set(pair.liquidityToken.address, pair) + } + return [...filtered.values()] + }, [allPairs]) return { ...asyncResult, diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts index 783b57907efb..0c492b38499d 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts @@ -14,6 +14,7 @@ function computeRealizedLPFeePercent(trade: Trade): Percent { // for each hop in our trade, take away the x*y=k price impact from 0.3% fees // e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03)) const percent = ONE_HUNDRED_PERCENT.subtract( + // eslint-disable-next-line unicorn/no-array-reduce trade.route.pairs.reduce( (currentFee: Percent): Percent => currentFee.multiply(INPUT_FRACTION_AFTER_FEE), ONE_HUNDRED_PERCENT, @@ -22,6 +23,7 @@ function computeRealizedLPFeePercent(trade: Trade): Percent { return new Percent(percent.numerator, percent.denominator) } else { const percent = ONE_HUNDRED_PERCENT.subtract( + // eslint-disable-next-line unicorn/no-array-reduce trade.route.pools.reduce( (currentFee: Percent, pool): Percent => currentFee.multiply(ONE_HUNDRED_PERCENT.subtract(new Fraction(pool.fee, 1_000_000))), diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts index 8b7b50d09439..d4b44d4dc3af 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts @@ -78,6 +78,7 @@ export function useV3BestTradeExactIn( } const { bestRoute, amountOut } = quotesResults .filter((x) => x.succeed) + // eslint-disable-next-line unicorn/no-array-reduce .reduce( ( currentBest: { bestRoute: Route | null; amountOut: string | null }, @@ -198,6 +199,7 @@ export function useV3BestTradeExactOut( } const { bestRoute, amountIn } = quotesResults .filter((x) => x.succeed) + // eslint-disable-next-line unicorn/no-array-reduce .reduce( ( currentBest: { bestRoute: Route | null; amountIn: string | null }, diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts index 1c4350cd890a..4e8d6591b71a 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts @@ -21,13 +21,11 @@ export function useV3SwapPools( const allCurrencyCombinationsWithAllFees: [Token, Token, FeeAmount][] = useMemo( () => - allCurrencyCombinations.reduce<[Token, Token, FeeAmount][]>((list, [tokenA, tokenB]) => { - return list.concat([ - [tokenA, tokenB, FeeAmount.LOW], - [tokenA, tokenB, FeeAmount.MEDIUM], - [tokenA, tokenB, FeeAmount.HIGH], - ]) - }, []), + allCurrencyCombinations.flatMap<[Token, Token, FeeAmount]>(([tokenA, tokenB]) => [ + [tokenA, tokenB, FeeAmount.LOW], + [tokenA, tokenB, FeeAmount.MEDIUM], + [tokenA, tokenB, FeeAmount.HIGH], + ]), [allCurrencyCombinations], ) const pools = usePools(TradeProvider.UNISWAP_V3, allCurrencyCombinationsWithAllFees) diff --git a/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts b/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts index bd86889f7cef..50c138cd9f2f 100644 --- a/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts +++ b/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts @@ -2,16 +2,13 @@ import { useActivatedPluginsDashboard } from '../manager/dashboard' import { useActivatedPluginsSNSAdaptor } from '../manager/sns-adaptor' import type { Web3Plugin } from '../web3-types' +type Capabilities = Web3Plugin.ObjectCapabilities.Capabilities + export function useAllPluginsWeb3State() { const pluginsSNSAdaptor = useActivatedPluginsSNSAdaptor('any') const pluginsDashboard = useActivatedPluginsDashboard() - - return [...pluginsSNSAdaptor, ...pluginsDashboard].reduce< - Record - >((accumulator, current) => { - if (current.Web3State) { - accumulator[current.ID] = current.Web3State - } - return accumulator - }, {}) + const entries = [...pluginsSNSAdaptor, ...pluginsDashboard] + .filter((definition) => definition.Web3State) + .map((definiton): [string, Capabilities] => [definiton.ID, definiton.Web3State!]) + return Object.fromEntries(entries) as Record } diff --git a/packages/plugin-infra/src/manager/sns-adaptor.ts b/packages/plugin-infra/src/manager/sns-adaptor.ts index 202666e5acc7..9635844ca9b7 100644 --- a/packages/plugin-infra/src/manager/sns-adaptor.ts +++ b/packages/plugin-infra/src/manager/sns-adaptor.ts @@ -57,15 +57,12 @@ export function useActivatedPluginSNSAdaptor(pluginID: string, minimalModeEquals export function useActivatedPluginSNSAdaptor_Web3Supported(chainId: number, pluginID: string) { const plugins = useActivatedPluginsSNSAdaptor('any') - return plugins.reduce>((acc, cur) => { - if (!cur.enableRequirement.web3) { - acc[cur.ID] = true - return acc - } - const supportedChainIds = cur.enableRequirement.web3?.[pluginID as NetworkPluginID]?.supportedChainIds - acc[cur.ID] = supportedChainIds?.includes(chainId) ?? false - return acc - }, {}) + const entries = plugins.map((plugin): [string, boolean] => { + if (!plugin.enableRequirement.web3) return [plugin.ID, true] + const supportedChainIds = plugin.enableRequirement.web3?.[pluginID as NetworkPluginID]?.supportedChainIds + return [plugin.ID, supportedChainIds?.includes(chainId) ?? false] + }) + return Object.fromEntries(entries) as Record } export function startPluginSNSAdaptor( diff --git a/packages/shared-base/src/color/avatar.ts b/packages/shared-base/src/color/avatar.ts index 2b32d55b143a..43b5b6d33ea5 100644 --- a/packages/shared-base/src/color/avatar.ts +++ b/packages/shared-base/src/color/avatar.ts @@ -1,4 +1,5 @@ export function generateContactAvatarColor(input: string, theme: 'light' | 'dark') { + // eslint-disable-next-line unicorn/no-array-reduce const hash = [...input].reduce((prev, current) => { // eslint-disable-next-line no-bitwise const next = current.charCodeAt(0) + (prev << 5) - prev diff --git a/packages/theme/src/Theme/Provider.tsx b/packages/theme/src/Theme/Provider.tsx index 226dedd32885..2260bdc1a4d2 100644 --- a/packages/theme/src/Theme/Provider.tsx +++ b/packages/theme/src/Theme/Provider.tsx @@ -3,6 +3,7 @@ import { MaskIconPalette, MaskIconPaletteContext } from '@masknet/icons' import { CustomSnackbarProvider } from '../Components' function compose(init: React.ReactNode, ...f: ((children: React.ReactNode) => JSX.Element)[]) { + // eslint-disable-next-line unicorn/no-array-reduce return f.reduceRight((prev, curr) => curr(prev), <>{init}) } diff --git a/packages/typed-message/base/transformer/Flatten.ts b/packages/typed-message/base/transformer/Flatten.ts index ba5f32c2a154..8ce7cc6b2789 100644 --- a/packages/typed-message/base/transformer/Flatten.ts +++ b/packages/typed-message/base/transformer/Flatten.ts @@ -20,6 +20,7 @@ export function FlattenTypedMessage(message: TypedMessage, context: Transformati .map((x) => FlattenTypedMessage(x, context)) .flatMap((x) => (isTypedMessageTuple(x) ? (x.meta ? x : x.items) : x)) .filter((x) => !isTypedMessageEmpty(x)) + // eslint-disable-next-line unicorn/no-array-reduce .reduce((result, current) => { const lastItem = result.at(-1) if (!lastItem || lastItem.meta || current.meta) return result.concat(current) diff --git a/packages/typed-message/base/transformer/composed.ts b/packages/typed-message/base/transformer/composed.ts index 1fbea4d71607..8f0c0cc73382 100644 --- a/packages/typed-message/base/transformer/composed.ts +++ b/packages/typed-message/base/transformer/composed.ts @@ -18,6 +18,7 @@ export function composeTransformers(): ComposedTransformers { const transformers = new Set() function composed(message: TypedMessage, context: TransformationContext) { + // eslint-disable-next-line unicorn/no-array-reduce return [...transformers].sort((a, b) => b[1] - a[1]).reduce((p, [c]) => c(p, context), message) } diff --git a/packages/web3-providers/src/debank/format.ts b/packages/web3-providers/src/debank/format.ts index a834097eefa7..22493411061b 100644 --- a/packages/web3-providers/src/debank/format.ts +++ b/packages/web3-providers/src/debank/format.ts @@ -6,40 +6,34 @@ import DeBank from '@masknet/web3-constants/evm/debank.json' type Asset = Web3Plugin.Asset -export function formatAssets(data: WalletTokenRecord[]): Asset[] { +export function formatAssets(records: WalletTokenRecord[]): Asset[] { const supportedChains = Object.values(DeBank.CHAIN_ID).filter(Boolean) - - const result: Asset[] = data.reduce((list: Asset[], y) => { - if (!y.is_verified) return list - const chainIdFromChain = getChainIdFromName(y.chain) - if (!chainIdFromChain) return list - const address = supportedChains.includes(y.id) ? createNativeToken(chainIdFromChain).address : y.id - - return [ - ...list, - { + return records.flatMap((asset) => { + if (!asset.is_verified) return [] + const chainIdFromChain = getChainIdFromName(asset.chain) + if (!chainIdFromChain) return [] + const address = supportedChains.includes(asset.id) ? createNativeToken(chainIdFromChain).address : asset.id + return { + id: address, + chainId: chainIdFromChain, + token: { id: address, + address, chainId: chainIdFromChain, - token: { - id: address, - address, - chainId: chainIdFromChain, - type: TokenType.Fungible, - decimals: y.decimals, - name: y.name, - symbol: y.symbol, - logoURI: y.logo_url, - }, - balance: rightShift(y.amount, y.decimals).toFixed(), - price: { - [CurrencyType.USD]: toFixed(y.price), - }, - value: { - [CurrencyType.USD]: multipliedBy(y.price ?? 0, y.amount).toFixed(), - }, - logoURI: y.logo_url, + type: TokenType.Fungible, + decimals: asset.decimals, + name: asset.name, + symbol: asset.symbol, + logoURI: asset.logo_url, + }, + balance: rightShift(asset.amount, asset.decimals).toFixed(), + price: { + [CurrencyType.USD]: toFixed(asset.price), + }, + value: { + [CurrencyType.USD]: multipliedBy(asset.price ?? 0, asset.amount).toFixed(), }, - ] - }, []) - return result + logoURI: asset.logo_url, + } + }) } diff --git a/packages/web3-shared/evm/utils/token.ts b/packages/web3-shared/evm/utils/token.ts index 863bce1ad8fc..d7cf9024203c 100644 --- a/packages/web3-shared/evm/utils/token.ts +++ b/packages/web3-shared/evm/utils/token.ts @@ -123,22 +123,22 @@ export function createERC20Tokens( symbol: string | ((chainId: ChainId) => string), decimals: number | ((chainId: ChainId) => number), ) { - type Table = ChainIdRecord - const base = {} as Table - return getEnumAsArray(ChainId).reduce((accumulator, { value: chainId }) => { + const entries = getEnumAsArray(ChainId).map(({ value: chainId }): [ChainId, ERC20TokenDetailed] => { const evaluator: (f: T | ((chainId: ChainId) => T)) => T = (f) => typeof f === 'function' ? (f as any)(chainId) : f - - accumulator[chainId] = { - type: EthereumTokenType.ERC20, + return [ chainId, - address: getTokenConstants(chainId)[key] ?? '', - name: evaluator(name), - symbol: evaluator(symbol), - decimals: evaluator(decimals), - } - return accumulator - }, base) + { + type: EthereumTokenType.ERC20, + chainId, + address: getTokenConstants(chainId)[key] ?? '', + name: evaluator(name), + symbol: evaluator(symbol), + decimals: evaluator(decimals), + }, + ] + }) + return Object.fromEntries(entries) as ChainIdRecord } export function addGasMargin(value: BigNumber.Value, scale = 3000) { From f64905e6ccbac3e3a3170c11772ec6762ec59302 Mon Sep 17 00:00:00 2001 From: Septs Date: Mon, 16 May 2022 22:53:40 +0800 Subject: [PATCH 2/6] fix: typo --- .../components/shared/ApplicationSettingPluginList.tsx | 9 ++++----- .../plugin-infra/src/hooks/useAllPluginsWeb3State.ts | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx index dcf5d050eba4..2d6572cf4b22 100644 --- a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx +++ b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx @@ -89,11 +89,10 @@ export function ApplicationSettingPluginList() { (entry) => entry.appBoardSortingDefaultPriority && !entry.recommendFeature, ).map((entry) => ({ entry, pluginId: plugin.ID })) return entries ?? EMPTY_LIST - }, EMPTY_LIST) - .sort( - (a, b) => - (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0), - ), + }) + .sort((a, b) => { + return (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0) + }), [snsAdaptorPlugins], ) const [listedAppList, setListedAppList] = useState(applicationList.filter((x) => !getUnlistedApp(x))) diff --git a/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts b/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts index 50c138cd9f2f..812584b89b59 100644 --- a/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts +++ b/packages/plugin-infra/src/hooks/useAllPluginsWeb3State.ts @@ -9,6 +9,6 @@ export function useAllPluginsWeb3State() { const pluginsDashboard = useActivatedPluginsDashboard() const entries = [...pluginsSNSAdaptor, ...pluginsDashboard] .filter((definition) => definition.Web3State) - .map((definiton): [string, Capabilities] => [definiton.ID, definiton.Web3State!]) + .map((definition): [string, Capabilities] => [definition.ID, definition.Web3State!]) return Object.fromEntries(entries) as Record } From d63093a85866d5e56d906e012d54bc7b084c5481 Mon Sep 17 00:00:00 2001 From: Septs Date: Tue, 17 May 2022 00:57:17 +0800 Subject: [PATCH 3/6] chore: no-array-reduce --- packages/.eslintrc.json | 2 +- .../backup-format/src/utils/backupPreview.ts | 3 ++- .../backup-format/src/utils/hex2buffer.ts | 4 ++- .../shared/ApplicationSettingPluginList.tsx | 26 ++++++++----------- .../shared/ApplicationSettingPluginSwitch.tsx | 10 +++---- .../FindTruman/SNSAdaptor/OptionsCard.tsx | 3 ++- .../FindTruman/SNSAdaptor/ResultCard.tsx | 3 ++- .../src/plugins/Polls/SNSAdaptor/Polls.tsx | 5 ++-- .../src/plugins/PoolTogether/UI/Account.tsx | 10 +++---- .../plugins/PoolTogether/UI/DepositDialog.tsx | 2 +- .../plugins/Snapshot/SNSAdaptor/VotesCard.tsx | 15 +++++------ .../Snapshot/SNSAdaptor/hooks/usePower.ts | 21 +++++++-------- .../Snapshot/SNSAdaptor/hooks/useResults.ts | 24 ++++++++--------- .../Snapshot/SNSAdaptor/hooks/useVotes.ts | 7 +++-- .../trader/uniswap/useAllCommonPairs.ts | 3 ++- packages/mask/src/utils/getTextUILength.ts | 5 +++- 16 files changed, 69 insertions(+), 74 deletions(-) diff --git a/packages/.eslintrc.json b/packages/.eslintrc.json index 6f8b87732d82..63beb8ce9274 100644 --- a/packages/.eslintrc.json +++ b/packages/.eslintrc.json @@ -59,7 +59,7 @@ "unicorn/no-new-buffer": "error", "unicorn/no-thenable": "error", "unicorn/no-useless-promise-resolve-reject": "error", - "unicorn/no-array-reduce": "error", + "unicorn/no-array-reduce": ["error", { "allowSimpleOperations": false }], "unicorn/prefer-add-event-listener": "error", "unicorn/prefer-date-now": "error", "unicorn/prefer-dom-node-dataset": "error", diff --git a/packages/backup-format/src/utils/backupPreview.ts b/packages/backup-format/src/utils/backupPreview.ts index eb1be97c3095..19c42f26438a 100644 --- a/packages/backup-format/src/utils/backupPreview.ts +++ b/packages/backup-format/src/utils/backupPreview.ts @@ -1,4 +1,5 @@ import type { NormalizedBackup } from '@masknet/backup-format' +import { sum } from 'lodash-unified' export interface BackupPreview { personas: number @@ -20,7 +21,7 @@ export function getBackupPreviewInfo(json: NormalizedBackup.Data): BackupPreview return { personas: json.personas.size, - accounts: [...json.personas.values()].reduce((a, b) => a + b.linkedProfiles.size, 0), + accounts: sum([...json.personas.values()].map((persona) => persona.linkedProfiles.size)), posts: json.posts.size, contacts: json.profiles.size, relations: json.relations.length, diff --git a/packages/backup-format/src/utils/hex2buffer.ts b/packages/backup-format/src/utils/hex2buffer.ts index 7204339f8dd7..4b8f76f2e0c2 100644 --- a/packages/backup-format/src/utils/hex2buffer.ts +++ b/packages/backup-format/src/utils/hex2buffer.ts @@ -1,3 +1,5 @@ +import { sum } from 'lodash-unified' + /** @internal */ export function hex2buffer(hexString: string, padded?: boolean) { if (hexString.length % 2) { @@ -21,7 +23,7 @@ export function hex2buffer(hexString: string, padded?: boolean) { /** @internal */ function concat(...buf: (Uint8Array | number[])[]) { - const res = new Uint8Array(buf.map((item) => item.length).reduce((prev, cur) => prev + cur)) + const res = new Uint8Array(sum(buf.map((item) => item.length))) let offset = 0 buf.forEach((item) => { for (let i = 0; i < item.length; i += 1) { diff --git a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx index 2d6572cf4b22..5e5d47c7e912 100644 --- a/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx +++ b/packages/mask/src/components/shared/ApplicationSettingPluginList.tsx @@ -2,7 +2,6 @@ import { useActivatedPluginsSNSAdaptor, Plugin } from '@masknet/plugin-infra/con import { useMemo, useState, useCallback } from 'react' import { List, ListItem, Typography } from '@mui/material' import { makeStyles, getMaskColor } from '@masknet/theme' -import { EMPTY_LIST } from '@masknet/shared-base' import { useI18N } from '../../utils' import { PersistentStorages } from '../../../shared' @@ -81,20 +80,17 @@ export function ApplicationSettingPluginList() { const { classes } = useStyles() const { t } = useI18N() const snsAdaptorPlugins = useActivatedPluginsSNSAdaptor('any') - const applicationList = useMemo( - () => - snsAdaptorPlugins - .flatMap((plugin) => { - const entries = plugin.ApplicationEntries?.filter( - (entry) => entry.appBoardSortingDefaultPriority && !entry.recommendFeature, - ).map((entry) => ({ entry, pluginId: plugin.ID })) - return entries ?? EMPTY_LIST - }) - .sort((a, b) => { - return (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0) - }), - [snsAdaptorPlugins], - ) + const applicationList = useMemo(() => { + return snsAdaptorPlugins + .flatMap(({ ID, ApplicationEntries: entries }) => + (entries ?? []) + .filter((entry) => entry.appBoardSortingDefaultPriority && !entry.recommendFeature) + .map((entry) => ({ entry, pluginId: ID })), + ) + .sort((a, b) => { + return (a.entry.appBoardSortingDefaultPriority ?? 0) - (b.entry.appBoardSortingDefaultPriority ?? 0) + }) + }, [snsAdaptorPlugins]) const [listedAppList, setListedAppList] = useState(applicationList.filter((x) => !getUnlistedApp(x))) const [unlistedAppList, setUnListedAppList] = useState(applicationList.filter((x) => getUnlistedApp(x))) diff --git a/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx b/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx index f4f471ef3dae..b8f5de60eed8 100644 --- a/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx +++ b/packages/mask/src/components/shared/ApplicationSettingPluginSwitch.tsx @@ -72,13 +72,9 @@ export function ApplicationSettingPluginSwitch(props: Props) { return ( {snsAdaptorPlugins - .flatMap((plugin) => { - const entries = plugin.ApplicationEntries?.map((entry) => ({ - entry, - pluginId: plugin.ID, - })) - return entries ?? [] - }) + .flatMap(({ ID, ApplicationEntries: entries }) => + (entries ?? []).map((entry) => ({ entry, pluginId: ID })), + ) .filter((x) => x.entry.category === 'dapp') .sort((a, b) => (a.entry.marketListSortingPriority ?? 0) - (b.entry.marketListSortingPriority ?? 0)) .map((x) => ( diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx index 8520baebbc93..6344907fd75e 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx @@ -7,6 +7,7 @@ import NoNftCard from './NoNftCard' import { FindTrumanContext } from '../context' import { BorderLinearProgress } from './ResultCard' import { ActionButtonPromise } from '../../../extension/options-page/DashboardComponents/ActionButton' +import { sum } from 'lodash-unified' const useOptionsStyles = makeStyles()((theme) => { return { @@ -92,7 +93,7 @@ export default function OptionsCard(props: OptionsViewProps) { const renderOptions = (userStatus: UserPollStatus) => { const showCount = !!userStatus.count - const total = userStatus.count?.reduce((total, status) => total + status.value, 0) ?? 0 + const total = sum((userStatus.count ?? []).map((status) => status.value)) return userStatus.options.map((option, index) => { const count = userStatus.count ? userStatus.count.find((e) => e.choice === index)?.value || 0 : 0 const percent = (total > 0 ? (count * 100) / total : 0).toFixed(2) diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx index 00b9a62b58b6..2c2aeb18d107 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx @@ -16,6 +16,7 @@ import { PostType } from '../types' import { useContext, useState } from 'react' import { FindTrumanContext } from '../context' import { makeStyles } from '@masknet/theme' +import { sum } from 'lodash-unified' export const BorderLinearProgress: any = styled(LinearProgress)(({ theme }) => ({ height: 10, @@ -49,7 +50,7 @@ export default function ResultCard(props: ResultViewProps) { const { t } = useContext(FindTrumanContext) - const total = result?.count?.reduce((total, status) => total + status.value, 0) ?? 1 + const total = result?.count ? sum(result.count.map((status) => status.value)) : 1 const answer = result ? type === PostType.PuzzleResult diff --git a/packages/mask/src/plugins/Polls/SNSAdaptor/Polls.tsx b/packages/mask/src/plugins/Polls/SNSAdaptor/Polls.tsx index 3167f68adc78..2fedf1d570ad 100644 --- a/packages/mask/src/plugins/Polls/SNSAdaptor/Polls.tsx +++ b/packages/mask/src/plugins/Polls/SNSAdaptor/Polls.tsx @@ -8,6 +8,7 @@ import type { PollGunDB } from '../Services' import { PollStatus } from '../types' import { SupportedLanguages } from '@masknet/public-api' import { safeUnreachable } from '@dimensiondev/kit' +import { sum } from 'lodash-unified' const useStyles = makeStyles()((theme) => ({ card: { @@ -71,9 +72,7 @@ export function PollCardUI(props: PollCardProps) { const { t } = useI18N() const lang = useLanguage() - const totalVotes = poll.results.reduce( - (accumulator: number, currentValue: number): number => accumulator + currentValue, - ) + const totalVotes = sum(poll.results) const getDeadline = (date: number) => { const deadline = new Date(date) diff --git a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx index e6fdde3a26fa..61598c08c583 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx @@ -8,6 +8,7 @@ import { COMMUNITY_URL } from '../constants' import { useAccountBalance } from '../hooks/useAccountBalances' import type { Pool } from '../types' import { AccountPool } from './AccountPool' +import { sum } from 'lodash-unified' const useStyles = makeStyles()((theme) => ({ root: { @@ -76,17 +77,16 @@ export function Account(props: AccountProps) { } const noZeroBalances = balances.filter((balance) => Number.parseInt(balance.account.ticketBalance, 10) !== 0) - const totalUsdBalance = noZeroBalances - .map((balance) => { + const totalUsdBalance = sum( + noZeroBalances.map((balance) => { const ticketBalance = Number.parseFloat( formatBalance(balance.account.ticketBalance, Number.parseInt(balance.pool.tokens.ticket.decimals, 10)), ) const ticketUsdRate = balance.pool.tokens.ticket.usd if (!ticketUsdRate) return 0 return ticketBalance * ticketUsdRate - }) - .reduce((x, y) => x + y, 0) - .toLocaleString() + }), + ) return ( diff --git a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx index ced220768201..68b1561e6db4 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx @@ -295,7 +295,7 @@ export function DepositDialog() { {t('plugin_pooltogether_odds_value', { - value: odds.toLocaleString(), + value: odds, period: getPrizePeriod(t, prizePeriodSeconds), })} diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/VotesCard.tsx b/packages/mask/src/plugins/Snapshot/SNSAdaptor/VotesCard.tsx index decf384a4212..b473f4db44aa 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/VotesCard.tsx +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/VotesCard.tsx @@ -95,14 +95,13 @@ function Content() { const isAverageWeight = v.choices?.every((c) => c.weight === 1) const fullChoiceText = v.totalWeight && v.choices - ? v.choices.reduce((acc, choice, i) => { - return ( - acc + - (i === 0 ? '' : ', ') + - (!isAverageWeight ? formatPercentage(choice.weight / v.totalWeight!) + ' ' : '') + - choice.name - ) - }, '') + ? v.choices + .flatMap((choice, index) => [ + index === 0 ? '' : ', ', + !isAverageWeight ? formatPercentage(choice.weight / v.totalWeight!) + ' ' : '', + choice.name, + ]) + .join('') : null return ( diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts index 9c6699ebfc59..adfa9b8bd96c 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts @@ -11,18 +11,15 @@ export function usePower(identifier: ProposalIdentifier) { const account = useAccount() return useAsyncRetry(async () => { if (!account) return 0 - return ( - await PluginSnapshotRPC.getScores( - proposal.snapshot, - [account], - proposal.network, - identifier.space, - proposal.strategies, - ) + const scores = await PluginSnapshotRPC.getScores( + proposal.snapshot, + [account], + proposal.network, + identifier.space, + proposal.strategies, ) - .map((v) => mapKeys(v, (_value, key) => key.toLowerCase()) as { [x: string]: number }) - .reduce((acc, cur) => { - return acc + (cur[account.toLowerCase()] ?? 0) - }, 0) + return scores + .map((score) => mapKeys(score, (_value, key) => key.toLowerCase()) as Record) + .map((record) => record[account.toLowerCase()] ?? 0) }, [account]) } diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts index 1552f87eb4ea..bc701b576d2a 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts @@ -2,6 +2,7 @@ import type { ProposalIdentifier, ProposalResult, VoteItem } from '../../types' import { useSuspense } from '../../../../utils/hooks/useSuspense' import { useProposal } from './useProposal' import { useVotes } from './useVotes' +import { sum } from 'lodash-unified' const cache = new Map< string, @@ -25,21 +26,20 @@ async function Suspender(identifier: ProposalIdentifier) { const { payload: proposal } = useProposal(identifier.id) const { payload: votes } = useVotes(identifier) const strategies = proposal.strategies - const powerOfChoices = proposal.choices.map((_choice, i) => - // eslint-disable-next-line unicorn/no-array-reduce - voteForChoice(votes, i).reduce((a, b) => { - if (b.choiceIndex) { - return a + b.balance - } else { - const totalWeight = b.choices!.reduce((_totalWeight, inner_b) => _totalWeight + inner_b.weight, 0) - return a + (b.balance * (b.choices!.find((v) => v.index === i + 1)?.weight ?? 0)) / totalWeight - } - }, 0), + const powerOfChoices = proposal.choices.map((_choice, index) => + sum( + voteForChoice(votes, index).map((choice) => { + if (choice.choiceIndex) return choice.balance + const totalWeight = sum(choice.choices!.map((choice) => choice.weight)) + const weight = choice.choices!.find((v) => v.index === index + 1)?.weight ?? 0 + return (choice.balance * weight) / totalWeight + }), + ), ) const powerDetailOfChoices = proposal.choices.map((_choice, i) => - strategies.map((_strategy, sI) => voteForChoice(votes, i).reduce((a, b) => a + b.scores[sI], 0)), + strategies.map((_strategy, index) => sum(voteForChoice(votes, i).map((vote) => vote.scores[index], 0))), ) - const totalPower = votes.reduce((a, b) => a + b.balance, 0) + const totalPower = sum(votes.map((vote) => vote.balance)) const results: ProposalResult[] = powerOfChoices.map((p, i) => ({ choice: proposal.choices[i], diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts index fd8c2f5e2e6c..8ddcc7468e99 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts @@ -2,6 +2,7 @@ import { PluginSnapshotRPC } from '../../messages' import type { VoteItem, ProposalIdentifier } from '../../types' import { useSuspense } from '../../../../utils/hooks/useSuspense' import { useProposal } from './useProposal' +import { sum } from 'lodash-unified' const cache = new Map] | [1, VoteItem[]] | [2, Error]>() export function votesRetry() { @@ -50,13 +51,11 @@ async function Suspender(identifier: ProposalIdentifier) { totalWeight: choices ? Array.isArray(v.choice) ? v.choice.length - : choices.reduce((acc, choice) => { - return acc + choice.weight - }, 0) + : sum(choices.map((choice) => choice.weight)) : undefined, address: v.voter, authorIpfsHash: v.id, - balance: scores.reduce((a, b) => a + (b[v.voter.toLowerCase()] ? b[v.voter.toLowerCase()] : 0), 0), + balance: sum(scores.map((score) => score[v.voter.toLowerCase()] ?? 0)), scores: strategies.map((_strategy, i) => scores[i][v.voter] || 0), strategySymbol: proposal.space.symbol ?? strategies[0].params.symbol, authorName: profileEntries[v.voter.toLowerCase()]?.name, diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts index aebec276a4e8..04220f26f898 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts @@ -75,7 +75,8 @@ export function useAllCommonPairs(tradeProvider: TradeProvider, currencyA?: Curr const filtered = new Map() for (const [state, pair] of allPairs as [PairState.EXISTS, Pair][]) { // filter out invalid pairs - if (!(state === PairState.EXISTS && pair)) continue + if (state !== PairState.EXISTS) continue + if (!pair) continue // filter out duplicated pairs const { address } = pair.liquidityToken if (filtered.has(address)) continue diff --git a/packages/mask/src/utils/getTextUILength.ts b/packages/mask/src/utils/getTextUILength.ts index 21263dbf1884..a4a255501ae3 100644 --- a/packages/mask/src/utils/getTextUILength.ts +++ b/packages/mask/src/utils/getTextUILength.ts @@ -1,6 +1,9 @@ +import { sum } from 'lodash-unified' + /* eslint @dimensiondev/unicode/specific-set: ["error", { "only": "code" }] */ + export function getTextUILength(text: string) { - return Array.from(text).reduce((acc, char) => acc + getCharUILength(char), 0) + return sum(Array.from(text).map(getCharUILength)) } export function sliceTextByUILength(text: string, len: number) { From 6b3d463da2264ec11f6c29ed89284e67e0006dd2 Mon Sep 17 00:00:00 2001 From: Septs Date: Tue, 17 May 2022 01:06:49 +0800 Subject: [PATCH 4/6] chore: no-array-reduce --- .../mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts index adfa9b8bd96c..7cc0c6238098 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts @@ -3,7 +3,7 @@ import { useAccount } from '@masknet/web3-shared-evm' import { PluginSnapshotRPC } from '../../messages' import type { ProposalIdentifier } from '../../types' import { useProposal } from './useProposal' -import { mapKeys } from 'lodash-unified' +import { find, sum } from 'lodash-unified' export function usePower(identifier: ProposalIdentifier) { const { payload: proposal } = useProposal(identifier.id) @@ -18,8 +18,6 @@ export function usePower(identifier: ProposalIdentifier) { identifier.space, proposal.strategies, ) - return scores - .map((score) => mapKeys(score, (_value, key) => key.toLowerCase()) as Record) - .map((record) => record[account.toLowerCase()] ?? 0) + return sum(scores.map((score) => find(score, (_, key) => key.toLowerCase() === account.toLowerCase()) ?? 0)) }, [account]) } From 1964e17e2543ebe477a6e6a7bc2a2b96cc1cbbf9 Mon Sep 17 00:00:00 2001 From: Septs Date: Tue, 17 May 2022 01:12:57 +0800 Subject: [PATCH 5/6] chore: no-array-reduce --- packages/mask/src/plugins/Trader/apis/balancer/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/mask/src/plugins/Trader/apis/balancer/index.ts b/packages/mask/src/plugins/Trader/apis/balancer/index.ts index 6fe5b10b8520..011191a2ab43 100644 --- a/packages/mask/src/plugins/Trader/apis/balancer/index.ts +++ b/packages/mask/src/plugins/Trader/apis/balancer/index.ts @@ -1,7 +1,6 @@ import { SOR } from '@balancer-labs/sor' import { JsonRpcProvider } from '@ethersproject/providers' import { ChainId, getRPCConstants, getTraderConstants, isSameAddress } from '@masknet/web3-shared-evm' -import { ZERO } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { first, memoize } from 'lodash-unified' import { currentChainIdSettings } from '../../../Wallet/settings' @@ -73,8 +72,7 @@ export async function getSwaps( // compose routes // learn more: https://github.com/balancer-labs/balancer-frontend/blob/develop/src/components/swap/Routing.vue - // eslint-disable-next-line unicorn/no-array-reduce - const totalSwapAmount = swaps.reduce((total, rawHops) => total.plus(first(rawHops)?.swapAmount || '0'), ZERO) + const totalSwapAmount = BigNumber.sum(...swaps.map((rawHops) => first(rawHops)?.swapAmount || '0')) const pools = sor.onChainCache.pools const routes = swaps.map((rawHops) => { From 5662e545242c99da84a0c41330f227f8f94f47b9 Mon Sep 17 00:00:00 2001 From: Septs Date: Tue, 17 May 2022 09:30:30 +0800 Subject: [PATCH 6/6] chore: no-array-reduce --- .../backup-format/src/utils/backupPreview.ts | 4 ++-- .../FindTruman/SNSAdaptor/OptionsCard.tsx | 4 ++-- .../FindTruman/SNSAdaptor/ResultCard.tsx | 4 ++-- .../src/plugins/PoolTogether/UI/Account.tsx | 19 ++++++++---------- .../Snapshot/SNSAdaptor/hooks/usePower.ts | 4 ++-- .../Snapshot/SNSAdaptor/hooks/useResults.ts | 20 +++++++++---------- .../Snapshot/SNSAdaptor/hooks/useVotes.ts | 6 +++--- 7 files changed, 28 insertions(+), 33 deletions(-) diff --git a/packages/backup-format/src/utils/backupPreview.ts b/packages/backup-format/src/utils/backupPreview.ts index 19c42f26438a..baeb83c4c208 100644 --- a/packages/backup-format/src/utils/backupPreview.ts +++ b/packages/backup-format/src/utils/backupPreview.ts @@ -1,5 +1,5 @@ import type { NormalizedBackup } from '@masknet/backup-format' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' export interface BackupPreview { personas: number @@ -21,7 +21,7 @@ export function getBackupPreviewInfo(json: NormalizedBackup.Data): BackupPreview return { personas: json.personas.size, - accounts: sum([...json.personas.values()].map((persona) => persona.linkedProfiles.size)), + accounts: sumBy([...json.personas.values()], (persona) => persona.linkedProfiles.size), posts: json.posts.size, contacts: json.profiles.size, relations: json.relations.length, diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx index 6344907fd75e..46a36cc3aa8e 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/OptionsCard.tsx @@ -7,7 +7,7 @@ import NoNftCard from './NoNftCard' import { FindTrumanContext } from '../context' import { BorderLinearProgress } from './ResultCard' import { ActionButtonPromise } from '../../../extension/options-page/DashboardComponents/ActionButton' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' const useOptionsStyles = makeStyles()((theme) => { return { @@ -93,7 +93,7 @@ export default function OptionsCard(props: OptionsViewProps) { const renderOptions = (userStatus: UserPollStatus) => { const showCount = !!userStatus.count - const total = sum((userStatus.count ?? []).map((status) => status.value)) + const total = sumBy(userStatus.count ?? [], (status) => status.value) return userStatus.options.map((option, index) => { const count = userStatus.count ? userStatus.count.find((e) => e.choice === index)?.value || 0 : 0 const percent = (total > 0 ? (count * 100) / total : 0).toFixed(2) diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx index 2c2aeb18d107..519ae4a753d8 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/ResultCard.tsx @@ -16,7 +16,7 @@ import { PostType } from '../types' import { useContext, useState } from 'react' import { FindTrumanContext } from '../context' import { makeStyles } from '@masknet/theme' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' export const BorderLinearProgress: any = styled(LinearProgress)(({ theme }) => ({ height: 10, @@ -50,7 +50,7 @@ export default function ResultCard(props: ResultViewProps) { const { t } = useContext(FindTrumanContext) - const total = result?.count ? sum(result.count.map((status) => status.value)) : 1 + const total = result?.count ? sumBy(result.count, (status) => status.value) : 1 const answer = result ? type === PostType.PuzzleResult diff --git a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx index 61598c08c583..013cdc5be9e5 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx @@ -8,7 +8,7 @@ import { COMMUNITY_URL } from '../constants' import { useAccountBalance } from '../hooks/useAccountBalances' import type { Pool } from '../types' import { AccountPool } from './AccountPool' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' const useStyles = makeStyles()((theme) => ({ root: { @@ -77,16 +77,13 @@ export function Account(props: AccountProps) { } const noZeroBalances = balances.filter((balance) => Number.parseInt(balance.account.ticketBalance, 10) !== 0) - const totalUsdBalance = sum( - noZeroBalances.map((balance) => { - const ticketBalance = Number.parseFloat( - formatBalance(balance.account.ticketBalance, Number.parseInt(balance.pool.tokens.ticket.decimals, 10)), - ) - const ticketUsdRate = balance.pool.tokens.ticket.usd - if (!ticketUsdRate) return 0 - return ticketBalance * ticketUsdRate - }), - ) + const totalUsdBalance = sumBy(noZeroBalances, (balance) => { + const decimals = Number.parseInt(balance.pool.tokens.ticket.decimals, 10) + const ticketBalance = Number.parseFloat(formatBalance(balance.account.ticketBalance, decimals)) + const ticketUsdRate = balance.pool.tokens.ticket.usd + if (!ticketUsdRate) return 0 + return ticketBalance * ticketUsdRate + }) return ( diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts index 7cc0c6238098..664a656d01fa 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/usePower.ts @@ -3,7 +3,7 @@ import { useAccount } from '@masknet/web3-shared-evm' import { PluginSnapshotRPC } from '../../messages' import type { ProposalIdentifier } from '../../types' import { useProposal } from './useProposal' -import { find, sum } from 'lodash-unified' +import { find, sumBy } from 'lodash-unified' export function usePower(identifier: ProposalIdentifier) { const { payload: proposal } = useProposal(identifier.id) @@ -18,6 +18,6 @@ export function usePower(identifier: ProposalIdentifier) { identifier.space, proposal.strategies, ) - return sum(scores.map((score) => find(score, (_, key) => key.toLowerCase() === account.toLowerCase()) ?? 0)) + return sumBy(scores, (score) => find(score, (_, key) => key.toLowerCase() === account.toLowerCase()) ?? 0) }, [account]) } diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts index bc701b576d2a..fdadf07e37e9 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useResults.ts @@ -2,7 +2,7 @@ import type { ProposalIdentifier, ProposalResult, VoteItem } from '../../types' import { useSuspense } from '../../../../utils/hooks/useSuspense' import { useProposal } from './useProposal' import { useVotes } from './useVotes' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' const cache = new Map< string, @@ -27,19 +27,17 @@ async function Suspender(identifier: ProposalIdentifier) { const { payload: votes } = useVotes(identifier) const strategies = proposal.strategies const powerOfChoices = proposal.choices.map((_choice, index) => - sum( - voteForChoice(votes, index).map((choice) => { - if (choice.choiceIndex) return choice.balance - const totalWeight = sum(choice.choices!.map((choice) => choice.weight)) - const weight = choice.choices!.find((v) => v.index === index + 1)?.weight ?? 0 - return (choice.balance * weight) / totalWeight - }), - ), + sumBy(voteForChoice(votes, index), (choice) => { + if (choice.choiceIndex) return choice.balance + const totalWeight = sumBy(choice.choices, (choice) => choice.weight) + const weight = choice.choices!.find((v) => v.index === index + 1)?.weight ?? 0 + return (choice.balance * weight) / totalWeight + }), ) const powerDetailOfChoices = proposal.choices.map((_choice, i) => - strategies.map((_strategy, index) => sum(voteForChoice(votes, i).map((vote) => vote.scores[index], 0))), + strategies.map((_strategy, index) => sumBy(voteForChoice(votes, i), (vote) => vote.scores[index])), ) - const totalPower = sum(votes.map((vote) => vote.balance)) + const totalPower = sumBy(votes, (vote) => vote.balance) const results: ProposalResult[] = powerOfChoices.map((p, i) => ({ choice: proposal.choices[i], diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts index 8ddcc7468e99..498e1f244f74 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/hooks/useVotes.ts @@ -2,7 +2,7 @@ import { PluginSnapshotRPC } from '../../messages' import type { VoteItem, ProposalIdentifier } from '../../types' import { useSuspense } from '../../../../utils/hooks/useSuspense' import { useProposal } from './useProposal' -import { sum } from 'lodash-unified' +import { sumBy } from 'lodash-unified' const cache = new Map] | [1, VoteItem[]] | [2, Error]>() export function votesRetry() { @@ -51,11 +51,11 @@ async function Suspender(identifier: ProposalIdentifier) { totalWeight: choices ? Array.isArray(v.choice) ? v.choice.length - : sum(choices.map((choice) => choice.weight)) + : sumBy(choices, (choice) => choice.weight) : undefined, address: v.voter, authorIpfsHash: v.id, - balance: sum(scores.map((score) => score[v.voter.toLowerCase()] ?? 0)), + balance: sumBy(scores, (score) => score[v.voter.toLowerCase()] ?? 0), scores: strategies.map((_strategy, i) => scores[i][v.voter] || 0), strategySymbol: proposal.space.symbol ?? strategies[0].params.symbol, authorName: profileEntries[v.voter.toLowerCase()]?.name,