Compare commits

..

No commits in common. "c88afc5aaedef8043b8f1c24f0c44cd5ddb532dd" and "8441e04d3eadf62d12f8c1af84ce0d323bff9bcb" have entirely different histories.

12 changed files with 57 additions and 90 deletions

View File

@ -2,11 +2,11 @@ import { USER_ID } from '@/lib/constants'
import { deleteReminders, getDeleteAt, getRemindAt } from '@/lib/item'
import { parseInternalLinks } from '@/lib/url'
export async function getMentions ({ text }, { me, tx }) {
export async function getMentions ({ text }, { me, models }) {
const mentionPattern = /\B@[\w_]+/gi
const names = text.match(mentionPattern)?.map(m => m.slice(1))
if (names?.length > 0) {
const users = await tx.user.findMany({
const users = await models.user.findMany({
where: {
name: {
in: names
@ -21,7 +21,7 @@ export async function getMentions ({ text }, { me, tx }) {
return []
}
export const getItemMentions = async ({ text }, { me, tx }) => {
export const getItemMentions = async ({ text }, { me, models }) => {
const linkPattern = new RegExp(`${process.env.NEXT_PUBLIC_URL}/items/\\d+[a-zA-Z0-9/?=]*`, 'gi')
const refs = text.match(linkPattern)?.map(m => {
try {
@ -33,7 +33,7 @@ export const getItemMentions = async ({ text }, { me, tx }) => {
}).filter(r => !!r)
if (refs?.length > 0) {
const referee = await tx.item.findMany({
const referee = await models.item.findMany({
where: {
id: { in: refs },
userId: { not: me?.id || USER_ID.anon }

View File

@ -2,7 +2,7 @@ import { useShowModal } from './modal'
import { useToast } from './toast'
import ItemAct from './item-act'
import AccordianItem from './accordian-item'
import { useMemo } from 'react'
import { useMemo, useState } from 'react'
import getColor from '@/lib/rainbow'
import BoostIcon from '@/svgs/arrow-up-double-line.svg'
import styles from './upvote.module.css'
@ -12,29 +12,32 @@ import classNames from 'classnames'
export default function Boost ({ item, className, ...props }) {
const { boost } = item
const [hover, setHover] = useState(false)
const [color, nextColor] = useMemo(() => [getColor(boost), getColor(boost + BOOST_MULT)], [boost])
const style = useMemo(() => ({
'--hover-fill': nextColor,
'--hover-filter': `drop-shadow(0 0 6px ${nextColor}90)`,
'--fill': color,
'--filter': `drop-shadow(0 0 6px ${color}90)`
}), [color, nextColor])
const style = useMemo(() => (hover || boost
? {
fill: hover ? nextColor : color,
filter: `drop-shadow(0 0 6px ${hover ? nextColor : color}90)`
}
: undefined), [boost, hover])
return (
<Booster
item={item} As={oprops =>
item={item} As={({ ...oprops }) =>
<div className='upvoteParent'>
<div
className={styles.upvoteWrapper}
>
<BoostIcon
{...props}
{...oprops}
style={style}
{...props} {...oprops} style={style}
width={26}
height={26}
className={classNames(styles.boost, className, boost && styles.boosted)}
onPointerEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
onTouchEnd={() => setHover(false)}
className={classNames(styles.boost, className, boost && styles.voted)}
/>
</div>
</div>}

View File

@ -78,11 +78,6 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload,
element.onerror = reject
element.src = window.URL.createObjectURL(file)
// iOS Force the video to load metadata
if (element.tagName === 'VIDEO') {
element.load()
}
})
}, [toaster, getSignedPOST])

View File

@ -109,6 +109,7 @@ export default function UpVote ({ item, className, collapsed }) {
const [tipShow, _setTipShow] = useState(false)
const ref = useRef()
const { me } = useMe()
const [hover, setHover] = useState(false)
const [setWalkthrough] = useMutation(
gql`
mutation setWalkthrough($upvotePopover: Boolean, $tipPopover: Boolean) {
@ -171,6 +172,10 @@ export default function UpVote ({ item, className, collapsed }) {
me, item?.meSats, item?.meAnonSats, me?.privates?.tipDefault, me?.privates?.turboDefault,
me?.privates?.tipRandom, me?.privates?.tipRandomMin, me?.privates?.tipRandomMax, pending])
const handleModalClosed = () => {
setHover(false)
}
const handleLongPress = (e) => {
if (!item) return
@ -190,7 +195,7 @@ export default function UpVote ({ item, className, collapsed }) {
setController(c)
showModal(onClose =>
<ItemAct onClose={onClose} item={item} abortSignal={c.signal} />)
<ItemAct onClose={onClose} item={item} abortSignal={c.signal} />, { onClose: handleModalClosed })
}
const handleShortPress = async () => {
@ -218,16 +223,19 @@ export default function UpVote ({ item, className, collapsed }) {
await zap({ item, me, abortSignal: c.signal })
} else {
showModal(onClose => <ItemAct onClose={onClose} item={item} />)
showModal(onClose => <ItemAct onClose={onClose} item={item} />, { onClose: handleModalClosed })
}
}
const style = useMemo(() => ({
'--hover-fill': nextColor,
'--hover-filter': `drop-shadow(0 0 6px ${nextColor}90)`,
'--fill': color,
'--filter': `drop-shadow(0 0 6px ${color}90)`
}), [color, nextColor])
const style = useMemo(() => {
const fillColor = pending || hover ? nextColor : color
return meSats || hover || pending
? {
fill: fillColor,
filter: `drop-shadow(0 0 6px ${fillColor}90)`
}
: undefined
}, [hover, pending, nextColor, color, meSats])
return (
<div ref={ref} className='upvoteParent'>
@ -238,6 +246,9 @@ export default function UpVote ({ item, className, collapsed }) {
<ActionTooltip notForm disable={disabled} overlayText={overlayText}>
<div className={classNames(disabled && styles.noSelfTips, styles.upvoteWrapper)}>
<UpBolt
onPointerEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
onTouchEnd={() => setHover(false)}
width={26}
height={26}
className={classNames(styles.upvote,

View File

@ -5,11 +5,6 @@
-webkit-touch-callout: none;
}
.upvote:hover {
fill: var(--hover-fill) !important;
filter: var(--hover-filter) !important;
}
.boost {
fill: var(--theme-clickToContextColor);
user-select: none;
@ -17,16 +12,6 @@
-webkit-touch-callout: none;
}
.boost:hover {
fill: var(--hover-fill) !important;
filter: var(--hover-filter) !important;
}
.boost.boosted {
fill: var(--fill);
filter: var(--filter);
}
.upvoteWrapper {
position: relative;
padding-right: .2rem;
@ -43,8 +28,8 @@
}
.upvote.voted {
fill: var(--fill);
filter: var(--filter);
fill: #F6911D;
filter: drop-shadow(0 0 6px #f6911d90);
}
.cover {
@ -58,7 +43,6 @@
}
.pending {
fill: var(--hover-fill);
animation-name: pulse;
animation-iteration-count: infinite;
animation-timing-function: linear;

View File

@ -27,17 +27,12 @@ function useIndexedDB ({ dbName, storeName, options = DEFAULT_OPTIONS, indices =
db.transaction(storeName)
while (operationQueue.current.length > 0) {
const operation = operationQueue.current.shift()
// if the db is the same as the one we're processing, run the operation
// else, we'll just clear the operation queue
// XXX this is a consquence of using a ref to store the queue and should be fixed
if (dbName === db.name) {
operation(db)
}
operation(db)
}
} catch (error) {
handleError(error)
}
}, [dbName, storeName, handleError, operationQueue])
}, [storeName, handleError, operationQueue])
useEffect(() => {
let isMounted = true

View File

@ -14,7 +14,6 @@ import { schnorr } from '@noble/curves/secp256k1'
import { notifyReferral } from '@/lib/webPush'
import { hashEmail } from '@/lib/crypto'
import * as cookie from 'cookie'
import { multiAuthMiddleware } from '@/pages/api/graphql'
/**
* Stores userIds in user table
@ -133,9 +132,6 @@ function setMultiAuthCookies (req, res, { id, jwt, name, photoId }) {
// add JWT to **httpOnly** cookie
res.appendHeader('Set-Cookie', cookie.serialize(`multi_auth.${id}`, jwt, cookieOptions))
// switch to user we just added
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth.user-id', id, { ...cookieOptions, httpOnly: false }))
let newMultiAuth = [{ id, name, photoId }]
if (req.cookies.multi_auth) {
const oldMultiAuth = b64Decode(req.cookies.multi_auth)
@ -144,6 +140,9 @@ function setMultiAuthCookies (req, res, { id, jwt, name, photoId }) {
newMultiAuth = [...oldMultiAuth, ...newMultiAuth]
}
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth', b64Encode(newMultiAuth), { ...cookieOptions, httpOnly: false }))
// switch to user we just added
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth.user-id', id, { ...cookieOptions, httpOnly: false }))
}
async function pubkeyAuth (credentials, req, res, pubkeyColumnName) {
@ -166,7 +165,6 @@ async function pubkeyAuth (credentials, req, res, pubkeyColumnName) {
let user = await prisma.user.findUnique({ where: { [pubkeyColumnName]: pubkey } })
// get token if it exists
req = multiAuthMiddleware(req)
const token = await getToken({ req })
if (!user) {
// we have not seen this pubkey before

View File

@ -82,7 +82,7 @@ export default startServerAndCreateNextHandler(apolloServer, {
}
})
export function multiAuthMiddleware (request) {
function multiAuthMiddleware (request) {
// switch next-auth session cookie with multi_auth cookie if cookie pointer present
// is there a cookie pointer?

View File

@ -13,12 +13,11 @@ import { canReceive, canSend, isConfigured } from '@/wallets/common'
import { SSR } from '@/lib/constants'
import WalletButtonBar from '@/components/wallet-buttonbar'
import { useWalletConfigurator } from '@/wallets/config'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useCallback, useMemo } from 'react'
import { useMe } from '@/components/me'
import validateWallet from '@/wallets/validate'
import { ValidationError } from 'yup'
import { useFormikContext } from 'formik'
import useDarkMode from '@/components/dark-mode'
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
@ -29,8 +28,6 @@ export default function WalletSettings () {
const wallet = useWallet(name)
const { me } = useMe()
const { save, detach } = useWalletConfigurator(wallet)
const [dark] = useDarkMode()
const [imgSrc, setImgSrc] = useState(wallet?.def.card?.image?.src)
const initial = useMemo(() => {
const initial = wallet?.def.fields.reduce((acc, field) => {
@ -72,16 +69,12 @@ export default function WalletSettings () {
const { card: { image, title, subtitle } } = wallet?.def || { card: {} }
useEffect(() => {
if (!imgSrc) return
// wallet.png <-> wallet-dark.png
setImgSrc(dark ? image?.src.replace(/\.([a-z]{3})$/, '-dark.$1') : image?.src)
}, [dark])
return (
<CenterLayout>
{image
? <img alt={title} {...image} src={imgSrc} className='pb-3 px-2 mw-100' />
? typeof image === 'object'
? <img {...image} alt={title} className='pb-2' />
: <img src={image} width='33%' alt={title} className='pb-2' />
: <h2 className='pb-2'>{title}</h2>}
<h6 className='text-muted text-center pb-3'><Text>{subtitle}</Text></h6>
<Form

View File

@ -1,11 +0,0 @@
-- AlterTable
ALTER TABLE "WalletBlink" ALTER COLUMN "apiKeyRecv" DROP NOT NULL;
-- AlterTable
ALTER TABLE "WalletLNbits" ALTER COLUMN "invoiceKey" DROP NOT NULL;
-- AlterTable
ALTER TABLE "WalletNWC" ALTER COLUMN "nwcUrlRecv" DROP NOT NULL;
-- AlterTable
ALTER TABLE "WalletPhoenixd" ALTER COLUMN "secondaryPassword" DROP NOT NULL;

View File

@ -289,7 +289,7 @@ model WalletLNbits {
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
url String
invoiceKey String?
invoiceKey String
}
model WalletNWC {
@ -298,7 +298,7 @@ model WalletNWC {
wallet Wallet @relation(fields: [walletId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
nwcUrlRecv String?
nwcUrlRecv String
}
model WalletBlink {
@ -307,7 +307,7 @@ model WalletBlink {
wallet Wallet @relation(fields: [walletId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
apiKeyRecv String?
apiKeyRecv String
currencyRecv String?
}
@ -318,7 +318,7 @@ model WalletPhoenixd {
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
url String
secondaryPassword String?
secondaryPassword String
}
model Mute {

View File

@ -119,12 +119,11 @@ async function performPessimisticAction ({ lndInvoice, dbInvoice, tx, models, ln
const context = {
tx,
cost: BigInt(lndInvoice.received_mtokens),
me: dbInvoice.user
me: dbInvoice.user,
sybilFeePercent: await paidActions[dbInvoice.actionType].getSybilFeePercent?.()
}
const sybilFeePercent = await paidActions[dbInvoice.actionType].getSybilFeePercent?.(args, context)
const result = await paidActions[dbInvoice.actionType].perform(args, { ...context, sybilFeePercent })
const result = await paidActions[dbInvoice.actionType].perform(args, context)
await tx.invoice.update({
where: { id: dbInvoice.id },
data: {