Skip to content

Commit

Permalink
✨feat(lld): UI of inscriptions table for ordis
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasWerey committed Sep 4, 2024
1 parent 255f035 commit 075494c
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-cups-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": patch
---

LLD ORDINALS add dummy table to display inscriptions inside BTC account screen.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from "react";
import { Account } from "@ledgerhq/types-live";
import { Box, Flex } from "@ledgerhq/react-ui";
import { useInscriptionsModel } from "./useInscriptionsModel";
import TableContainer from "~/renderer/components/TableContainer";
import TableHeader from "LLD/features/Collectibles/components/Collection/TableHeader";
import { OrdinalsRowProps, TableHeaderTitleKey } from "LLD/features/Collectibles/types/Collection";
import TableRow from "LLD/features/Collectibles/components/Collection/TableRow";
import ShowMore from "LLD/features/Collectibles/components/Collection/ShowMore";
import { MediaProps } from "LLD/features/Collectibles/types/Media";

type ViewProps = ReturnType<typeof useInscriptionsModel>;

type Props = {
account: Account;
};

export type InscriptionsItemProps = {
isLoading: boolean;
tokenName: string;
collectionName: string;
tokenIcons: OrdinalsRowProps["tokenIcons"];
media: MediaProps;
onClick: () => void;
};

const Item: React.FC<InscriptionsItemProps> = ({
isLoading,
tokenName,
collectionName,
tokenIcons,
media,
onClick,
}) => {
return (
<TableRow
isLoading={isLoading}
tokenName={tokenName}
collectionName={collectionName}
tokenIcons={tokenIcons}
media={media}
onClick={onClick}
/>
);
};

function View({ temporyObjects, displayShowMore, onShowMore }: ViewProps) {
return (
<Box>
<TableContainer id="oridinals-inscriptions" mb={50}>
<TableHeader titleKey={TableHeaderTitleKey.Inscriptions} />
{/** titlekey doesn't need to be translated so we keep it hard coded */}
{temporyObjects ? (
temporyObjects.map((item, index) => (
<Item
key={index}
isLoading={item.isLoading}
tokenName={item.tokenName}
collectionName={item.collectionName}
tokenIcons={item.tokenIcons}
media={item.media}
onClick={item.onClick}
/>
))
) : (
<Flex justifyContent={"center"} my={12}>
{"NOTHING TO SHOW"}
</Flex>
)}
{displayShowMore && <ShowMore onShowMore={onShowMore} />}
</TableContainer>
</Box>
);
}

const Inscriptions: React.FC<Props> = ({ account }: Props) => {
return <View {...useInscriptionsModel({ account })} />;
};

export default Inscriptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { useEffect, useMemo, useState } from "react";
import { Icons } from "@ledgerhq/react-ui";
import { Account } from "@ledgerhq/types-live";
import { InscriptionsItemProps } from "./index";

type Props = {
account: Account;
};

export const useInscriptionsModel = ({ account }: Props) => {
const [displayShowMore, setDisplayShowMore] = useState(false);
const [displayedObjects, setDisplayedObjects] = useState<InscriptionsItemProps[]>([]);

const temporyObjects: InscriptionsItemProps[] = useMemo(
() => [
{
isLoading: false,
tokenName: "NodeMonke#5673",
collectionName: "NodeMonkes",
tokenIcons: [Icons.OrdinalsAlpha, Icons.OrdinalsPaliblockPalindrome],
media: {
uri: "https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2Ff976d219206858d782cccd90d25882cc77cafd3d6c159728f0d3407e25961ab0i0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252Ff976d219206858d782cccd90d25882cc77cafd3d6c159728f0d3407e25961ab0i0.png&w=1920&q=75",
previewUri:
"https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2Ff976d219206858d782cccd90d25882cc77cafd3d6c159728f0d3407e25961ab0i0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252Ff976d219206858d782cccd90d25882cc77cafd3d6c159728f0d3407e25961ab0i0.png&w=1920&q=75",
mediaType: "image",
isLoading: false,
useFallback: true,
contentType: "image",
},
onClick: () => console.log("clicked"),
},
{
isLoading: false,
tokenName: "NodeMonke#5673#22",
collectionName: "NodeMonkes#2",
tokenIcons: [Icons.OrdinalsAlpha, Icons.OrdinalsPaliblockPalindrome],
media: {
uri: "https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
previewUri:
"https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
mediaType: "image",
isLoading: false,
useFallback: true,
contentType: "image",
},
onClick: () => console.log("clicked"),
},
{
isLoading: false,
tokenName: "NodeMonke#5673#33",
collectionName: "NodeMonkes#2",
tokenIcons: [Icons.OrdinalsAlpha, Icons.OrdinalsPaliblockPalindrome],
media: {
uri: "https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
previewUri:
"https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
mediaType: "image",
isLoading: false,
useFallback: true,
contentType: "image",
},
onClick: () => console.log("clicked"),
},
{
isLoading: false,
tokenName: "NodeMonke#5673#44",
collectionName: "NodeMonkes#2",
tokenIcons: [Icons.OrdinalsAlpha, Icons.OrdinalsPaliblockPalindrome],
media: {
uri: "https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
previewUri:
"https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
mediaType: "image",
isLoading: false,
useFallback: true,
contentType: "image",
},
onClick: () => console.log("clicked"),
},
{
isLoading: false,
tokenName: "NodeMonke#5673#55",
collectionName: "NodeMonkes#2",
tokenIcons: [Icons.OrdinalsAlpha, Icons.OrdinalsPaliblockPalindrome],
media: {
uri: "https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
previewUri:
"https://www.cryptoslam.io/_next/image?url=https%3A%2F%2Fd6rvidx1ucs57.cloudfront.net%2Fcryptoslam-token-images.s3.amazonaws.com%2FBitcoin%2Fnodemonkes%2Fimage%2F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png%3Fd%3D354%26u%3Dhttps%253A%252F%252Fcryptoslam-token-images.s3.amazonaws.com%252FBitcoin%252Fnodemonkes%252Fimage%252F33199e5e35a90b516d274e8c076ca205436db00a36bc5a99d2f0e26110ca7abai0.png&w=1920&q=75",
mediaType: "image",
isLoading: false,
useFallback: true,
contentType: "image",
},
onClick: () => console.log("clicked"),
},
],
[],
);

useEffect(() => {
if (temporyObjects.length > 3) setDisplayShowMore(true);
setDisplayedObjects(temporyObjects.slice(0, 3));
}, [temporyObjects]);

const onShowMore = () => {
setDisplayedObjects(prevDisplayedObjects => {
const newDisplayedObjects = [
...prevDisplayedObjects,
...temporyObjects.slice(prevDisplayedObjects.length, prevDisplayedObjects.length + 3),
];
if (newDisplayedObjects.length === temporyObjects.length) setDisplayShowMore(false);
return newDisplayedObjects;
});
};

console.log(displayedObjects);
return { account, temporyObjects: displayedObjects, displayShowMore, onShowMore };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";
import { Account } from "@ledgerhq/types-live";
import Inscriptions from "../../components/Inscriptions";

type Props = {
account: Account;
};

const OrdinalsAccount: React.FC<Props> = ({ account }) => {
return <Inscriptions account={account} />;
// here we will add the rare sats table
};

export default OrdinalsAccount;
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import React from "react";
import { Skeleton } from "../../Skeleton";
import { Text } from "@ledgerhq/react-ui";
import { Flex, Text } from "@ledgerhq/react-ui";
import { useTheme } from "styled-components";

type Props = {
tokenName: string | string[];
isLoading: boolean;
collectionName?: string;
};

const TokenTitle: React.FC<Props> = ({ tokenName, isLoading }) => {
const TokenTitle: React.FC<Props> = ({ tokenName, isLoading, collectionName }) => {
const theme = useTheme();

return (
<Skeleton width={136} minHeight={24} barHeight={10} show={isLoading}>
<Text ff="Inter|SemiBold" color="palette.text.shade100" fontSize={4}>
{tokenName}
</Text>
<Flex flexDirection="column" alignItems="flex-start">
<Text ff="Inter|SemiBold" color="palette.text.shade100" fontSize={4}>
{tokenName}
</Text>
<Text ff="Inter|SemiBold" color={theme.colors.opacityDefault.c50} fontSize={3}>
{collectionName}
</Text>
</Flex>
</Skeleton>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { Media, Skeleton } from "../../index";
import { Box, Text } from "@ledgerhq/react-ui";
import { Box, Flex, Text } from "@ledgerhq/react-ui";
import { rgba } from "~/renderer/styles/helpers";
import styled from "styled-components";
import {
Expand All @@ -25,6 +25,13 @@ const Container = styled(Box)`
}
`;

const SatsIconContainer = styled(Flex)`
border-radius: 8px;
background: ${p => p.theme.colors.opacityDefault.c05};
border: 1px solid ${p => p.theme.colors.opacityDefault.c10};
padding: 8px;
`;

const TableRow: React.FC<Props> = props => {
const mediaBox = () => {
return (
Expand All @@ -43,7 +50,19 @@ const TableRow: React.FC<Props> = props => {
{props.numberOfNfts || 0}
</Text>
)}
{isOrdinalsRow(props) && null}
{isOrdinalsRow(props) && (
<SatsIconContainer
p={"8px"}
alignItems={"center"}
justifyContent={"center"}
flexDirection={"row"}
columnGap={"12px"}
>
{props.tokenIcons?.map((Icon, index) => (
<Icon key={index} size={"XS"} color={"neutral.c100"} />
))}
</SatsIconContainer>
)}
</Skeleton>
);
};
Expand All @@ -54,12 +73,17 @@ const TableRow: React.FC<Props> = props => {
justifyContent="center"
px={4}
py={3}
maxHeight={64}
display={"flex"}
onClick={props.onClick}
>
{mediaBox()}
<Box ml={3} flex={1}>
<TokenTitle tokenName={props.tokenName} isLoading={props.isLoading} />
<TokenTitle
tokenName={props.tokenName}
isLoading={props.isLoading}
collectionName={isOrdinalsRow(props) ? props.collectionName : undefined}
/>
</Box>
{nftCount()}
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ export type NftRowProps = {
onClick: () => void;
};

export interface IconProps {
size: "S" | "XS" | "M" | "L" | "XL" | undefined;
color: string;
style?: React.CSSProperties;
}

export type OrdinalsRowProps = {
media: MediaProps;
tokenName: string;
collectionName: string;
tokenIcons: string[];
tokenIcons: Array<({ size, color, style }: IconProps) => JSX.Element>;
onClick: () => void;
};

export type RareSatsRowProps = {
tokenIcons: string[];
tokenIcons: Array<({ size, color, style }: IconProps) => JSX.Element>;
tokenName: string[];
numberOfSats: number[];
yearOfCreation: number[];
Expand All @@ -35,6 +41,7 @@ export type TableHeaderActionsProps = {

export enum TableHeaderTitleKey {
NFTCollections = "NFT.collections.title",
Inscriptions = "Inscriptions",
}

export type TableHeaderProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "../types/Collection";

export function isNFTRow(props: Props): props is Props & NftRowProps {
return "media" in props;
return "media" in props && !("collectionName" in props);
}

export function isOrdinalsRow(props: Props): props is Props & OrdinalsRowProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import OperationsList from "~/renderer/components/OperationsList";
import useTheme from "~/renderer/hooks/useTheme";
import Collections from "~/renderer/screens/nft/Collections";
import NftCollections from "LLD/features/Collectibles/Nfts/Collections";
import OrdinalsAccount from "LLD/features/Collectibles/Ordinals/screens/Account";
import BalanceSummary from "./BalanceSummary";
import AccountHeader from "./AccountHeader";
import AccountHeaderActions, { AccountHeaderSettingsButton } from "./AccountHeaderActions";
Expand Down Expand Up @@ -110,6 +111,9 @@ const AccountPage = ({
const nftReworked = useFeature("lldNftsGalleryNewArch");
const isNftReworkedEnabled = nftReworked?.enabled;

const ordinalsFF = useFeature("lldnewArchOrdinals");
const isOrdinalsEnabled = ordinalsFF?.enabled;

const filterOperations = useCallback(
(operation: Operation, account: AccountLike) => {
// Remove operations linked to address poisoning
Expand Down Expand Up @@ -215,6 +219,9 @@ const AccountPage = ({
<Collections account={account} />
)
) : null}
{isOrdinalsEnabled && account.type === "Account" && account.currency.id === "bitcoin" ? (
<OrdinalsAccount account={account} />
) : null}
{account.type === "Account" ? <TokensList account={account} /> : null}
<OperationsList
account={account}
Expand Down

0 comments on commit 075494c

Please sign in to comment.