different freebie rules
This commit is contained in:
parent
03e0646560
commit
431947eeee
|
@ -2,7 +2,7 @@ import { useState } from 'react'
|
|||
import { Modal } from 'react-bootstrap'
|
||||
import InfoIcon from '../svgs/information-fill.svg'
|
||||
|
||||
export default function Info ({ children }) {
|
||||
export default function Info ({ children, iconClassName = 'fill-theme-color' }) {
|
||||
const [info, setInfo] = useState()
|
||||
|
||||
return (
|
||||
|
@ -17,7 +17,7 @@ export default function Info ({ children }) {
|
|||
</Modal.Body>
|
||||
</Modal>
|
||||
<InfoIcon
|
||||
width={18} height={18} className='fill-theme-color pointer ml-1'
|
||||
width={18} height={18} className={`${iconClassName} pointer ml-1`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setInfo(true)
|
||||
|
|
|
@ -9,6 +9,22 @@ import { LinkForm } from './link-form'
|
|||
import { PollForm } from './poll-form'
|
||||
import { BountyForm } from './bounty-form'
|
||||
import SubSelect from './sub-select-form'
|
||||
import Info from './info'
|
||||
|
||||
function FreebieDialog () {
|
||||
return (
|
||||
<div className='text-center mb-4 text-muted'>
|
||||
you have no sats, so this one is on us
|
||||
<Info>
|
||||
<ul className='font-weight-bold'>
|
||||
<li>Free posts have limited visibility and are hidden on the recent tab until other stackers zap them.</li>
|
||||
<li>Free posts will not cover posts that cost more than 1 sat.</li>
|
||||
<li>To get fully visibile and unrestricted posts right away, fund your account with a few sats or earn some on Stacker News.</li>
|
||||
</ul>
|
||||
</Info>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function PostForm ({ type, sub, children }) {
|
||||
const me = useMe()
|
||||
|
@ -18,9 +34,7 @@ export function PostForm ({ type, sub, children }) {
|
|||
if (!type) {
|
||||
return (
|
||||
<div className='align-items-center'>
|
||||
{me?.freePosts && me?.sats < 1
|
||||
? <div className='text-center font-weight-bold mb-3 text-success'>{me.freePosts} free posts left</div>
|
||||
: null}
|
||||
{me?.sats < 1 && <FreebieDialog />}
|
||||
<SubSelect noForm sub={sub?.name} />
|
||||
<Link href={prefix + '/post?type=link'}>
|
||||
<Button variant='secondary'>link</Button>
|
||||
|
@ -29,7 +43,7 @@ export function PostForm ({ type, sub, children }) {
|
|||
<Link href={prefix + '/post?type=discussion'}>
|
||||
<Button variant='secondary'>discussion</Button>
|
||||
</Link>
|
||||
<div className='d-flex mt-3'>
|
||||
<div className='d-flex mt-4'>
|
||||
<AccordianItem
|
||||
headerColor='#6c757d'
|
||||
header={<div className='font-weight-bold text-muted'>more types</div>}
|
||||
|
|
|
@ -9,6 +9,7 @@ import Link from 'next/link'
|
|||
import FeeButton from './fee-button'
|
||||
import { commentsViewedAfterComment } from '../lib/new-comments'
|
||||
import { commentSchema } from '../lib/validate'
|
||||
import Info from './info'
|
||||
|
||||
export function ReplyOnAnotherPage ({ parentId }) {
|
||||
return (
|
||||
|
@ -18,6 +19,21 @@ export function ReplyOnAnotherPage ({ parentId }) {
|
|||
)
|
||||
}
|
||||
|
||||
function FreebieDialog () {
|
||||
return (
|
||||
<div className='text-muted'>
|
||||
you have no sats, so this one is on us
|
||||
<Info>
|
||||
<ul className='font-weight-bold'>
|
||||
<li>Free comments have limited visibility and are listed at the bottom of the comment section until other stackers zap them.</li>
|
||||
<li>Free comments will not cover comments that cost more than 1 sat.</li>
|
||||
<li>To get fully visibile and unrestricted comments right away, fund your account with a few sats or earn some on Stacker News.</li>
|
||||
</ul>
|
||||
</Info>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Reply ({ item, onSuccess, replyOpen, children, placeholder }) {
|
||||
const [reply, setReply] = useState(replyOpen)
|
||||
const me = useMe()
|
||||
|
@ -117,7 +133,7 @@ export default function Reply ({ item, onSuccess, replyOpen, children, placehold
|
|||
autoFocus={!replyOpen}
|
||||
required
|
||||
placeholder={placeholder}
|
||||
hint={me?.freeComments && me?.sats < 1 ? <span className='text-success'>{me.freeComments} free comments left</span> : null}
|
||||
hint={me?.sats < 1 && <FreebieDialog />}
|
||||
innerRef={replyInput}
|
||||
/>
|
||||
{reply &&
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
CREATE OR REPLACE FUNCTION create_item(
|
||||
sub TEXT, title TEXT, url TEXT, text TEXT, boost INTEGER, bounty INTEGER,
|
||||
parent_id INTEGER, user_id INTEGER, fwd_user_id INTEGER,
|
||||
spam_within INTERVAL)
|
||||
RETURNS "Item"
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
user_msats BIGINT;
|
||||
cost_msats BIGINT;
|
||||
freebie BOOLEAN;
|
||||
item "Item";
|
||||
med_votes FLOAT;
|
||||
BEGIN
|
||||
PERFORM ASSERT_SERIALIZED();
|
||||
|
||||
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
||||
|
||||
cost_msats := 1000 * POWER(10, item_spam(parent_id, user_id, spam_within));
|
||||
-- it's only a freebie if it's a 1 sat cost, they have < 1 sat, boost = 0, and they have freebies left
|
||||
freebie := (cost_msats <= 1000) AND (user_msats < 1000) AND (boost = 0);
|
||||
|
||||
IF NOT freebie AND cost_msats > user_msats THEN
|
||||
RAISE EXCEPTION 'SN_INSUFFICIENT_FUNDS';
|
||||
END IF;
|
||||
|
||||
-- get this user's median item score
|
||||
SELECT COALESCE(percentile_cont(0.5) WITHIN GROUP(ORDER BY "weightedVotes" - "weightedDownVotes"), 0) INTO med_votes FROM "Item" WHERE "userId" = user_id;
|
||||
|
||||
-- if their median votes are positive, start at 0
|
||||
-- if the median votes are negative, start their post with that many down votes
|
||||
-- basically: if their median post is bad, presume this post is too
|
||||
IF med_votes >= 0 THEN
|
||||
med_votes := 0;
|
||||
ELSE
|
||||
med_votes := ABS(med_votes);
|
||||
END IF;
|
||||
|
||||
INSERT INTO "Item"
|
||||
("subName", title, url, text, bounty, "userId", "parentId", "fwdUserId",
|
||||
freebie, "weightedDownVotes", created_at, updated_at)
|
||||
VALUES
|
||||
(sub, title, url, text, bounty, user_id, parent_id, fwd_user_id,
|
||||
freebie, med_votes, now_utc(), now_utc()) RETURNING * INTO item;
|
||||
|
||||
IF NOT freebie THEN
|
||||
UPDATE users SET msats = msats - cost_msats WHERE id = user_id;
|
||||
|
||||
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
||||
VALUES (cost_msats, item.id, user_id, 'FEE', now_utc(), now_utc());
|
||||
END IF;
|
||||
|
||||
IF boost > 0 THEN
|
||||
PERFORM item_act(item.id, user_id, 'BOOST', boost);
|
||||
END IF;
|
||||
|
||||
RETURN item;
|
||||
END;
|
||||
$$;
|
Loading…
Reference in New Issue