From ee71a6ab957852d9d2676ee4ce172dbe9d4e593e Mon Sep 17 00:00:00 2001 From: ttang Date: Thu, 21 Sep 2023 15:26:34 +0800 Subject: [PATCH] feat: add model info --- .../scan/src/components/CodeDownload.tsx | 2 +- .../client/scan/src/components/ImgOrName.tsx | 30 ++++ .../src/components/ModelView/Definition.tsx | 165 +++++++++++++++++- packages/client/scan/src/container/Models.tsx | 30 +--- packages/client/scan/src/types/index.ts | 21 +++ 5 files changed, 215 insertions(+), 33 deletions(-) create mode 100644 packages/client/scan/src/components/ImgOrName.tsx diff --git a/packages/client/scan/src/components/CodeDownload.tsx b/packages/client/scan/src/components/CodeDownload.tsx index 06fd7ec3..9aead04f 100644 --- a/packages/client/scan/src/components/CodeDownload.tsx +++ b/packages/client/scan/src/components/CodeDownload.tsx @@ -20,7 +20,7 @@ export default function CodeDownload({ downloadContent: string downloadFileName: string }) { - const [show, setShow] = useState(false) + const [show, setShow] = useState(true) const download = (text: string, filename: string) => { const blob = new Blob([text], { type: 'text/plain;charset=utf-8', diff --git a/packages/client/scan/src/components/ImgOrName.tsx b/packages/client/scan/src/components/ImgOrName.tsx new file mode 100644 index 00000000..f253aceb --- /dev/null +++ b/packages/client/scan/src/components/ImgOrName.tsx @@ -0,0 +1,30 @@ +import { useState } from 'react' + +export function ImgOrName({ imgUrl, name }: { imgUrl: string; name: string }) { + const [showName, setShowName] = useState(true) + if (showName) { + return ( + <> + + {name.slice(0, 1).toUpperCase()} + + { + setShowName(false) + }} + onError={() => { + setShowName(true) + }} + /> + + ) + } + return ( + + + + ) +} diff --git a/packages/client/scan/src/components/ModelView/Definition.tsx b/packages/client/scan/src/components/ModelView/Definition.tsx index 9a04a558..eb020149 100644 --- a/packages/client/scan/src/components/ModelView/Definition.tsx +++ b/packages/client/scan/src/components/ModelView/Definition.tsx @@ -1,5 +1,5 @@ -import { useCallback, useEffect, useState } from 'react' -import { Link, useParams } from 'react-router-dom' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { useParams } from 'react-router-dom' import styled from 'styled-components' import FileSaver from 'file-saver' @@ -10,6 +10,10 @@ import { schemas } from '../../utils/composedb-types/schemas' import { AxiosError } from 'axios' import { useCeramicCtx } from '../../context/CeramicCtx' import CodeDownload from '../CodeDownload' +import { UserAvatar } from '@us3r-network/profile' +import dayjs from 'dayjs' +import { shortPubKey } from '../../utils/shortPubKey' +import { ImgOrName } from '../ImgOrName' export default function Definition() { const { streamId } = useParams() @@ -102,6 +106,7 @@ export default function Definition() { /> + {modelData?.composite && ( +
+
+

Model‘s Information

+
+ +
+ {modelStream && ( +
+
+ Model name: + {modelStream.streamContent.name} +
+
+ Description: + {modelStream.streamContent.description || ''} +
+
+ Model ID: + {shortPubKey(modelStream.streamId, { len: 10 })} +
+
+ Usage count: + {modelStream.useCount || 0} +
+
+ Creator: +
+ + {shortPubKey(modelStream.controllerDid, { len: 10 })} +
+
+
+ Release date: + {dayjs(modelStream.createdAt).format('YYYY-MM-DD')} +
+
+ Dapps: + {modelStream.dapps && } +
+
+ )} + + ) +} + +function Dapps({ + dapps, +}: { + dapps: Array<{ name: string; description: string; icon: string }> +}) { + return ( + <> + {[...dapps].map((item, idx) => { + return ( +
+ + {item.name} +
+ ) + })} + + ) +} + +const InfoBox = styled.div` + box-sizing: border-box; + background-color: #1a1a1c; + height: fit-content; + overflow: hidden; + .title { + display: flex; + align-items: center; + justify-content: space-between; + margin: 0; + font-weight: 700; + font-size: 24px; + line-height: 28px; + font-style: italic; + color: #ffffff; + + h3 { + margin: 0; + padding: 0; + font-weight: 700; + font-size: 20px; + line-height: 24px; + } + } + + .info { + padding: 10px; + display: flex; + flex-direction: column; + gap: 8px; + > div { + word-wrap: break-word; + > span { + margin-right: 5px; + color: #718096; + } + } + + .avatar { + display: flex; + margin-top: 5px; + align-items: center; + gap: 5px; + } + } + + .dapp { + margin-top: 10px; + display: flex; + gap: 10px; + align-items: center; + > span { + color: #fff; + width: 36px; + height: 36px; + border-radius: 10px; + border: 1px solid #718096; + display: inline-flex; + align-items: center; + justify-content: center; + overflow: hidden; + &.name { + font-size: 20px; + font-weight: 500; + } + &.left { + border: none; + color: #fff; + justify-content: start; + font-family: Rubik; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: normal; + } + > img { + width: 100%; + height: 100%; + object-fit: cover; + flex-shrink: 0; + border-radius: 50%; + } + } + } +` + const EditorBox = styled.div` height: calc(100vh - 300px); max-height: 800px; @@ -146,9 +304,10 @@ const ResultBox = styled.div` background: #1b1e23; border: 1px solid #39424c; border-radius: 20px; + flex-shrink: 0; } > div { - width: calc(50% - 10px); + width: calc(33% - 8px); margin: 20px 0px; /* padding: 10px; */ box-sizing: border-box; diff --git a/packages/client/scan/src/container/Models.tsx b/packages/client/scan/src/container/Models.tsx index 5c648f23..c81996b7 100644 --- a/packages/client/scan/src/container/Models.tsx +++ b/packages/client/scan/src/container/Models.tsx @@ -17,6 +17,7 @@ import Star from '../components/icons/Star' import StarEmpty from '../components/icons/StarEmpty' import { useCeramicCtx } from '../context/CeramicCtx' import { debounce } from 'lodash' +import { ImgOrName } from '../components/ImgOrName' export default function ModelsPage() { const [searchParams] = useSearchParams() @@ -288,35 +289,6 @@ function Dapps({ ) } -function ImgOrName({ imgUrl, name }: { imgUrl: string; name: string }) { - const [showName, setShowName] = useState(true) - if (showName) { - return ( - <> - - {name.slice(0, 1).toUpperCase()} - - { - setShowName(false) - }} - onError={() => { - setShowName(true) - }} - /> - - ) - } - return ( - - - - ) -} - const DappBox = styled.div` display: flex; gap: 5px; diff --git a/packages/client/scan/src/types/index.ts b/packages/client/scan/src/types/index.ts index 400afc99..22b0dadb 100644 --- a/packages/client/scan/src/types/index.ts +++ b/packages/client/scan/src/types/index.ts @@ -27,10 +27,30 @@ export enum Network { export type ModelStream = { stream_id: string + streamId: string controller_did: string + controllerDid: string tip: string streamContent: { name: string + description: string | null + schema: { + type: 'object' + $schema: 'https://json-schema.org/draft/2020-12/schema' + required: ['myData'] + properties: { + myData: { + type: 'integer' + maximum: 10000 + minimum: 0 + } + } + additionalProperties: false + } + version: '1.0' + accountRelation: { + type: 'list' + } } stream_content: { name: string @@ -56,6 +76,7 @@ export type ModelStream = { last_anchored_at: null first_anchored_at: null created_at: string + createdAt: string updated_at: string useCount: number recentlyUseCount?: number