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

Fix cannot focus compositon dialog in twitter #1015

Merged
merged 1 commit into from
Apr 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/components/InjectedComponents/PostDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Chip,
ThemeProvider,
Theme,
DialogProps,
} from '@material-ui/core'
import { MessageCenter, CompositionEvent } from '../../utils/messages'
import { useCapturedInput } from '../../utils/hooks/useCapturedEvents'
Expand Down Expand Up @@ -96,6 +97,7 @@ export interface PostDialogUIProps
onFinishButtonClicked: () => void
onCloseButtonClicked: () => void
onSetSelected: SelectRecipientsUIProps['onSetSelected']
DialogProps?: Partial<DialogProps>
SelectRecipientsUIProps?: Partial<SelectRecipientsUIProps>
}
export function PostDialogUI(props: PostDialogUIProps) {
Expand Down Expand Up @@ -131,7 +133,8 @@ export function PostDialogUI(props: PostDialogUIProps) {
onEscapeKeyDown={props.onCloseButtonClicked}
BackdropProps={{
className: classes.backdrop,
}}>
}}
{...props.DialogProps}>
<DialogTitle className={classes.header}>
<IconButton
classes={{ root: classes.close }}
Expand Down Expand Up @@ -240,6 +243,7 @@ export function PostDialogUI(props: PostDialogUIProps) {
open={props.open && redPacketDialogOpen}
onConfirm={() => setRedPacketDialogOpen(false)}
onDecline={() => setRedPacketDialogOpen(false)}
DialogProps={props.DialogProps}
/>
</div>
)
Expand Down
8 changes: 5 additions & 3 deletions src/plugins/Wallet/UI/RedPacket/RedPacketDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
InputLabel,
Select,
MenuItem,
DialogProps,
} from '@material-ui/core'
import { useStylesExtends, or } from '../../../../components/custom-ui-helper'
import { DialogDismissIconUI } from '../../../../components/InjectedComponents/DialogDismissIcon'
Expand All @@ -28,7 +29,7 @@ import {
WalletRecord,
ERC20TokenRecord,
} from '../../database/types'
import { useLastRecognizedIdentity, useCurrentIdentity } from '../../../../components/DataSource/useActivatedUI'
import { useCurrentIdentity } from '../../../../components/DataSource/useActivatedUI'
import { useCapturedInput } from '../../../../utils/hooks/useCapturedEvents'
import { PluginMessageCenter } from '../../../PluginMessages'
import { getActivatedUI } from '../../../../social-network/ui'
Expand Down Expand Up @@ -58,6 +59,7 @@ interface RedPacketDialogProps
open: boolean
onConfirm: (opt?: RedPacketJSONPayload | null) => void
onDecline: () => void
DialogProps?: Partial<DialogProps>
}

const useNewPacketStyles = makeStyles(theme =>
Expand Down Expand Up @@ -471,7 +473,6 @@ export function RedPacketDialogUI(
props: RedPacketDialogProps & NewPacketProps & ExistingPacketProps & { tab?: [0 | 1, (next: 0 | 1) => void] },
) {
const classes = useStylesExtends(useStyles(), props)
const rootRef = useRef<HTMLDivElement>(null)
const [currentTab, setCurrentTab] = or(props.tab, useState<0 | 1>(0)) as [
number,
React.Dispatch<React.SetStateAction<number>>,
Expand Down Expand Up @@ -504,7 +505,8 @@ export function RedPacketDialogUI(
disableEnforceFocus
BackdropProps={{
className: classes.backdrop,
}}>
}}
{...props.DialogProps}>
<DialogTitle className={classes.header}>
<IconButton classes={{ root: classes.close }} onClick={props.onDecline}>
<DialogDismissIconUI />
Expand Down
21 changes: 16 additions & 5 deletions src/social-network-provider/twitter.com/ui/injectPostDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import { renderInShadowRoot } from '../../../utils/jss/renderInShadowRoot'
import { PostDialog } from '../../../components/InjectedComponents/PostDialog'
import { useTwitterButton, useTwitterCloseButton, useTwitterLabel, useTwitterDialog } from '../utils/theme'
import { makeStyles } from '@material-ui/styles'
import { postEditorInPopupSelector, rootSelector } from '../utils/selector'
import { postEditorContentInPopupSelector, rootSelector } from '../utils/selector'
import { Theme } from '@material-ui/core'
import { useValueRef } from '../../../utils/hooks/useValueRef'
import { instanceOfTwitterUI } from '.'

const useStyles = makeStyles((theme: Theme) => ({
MUIInputInput: {
Expand All @@ -34,7 +32,7 @@ const useStyles = makeStyles((theme: Theme) => ({

export function injectPostDialogAtTwitter() {
if (location.hostname.indexOf(twitterUrl.hostIdentifier) === -1) return
renderPostDialogTo('popup', postEditorInPopupSelector())
renderPostDialogTo('popup', postEditorContentInPopupSelector())
renderPostDialogTo('timeline', rootSelector())
}

Expand All @@ -52,7 +50,15 @@ function renderPostDialogTo<T>(reason: 'timeline' | 'popup', ls: LiveSelector<T,
}

function PostDialogAtTwitter(props: { reason: 'timeline' | 'popup' }) {
return (
const rootRef = React.useRef<HTMLDivElement>(null)
const dialogProps =
props.reason === 'popup'
? {
disablePortal: true,
container: () => rootRef.current,
}
: {}
const dialog = (
<PostDialog
classes={{
...useStyles(),
Expand All @@ -61,6 +67,7 @@ function PostDialogAtTwitter(props: { reason: 'timeline' | 'popup' }) {
...useTwitterButton(),
...useTwitterCloseButton(),
}}
DialogProps={dialogProps}
SelectRecipientsUIProps={{
SelectRecipientsDialogUIProps: {
classes: {
Expand All @@ -73,4 +80,8 @@ function PostDialogAtTwitter(props: { reason: 'timeline' | 'popup' }) {
reason={props.reason}
/>
)

// ! Render dialog into native composition view instead of portal shadow
// ! More https://github.com/DimensionDev/Maskbook/issues/837
return props.reason === 'popup' ? <div ref={rootRef}>{dialog}</div> : dialog
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ import { hasEditor, isCompose } from '../utils/postBox'
export function injectPostDialogHintAtTwitter() {
if (location.hostname.indexOf(twitterUrl.hostIdentifier) === -1) return
const emptyNode = document.createElement('div')
renderPostDialogHintTo(postEditorInTimelineSelector().map(x => (hasEditor() ? x : emptyNode)))
renderPostDialogHintTo(postEditorInPopupSelector().map(x => (isCompose() && hasEditor() ? x : emptyNode)))
renderPostDialogHintTo(
'timeline',
postEditorInTimelineSelector().map(x => (hasEditor() ? x : emptyNode)),
)
renderPostDialogHintTo(
'popup',
postEditorInPopupSelector().map(x => (isCompose() && hasEditor() ? x : emptyNode)),
)
}

function renderPostDialogHintTo<T>(ls: LiveSelector<T, true>) {
function renderPostDialogHintTo<T>(reason: 'timeline' | 'popup', ls: LiveSelector<T, true>) {
const watcher = new MutationObserverWatcher(ls)
.setDOMProxyOption({
afterShadowRootInit: { mode: 'closed' },
Expand All @@ -27,7 +33,7 @@ function renderPostDialogHintTo<T>(ls: LiveSelector<T, true>) {
subtree: true,
})

renderInShadowRoot(<PostDialogHintAtTwitter />, watcher.firstDOMProxy.afterShadow)
renderInShadowRoot(<PostDialogHintAtTwitter reason={reason} />, watcher.firstDOMProxy.afterShadow)
}

export const useTwitterThemedPostDialogHint = makeStyles((theme: Theme) => ({
Expand All @@ -53,15 +59,14 @@ export const useTwitterThemedPostDialogHint = makeStyles((theme: Theme) => ({
},
}))

function PostDialogHintAtTwitter() {
function PostDialogHintAtTwitter({ reason }: { reason: 'timeline' | 'popup' }) {
const classes = {
...useTwitterThemedPostDialogHint(),
...useTwitterButton(),
}
const onHintButtonClicked = useCallback(
() => MessageCenter.emit('compositionUpdated', { reason: 'timeline', open: true }),
[],
)
const onHintButtonClicked = useCallback(() => MessageCenter.emit('compositionUpdated', { reason, open: true }), [
reason,
])
return (
<PostDialogHint
classes={classes}
Expand Down
2 changes: 2 additions & 0 deletions src/social-network-provider/twitter.com/utils/selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const rootSelector: () => LiveSelector<E, true> = () => querySelector<E>(
export const composeAnchorSelector: () => LiveSelector<HTMLAnchorElement, true> = () =>
querySelector<HTMLAnchorElement>('a[href="/compose/tweet"]')

export const postEditorContentInPopupSelector: () => LiveSelector<E, true> = () =>
querySelector<E>('[aria-labelledby="modal-header"] > div:first-child > div:nth-child(3)')
export const postEditorInPopupSelector: () => LiveSelector<E, true> = () =>
querySelector<E>(
'[aria-labelledby="modal-header"] > div:first-child > div:nth-child(3) > div:first-child > div:first-child',
Expand Down
8 changes: 4 additions & 4 deletions src/utils/jss/ShadowRootDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React from 'react'
import { Dialog, withMobileDialog } from '@material-ui/core'
import { Dialog, withMobileDialog, DialogProps } from '@material-ui/core'
import '../../utils/jss/ShadowRootPortal'
import { PortalShadowRoot } from '../../utils/jss/ShadowRootPortal'
import { useSheetsRegistryStyles } from './renderInShadowRoot'

const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog)

export default function ShadowRootDialog(_props: any) {
export default function ShadowRootDialog(_props: DialogProps) {
const ref = React.useRef<HTMLDivElement>(null)
const styles = useSheetsRegistryStyles(ref.current)

// ? I need the render tree to get the shadowroot. Is the extra div must be rendered?
// ? can style be transported to shadowroot directly instead of with dialog children?
const { children, ...props } = _props
const { children, container, ...props } = _props
return (
<div ref={ref}>
<ResponsiveDialog {...props} container={PortalShadowRoot}>
<ResponsiveDialog {...props} container={container ?? PortalShadowRoot}>
<style>{styles}</style>
{children}
</ResponsiveDialog>
Expand Down