Skip to content

Commit 19260e8

Browse files
authored
fix: nft redpacket issues (#12144)
* fix: mf-6643 disable report spam for nft picker in redpacket * fix: mf-6642 add custom nfts * fix: filter nfts * fixup! fix: mf-6642 add custom nfts
1 parent 875d1cd commit 19260e8

File tree

22 files changed

+195
-49
lines changed

22 files changed

+195
-49
lines changed

packages/plugins/RedPacket/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@masknet/web3-shared-evm": "workspace:^",
3434
"@masknet/web3-shared-solana": "workspace:^",
3535
"@masknet/web3-telemetry": "workspace:^",
36+
"@servie/events": "^3.0.0",
3637
"@solana/spl-token": "^0.4.9",
3738
"@solana/web3.js": "^1.75.0",
3839
"@tanstack/react-query": "^5.49.2",

packages/plugins/RedPacket/src/SiteAdaptor/components/RouterDialog.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useLayoutEffect, type ReactNode } from 'react'
88
import { matchPath, useLocation, useNavigate } from 'react-router-dom'
99
import { RoutePaths } from '../../constants.js'
1010
import { HistoryTabs, RedPacketTabs } from '../../types.js'
11+
import { addCollectibles } from '../emitter.js'
1112

1213
export function RouterDialog({
1314
pageMap,
@@ -52,6 +53,7 @@ export function RouterDialog({
5253
[RoutePaths.HistoryDetail]: <Trans>Claim Details</Trans>,
5354
[RoutePaths.NftHistory]: <Trans>History</Trans>,
5455
[RoutePaths.CustomCover]: <Trans>Add a Custom Cover</Trans>,
56+
[RoutePaths.SelectCollectibles]: <Trans>Selecting NFTs</Trans>,
5557
}
5658
const titleTailMap: Record<string, ReactNode> = {
5759
[RoutePaths.CreateTokenRedPacket]: (
@@ -71,6 +73,7 @@ export function RouterDialog({
7173
}}
7274
/>
7375
),
76+
[RoutePaths.SelectCollectibles]: <Icons.Plus onClick={addCollectibles} />,
7477
}
7578

7679
return (
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
import { Emitter } from '@servie/events'
12
import type { CompositionType } from '@masknet/plugin-infra/content-script'
23
import { CrossIsolationMessages } from '@masknet/shared-base'
34

45
export function openDialog(compositionType: CompositionType = 'timeline') {
56
CrossIsolationMessages.events.redpacketDialogEvent.sendToLocal({ open: true, compositionType })
67
}
8+
9+
export const emitter = new Emitter<{ add: [] }>()
10+
11+
export function addCollectibles() {
12+
emitter.emit('add')
13+
}

packages/plugins/RedPacket/src/SiteAdaptor/views/CreateNftRedPacket.tsx

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import { NFTCard } from '../components/NFTCard.js'
3232
import { useRedPacket } from '../contexts/RedPacketContext.js'
3333
import { useCreateNFTRedpacketGas } from '../hooks/useCreateNftRedpacketGas.js'
3434
import { useMyCollectionNfts } from '../hooks/useMyCollectionNfts.js'
35-
import { ConditionSettings } from '../components/ConditionSettings.js'
3635

3736
const useStyles = makeStyles()((theme) => {
3837
return {
@@ -43,20 +42,6 @@ const useStyles = makeStyles()((theme) => {
4342
gap: theme.spacing(2),
4443
paddingBottom: 88,
4544
},
46-
field: {
47-
display: 'flex',
48-
gap: 16,
49-
alignItems: 'center',
50-
},
51-
label: {
52-
fontSize: 14,
53-
fontWeight: 700,
54-
lineHeight: '18px',
55-
color: theme.palette.maskColor.second,
56-
},
57-
fieldValue: {
58-
marginLeft: 'auto',
59-
},
6045
approveAllTip: {
6146
color: '#FF5F5F',
6247
margin: theme.spacing(0, 0.5),
@@ -175,12 +160,6 @@ export function CreateNftRedPacket() {
175160
</Typography>
176161
: null}
177162
</Box>
178-
<Box className={classes.field}>
179-
<Typography className={classes.label}>
180-
<Trans>Claim Conditions</Trans>
181-
</Typography>
182-
<ConditionSettings className={classes.fieldValue} />
183-
</Box>
184163
{nativeTokenDetailed && nativeTokenPrice ?
185164
<SelectGasSettingsToolbar
186165
className={classes.toolbar}

packages/plugins/RedPacket/src/SiteAdaptor/views/SelectCollectibles.tsx

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { Trans } from '@lingui/react/macro'
2-
import { CollectionList, UserAssetsProvider } from '@masknet/shared'
2+
import { AddCollectiblesModal, CollectionList, UserAssetsProvider } from '@masknet/shared'
33
import { NetworkPluginID } from '@masknet/shared-base'
44
import { makeStyles } from '@masknet/theme'
55
import type { Web3Helper } from '@masknet/web3-helpers'
6-
import { useChainContext } from '@masknet/web3-hooks-base'
6+
import { useChainContext, useNetworkContext, useWeb3Connection, useWeb3Hub } from '@masknet/web3-hooks-base'
77
import { isSameAddress } from '@masknet/web3-shared-base'
88
import type { ChainId } from '@masknet/web3-shared-evm'
99
import { alpha, Box, Button, DialogActions } from '@mui/material'
10-
import { useCallback, useMemo, useState } from 'react'
10+
import { useCallback, useEffect, useMemo, useState } from 'react'
1111
import { useNavigate } from 'react-router-dom'
1212
import { NFT_DEFAULT_CHAINS, NFT_RED_PACKET_MAX_SHARES } from '../../constants.js'
1313
import { useRedPacket } from '../contexts/RedPacketContext.js'
14+
import { emitter } from '../emitter.js'
15+
import { compact, uniqBy } from 'lodash-es'
1416

1517
const useStyles = makeStyles()((theme) => ({
1618
container: {
@@ -40,8 +42,12 @@ const gridProps = {
4042
}
4143
export function SelectCollectibles() {
4244
const { classes } = useStyles()
43-
const { account, setChainId } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
45+
const { account, chainId, setChainId } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
46+
const [assetChainId, setAssetChainId] = useState<ChainId>()
4447
const navigate = useNavigate()
48+
const { pluginID } = useNetworkContext()
49+
const Web3 = useWeb3Connection(pluginID)
50+
const Hub = useWeb3Hub(pluginID)
4551
const { selectedNfts, setSelectedNfts, setCollection } = useRedPacket()
4652
const [pendingNfts, setPendingNfts] = useState<Web3Helper.NonFungibleAssetAll[]>(selectedNfts)
4753
const handleItemClick = useCallback((nft: Web3Helper.NonFungibleAssetAll) => {
@@ -61,6 +67,60 @@ export function SelectCollectibles() {
6167
const selectedSet = new Set(selectedNfts.map((x) => [x.chainId, x.address, x.tokenId].join(':').toLowerCase()))
6268
return pendingSet.difference(selectedSet).size === 0
6369
}, [pendingNfts, selectedNfts])
70+
71+
const [pendingTokenCount, setPendingTokenCount] = useState(0)
72+
const [tokens, setTokens] = useState<Web3Helper.NonFungibleAssetAll[]>([])
73+
const handleAddCollectibles = useCallback(async () => {
74+
const results = await AddCollectiblesModal.openAndWaitForClose({
75+
pluginID,
76+
chainId: assetChainId || chainId,
77+
account,
78+
})
79+
if (!results) return
80+
const [contract, tokenIds] = results
81+
const selectedChainId = contract.chainId || assetChainId || chainId
82+
const address = contract.address
83+
setPendingTokenCount((count) => count + tokenIds.length)
84+
const allSettled = await Promise.allSettled(
85+
tokenIds.map(async (tokenId) => {
86+
const [asset, token, isOwner] = await Promise.all([
87+
Hub.getNonFungibleAsset(address, tokenId, {
88+
chainId: selectedChainId,
89+
account,
90+
}),
91+
Web3.getNonFungibleToken(address, tokenId, undefined, {
92+
chainId: selectedChainId,
93+
}),
94+
Web3.getNonFungibleTokenOwnership(address, tokenId, account, undefined, {
95+
chainId: selectedChainId,
96+
}),
97+
])
98+
99+
if (!asset?.contract?.chainId || !token.chainId || token.contract?.chainId !== assetChainId) return
100+
if (!isOwner) return
101+
return { ...token, ...asset } as Web3Helper.NonFungibleAssetAll
102+
}),
103+
)
104+
105+
setPendingTokenCount((count) => Math.max(count - tokenIds.length, 0))
106+
const tokens = compact(allSettled.map((x) => (x.status === 'fulfilled' ? x.value : null)))
107+
if (!tokens.length) return
108+
setTokens((originalTokens) => {
109+
return uniqBy([...originalTokens, ...tokens], (x) => `${x.contract?.address}.${x.tokenId}`)
110+
})
111+
}, [pluginID, assetChainId, chainId, account])
112+
113+
const handleSelect = useCallback((assets: Web3Helper.NonFungibleAssetAll[]) => {
114+
setPendingNfts(assets.length > NFT_RED_PACKET_MAX_SHARES ? assets.slice(0, NFT_RED_PACKET_MAX_SHARES) : assets)
115+
}, [])
116+
117+
useEffect(() => {
118+
const unsubscribe = emitter.on('add', handleAddCollectibles)
119+
return () => {
120+
unsubscribe()
121+
}
122+
}, [handleAddCollectibles])
123+
64124
return (
65125
<Box className={classes.container}>
66126
<UserAssetsProvider
@@ -73,8 +133,18 @@ export function SelectCollectibles() {
73133
maxSelectionDescription={
74134
<Trans>The maximum number of NFTs to be sold in one collection lucky drop contract is 255.</Trans>
75135
}
76-
selectedAssets={pendingNfts}>
77-
<CollectionList height={564} gridProps={gridProps} disableWindowScroll onItemClick={handleItemClick} />
136+
selectedAssets={pendingNfts}
137+
disableReport>
138+
<CollectionList
139+
height={564}
140+
gridProps={gridProps}
141+
disableWindowScroll
142+
additionalAssets={tokens}
143+
pendingAdditionalAssetCount={pendingTokenCount}
144+
onItemClick={handleItemClick}
145+
onChainChange={setAssetChainId as (chainId?: Web3Helper.ChainIdAll) => void}
146+
onSelect={handleSelect}
147+
/>
78148
</UserAssetsProvider>
79149
<DialogActions className={classes.dialogActions}>
80150
<Button className={classes.cancel} fullWidth variant="outlined" onClick={() => navigate(-1)}>

packages/plugins/RedPacket/src/locale/en-US.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/plugins/RedPacket/src/locale/en-US.po

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/plugins/RedPacket/src/locale/ja-JP.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/plugins/RedPacket/src/locale/ja-JP.po

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/plugins/RedPacket/src/locale/ko-KR.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)