Skip to content

Commit 6c55180

Browse files
authored
fix(lens): mf-6729 update lens follow logic (#12252)
1 parent 3c0f335 commit 6c55180

File tree

12 files changed

+112
-85
lines changed

12 files changed

+112
-85
lines changed

packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
setMyLensAccountAddress,
88
useAvailableLensAccounts,
99
useLensClient,
10-
useMyLensAccountAddress,
10+
useMyLensAccount,
1111
WalletConnectedBoundary,
1212
} from '@masknet/shared'
1313
import { NetworkPluginID } from '@masknet/shared-base'
@@ -119,7 +119,8 @@ export function FollowLensDialog({ handle, onClose }: Props) {
119119

120120
const { showSnackbar } = useCustomSnackbar()
121121
const lensClient = useLensClient()
122-
const myLensAccount = useMyLensAccountAddress(true)
122+
const myLensAccount = useMyLensAccount()
123+
const myLensAddress = myLensAccount?.account.address
123124

124125
const { data: lensAccount, isLoading } = useQuery({
125126
enabled: !!handle && !!open,
@@ -133,13 +134,15 @@ export function FollowLensDialog({ handle, onClose }: Props) {
133134
const { data: accounts } = useAvailableLensAccounts()
134135
const isSelf = isSameAddress(lensAccount?.username?.ownedBy as string, walletAccount)
135136

136-
const currentAccount = accounts?.find((p) => isSameAddress(p.account.address, myLensAccount)) || first(accounts)
137-
const targetAccountAddress: EvmAddress | undefined = lensAccount?.address
137+
const currentAccount = accounts?.find((p) => isSameAddress(p.account.address, myLensAddress)) || first(accounts)
138+
const targetLensAddress: EvmAddress | undefined = lensAccount?.address
138139
const { isPending, data: isFollowing } = useQuery({
139-
queryKey: ['lens', 'following-status', myLensAccount, targetAccountAddress, !lensClient],
140+
queryKey: ['lens', 'following-status', myLensAddress, targetLensAddress, !lensClient],
140141
queryFn: async () => {
141-
if (!targetAccountAddress || !myLensAccount || !lensClient) return false
142-
const res = await lensClient.getFollowStatus([{ account: targetAccountAddress, follower: myLensAccount }])
142+
if (!targetLensAddress || !myLensAddress || !lensClient) return false
143+
const res = await lensClient.getFollowStatus([
144+
{ account: targetLensAddress, follower: myLensAddress as EvmAddress },
145+
])
143146
const status = res[0].isFollowing
144147
return status.onChain
145148
},
@@ -154,14 +157,14 @@ export function FollowLensDialog({ handle, onClose }: Props) {
154157
accountAddress: lensAccount?.address,
155158
onSuccess: (width: number, height: number) => {
156159
showConfettiExplosion(width, height)
157-
updateFollowingStatus(myLensAccount, targetAccountAddress, true)
160+
updateFollowingStatus(myLensAddress, targetLensAddress, true)
158161
},
159-
onFailed: () => updateFollowingStatus(myLensAccount, targetAccountAddress, false),
162+
onFailed: () => updateFollowingStatus(myLensAddress, targetLensAddress, false),
160163
})
161164
const { loading: unfollowLoading, handleUnfollow } = useUnfollow({
162165
accountAddress: lensAccount?.address as string,
163-
onSuccess: () => updateFollowingStatus(myLensAccount, targetAccountAddress, false),
164-
onFailed: () => updateFollowingStatus(myLensAccount, targetAccountAddress, true),
166+
onSuccess: () => updateFollowingStatus(myLensAddress, targetLensAddress, false),
167+
onFailed: () => updateFollowingStatus(myLensAddress, targetLensAddress, true),
165168
})
166169
// #endregion
167170

@@ -217,9 +220,12 @@ export function FollowLensDialog({ handle, onClose }: Props) {
217220

218221
const avatar = lensAccount?.metadata?.picture
219222

220-
const handleProfileChange = useCallback((profile: Account) => {
221-
setMyLensAccountAddress(profile.address)
222-
}, [])
223+
const handleProfileChange = useCallback(
224+
(profile: Account) => {
225+
setMyLensAccountAddress(walletAccount, profile.address)
226+
},
227+
[walletAccount],
228+
)
223229

224230
const loading = followLoading || unfollowLoading || isLoading || isPending
225231

packages/plugins/Web3Profile/src/SiteAdaptor/components/ProfilePopup.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,12 @@ export const ProfilePopup = memo<ProfilePopupProps>(function ProfilePopup({
159159
horizontal: 'right',
160160
}}>
161161
<List disablePadding className={classes.list}>
162-
{availableAccounts.map((available) => {
163-
const account = available.account
162+
{availableAccounts.map(({ account, __typename: accountType }) => {
164163
const avatar = LensV3.getAccountAvatar(account)
165164
const name = account.metadata?.name || account.username?.localName
166165
const ownerAddress: EvmAddress = account.username?.ownedBy
167166
const accountId = account.username?.id
168-
const disabled =
169-
(currentAccountId && currentAccountId === accountId) ||
170-
available.__typename !== 'AccountManaged'
167+
const disabled = accountId === currentAccountId
171168
return (
172169
<ListItemButton
173170
className={cx(classes.item, { [classes.disabled]: disabled })}
@@ -196,7 +193,7 @@ export const ProfilePopup = memo<ProfilePopupProps>(function ProfilePopup({
196193
<Typography component="div" className={classes.address}>
197194
{formatEthereumAddress(ownerAddress, 4)}
198195
</Typography>
199-
{available.__typename === 'AccountManaged' ?
196+
{accountType === 'AccountManaged' ?
200197
<Typography component="span" className={classes.managedTag}>
201198
Managed
202199
</Typography>

packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { evmAddress } from '@lens-protocol/client'
22
import { Trans } from '@lingui/react/macro'
33
import { Icons } from '@masknet/icons'
4-
import { Image, useLensClient, useMyLensAccountAddress } from '@masknet/shared'
4+
import { Image, useLensClient, useMyLensAccount } from '@masknet/shared'
55
import { CrossIsolationMessages, EMPTY_LIST } from '@masknet/shared-base'
66
import { ActionButton, makeStyles } from '@masknet/theme'
77
import { useChainContext } from '@masknet/web3-hooks-base'
@@ -80,16 +80,17 @@ interface Props {
8080

8181
export const LensList = memo(function LensList({ accounts }: Props) {
8282
const lensV3 = useLensClient()
83-
const myLensAccount = useMyLensAccountAddress()
83+
const myLensAccount = useMyLensAccount()
84+
const myLensAddress = myLensAccount?.account.address
8485

8586
const { data = accounts, isPending } = useQuery({
86-
queryKey: ['lens', 'popup-list', myLensAccount, accounts.map((x) => x.handle).join('')],
87+
queryKey: ['lens', 'popup-list', myLensAddress, accounts.map((x) => x.handle).join('')],
8788
queryFn: async () => {
8889
if (!accounts.length) return EMPTY_LIST
8990
if (!lensV3) return accounts
9091

9192
const nativeAccounts = await lensV3.getAccountsByHandles(accounts.map((x) => x.handle))
92-
if (!myLensAccount && nativeAccounts?.length)
93+
if (!myLensAddress && nativeAccounts?.length)
9394
return compact(
9495
nativeAccounts.map((nativeAccount) => {
9596
const target = accounts.find(
@@ -106,8 +107,8 @@ export const LensList = memo(function LensList({ accounts }: Props) {
106107

107108
if (!nativeAccounts?.length) return accounts
108109
const followStatus = await lensV3.getFollowStatus(
109-
(myLensAccount ? nativeAccounts || [] : []).map((x) => ({
110-
follower: evmAddress(myLensAccount!),
110+
(myLensAddress ? nativeAccounts || [] : []).map((x) => ({
111+
follower: evmAddress(myLensAddress!),
111112
account: evmAddress(x.address),
112113
})),
113114
)

packages/plugins/Web3Profile/src/SiteAdaptor/hooks/Lens/useFollow.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type EvmAddress } from '@lens-protocol/client'
22
import { Trans, useLingui } from '@lingui/react/macro'
3-
import { useLensClient, useMyLensAccountAddress } from '@masknet/shared'
3+
import { useLensClient, useMyLensAccount } from '@masknet/shared'
44
import type { NetworkPluginID } from '@masknet/shared-base'
55
import { useCustomSnackbar, type ShowSnackbarOptions, type SnackbarKey, type SnackbarMessage } from '@masknet/theme'
66
import { useChainContext } from '@masknet/web3-hooks-base'
@@ -32,15 +32,17 @@ export function useFollow({ accountAddress, onSuccess, onFailed }: FollowOptions
3232
[showSnackbar, closeSnackbar],
3333
)
3434

35-
const myLensAccount = useMyLensAccountAddress()
35+
const myLensAccount = useMyLensAccount()
3636
const lensClient = useLensClient()
3737

3838
const handleFollow = useCallback(
3939
async (event: React.MouseEvent<HTMLButtonElement>) => {
4040
try {
4141
setLoading(true)
4242
if (!accountAddress || chainId !== ChainId.Polygon) return
43-
if (!lensClient || !myLensAccount) return
43+
if (!lensClient) throw new Error('No lens client')
44+
if (!myLensAccount) throw new Error('No lens account')
45+
4446
await lensClient.login(myLensAccount)
4547
const res = await lensClient.follow(accountAddress)
4648
if (res.isErr()) {

packages/plugins/Web3Profile/src/SiteAdaptor/hooks/Lens/useUnfollow.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useLingui } from '@lingui/react/macro'
2-
import { useLensClient, useMyLensAccountAddress } from '@masknet/shared'
2+
import { useLensClient, useMyLensAccount } from '@masknet/shared'
33
import type { NetworkPluginID } from '@masknet/shared-base'
44
import { useCustomSnackbar, type ShowSnackbarOptions, type SnackbarKey, type SnackbarMessage } from '@masknet/theme'
55
import { useChainContext } from '@masknet/web3-hooks-base'
@@ -31,7 +31,7 @@ export function useUnfollow({ accountAddress, onSuccess, onFailed }: UnfollowOpt
3131
[showSnackbar, closeSnackbar],
3232
)
3333

34-
const myLensAccount = useMyLensAccountAddress()
34+
const myLensAccount = useMyLensAccount()
3535
const lensClient = useLensClient()
3636
const handleUnfollow = useCallback(async () => {
3737
try {

packages/shared-base/src/KVStorage/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ export const PersistentStorages = {
4545
debugging: boolean
4646
/** @deprecated use lastLensAccount instead */
4747
latestLensProfile: string
48-
/** lens account address */
49-
lastLensAccount: string
48+
/** lens account address, distinct by wallet address */
49+
lastLensAccountMap: Record<string, string>
5050
backupConfig: BackupConfig
51-
}>('settings', {
51+
}>('settings@v1', {
5252
debugging: false,
5353
latestLensProfile: '',
54-
lastLensAccount: '',
54+
lastLensAccountMap: {},
5555
backupConfig: {
5656
backupPassword: '',
5757
email: '',

packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import { Icons } from '@masknet/icons'
22
// import { CopyButton, Image } from '@masknet/shared'
3+
import { evmAddress } from '@lens-protocol/client'
4+
import { Trans } from '@lingui/react/macro'
35
import { CrossIsolationMessages, NextIDPlatform, type BindingProof } from '@masknet/shared-base'
46
import { openWindow } from '@masknet/shared-base-ui'
57
import { ActionButton, MaskColors, makeStyles } from '@masknet/theme'
68
import { useChainContext, useWeb3Utils } from '@masknet/web3-hooks-base'
79
import { ENS, EVMWeb3, LensV3 } from '@masknet/web3-providers'
810
import { isSameAddress, resolveNextIDPlatformLink } from '@masknet/web3-shared-base'
911
import { MenuItem, Typography } from '@mui/material'
12+
import { useQuery } from '@tanstack/react-query'
1013
import { memo } from 'react'
1114
import { useAsync } from 'react-use'
12-
import { SocialTooltip } from './SocialTooltip.js'
13-
import { resolveNextIDPlatformIcon } from './utils.js'
14-
import { Trans } from '@lingui/react/macro'
15-
import { useMyLensAccountAddress } from '../../../hooks/index.js'
15+
import { useMyLensAccount } from '../../../hooks/index.js'
1616
import { CopyButton } from '../CopyButton/index.js'
1717
import { Image } from '../Image/index.js'
18-
import { useQuery } from '@tanstack/react-query'
19-
import { evmAddress } from '@lens-protocol/client'
18+
import { SocialTooltip } from './SocialTooltip.js'
19+
import { resolveNextIDPlatformIcon } from './utils.js'
2020

2121
const useStyles = makeStyles()((theme) => ({
2222
listItem: {
@@ -159,7 +159,8 @@ export function SocialAccountListItem({
159159
const { classes, cx } = useStyles()
160160
const Utils = useWeb3Utils()
161161

162-
const myAccountAddress = useMyLensAccountAddress()
162+
const myLensAccount = useMyLensAccount()
163+
const myAccountAddress = myLensAccount?.account.address
163164
const { data: statusData, isLoading } = useQuery({
164165
queryKey: ['lens', 'follow', platform, identity, account, myAccountAddress],
165166
queryFn: async () => {

packages/shared/src/hooks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export * from './useGasCurrencyMenu.js'
88
export * from './useIsImageURL.js'
99
export * from './useLensClient.js'
1010
export * from './useMenu.js'
11-
export * from './useMyLensAccountAddress.js'
11+
export * from './useMyLensAccount.js'
1212
export * from './useOpenApplicationSettings.js'
1313
export * from './useOpenShareTxDialog.js'
1414
export * from './usePageTab.js'

packages/shared/src/hooks/useAvailableLensAccounts.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useChainContext } from '@masknet/web3-hooks-base'
44
import { useQuery } from '@tanstack/react-query'
55
import { useLensClient } from './useLensClient.js'
66

7-
export function useAvailableLensAccounts(isManaged?: boolean) {
7+
export function useAvailableLensAccounts() {
88
const { account: walletAccount } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
99
const lensClient = useLensClient()
1010

@@ -15,11 +15,5 @@ export function useAvailableLensAccounts(isManaged?: boolean) {
1515
const accounts = await lensClient.getAvailableAccounts(evmAddress(walletAccount))
1616
return accounts
1717
},
18-
select(data) {
19-
if (isManaged === undefined || !data) return data
20-
return data.filter((account) =>
21-
isManaged ? account.__typename === 'AccountManaged' : account.__typename === 'AccountOwned',
22-
)
23-
},
2418
})
2519
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { type NetworkPluginID, PersistentStorages } from '@masknet/shared-base'
2+
import { isSameAddress } from '@masknet/web3-shared-base'
3+
import { useMemo } from 'react'
4+
import { useSubscription } from 'use-subscription'
5+
import { useAvailableLensAccounts } from './useAvailableLensAccounts.js'
6+
import { first } from 'lodash-es'
7+
import { useChainContext } from '@masknet/web3-hooks-base'
8+
9+
export function useMyLensAccount() {
10+
const { account: walletAccount } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
11+
const lastLensAccountMap = useSubscription(PersistentStorages.Settings.storage.lastLensAccountMap.subscription)
12+
const { data: lensAccounts } = useAvailableLensAccounts()
13+
14+
const lastLensAccount = lastLensAccountMap[walletAccount.toLowerCase()]
15+
return useMemo(() => {
16+
if (!lensAccounts?.length) return
17+
// Make sure lastLensAccount is in lensAccounts
18+
const lensAccount =
19+
lastLensAccount ?
20+
lensAccounts.find((x) => isSameAddress(x.account.address, lastLensAccount))
21+
: first(lensAccounts)
22+
return lensAccount
23+
}, [lastLensAccount, lensAccounts])
24+
}
25+
26+
export function setMyLensAccountAddress(walletAddress: string, address: string) {
27+
const prev = PersistentStorages.Settings.storage.lastLensAccountMap.value
28+
const key = walletAddress.toLowerCase()
29+
if (isSameAddress(prev[key], address)) return
30+
31+
PersistentStorages.Settings.storage.lastLensAccountMap.setValue({
32+
...prev,
33+
[walletAddress.toLowerCase()]: address,
34+
})
35+
}

0 commit comments

Comments
 (0)