Skip to content

Commit

Permalink
Merge pull request #702 from secretkeylabs/fix/revert-to-old-inscript…
Browse files Browse the repository at this point in the history
…ion-view-component
  • Loading branch information
teebszet committed Dec 5, 2023
2 parents c927dc5 + 0e47b09 commit 7b04bfc
Show file tree
Hide file tree
Showing 4 changed files with 379 additions and 19 deletions.
85 changes: 85 additions & 0 deletions src/app/components/rareSatAsset/rareSatAsset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import RareSatIcon from '@components/rareSatIcon/rareSatIcon';
import OrdinalImage from '@screens/ordinals/ordinalImage';
import { Inscription } from '@secretkeylabs/xverse-core';
import { BundleItem } from '@utils/rareSats';
import styled from 'styled-components';

const Container = styled.div`
width: 100%;
height: 100%;
`;

const InscriptionContainer = styled.div`
width: 100%;
height: 100%;
position: relative;
border-radius: 8px;
overflow: hidden;
`;

const RareSatIconContainer = styled.div<{ isGallery: boolean }>((props) => ({
display: 'flex',
position: 'absolute',
zIndex: 1,
left: props.isGallery ? 20 : 8,
top: props.isGallery ? 20 : 8,
}));

const RareSatsContainer = styled.div((props) => ({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
aspectRatio: '1',
overflow: 'hidden',
position: 'relative',
backgroundColor: props.theme.colors.elevation1,
borderRadius: 8,
}));

const DynamicSizeContainer = styled.div<{ isCollage: boolean }>((props) => ({
width: props.isCollage ? '40%' : '50%',
height: props.isCollage ? '40%' : '50%',
}));

interface Props {
item: BundleItem;
isCollage?: boolean;
}

function RareSatAsset({ item, isCollage = false }: Props) {
const isGallery: boolean = document.documentElement.clientWidth > 360;
const isInscription = item.type === 'inscription' || item.type === 'inscribed-sat';

return (
<Container>
{isInscription ? (
<InscriptionContainer>
{!isCollage && !!item.rarity_ranking && item.rarity_ranking !== 'COMMON' && (
<RareSatIconContainer isGallery={isGallery}>
<RareSatIcon
type={item.rarity_ranking}
size={isGallery ? 40 : 24}
padding={isGallery ? 8 : 4}
bgColor="elevation0"
/>
</RareSatIconContainer>
)}
<OrdinalImage
ordinal={item.inscription as Inscription}
isSmallImage={!isGallery && isCollage}
withoutSizeIncrease={!isGallery || isCollage}
/>
</InscriptionContainer>
) : (
<RareSatsContainer>
<DynamicSizeContainer isCollage={isCollage}>
<RareSatIcon type={item.rarity_ranking as any} isDynamicSize />
</DynamicSizeContainer>
</RareSatsContainer>
)}
</Container>
);
}

export default RareSatAsset;
219 changes: 219 additions & 0 deletions src/app/screens/signPsbtRequest/bundleItemsComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import Eye from '@assets/img/createPassword/Eye.svg';
import Cross from '@assets/img/dashboard/X.svg';
import IconOrdinal from '@assets/img/transactions/ordinal.svg';
import RareSatAsset from '@components/rareSatAsset/rareSatAsset';
import { animated, useSpring } from '@react-spring/web';
import { getTruncatedAddress } from '@utils/helper';
import { BundleItem, getBundleItemSubText } from '@utils/rareSats';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';

const Container = styled.div((props) => ({
display: 'flex',
flexDirection: 'column',
background: props.theme.colors.elevation1,
borderRadius: 12,
padding: '16px 16px',
justifyContent: 'center',
marginBottom: 12,
}));

const RecipientTitleText = styled.h1((props) => ({
...props.theme.body_medium_m,
color: props.theme.colors.white_200,
marginBottom: 10,
}));

const RowContainer = styled.div({
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
});

const TransparentButton = styled.button({
background: 'transparent',
display: 'flex',
alignItems: 'center',
marginLeft: 10,
});

const Icon = styled.img((props) => ({
marginRight: props.theme.spacing(4),
width: 32,
height: 32,
borderRadius: 30,
}));

const TitleText = styled.h1((props) => ({
...props.theme.body_medium_m,
color: props.theme.colors.white_200,
}));

const ValueText = styled.h1((props) => ({
...props.theme.body_medium_m,
color: props.theme.colors.white_0,
}));

const SubValueText = styled.h1((props) => ({
...props.theme.body_m,
fontSize: 12,
color: props.theme.colors.white_400,
}));

const InscriptionText = styled.h1((props) => ({
...props.theme.body_medium_m,
fontSize: 21,
marginTop: 24,
textAlign: 'center',
color: props.theme.colors.white[0],
overflowWrap: 'break-word',
wordWrap: 'break-word',
wordBreak: 'break-word',
}));

const ColumnContainer = styled.div({
display: 'flex',
flexDirection: 'column',
flex: 1,
justifyContent: 'flex-end',
alignItems: 'flex-end',
marginTop: 12,
});

const CrossContainer = styled.div({
display: 'flex',
marginTop: 10,
justifyContent: 'flex-end',
alignItems: 'flex-end',
});

const OrdinalOuterImageContainer = styled.div({
justifyContent: 'center',
alignItems: 'center',
borderRadius: 2,
display: 'flex',
flexDirection: 'column',
flex: 1,
});

const OrdinalImageContainer = styled.div({
width: '50%',
});

const OrdinalBackgroundContainer = styled(animated.div)({
width: '100%',
height: '100%',
top: 0,
left: 0,
bottom: 0,
right: 0,
position: 'fixed',
zIndex: 10,
background: 'rgba(18, 21, 30, 0.8)',
backdropFilter: 'blur(16px)',
padding: 16,
display: 'flex',
flexDirection: 'column',
});

const EyeIcon = styled.img({
width: 20,
height: 20,
});

interface Props {
item: BundleItem;
userReceivesOrdinal: boolean;
}
function BundleItemsComponent({ item, userReceivesOrdinal }: Props) {
const { t } = useTranslation('translation');
const [showOrdinal, setShowOrdinal] = useState(false);
const styles = useSpring({
from: {
opacity: 0,
y: 24,
},
to: {
y: 0,
opacity: 1,
},
delay: 100,
});
const onButtonClick = () => {
setShowOrdinal(true);
};

const onCrossClick = () => {
setShowOrdinal(false);
};
const getItemId = () => {
if (item.type === 'inscription') {
return item.inscription.id;
}
if (item.type === 'inscribed-sat' || item.type === 'rare-sat') {
return item.number;
}
return '';
};
const itemSubText = getBundleItemSubText({
satType: item.type,
rareSatsType: item.rarity_ranking as any,
});
const getDetail = () => {
if (item.type === 'inscription' || item.type === 'inscribed-sat') {
return item.inscription.content_type;
}
return itemSubText;
};
const getTitle = () => {
if (item.type === 'inscription') {
return t('COMMON.INSCRIPTION');
}
if (item.type === 'inscribed-sat') {
return t('RARE_SATS.INSCRIBED_SAT');
}
return t('RARE_SATS.RARE_SAT');
};
return (
<>
{showOrdinal && (
<OrdinalBackgroundContainer style={styles}>
<CrossContainer onClick={onCrossClick}>
<TransparentButton>
<img src={Cross} alt="cross" />
</TransparentButton>
</CrossContainer>
<OrdinalOuterImageContainer>
<OrdinalImageContainer>
<RareSatAsset item={item} />
</OrdinalImageContainer>
<InscriptionText>{`${getTitle()} ${getItemId()} `}</InscriptionText>
</OrdinalOuterImageContainer>
</OrdinalBackgroundContainer>
)}
<Container>
<RecipientTitleText>
{userReceivesOrdinal
? t('CONFIRM_TRANSACTION.YOU_WILL_RECEIVE')
: t('CONFIRM_TRANSACTION.YOU_WILL_TRANSFER')}
</RecipientTitleText>
<RowContainer>
<Icon src={IconOrdinal} />
<TitleText>{getTitle()}</TitleText>
<ColumnContainer>
<RowContainer>
<ValueText>{getTruncatedAddress(String(getItemId()))}</ValueText>
<TransparentButton onClick={onButtonClick}>
<EyeIcon src={Eye} alt="show" />
</TransparentButton>
</RowContainer>
<SubValueText>{getDetail()}</SubValueText>
</ColumnContainer>
</RowContainer>
</Container>
</>
);
}

export default BundleItemsComponent;
29 changes: 10 additions & 19 deletions src/app/screens/signPsbtRequest/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ import { delay } from '@common/utils/ledger';
import AccountHeaderComponent from '@components/accountHeader';
import BottomModal from '@components/bottomModal';
import ActionButton from '@components/button';
import SatsBundle from '@components/confirmBtcTransactionComponent/bundle';
import InputOutputComponent from '@components/confirmBtcTransactionComponent/inputOutputComponent';
import InfoContainer from '@components/infoContainer';
import LedgerConnectionView from '@components/ledger/connectLedgerView';
import RecipientComponent from '@components/recipientComponent';
import TransactionDetailComponent from '@components/transactionDetailComponent';
import useBtcClient from '@hooks/useBtcClient';
import useDetectOrdinalInSignPsbt, { InputsBundle } from '@hooks/useDetectOrdinalInSignPsbt';
import useDetectOrdinalInSignPsbt from '@hooks/useDetectOrdinalInSignPsbt';
import useSignPsbtTx from '@hooks/useSignPsbtTx';
import useWalletSelector from '@hooks/useWalletSelector';
import Transport from '@ledgerhq/hw-transport-webusb';
import {
Bundle,
getBtcFiatEquivalent,
parsePsbt,
psbtBase64ToHex,
Expand All @@ -26,6 +24,7 @@ import {
Transport as TransportType,
} from '@secretkeylabs/xverse-core';
import { isLedgerAccount } from '@utils/helper';
import { BundleItem, convertV2ToV1Bundle } from '@utils/rareSats';
import BigNumber from 'bignumber.js';
import { decodeToken } from 'jsontokens';
import { useEffect, useMemo, useState } from 'react';
Expand All @@ -35,6 +34,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { MoonLoader } from 'react-spinners';
import { SignTransactionOptions } from 'sats-connect';
import styled from 'styled-components';
import BundleItemsComponent from './bundleItemsComponent';

const OuterContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -110,9 +110,6 @@ function SignPsbtRequest() {
const { t: signatureRequestTranslate } = useTranslation('translation', {
keyPrefix: 'SIGNATURE_REQUEST',
});
const { t: tCommon } = useTranslation('translation', {
keyPrefix: 'COMMON',
});
const [expandInputOutputView, setExpandInputOutputView] = useState(false);
const { payload, confirmSignPsbt, cancelSignPsbt, getSigningAddresses } = useSignPsbtTx();
const [isSigning, setIsSigning] = useState(false);
Expand Down Expand Up @@ -142,7 +139,7 @@ function SignPsbtRequest() {
const handleOrdinalAndOrdinalInfo = useDetectOrdinalInSignPsbt();
const [isLoading, setIsLoading] = useState(true);
const [userReceivesOrdinal, setUserReceivesOrdinal] = useState(false);
const [bundleItemsData, setBundleItemsData] = useState<InputsBundle>();
const [bundleItemsData, setBundleItemsData] = useState<BundleItem[]>([]);
const signingAddresses = useMemo(
() => getSigningAddresses(payload.inputsToSign),
[payload.inputsToSign],
Expand Down Expand Up @@ -189,7 +186,7 @@ function SignPsbtRequest() {
const checkIfUserReceivesOrdinal = async () => {
try {
const result = await handleOrdinalAndOrdinalInfo(parsedPsbt);
setBundleItemsData(result.bundleItemsData);
setBundleItemsData(convertV2ToV1Bundle(result.bundleItemsData));
setUserReceivesOrdinal(result.userReceivesOrdinal);
} catch {
navigate('/tx-status', {
Expand Down Expand Up @@ -387,21 +384,15 @@ function SignPsbtRequest() {
<Container>
<ReviewTransactionText>{t('REVIEW_TRANSACTION')}</ReviewTransactionText>
{!payload.broadcast && <InfoContainer bodyText={t('PSBT_NO_BROADCAST_DISCLAIMER')} />}
{Array.isArray(bundleItemsData) &&
bundleItemsData.map((bundle, index) => (
<SatsBundle
title={`${tCommon('INPUT')} #${bundle.inputIndex}`}
{bundleItemsData &&
bundleItemsData.map((bundleItem, index) => (
<BundleItemsComponent
// eslint-disable-next-line react/no-array-index-key
key={index}
bundle={
{
totalExoticSats: bundle.totalExoticSats,
satRanges: bundle.satRanges,
} as Bundle
}
item={bundleItem}
userReceivesOrdinal={userReceivesOrdinal}
/>
))}

<RecipientComponent
value={`${satsToBtc(new BigNumber((parsedPsbt?.netAmount ?? 0).toString()))
.toString()
Expand Down
Loading

0 comments on commit 7b04bfc

Please sign in to comment.