Skip to content

Commit

Permalink
TW-834: NFT page. 'Sell' button. Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-tsx committed Jul 13, 2023
1 parent 38518dc commit 407a909
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/app/atoms/FormSecondaryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const FormSecondaryButton: FC<FormSecondaryButtonProps> = ({
<Button type={type} className={classNameMemo} disabled={disabled} {...rest}>
{loading ? keepChildrenWhenLoading && children : children}

{loading && <Spinner theme="primary" style={{ width: small ? '2rem' : '3rem' }} />}
{loading && <Spinner theme="primary" className={small ? 'w-8' : 'w-12'} />}
</Button>
);
};
2 changes: 1 addition & 1 deletion src/app/atoms/FormSubmitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const FormSubmitButton: FC<FormSubmitButtonProps> = ({

return (
<Button className={classNameMemo} disabled={disabled} {...rest} {...otherProps}>
{loading && <Spinner theme="white" style={{ width: small ? '2rem' : '3rem' }} />}
{loading && <Spinner theme="white" className={small ? 'w-8' : 'w-12'} />}

{loading ? keepChildrenWhenLoading && children : children}
</Button>
Expand Down
65 changes: 6 additions & 59 deletions src/app/pages/Collectibles/CollectiblePage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { FC, useMemo, useCallback, useState } from 'react';
import React, { FC, useMemo } from 'react';

import { isDefined } from '@rnw-community/shared';
import BigNumber from 'bignumber.js';

import { FormSubmitButton, FormSecondaryButton } from 'app/atoms';
import Money from 'app/atoms/Money';
Expand All @@ -12,23 +11,19 @@ import {
useCollectibleDetailsSelector
} from 'app/store/collectibles/selectors';
import AddressChip from 'app/templates/AddressChip';
import { getObjktMarketplaceContract, objktCurrencies } from 'lib/apis/objkt';
import { fromFa2TokenSlug } from 'lib/assets/utils';
import { objktCurrencies } from 'lib/apis/objkt';
import { T } from 'lib/i18n';
import { useAssetMetadata, getAssetName } from 'lib/metadata';
import { useAccount, useTezos } from 'lib/temple/front';
import { useAccount } from 'lib/temple/front';
import { formatTcInfraImgUri } from 'lib/temple/front/image-uri';
import { atomsToTokens } from 'lib/temple/helpers';
import { TempleAccountType } from 'lib/temple/types';
import { Image } from 'lib/ui/Image';
import { getTransferPermissions } from 'lib/utils/get-transfer-permissions';
import { parseTransferParamsToParamsWithKind } from 'lib/utils/parse-transfer-params';
import { navigate } from 'lib/woozie';

import { CollectibleImage } from './CollectibleImage';
import { CollectiblesSelectors } from './selectors';

const DEFAULT_OBJKT_STORAGE_LIMIT = 350;
import { useCollectibleSelling } from './use-collectible-selling.hook';

interface Props {
assetSlug: string;
Expand Down Expand Up @@ -57,6 +52,8 @@ const CollectiblePage: FC<Props> = ({ assetSlug }) => {

const creators = details?.creators ?? [];

const { isSelling, initiateSelling: onSellButtonClick } = useCollectibleSelling(assetSlug, details);

const offer = useMemo(() => {
const highestOffer = details?.highestOffer;
if (!isDefined(highestOffer)) return null;
Expand All @@ -69,56 +66,6 @@ const CollectiblePage: FC<Props> = ({ assetSlug }) => {
return { price, symbol: currency.symbol, buyerIsMe: highestOffer.buyer_address === publicKeyHash };
}, [details, publicKeyHash]);

const tezos = useTezos();
const [isSelling, setIsSelling] = useState(false);

const onSellButtonClick = useCallback(async () => {
const offer = details?.highestOffer;
if (!offer || isSelling) return;
setIsSelling(true);

const { contract: tokenAddress, id } = fromFa2TokenSlug(assetSlug);
const tokenId = Number(id.toString());

const contract = await getObjktMarketplaceContract(tezos, offer.marketplace_contract);

const transferParams = (() => {
if ('fulfill_offer' in contract.methods) {
return contract.methods.fulfill_offer(offer.bigmap_key, tokenId).toTransferParams();
} else {
return contract.methods.offer_accept(offer.bigmap_key).toTransferParams();
}
})();

const tokenToSpend = {
standard: 'fa2' as const,
contract: tokenAddress,
tokenId
};

const { approve, revoke } = await getTransferPermissions(
tezos,
offer.marketplace_contract,
publicKeyHash,
tokenToSpend,
new BigNumber('0')
);

const operationParams = approve
.concat(transferParams)
.concat(revoke)
.map(params => parseTransferParamsToParamsWithKind({ ...params, storageLimit: DEFAULT_OBJKT_STORAGE_LIMIT }));

await tezos.wallet
.batch(operationParams)
.send()
.catch(error => {
console.error('Operation send error:', error);
});

setIsSelling(false);
}, [tezos, isSelling, details, assetSlug, publicKeyHash]);

const sellButtonTooltipStr = useMemo(() => {
if (!offer) return;
let value = offer.price.toString();
Expand Down
67 changes: 67 additions & 0 deletions src/app/pages/Collectibles/use-collectible-selling.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useCallback, useState } from 'react';

import BigNumber from 'bignumber.js';

import type { CollectibleDetails } from 'app/store/collectibles/state';
import { getObjktMarketplaceContract } from 'lib/apis/objkt';
import { fromFa2TokenSlug } from 'lib/assets/utils';
import { useAccount, useTezos } from 'lib/temple/front';
import { getTransferPermissions } from 'lib/utils/get-transfer-permissions';
import { parseTransferParamsToParamsWithKind } from 'lib/utils/parse-transfer-params';

const DEFAULT_OBJKT_STORAGE_LIMIT = 350;

export const useCollectibleSelling = (assetSlug: string, details?: CollectibleDetails) => {
const tezos = useTezos();
const { publicKeyHash } = useAccount();
const [isSelling, setIsSelling] = useState(false);

const initiateSelling = useCallback(async () => {
const offer = details?.highestOffer;
if (!offer || isSelling) return;
setIsSelling(true);

const { contract: tokenAddress, id } = fromFa2TokenSlug(assetSlug);
const tokenId = Number(id.toString());

const contract = await getObjktMarketplaceContract(tezos, offer.marketplace_contract);

const transferParams = (() => {
if ('fulfill_offer' in contract.methods) {
return contract.methods.fulfill_offer(offer.bigmap_key, tokenId).toTransferParams();
} else {
return contract.methods.offer_accept(offer.bigmap_key).toTransferParams();
}
})();

const tokenToSpend = {
standard: 'fa2' as const,
contract: tokenAddress,
tokenId
};

const { approve, revoke } = await getTransferPermissions(
tezos,
offer.marketplace_contract,
publicKeyHash,
tokenToSpend,
new BigNumber('0')
);

const operationParams = approve
.concat(transferParams)
.concat(revoke)
.map(params => parseTransferParamsToParamsWithKind({ ...params, storageLimit: DEFAULT_OBJKT_STORAGE_LIMIT }));

await tezos.wallet
.batch(operationParams)
.send()
.catch(error => {
console.error('Operation send error:', error);
});

setIsSelling(false);
}, [tezos, isSelling, details, assetSlug, publicKeyHash]);

return { isSelling, initiateSelling };
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const PaymentProvidersMenu: FC<Props> = ({
{(options.length === 0 || isLoading) && (
<div className="my-8 flex flex-col items-center justify-center text-gray-500">
{isLoading ? (
<Spinner theme="primary" style={{ width: '3rem' }} />
<Spinner theme="primary" className="w-12" />
) : (
<p className="flex items-center justify-center text-gray-600 text-base font-light">
<T id="noTopUpOptionsAvailable" />
Expand Down

0 comments on commit 407a909

Please sign in to comment.