Skip to content

Commit a88b07d

Browse files
authored
feat: mf-6673 lens v3 follow/unfollow (#12198)
* feat: mf-6673 lens v3 follow/unfollow * refactor: lens feeds migrate to lens v3 api * chore: lingui compile * fix: eslint --------- Co-authored-by: swkatmask <[email protected]>
1 parent 6d74669 commit a88b07d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1576
-3218
lines changed

Diff for: cspell.json

+2
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@
249249
"linkedin",
250250
"luma",
251251
"muln",
252+
"reposted",
253+
"reposts",
252254
"sepolia",
253255
"tanstack",
254256
"tiktok",

Diff for: packages/mask/popups/hooks/useSearchValue.ts

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
1-
import { useAsyncRetry } from 'react-use'
2-
import type { AsyncStateRetry } from 'react-use/lib/useAsyncRetry.js'
1+
import { useLensClient } from '@masknet/shared'
32
import { ECKeyIdentifier, NextIDPlatform } from '@masknet/shared-base'
4-
import { ENS, Lens } from '@masknet/web3-providers'
3+
import { ENS } from '@masknet/web3-providers'
4+
import { useQuery } from '@tanstack/react-query'
55

6-
export function useSearchValue(value: string, type?: NextIDPlatform): AsyncStateRetry<string> {
7-
return useAsyncRetry(async () => {
8-
if (!type) return ''
9-
if (value.length === 44) return new ECKeyIdentifier('secp256k1', value).publicKeyAsHex ?? value
10-
if (type === NextIDPlatform.Twitter) return value.replace(/^@/, '').toLowerCase()
6+
export function useSearchValue(value: string, type?: NextIDPlatform) {
7+
const lensClient = useLensClient()
8+
return useQuery({
9+
queryKey: ['search-value', value, type, !lensClient],
10+
queryFn: async () => {
11+
if (!type) return ''
12+
if (value.length === 44) return new ECKeyIdentifier('secp256k1', value).publicKeyAsHex ?? value
13+
if (type === NextIDPlatform.Twitter) return value.replace(/^@/, '').toLowerCase()
1114

12-
if (value.endsWith('.eth')) return (await ENS.lookup(value))?.toLowerCase()
15+
if (value.endsWith('.eth')) return (await ENS.lookup(value))?.toLowerCase()
1316

14-
if (value.endsWith('.lens')) return (await Lens.getProfileByHandle(value)).ownedBy.address?.toLowerCase()
17+
if (value.endsWith('.lens') && lensClient) {
18+
const account = await lensClient?.getAccountByHandle(value)
19+
return (account?.username?.ownedBy as string).toLowerCase()
20+
}
1521

16-
return value.toLowerCase()
17-
}, [value])
22+
return value.toLowerCase()
23+
},
24+
})
1825
}

Diff for: packages/mask/popups/pages/Friends/Home/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const Component = memo(function FriendsHome() {
2222
const friends = useMemo(() => data?.pages.flatMap((x) => x.friends) ?? EMPTY_LIST, [data])
2323
const [searchValue, setSearchValue] = useState('')
2424
const type = resolveNextIDPlatform(searchValue)
25-
const { loading: resolveLoading, value: keyword = '' } = useSearchValue(searchValue, type)
25+
const { isLoading: resolveLoading, data: keyword = '' } = useSearchValue(searchValue, type)
2626
const fuse = useMemo(() => {
2727
return new Fuse(records, {
2828
keys: ['profile.userId'],

Diff for: packages/mask/shared-ui/initialization/fetch.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const { fetch: original_fetch } = globalThis
88
function contentFetch(input: RequestInfo | URL, init?: RequestInit) {
99
const request = new Request(input, init)
1010

11-
if (canAccessAsContent(request.url)) {
11+
if (shouldAccessViaContent(request.url)) {
1212
if (
1313
navigator.userAgent.includes('Firefox') &&
1414
browser.runtime.getManifest().manifest_version === 2 &&
@@ -48,14 +48,15 @@ function fetchingTwitterResource(target: URL) {
4848

4949
function fetchingInsResource(target: URL) {
5050
// cspell:disable-next-line
51-
return location.origin.endsWith('instagram.com') && target.origin.match(/(fbcdn\.net|cdninstagram\.com)$/)
51+
if (isHostName(location, 'instagram.com') && target.origin.match(/(fbcdn\.net|cdninstagram\.com)$/)) return true
52+
return target.host === 'api.lens.xyz'
5253
}
5354

5455
function fetchingGoogleDriveResource(target: URL) {
5556
return target.origin === 'https://www.googleapis.com'
5657
}
5758

58-
function canAccessAsContent(url: string) {
59+
function shouldAccessViaContent(url: string) {
5960
const target = new URL(url, location.href)
6061
if (fetchingTwitterResource(target) || fetchingInsResource(target) || fetchingGoogleDriveResource(target))
6162
return true

Diff for: packages/plugins/RSS3/src/SiteAdaptor/SocialFeeds/useSocialFeeds.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { t } from '@lingui/core/macro'
22
import { timeout } from '@masknet/kit'
3+
import { useLensClient } from '@masknet/shared'
34
import { EMPTY_LIST, type PageIndicator } from '@masknet/shared-base'
45
import { useFireflyFarcasterAccounts, useFireflyLensAccounts } from '@masknet/web3-hooks-base'
5-
import { FireflyConfig, FireflyFarcaster, Lens } from '@masknet/web3-providers'
6+
import { FireflyConfig, FireflyFarcaster } from '@masknet/web3-providers'
67
import { skipToken, useInfiniteQuery, useQuery } from '@tanstack/react-query'
78
import { sortBy, uniq } from 'lodash-es'
89
import { useCallback } from 'react'
@@ -48,12 +49,14 @@ export function useSocialFeeds({ userId, address }: Options) {
4849
},
4950
})
5051

52+
const lensClient = useLensClient()
5153
const lensHandles = uniq(lensAccounts.map((x) => x.handle).concat(profiles?.lensHandles || []))
52-
const { data: lensIds = EMPTY_LIST } = useQuery({
53-
queryKey: ['lens', 'popup-list', lensHandles],
54+
const { data: accounts = EMPTY_LIST } = useQuery({
55+
queryKey: ['lens', 'popup-list', lensHandles, !lensClient],
5456
queryFn: async () => {
55-
const profiles = await Lens.getProfilesByHandles(lensHandles)
56-
return profiles.map((x) => x.id)
57+
if (!lensClient) return
58+
const profiles = await lensClient.getAccountsByHandles(lensHandles)
59+
return profiles?.map((x) => x.address) || EMPTY_LIST
5760
},
5861
})
5962
const {
@@ -65,9 +68,10 @@ export function useSocialFeeds({ userId, address }: Options) {
6568
hasNextPage: hasNextLensPage,
6669
isLoading: isLoadingLens,
6770
} = useInfiniteQuery({
68-
queryKey: ['social-feeds', 'lens', lensIds],
71+
enabled: !!lensClient,
72+
queryKey: ['social-feeds', 'lens', accounts, !lensClient],
6973
queryFn: async ({ pageParam }) => {
70-
return timeout(Lens.getPostsByProfileId(lensIds, pageParam), 30_000, t`Request timed out`)
74+
return timeout(lensClient!.getPostsByAccounts(accounts, pageParam), 30_000, t`Request timed out`)
7175
},
7276
initialPageParam: undefined as PageIndicator | undefined,
7377
getNextPageParam: (lastPage) => lastPage?.nextIndicator,

Diff for: packages/plugins/RSS3/src/SiteAdaptor/hooks/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
export * from './useAddressLabel.js'
22
export * from './useFeeds.js'
3-
export * from './usePublicationId.js'
43
export * from './useMarkdownStyles.js'

Diff for: packages/plugins/RSS3/src/SiteAdaptor/hooks/usePublicationId.ts

-12
This file was deleted.

Diff for: packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { Icons } from '@masknet/icons'
22
import type { Plugin } from '@masknet/plugin-infra'
3+
import { useDirtyDetectionDependency } from '@masknet/plugin-infra/dom'
34
import { makeStyles, ShadowRootPopper } from '@masknet/theme'
45
import { Link } from '@mui/material'
56
import { memo } from 'react'
6-
import { usePopoverControl } from './usePopoverControl.js'
7-
import { WarningCard } from './WarningCard.js'
7+
import { useCheckLink } from '../hooks/useCheckLink.js'
88
import { useDetectAddress } from '../hooks/useDetectAddress.js'
99
import { AddressTag } from './TextModifier.js'
10-
import { useCheckLink } from '../hooks/useCheckLink.js'
10+
import { usePopoverControl } from './usePopoverControl.js'
11+
import { WarningCard } from './WarningCard.js'
1112

1213
const useStyles = makeStyles()((theme) => ({
1314
link: {
@@ -37,10 +38,14 @@ export const LinkModifier = memo<PropsOf<Plugin.SiteAdaptor.Definition['LinkModi
3738
...props
3839
}) {
3940
const { classes } = useStyles()
40-
const { data } = useCheckLink(props.href, props.children)
41-
const { data: detected } = useDetectAddress(data?.address, data?.isScam === false)
41+
const { data, isLoading: isChecking } = useCheckLink(props.href, props.children)
42+
const { data: detected, isLoading: isDetecting } = useDetectAddress(data?.address, data?.isScam === false)
4243
const { open, anchorEl, iconRef, onMouseEnter, onMouseLeave } = usePopoverControl()
4344

45+
const pending = isChecking || (data?.isScam === false && isDetecting)
46+
const isDirty = !!(data?.isScam || detected?.isScam)
47+
useDirtyDetectionDependency(isDirty, pending, props.href)
48+
4449
if (!data?.isScam) {
4550
if (detected?.isScam) {
4651
return (

Diff for: packages/plugins/Web3Profile/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
}
1717
},
1818
"dependencies": {
19+
"@lens-protocol/client": "0.0.0-canary-20250408064617",
1920
"@masknet/icons": "workspace:^",
2021
"@masknet/plugin-infra": "workspace:^",
2122
"@masknet/shared": "workspace:^",

Diff for: packages/plugins/Web3Profile/src/SiteAdaptor/Web3ProfileGlobalInjection.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ export const Web3ProfileGlobalInjection = memo(function Web3ProfileGlobalInjecti
1919
const { open: lensOpen, closeDialog: closeLensDialog } = useRemoteControlledDialog(
2020
CrossIsolationMessages.events.followLensDialogEvent,
2121
(ev) => {
22-
if (!ev.open) {
23-
setHandle('')
24-
}
25-
setHandle(ev.handle)
22+
setHandle(ev.open ? ev.handle : '')
2623
},
2724
)
2825

0 commit comments

Comments
 (0)