variable downzaps
This commit is contained in:
		
							parent
							
								
									25d2c58559
								
							
						
					
					
						commit
						7d170a654f
					
				@ -834,7 +834,7 @@ export default {
 | 
				
			|||||||
        sats
 | 
					        sats
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    dontLikeThis: async (parent, { id, hash, hmac }, { me, models }) => {
 | 
					    dontLikeThis: async (parent, { id, sats, hash, hmac }, { me, models }) => {
 | 
				
			||||||
      // need to make sure we are logged in
 | 
					      // need to make sure we are logged in
 | 
				
			||||||
      if (!me) {
 | 
					      if (!me) {
 | 
				
			||||||
        throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } })
 | 
					        throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } })
 | 
				
			||||||
@ -856,7 +856,7 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      const trx = [
 | 
					      const trx = [
 | 
				
			||||||
        models.$queryRaw`SELECT item_act(${Number(id)}::INTEGER,
 | 
					        models.$queryRaw`SELECT item_act(${Number(id)}::INTEGER,
 | 
				
			||||||
        ${me.id}::INTEGER, 'DONT_LIKE_THIS', ${DONT_LIKE_THIS_COST}::INTEGER)`
 | 
					        ${me.id}::INTEGER, 'DONT_LIKE_THIS', ${sats || DONT_LIKE_THIS_COST}::INTEGER)`
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
      if (invoice) {
 | 
					      if (invoice) {
 | 
				
			||||||
        trx.unshift(models.$queryRaw`UPDATE users SET msats = msats + ${invoice.msatsReceived} WHERE id = ${invoice.user.id}`)
 | 
					        trx.unshift(models.$queryRaw`UPDATE users SET msats = msats + ${invoice.msatsReceived} WHERE id = ${invoice.user.id}`)
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ export default gql`
 | 
				
			|||||||
      text: String!, url: String!, maxBid: Int!, status: String, logo: Int, hash: String, hmac: String): Item!
 | 
					      text: String!, url: String!, maxBid: Int!, status: String, logo: Int, hash: String, hmac: String): Item!
 | 
				
			||||||
    upsertPoll(id: ID, sub: String, title: String!, text: String, options: [String!]!, boost: Int, forward: [ItemForwardInput], hash: String, hmac: String): Item!
 | 
					    upsertPoll(id: ID, sub: String, title: String!, text: String, options: [String!]!, boost: Int, forward: [ItemForwardInput], hash: String, hmac: String): Item!
 | 
				
			||||||
    upsertComment(id:ID, text: String!, parentId: ID, hash: String, hmac: String): Item!
 | 
					    upsertComment(id:ID, text: String!, parentId: ID, hash: String, hmac: String): Item!
 | 
				
			||||||
    dontLikeThis(id: ID!, hash: String, hmac: String): Boolean!
 | 
					    dontLikeThis(id: ID!, sats: Int, hash: String, hmac: String): Boolean!
 | 
				
			||||||
    act(id: ID!, sats: Int, hash: String, hmac: String): ItemActResult!
 | 
					    act(id: ID!, sats: Int, hash: String, hmac: String): ItemActResult!
 | 
				
			||||||
    pollVote(id: ID!, hash: String, hmac: String): ID!
 | 
					    pollVote(id: ID!, hash: String, hmac: String): ID!
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ import { useShowModal } from './modal'
 | 
				
			|||||||
import { useToast } from './toast'
 | 
					import { useToast } from './toast'
 | 
				
			||||||
import { InvoiceModal, payOrLoginError } from './invoice'
 | 
					import { InvoiceModal, payOrLoginError } from './invoice'
 | 
				
			||||||
import { DONT_LIKE_THIS_COST } from '../lib/constants'
 | 
					import { DONT_LIKE_THIS_COST } from '../lib/constants'
 | 
				
			||||||
 | 
					import ItemAct from './item-act'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function DontLikeThisDropdownItem ({ id }) {
 | 
					export default function DontLikeThisDropdownItem ({ id }) {
 | 
				
			||||||
  const toaster = useToast()
 | 
					  const toaster = useToast()
 | 
				
			||||||
@ -11,8 +12,8 @@ export default function DontLikeThisDropdownItem ({ id }) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const [dontLikeThis] = useMutation(
 | 
					  const [dontLikeThis] = useMutation(
 | 
				
			||||||
    gql`
 | 
					    gql`
 | 
				
			||||||
      mutation dontLikeThis($id: ID!, $hash: String, $hmac: String) {
 | 
					      mutation dontLikeThis($id: ID!, $sats: Int, $hash: String, $hmac: String) {
 | 
				
			||||||
        dontLikeThis(id: $id, hash: $hash, hmac: $hmac)
 | 
					        dontLikeThis(id: $id, sats: $sats, hash: $hash, hmac: $hmac)
 | 
				
			||||||
      }`, {
 | 
					      }`, {
 | 
				
			||||||
      update (cache) {
 | 
					      update (cache) {
 | 
				
			||||||
        cache.modify({
 | 
					        cache.modify({
 | 
				
			||||||
@ -31,11 +32,13 @@ export default function DontLikeThisDropdownItem ({ id }) {
 | 
				
			|||||||
    <Dropdown.Item
 | 
					    <Dropdown.Item
 | 
				
			||||||
      onClick={async () => {
 | 
					      onClick={async () => {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          await dontLikeThis({
 | 
					          showModal(onClose =>
 | 
				
			||||||
            variables: { id },
 | 
					            <ItemAct
 | 
				
			||||||
            optimisticResponse: { dontLikeThis: true }
 | 
					              onClose={() => {
 | 
				
			||||||
          })
 | 
					                onClose()
 | 
				
			||||||
          toaster.success('item flagged')
 | 
					                toaster.success('item flagged')
 | 
				
			||||||
 | 
					              }} itemId={id} act={dontLikeThis} down
 | 
				
			||||||
 | 
					            />)
 | 
				
			||||||
        } catch (error) {
 | 
					        } catch (error) {
 | 
				
			||||||
          console.error(error)
 | 
					          console.error(error)
 | 
				
			||||||
          if (payOrLoginError(error)) {
 | 
					          if (payOrLoginError(error)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,7 @@ const addCustomTip = (amount) => {
 | 
				
			|||||||
  window.localStorage.setItem('custom-tips', JSON.stringify(customTips))
 | 
					  window.localStorage.setItem('custom-tips', JSON.stringify(customTips))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function ItemAct ({ onClose, itemId, act, strike }) {
 | 
					export default function ItemAct ({ onClose, itemId, act, down, strike }) {
 | 
				
			||||||
  const inputRef = useRef(null)
 | 
					  const inputRef = useRef(null)
 | 
				
			||||||
  const me = useMe()
 | 
					  const me = useMe()
 | 
				
			||||||
  const [oValue, setOValue] = useState()
 | 
					  const [oValue, setOValue] = useState()
 | 
				
			||||||
@ -59,7 +59,7 @@ export default function ItemAct ({ onClose, itemId, act, strike }) {
 | 
				
			|||||||
        hmac
 | 
					        hmac
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    await strike()
 | 
					    strike && await strike()
 | 
				
			||||||
    addCustomTip(Number(amount))
 | 
					    addCustomTip(Number(amount))
 | 
				
			||||||
    onClose()
 | 
					    onClose()
 | 
				
			||||||
  }, [act])
 | 
					  }, [act])
 | 
				
			||||||
@ -88,7 +88,7 @@ export default function ItemAct ({ onClose, itemId, act, strike }) {
 | 
				
			|||||||
        <Tips setOValue={setOValue} />
 | 
					        <Tips setOValue={setOValue} />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div className='d-flex'>
 | 
					      <div className='d-flex'>
 | 
				
			||||||
        <SubmitButton variant='success' className='ms-auto mt-1 px-4' value='TIP'>zap</SubmitButton>
 | 
					        <SubmitButton variant={down ? 'danger' : 'success'} className='ms-auto mt-1 px-4' value='TIP'>{down && 'down '}zap</SubmitButton>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Form>
 | 
					    </Form>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
				
			|||||||
@ -136,7 +136,7 @@ export default function ItemInfo ({
 | 
				
			|||||||
          <Link href={`/items/${item.id}/ots`} className='text-reset dropdown-item'>
 | 
					          <Link href={`/items/${item.id}/ots`} className='text-reset dropdown-item'>
 | 
				
			||||||
            ots timestamp
 | 
					            ots timestamp
 | 
				
			||||||
          </Link>}
 | 
					          </Link>}
 | 
				
			||||||
        {me && !item.meSats && !item.position && !item.meDontLike &&
 | 
					        {me && !item.meSats && !item.position &&
 | 
				
			||||||
          !item.mine && !item.deletedAt && <DontLikeThisDropdownItem id={item.id} />}
 | 
					          !item.mine && !item.deletedAt && <DontLikeThisDropdownItem id={item.id} />}
 | 
				
			||||||
        {item.mine && !item.position && !item.deletedAt &&
 | 
					        {item.mine && !item.position && !item.deletedAt &&
 | 
				
			||||||
          <DeleteDropdownItem itemId={item.id} type={item.title ? 'post' : 'comment'} />}
 | 
					          <DeleteDropdownItem itemId={item.id} type={item.title ? 'post' : 'comment'} />}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										115
									
								
								prisma/migrations/20230914005420_variable_down_zap/migration.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								prisma/migrations/20230914005420_variable_down_zap/migration.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					DROP FUNCTION weighted_downvotes_after_act(item_id INTEGER, user_id INTEGER, sats INTEGER);
 | 
				
			||||||
 | 
					CREATE OR REPLACE FUNCTION weighted_downvotes_after_act(item_id INTEGER, user_id INTEGER, sats INTEGER) RETURNS INTEGER AS $$
 | 
				
			||||||
 | 
					DECLARE
 | 
				
			||||||
 | 
					    user_trust DOUBLE PRECISION;
 | 
				
			||||||
 | 
					    sats_past INTEGER;
 | 
				
			||||||
 | 
					    multiplier DOUBLE PRECISION;
 | 
				
			||||||
 | 
					BEGIN
 | 
				
			||||||
 | 
					    -- grab user's trust who is upvoting
 | 
				
			||||||
 | 
					    SELECT trust INTO user_trust FROM users WHERE id = user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- in order to add this to weightedVotes, we need to do log((satsN+satsPrior)/satsPrior)
 | 
				
			||||||
 | 
					    -- so compute sats prior
 | 
				
			||||||
 | 
					    SELECT SUM(msats) / 1000 INTO sats_past
 | 
				
			||||||
 | 
					    FROM "ItemAct"
 | 
				
			||||||
 | 
					    WHERE "userId" = user_id AND "itemId" = item_id AND act IN ('DONT_LIKE_THIS');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IF sats_past IS NULL OR sats_past = 0 THEN
 | 
				
			||||||
 | 
					        multiplier := LOG(sats);
 | 
				
			||||||
 | 
					    ELSE
 | 
				
			||||||
 | 
					        multiplier := LOG((sats+sats_past)/sats_past::FLOAT);
 | 
				
			||||||
 | 
					    END IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- update item
 | 
				
			||||||
 | 
					    UPDATE "Item"
 | 
				
			||||||
 | 
					        SET "weightedDownVotes" = "weightedDownVotes" + (user_trust * multiplier)
 | 
				
			||||||
 | 
					        WHERE id = item_id AND "userId" <> user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RETURN 0;
 | 
				
			||||||
 | 
					END;
 | 
				
			||||||
 | 
					$$ LANGUAGE plpgsql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Update item_act to support multiple dont_like_this
 | 
				
			||||||
 | 
					CREATE OR REPLACE FUNCTION item_act(item_id INTEGER, user_id INTEGER, act "ItemActType", act_sats INTEGER)
 | 
				
			||||||
 | 
					RETURNS INTEGER
 | 
				
			||||||
 | 
					LANGUAGE plpgsql
 | 
				
			||||||
 | 
					AS $$
 | 
				
			||||||
 | 
					DECLARE
 | 
				
			||||||
 | 
					    user_msats BIGINT;
 | 
				
			||||||
 | 
					    act_msats BIGINT;
 | 
				
			||||||
 | 
					    fee_msats BIGINT;
 | 
				
			||||||
 | 
					    item_act_id INTEGER;
 | 
				
			||||||
 | 
					    fwd_entry record; -- for loop iterator variable to iterate across forward recipients
 | 
				
			||||||
 | 
					    fwd_msats BIGINT; -- for loop variable calculating how many msats to give each forward recipient
 | 
				
			||||||
 | 
					    total_fwd_msats BIGINT := 0; -- accumulator to see how many msats have been forwarded for the act
 | 
				
			||||||
 | 
					BEGIN
 | 
				
			||||||
 | 
					    PERFORM ASSERT_SERIALIZED();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    act_msats := act_sats * 1000;
 | 
				
			||||||
 | 
					    SELECT msats INTO user_msats FROM users WHERE id = user_id;
 | 
				
			||||||
 | 
					    IF act_msats > user_msats THEN
 | 
				
			||||||
 | 
					        RAISE EXCEPTION 'SN_INSUFFICIENT_FUNDS';
 | 
				
			||||||
 | 
					    END IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- deduct msats from actor
 | 
				
			||||||
 | 
					    UPDATE users SET msats = msats - act_msats WHERE id = user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IF act = 'TIP' THEN
 | 
				
			||||||
 | 
					        -- call to influence weightedVotes ... we need to do this before we record the acts because
 | 
				
			||||||
 | 
					        -- the priors acts are taken into account
 | 
				
			||||||
 | 
					        PERFORM weighted_votes_after_tip(item_id, user_id, act_sats);
 | 
				
			||||||
 | 
					        -- call to denormalize sats and commentSats
 | 
				
			||||||
 | 
					        PERFORM sats_after_tip(item_id, user_id, act_msats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- take 10% and insert as FEE
 | 
				
			||||||
 | 
					        fee_msats := CEIL(act_msats * 0.1);
 | 
				
			||||||
 | 
					        act_msats := act_msats - fee_msats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- save the fee act into item_act_id so we can record referral acts
 | 
				
			||||||
 | 
					        INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
 | 
				
			||||||
 | 
					            VALUES (fee_msats, item_id, user_id, 'FEE', now_utc(), now_utc())
 | 
				
			||||||
 | 
					            RETURNING id INTO item_act_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- leave the rest as a tip
 | 
				
			||||||
 | 
					        INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
 | 
				
			||||||
 | 
					            VALUES (act_msats, item_id, user_id, 'TIP', now_utc(), now_utc());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- denormalize bounty paid (if applicable)
 | 
				
			||||||
 | 
					        PERFORM bounty_paid_after_act(item_id, user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- add sats to actees' balance and stacked count
 | 
				
			||||||
 | 
					        FOR fwd_entry IN SELECT "userId", "pct" FROM "ItemForward" WHERE "itemId" = item_id
 | 
				
			||||||
 | 
					        LOOP
 | 
				
			||||||
 | 
					            -- fwd_msats represents the sats for this forward recipient from this particular tip action
 | 
				
			||||||
 | 
					            fwd_msats := act_msats * fwd_entry.pct / 100;
 | 
				
			||||||
 | 
					            -- keep track of how many msats have been forwarded, so we can give any remaining to OP
 | 
				
			||||||
 | 
					            total_fwd_msats := fwd_msats + total_fwd_msats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            UPDATE users
 | 
				
			||||||
 | 
					            SET msats = msats + fwd_msats, "stackedMsats" = "stackedMsats" + fwd_msats
 | 
				
			||||||
 | 
					            WHERE id = fwd_entry."userId";
 | 
				
			||||||
 | 
					        END LOOP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- Give OP any remaining msats after forwards have been applied
 | 
				
			||||||
 | 
					        IF act_msats - total_fwd_msats > 0 THEN
 | 
				
			||||||
 | 
					            UPDATE users
 | 
				
			||||||
 | 
					            SET msats = msats + act_msats - total_fwd_msats, "stackedMsats" = "stackedMsats" + act_msats - total_fwd_msats
 | 
				
			||||||
 | 
					            WHERE id = (SELECT "userId" FROM "Item" WHERE id = item_id);
 | 
				
			||||||
 | 
					        END IF;
 | 
				
			||||||
 | 
					    ELSE -- BOOST, POLL, DONT_LIKE_THIS, STREAM
 | 
				
			||||||
 | 
					        -- call to influence if DONT_LIKE_THIS weightedDownVotes
 | 
				
			||||||
 | 
					        IF act = 'DONT_LIKE_THIS' THEN
 | 
				
			||||||
 | 
					            PERFORM weighted_downvotes_after_act(item_id, user_id, act_sats);
 | 
				
			||||||
 | 
					        END IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
 | 
				
			||||||
 | 
					            VALUES (act_msats, item_id, user_id, act, now_utc(), now_utc())
 | 
				
			||||||
 | 
					            RETURNING id INTO item_act_id;
 | 
				
			||||||
 | 
					    END IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- store referral effects
 | 
				
			||||||
 | 
					    PERFORM referral_act(item_act_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RETURN 0;
 | 
				
			||||||
 | 
					END;
 | 
				
			||||||
 | 
					$$;
 | 
				
			||||||
@ -11,7 +11,7 @@ function checkInvoice ({ boss, models, lnd }) {
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
      inv = await getInvoice({ id: hash, lnd })
 | 
					      inv = await getInvoice({ id: hash, lnd })
 | 
				
			||||||
    } catch (err) {
 | 
					    } catch (err) {
 | 
				
			||||||
      console.log(err)
 | 
					      console.log(err, hash)
 | 
				
			||||||
      // on lnd related errors, we manually retry so we don't exponentially backoff
 | 
					      // on lnd related errors, we manually retry so we don't exponentially backoff
 | 
				
			||||||
      await boss.send('checkInvoice', { hash }, walletOptions)
 | 
					      await boss.send('checkInvoice', { hash }, walletOptions)
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user