feat: launch mira

This commit is contained in:
DIYgod 2023-03-17 19:52:47 +00:00
parent 7738bc285b
commit 0b4fe83f17
No known key found for this signature in database
14 changed files with 226 additions and 33 deletions

View File

@ -11,5 +11,6 @@ NEXT_PUBLIC_GITHUB_LINK="https://github.com/Crossbell-Box/xlog"
NEXT_PUBLIC_CSB_IO="https://crossbell.io"
NEXT_PUBLIC_CSB_SCAN="https://scan.crossbell.io"
NEXT_PUBLIC_IPFS_GATEWAY="https://ipfs.4everland.xyz/ipfs/"
NEXT_PUBLIC_MIRA_LINK="https://mira.crossbell.io"
REDIS_URL=

View File

@ -15,7 +15,7 @@
},
"Earn": {
"subtitle": "Earn tokens and rights",
"description": "Great content deserves to be rewarded, and a blockchain offers the wonderful opportunity for creators to be rewarded transparently and fairly. An xLog DAO further promotes the growth of our community."
"description": "Great content deserves to be rewarded, and a blockchain offers the wonderful opportunity for creators to be rewarded transparently and fairly. An xLog DAO will further promote the growth of our community."
}
},
"Easy to get started text": "xLog supports <strong>web3 wallets</strong> and <strong>email</strong> connections, allowing you to quickly create a customized blog with features like a custom domain, subscriptions, comments, NFT minting, RSS feeds, and AI enhancements in just 5 minutes - with no application or costs required.",

View File

@ -148,5 +148,18 @@
"Preview your Mirror.xyz entries": "预览你的 Mirror.xyz 条目",
"Please select .md files, multiple files are supported, and front matter is supported.":
"请选择 .md 文件,支持多个文件,支持 front matter。",
"Achievements": "成就"
"Achievements": "成就",
"Tokens": "代币",
"1 MIRA ≈ 1 USDC, swap easily on cross-chain bridge and Uniswap.": "1 MIRA ≈ 1 USDC可以在跨链桥和 Uniswap 上轻松兑换。",
"In the early stage, xLog will use $MIRA to motivate creators.": "在早期阶段xLog 将使用 $MIRA 激励创作者。",
"You can obtain $MIRA through the following ways:": "你可以通过以下方式获得 $MIRA",
"Creator incentive program." : "创作者激励计划。",
"Participate in events.": "参加活动。",
"Swap from USDC.": "从 USDC 兑换。",
"Swap to USDC": "兑换到 USDC",
"Free Claim": "免费领取",
"$XLOG is related to xLog DAO, but it's too early now, please stay tuned.": "$XLOG 与 xLog DAO 相关,但现在还为时尚早,敬请期待。",
"Stay tuned": "敬请期待",
"This is a token used for interaction on the Crossbell blockchain, which can be claimed for free from the faucet, so there's no need to worry about its balance.": "这是一个用于 Crossbell 区块链上交互的代币,可以从水龙头免费领取,所以不用担心它的余额。",
"Balance": "余额"
}

View File

@ -23,7 +23,7 @@
},
"Earn": {
"subtitle": "赚取代币和权利",
"description": "优秀的内容应该得到奖励而区块链为创作者提供了透明公正的奖励机会。xLog DAO 进一步促进我们社区的发展。"
"description": "优秀的内容应该得到奖励而区块链为创作者提供了透明公正的奖励机会。xLog DAO 进一步促进我们社区的发展。"
}
},
"Features": "特色",

View File

@ -13,7 +13,7 @@ import { Avatar } from "~/components/ui/Avatar"
import { CharacterFloatCard } from "./CharacterFloatCard"
import { UniLink } from "../ui/UniLink"
import { getSiteLink } from "~/lib/helpers"
import { CSB_SCAN } from "~/lib/env"
import { CSB_SCAN, MIRA_LINK } from "~/lib/env"
import { parsePageId } from "~/models/page.model"
export const PatronModal: React.FC<{
@ -156,22 +156,24 @@ export const PatronModal: React.FC<{
className="inline-flex flex-col items-center w-[12.5%]"
key={index}
>
<CharacterFloatCard siteId={tip.character?.handle}>
<UniLink
href={getSiteLink({
subdomain: tip.character?.handle || "",
})}
>
<Avatar
className="relative align-middle border-2 border-white"
images={
tip.character?.metadata?.content?.avatars || []
}
name={tip.character?.metadata?.content?.name}
size={50}
/>
</UniLink>
</CharacterFloatCard>
<div className="text-left">
<CharacterFloatCard siteId={tip.character?.handle}>
<UniLink
href={getSiteLink({
subdomain: tip.character?.handle || "",
})}
>
<Avatar
className="relative align-middle border-2 border-white"
images={
tip.character?.metadata?.content?.avatars || []
}
name={tip.character?.metadata?.content?.name}
size={50}
/>
</UniLink>
</CharacterFloatCard>
</div>
<UniLink
href={`${CSB_SCAN}/tx/${tip.transactionHash}`}
className="inline-flex items-center mt-1 text-center w-full"
@ -224,7 +226,9 @@ export const PatronModal: React.FC<{
<p>1 Mira 1 USDC</p>
<p className="flex items-center justify-center">
<i className="i-mingcute:question-line mr-1 text-sm" />
{t("What is Mira? Where can I get some?")}
<UniLink href={MIRA_LINK}>
{t("What is Mira? Where can I get some?")}
</UniLink>
</p>
</div>
</div>

View File

@ -273,7 +273,7 @@ export const Reactions: React.FC<{
)}
</div>
{size !== "sm" && (
<div className="xlog-reactions-tip flex items-center opacity-0 pointer-events-none">
<div className="xlog-reactions-tip flex items-center">
<Button
variant="tip"
className={`flex items-center mr-2 ${

View File

@ -7,6 +7,7 @@ export const getServerSideProps = async (ctx: any) => {
...(await serverSideTranslations(languageDetector(ctx), [
"common",
"dashboard",
"index",
])),
},
}

View File

@ -139,6 +139,12 @@ export function DashboardLayout({
icon: "i-mingcute-trophy-line",
text: "Achievements",
},
{
href: `/dashboard/${subdomain}/tokens`,
isActive: ({ href, pathname }) => href === pathname,
icon: "i-mingcute-pig-money-line",
text: "Tokens",
},
{
href: `/dashboard/${subdomain}/settings/general`,
isActive: ({ pathname }) =>

View File

@ -286,7 +286,7 @@ export const SiteHeader: React.FC<{
<span className="xlog-site-follow-count block sm:inline-block whitespace-nowrap">
<FollowingCount siteId={site?.username} />
</span>
<span className="xlog-site-patron opacity-0 pointer-events-none">
<span className="xlog-site-patron">
<PatronButton site={site} />
</span>
</div>

View File

@ -17,3 +17,5 @@ export const CSB_XCHAR =
process.env.NEXT_PUBLIC_CSB_XCHAR || "https://xchar.app"
export const IPFS_GATEWAY =
process.env.NEXT_PUBLIC_IPFS_GATEWAY || "https://ipfs.4everland.xyz/ipfs/"
export const MIRA_LINK =
process.env.NEXT_PUBLIC_MIRA_LINK || "https://mira.crossbell.io"

View File

@ -696,3 +696,14 @@ export async function mintAchievement(input: {
}) {
return indexer.mintAchievement(input.characterId, input.achievementId)
}
export async function getMiraBalance(address: string, contract: Contract) {
const decimals = await contract.getMiraTokenDecimals()
const result = await contract.getMiraBalance(address)
result.data = (
BigInt(result.data) /
BigInt(10) ** BigInt(decimals?.data || 18)
).toString()
return result
}

View File

@ -1,21 +1,12 @@
import { DashboardLayout } from "~/components/dashboard/DashboardLayout"
import { DashboardMain } from "~/components/dashboard/DashboardMain"
import { UniLink } from "~/components/ui/UniLink"
import { Image } from "~/components/ui/Image"
import type { ReactElement } from "react"
import { useGetAchievements, useGetSite } from "~/queries/site"
import { useGetAchievements } from "~/queries/site"
import { useDate } from "~/hooks/useDate"
import { useTranslation } from "next-i18next"
import { getServerSideProps as getLayoutServerSideProps } from "~/components/dashboard/DashboardLayout.server"
import { GetServerSideProps } from "next"
import { serverSidePropsHandler } from "~/lib/server-side-props"
import { useGetPagesBySite } from "~/queries/page"
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
import { useEffect, useState } from "react"
import { Avatar } from "~/components/ui/Avatar"
import { cn } from "~/lib/utils"
import { getSiteLink } from "~/lib/helpers"
import { getStorage, setStorage } from "~/lib/storage"
import { useAccountState } from "@crossbell/connect-kit"
import { AchievementItem } from "~/components/common/AchievementItem"

View File

@ -0,0 +1,152 @@
import { DashboardLayout } from "~/components/dashboard/DashboardLayout"
import { DashboardMain } from "~/components/dashboard/DashboardMain"
import type { ReactElement } from "react"
import { useDate } from "~/hooks/useDate"
import { useTranslation } from "next-i18next"
import { getServerSideProps as getLayoutServerSideProps } from "~/components/dashboard/DashboardLayout.server"
import { GetServerSideProps } from "next"
import { serverSidePropsHandler } from "~/lib/server-side-props"
import {
useAccountState,
useAccountBalance,
useWalletClaimCSBModal,
useClaimCSBStatus,
} from "@crossbell/connect-kit"
import { useGetMiraBalance } from "~/queries/site"
import { Button } from "~/components/ui/Button"
import { MIRA_LINK } from "~/lib/env"
import { UniLink } from "~/components/ui/UniLink"
import { useRouter } from "next/router"
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
async (ctx) => {
const { props: layoutProps } = await getLayoutServerSideProps(ctx)
return {
props: {
...layoutProps,
},
}
},
)
export default function TokensPage() {
const router = useRouter()
const { t } = useTranslation(["dashboard", "index"])
const subdomain = router.query.subdomain as string
const address = useAccountState((s) => s.wallet?.address)
const miraBalance = useGetMiraBalance(address)
const csbBalance = useAccountBalance()
const claimCSBStatus = useClaimCSBStatus()
const claimCSBModal = useWalletClaimCSBModal()
const tokens = [
{
name: "MIRA",
balance: miraBalance.data?.data || 0,
description: (
<>
<p>
{t(
"1 MIRA ≈ 1 USDC, swap easily on cross-chain bridge and Uniswap.",
)}
</p>
<p>
{t("In the early stage, xLog will use $MIRA to motivate creators.")}
</p>
<p>{t("You can obtain $MIRA through the following ways:")}</p>
<ul className="ml-2">
<li>
1.{" "}
<UniLink className="underline" href="">
{t("Creator incentive program.")}
</UniLink>
</li>
<li>
2.{" "}
<UniLink
className="underline"
href={`/dashboard/${subdomain}/events`}
>
{t("Participate in events.")}
</UniLink>
</li>
<li>
3.{" "}
<UniLink className="underline" href={MIRA_LINK}>
{t("Swap from USDC.")}
</UniLink>
</li>
</ul>
</>
),
buttons: (
<>
<Button onClick={() => window.open(MIRA_LINK)}>
{t("Swap to USDC")}
</Button>
</>
),
},
{
name: "CSB",
balance: csbBalance?.balance?.formatted || 0,
description: (
<>
{t(
"This is a token used for interaction on the Crossbell blockchain, which can be claimed for free from the faucet, so there's no need to worry about its balance.",
)}
</>
),
buttons: (
<>
<Button
isDisabled={!claimCSBStatus.isEligibleToClaim}
onClick={() => claimCSBModal.show()}
>
{claimCSBStatus.errorMsg || t("Free Claim")}
</Button>
</>
),
},
{
name: "XLOG",
description: t(
"$XLOG is related to xLog DAO, but it's too early now, please stay tuned.",
),
balance: t("Stay tuned"),
},
]
return (
<DashboardMain title="Tokens">
<div className="min-w-[270px] max-w-screen-lg flex flex-col space-y-8">
<div className="text-sm text-zinc-500 leading-relaxed">
{t("features.Earn.description", { ns: "index" })}
</div>
{tokens.map((token) => {
return (
<div key={token.name} className="space-y-4">
<div className="text-2xl font-medium text-accent">
${token.name}
</div>
<div className="text-zinc-500 text-sm space-y-1">
{token.description}
</div>
<div className="text-lg">
{t("Balance")}:{" "}
<span className="font-bold">{token.balance}</span>
</div>
<div>{token.buttons}</div>
</div>
)
})}
</div>
</DashboardMain>
)
}
TokensPage.getLayout = (page: ReactElement) => {
return <DashboardLayout title="Tokens">{page}</DashboardLayout>
}

View File

@ -409,3 +409,15 @@ export const useMintAchievement = () => {
},
)
}
export const useGetMiraBalance = (address?: string) => {
const contract = useContract()
return useQuery(["getMiraBalance", address], async () => {
if (!address) {
return {
data: "0",
}
}
return siteModel.getMiraBalance(address, contract)
})
}