Skip to content
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
3 changes: 2 additions & 1 deletion packages/mask/src/plugins/Wallet/services/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { PluginNFTAvatarRPC } from '../../Avatar/messages'

const ENS_RE = /\S{1,256}\.(eth|kred|xyz|luxe)\b/
const ADDRESS_FULL = /0x\w+/
const RSS3_URL_RE = /https?:\/\/(?<name>[\w.]+)\.rss3\.bio/
// xxx.cheers.bio xxx.rss3.bio
const RSS3_URL_RE = /https?:\/\/(?<name>[\w.]+)\.(rss3|cheers)\.bio/
const RSS3_RNS_RE = /(?<name>[\w.]+)\.rss3/

function isValidAddress(address: string) {
Expand Down
1 change: 1 addition & 0 deletions packages/plugins/RSS3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@masknet/web3-shared-base": "workspace:*",
"@masknet/web3-shared-evm": "workspace:*",
"bignumber.js": "^9.0.2",
"classnames": "^2.3.1",
"date-fns": "^2.28.0",
"react-use": "^17.3.2",
"urlcat": "^2.0.4"
Expand Down
57 changes: 57 additions & 0 deletions packages/plugins/RSS3/src/SNSAdaptor/TabCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { AddressViewer } from '@masknet/shared'
import { AddressName, AddressNameType, EMPTY_LIST } from '@masknet/web3-shared-evm'
import { Box, Typography } from '@mui/material'
import { useI18N } from '../locales'
import { useDonations, useFootprints } from './hooks'
import { DonationPage, FootprintPage } from './pages'

export enum TabCardType {
Donation = 1,
Footprint = 2,
}

export interface TabCardProps {
type: TabCardType
addressNames: AddressName[]
}

export function TabCard({ type, addressNames }: TabCardProps) {
const t = useI18N()
const addressName = addressNames.find((x) => x.type === AddressNameType.RSS3)
const userAddress = addressName?.resolvedAddress || ''
const { value: donations = EMPTY_LIST, loading: loadingDonations } = useDonations(userAddress)
const { value: footprints = EMPTY_LIST, loading: loadingFootprints } = useFootprints(userAddress)

if (!addressName) return null

const isDonation = type === TabCardType.Donation

const summary =
isDonation && !loadingDonations ? (
<Typography color="textPrimary" component="span">
{t.total_grants({
count: donations.length.toString(),
})}
</Typography>
) : null

return (
<>
<link rel="stylesheet" href={new URL('./styles/tailwind.css', import.meta.url).toString()} />
<Box display="flex" alignItems="center" justifyContent="space-between">
<div>{summary}</div>
<AddressViewer addressName={addressName} />
</Box>
{isDonation ? (
<DonationPage donations={donations} loading={loadingDonations} addressLabel={addressName.label} />
) : (
<FootprintPage
address={userAddress}
loading={loadingFootprints}
footprints={footprints}
addressLabel={addressName.label}
/>
)}
</>
)
}
107 changes: 84 additions & 23 deletions packages/plugins/RSS3/src/SNSAdaptor/components/DonationCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { makeStyles, MaskColorVar } from '@masknet/theme'
import { Typography } from '@mui/material'
import classnames from 'classnames'
import { HTMLProps, Fragment } from 'react'

export interface DonationCardProps {
export interface DonationCardProps extends HTMLProps<HTMLDivElement> {
imageUrl: string
name: string
contribCount: number
Expand All @@ -10,31 +13,89 @@ export interface DonationCardProps {
}[]
}

export const DonationCard = ({ imageUrl, name, contribCount, contribDetails }: DonationCardProps) => {
const useStyles = makeStyles()((theme) => ({
card: {
borderRadius: 8,
display: 'flex',
flexDirection: 'row',
backgroundColor: MaskColorVar.twitterBg,
padding: theme.spacing(1),
flexGrow: 1,
alignItems: 'stretch',
},
cover: {
flexShrink: 1,
height: 90,
width: 90,
borderRadius: 8,
objectFit: 'cover',
},
title: {
color: theme.palette.text.primary,
fontSize: 16,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
info: {
flexGrow: 1,
marginLeft: theme.spacing(1),
fontSize: 16,
display: 'flex',
overflow: 'hidden',
flexDirection: 'column',
justifyContent: 'space-around',
fontFamily: '-apple-system,system-ui,sans-serif',
},
infoRow: {
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
infoLabel: {
color: theme.palette.text.primary,
},
infoValue: {
color: theme.palette.text.secondary,
},
}))

export const DonationCard = ({
imageUrl,
name,
contribCount,
contribDetails,
className,
...rest
}: DonationCardProps) => {
const { classes } = useStyles()
return (
<div className="flex flex-row items-center justify-start w-full border-2 rounded cursor-pointer text-body-text bg-body-bg border-donation-bg">
<img
className="flex-shrink m-0.5 w-32 md:w-64 h-32 bg-cover bg-center bg-no-repeat rounded object-cover"
src={imageUrl}
alt={name}
/>
<div className="flex-1 w-0 px-8 flex flex-col justify-around">
<Typography variant="h6" color="textPrimary" fontWeight={600} className="w-full truncate">
{name}
</Typography>
<div className="flex flex-row w-full overflow-y-auto gap-x-6">
<div className="text-donation">
<Typography variant="subtitle1">{contribCount}</Typography>
<Typography variant="subtitle1">Contrib</Typography>
</div>
<div className={classnames(classes.card, className)} {...rest}>
<img className={classes.cover} src={imageUrl} alt={name} />
<dl className={classes.info}>
<dt className={classes.infoRow}>
<Typography
variant="h6"
color="textPrimary"
fontWeight={600}
className={classes.title}
title={name}>
{name}
</Typography>
</dt>
<dd className={classes.infoRow}>
<span className={classes.infoLabel}>{contribCount}</span>
<span className={classes.infoValue}> Contrib</span>
</dd>
<dd className={classes.infoRow}>
{contribDetails.map((contrib, i) => (
<div key={i} className="text-donation">
<Typography variant="subtitle1">{contrib.amount}</Typography>
<Typography variant="subtitle1">{contrib.token}</Typography>
</div>
<Fragment key={i}>
<span className={classes.infoLabel}>{contrib.amount}</span>
<span className={classes.infoValue}> {contrib.token} </span>
</Fragment>
))}
</div>
</div>
</dd>
</dl>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const FootprintCard = ({ imageUrl, startDate, endDate, city, country, act
</Typography>
</div>
<div className="flex flex-row gap-2 font-medium">
<Typography variant="body1" className="capitalize" style={{ color: 'rgba(255, 180, 38, 1)' }}>
<Typography variant="body1" className="capitalize" style={{ color: 'rgb(255, 180, 38)' }}>
{t.attended()}
</Typography>
<Typography variant="body1" color="textPrimary">
Expand Down
39 changes: 39 additions & 0 deletions packages/plugins/RSS3/src/SNSAdaptor/components/StatusBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { makeStyles } from '@masknet/theme'
import { Box, CircularProgress, Typography } from '@mui/material'
import type { FC } from 'react'
import { useI18N } from '../../locales'

interface Props {
loading?: boolean
empty?: boolean
}

const useStyles = makeStyles()((theme) => ({
statusBox: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop: theme.spacing(6),
},
}))

export const StatusBox: FC<Props> = ({ loading, empty }) => {
const { classes } = useStyles()
const t = useI18N()
if (loading) {
return (
<Box className={classes.statusBox}>
<CircularProgress />
</Box>
)
}

if (empty) {
return (
<Box className={classes.statusBox}>
<Typography color="textPrimary">{t.no_data()}</Typography>
</Box>
)
}
return null
}
33 changes: 0 additions & 33 deletions packages/plugins/RSS3/src/SNSAdaptor/components/TabCard.tsx

This file was deleted.

1 change: 1 addition & 0 deletions packages/plugins/RSS3/src/SNSAdaptor/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './DonationCard'
export * from './FootprintCard'
export * from './ImageHolder'
export * from './StatusBox'
3 changes: 2 additions & 1 deletion packages/plugins/RSS3/src/SNSAdaptor/hooks/useDonations.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { EMPTY_LIST } from '@masknet/web3-shared-evm'
import { useAsync } from 'react-use'
import { PluginProfileRPC } from '../../messages'

export function useDonations(address: string) {
return useAsync(async () => {
const response = await PluginProfileRPC.getDonations(address)
return response.status ? response.assets : []
return response.status ? response.assets : EMPTY_LIST
}, [address])
}
2 changes: 1 addition & 1 deletion packages/plugins/RSS3/src/SNSAdaptor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Plugin } from '@masknet/plugin-infra'
import { AddressName, AddressNameType } from '@masknet/web3-shared-evm'
import { base } from '../base'
import { PLUGIN_ID } from '../constants'
import { TabCard, TabCardType } from './components/TabCard'
import { TabCard, TabCardType } from './TabCard'

function addressNameSorter(a: Plugin.SNSAdaptor.ProfileAddress, z: Plugin.SNSAdaptor.ProfileAddress) {
if (a.type === AddressNameType.RSS3) return -1
Expand Down
Loading