Skip to content

Commit

Permalink
feat: implement inscription detail and list page (Magickbase#196)
Browse files Browse the repository at this point in the history
* refactor: SimpleUDT -> UDT

* feat: implement inscription detail page

* feat: implement inscription list page

* feat: implement two different tokens list entries in the header

* feat: temporarily disable the export function on the Inscription details page

* fix: inscription links
  • Loading branch information
WhiteMinds authored Jan 16, 2024
1 parent a2897e5 commit 87090e7
Show file tree
Hide file tree
Showing 18 changed files with 447 additions and 105 deletions.
3 changes: 3 additions & 0 deletions src/components/Header/MenusComp/arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions src/components/Header/MenusComp/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.submenu {
padding: 4px 12px;
border-radius: 4px;
background: #fff;
color: #333;
box-shadow: 0 4px 4px 0 rgb(16 16 16 / 5%);

.link {
display: block;
padding: 12px 0;
border-top: 1px solid #e5e5e5;
line-height: 1;

&:first-child {
border-top: 0;
}
}
}

.submenuTrigger {
gap: 4px;

.icon {
transform: rotate(180deg);
transition: transform 0.1s;
}

/* stylelint-disable-next-line selector-class-pattern */
&:global(.ant-dropdown-open) {
.icon {
transform: rotate(0deg);
}
}
}

.mobileSubmenuTrigger {
width: 100%;
justify-content: space-between;

.icon {
transform: rotate(180deg);
transition: transform 0.1s;
}
}
83 changes: 71 additions & 12 deletions src/components/Header/MenusComp/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Link } from 'react-router-dom'
import { memo } from 'react'
import { FC, memo } from 'react'
import { useTranslation } from 'react-i18next'
import { Dropdown } from 'antd'
import classNames from 'classnames'
import { MobileMenuItem, MobileMenuLink, HeaderMenuPanel } from './styled'
import { isMainnet } from '../../../utils/chain'
import styles from './index.module.scss'
import { ReactComponent as ArrowIcon } from './arrow.svg'

export enum LinkType {
Inner,
Expand All @@ -12,7 +16,8 @@ export enum LinkType {
interface MenuData {
type: LinkType
name: string
url: string
url?: string
children?: MenuData[]
}

const useMenuDataList = () => {
Expand All @@ -31,7 +36,18 @@ const useMenuDataList = () => {
{
type: LinkType.Inner,
name: t('navbar.tokens'),
url: '/tokens',
children: [
{
type: LinkType.Inner,
name: t('navbar.sUDT'),
url: '/tokens',
},
{
type: LinkType.Inner,
name: t('navbar.inscription'),
url: '/inscriptions',
},
],
},
{
type: LinkType.Inner,
Expand Down Expand Up @@ -59,29 +75,72 @@ const useMenuDataList = () => {
return list
}

const MenuItemLink = ({ menu }: { menu: MenuData }) => {
const { url, type, name } = menu
const SubmenuDropdown: FC<{ menu: MenuData }> = ({ children, menu }) => {
return (
<MobileMenuLink href={url} target={type === LinkType.Inner ? '_self' : '_blank'} rel="noopener noreferrer">
{name}
</MobileMenuLink>
<Dropdown
overlay={
<div className={styles.submenu}>
{menu.children?.map(menu => (
<a
key={menu.name}
className={styles.link}
href={menu.url}
target={menu.type === LinkType.Inner ? '_self' : '_blank'}
rel="noopener noreferrer"
>
{menu.name}
</a>
))}
</div>
}
mouseEnterDelay={0}
transitionName=""
>
{children}
</Dropdown>
)
}

export default memo(({ isMobile }: { isMobile: boolean }) => {
const menuList = useMenuDataList()

return isMobile ? (
<MobileMenuItem>
{menuList
.filter(menu => menu.name !== undefined)
.map(menu => (
<MenuItemLink menu={menu} key={menu.name} />
))}
.map(menu =>
menu.children ? (
<SubmenuDropdown key={menu.name} menu={menu}>
<MobileMenuLink className={styles.mobileSubmenuTrigger}>
{menu.name}
<ArrowIcon className={styles.icon} />
</MobileMenuLink>
</SubmenuDropdown>
) : (
<MobileMenuLink
key={menu.name}
href={menu.url}
target={menu.type === LinkType.Inner ? '_self' : '_blank'}
rel="noopener noreferrer"
>
{menu.name}
</MobileMenuLink>
),
)}
</MobileMenuItem>
) : (
<HeaderMenuPanel>
{menuList.map(menu =>
menu.type === LinkType.Inner ? (
// eslint-disable-next-line no-nested-ternary
menu.children ? (
<SubmenuDropdown key={menu.name} menu={menu}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a className={classNames('headerMenusItem', styles.submenuTrigger)}>
{menu.name}
<ArrowIcon className={styles.icon} />
</a>
</SubmenuDropdown>
) : menu.type === LinkType.Inner ? (
<Link className="headerMenusItem" to={menu.url} key={menu.name}>
{menu.name}
</Link>
Expand Down
7 changes: 5 additions & 2 deletions src/components/Search/SearchByNameResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ const EmptySearchByNameResult = () => {
const SearchByNameResult = (props: { item: UDTQueryResult }) => {
const { t } = useTranslation()
const { item } = props
const { typeHash, fullName, symbol } = item
const { typeHash, fullName, symbol, udtType } = item
const displayName = symbol ?? fullName
return (
<a className={styles.searchResult} href={`${window.origin}/sudt/${typeHash}`}>
<a
className={styles.searchResult}
href={`${window.origin}/${udtType === 'omiga_inscription' ? 'inscription' : 'sudt'}/${typeHash}`}
>
<EllipsisMiddle className={styles.tokenSymbol}>{displayName ?? t('udt.unknown_token')}</EllipsisMiddle>
<EllipsisMiddle className={classNames(styles.typeHash, 'monospace')}>{typeHash}</EllipsisMiddle>
</a>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const handleSearchById = async (
break

case SearchResultType.UDT:
history.push(`/sudt/${query}`)
history.push(data.attributes.udtType === 'omiga_inscription' ? `/inscription/${query}` : `/sudt/${query}`)
break

default:
Expand Down
12 changes: 11 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@
"nervos_dao": "Nervos DAO",
"faucet": "Faucet",
"tokens": "Tokens",
"sUDT": "sUDT",
"inscription": "Inscription",
"docs": "Docs",
"search_placeholder": "Block/Transaction/Address/Lock Hash/Type Hash/Args",
"search_by_name_placeholder": "Token Name",
Expand Down Expand Up @@ -581,7 +583,15 @@
"view-transfer-txns": "View Transfer Txns",
"view-burn-txns": "View Burn Txns",
"address-or-hash": "Transaction Hash / Address",
"address": "Address"
"address": "Address",
"inscriptions": "Inscriptions",
"status": "Status",
"progress": "Progress",
"expected_supply": "Expected Supply",
"mint_limit": "Mint Limit",
"mint_status_minting": "Minting",
"mint_status_closed": "Closed",
"mint_status_rebase_start": "Rebase Start"
},
"nft": {
"nft_collection": "NFT Collection",
Expand Down
12 changes: 11 additions & 1 deletion src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@
"nervos_dao": "Nervos DAO",
"faucet": "水龙头",
"tokens": "代币",
"sUDT": "sUDT",
"inscription": "铭文",
"docs": "文档",
"search_placeholder": "区块/交易/地址/锁定脚本哈希/Type 脚本哈希/参数",
"search_by_name_placeholder": "代币名称",
Expand Down Expand Up @@ -582,7 +584,15 @@
"view-transfer-txns": "查看转帐交易",
"view-burn-txns": "查看销毁交易",
"address-or-hash": "交易哈希 / 地址",
"address": "地址"
"address": "地址",
"inscriptions": "铭文",
"status": "状态",
"progress": "进度",
"expected_supply": "预期供应量",
"mint_limit": "铸造限制",
"mint_status_minting": "铸造中",
"mint_status_closed": "已关闭",
"mint_status_rebase_start": "重铸开始"
},
"nft": {
"nft_collection": "NFT 藏品",
Expand Down
19 changes: 19 additions & 0 deletions src/models/UDT/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,23 @@ export interface UDT {
typeScript: Script
displayName?: string
uan?: string
// TODO: Not quite sure if there are only two types here, so add a string for now.
udtType: 'omiga_inscription' | 'sudt' | string
}

export enum MintStatus {
Minting = 'minting',
Closed = 'closed',
RebaseStart = 'rebase_start',
}

export interface OmigaInscriptionCollection extends UDT {
mintStatus: MintStatus
mintLimit: string
expectedSupply: string
inscriptionInfoId: string
}

export function isOmigaInscriptionCollection(udt: UDT): udt is OmigaInscriptionCollection {
return 'mintStatus' in udt && 'mintLimit' in udt && 'expectedSupply' in udt && 'inscriptionInfoId' in udt
}
Loading

0 comments on commit 87090e7

Please sign in to comment.