Skip to content

Commit

Permalink
[Release] Hotfix 2.21.4 => 2.21.5 (patch) (#10235)
Browse files Browse the repository at this point in the history
* 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 <billbill290@gmail.com>
  • Loading branch information
guanbinrui and UncleBill committed Aug 2, 2023
1 parent 2a027e4 commit e5ac023
Show file tree
Hide file tree
Showing 16 changed files with 85 additions and 120 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"yarn": ">=999.0.0",
"npm": ">=999.0.0"
},
"version": "2.21.4",
"version": "2.21.5",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
Expand Down
10 changes: 5 additions & 5 deletions packages/mask/src/components/InjectedComponents/PostReplacer.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useEffect, useMemo, useState } from 'react'
import { produce } from 'immer'
import {
type TransformationContext,
type TypedMessage,
Expand All @@ -11,13 +13,11 @@ import {
} from '@masknet/typed-message'
import { TypedMessageRender, useTransformedValue } from '@masknet/typed-message-react'
import { makeStyles } from '@masknet/theme'
import { useEffect, useMemo, useState } from 'react'
import { usePostInfoDetails } from '@masknet/plugin-infra/content-script'
import { TypedMessageRenderContext } from '../../../shared-ui/TypedMessageRender/context.js'
import { useCurrentIdentity } from '../DataSource/useActivatedUI.js'
import { activatedSocialNetworkUI } from '../../social-network/ui.js'
import { MaskMessages } from '../../utils/messages.js'
import { produce } from 'immer'

const useStyles = makeStyles()({
root: {
Expand All @@ -26,8 +26,8 @@ const useStyles = makeStyles()({
})

export interface PostReplacerProps {
zip?: () => void
unzip?: () => void
zip: () => void
unzip: () => void
}

export function PostReplacer(props: PostReplacerProps) {
Expand Down Expand Up @@ -72,8 +72,8 @@ export function PostReplacer(props: PostReplacerProps) {

function Transformer({
message,
unzip,
zip,
unzip,
}: {
message: TypedMessage
} & PostReplacerProps) {
Expand Down
2 changes: 1 addition & 1 deletion packages/mask/src/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Mask Network",
"version": "2.21.4",
"version": "2.21.5",
"manifest_version": 2,
"permissions": ["storage", "downloads", "webNavigation", "activeTab"],
"optional_permissions": ["<all_urls>", "notifications", "clipboardRead"],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useEffect } from 'react'
import { RedPacketRPC } from '../messages.js'
import { NetworkPluginID } from '@masknet/shared-base'
import { Web3ContextProvider } from '@masknet/web3-hooks-base'
import type { RedPacketNftJSONPayload } from '../types.js'
import { RedPacketRPC } from '../messages.js'
import { RedPacketNft } from './RedPacketNft.js'
import { TransactionConfirmDialogProvider } from './context/TokenTransactionConfirmDialogContext.js'
import { ChainContextProvider } from '@masknet/web3-hooks-base'

export interface RedPacketNftInPostProps {
payload: RedPacketNftJSONPayload
Expand All @@ -20,9 +21,9 @@ export function RedPacketNftInPost({ payload }: RedPacketNftInPostProps) {
}, [payload])
return (
<TransactionConfirmDialogProvider>
<ChainContextProvider value={{ chainId: payload.chainId }}>
<Web3ContextProvider value={{ pluginID: NetworkPluginID.PLUGIN_EVM, chainId: payload.chainId }}>
<RedPacketNft payload={payload} />
</ChainContextProvider>
</Web3ContextProvider>
</TransactionConfirmDialogProvider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ const facebookUI: SocialNetworkUI.Definition = {
profileCover: injectFacebookProfileCover,
openNFTAvatar: injectOpenNFTAvatarEditProfileButton,
openNFTAvatarSettingDialog,
enhancedPostRenderer: injectPostReplacerAtFacebook,
postReplacer: injectPostReplacerAtFacebook,
postInspector: injectPostInspectorFacebook,
pageInspector: injectPageInspectorDefault(),
setupWizard: createTaskStartSetupGuideDefault(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const mindsUI: SocialNetworkUI.Definition = {
profileCover: injectMindsProfileCover,
pageInspector: injectPageInspectorDefault(),
postInspector: injectPostInspectorAtMinds,
enhancedPostRenderer: injectPostReplacerAtMinds,
postReplacer: injectPostReplacerAtMinds,
banner: injectBannerAtMinds,
searchResult: injectSearchResultInspectorAtMinds,
newPostComposition: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ function getTweetNode(node: HTMLElement) {
return root || node.closest<HTMLDivElement>('article > div')
}
const shouldSkipDecrypt = (node: HTMLElement, tweetNode: HTMLElement) => {
const isAdsNode = !!tweetNode.querySelector(
// promotion icon
'svg path[d$="996V8h7v7z"]',
)
if (isAdsNode) return true

const isCardNode = node.matches('[data-testid="card.wrapper"]')
const hasTextNode = !!tweetNode.querySelector(
[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
import { createInjectHooksRenderer, Plugin, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script'
import { Plugin, createInjectHooksRenderer, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script'
import { EnhanceableSite, ProfileIdentifier } from '@masknet/shared-base'
import { makeStyles } from '@masknet/theme'
import { useMemo, useState } from 'react'
import { memo, useMemo, useState } from 'react'
import { attachReactTreeWithContainer } from '../../../../utils/index.js'
import { startWatch } from '../../../../utils/watcher.js'
import { querySelectorAll } from '../../utils/selector.js'
Expand All @@ -11,31 +11,6 @@ const selector = () => {
return querySelectorAll<HTMLElement>('[data-testid=conversation] div:not([tabindex]) div[dir] + div[dir]')
}

/**
* Inject on conversation, including both DM drawer and message page (/messages/xxx)
*/
export function injectLensOnConversation(signal: AbortSignal) {
const watcher = new MutationObserverWatcher(selector())
startWatch(watcher, signal)
watcher.useForeach((node, _, proxy) => {
const spans = node
.closest('[data-testid=conversation]')
?.querySelectorAll<HTMLElement>('[tabindex] [dir] span:not([data-testid=tweetText])')
if (!spans) return
const userId = [...spans].reduce((id, node) => {
if (id) return id
if (node.textContent?.match(/@\w/)) {
return node.textContent.trim().slice(1)
}
return ''
}, '')
if (!userId) return
attachReactTreeWithContainer(proxy.afterShadow, { signal, untilVisible: true }).render(
<ConversationLensSlot userId={userId} />,
)
})
}

const useStyles = makeStyles()((theme) => ({
hide: {
display: 'none',
Expand Down Expand Up @@ -67,7 +42,7 @@ const createRootElement = () => {
return span
}

function ConversationLensSlot({ userId }: Props) {
const ConversationLensSlot = memo(function ConversationLensSlot({ userId }: Props) {
const [disabled, setDisabled] = useState(true)
const { classes, cx } = useStyles()

Expand All @@ -78,7 +53,7 @@ function ConversationLensSlot({ userId }: Props) {
undefined,
createRootElement,
)
const identifier = ProfileIdentifier.of(EnhanceableSite.Twitter, userId).unwrap()
const identifier = ProfileIdentifier.of(EnhanceableSite.Twitter, userId).unwrapOr(null)
if (!identifier) return null

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

return <span className={cx(classes.slot, disabled ? classes.hide : null)}>{component}</span>
})

/**
* Inject on conversation, including both DM drawer and message page (/messages/xxx)
*/
export function injectLensOnConversation(signal: AbortSignal) {
const watcher = new MutationObserverWatcher(selector())
startWatch(watcher, signal)
watcher.useForeach((node, _, proxy) => {
const spans = node
.closest('[data-testid=conversation]')
?.querySelectorAll<HTMLElement>('[tabindex] [dir] span:not([data-testid=tweetText])')
if (!spans) return
const userId = [...spans].reduce((id, node) => {
if (id) return id
if (node.textContent?.match(/@\w/)) {
return node.textContent.trim().slice(1)
}
return ''
}, '')
if (!userId) return
attachReactTreeWithContainer(proxy.afterShadow, { signal, untilVisible: true }).render(
<ConversationLensSlot userId={userId} />,
)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ function resolveLangNode(node: HTMLElement) {
}

export function injectPostReplacerAtTwitter(signal: AbortSignal, current: PostInfo) {
const isPromotionPost = !!current.rootNode?.querySelector('svg path[d$="996V8h7v7z"]')
const isCollapsedPost = !!current.rootNode?.querySelector('[data-testid="tweet-text-show-more-link"]')
if (isPromotionPost || isCollapsedPost) return

const hasVideo = !!current.rootNode?.closest('[data-testid="tweet"]')?.querySelector('video')
if (hasVideo) return

const hasCashOrHashTag = !!current.rootNode?.querySelector(
['a[role="link"][href*="cashtag_click"]', 'a[role="link"][href*="hashtag_click"]'].join(','),
)
if (!hasCashOrHashTag) return

return injectPostReplacer({
zipPost(node) {
if (node.destroyed) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const twitterUI: SocialNetworkUI.Definition = {
profileTab: injectProfileTabAtTwitter,
profileCover: injectProfileCover,
profileTabContent: injectProfileTabContentAtTwitter,
enhancedPostRenderer: injectPostReplacerAtTwitter,
postReplacer: injectPostReplacerAtTwitter,
pageInspector: injectPageInspectorDefault(),
postInspector: injectPostInspectorAtTwitter,
postActions: injectPostActionsAtTwitter,
Expand Down
27 changes: 12 additions & 15 deletions packages/mask/src/social-network/defaults/inject/PostReplacer.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
import { memo } from 'react'
import { attachReactTreeWithContainer } from '../../../utils/shadow-root/renderInShadowRoot.js'
import type { DOMProxy } from '@dimensiondev/holoflows-kit'
import { PostInfoProvider, type PostInfo } from '@masknet/plugin-infra/content-script'
import { attachReactTreeWithContainer } from '../../../utils/shadow-root/renderInShadowRoot.js'
import { PostReplacer, type PostReplacerProps } from '../../../components/InjectedComponents/PostReplacer.js'
import type { DOMProxy } from '@dimensiondev/holoflows-kit'
import { noop } from 'lodash-es'

export function injectPostReplacer(config: injectPostReplacerConfig = {}) {
interface InjectPostReplacerConfig {
zipPost(node: DOMProxy): void
unzipPost(node: DOMProxy): void
}

export function injectPostReplacer({ zipPost, unzipPost }: InjectPostReplacerConfig) {
const PostReplacerDefault = memo(function PostReplacerDefault(props: {
zipPost: PostReplacerProps['zip']
unZipPost: PostReplacerProps['unzip']
}) {
return <PostReplacer zip={props.zipPost} unzip={props.unZipPost} />
})

const { zipPost, unzipPost } = config
const zipPostF = zipPost || noop
const unzipPostF = unzipPost || noop
return function injectPostReplacer(current: PostInfo, signal: AbortSignal) {
signal.addEventListener('abort', unzipPostF)
signal.addEventListener('abort', unzipPost as () => void)

attachReactTreeWithContainer(current.rootElement.afterShadow, {
key: 'post-replacer',
untilVisible: true,
signal,
}).render(
<PostInfoProvider post={current}>
<PostReplacerDefault
zipPost={() => zipPostF(current.rootElement)}
unZipPost={() => unzipPostF(current.rootElement)}
zipPost={() => zipPost(current.rootElement)}
unZipPost={() => unzipPost(current.rootElement)}
{...current}
/>
</PostInfoProvider>,
)
}
}

interface injectPostReplacerConfig {
zipPost?(node: DOMProxy): void
unzipPost?(node: DOMProxy): void
}
2 changes: 1 addition & 1 deletion packages/mask/src/social-network/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI.
signal.addEventListener('abort', () => abort.abort())
abortSignals.set(key, abort)
const { signal: postSignal } = abort
ui.injection.enhancedPostRenderer?.(postSignal, value)
ui.injection.postReplacer?.(postSignal, value)
ui.injection.postInspector?.(postSignal, value)
ui.injection.postActions?.(postSignal, value)
ui.injection.commentComposition?.compositionBox(postSignal, value)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { memo, useEffect, useState } from 'react'
import { SNSAdaptorContext } from '@masknet/plugin-infra/content-script'
import { CrossIsolationMessages } from '@masknet/shared-base'
import { Sentry } from '@masknet/web3-telemetry'
import { ChainId } from '@masknet/web3-shared-evm'
import { useRemoteControlledDialog } from '@masknet/shared-base-ui'
import { ChainContextProvider } from '@masknet/web3-hooks-base'
import { Sentry } from '@masknet/web3-telemetry'
import { CrossIsolationMessages, NetworkPluginID } from '@masknet/shared-base'
import { Web3ContextProvider } from '@masknet/web3-hooks-base'
import { EventType, EventID } from '@masknet/web3-telemetry/types'
import { FollowLensDialog } from './components/FollowLensDialog.js'
import { LensPopup } from './components/LensPopup.js'
import { FollowLensDialog } from './components/FollowLensDialog.js'
import { Web3ProfileDialog } from './components/Web3ProfileDialog.js'
import { context } from './context.js'

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

{lensOpen && handle ? (
<ChainContextProvider value={{ chainId: ChainId.Matic }}>
<Web3ContextProvider value={{ pluginID: NetworkPluginID.PLUGIN_EVM, chainId: ChainId.Matic }}>
<FollowLensDialog handle={handle} onClose={closeLensDialog} />
</ChainContextProvider>
</Web3ContextProvider>
) : null}

<LensPopup />
Expand Down
3 changes: 2 additions & 1 deletion packages/types/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export namespace SocialNetworkUI {
/** Inject the UI that used to open the composition UI */
newPostComposition?: NewPostComposition
commentComposition?: CommentComposition
enhancedPostRenderer?(signal: AbortSignal, current: PostInfo): void
/** Inject a replacer of the original post */
postReplacer?(signal: AbortSignal, current: PostInfo): void
/** Display the additional content (decrypted, plugin, ...) below the post */
postInspector?(signal: AbortSignal, current: PostInfo): void
/** Add custom actions buttons to the post */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const features = {
highlights_tweets_tab_ui_enabled: false,
hidden_profile_likes_enabled: false,
hidden_profile_subscriptions_enabled: false,
subscriptions_verification_info_is_identity_verified_enabled: false,
}

async function createRequest(screenName: string) {
Expand Down

0 comments on commit e5ac023

Please sign in to comment.