Skip to content

Commit

Permalink
feat: inject KnownIdentity into twitter profile page
Browse files Browse the repository at this point in the history
close #469
  • Loading branch information
guanbinrui authored and Jack-Works committed Dec 11, 2019
1 parent a12784d commit 6fbe24b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/social-network-provider/twitter.com/ui/inject.tsx
Expand Up @@ -5,6 +5,7 @@ import { hasDraftEditor, newPostEditorBelow, postPopupInjectPointSelector } from
import { renderInShadowRoot } from '../../../utils/jss/renderInShadowRoot'
import { PostInfo, SocialNetworkUIInjections } from '../../../social-network/ui'
import { injectPostInspectorDefault } from '../../../social-network/defaults/injectPostInspector'
import { injectKnownIdentityAtTwitter } from './injectKnownIdentity'

// Closing these shadowRoot prevents external access to them.
const newMOW = (i: LiveSelector<HTMLElement, true>) =>
Expand Down Expand Up @@ -34,4 +35,5 @@ const injectPostInspector = (current: PostInfo) => {
export const twitterUIInjections: SocialNetworkUIInjections = {
injectPostBox,
injectPostInspector,
injectKnownIdentity: injectKnownIdentityAtTwitter,
}
63 changes: 63 additions & 0 deletions src/social-network-provider/twitter.com/ui/injectKnownIdentity.tsx
@@ -0,0 +1,63 @@
import { MutationObserverWatcher } from '@holoflows/kit'
import { PersonKnown } from '../../../components/InjectedComponents/PersonKnown'
import { bioSelector, bioCard } from '../utils/selector'
import { renderInShadowRoot } from '../../../utils/jss/renderInShadowRoot'
import { PersonIdentifier } from '../../../database/type'
import { twitterUrl } from '../utils/url'
import { makeStyles } from '@material-ui/styles'
import { timeout } from '../../../utils/utils'
import AsyncComponent from '../../../utils/components/AsyncComponent'
import { useState } from 'react'
import { bioCardParser } from '../utils/fetch'

const useStyles = makeStyles({
root: {
marginTop: -10,
marginBottom: 10,
},
center: {
color: '#657786', // TODO: use color in theme
justifyContent: 'flex-start',
marginBottom: 0,
},
})

function PersonKnownAtTwitter() {
const [userId, setUserId] = useState(PersonIdentifier.unknown.userId)
return (
<AsyncComponent
promise={async () => {
const [bioCardNode] = await timeout(new MutationObserverWatcher(bioCard<false>(false)), 10000)
setUserId(bioCardParser(bioCardNode).handle)
}}
dependencies={[userId]}
awaitingComponent={null}
completeComponent={
<PersonKnown
whois={new PersonIdentifier(twitterUrl.hostIdentifier, userId)}
AdditionalContentProps={{
classes: {
...useStyles(),
},
}}
/>
}
failedComponent={null}
/>
)
}

export function injectKnownIdentityAtTwitter() {
const target = new MutationObserverWatcher(bioSelector())
.setDOMProxyOption({
beforeShadowRootInit: { mode: 'closed' },
afterShadowRootInit: { mode: 'closed' },
})
.startWatch({
childList: true,
subtree: true,
characterData: true,
})

renderInShadowRoot(<PersonKnownAtTwitter />, target.firstDOMProxy.beforeShadow)
}
18 changes: 12 additions & 6 deletions src/social-network-provider/twitter.com/utils/selector.ts
Expand Up @@ -4,29 +4,35 @@ import { postBoxInPopup } from './postBox'
import { isNull } from 'lodash-es'

type E = HTMLElement
const querySelector = <T extends E>(selector: string) => {
return new LiveSelector().querySelector<T>(selector).enableSingleMode()
const querySelector = <T extends E, SingleMode extends boolean = true>(
selector: string,
singleMode: boolean = true,
) => {
const ls = new LiveSelector<T, SingleMode>().querySelector<T>(selector)
return (singleMode ? ls.enableSingleMode() : ls) as LiveSelector<T, SingleMode>
}
const querySelectorAll = <T extends E>(selector: string) => {
return new LiveSelector().querySelectorAll<T>(selector)
}

export const bioCard = () =>
querySelector<HTMLDivElement>(
export const bioSelector = () => querySelector<HTMLDivElement>(['[data-testid="UserProfileHeader_Items"]'].join())

export const bioCard = <SingleMode extends boolean = true>(singleMode = true) =>
querySelector<HTMLDivElement, SingleMode>(
[
'.profile', // legacy twitter
'a[href*="header_photo"] ~ div', // new twitter
'div[data-testid="primaryColumn"] > div > div:last-child > div > div > div > div ~ div', // new twitter without header photo
].join(),
singleMode,
)

export const newPostButton = () => querySelector<E>('[data-testid="SideNav_NewTweet_Button"]')

const postEditor = () =>
postBoxInPopup() ? '[aria-labelledby="modal-header"]' : '[role="main"] :not(aside) > [role="progressbar"] ~ div'

export const newPostEditorBelow: () => LiveSelector<E, true> = () =>
querySelector<E>('[role="main"] :not(aside) > [role="progressbar"] ~ div')
export const newPostEditorBelow = () => querySelector<E>('[role="main"] :not(aside) > [role="progressbar"] ~ div')
export const newPostEditorSelector = () => querySelector<HTMLDivElement>(`${postEditor()} .DraftEditor-root`)
export const newPostEditorFocusAnchor = () => querySelector<E>(`${postEditor()} .public-DraftEditor-content`)

Expand Down

0 comments on commit 6fbe24b

Please sign in to comment.