mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 07:39:07 +03:00
* duplicate page * whale init * table background * prepare * sync undocumented remote schema from master * revert remote schema sync * add lw12 tickets migration file * ticket init * set up lw12 ticket layout * finish ticket layout and customization form * lw12 ticket og * ticket styling * code highlight border * launch week migrations * local dev progress * keep local gh config * comment section * comment section * comment out username.tsx * remove lw/ticekts temp * update copy * fix migration view * redirect to try * use misc * lw12 og * share * share correct * env var * username page * update example env * push new db schema * trigger deploy * update ticket og * ticket themes * bypass browser * change env var name * fix * fix * process env * create client server side * lw announcements * promoToast * animated bg * update ticket og bg * minor details * secret ticket * social share text * social share textgst * flow text * update og * update og handler * Update index.ts * use functions.invoke and use generic supabase URL * Update index.ts * Update handler.tsx * Update package-lock.json * Update handler.tsx * add next api route * moved to vercel edge function * set revalidate * Update route.tsx * Delete lw-ticket-og.tsx * Update route.tsx * Update [username].tsx * Update [username].tsx * add more fetches * Update turbo.json * ticket themes updated * copy and layout updated * Update index.tsx * Update Ticket.tsx * Update TicketingFlow.tsx * update countdown * updated bg * small updates * moat * Update [username].tsx * Update 20240723155310_add_lw12_ticketing_schema.sql * optimistic ticket stuff og generation * Update index.tsx * updated layout * update themes in og * Update constants.ts * attr renamed * Update TicketingFlow.tsx * Update TicketActions.tsx * grammar * moar updates * Update TicketActions.tsx * Update TicketActions2.tsx * Update TicketActions.tsx * Update Hero.tsx * Update TicketingFlow.tsx * remove console logs --------- Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com>
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
import React, { useEffect, useState } from 'react'
|
|
import { SupabaseClient } from '@supabase/supabase-js'
|
|
import { cn } from 'ui'
|
|
import { Dot } from 'lucide-react'
|
|
import useConfData from '~/components/LaunchWeek/hooks/use-conf-data'
|
|
|
|
const TicketPresence = (props: { className?: string }) => {
|
|
const { supabase, ticketState } = useConfData()
|
|
const hasTicket = ticketState === 'ticket'
|
|
const [realtimeChannel, setRealtimeChannel] = useState<ReturnType<
|
|
SupabaseClient['channel']
|
|
> | null>(null)
|
|
const [onlineUsers, setOnlineUsers] = useState<any[]>([])
|
|
const isSingular = onlineUsers.length === 1
|
|
const lowTraffic = onlineUsers.length < 5
|
|
|
|
useEffect(() => {
|
|
// Listen to realtime presence
|
|
if (!realtimeChannel && supabase) {
|
|
const lwxRoom = supabase?.channel('lwx_online', {
|
|
config: { broadcast: { self: true, ack: true } },
|
|
})
|
|
|
|
setRealtimeChannel(lwxRoom)
|
|
const userStatus = {}
|
|
|
|
lwxRoom
|
|
?.on('presence', { event: 'sync' }, () => {
|
|
const newState = lwxRoom.presenceState()
|
|
const users = [...Object.entries(newState).map(([_, value]) => value[0])]
|
|
const uniqueUsrs = users.filter(onlyUnique)
|
|
setOnlineUsers(uniqueUsrs)
|
|
})
|
|
.subscribe(async (status) => {
|
|
if (status !== 'SUBSCRIBED') {
|
|
return null
|
|
}
|
|
await lwxRoom.track(userStatus)
|
|
})
|
|
}
|
|
|
|
return () => {
|
|
realtimeChannel?.unsubscribe()
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'text-foreground-lighter text-xs flex items-center transition-opacity',
|
|
hasTicket && 'text-sm opacity-80',
|
|
props.className
|
|
)}
|
|
>
|
|
<Dot className="text-brand animate-pulse -ml-2" />
|
|
{onlineUsers.length} {isSingular ? 'person is' : 'people are'}{' '}
|
|
{hasTicket ? 'customizing' : 'generating'} their ticket
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function onlyUnique(value: any, index: number, array: any[]) {
|
|
return array.indexOf(value) === index
|
|
}
|
|
|
|
export default TicketPresence
|