Items: make it feel more good to click the button

items
Alex Gleason 2024-01-13 17:53:57 -06:00
rodzic 4850a4d314
commit 2530acece5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
2 zmienionych plików z 60 dodań i 7 usunięć

Wyświetl plik

@ -12,7 +12,7 @@ import React, { useRef, useState } from 'react';
interface ITooltip {
/** Element to display the tooltip around. */
children: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
children: JSX.Element;
/** Text to display in the tooltip. */
text: string;
}

Wyświetl plik

@ -1,3 +1,4 @@
import clsx from 'clsx';
import { type Event } from 'nostr-tools';
import React from 'react';
import { FormattedNumber } from 'react-intl';
@ -63,6 +64,40 @@ const Item: React.FC<SoapboxItem> = ({ id, name, image, account, price }) => {
const free = price === 0;
const favicon = account?.pleroma?.favicon;
const [purchased, setPurchased] = React.useState(false);
const [isPurchasing, setPurchasing] = React.useState(false);
const handlePurchase = async () => {
setPurchasing(true);
await new Promise((resolve) => setTimeout(resolve, 100));
setPurchasing(false);
setPurchased(true);
};
function getButtonIcon() {
if (free || isPurchasing) {
return undefined;
}
if (purchased) {
return require('@tabler/icons/check.svg');
}
return require('@tabler/icons/bolt.svg');
}
function renderButtonText() {
if (purchased) {
return <Text>Got it</Text>;
}
if (free) {
return <Text>Free</Text>;
}
return (
<span className={clsx({ 'opacity-0': isPurchasing })}>
<FormattedNumber value={price} />
</span>
);
}
return (
<div key={id} className='flex flex-col gap-3 text-center'>
<img
@ -84,14 +119,32 @@ const Item: React.FC<SoapboxItem> = ({ id, name, image, account, price }) => {
</HStack>
</div>
<Button
className='mt-auto'
icon={free ? undefined : require('@tabler/icons/bolt.svg')}
>
{free ? 'Free' : <FormattedNumber value={price} />}
</Button>
<MaybeTooltip text='You own this item' show={purchased}>
<Button
className={clsx('mt-auto', { 'animate-pulse': isPurchasing })}
disabled={isPurchasing || purchased}
theme='primary'
onClick={handlePurchase}
icon={getButtonIcon()}
>
{renderButtonText()}
</Button>
</MaybeTooltip>
</div>
);
};
interface IMaybeTooltip {
text?: string;
children: JSX.Element;
show?: boolean;
}
function MaybeTooltip({ text, children, show = true }: IMaybeTooltip) {
if (text && show) {
return <Tooltip text={text}>{children}</Tooltip>;
}
return <>{children}</>;
}
export default Items;