@@ -12,14 +12,15 @@ import { NetworkPluginID } from '@masknet/shared-base'
12
12
import { ActionButton , makeStyles , useCustomSnackbar } from '@masknet/theme'
13
13
import { useChainContext , useFungibleTokenBalance , useNetworkContext , useWallet } from '@masknet/web3-hooks-base'
14
14
import { Lens } from '@masknet/web3-providers'
15
- import { FollowModuleType } from '@masknet/web3-providers/types'
16
- import { formatBalance , isLessThan , isSameAddress , resolveIPFS_URL , ZERO } from '@masknet/web3-shared-base'
15
+ import { FollowModuleType , type LensBaseAPI } from '@masknet/web3-providers/types'
16
+ import { formatBalance , isLessThan , isSameAddress , ZERO } from '@masknet/web3-shared-base'
17
17
import { ChainId , createERC20Token , formatAmount , ProviderType } from '@masknet/web3-shared-evm'
18
18
import { Avatar , Box , Button , buttonClasses , CircularProgress , DialogContent , Typography } from '@mui/material'
19
19
import { Translate , useI18N } from '../../locales/i18n_generated.js'
20
20
import { getLensterLink } from '../../utils.js'
21
21
import { useFollow } from '../hooks/Lens/useFollow.js'
22
22
import { useUnfollow } from '../hooks/Lens/useUnfollow.js'
23
+ import { useQuery } from '@tanstack/react-query'
23
24
import { HandlerDescription } from './HandlerDescription.js'
24
25
import { useConfettiExplosion } from '../hooks/ConfettiExplosion/index.js'
25
26
@@ -111,6 +112,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
111
112
const t = useI18N ( )
112
113
113
114
const wallet = useWallet ( )
115
+ const [ currentProfile , setCurrentProfile ] = useState < LensBaseAPI . Profile > ( )
114
116
const [ isFollowing , setIsFollowing ] = useState ( false )
115
117
const [ isHovering , setIsHovering ] = useState ( false )
116
118
const { classes } = useStyles ( { account : ! ! wallet } )
@@ -125,22 +127,35 @@ export function FollowLensDialog({ handle, onClose }: Props) {
125
127
const profile = await Lens . getProfileByHandle ( handle )
126
128
127
129
if ( ! profile ) return
128
- const isFollowing = await Lens . queryFollowStatus ( account , profile . id )
129
130
130
131
const defaultProfile = await Lens . queryDefaultProfileByAddress ( account )
131
132
132
133
const profiles = await Lens . queryProfilesByAddress ( account )
133
134
134
- setIsFollowing ( ! ! isFollowing )
135
+ setCurrentProfile ( ( prev ) => {
136
+ if ( ! prev ) return defaultProfile ?? first ( profiles )
137
+ return prev
138
+ } )
135
139
return {
136
140
profile,
137
- isSelf : isSameAddress ( profile . ownedBy , account ) ,
138
- isFollowing ,
141
+ isSelf : isSameAddress ( profile . ownedBy . address , account ) ,
142
+ profiles ,
139
143
defaultProfile : defaultProfile ?? first ( profiles ) ,
140
144
}
141
145
} , [ handle , open , account ] )
142
146
143
- const { profile, defaultProfile, isSelf } = value ?? { }
147
+ const { profile, defaultProfile, isSelf, profiles } = value ?? { }
148
+
149
+ const { isLoading } = useQuery ( {
150
+ queryKey : [ 'lens' , 'following-status' , currentProfile ?. id , value ?. profile . id ] ,
151
+ queryFn : async ( ) => {
152
+ if ( ! value ?. profile . id || ! currentProfile ) return false
153
+ const result = await Lens . queryFollowStatus ( currentProfile . id , value ?. profile . id )
154
+ setIsFollowing ( result )
155
+ return result
156
+ } ,
157
+ refetchOnWindowFocus : false ,
158
+ } )
144
159
145
160
const followModule = useMemo ( ( ) => {
146
161
if ( profile ?. followModule ?. type === FollowModuleType . ProfileFollowModule && defaultProfile ) {
@@ -152,7 +167,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
152
167
} else if ( profile ?. followModule ?. type === FollowModuleType . FeeFollowModule && profile . followModule . amount ) {
153
168
return {
154
169
feeFollowModule : {
155
- currency : profile . followModule . amount . asset . address ,
170
+ currency : profile . followModule . amount . asset . contract . address ,
156
171
value : profile . followModule . amount . value ,
157
172
} ,
158
173
}
@@ -163,7 +178,12 @@ export function FollowLensDialog({ handle, onClose }: Props) {
163
178
164
179
const approved = useMemo ( ( ) => {
165
180
if ( ! profile ?. followModule ?. amount ?. asset ) return { amount : ZERO . toFixed ( ) }
166
- const { address, name, symbol, decimals } = profile . followModule . amount . asset
181
+ const {
182
+ contract : { address } ,
183
+ name,
184
+ symbol,
185
+ decimals,
186
+ } = profile . followModule . amount . asset
167
187
const token = createERC20Token ( chainId , address , name , symbol , decimals )
168
188
const amount = formatAmount ( profile . followModule . amount . value , decimals )
169
189
@@ -177,8 +197,9 @@ export function FollowLensDialog({ handle, onClose }: Props) {
177
197
const { showConfettiExplosion, canvasRef } = useConfettiExplosion ( )
178
198
const { loading : followLoading , handleFollow } = useFollow (
179
199
profile ?. id ,
200
+ currentProfile ?. id ,
180
201
followModule ,
181
- ! ! defaultProfile ,
202
+ currentProfile ?. signless ,
182
203
( event : MouseEvent < HTMLElement > ) => {
183
204
showConfettiExplosion ( event . currentTarget . offsetWidth , event . currentTarget . offsetHeight )
184
205
setIsFollowing ( true )
@@ -187,6 +208,8 @@ export function FollowLensDialog({ handle, onClose }: Props) {
187
208
)
188
209
const { loading : unfollowLoading , handleUnfollow } = useUnfollow (
189
210
profile ?. id ,
211
+ currentProfile ?. id ,
212
+ currentProfile ?. signless ,
190
213
( event : MouseEvent < HTMLElement > ) => {
191
214
setIsFollowing ( false )
192
215
} ,
@@ -196,7 +219,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
196
219
197
220
const { data : feeTokenBalance , isLoading : getBalanceLoading } = useFungibleTokenBalance (
198
221
NetworkPluginID . PLUGIN_EVM ,
199
- profile ?. followModule ?. amount ?. asset . address ?? '' ,
222
+ profile ?. followModule ?. amount ?. asset . contract . address ?? '' ,
200
223
)
201
224
202
225
const handleClick = useCallback (
@@ -217,11 +240,13 @@ export function FollowLensDialog({ handle, onClose }: Props) {
217
240
const disabled = useMemo ( ( ) => {
218
241
if (
219
242
! account ||
243
+ ! currentProfile ||
220
244
! ! wallet ?. owner ||
221
245
pluginID !== NetworkPluginID . PLUGIN_EVM ||
222
246
providerType === ProviderType . Fortmatic ||
223
247
followLoading ||
224
248
unfollowLoading ||
249
+ profile ?. followModule ?. type === FollowModuleType . UnknownFollowModule ||
225
250
( profile ?. followModule ?. type === FollowModuleType . ProfileFollowModule && ! defaultProfile ) ||
226
251
( profile ?. followModule ?. type === FollowModuleType . FeeFollowModule &&
227
252
profile . followModule . amount &&
@@ -236,6 +261,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
236
261
237
262
return false
238
263
} , [
264
+ currentProfile ,
239
265
account ,
240
266
wallet ?. owner ,
241
267
chainId ,
@@ -249,6 +275,8 @@ export function FollowLensDialog({ handle, onClose }: Props) {
249
275
const buttonText = useMemo ( ( ) => {
250
276
if ( isFollowing ) {
251
277
return isHovering ? t . unfollow ( ) : t . following_action ( )
278
+ } else if ( profile ?. followModule ?. type === FollowModuleType . UnknownFollowModule ) {
279
+ return t . can_not_follow ( )
252
280
} else if ( profile ?. followModule ?. type === FollowModuleType . FeeFollowModule && profile . followModule . amount ) {
253
281
return t . follow_for_fees ( {
254
282
value : profile . followModule . amount . value ,
@@ -260,7 +288,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
260
288
} , [ isFollowing , isHovering , profile ] )
261
289
262
290
const tips = useMemo ( ( ) => {
263
- if ( isSelf && profile ) return t . edit_profile_tips ( { profile : profile . handle } )
291
+ if ( isSelf && profile ) return t . edit_profile_tips ( { profile : profile . handle . localName } )
264
292
if ( wallet ?. owner || pluginID !== NetworkPluginID . PLUGIN_EVM || providerType === ProviderType . Fortmatic )
265
293
return t . follow_wallet_tips ( )
266
294
else if ( profile ?. followModule ?. type === FollowModuleType . ProfileFollowModule && ! defaultProfile )
@@ -276,16 +304,16 @@ export function FollowLensDialog({ handle, onClose }: Props) {
276
304
)
277
305
return t . follow_with_charge_tips ( )
278
306
else if ( profile ?. followModule ?. type === FollowModuleType . RevertFollowModule ) return t . follow_with_revert_tips ( )
279
- else if ( ! defaultProfile ) {
280
- return t . follow_gas_tips ( )
307
+ else if ( ! currentProfile ) {
308
+ return t . follow_with_out_handle_tips ( )
281
309
}
282
310
return
283
- } , [ wallet ?. owner , chainId , profile , feeTokenBalance , pluginID , providerType , isSelf ] )
311
+ } , [ wallet ?. owner , chainId , profile , feeTokenBalance , pluginID , providerType , isSelf , currentProfile ] )
284
312
285
313
const avatar = useMemo ( ( ) => {
286
- if ( ! profile ?. picture ?. original ) return
287
- return resolveIPFS_URL ( profile ?. picture ?. original . url )
288
- } , [ profile ?. picture ?. original ] )
314
+ if ( ! profile ?. metadata ?. picture ?. optimized . uri ) return
315
+ return profile ?. metadata ?. picture . optimized . uri
316
+ } , [ profile ?. metadata ?. picture ?. optimized . uri ] )
289
317
290
318
return (
291
319
< InjectedDialog
@@ -304,24 +332,26 @@ export function FollowLensDialog({ handle, onClose }: Props) {
304
332
src = { avatar ?? new URL ( '../assets/Lens.png' , import . meta. url ) . toString ( ) }
305
333
sx = { { width : 64 , height : 64 } }
306
334
/>
307
- < Typography className = { classes . name } > { profile ?. name } </ Typography >
308
- < Typography className = { classes . handle } > @{ profile ?. handle } </ Typography >
335
+ < Typography className = { classes . name } >
336
+ { profile ?. metadata ?. displayName ?? profile ?. handle . localName }
337
+ </ Typography >
338
+ < Typography className = { classes . handle } > @{ profile ?. handle . localName } </ Typography >
309
339
< Typography className = { classes . followers } >
310
340
< Translate . followers
311
341
components = { { strong : < strong /> } }
312
- values = { { followers : String ( profile ?. stats ?. totalFollowers ?? '0' ) } }
342
+ values = { { followers : String ( profile ?. stats . followers ?? '0' ) } }
313
343
/>
314
344
< Translate . following
315
345
components = { { strong : < strong /> } }
316
- values = { { following : String ( profile ?. stats ?. totalFollowing ?? '0' ) } }
346
+ values = { { following : String ( profile ?. stats ?. following ?? '0' ) } }
317
347
/>
318
348
</ Typography >
319
349
< Box className = { classes . actions } >
320
350
{ isSelf ? (
321
351
< Button
322
352
variant = "roundedContained"
323
353
className = { classes . followAction }
324
- href = { profile ?. handle ? getLensterLink ( profile . handle ) : '#' }
354
+ href = { profile ?. handle ? getLensterLink ( profile . handle . localName ) : '#' }
325
355
target = "_blank"
326
356
rel = "noopener noreferrer"
327
357
endIcon = { < Icons . LinkOut size = { 18 } /> }
@@ -331,7 +361,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
331
361
) : (
332
362
< >
333
363
< EthereumERC20TokenApprovedBoundary
334
- spender = { value ?. profile . followModule ?. contractAddress }
364
+ spender = { value ?. profile . followModule ?. contract ?. address }
335
365
amount = { approved . amount }
336
366
token = { ! isFollowing ? approved . token : undefined }
337
367
showHelperToken = { false }
@@ -363,7 +393,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
363
393
variant = "roundedContained"
364
394
className = { classes . followAction }
365
395
disabled = { disabled }
366
- loading = { followLoading || unfollowLoading || loading }
396
+ loading = { followLoading || unfollowLoading || loading || isLoading }
367
397
onClick = { handleClick }
368
398
onMouseOver = { ( ) => setIsHovering ( true ) }
369
399
onMouseOut = { ( ) => setIsHovering ( false ) } >
@@ -374,12 +404,12 @@ export function FollowLensDialog({ handle, onClose }: Props) {
374
404
< Button
375
405
className = { classes . linkButton }
376
406
variant = "roundedOutlined"
377
- href = { profile ?. handle ? getLensterLink ( profile . handle ) : '#' }
407
+ href = { profile ?. handle ? getLensterLink ( profile . handle . localName ) : '#' }
378
408
target = "_blank"
379
409
rel = "noopener noreferrer"
380
410
endIcon = { < Icons . LinkOut size = { 18 } /> }
381
411
sx = { { cursor : 'pointer' } } >
382
- { t . lenster ( ) }
412
+ { t . hey ( ) }
383
413
</ Button >
384
414
</ >
385
415
) }
@@ -391,15 +421,11 @@ export function FollowLensDialog({ handle, onClose }: Props) {
391
421
expectedChainId = { ChainId . Matic }
392
422
ActionButtonProps = { { variant : 'roundedContained' } } >
393
423
{ tips ? < Typography className = { classes . tips } > { tips } </ Typography > : null }
424
+
394
425
< HandlerDescription
395
- profile = {
396
- defaultProfile
397
- ? {
398
- avatar : defaultProfile . picture ?. original ?. url ,
399
- handle : defaultProfile . handle ,
400
- }
401
- : undefined
402
- }
426
+ currentProfile = { currentProfile }
427
+ profiles = { profiles }
428
+ onChange = { ( profile ) => setCurrentProfile ( profile ) }
403
429
/>
404
430
</ WalletConnectedBoundary >
405
431
</ Box >
0 commit comments