Skip to content

Commit

Permalink
chore: inject page inspector
Browse files Browse the repository at this point in the history
  • Loading branch information
guanbinrui committed Aug 26, 2020
1 parent 02d7f21 commit e5c7dc6
Show file tree
Hide file tree
Showing 19 changed files with 276 additions and 177 deletions.
20 changes: 20 additions & 0 deletions src/components/InjectedComponents/PageInspector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import { PluginUI, PluginConfig } from '../../plugins/plugin'

export interface PageInspectorProps {}

export function PageInspector(props: PageInspectorProps) {
return (
<>
{[...PluginUI.values()].map((x) => (
<PluginPageInspectorForEach key={x.identifier} config={x} />
))}
</>
)
}

function PluginPageInspectorForEach({ config }: { config: PluginConfig }) {
const F = config.pageInspector
if (typeof F === 'function') return <F />
return null
}
1 change: 0 additions & 1 deletion src/components/InjectedComponents/PostDummy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import { usePostInfoDetails } from '../DataSource/usePostInfo'
import { DefaultTypedMessageRenderer } from './TypedMessageRenderer'
import { PluginUI } from '../../plugins/plugin'
import { remove } from 'lodash-es'
import { makeTypedMessageCompound, isTypedMessageSuspended } from '../../protocols/typed-message'

export interface PostDummyProps {}
Expand Down
17 changes: 10 additions & 7 deletions src/plugins/Trader/UI/SettingsDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React from 'react'
import { useI18N } from '../../../utils/i18n-next-ui'
import {
makeStyles,
Expand All @@ -16,6 +16,7 @@ import {
DialogActions,
Button,
Divider,
MenuProps,
} from '@material-ui/core'
import ShadowRootDialog from '../../../utils/jss/ShadowRootDialog'
import { DialogDismissIconUI } from '../../../components/InjectedComponents/DialogDismissIcon'
Expand Down Expand Up @@ -69,16 +70,13 @@ interface SettingsDialogUIProps
onPlatformChange?: (platform: Platform) => void
onClose?: () => void
DialogProps?: Partial<DialogProps>
MenuProps?: Partial<MenuProps>
}

function SettingsDialogUI(props: SettingsDialogUIProps) {
const { t } = useI18N()
const { currency, platform, currencies } = props
const classes = useStylesExtends(useStyles(), props)

console.log('DEBUG: SettingsDialogUI')
console.log(props)

return (
<div className={classes.root}>
<ShadowRootDialog
Expand Down Expand Up @@ -116,7 +114,11 @@ function SettingsDialogUI(props: SettingsDialogUIProps) {
fullWidth
value={platform}
onChange={(e) => props.onPlatformChange?.(e.target.value as Platform)}
MenuProps={{ container: props.DialogProps?.container ?? PortalShadowRoot }}>
MenuProps={{
classes: { paper: classes.menuPaper },
container: props.DialogProps?.container ?? PortalShadowRoot,
...props.MenuProps,
}}>
{getEnumAsArray(Platform).map(({ key, value }) => (
<MenuItem key={key} value={value}>
{resolvePlatformName(value)}
Expand All @@ -134,8 +136,9 @@ function SettingsDialogUI(props: SettingsDialogUIProps) {
if (target) props.onCurrencyChange?.(target)
}}
MenuProps={{
container: props.DialogProps?.container ?? PortalShadowRoot,
classes: { paper: classes.menuPaper },
container: props.DialogProps?.container ?? PortalShadowRoot,
...props.MenuProps,
}}>
{currencies.map((x) => (
<MenuItem key={x.id} value={x.id}>
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/Trader/UI/TradeDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface TradeDialogProps {}

export function TradeDialog(props: TradeDialogProps) {
return null
}
39 changes: 39 additions & 0 deletions src/plugins/Trader/UI/TrendingPopper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useState, useEffect } from 'react'
import { Popper, ClickAwayListener, PopperProps } from '@material-ui/core'
import { MessageCenter, ObserveCashTagEvent } from '../messages'

export interface TrendingPopperProps {
children?: (name: string) => React.ReactNode
PopperProps?: Partial<PopperProps>
}

export function TrendingPopper(props: TrendingPopperProps) {
const [name, setName] = useState('')
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)

useEffect(() => {
const off = MessageCenter.on('cashTagObserved', (ev: ObserveCashTagEvent) => {
setName(ev.name)
setAnchorEl(ev.element)
})
return () => {
off()
setAnchorEl(null)
}
}, [])

if (!anchorEl) return null
return (
<ClickAwayListener onClickAway={() => setAnchorEl(null)}>
<Popper
open={true}
anchorEl={anchorEl}
disablePortal
transition
style={{ zIndex: 1 }}
{...props.PopperProps}>
{props.children?.(name)}
</Popper>
</ClickAwayListener>
)
}
180 changes: 37 additions & 143 deletions src/plugins/Trader/UI/TrendingView.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import React, { useState, useEffect } from 'react'
import {
makeStyles,
Avatar,
Typography,
Card,
CardHeader,
IconButton,
CardActions,
Theme,
createStyles,
CircularProgress,
CardContent,
} from '@material-ui/core'
import { useAsync } from 'react-use'
import SettingsIcon from '@material-ui/icons/Settings'
import React from 'react'
import { makeStyles, Avatar, Typography, Card, CardHeader, CardActions, Theme, createStyles } from '@material-ui/core'
import classNames from 'classnames'
import { SettingsDialog, SettingsDialogProps } from './SettingsDialog'
import { Platform, Currency, resolvePlatformName, Settings } from '../type'
import { resolvePlatformName } from '../type'
import { getActivatedUI } from '../../../social-network/ui'
import stringify from 'json-stable-stringify'
import { currentTrendingViewSettings, currentTrendingViewPlatformSettings } from '../settings'
import { useValueRef } from '../../../utils/hooks/useValueRef'
import Services from '../../../extension/service'
import { formatCurrency } from '../../Wallet/formatter'
import { useColorStyles } from '../../../utils/theme'
import { useTrending } from '../hooks/useTrending'

const network = getActivatedUI().networkIdentifier

Expand Down Expand Up @@ -53,134 +35,46 @@ const useStyles = makeStyles((theme: Theme) => {
})

export interface TrendingViewProps extends withClasses<KeysInferFromUseStyles<typeof useStyles>> {
keyword: string
SettingsDialogProps?: Partial<SettingsDialogProps>
name: string
}

export function TrendingView(props: TrendingViewProps) {
const classes = useStyles()
const color = useColorStyles()
const [settingsDialogOpen, setSettingsDialogOpen] = useState(false)

const [platform, setPlatform] = useState(Platform.COIN_GECKO)
const [currency, setCurrency] = useState<Currency | null>(null)

const networkKey = `${network}-${platform}`
const trendingSettings = useValueRef<string>(currentTrendingViewSettings[networkKey])
const trendingPlatformSettings = useValueRef<string>(currentTrendingViewPlatformSettings[network])

//#region currency & platform
const { value: currencies = [], loading: loadingCurrencies } = useAsync(
() => Services.Plugin.invokePlugin('maskbook.trader', 'getCurrenies', platform),
[platform],
)

// sync platform
useEffect(() => {
if (String(platform) !== trendingPlatformSettings) {
if (trendingPlatformSettings === String(Platform.COIN_GECKO)) setPlatform(Platform.COIN_GECKO)
if (trendingPlatformSettings === String(Platform.COIN_MARKET_CAP)) setPlatform(Platform.COIN_MARKET_CAP)
}
}, [platform, trendingPlatformSettings])

// sync currency
useEffect(() => {
if (!currencies.length) return
try {
const parsed = JSON.parse(trendingSettings || '{}') as Settings
if (parsed.currency && currencies.some((x) => x.id === parsed.currency.id)) setCurrency(parsed.currency)
else setCurrency(currencies[0])
} catch (e) {
setCurrency(null)
}
}, [trendingSettings, currencies.length])
//#endregion

//#region coins info
const { value: coinInfo, loading: loadingCoinInfo, error } = useAsync(async () => {
if (!currency) return null
return Services.Plugin.invokePlugin(
'maskbook.trader',
'getCoinTrendingByKeyword',
props.keyword,
platform,
currency,
)
}, [platform, currency, props.keyword])
//#endregion

if (loadingCurrencies || loadingCoinInfo)
return (
<Card className={classes.root} elevation={0} component="article">
<CardActions className={classes.footer}>
<CircularProgress size={20} />
</CardActions>
</Card>
)
if (!currency) return null
if (!coinInfo) return null

const { value: trending } = useTrending(props.name)
if (!trending) return null
const { currency, platform } = trending
return (
<>
<Card className={classes.root} elevation={0} component="article" style={{ minWidth: 250 }}>
<CardHeader
className={classes.header}
avatar={<Avatar src={coinInfo.coin.image_url} alt={coinInfo.coin.symbol} />}
action={
<IconButton
size="small"
onClick={() => {
console.log('DEUBG: click')
setSettingsDialogOpen(true)
}}>
<SettingsIcon />
</IconButton>
}
title={
<Typography variant="h6">{`${coinInfo.coin.symbol.toUpperCase()} / ${
currency.name
}`}</Typography>
}
subheader={
<Typography variant="body1">
<span>{`${currency.symbol ?? `${currency.name} `}${formatCurrency(
coinInfo.market.current_price,
)}`}</span>
{coinInfo.market.price_change_24h ? (
<span
className={classNames(
classes.percentage,
coinInfo.market.price_change_24h > 0 ? color.success : color.error,
)}>
{coinInfo.market.price_change_24h > 0 ? '\u25B2 ' : '\u25BC '}
{coinInfo.market.price_change_24h.toFixed(2)}%
</span>
) : null}
</Typography>
}
/>
<CardActions className={classes.footer}>
<Typography className={classes.footnote} color="textSecondary" variant="subtitle2">
Powered by {resolvePlatformName(platform)}
<Card className={classes.root} elevation={0} component="article" style={{ minWidth: 250 }}>
<CardHeader
className={classes.header}
avatar={<Avatar className={classes.avatar} src={trending.coin.image_url} alt={trending.coin.symbol} />}
title={
<Typography variant="h6">{`${trending.coin.symbol.toUpperCase()} / ${currency.name}`}</Typography>
}
subheader={
<Typography variant="body1">
<span>{`${currency.symbol ?? `${currency.name} `}${formatCurrency(
trending.market.current_price,
)}`}</span>
{trending.market.price_change_24h ? (
<span
className={classNames(
classes.percentage,
trending.market.price_change_24h > 0 ? color.success : color.error,
)}>
{trending.market.price_change_24h > 0 ? '\u25B2 ' : '\u25BC '}
{trending.market.price_change_24h.toFixed(2)}%
</span>
) : null}
</Typography>
</CardActions>
</Card>
<SettingsDialog
open={settingsDialogOpen}
currencies={currencies}
currency={currency}
platform={platform}
onCurrencyChange={(currency) => {
currentTrendingViewSettings[networkKey].value = stringify({
currency,
})
}}
onPlatformChange={(platform) => {
currentTrendingViewPlatformSettings[network].value = String(platform)
}}
onClose={() => setSettingsDialogOpen(false)}
{...props.SettingsDialogProps}
}
/>
</>
<CardActions className={classes.footer}>
<Typography className={classes.footnote} color="textSecondary" variant="subtitle2">
Powered by {resolvePlatformName(platform)}
</Typography>
</CardActions>
</Card>
)
}
13 changes: 12 additions & 1 deletion src/plugins/Trader/define.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Suspense } from 'react'
import React from 'react'
import type { PluginConfig } from '../plugin'
import {
TypedMessage,
Expand All @@ -7,6 +7,8 @@ import {
TypedMessageCompound,
} from '../../protocols/typed-message'
import { makeTypedMessageCashTrending } from './messages/TypedMessageCashTrending'
import { TrendingPopper } from './UI/TrendingPopper'
import { TrendingView } from './UI/TrendingView'

const isCashTagMessage = (m: TypedMessage): m is TypedMessageAnchor => isTypedMessgaeAnchor(m) && m.category === 'cash'

Expand All @@ -20,4 +22,13 @@ export const TraderPluginDefine: PluginConfig = {
items: message.items.map((m: TypedMessage) => (isCashTagMessage(m) ? makeTypedMessageCashTrending(m) : m)),
}
},
pageInspector() {
return (
<TrendingPopper>
{(name: string) => {
return <TrendingView name={name}></TrendingView>
}}
</TrendingPopper>
)
},
}
Loading

0 comments on commit e5c7dc6

Please sign in to comment.