diff --git a/ui/component/commentCreate/view.jsx b/ui/component/commentCreate/view.jsx index 8e113f269..3d78b4133 100644 --- a/ui/component/commentCreate/view.jsx +++ b/ui/component/commentCreate/view.jsx @@ -131,6 +131,7 @@ export function CommentCreate(props: Props) { return; } + // if comment post didn't work, but tip was already made, try againt o create comment if (commentFailure && tipAmount === successTip.tipAmount) { handleCreateComment(successTip.txid); return; @@ -147,6 +148,21 @@ export function CommentCreate(props: Props) { const activeChannelName = activeChannelClaim && activeChannelClaim.name; const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id; + // setup variables for tip API + let channelClaimId, tipChannelName; + // if there is a signing channel it's on a file + if (claim.signing_channel) { + channelClaimId = claim.signing_channel.claim_id; + tipChannelName = claim.signing_channel.name; + + // otherwise it's on the channel page + } else { + channelClaimId = claim.claim_id; + tipChannelName = claim.name; + } + + console.log(activeChannelClaim); + setIsSubmitting(true); if (activeTab === TAB_LBC) { @@ -160,6 +176,14 @@ export function CommentCreate(props: Props) { setTimeout(() => { handleCreateComment(txid); }, 1500); + + doToast({ + message: __("You sent %tipAmount% LBRY Credits as a tip to %tipChannelName%, I'm sure they appreciate it!", { + tipAmount: tipAmount, // force show decimal places + tipChannelName + }), + }); + setSuccessTip({ txid, tipAmount }); }, () => { @@ -168,18 +192,6 @@ export function CommentCreate(props: Props) { } ); } else { - // setup variables for tip API - let channelClaimId, tipChannelName; - // if there is a signing channel it's on a file - if (claim.signing_channel) { - channelClaimId = claim.signing_channel.claim_id; - tipChannelName = claim.signing_channel.name; - - // otherwise it's on the channel page - } else { - channelClaimId = claim.claim_id; - tipChannelName = claim.name; - } const sourceClaimId = claim.claim_id; const roundedAmount = Math.round(tipAmount * 100) / 100; @@ -187,8 +199,8 @@ export function CommentCreate(props: Props) { Lbryio.call( 'customer', 'tip', - { - amount: 100 * roundedAmount, // convert from dollars to cents + { // round to deal with floating point precision + amount: Math.round(100 * roundedAmount), // convert from dollars to cents creator_channel_name: tipChannelName, // creator_channel_name creator_channel_claim_id: channelClaimId, tipper_channel_name: activeChannelName, diff --git a/ui/component/livestreamComments/view.jsx b/ui/component/livestreamComments/view.jsx index f4b073fef..0ed35c9e3 100644 --- a/ui/component/livestreamComments/view.jsx +++ b/ui/component/livestreamComments/view.jsx @@ -22,7 +22,9 @@ type Props = { fetchingComments: boolean, doSuperChatList: (string) => void, superChats: Array, + superChatsReversed: Array, superChatsTotalAmount: number, + superChatsFiatAmount: number, myChannels: ?Array, }; @@ -38,15 +40,16 @@ export default function LivestreamComments(props: Props) { embed, doCommentSocketConnect, doCommentSocketDisconnect, - comments, + comments, // superchats in chronological format doCommentList, fetchingComments, doSuperChatList, - superChats, - superChatsTotalAmount, myChannels, + superChats, // superchats organized by tip amount } = props; + let { superChatsReversed, superChatsFiatAmount, superChatsTotalAmount } = props; + const commentsRef = React.createRef(); const [scrollBottom, setScrollBottom] = React.useState(true); const [viewMode, setViewMode] = React.useState(VIEW_MODE_CHAT); @@ -58,6 +61,36 @@ export default function LivestreamComments(props: Props) { const discussionElement = document.querySelector('.livestream__comments'); const commentElement = document.querySelector('.livestream-comment'); + // sum total amounts for fiat tips and lbc tips + if (superChats) { + let fiatAmount = 0; + let LBCAmount = 0; + for (const superChat of superChats) { + if (superChat.is_fiat) { + fiatAmount = fiatAmount + superChat.support_amount; + } else { + LBCAmount = LBCAmount + superChat.support_amount; + } + } + + superChatsFiatAmount = fiatAmount; + superChatsTotalAmount = LBCAmount; + } + + // array of superchats organized by fiat or not first, then support amount + if (superChats) { + const clonedSuperchats = JSON.parse(JSON.stringify(superChats)); + + // sort by fiat first then by support amount + superChatsReversed = clonedSuperchats.sort(function(a,b) { + if (a.is_fiat === b.is_fiat) { + return b.support_amount - a.support_amount; + } else { + return (a.is_fiat === b.is_fiat) ? 0 : a.is_fiat ? -1 : 1; + } + }).reverse(); + } + // todo: implement comment_list --mine in SDK so redux can grab with selectCommentIsMine function isMyComment(channelId: string) { if (myChannels != null && channelId != null) { @@ -71,6 +104,7 @@ export default function LivestreamComments(props: Props) { } React.useEffect(() => { + if (claimId) { doCommentList(uri, '', 1, 75); doSuperChatList(uri); @@ -132,24 +166,38 @@ export default function LivestreamComments(props: Props) {
{__('Live discussion')}
{superChatsTotalAmount > 0 && (
+ + {/* the superchats in chronological order button */}
)} @@ -187,9 +235,23 @@ export default function LivestreamComments(props: Props) { )} + {/* top to bottom comment display */} {!fetchingComments && comments.length > 0 ? (
- {commentsToDisplay.map((comment) => ( + {viewMode === VIEW_MODE_CHAT && commentsToDisplay.map((comment) => ( + + ))} + + {viewMode === VIEW_MODE_SUPER_CHAT && superChatsReversed && superChatsReversed.map((comment) => ( ) { - const tipAmount = parseFloat(event.target.value); + var countDecimals = function(value) { + var text = value.toString(); + var index = text.indexOf('.'); + return (text.length - index - 1); + } - setCustomTipAmount(tipAmount); + function handleCustomPriceChange(event: SyntheticInputEvent<*>) { + + let tipAmountAsString = event.target.value; + + let tipAmount = parseFloat(tipAmountAsString); + + const howManyDecimals = countDecimals(tipAmountAsString); + + // allow maximum two decimals + if (activeTab === TAB_FIAT) { + + if (Number.isNaN(tipAmount)) { + setCustomTipAmount(''); + } + + if (howManyDecimals > 2) { + tipAmount = Math.floor(tipAmount * 100) / 100; + } + + const howManyDigits = Math.trunc(tipAmount).toString().length; + + if (howManyDigits > 4 && tipAmount !== 1000) { + setTipError('Amount cannot be over 1000 dollars'); + } else if (tipAmount > 1000) { + setTipError('Amount cannot be over 1000 dollars'); + setCustomTipAmount(tipAmount); + } else { + setCustomTipAmount(tipAmount); + } + } else { + if (howManyDecimals > 9) { + tipAmount = Number(tipAmount.toString().match(/^-?\d+(?:\.\d{0,8})?/)[0]); + + setTipError('Please only use up to 8 decimals') + } + setCustomTipAmount(tipAmount); + } } function buildButtonText() { @@ -331,8 +370,14 @@ function WalletSendTip(props: Props) { return false; } + function convertToTwoDecimals(number){ + return (Math.round(number * 100) / 100).toFixed(2); + } + + const amountToShow = activeTab === TAB_FIAT ? convertToTwoDecimals(tipAmount) : tipAmount; + // if it's a valid number display it, otherwise do an empty string - const displayAmount = !isNan(tipAmount) ? tipAmount : ''; + const displayAmount = !isNan(tipAmount) ? amountToShow : ''; if (activeTab === TAB_BOOST) { return (claimIsMine ? __('Boost Your %claimTypeText%', {claimTypeText}) : __('Boost This %claimTypeText%', {claimTypeText})); @@ -362,7 +407,7 @@ function WalletSendTip(props: Props) { return (
{/* if there is no LBC balance, show user frontend to get credits */} - {noBalance ? ( + {1 == 2 ? ( }}>Supporting content requires %lbc%} subtitle={ @@ -444,7 +489,7 @@ function WalletSendTip(props: Props) { {/* short explainer under the button */}
- {explainerText} + {explainerText + ' '} {/* {activeTab === TAB_FIAT && !hasCardSaved &&
@@ -464,7 +509,7 @@ function WalletSendTip(props: Props) {
{setConfirmLabel()}
- {activeTab === TAB_FIAT ?

$ {tipAmount}

: } + {activeTab === TAB_FIAT ?

$ {(Math.round(tipAmount * 100) / 100).toFixed(2)}

: }
@@ -479,8 +524,10 @@ function WalletSendTip(props: Props) {