refine tipping experience, removing notion of upvote from UX
This commit is contained in:
parent
b6b5cea1f5
commit
5d49ecc536
|
@ -362,7 +362,7 @@ export default {
|
|||
|
||||
return await updateItem(parent, { id, data: { text } }, { me, models })
|
||||
},
|
||||
act: async (parent, { id, act, sats, tipDefault }, { me, models }) => {
|
||||
act: async (parent, { id, sats }, { me, models }) => {
|
||||
// need to make sure we are logged in
|
||||
if (!me) {
|
||||
throw new AuthenticationError('you must be logged in')
|
||||
|
@ -372,8 +372,7 @@ export default {
|
|||
throw new UserInputError('sats must be positive', { argumentName: 'sats' })
|
||||
}
|
||||
|
||||
// if we are tipping disallow self tips
|
||||
if (act === 'TIP') {
|
||||
// disallow self tips
|
||||
const [item] = await models.$queryRaw(`
|
||||
${SELECT}
|
||||
FROM "Item"
|
||||
|
@ -381,17 +380,12 @@ export default {
|
|||
if (item) {
|
||||
throw new UserInputError('cannot tip your self')
|
||||
}
|
||||
// if tipDefault, set on user
|
||||
if (tipDefault) {
|
||||
await models.user.update({ where: { id: me.id }, data: { tipDefault: sats } })
|
||||
}
|
||||
}
|
||||
|
||||
await serialize(models, models.$queryRaw`SELECT item_act(${Number(id)}, ${me.id}, ${act}, ${Number(sats)})`)
|
||||
const [{ item_act: vote }] = await serialize(models, models.$queryRaw`SELECT item_act(${Number(id)}, ${me.id}, 'TIP', ${Number(sats)})`)
|
||||
|
||||
return {
|
||||
sats,
|
||||
act
|
||||
vote,
|
||||
sats
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -448,6 +442,27 @@ export default {
|
|||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
userId: {
|
||||
not: item.userId
|
||||
},
|
||||
act: {
|
||||
not: 'BOOST'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return sats || 0
|
||||
},
|
||||
upvotes: async (item, args, { models }) => {
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
userId: {
|
||||
not: item.userId
|
||||
},
|
||||
act: 'VOTE'
|
||||
}
|
||||
})
|
||||
|
@ -467,35 +482,6 @@ export default {
|
|||
|
||||
return sats || 0
|
||||
},
|
||||
tips: async (item, args, { models }) => {
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
act: 'TIP'
|
||||
}
|
||||
})
|
||||
|
||||
return sats || 0
|
||||
},
|
||||
meVote: async (item, args, { me, models }) => {
|
||||
if (!me) return 0
|
||||
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
userId: me.id,
|
||||
act: 'VOTE'
|
||||
}
|
||||
})
|
||||
|
||||
return sats || 0
|
||||
},
|
||||
meSats: async (item, args, { me, models }) => {
|
||||
if (!me) return 0
|
||||
|
||||
|
@ -522,22 +508,6 @@ export default {
|
|||
mine: async (item, args, { me, models }) => {
|
||||
return me?.id === item.userId
|
||||
},
|
||||
meTip: async (item, args, { me, models }) => {
|
||||
if (!me) return 0
|
||||
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
userId: me.id,
|
||||
act: 'TIP'
|
||||
}
|
||||
})
|
||||
|
||||
return sats || 0
|
||||
},
|
||||
root: async (item, args, { models }) => {
|
||||
if (!item.parentId) {
|
||||
return null
|
||||
|
|
|
@ -10,15 +10,9 @@ export default gql`
|
|||
dupes(url: String!): [Item!]
|
||||
}
|
||||
|
||||
enum ItemAct {
|
||||
VOTE
|
||||
BOOST
|
||||
TIP
|
||||
}
|
||||
|
||||
type ItemActResult {
|
||||
vote: Int!
|
||||
sats: Int!
|
||||
act: ItemAct!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
|
@ -28,7 +22,7 @@ export default gql`
|
|||
updateDiscussion(id: ID!, title: String!, text: String): Item!
|
||||
createComment(text: String!, parentId: ID!): Item!
|
||||
updateComment(id: ID!, text: String!): Item!
|
||||
act(id: ID!, act: ItemAct!, sats: Int, tipDefault: Boolean): ItemActResult!
|
||||
act(id: ID!, sats: Int): ItemActResult!
|
||||
}
|
||||
|
||||
type Items {
|
||||
|
@ -53,13 +47,11 @@ export default gql`
|
|||
root: Item
|
||||
user: User!
|
||||
depth: Int!
|
||||
sats: Int!
|
||||
boost: Int!
|
||||
tips: Int!
|
||||
mine: Boolean!
|
||||
meVote: Int!
|
||||
boost: Int!
|
||||
sats: Int!
|
||||
upvotes: Int!
|
||||
meSats: Int!
|
||||
meTip: Int!
|
||||
ncomments: Int!
|
||||
comments: [Item!]!
|
||||
path: String
|
||||
|
|
|
@ -79,7 +79,7 @@ export default function Comment ({
|
|||
<div className={`${itemStyles.hunk} ${styles.hunk}`}>
|
||||
<div className='d-flex align-items-center'>
|
||||
<div className={`${itemStyles.other} ${styles.other}`}>
|
||||
<span title={`${item.sats} upvotes \\ ${item.tips} tipped${item.meSats > 0 ? ` (${item.meSats} from me)` : ''}`}>{item.sats + item.tips} sats</span>
|
||||
<span title={`from ${item.upvotes} users (${item.meSats} from me)`}>{item.sats} sats</span>
|
||||
<span> \ </span>
|
||||
{item.boost > 0 &&
|
||||
<>
|
||||
|
|
|
@ -57,13 +57,11 @@ export function ItemActModal () {
|
|||
default: false
|
||||
}}
|
||||
schema={ActSchema}
|
||||
onSubmit={async ({ amount, tipDefault, submit }) => {
|
||||
onSubmit={async ({ amount }) => {
|
||||
await item.act({
|
||||
variables: {
|
||||
id: item.itemId,
|
||||
act: submit,
|
||||
sats: Number(amount),
|
||||
tipDefault
|
||||
sats: Number(amount)
|
||||
}
|
||||
})
|
||||
await item.strike()
|
||||
|
|
|
@ -50,7 +50,7 @@ export default function Item ({ item, rank, children }) {
|
|||
<div className={`${styles.other}`}>
|
||||
{!item.position &&
|
||||
<>
|
||||
<span title={`${item.sats} upvotes \\ ${item.tips} tipped${item.meSats > 0 ? ` (${item.meSats} from me)` : ''}`}>{item.sats + item.tips} sats</span>
|
||||
<span title={`from ${item.upvotes} users (${item.meSats} sats from me)`}>{item.sats} sats</span>
|
||||
<span> \ </span>
|
||||
</>}
|
||||
{item.boost > 0 &&
|
||||
|
|
|
@ -20,7 +20,7 @@ export default function Seo ({ item, user }) {
|
|||
desc = desc.replace(/\s+/g, ' ')
|
||||
}
|
||||
} else {
|
||||
desc = `@${item.user.name} stacked ${(item.sats > 0 ? item.sats - 1 : 0) + item.tips} sats ${item.url ? `posting ${item.url}` : 'with this discussion'}`
|
||||
desc = `@${item.user.name} stacked ${item.sats} sats ${item.url ? `posting ${item.url}` : 'with this discussion'}`
|
||||
}
|
||||
if (item.ncomments) {
|
||||
desc += ` [${item.ncomments} comments`
|
||||
|
|
|
@ -104,60 +104,29 @@ export default function UpVote ({ item, className }) {
|
|||
|
||||
const [act] = useMutation(
|
||||
gql`
|
||||
mutation act($id: ID!, $act: ItemAct! $sats: Int!, $tipDefault: Boolean) {
|
||||
act(id: $id, act: $act, sats: $sats, tipDefault: $tipDefault) {
|
||||
act,
|
||||
mutation act($id: ID!, $sats: Int!) {
|
||||
act(id: $id, sats: $sats) {
|
||||
vote,
|
||||
sats
|
||||
}
|
||||
}`, {
|
||||
update (cache, { data: { act: { act, sats } } }) {
|
||||
// read in the cached object so we don't use meSats prop
|
||||
// which can be stale
|
||||
if (act === 'VOTE') {
|
||||
setVoteShow(true)
|
||||
}
|
||||
if (act === 'TIP') {
|
||||
setTipShow(true)
|
||||
}
|
||||
|
||||
update (cache, { data: { act: { vote, sats } } }) {
|
||||
cache.modify({
|
||||
id: `Item:${item.id}`,
|
||||
fields: {
|
||||
meVote (existingMeVote = 0) {
|
||||
if (act === 'VOTE') {
|
||||
return existingMeVote + sats
|
||||
}
|
||||
return existingMeVote
|
||||
},
|
||||
meTip (existingMeTip = 0) {
|
||||
if (act === 'TIP') {
|
||||
return existingMeTip + sats
|
||||
}
|
||||
return existingMeTip
|
||||
},
|
||||
sats (existingSats = 0) {
|
||||
if (act === 'VOTE') {
|
||||
return existingSats + sats
|
||||
}
|
||||
return existingSats
|
||||
},
|
||||
meSats (existingSats = 0) {
|
||||
if (act === 'VOTE' || act === 'TIP') {
|
||||
if (existingSats === 0) {
|
||||
setVoteShow(true)
|
||||
} else {
|
||||
setTipShow(true)
|
||||
}
|
||||
return existingSats + sats
|
||||
}
|
||||
return existingSats
|
||||
},
|
||||
boost (existingBoost = 0) {
|
||||
if (act === 'BOOST') {
|
||||
return existingBoost + sats
|
||||
}
|
||||
return existingBoost
|
||||
},
|
||||
tips (existingTips = 0) {
|
||||
if (act === 'TIP') {
|
||||
return existingTips + sats
|
||||
}
|
||||
return existingTips
|
||||
upvotes (existingUpvotes = 0) {
|
||||
return existingUpvotes + vote
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -166,15 +135,12 @@ export default function UpVote ({ item, className }) {
|
|||
)
|
||||
|
||||
const overlayText = () => {
|
||||
if (item?.meVote) {
|
||||
if (me?.tipDefault) {
|
||||
return `${me.tipDefault} sat${me.tipDefault > 1 ? 's' : ''}`
|
||||
}
|
||||
return '1 sat'
|
||||
}
|
||||
}
|
||||
|
||||
const noSelfTips = item?.meVote && item?.mine
|
||||
const color = getColor(item?.meSats)
|
||||
return (
|
||||
<LightningConsumer>
|
||||
|
@ -186,7 +152,7 @@ export default function UpVote ({ item, className }) {
|
|||
if (!item || voteLock) return
|
||||
|
||||
// we can't tip ourselves
|
||||
if (noSelfTips) {
|
||||
if (item?.mine) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -200,26 +166,19 @@ export default function UpVote ({ item, className }) {
|
|||
if (!item || voteLock) return
|
||||
|
||||
// we can't tip ourselves
|
||||
if (noSelfTips) {
|
||||
if (item?.mine) {
|
||||
return
|
||||
}
|
||||
|
||||
if (item?.meVote) {
|
||||
if (item?.meSats) {
|
||||
setVoteShow(false)
|
||||
try {
|
||||
strike()
|
||||
await act({ variables: { id: item.id, act: 'TIP', sats: me.tipDefault || 1 } })
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
strike()
|
||||
|
||||
try {
|
||||
setVoteLock(true)
|
||||
await act({ variables: { id: item.id, act: 'VOTE', sats: 1 } })
|
||||
await act({ variables: { id: item.id, sats: me.tipDefault || 1 } })
|
||||
} catch (error) {
|
||||
if (error.toString().includes('insufficient funds')) {
|
||||
setError(true)
|
||||
|
@ -233,9 +192,9 @@ export default function UpVote ({ item, className }) {
|
|||
: signIn
|
||||
}
|
||||
>
|
||||
<ActionTooltip notForm disable={noSelfTips} overlayText={overlayText()}>
|
||||
<ActionTooltip notForm disable={item?.mine} overlayText={overlayText()}>
|
||||
<div
|
||||
className={`${noSelfTips ? styles.noSelfTips : ''}
|
||||
className={`${item?.mine ? styles.noSelfTips : ''}
|
||||
${styles.upvoteWrapper}`}
|
||||
>
|
||||
<UpBolt
|
||||
|
@ -244,7 +203,7 @@ export default function UpVote ({ item, className }) {
|
|||
className={
|
||||
`${styles.upvote}
|
||||
${className || ''}
|
||||
${noSelfTips ? styles.noSelfTips : ''}
|
||||
${item?.mine ? styles.noSelfTips : ''}
|
||||
${item?.meSats ? styles.voted : ''}`
|
||||
}
|
||||
style={item?.meSats
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
padding-right: .2rem;
|
||||
}
|
||||
|
||||
.noSelfTips .upvote.voted {
|
||||
.noSelfTips {
|
||||
fill: transparent !important;
|
||||
filter: none !important;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,9 @@ export const COMMENT_FIELDS = gql`
|
|||
id
|
||||
}
|
||||
sats
|
||||
upvotes
|
||||
boost
|
||||
tips
|
||||
meVote
|
||||
meSats
|
||||
meTip
|
||||
mine
|
||||
ncomments
|
||||
root {
|
||||
|
|
|
@ -13,11 +13,9 @@ export const ITEM_FIELDS = gql`
|
|||
id
|
||||
}
|
||||
sats
|
||||
upvotes
|
||||
boost
|
||||
tips
|
||||
meVote
|
||||
meSats
|
||||
meTip
|
||||
ncomments
|
||||
mine
|
||||
root {
|
||||
|
|
|
@ -37,9 +37,11 @@ BEGIN
|
|||
INSERT INTO "ItemAct" (sats, "itemId", "userId", act, created_at, updated_at)
|
||||
VALUES (act_sats, item_id, user_id, 'TIP', now_utc(), now_utc());
|
||||
END IF;
|
||||
|
||||
RETURN 1;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
RETURN act_sats;
|
||||
RETURN 0;
|
||||
END;
|
||||
$$;
|
Loading…
Reference in New Issue