stacker.news/components/adv-post-form.js
SatsAllDay 3da395a792
multiple forwards on a post (#403)
* multiple forwards on a post

first phase of the multi-forward support

* update the graphql mutation for discussion posts to accept and validate multiple forwards

* update the discussion form to allow multiple forwards in the UI

* start working on db schema changes

* uncomment db schema, add migration to create the new model, and update create_item, update_item
stored procedures

* Propagate updates from discussion to poll, link, and bounty forms

Update the create, update poll sql functions for multi forward support

* Update gql, typedefs, and resolver to return forwarded users in items responses

* UI changes to show multiple forward recipients, and conditional upvote logic changes

* Update notification text to reflect multiple forwards upon vote action

* Disallow duplicate stacker entries

* reduce duplication in populating adv-post-form initial values

* Update item_act sql function to implement multi-way forwarding

* Update referral functions to scale referral bonuses for forwarded users

* Update notification text to reflect non-100% forwarded sats cases

* Update wallet history sql queries to accommodate multi-forward use cases

* Block zaps for posts you are forwarded zaps at the API layer, in addition
to in the UI

* Delete fwdUserId column from Item table as part of migration

* Fix how we calculate stacked sats after partial forwards in wallet history

* Exclude entries from wallet history that are 0 stacked sats from posts with 100% forwarded to other users

* Fix wallet history query for forwarded stacked sats to be scaled by the fwd pct

* Reduce duplication in adv post form, and do some style tweaks for better layout

* Use MAX_FORWARDS constants

* Address various PR feedback

* first enhancement pass

* enhancement pass too

---------

Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2023-08-23 17:44:17 -05:00

84 lines
3.1 KiB
JavaScript

import AccordianItem from './accordian-item'
import { Input, InputUserSuggest, VariableInput } from './form'
import InputGroup from 'react-bootstrap/InputGroup'
import { BOOST_MIN, MAX_FORWARDS } from '../lib/constants'
import Info from './info'
import { numWithUnits } from '../lib/format'
const EMPTY_FORWARD = { nym: '', pct: '' }
export function AdvPostInitial ({ forward }) {
return {
boost: '',
forward: forward?.length ? forward : [EMPTY_FORWARD]
}
}
export default function AdvPostForm ({ edit }) {
return (
<AccordianItem
header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>options</div>}
body={
<>
<Input
label={
<div className='d-flex align-items-center'>{edit ? 'add boost' : 'boost'}
<Info>
<ol className='fw-bold'>
<li>Boost ranks posts higher temporarily based on the amount</li>
<li>The minimum boost is {numWithUnits(BOOST_MIN, { abbreviate: false })}</li>
<li>Each {numWithUnits(BOOST_MIN, { abbreviate: false })} of boost is equivalent to one trusted upvote
<ul>
<li>e.g. {numWithUnits(BOOST_MIN * 2, { abbreviate: false })} is like 2 votes</li>
</ul>
</li>
<li>The decay of boost "votes" increases at 2x the rate of organic votes
<ul>
<li>i.e. boost votes fall out of ranking faster</li>
</ul>
</li>
<li>100% of sats from boost are given back to top stackers as rewards</li>
</ol>
</Info>
</div>
}
name='boost'
hint={<span className='text-muted'>ranks posts higher temporarily based on the amount</span>}
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
/>
<VariableInput
label='forward sats to'
name='forward'
min={0}
max={MAX_FORWARDS}
emptyItem={EMPTY_FORWARD}
hint={<span className='text-muted'>Forward sats to up to 5 other stackers. Any remaining sats go to you.</span>}
>
{({ index, placeholder }) => {
return (
<div key={index} className='d-flex flex-row'>
<InputUserSuggest
name={`forward[${index}].nym`}
prepend={<InputGroup.Text>@</InputGroup.Text>}
showValid
groupClassName='flex-grow-1 me-3 mb-0'
/>
<Input
name={`forward[${index}].pct`}
type='number'
step='1'
min='1'
max='100'
append={<InputGroup.Text className='text-monospace'>%</InputGroup.Text>}
groupClassName='flex-shrink-1 mb-0'
/>
</div>
)
}}
</VariableInput>
</>
}
/>
)
}