Skip to content

Commit 195aaec

Browse files
authored
Merge branch 'master' into notification_filters
2 parents cfa1561 + 4262189 commit 195aaec

28 files changed

+236
-61
lines changed

api/paidAction/inviteGift.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export async function perform ({ id, userId }, { me, cost, tx }) {
2121
where: { id, userId: me.id, revoked: false }
2222
})
2323

24-
if (invite.giftedCount >= invite.limit) {
24+
if (invite.limit && invite.giftedCount >= invite.limit) {
2525
throw new Error('invite limit reached')
2626
}
2727

@@ -45,7 +45,7 @@ export async function perform ({ id, userId }, { me, cost, tx }) {
4545
})
4646

4747
return await tx.invite.update({
48-
where: { id, userId: me.id, giftedCount: { lt: invite.limit }, revoked: false },
48+
where: { id, userId: me.id, revoked: false, ...(invite.limit ? { giftedCount: { lt: invite.limit } } : {}) },
4949
data: {
5050
giftedCount: {
5151
increment: 1

api/paidAction/itemCreate.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ANON_ITEM_SPAM_INTERVAL, ITEM_SPAM_INTERVAL, PAID_ACTION_PAYMENT_METHOD
22
import { notifyItemMention, notifyItemParents, notifyMention, notifyTerritorySubscribers, notifyUserSubscribers } from '@/lib/webPush'
33
import { getItemMentions, getMentions, performBotBehavior } from './lib/item'
44
import { msatsToSats, satsToMsats } from '@/lib/format'
5+
import { GqlInputError } from '@/lib/error'
56

67
export const anonable = true
78

@@ -137,7 +138,15 @@ export async function perform (args, context) {
137138
}
138139
})).bio
139140
} else {
140-
item = await tx.item.create({ data: itemData })
141+
try {
142+
item = await tx.item.create({ data: itemData })
143+
} catch (err) {
144+
if (err.message.includes('violates exclusion constraint \\"Item_unique_time_constraint\\"')) {
145+
const message = `you already submitted this ${itemData.title ? 'post' : 'comment'}`
146+
throw new GqlInputError(message)
147+
}
148+
throw err
149+
}
141150
}
142151

143152
// store a reference to the item in the invoice
@@ -223,7 +232,7 @@ export async function onPaid ({ invoice, id }, context) {
223232
), ancestors AS (
224233
UPDATE "Item"
225234
SET ncomments = "Item".ncomments + 1,
226-
"lastCommentAt" = now(),
235+
"lastCommentAt" = GREATEST("Item"."lastCommentAt", comment.created_at),
227236
"weightedComments" = "Item"."weightedComments" +
228237
CASE WHEN comment."userId" = "Item"."userId" THEN 0 ELSE comment.trust END
229238
FROM comment

api/typeDefs/invite.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default gql`
77
}
88
99
extend type Mutation {
10-
createInvite(id: String, gift: Int!, limit: Int, description: String): Invite
10+
createInvite(id: String, gift: Int!, limit: Int!, description: String): Invite
1111
revokeInvite(id: ID!): Invite
1212
}
1313

components/bookmark.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export default function BookmarkDropdownItem ({ item: { id, meBookmark } }) {
1717
id: `Item:${id}`,
1818
fields: {
1919
meBookmark: () => bookmarkItem.meBookmark
20-
}
20+
},
21+
optimistic: true
2122
})
2223
}
2324
}

components/boost-button.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default function Boost ({ item, className, ...props }) {
2626
item={item} As={oprops =>
2727
<div className='upvoteParent'>
2828
<div
29-
className={styles.upvoteWrapper}
29+
className={classNames(styles.upvoteWrapper, item.deletedAt && styles.noSelfTips)}
3030
>
3131
<BoostIcon
3232
{...props}

components/comment-edit.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export default function CommentEdit ({ comment, editThreshold, onSuccess, onCanc
1818
text () {
1919
return result.text
2020
}
21-
}
21+
},
22+
optimistic: true
2223
})
2324
}
2425
},

components/delete.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export default function Delete ({ itemId, children, onDelete, type = 'post' }) {
3030
url: () => deleteItem.url,
3131
pollCost: () => deleteItem.pollCost,
3232
deletedAt: () => deleteItem.deletedAt
33-
}
33+
},
34+
optimistic: true
3435
})
3536
}
3637
}

components/dont-link-this.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ export function OutlawDropdownItem ({ item }) {
8484
id: `Item:${item.id}`,
8585
fields: {
8686
outlawed: () => true
87-
}
87+
},
88+
optimistic: true
8889
})
8990
}
9091
}

components/item-act.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export default function ItemAct ({ onClose, item, act = 'TIP', step, children, a
181181

182182
function modifyActCache (cache, { result, invoice }) {
183183
if (!result) return
184-
const { id, sats, path, act } = result
184+
const { id, sats, act } = result
185185
cache.modify({
186186
id: `Item:${id}`,
187187
fields: {
@@ -209,9 +209,16 @@ function modifyActCache (cache, { result, invoice }) {
209209
}
210210
return existingBoost
211211
}
212-
}
212+
},
213+
optimistic: true
213214
})
215+
}
214216

217+
// doing this onPaid fixes issue #1695 because optimistically updating all ancestors
218+
// conflicts with the writeQuery on navigation from SSR
219+
function updateAncestors (cache, { result, invoice }) {
220+
if (!result) return
221+
const { id, sats, act, path } = result
215222
if (act === 'TIP') {
216223
// update all ancestors
217224
path.split('.').forEach(aId => {
@@ -222,7 +229,8 @@ function modifyActCache (cache, { result, invoice }) {
222229
commentSats (existingCommentSats = 0) {
223230
return existingCommentSats + sats
224231
}
225-
}
232+
},
233+
optimistic: true
226234
})
227235
})
228236
}
@@ -259,6 +267,7 @@ export function useAct ({ query = ACT_MUTATION, ...options } = {}) {
259267
onPaid: (cache, { data }) => {
260268
const response = getPaidActionResult(data)
261269
if (!response) return
270+
updateAncestors(cache, response)
262271
options?.onPaid?.(cache, { data })
263272
}
264273
})

components/nav/common.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export function SignUpButton ({ className = 'py-0', width }) {
227227

228228
return (
229229
<Button
230-
className={classNames('align-items-center ps-2 py-1 pe-3', className)}
230+
className={classNames('align-items-center ps-2 pe-3', className)}
231231
style={{ borderWidth: '2px', width: width || '150px' }}
232232
id='signup'
233233
onClick={() => handleLogin('/signup')}
@@ -359,7 +359,7 @@ export function LoginButtons ({ handleClose }) {
359359
<LoginButton />
360360
</Dropdown.Item>
361361
<Dropdown.Item className='py-1'>
362-
<SignUpButton />
362+
<SignUpButton className='py-1' />
363363
</Dropdown.Item>
364364
<Dropdown.Item className='py-1'>
365365
<SwitchAccountButton handleClose={handleClose} />

components/notifications.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ function getPayerSig (lud18Data) {
345345

346346
function InvoicePaid ({ n }) {
347347
const payerSig = getPayerSig(n.invoice.lud18Data)
348-
let actionString = 'desposited to your account'
348+
let actionString = 'deposited to your account'
349349
let sats = n.earnedSats
350350
if (n.invoice.forwardedSats) {
351351
actionString = 'sent directly to your attached wallet'

components/pay-bounty.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ export const payBountyCacheMods = {
2222
bountyPaidTo (existingPaidTo = []) {
2323
return [...(existingPaidTo || []), Number(id)]
2424
}
25-
}
25+
},
26+
optimistic: true
2627
})
2728
},
2829
onPayError: (e, cache, { data }) => {
@@ -36,7 +37,8 @@ export const payBountyCacheMods = {
3637
bountyPaidTo (existingPaidTo = []) {
3738
return (existingPaidTo || []).filter(i => i !== Number(id))
3839
}
39-
}
40+
},
41+
optimistic: true
4042
})
4143
}
4244
}

components/poll.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,17 @@ export function usePollVote ({ query = POLL_VOTE, itemId }) {
123123
poll.count += 1
124124
return poll
125125
}
126-
}
126+
},
127+
optimistic: true
127128
})
128129
cache.modify({
129130
id: `PollOption:${id}`,
130131
fields: {
131132
count (existingCount) {
132133
return existingCount + 1
133134
}
134-
}
135+
},
136+
optimistic: true
135137
})
136138
}
137139

@@ -154,15 +156,17 @@ export function usePollVote ({ query = POLL_VOTE, itemId }) {
154156
poll.count -= 1
155157
return poll
156158
}
157-
}
159+
},
160+
optimistic: true
158161
})
159162
cache.modify({
160163
id: `PollOption:${id}`,
161164
fields: {
162165
count (existingCount) {
163166
return existingCount - 1
164167
}
165-
}
168+
},
169+
optimistic: true
166170
})
167171
}
168172

components/pull-to-refresh.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useRouter } from 'next/router'
22
import { useState, useRef, useEffect, useCallback, useMemo } from 'react'
33
import styles from './pull-to-refresh.module.css'
44

5-
const REFRESH_THRESHOLD = 50
5+
const REFRESH_THRESHOLD = 150
66

77
export default function PullToRefresh ({ children, className }) {
88
const router = useRouter()

components/reply.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ export default forwardRef(function Reply ({
7878
})
7979
return [newCommentRef, ...existingCommentRefs]
8080
}
81-
}
81+
},
82+
optimistic: true
8283
})
8384

8485
// no lag for itemRepetition
@@ -102,7 +103,8 @@ export default forwardRef(function Reply ({
102103
ncomments (existingNComments = 0) {
103104
return existingNComments + 1
104105
}
105-
}
106+
},
107+
optimistic: true
106108
})
107109
})
108110

components/subscribe.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export default function SubscribeDropdownItem ({ item: { id, meSubscription } })
1717
id: `Item:${id}`,
1818
fields: {
1919
meSubscription: () => subscribeItem.meSubscription
20-
}
20+
},
21+
optimistic: true
2122
})
2223
}
2324
}

components/territory-form.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export default function TerritoryForm ({ sub }) {
197197
>
198198
<Checkbox
199199
type='radio'
200-
label='100k sats/month'
200+
label={`${abbrNum(TERRITORY_PERIOD_COST('MONTHLY'))} sats/month`}
201201
value='MONTHLY'
202202
name='billingType'
203203
id='monthly-checkbox'
@@ -206,7 +206,7 @@ export default function TerritoryForm ({ sub }) {
206206
/>
207207
<Checkbox
208208
type='radio'
209-
label='1m sats/year'
209+
label={`${abbrNum(TERRITORY_PERIOD_COST('YEARLY'))} sats/year`}
210210
value='YEARLY'
211211
name='billingType'
212212
id='yearly-checkbox'
@@ -215,7 +215,7 @@ export default function TerritoryForm ({ sub }) {
215215
/>
216216
<Checkbox
217217
type='radio'
218-
label='3m sats once'
218+
label={`${abbrNum(TERRITORY_PERIOD_COST('ONCE'))} sats once`}
219219
value='ONCE'
220220
name='billingType'
221221
id='once-checkbox'

components/upvote.module.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
}
3838

3939
.noSelfTips {
40-
transform: scaleX(-1);
40+
visibility: hidden;
4141
}
4242

4343
.upvoteWrapper:not(.noSelfTips):hover {

components/use-item-submit.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ export function useRetryCreateItem ({ id }) {
118118
`,
119119
data: { bolt11: response.invoice.bolt11 }
120120
})
121-
}
121+
},
122+
optimistic: true
122123
})
123124
paidActionCacheMods?.update?.(cache, { data })
124125
}

components/vault/use-vault-configurator.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } =
3737
beforeDisconnectVault?.()
3838
await remove('key')
3939
keyReactiveVar(null)
40-
}, [remove, keyReactiveVar])
40+
}, [remove, keyReactiveVar, beforeDisconnectVault])
4141

4242
useEffect(() => {
4343
if (!me) return
@@ -94,6 +94,17 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } =
9494

9595
await updateVaultKey({
9696
variables: { entries, hash: vaultKey.hash },
97+
update: (cache, { data }) => {
98+
cache.modify({
99+
id: `User:${me.id}`,
100+
fields: {
101+
privates: (existing) => ({
102+
...existing,
103+
vaultKeyHash: vaultKey.hash
104+
})
105+
}
106+
})
107+
},
97108
onError: (error) => {
98109
const errorCode = error.graphQLErrors[0]?.extensions?.code
99110
if (errorCode === E_VAULT_KEY_EXISTS) {
@@ -110,7 +121,7 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } =
110121
console.error('error setting vault key', e)
111122
toaster.danger(e.message)
112123
}
113-
}, [getVaultEntries, updateVaultKey, set, get, remove, onVaultKeySet, keyReactiveVar])
124+
}, [getVaultEntries, updateVaultKey, set, get, remove, onVaultKeySet, keyReactiveVar, me?.id])
114125

115126
return { key, setVaultKey, clearVault, disconnectVault }
116127
}

docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ services:
283283
echo "Creating wallet and address..."
284284
bitcoin-cli createwallet ""
285285
nodes+=($$(bitcoin-cli getnewaddress))
286-
echo "Mining 100 blocks to sn_lnd, lnd, cln, eclair..."
286+
echo "Mining 100 blocks to sn_lnd, lnd, cln, router_lnd, eclair..."
287287
for addr in "$${nodes[@]}"; do
288288
bitcoin-cli generatetoaddress 100 $$addr
289289
echo "Mining 100 blocks to a random address..."

lib/constants.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,19 @@ export const FREEBIE_BASE_COST_THRESHOLD = 10
9393
// From lawyers: north korea, cuba, iran, ukraine, syria
9494
export const SANCTIONED_COUNTRY_CODES = ['KP', 'CU', 'IR', 'UA', 'SY']
9595

96-
export const TERRITORY_COST_MONTHLY = 100000
97-
export const TERRITORY_COST_YEARLY = 1000000
96+
export const TERRITORY_COST_MONTHLY = 50000
97+
export const TERRITORY_COST_YEARLY = 500000
9898
export const TERRITORY_COST_ONCE = 3000000
9999

100100
export const TERRITORY_BILLING_OPTIONS = (labelPrefix) => ({
101101
monthly: {
102-
term: '+ 100k',
102+
term: '+ 50k',
103103
label: `${labelPrefix} month`,
104104
op: '+',
105105
modifier: cost => cost + TERRITORY_COST_MONTHLY
106106
},
107107
yearly: {
108-
term: '+ 1m',
108+
term: '+ 500k',
109109
label: `${labelPrefix} year`,
110110
op: '+',
111111
modifier: cost => cost + TERRITORY_COST_YEARLY

0 commit comments

Comments
 (0)