Skip to content

Commit

Permalink
small copy and semantics changes
Browse files Browse the repository at this point in the history
  • Loading branch information
huumn committed Feb 12, 2025
1 parent 993c589 commit c13bdd2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 53 deletions.
8 changes: 5 additions & 3 deletions components/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import classNames from 'classnames'
import HolsterIcon from '@/svgs/holster.svg'
import SaddleIcon from '@/svgs/saddle.svg'
import CCInfo from './info/cc'
import { useMe } from './me'

function Notification ({ n, fresh }) {
const type = n.__typename
Expand Down Expand Up @@ -528,16 +529,17 @@ function WithdrawlPaid ({ n }) {
}

function Referral ({ n }) {
const { me } = useMe()
let referralSource = 'of you'
switch (n.source?.__typename) {
case 'Item':
referralSource = 'you shared this ' + (n.source.title ? 'post' : 'comment')
referralSource = (Number(me?.id) === Number(n.source.user?.id) ? 'of your' : 'you shared this') + ' ' + (n.source.title ? 'post' : 'comment')
break
case 'Sub':
referralSource = 'you shared ~' + n.source.name + ' territory'
referralSource = (Number(me?.id) === Number(n.source.userId) ? 'of your' : 'you shared the') + ' ~' + n.source.name + ' territory'
break
case 'User':
referralSource = 'you shared ' + n.source.name + '\'s profile'
referralSource = (me?.name === n.source.name ? 'of your profile' : `you shared ${n.source.name}'s profile`)
break
}
return (
Expand Down
48 changes: 28 additions & 20 deletions middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ const SN_REFERRER_NONCE = 'sn_referrer_nonce'
// key for referred pages
const SN_REFEREE_LANDING = 'sn_referee_landing'

function getContentReferrer (request, url) {
if (itemPattern.test(url)) {
let id = request.nextUrl.searchParams.get('commentId')
if (!id) {
({ id } = itemPattern.exec(url).pathname.groups)
}
return `item-${id}`
}
if (profilePattern.test(url)) {
const { name } = profilePattern.exec(url).pathname.groups
return `profile-${name}`
}
if (territoryPattern.test(url)) {
const { name } = territoryPattern.exec(url).pathname.groups
return `territory-${name}`
}
}

// we store the referrers in cookies for a future signup event
// we pass the referrers in the request headers so we can use them in referral rewards for logged in stackers
function referrerMiddleware (request) {
Expand All @@ -27,6 +45,14 @@ function referrerMiddleware (request) {
// referrers. Content referrers do not override explicit referrers because
// explicit referees might click around before signing up.
response.cookies.set(SN_REFERRER, referrer, { maxAge: 60 * 60 * 24 })

// we record the first page the user lands on and keep it for 24 hours
// in addition to the explicit referrer, this allows us to tell the referrer
// which share link the user clicked on
const contentReferrer = getContentReferrer(request, url)
if (contentReferrer) {
response.cookies.set(SN_REFEREE_LANDING, contentReferrer, { maxAge: 60 * 60 * 24 })
}
// store the explicit referrer for one page load
// this allows us to attribute both explicit and implicit referrers after the redirect
// e.g. items/<num>/r/<referrer> links should attribute both the item op and the referrer
Expand All @@ -35,22 +61,9 @@ function referrerMiddleware (request) {
return response
}

let contentReferrer
if (itemPattern.test(request.url)) {
let id = request.nextUrl.searchParams.get('commentId')
if (!id) {
({ id } = itemPattern.exec(request.url).pathname.groups)
}
contentReferrer = `item-${id}`
} else if (profilePattern.test(request.url)) {
const { name } = profilePattern.exec(request.url).pathname.groups
contentReferrer = `profile-${name}`
} else if (territoryPattern.test(request.url)) {
const { name } = territoryPattern.exec(request.url).pathname.groups
contentReferrer = `territory-${name}`
}
const contentReferrer = getContentReferrer(request, request.url)

// pass the referrers to SSR in the request headers
// pass the referrers to SSR in the request headers for one day referrer attribution
const requestHeaders = new Headers(request.headers)
const referrers = [request.cookies.get(SN_REFERRER_NONCE)?.value, contentReferrer].filter(Boolean)
if (referrers.length) {
Expand All @@ -63,11 +76,6 @@ function referrerMiddleware (request) {
}
})

// we record the first page the user lands on and keep it for 24 hours
if (!request.cookies.has(SN_REFEREE_LANDING) && contentReferrer) {
response.cookies.set(SN_REFEREE_LANDING, contentReferrer, { maxAge: 60 * 60 * 24 })
}

// if we don't already have an explicit referrer, give them the content referrer as one
if (!request.cookies.has(SN_REFERRER) && contentReferrer) {
response.cookies.set(SN_REFERRER, contentReferrer, { maxAge: 60 * 60 * 24 })
Expand Down
64 changes: 34 additions & 30 deletions pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,46 @@ function getEventCallbacks () {
}
}

async function getReferrerId (referrer) {
async function getReferrerFromCookie (referrer) {
let referrerId
let type
let typeId
try {
if (referrer.startsWith('item-')) {
return (await prisma.item.findUnique({ where: { id: parseInt(referrer.slice(5)) } }))?.userId
const item = await prisma.item.findUnique({ where: { id: parseInt(referrer.slice(5)) } })
type = item?.parentId ? 'COMMENT' : 'POST'
referrerId = item?.userId
typeId = item?.id
} else if (referrer.startsWith('profile-')) {
return (await prisma.user.findUnique({ where: { name: referrer.slice(8) } }))?.id
const user = await prisma.user.findUnique({ where: { name: referrer.slice(8) } })
type = 'PROFILE'
referrerId = user?.id
typeId = user?.id
} else if (referrer.startsWith('territory-')) {
return (await prisma.sub.findUnique({ where: { name: referrer.slice(10) } }))?.userId
type = 'TERRITORY'
typeId = referrer.slice(10)
const sub = await prisma.sub.findUnique({ where: { name: typeId } })
referrerId = sub?.userId
} else {
return (await prisma.user.findUnique({ where: { name: referrer } }))?.id
return {
referrerId: (await prisma.user.findUnique({ where: { name: referrer } }))?.id
}
}
} catch (error) {
console.error('error getting referrer id', error)
return
}
return { referrerId, type, typeId: String(typeId) }
}

async function getRefereeLanding (refereeLanding, refereeId) {
const referrerId = await getReferrerId(refereeLanding)
if (!referrerId) return null // we only record if it's a valid content

let type, typeId

if (refereeLanding.startsWith('item-')) {
typeId = refereeLanding.slice(5)
const item = await prisma.item.findUnique({ where: { id: parseInt(typeId) } })
type = item?.parentId ? 'COMMENT' : 'POST'
} else if (refereeLanding.startsWith('profile-')) {
type = 'PROFILE'
typeId = refereeLanding.slice(8)
} else if (refereeLanding.startsWith('territory-')) {
type = 'TERRITORY'
typeId = refereeLanding.slice(10)
async function getReferrerData (referrer, landing) {
const referrerData = await getReferrerFromCookie(referrer)
if (landing) {
const landingData = await getReferrerFromCookie(landing)
// explicit referrer takes precedence over landing referrer
return { ...landingData, ...referrerData }
}

return { referrerId, refereeId, type, typeId, landing: true }
return referrerData
}

/** @returns {Partial<import('next-auth').CallbacksOptions>} */
Expand All @@ -98,15 +103,14 @@ function getCallbacks (req, res) {
// isNewUser doesn't work for nostr/lightning auth because we create the user before nextauth can
// this means users can update their referrer if they don't have one, which is fine
if (req.cookies.sn_referrer && user?.id) {
const referrerId = await getReferrerId(req.cookies.sn_referrer)
if (referrerId && referrerId !== parseInt(user?.id)) {
const referrerData = await getReferrerData(req.cookies.sn_referrer, req.cookies.sn_referee_landing)
if (referrerData?.referrerId && referrerData.referrerId !== parseInt(user?.id)) {
// if we have recorded a referee landing, record it in the db
if (req.cookies.sn_referee_landing) {
const refereeLanding = await getRefereeLanding(req.cookies.sn_referee_landing, user.id)
if (refereeLanding) await prisma.oneDayReferral.create({ data: refereeLanding })
if (referrerData.type && referrerData.typeId) {
await prisma.oneDayReferral.create({ data: { ...referrerData, refereeId: user.id, landing: true } })
}
const { count } = await prisma.user.updateMany({ where: { id: user.id, referrerId: null }, data: { referrerId } })
if (count > 0) notifyReferral(referrerId)
const { count } = await prisma.user.updateMany({ where: { id: user.id, referrerId: null }, data: { referrerId: referrerData.referrerId } })
if (count > 0) notifyReferral(referrerData.referrerId)
}
}
}
Expand Down

0 comments on commit c13bdd2

Please sign in to comment.