import type { Plugin } from '@masknet/plugin-infra' ; import { base } from '../base' ; import { useMemo , Suspense } from 'react' ; import { Skeleton } from '@mui/material' ; import { makeStyles } from '@masknet/theme' ; import MaskPluginWrapper from '../../MaskPluginWrapper' ; import { PostInspector } from './PostInspector' ; import { usePostInfoDetails } from '../../../components/DataSource/usePostInfo' ; import { extractTextFromTypedMessage , parseURL } from '@masknet/shared-base' ; const useStyles = makeStyles ( ) ( ( theme ) => { return { skeleton : { margin : theme . spacing ( 2 ) , '&:first-child' : { marginTop : theme . spacing ( 3 ) , } , } , } ; } ) ; const isSnapshotURL = ( x ) : boolean => /^https:\/\/(?:www.)?snapshot.(org|page)\/#\/(.*?)\/proposal\/[\dA-Za-z]+$/ . test ( x ) ; function Renderer ( { url } ) { const { classes } = useStyles ( ) ; return ( < MaskPluginWrapper pluginName = "Snapshot" > < Suspense fallback = { Array . from ( { length : 2 } ) . fill ( 0 ) . map ( ( _ , i ) => ( < Skeleton key = { i } className = { classes . skeleton } animation = "wave" variant = "rectangular" width = { i === 0 ? '80%' : '60%' } height = { 15 } / > ) ) } > < PostInspector url = { url } /> < /Suspense> < /MaskPluginWrapper>); } const sns = { ... base , init ( signal ) { } , DecryptedInspector : function Component ( props ) : JSX . Element | null { const link = useMemo ( ( ) => { const x = extractTextFromTypedMessage ( props . message ) ; if ( x . none ) return null ; return parseURL ( x . val ) . find ( isSnapshotURL ) ; } , [ props . message ] ) ; if ( ! link ) return null ; return < Renderer url = { link } />; } , PostInspector : function Component ( ) : JSX . Element | null { const links = usePostInfoDetails . mentionedLinks ( ) ; const link = links . find ( isSnapshotURL ) ; if ( ! link ) return null ; return < Renderer url = { link } />; } , } ; export default sns ;