lbry-desktop/ui/component/transactionListTableItem/view.jsx

173 lines
5.3 KiB
React
Raw Permalink Normal View History

// @flow
import * as ICONS from 'constants/icons';
import { SITE_NAME } from 'config';
import React from 'react';
import ButtonTransaction from 'component/common/transaction-link';
import CreditAmount from 'component/common/credit-amount';
import DateTime from 'component/dateTime';
import Button from 'component/button';
2020-04-14 22:37:20 +02:00
import Spinner from 'component/spinner';
2020-04-15 16:12:54 +02:00
import { toCapitalCase } from 'util/string';
import { buildURI, parseURI } from 'util/lbryURI';
import * as TXO from 'constants/txo_list';
import * as ABANDON_STATES from 'constants/abandon_states';
2021-03-05 20:24:26 +01:00
import UriIndicator from 'component/uriIndicator';
type Props = {
txo: Txo,
2020-04-14 22:37:20 +02:00
revokeClaim: (Txo, (string) => void) => void,
isRevokeable: boolean,
reward: ?{
reward_title: string,
},
2021-03-05 20:24:26 +01:00
signingChannel: ChannelClaim,
};
type State = {
2020-04-14 22:37:20 +02:00
abandonState: string,
};
2021-03-05 20:24:26 +01:00
class TransactionListTableItem extends React.PureComponent<Props, State> {
constructor() {
super();
this.state = { abandonState: ABANDON_STATES.READY };
(this: any).abandonClaim = this.abandonClaim.bind(this);
(this: any).getLink = this.getLink.bind(this);
}
getLink(type: string, tip: boolean, valueType: string) {
2020-04-14 22:37:20 +02:00
const { abandonState } = this.state;
if (type === 'claim' && valueType !== 'repost') {
return null;
}
if (this.state.abandonState === ABANDON_STATES.PENDING) {
2020-04-14 22:37:20 +02:00
return <Spinner type={'small'} />;
}
2020-05-22 03:19:01 +02:00
if (tip && type === TXO.SUPPORT) {
return (
<Button
disabled={abandonState === ABANDON_STATES.DONE}
button="secondary"
icon={ICONS.UNLOCK}
onClick={this.abandonClaim}
2020-08-26 22:28:33 +02:00
title={__('Unlock tip')}
/>
);
}
const abandonTitle = type === TXO.SUPPORT ? 'Abandon Support' : 'Abandon Claim';
return (
<Button
disabled={abandonState === ABANDON_STATES.DONE}
button="secondary"
icon={ICONS.DELETE}
onClick={this.abandonClaim}
title={__(abandonTitle)}
/>
);
}
abandonClaim() {
2021-03-05 20:24:26 +01:00
this.props.revokeClaim(this.props.txo, (abandonState) => this.setState({ abandonState }));
}
render() {
2021-03-05 20:24:26 +01:00
const { reward, txo, isRevokeable, signingChannel } = this.props;
const {
amount,
claim_id: claimId,
normalized_name: txoListName,
timestamp,
txid,
type,
value_type: valueType,
2020-04-15 16:12:54 +02:00
is_my_input: isMyInput,
is_my_output: isMyOutput,
} = txo;
const isLbryViewReward =
2021-03-05 20:24:26 +01:00
txo.signing_channel &&
(txo.signing_channel.channel_id === '74562a01e5836c04040b80bf1f4d685fec02cc90' ||
txo.signing_channel.channel_id === '7d0b0f83a195fd1278e1944ddda4cda8d9c01a56');
const name = txoListName;
const isMinus = (type === 'support' || type === 'payment' || type === 'other') && isMyInput && !isMyOutput;
const isTip = type === 'support' && ((isMyInput && !isMyOutput) || (!isMyInput && isMyOutput));
const date = new Date(timestamp * 1000);
// Ensure the claim name exists and is valid
let uri;
let claimName;
try {
if (name.startsWith('@')) {
({ claimName } = parseURI(name));
uri = buildURI({ channelName: claimName, channelClaimId: claimId });
} else {
({ claimName } = parseURI(name));
uri = buildURI({ streamName: claimName, streamClaimId: claimId });
}
} catch (e) {}
const dateFormat = {
month: 'short',
day: 'numeric',
year: 'numeric',
};
const forClaim = name && claimId;
return (
<tr>
<td className="table__date">
{timestamp ? (
<div>
<DateTime date={date} show={DateTime.SHOW_DATE} formatOptions={dateFormat} />
<div className="table__item-label">
<DateTime date={date} show={DateTime.SHOW_TIME} />
</div>
</div>
) : (
<span className="empty">{__('Pending')}</span>
)}
</td>
<td className="table__item--actionable">
<span>
2020-06-16 01:02:03 +02:00
{(isTip && __('Tip')) ||
(type === 'support' && !isTip && __('Support --[noun; transaction type]--')) ||
2020-07-23 19:02:07 +02:00
(valueType && ((valueType === 'stream' && __('Upload')) || __(toCapitalCase(valueType)))) ||
2020-04-15 16:12:54 +02:00
(type && __(toCapitalCase(type)))}
</span>{' '}
{isRevokeable && this.getLink(type, isTip, valueType)}
</td>
<td>
{forClaim && <Button button="link" navigate={uri} label={claimName} disabled={!date} />}
{!forClaim && reward && <span>{reward.reward_title}</span>}
2021-03-05 20:24:26 +01:00
{isLbryViewReward && <div className="table__item-label">{__('%SITE_NAME% view reward', { SITE_NAME })}</div>}
{isTip && signingChannel && !isLbryViewReward && (
<div className="table__item-label">
<UriIndicator uri={signingChannel && signingChannel.permanent_url} link />
</div>
)}
{isTip && !signingChannel && !isLbryViewReward && <div className="table__item-label">Anonymous</div>}
</td>
<td>
<ButtonTransaction id={txid} />
</td>
<td className="table__item--align-right">
<CreditAmount
showPlus={isMinus}
amount={isMinus ? Number(0 - amount) : Number(amount)}
precision={8}
showLBC={false}
/>
</td>
</tr>
);
}
}
2021-03-05 20:24:26 +01:00
export default TransactionListTableItem;