Compare commits
No commits in common. "1dcb6461c77bc0e5a9f680f78d48850dcaf41afc" and "d8fe6989637553cc9867cb5413b45678c273b3fc" have entirely different histories.
1dcb6461c7
...
d8fe698963
@ -10,7 +10,7 @@ import { useToast } from './toast'
|
|||||||
import { useLightning } from './lightning'
|
import { useLightning } from './lightning'
|
||||||
import { nextTip } from './upvote'
|
import { nextTip } from './upvote'
|
||||||
import { InvoiceCanceledError, usePayment } from './payment'
|
import { InvoiceCanceledError, usePayment } from './payment'
|
||||||
// import { optimisticUpdate } from '@/lib/apollo'
|
import { optimisticUpdate } from '@/lib/apollo'
|
||||||
import { Types as ClientNotification, ClientNotifyProvider, useClientNotifications } from './client-notifications'
|
import { Types as ClientNotification, ClientNotifyProvider, useClientNotifications } from './client-notifications'
|
||||||
import { ZAP_UNDO_DELAY_MS } from '@/lib/constants'
|
import { ZAP_UNDO_DELAY_MS } from '@/lib/constants'
|
||||||
|
|
||||||
@ -120,31 +120,23 @@ export default function ItemAct ({ onClose, item, down, children, abortSignal })
|
|||||||
act: down ? 'DONT_LIKE_THIS' : 'TIP',
|
act: down ? 'DONT_LIKE_THIS' : 'TIP',
|
||||||
hash,
|
hash,
|
||||||
hmac
|
hmac
|
||||||
},
|
}
|
||||||
optimisticResponse: {
|
|
||||||
act: { id: item.id, sats: Number(amount), act: down ? 'DONT_LIKE_THIS' : 'TIP', path: item.path }
|
|
||||||
},
|
|
||||||
update: actUpdate({ me })
|
|
||||||
})
|
})
|
||||||
if (!me) setItemMeAnonSats({ id: item.id, amount })
|
if (!me) setItemMeAnonSats({ id: item.id, amount })
|
||||||
addCustomTip(Number(amount))
|
addCustomTip(Number(amount))
|
||||||
strike()
|
|
||||||
onClose()
|
|
||||||
}, [me, act, down, item.id, strike])
|
}, [me, act, down, item.id, strike])
|
||||||
|
|
||||||
// XXX avoid manual optimistic updates until
|
const optimisticUpdate = useCallback(({ amount }) => {
|
||||||
// https://github.com/stackernews/stacker.news/issues/1218 is fixed
|
const variables = {
|
||||||
// const optimisticUpdate = useCallback(({ amount }) => {
|
id: item.id,
|
||||||
// const variables = {
|
sats: Number(amount),
|
||||||
// id: item.id,
|
act: down ? 'DONT_LIKE_THIS' : 'TIP'
|
||||||
// sats: Number(amount),
|
}
|
||||||
// act: down ? 'DONT_LIKE_THIS' : 'TIP'
|
const optimisticResponse = { act: { ...variables, path: item.path } }
|
||||||
// }
|
strike()
|
||||||
// const optimisticResponse = { act: { ...variables, path: item.path } }
|
onClose()
|
||||||
// strike()
|
return { mutation: ACT_MUTATION, variables, optimisticResponse, update: actUpdate({ me }) }
|
||||||
// onClose()
|
}, [item.id, down, !!me, strike])
|
||||||
// return { mutation: ACT_MUTATION, variables, optimisticResponse, update: actUpdate({ me }) }
|
|
||||||
// }, [item.id, down, !!me, strike])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClientNotifyProvider additionalProps={{ itemId: item.id }}>
|
<ClientNotifyProvider additionalProps={{ itemId: item.id }}>
|
||||||
@ -155,7 +147,7 @@ export default function ItemAct ({ onClose, item, down, children, abortSignal })
|
|||||||
}}
|
}}
|
||||||
schema={amountSchema}
|
schema={amountSchema}
|
||||||
prepaid
|
prepaid
|
||||||
// optimisticUpdate={optimisticUpdate}
|
optimisticUpdate={optimisticUpdate}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
clientNotification={ClientNotification.Zap}
|
clientNotification={ClientNotification.Zap}
|
||||||
signal={abortSignal}
|
signal={abortSignal}
|
||||||
@ -274,10 +266,8 @@ export function useZap () {
|
|||||||
|
|
||||||
let revert, cancel, nid
|
let revert, cancel, nid
|
||||||
try {
|
try {
|
||||||
// XXX avoid manual optimistic updates until
|
revert = optimisticUpdate({ mutation: ZAP_MUTATION, variables, optimisticResponse, update })
|
||||||
// https://github.com/stackernews/stacker.news/issues/1218 is fixed
|
strike()
|
||||||
// revert = optimisticUpdate({ mutation: ZAP_MUTATION, variables, optimisticResponse, update })
|
|
||||||
// strike()
|
|
||||||
|
|
||||||
await abortSignal.pause({ me, amount: satsDelta })
|
await abortSignal.pause({ me, amount: satsDelta })
|
||||||
|
|
||||||
@ -287,11 +277,7 @@ export function useZap () {
|
|||||||
|
|
||||||
let hash, hmac;
|
let hash, hmac;
|
||||||
[{ hash, hmac }, cancel] = await payment.request(satsDelta)
|
[{ hash, hmac }, cancel] = await payment.request(satsDelta)
|
||||||
|
await zap({ variables: { ...variables, hash, hmac } })
|
||||||
// XXX related to comment above
|
|
||||||
// await zap({ variables: { ...variables, hash, hmac } })
|
|
||||||
await zap({ variables: { ...variables, hash, hmac }, optimisticResponse, update })
|
|
||||||
strike()
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
revert?.()
|
revert?.()
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ import { useMe } from './me'
|
|||||||
import { numWithUnits } from '@/lib/format'
|
import { numWithUnits } from '@/lib/format'
|
||||||
import { useShowModal } from './modal'
|
import { useShowModal } from './modal'
|
||||||
import { useRoot } from './root'
|
import { useRoot } from './root'
|
||||||
import { useAct, actUpdate } from './item-act'
|
import { useAct, actUpdate, ACT_MUTATION } from './item-act'
|
||||||
import { InvoiceCanceledError, usePayment } from './payment'
|
import { InvoiceCanceledError, usePayment } from './payment'
|
||||||
|
import { optimisticUpdate } from '@/lib/apollo'
|
||||||
import { useLightning } from './lightning'
|
import { useLightning } from './lightning'
|
||||||
import { useToast } from './toast'
|
import { useToast } from './toast'
|
||||||
import { Types as ClientNotification, useClientNotifications } from './client-notifications'
|
import { Types as ClientNotification, useClientNotifications } from './client-notifications'
|
||||||
@ -44,21 +45,30 @@ export default function PayBounty ({ children, item }) {
|
|||||||
const notifyProps = { itemId: item.id, sats }
|
const notifyProps = { itemId: item.id, sats }
|
||||||
const optimisticResponse = { act: { ...variables, path: item.path } }
|
const optimisticResponse = { act: { ...variables, path: item.path } }
|
||||||
|
|
||||||
let cancel, nid
|
let revert, cancel, nid
|
||||||
try {
|
try {
|
||||||
|
revert = optimisticUpdate({
|
||||||
|
mutation: ACT_MUTATION,
|
||||||
|
variables,
|
||||||
|
optimisticResponse,
|
||||||
|
update: actUpdate({ me, onUpdate: onUpdate(onComplete) })
|
||||||
|
})
|
||||||
|
|
||||||
if (me) {
|
if (me) {
|
||||||
nid = notify(ClientNotification.Bounty.PENDING, notifyProps)
|
nid = notify(ClientNotification.Bounty.PENDING, notifyProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash, hmac;
|
let hash, hmac;
|
||||||
[{ hash, hmac }, cancel] = await payment.request(sats)
|
[{ hash, hmac }, cancel] = await payment.request(sats)
|
||||||
|
|
||||||
await act({
|
await act({
|
||||||
variables: { hash, hmac, ...variables },
|
variables: { hash, hmac, ...variables },
|
||||||
optimisticResponse,
|
optimisticResponse: {
|
||||||
update: actUpdate({ me, onUpdate: onUpdate(onComplete) })
|
act: variables
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
revert?.()
|
||||||
|
|
||||||
if (error instanceof InvoiceCanceledError) {
|
if (error instanceof InvoiceCanceledError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import { signIn } from 'next-auth/react'
|
|||||||
import ActionTooltip from './action-tooltip'
|
import ActionTooltip from './action-tooltip'
|
||||||
import { POLL_COST } from '@/lib/constants'
|
import { POLL_COST } from '@/lib/constants'
|
||||||
import { InvoiceCanceledError, usePayment } from './payment'
|
import { InvoiceCanceledError, usePayment } from './payment'
|
||||||
|
import { optimisticUpdate } from '@/lib/apollo'
|
||||||
import { useToast } from './toast'
|
import { useToast } from './toast'
|
||||||
import { Types as ClientNotification, useClientNotifications } from './client-notifications'
|
import { Types as ClientNotification, useClientNotifications } from './client-notifications'
|
||||||
|
|
||||||
@ -54,17 +55,20 @@ export default function Poll ({ item }) {
|
|||||||
const variables = { id: v.id }
|
const variables = { id: v.id }
|
||||||
const notifyProps = { itemId: item.id }
|
const notifyProps = { itemId: item.id }
|
||||||
const optimisticResponse = { pollVote: v.id }
|
const optimisticResponse = { pollVote: v.id }
|
||||||
let cancel, nid
|
let revert, cancel, nid
|
||||||
try {
|
try {
|
||||||
|
revert = optimisticUpdate({ mutation: POLL_VOTE_MUTATION, variables, optimisticResponse, update })
|
||||||
|
|
||||||
if (me) {
|
if (me) {
|
||||||
nid = notify(ClientNotification.PollVote.PENDING, notifyProps)
|
nid = notify(ClientNotification.PollVote.PENDING, notifyProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash, hmac;
|
let hash, hmac;
|
||||||
[{ hash, hmac }, cancel] = await payment.request(item.pollCost || POLL_COST)
|
[{ hash, hmac }, cancel] = await payment.request(item.pollCost || POLL_COST)
|
||||||
|
await pollVote({ variables: { hash, hmac, ...variables } })
|
||||||
await pollVote({ variables: { hash, hmac, ...variables }, optimisticResponse, update })
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
revert?.()
|
||||||
|
|
||||||
if (error instanceof InvoiceCanceledError) {
|
if (error instanceof InvoiceCanceledError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -259,6 +259,7 @@ export default memo(function Text ({ rel, imgproxyUrls, children, tab, itemId, o
|
|||||||
paddingRight: '15px'
|
paddingRight: '15px'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const { provider, id, meta } = parseEmbedUrl(href)
|
const { provider, id, meta } = parseEmbedUrl(href)
|
||||||
// Youtube video embed
|
// Youtube video embed
|
||||||
if (provider === 'youtube') {
|
if (provider === 'youtube') {
|
||||||
@ -289,6 +290,9 @@ export default memo(function Text ({ rel, imgproxyUrls, children, tab, itemId, o
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore invalid URLs
|
||||||
|
}
|
||||||
|
|
||||||
// assume the link is an image which will fallback to link if it's not
|
// assume the link is an image which will fallback to link if it's not
|
||||||
return <Img src={href} rel={rel ?? UNKNOWN_LINK_REL} {...props}>{children}</Img>
|
return <Img src={href} rel={rel ?? UNKNOWN_LINK_REL} {...props}>{children}</Img>
|
||||||
|
23
lib/url.js
23
lib/url.js
@ -1,24 +1,11 @@
|
|||||||
export function ensureProtocol (value) {
|
export function ensureProtocol (value) {
|
||||||
if (!value) return value
|
if (!value) return value
|
||||||
value = value.trim()
|
value = value.trim()
|
||||||
let url
|
if (!/^([a-z0-9]+:\/\/|mailto:)/.test(value)) {
|
||||||
|
value = 'http://' + value
|
||||||
try {
|
}
|
||||||
url = new URL(value)
|
|
||||||
} catch {
|
|
||||||
try {
|
|
||||||
url = new URL('http://' + value)
|
|
||||||
} catch {
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// remove trailing slash if new URL() added it
|
|
||||||
if (url.href.endsWith('/') && !value.endsWith('/')) {
|
|
||||||
return url.href.slice(0, -1)
|
|
||||||
}
|
|
||||||
return url.href
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isExternal (url) {
|
export function isExternal (url) {
|
||||||
return !url.startsWith(process.env.NEXT_PUBLIC_URL + '/') && !url.startsWith('/')
|
return !url.startsWith(process.env.NEXT_PUBLIC_URL + '/') && !url.startsWith('/')
|
||||||
@ -76,7 +63,6 @@ export function parseInternalLinks (href) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseEmbedUrl (href) {
|
export function parseEmbedUrl (href) {
|
||||||
try {
|
|
||||||
const { hostname, pathname, searchParams } = new URL(href)
|
const { hostname, pathname, searchParams } = new URL(href)
|
||||||
|
|
||||||
if (hostname.endsWith('youtube.com') && pathname.includes('/watch')) {
|
if (hostname.endsWith('youtube.com') && pathname.includes('/watch')) {
|
||||||
@ -110,9 +96,6 @@ export function parseEmbedUrl (href) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
// Important to return empty object as default
|
// Important to return empty object as default
|
||||||
return {}
|
return {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user