CommentCreate: handle minimum tips

To avoid calling `setting.Get` excessively, we'll do the following:

(a) Call `setting.Get` once per encountered channel, and stash it.

(b) Before sending **each** comment **with a tip**, call `setting.Get` again to get the latest `min_tip`. Report any over- or under-paid values in the confirmation widget before user hits Send.

(c) For regular comments (no tips), just send as normal based on stashed data from `a`.
    - If `min_tip` was `0` but creator later changed to non-zero, Commentron would trigger an error anyway, and the app can get the latest `min_tip` amount to inform the user.
    - If `min_tip` was not `0` but creator later changed to `0`, the app would be incorrectly forcing the user to pay based on the old amount from `a`.  But when he hits `b`, he now knows he has overpaid, and can still cancel.
This commit is contained in:
infinite-persistence 2021-08-04 16:54:20 +08:00
parent 635b0a0c15
commit 0e0e2359f2
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0

View file

@ -15,6 +15,7 @@ import WalletTipAmountSelector from 'component/walletTipAmountSelector';
import CreditAmount from 'component/common/credit-amount';
import ChannelThumbnail from 'component/channelThumbnail';
import UriIndicator from 'component/uriIndicator';
import I18nMessage from 'component/i18nMessage';
import Empty from 'component/common/empty';
import { Lbryio } from 'lbryinc';
import { getChannelIdFromClaim } from 'util/claim';
@ -97,6 +98,17 @@ export function CommentCreate(props: Props) {
const [shouldDisableReviewButton, setShouldDisableReviewButton] = React.useState();
const channelId = getChannelIdFromClaim(claim);
const channelSettings = channelId ? settingsByChannelId[channelId] : undefined;
const minTip = (channelSettings && channelSettings.min_tip_amount_comment) || 0;
const minTipMet = minTip === 0 || tipAmount >= minTip;
const MinTipNotice =
minTip !== 0 ? (
<div className="help--notice">
<I18nMessage tokens={{ lbc: <CreditAmount noFormat amount={minTip} /> }}>
This channel requires a minimum tip of %lbc% to post a comment.
</I18nMessage>
</div>
) : null;
function handleCommentChange(event) {
let commentValue;
@ -125,6 +137,14 @@ export function CommentCreate(props: Props) {
window.removeEventListener('keydown', altEnterListener);
}
function handleReview() {
if (channelId) {
// Get the latest minTip value for final review.
doFetchCreatorSettings(channelId);
}
setIsReviewingSupportComment(true);
}
function handleSubmit() {
if (activeChannelClaim && commentValue.length) {
handleCreateComment();
@ -238,7 +258,7 @@ export function CommentCreate(props: Props) {
}
/**
*
* handleCreateComment
* @param {string} [txid] Optional transaction id generated by
* @param {string} [payment_intent_id] Optional payment_intent_id from Stripe payment
* @param {string} [environment] Optional environment for Stripe (test|live)
@ -271,6 +291,7 @@ export function CommentCreate(props: Props) {
setAdvancedEditor(!advancedEditor);
}
// Fetch channel constraints if not already.
React.useEffect(() => {
if (!channelSettings && channelId) {
doFetchCreatorSettings(channelId);
@ -333,7 +354,7 @@ export function CommentCreate(props: Props) {
<Button
autoFocus
button="primary"
disabled={disabled}
disabled={disabled || !minTipMet}
label={
isSubmitting
? __('Sending...')
@ -344,6 +365,7 @@ export function CommentCreate(props: Props) {
onClick={handleSupportComment}
/>
<Button button="link" label={__('Cancel')} onClick={() => setIsReviewingSupportComment(false)} />
{MinTipNotice}
</div>
</div>
);
@ -397,34 +419,36 @@ export function CommentCreate(props: Props) {
{isSupportComment ? (
<>
<Button
disabled={disabled || tipError || shouldDisableReviewButton}
disabled={disabled || tipError || shouldDisableReviewButton || !minTipMet}
type="button"
button="primary"
icon={activeTab === TAB_LBC ? ICONS.LBC : ICONS.FINANCE}
label={__('Review')}
onClick={() => setIsReviewingSupportComment(true)}
onClick={handleReview}
/>
<Button disabled={disabled} button="link" label={__('Cancel')} onClick={() => setIsSupportComment(false)} />
</>
) : (
<>
<Button
ref={buttonRef}
button="primary"
disabled={disabled}
type="submit"
label={
isReply
? isSubmitting
? __('Replying...')
: __('Reply')
: isSubmitting
? __('Commenting...')
: __('Comment --[button to submit something]--')
}
requiresAuth={IS_WEB}
/>
{minTip === 0 && (
<Button
ref={buttonRef}
button="primary"
disabled={disabled}
type="submit"
label={
isReply
? isSubmitting
? __('Replying...')
: __('Reply')
: isSubmitting
? __('Commenting...')
: __('Comment --[button to submit something]--')
}
requiresAuth={IS_WEB}
/>
)}
{!claimIsMine && (
<Button
disabled={disabled}
@ -449,7 +473,7 @@ export function CommentCreate(props: Props) {
}}
/>
)}
{isReply && (
{isReply && minTip === 0 && (
<Button
button="link"
label={__('Cancel')}
@ -462,6 +486,7 @@ export function CommentCreate(props: Props) {
)}
</>
)}
{MinTipNotice}
</div>
</Form>
);