Skip to content

Commit e5ac023

Browse files
[Release] Hotfix 2.21.4 => 2.21.5 (patch) (#10235)
* chore: bump version 2.21.5 * fix: lens icon crash on conversation group (#10233) (#10245) * fix: post replacer (#10248) * chore: update lock file * refactor: injectPostReplacer * chore: disable PostReplacer * refactor: code style * fix: not more replacing promotion & collapsed posts * refactor: posts have a tag link will be replaced * fix: twitter requests need another new feature option (#10247) * fix: read of undefined (#10250) * refactor: do not replace post includes videos (#10251) --------- Co-authored-by: UncleBill <[email protected]>
1 parent 2a027e4 commit e5ac023

File tree

16 files changed

+85
-120
lines changed

16 files changed

+85
-120
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"yarn": ">=999.0.0",
99
"npm": ">=999.0.0"
1010
},
11-
"version": "2.21.4",
11+
"version": "2.21.5",
1212
"private": true,
1313
"license": "AGPL-3.0-or-later",
1414
"scripts": {

packages/mask/src/components/InjectedComponents/PostReplacer.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useEffect, useMemo, useState } from 'react'
2+
import { produce } from 'immer'
13
import {
24
type TransformationContext,
35
type TypedMessage,
@@ -11,13 +13,11 @@ import {
1113
} from '@masknet/typed-message'
1214
import { TypedMessageRender, useTransformedValue } from '@masknet/typed-message-react'
1315
import { makeStyles } from '@masknet/theme'
14-
import { useEffect, useMemo, useState } from 'react'
1516
import { usePostInfoDetails } from '@masknet/plugin-infra/content-script'
1617
import { TypedMessageRenderContext } from '../../../shared-ui/TypedMessageRender/context.js'
1718
import { useCurrentIdentity } from '../DataSource/useActivatedUI.js'
1819
import { activatedSocialNetworkUI } from '../../social-network/ui.js'
1920
import { MaskMessages } from '../../utils/messages.js'
20-
import { produce } from 'immer'
2121

2222
const useStyles = makeStyles()({
2323
root: {
@@ -26,8 +26,8 @@ const useStyles = makeStyles()({
2626
})
2727

2828
export interface PostReplacerProps {
29-
zip?: () => void
30-
unzip?: () => void
29+
zip: () => void
30+
unzip: () => void
3131
}
3232

3333
export function PostReplacer(props: PostReplacerProps) {
@@ -72,8 +72,8 @@ export function PostReplacer(props: PostReplacerProps) {
7272

7373
function Transformer({
7474
message,
75-
unzip,
7675
zip,
76+
unzip,
7777
}: {
7878
message: TypedMessage
7979
} & PostReplacerProps) {

packages/mask/src/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Mask Network",
3-
"version": "2.21.4",
3+
"version": "2.21.5",
44
"manifest_version": 2,
55
"permissions": ["storage", "downloads", "webNavigation", "activeTab"],
66
"optional_permissions": ["<all_urls>", "notifications", "clipboardRead"],

packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketNftInPost.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useEffect } from 'react'
2-
import { RedPacketRPC } from '../messages.js'
2+
import { NetworkPluginID } from '@masknet/shared-base'
3+
import { Web3ContextProvider } from '@masknet/web3-hooks-base'
34
import type { RedPacketNftJSONPayload } from '../types.js'
5+
import { RedPacketRPC } from '../messages.js'
46
import { RedPacketNft } from './RedPacketNft.js'
57
import { TransactionConfirmDialogProvider } from './context/TokenTransactionConfirmDialogContext.js'
6-
import { ChainContextProvider } from '@masknet/web3-hooks-base'
78

89
export interface RedPacketNftInPostProps {
910
payload: RedPacketNftJSONPayload
@@ -20,9 +21,9 @@ export function RedPacketNftInPost({ payload }: RedPacketNftInPostProps) {
2021
}, [payload])
2122
return (
2223
<TransactionConfirmDialogProvider>
23-
<ChainContextProvider value={{ chainId: payload.chainId }}>
24+
<Web3ContextProvider value={{ pluginID: NetworkPluginID.PLUGIN_EVM, chainId: payload.chainId }}>
2425
<RedPacketNft payload={payload} />
25-
</ChainContextProvider>
26+
</Web3ContextProvider>
2627
</TransactionConfirmDialogProvider>
2728
)
2829
}

packages/mask/src/social-network-adaptor/facebook.com/ui-provider.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ const facebookUI: SocialNetworkUI.Definition = {
201201
profileCover: injectFacebookProfileCover,
202202
openNFTAvatar: injectOpenNFTAvatarEditProfileButton,
203203
openNFTAvatarSettingDialog,
204-
enhancedPostRenderer: injectPostReplacerAtFacebook,
204+
postReplacer: injectPostReplacerAtFacebook,
205205
postInspector: injectPostInspectorFacebook,
206206
pageInspector: injectPageInspectorDefault(),
207207
setupWizard: createTaskStartSetupGuideDefault(),

packages/mask/src/social-network-adaptor/minds.com/ui-provider.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ const mindsUI: SocialNetworkUI.Definition = {
158158
profileCover: injectMindsProfileCover,
159159
pageInspector: injectPageInspectorDefault(),
160160
postInspector: injectPostInspectorAtMinds,
161-
enhancedPostRenderer: injectPostReplacerAtMinds,
161+
postReplacer: injectPostReplacerAtMinds,
162162
banner: injectBannerAtMinds,
163163
searchResult: injectSearchResultInspectorAtMinds,
164164
newPostComposition: {

packages/mask/src/social-network-adaptor/twitter.com/collecting/post.ts

-6
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,6 @@ function getTweetNode(node: HTMLElement) {
6060
return root || node.closest<HTMLDivElement>('article > div')
6161
}
6262
const shouldSkipDecrypt = (node: HTMLElement, tweetNode: HTMLElement) => {
63-
const isAdsNode = !!tweetNode.querySelector(
64-
// promotion icon
65-
'svg path[d$="996V8h7v7z"]',
66-
)
67-
if (isAdsNode) return true
68-
6963
const isCardNode = node.matches('[data-testid="card.wrapper"]')
7064
const hasTextNode = !!tweetNode.querySelector(
7165
[

packages/mask/src/social-network-adaptor/twitter.com/injection/Lens/injectLensOnConversation.tsx

+29-29
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
2-
import { createInjectHooksRenderer, Plugin, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script'
2+
import { Plugin, createInjectHooksRenderer, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script'
33
import { EnhanceableSite, ProfileIdentifier } from '@masknet/shared-base'
44
import { makeStyles } from '@masknet/theme'
5-
import { useMemo, useState } from 'react'
5+
import { memo, useMemo, useState } from 'react'
66
import { attachReactTreeWithContainer } from '../../../../utils/index.js'
77
import { startWatch } from '../../../../utils/watcher.js'
88
import { querySelectorAll } from '../../utils/selector.js'
@@ -11,31 +11,6 @@ const selector = () => {
1111
return querySelectorAll<HTMLElement>('[data-testid=conversation] div:not([tabindex]) div[dir] + div[dir]')
1212
}
1313

14-
/**
15-
* Inject on conversation, including both DM drawer and message page (/messages/xxx)
16-
*/
17-
export function injectLensOnConversation(signal: AbortSignal) {
18-
const watcher = new MutationObserverWatcher(selector())
19-
startWatch(watcher, signal)
20-
watcher.useForeach((node, _, proxy) => {
21-
const spans = node
22-
.closest('[data-testid=conversation]')
23-
?.querySelectorAll<HTMLElement>('[tabindex] [dir] span:not([data-testid=tweetText])')
24-
if (!spans) return
25-
const userId = [...spans].reduce((id, node) => {
26-
if (id) return id
27-
if (node.textContent?.match(/@\w/)) {
28-
return node.textContent.trim().slice(1)
29-
}
30-
return ''
31-
}, '')
32-
if (!userId) return
33-
attachReactTreeWithContainer(proxy.afterShadow, { signal, untilVisible: true }).render(
34-
<ConversationLensSlot userId={userId} />,
35-
)
36-
})
37-
}
38-
3914
const useStyles = makeStyles()((theme) => ({
4015
hide: {
4116
display: 'none',
@@ -67,7 +42,7 @@ const createRootElement = () => {
6742
return span
6843
}
6944

70-
function ConversationLensSlot({ userId }: Props) {
45+
const ConversationLensSlot = memo(function ConversationLensSlot({ userId }: Props) {
7146
const [disabled, setDisabled] = useState(true)
7247
const { classes, cx } = useStyles()
7348

@@ -78,7 +53,7 @@ function ConversationLensSlot({ userId }: Props) {
7853
undefined,
7954
createRootElement,
8055
)
81-
const identifier = ProfileIdentifier.of(EnhanceableSite.Twitter, userId).unwrap()
56+
const identifier = ProfileIdentifier.of(EnhanceableSite.Twitter, userId).unwrapOr(null)
8257
if (!identifier) return null
8358

8459
return (
@@ -89,4 +64,29 @@ function ConversationLensSlot({ userId }: Props) {
8964
if (!component) return null
9065

9166
return <span className={cx(classes.slot, disabled ? classes.hide : null)}>{component}</span>
67+
})
68+
69+
/**
70+
* Inject on conversation, including both DM drawer and message page (/messages/xxx)
71+
*/
72+
export function injectLensOnConversation(signal: AbortSignal) {
73+
const watcher = new MutationObserverWatcher(selector())
74+
startWatch(watcher, signal)
75+
watcher.useForeach((node, _, proxy) => {
76+
const spans = node
77+
.closest('[data-testid=conversation]')
78+
?.querySelectorAll<HTMLElement>('[tabindex] [dir] span:not([data-testid=tweetText])')
79+
if (!spans) return
80+
const userId = [...spans].reduce((id, node) => {
81+
if (id) return id
82+
if (node.textContent?.match(/@\w/)) {
83+
return node.textContent.trim().slice(1)
84+
}
85+
return ''
86+
}, '')
87+
if (!userId) return
88+
attachReactTreeWithContainer(proxy.afterShadow, { signal, untilVisible: true }).render(
89+
<ConversationLensSlot userId={userId} />,
90+
)
91+
})
9292
}

packages/mask/src/social-network-adaptor/twitter.com/injection/PostReplacer.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ function resolveLangNode(node: HTMLElement) {
88
}
99

1010
export function injectPostReplacerAtTwitter(signal: AbortSignal, current: PostInfo) {
11+
const isPromotionPost = !!current.rootNode?.querySelector('svg path[d$="996V8h7v7z"]')
12+
const isCollapsedPost = !!current.rootNode?.querySelector('[data-testid="tweet-text-show-more-link"]')
13+
if (isPromotionPost || isCollapsedPost) return
14+
15+
const hasVideo = !!current.rootNode?.closest('[data-testid="tweet"]')?.querySelector('video')
16+
if (hasVideo) return
17+
18+
const hasCashOrHashTag = !!current.rootNode?.querySelector(
19+
['a[role="link"][href*="cashtag_click"]', 'a[role="link"][href*="hashtag_click"]'].join(','),
20+
)
21+
if (!hasCashOrHashTag) return
22+
1123
return injectPostReplacer({
1224
zipPost(node) {
1325
if (node.destroyed) return

packages/mask/src/social-network-adaptor/twitter.com/ui-provider.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ const twitterUI: SocialNetworkUI.Definition = {
177177
profileTab: injectProfileTabAtTwitter,
178178
profileCover: injectProfileCover,
179179
profileTabContent: injectProfileTabContentAtTwitter,
180-
enhancedPostRenderer: injectPostReplacerAtTwitter,
180+
postReplacer: injectPostReplacerAtTwitter,
181181
pageInspector: injectPageInspectorDefault(),
182182
postInspector: injectPostInspectorAtTwitter,
183183
postActions: injectPostActionsAtTwitter,
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,37 @@
11
import { memo } from 'react'
2-
import { attachReactTreeWithContainer } from '../../../utils/shadow-root/renderInShadowRoot.js'
2+
import type { DOMProxy } from '@dimensiondev/holoflows-kit'
33
import { PostInfoProvider, type PostInfo } from '@masknet/plugin-infra/content-script'
4+
import { attachReactTreeWithContainer } from '../../../utils/shadow-root/renderInShadowRoot.js'
45
import { PostReplacer, type PostReplacerProps } from '../../../components/InjectedComponents/PostReplacer.js'
5-
import type { DOMProxy } from '@dimensiondev/holoflows-kit'
6-
import { noop } from 'lodash-es'
76

8-
export function injectPostReplacer(config: injectPostReplacerConfig = {}) {
7+
interface InjectPostReplacerConfig {
8+
zipPost(node: DOMProxy): void
9+
unzipPost(node: DOMProxy): void
10+
}
11+
12+
export function injectPostReplacer({ zipPost, unzipPost }: InjectPostReplacerConfig) {
913
const PostReplacerDefault = memo(function PostReplacerDefault(props: {
1014
zipPost: PostReplacerProps['zip']
1115
unZipPost: PostReplacerProps['unzip']
1216
}) {
1317
return <PostReplacer zip={props.zipPost} unzip={props.unZipPost} />
1418
})
1519

16-
const { zipPost, unzipPost } = config
17-
const zipPostF = zipPost || noop
18-
const unzipPostF = unzipPost || noop
1920
return function injectPostReplacer(current: PostInfo, signal: AbortSignal) {
20-
signal.addEventListener('abort', unzipPostF)
21+
signal.addEventListener('abort', unzipPost as () => void)
22+
2123
attachReactTreeWithContainer(current.rootElement.afterShadow, {
2224
key: 'post-replacer',
2325
untilVisible: true,
2426
signal,
2527
}).render(
2628
<PostInfoProvider post={current}>
2729
<PostReplacerDefault
28-
zipPost={() => zipPostF(current.rootElement)}
29-
unZipPost={() => unzipPostF(current.rootElement)}
30+
zipPost={() => zipPost(current.rootElement)}
31+
unZipPost={() => unzipPost(current.rootElement)}
3032
{...current}
3133
/>
3234
</PostInfoProvider>,
3335
)
3436
}
3537
}
36-
37-
interface injectPostReplacerConfig {
38-
zipPost?(node: DOMProxy): void
39-
unzipPost?(node: DOMProxy): void
40-
}

packages/mask/src/social-network/ui.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI.
272272
signal.addEventListener('abort', () => abort.abort())
273273
abortSignals.set(key, abort)
274274
const { signal: postSignal } = abort
275-
ui.injection.enhancedPostRenderer?.(postSignal, value)
275+
ui.injection.postReplacer?.(postSignal, value)
276276
ui.injection.postInspector?.(postSignal, value)
277277
ui.injection.postActions?.(postSignal, value)
278278
ui.injection.commentComposition?.compositionBox(postSignal, value)

packages/plugins/Web3Profile/src/SNSAdaptor/Web3ProfileGlobalInjection.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { memo, useEffect, useState } from 'react'
22
import { SNSAdaptorContext } from '@masknet/plugin-infra/content-script'
3-
import { CrossIsolationMessages } from '@masknet/shared-base'
3+
import { Sentry } from '@masknet/web3-telemetry'
44
import { ChainId } from '@masknet/web3-shared-evm'
55
import { useRemoteControlledDialog } from '@masknet/shared-base-ui'
6-
import { ChainContextProvider } from '@masknet/web3-hooks-base'
7-
import { Sentry } from '@masknet/web3-telemetry'
6+
import { CrossIsolationMessages, NetworkPluginID } from '@masknet/shared-base'
7+
import { Web3ContextProvider } from '@masknet/web3-hooks-base'
88
import { EventType, EventID } from '@masknet/web3-telemetry/types'
9-
import { FollowLensDialog } from './components/FollowLensDialog.js'
109
import { LensPopup } from './components/LensPopup.js'
10+
import { FollowLensDialog } from './components/FollowLensDialog.js'
1111
import { Web3ProfileDialog } from './components/Web3ProfileDialog.js'
1212
import { context } from './context.js'
1313

@@ -40,9 +40,9 @@ export const Web3ProfileGlobalInjection = memo(function Web3ProfileGlobalInjecti
4040
{profileOpen ? <Web3ProfileDialog open onClose={() => setProfileOpen(false)} /> : null}
4141

4242
{lensOpen && handle ? (
43-
<ChainContextProvider value={{ chainId: ChainId.Matic }}>
43+
<Web3ContextProvider value={{ pluginID: NetworkPluginID.PLUGIN_EVM, chainId: ChainId.Matic }}>
4444
<FollowLensDialog handle={handle} onClose={closeLensDialog} />
45-
</ChainContextProvider>
45+
</Web3ContextProvider>
4646
) : null}
4747

4848
<LensPopup />

packages/types/src/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export namespace SocialNetworkUI {
8787
/** Inject the UI that used to open the composition UI */
8888
newPostComposition?: NewPostComposition
8989
commentComposition?: CommentComposition
90-
enhancedPostRenderer?(signal: AbortSignal, current: PostInfo): void
90+
/** Inject a replacer of the original post */
91+
postReplacer?(signal: AbortSignal, current: PostInfo): void
9192
/** Display the additional content (decrypted, plugin, ...) below the post */
9293
postInspector?(signal: AbortSignal, current: PostInfo): void
9394
/** Add custom actions buttons to the post */

packages/web3-providers/src/Twitter/apis/getUserViaWebAPI.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const features = {
1818
highlights_tweets_tab_ui_enabled: false,
1919
hidden_profile_likes_enabled: false,
2020
hidden_profile_subscriptions_enabled: false,
21+
subscriptions_verification_info_is_identity_verified_enabled: false,
2122
}
2223

2324
async function createRequest(screenName: string) {

0 commit comments

Comments
 (0)