Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: avatar plugin #11473

Merged
merged 8 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from 'react'
import { useCopyToClipboard } from 'react-use'
import { useMaskSharedTrans } from '../../../shared-ui/index.js'
import { format as formatDateTime } from 'date-fns'
import { makeStyles, useCustomSnackbar } from '@masknet/theme'
import {
Expand All @@ -22,10 +21,11 @@ import { useMatchXS } from '@masknet/shared-base-ui'
import { DraggableDiv } from '../shared/DraggableDiv.js'
import { Close as CloseIcon, Download, OpenInBrowser } from '@mui/icons-material'
import { saveFileFromUrl } from '../../../shared/index.js'
import { useMaskSharedTrans } from '../../../shared-ui/index.js'

interface AutoPasteFailedDialogProps {
onClose: () => void
data: AutoPasteFailedEvent
onClose: () => void
}
const useStyles = makeStyles()((theme) => ({
title: { marginLeft: theme.spacing(1) },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Icons } from '@masknet/icons'
import { MaskColors, ShadowRootTooltip, makeStyles } from '@masknet/theme'
import { IconButton, Typography } from '@mui/material'
import { IconButton } from '@mui/material'
import { memo } from 'react'
import { isMobileFacebook } from '../../site-adaptors/facebook.com/utils/isMobile.js'
import { useMaskSharedTrans } from '../../../shared-ui/index.js'
import GuideStep from '../GuideStep/index.js'

Expand All @@ -21,19 +20,7 @@ interface PostDialogHintUIProps extends withClasses<'buttonTransform' | 'iconBut

const useStyles = makeStyles()((theme) => ({
button: {
// TODO: is it correct? (what about twitter?)
padding: isMobileFacebook ? 0 : 'var(--icon-padding, 10px)',
},
text: {
color: theme.palette.grey[300],
marginLeft: theme.spacing(1),
},
wrapper: {
display: 'flex',
alignItems: 'center',
width: '100%',
padding: '8px 10px',
borderBottom: `1px solid ${theme.palette.divider}`,
padding: 'var(--icon-padding, 10px)',
},
}))

Expand Down Expand Up @@ -84,15 +71,6 @@ export const PostDialogHint = memo(function PostDialogHintUI(props: PostDialogHi
const { onHintButtonClicked, size, ...others } = props
const { classes } = useStyles(undefined, { props })
const t = useMaskSharedTrans()

if (isMobileFacebook)
return (
<div className={classes.wrapper} onClick={onHintButtonClicked}>
<EntryIconButton size={size} onHintButtonClicked={() => undefined} />
<Typography className={classes.text}>{t.post_modal_hint__button()}</Typography>
</div>
)

return (
<div className={classes.buttonTransform}>
<EntryIconButton size={size} onHintButtonClicked={onHintButtonClicked} {...others} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Twitter } from '@masknet/web3-providers'
import { RSS3_KEY_SITE, NFTBadgeTimeline } from '@masknet/plugin-avatar'
import { NFTBadgeTimeline } from '@masknet/plugin-avatar'
import { useQuery } from '@tanstack/react-query'

interface Props {
className?: string
clipPathId: string
size: number
userId?: string
}
export function AvatarDecoration({ clipPathId, userId, className, size }: Props) {
export function AvatarDecoration({ userId, className, size }: Props) {
const { data: user } = useQuery({
queryKey: ['twitter', 'profile', 'check-nft-avatar', userId],
queryFn: () => {
Expand All @@ -26,7 +25,6 @@ export function AvatarDecoration({ clipPathId, userId, className, size }: Props)
avatarId={Twitter.getAvatarId(user.avatarURL)}
height={size}
width={size}
siteKey={RSS3_KEY_SITE.TWITTER}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,7 @@ export const ProfileBar = memo<ProfileBarProps>(function ProfileBar({
},
}}
/>
<AvatarDecoration
className={classes.avatarDecoration}
clipPathId={avatarClipPathId}
userId={identity.identifier?.userId}
size={40}
/>
<AvatarDecoration className={classes.avatarDecoration} userId={identity.identifier?.userId} size={40} />
</div>
<Box className={classes.description}>
<Typography className={classes.nickname} title={identity.nickname}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { SiteAdaptorUI } from '@masknet/types'
import { inputText, pasteText } from '@masknet/injected-script'
import { delay, waitDocumentReadyState } from '@masknet/kit'
import { MaskMessages } from '@masknet/shared-base'
import { isMobileFacebook } from '../utils/isMobile.js'

/**
* Access: https://(www|m).facebook.com/
Expand All @@ -23,9 +22,8 @@ export async function pasteTextToCompositionFacebook(

const activated = new LiveSelector().querySelectorAll<HTMLDivElement | HTMLTextAreaElement>(
// cspell:disable-next-line
isMobileFacebook ? 'form textarea' : 'div[role=presentation] .notranslate[role=textbox]',
'div[role=presentation] .notranslate[role=textbox]',
)
if (isMobileFacebook) activated.filter((x) => x.getClientRects().length > 0)

// Select element with fb customize background image.
const activatedCustom = new LiveSelector().querySelectorAll<HTMLDivElement | HTMLTextAreaElement>(
Expand Down Expand Up @@ -53,10 +51,6 @@ export async function pasteTextToCompositionFacebook(
if ('value' in document.activeElement!) inputText(text)
else pasteText(text)
await delay(200)
if (isMobileFacebook) {
const e = document.querySelector<HTMLDivElement | HTMLTextAreaElement>('.mentions-placeholder')
if (e) e.style.display = 'none'
}
// Prevent Custom Paste failed, this will cause service not available to user.
if (!element.innerText.includes(text) || ('value' in element && !element.value.includes(text)))
copyFailed('Not detected')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
import { selectElementContents } from '../../../utils/selectElementContents.js'
import { delay } from '@masknet/kit'
import { isMobileFacebook } from '../utils/isMobile.js'
import type { PostInfo } from '@masknet/plugin-infra/content-script'
import { inputText, pasteText } from '@masknet/injected-script'
import { pasteText } from '@masknet/injected-script'
import { MaskMessages } from '@masknet/shared-base'

export async function pasteToCommentBoxFacebook(encryptedComment: string, current: PostInfo, dom: HTMLElement | null) {
const fail = () => {
MaskMessages.events.autoPasteFailed.sendToLocal({ text: encryptedComment })
}
if (isMobileFacebook) {
const root = dom || current.comment?.commentBoxSelector?.evaluate()[0]
if (!root) return fail()
const textarea = root.querySelector('textarea')
if (!textarea) return fail()
textarea.focus()
inputText(encryptedComment)
textarea.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: false, composed: true }))
await delay(200)
if (!root.innerText.includes(encryptedComment)) return fail()
} else {
const root = dom || current.rootNode
if (!root) return fail()
const input = root.querySelector<HTMLElement>('[contenteditable] > *')
if (!input) return fail()
selectElementContents(input)
input.focus()
pasteText(encryptedComment)
await delay(200)
if (!root.innerText.includes(encryptedComment)) return fail()
}
const root = dom || current.rootNode
if (!root) return fail()
const input = root.querySelector<HTMLElement>('[contenteditable] > *')
if (!input) return fail()
selectElementContents(input)
input.focus()
pasteText(encryptedComment)
await delay(200)
if (!root.innerText.includes(encryptedComment)) return fail()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { LiveSelector, MutationObserverWatcher } from '@dimensiondev/holoflows-k
import type { SiteAdaptorUI } from '@masknet/types'
import { creator } from '../../../site-adaptor-infra/index.js'
import { getProfileIdentifierAtFacebook, getUserID } from '../utils/getProfileIdentifier.js'
import { isMobileFacebook } from '../utils/isMobile.js'
import { ProfileIdentifier, EnhanceableSite, type ValueRef } from '@masknet/shared-base'
import { searchFacebookAvatarSelector, searchUserIdOnMobileSelector } from '../utils/selector.js'
import { searchFacebookAvatarSelector } from '../utils/selector.js'
import { getAvatar, getBioDescription, getFacebookId, getNickName, getPersonalHomepage } from '../utils/user.js'
import { delay } from '@masknet/kit'
import type { IdentityResolved } from '@masknet/plugin-infra'
Expand All @@ -18,7 +17,7 @@ export const IdentityProviderFacebook: SiteAdaptorUI.CollectingCapabilities.Iden
}

function resolveLastRecognizedIdentityFacebookInner(ref: ValueRef<IdentityResolved>, signal: AbortSignal) {
const self = myUsernameLiveSelectorPC.clone().map((x) => getProfileIdentifierAtFacebook(x, false))
const self = myUsernameLiveSelector.clone().map((x) => getProfileIdentifierAtFacebook(x, false))
new MutationObserverWatcher(self)
.addListener('onAdd', (e) => assign(e.value))
.addListener('onChange', (e) => assign(e.newValue))
Expand Down Expand Up @@ -47,8 +46,6 @@ function resolveCurrentVisitingIdentityInner(
ownerRef: SiteAdaptorUI.CollectingCapabilities.IdentityResolveProvider['recognized'],
cancel: AbortSignal,
) {
const selector = isMobileFacebook ? searchUserIdOnMobileSelector() : searchFacebookAvatarSelector()

const assign = async () => {
await delay(3000)
const nickname = getNickName()
Expand Down Expand Up @@ -86,7 +83,7 @@ function resolveCurrentVisitingIdentityInner(

assign()

createWatcher(selector)
createWatcher(searchFacebookAvatarSelector())
}

export const CurrentVisitingIdentityProviderFacebook: SiteAdaptorUI.CollectingCapabilities.IdentityResolveProvider = {
Expand All @@ -98,12 +95,9 @@ export const CurrentVisitingIdentityProviderFacebook: SiteAdaptorUI.CollectingCa
}

// Try to resolve my identities
const myUsernameLiveSelectorPC = new LiveSelector()
const myUsernameLiveSelector = new LiveSelector()
.querySelectorAll<HTMLAnchorElement>(
'[data-pagelet="LeftRail"] > [data-visualcompletion="ignore-dynamic"]:first-child > div:first-child > ul [role="link"]',
)

.filter((x) => x.innerText)
const myUsernameLiveSelectorMobile = new LiveSelector().querySelector<HTMLAnchorElement>(
'#bookmarks_flyout .mSideMenu > div > ul > li:first-child a, #MComposer a',
)