Skip to content

Instantly share code, notes, and snippets.

@netgfx
Created April 12, 2023 10:12
Show Gist options
  • Save netgfx/905f9122a05e3ed579110a1828c56e34 to your computer and use it in GitHub Desktop.
Save netgfx/905f9122a05e3ed579110a1828c56e34 to your computer and use it in GitHub Desktop.
Framer + Supabase realtime (receiver)
import { ComponentType, useRef, useState } from "react"
import { useEffect } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { randomColor } from "https://framer.com/m/framer/utils.js@^0.9.0"
import * as SupabaseJs from "https://jspm.dev/@supabase/supabase-js@rc"
import _ from "lodash"
// Learn more: https://www.framer.com/docs/guides/overrides/
export const useStore = createStore({
background: "#0099FF",
dburl: "https://qsxfdqhsuyovskknxkaj.supabase.co",
dbAPIKey:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0MDM3ODAxMCwiZXhwIjoxOTU1OTU0MDEwfQ.STNbut59AMoiD6Zd6O4oi0NJ__8fKahZitQPnWffK0E",
supabaseObj: null,
roomName: "sandbox-room-1",
objects: {
red: { x: 0, y: 0 },
yellow: { x: 0, y: 0 },
},
objectName: "",
channelRef: null,
})
export function init(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
var ref = useRef()
useEffect(() => {
const supabase = SupabaseJs.createClient(
store.dburl,
store.dbAPIKey
)
setStore({ supabaseObj: supabase })
console.log("supabase connected: ", supabase)
var name = new URLSearchParams(window.location.search).getAll("id")
setStore({ objectName: name[0], channelRef: ref })
}, [])
return <Component {...props} />
}
}
export function addDrag(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
var channel
var ref = useRef()
const subscribeToRoom = () => {
// The name of the channel can be set to any string.
// Set the same name across both the broadcasting and receiving clients.
store.channelRef.current = store.supabaseObj.channel(
store.roomName,
{
configs: {
broadcast: { ack: true },
},
}
)
// listen to broadcasts
console.log(channel)
store.channelRef.current.subscribe(async (status) => {
console.log(status)
if (status === "SUBSCRIBED") {
store.channelRef.current.on(
"broadcast",
{ event: "location" },
(payload) => {
console.log(payload)
var obj = _.cloneDeep(store.objects)
obj[payload.payload.name] = {
x: payload.payload.x,
y: payload.payload.y,
}
setStore({ objects: obj })
}
)
console.log("Status: ", status)
}
})
}
const sendDrag = async (event, info) => {
console.log(store.channelRef.current)
if (store.channelRef.current) {
var diffX = Math.abs(
ref.current.getBoundingClientRect().left - info.point.x
)
var diffY = Math.abs(
ref.current.getBoundingClientRect().top - info.point.y
)
const status = await store.channelRef.current.send({
type: "broadcast",
event: "location",
payload: {
x: ref.current.getBoundingClientRect().left,
y: ref.current.getBoundingClientRect().top,
name: store.objectName,
},
})
console.log(status)
}
}
useEffect(() => {
if (store.supabaseObj !== null) {
subscribeToRoom()
}
}, [store.supabaseObj])
return (
<Component
ref={ref}
{...props}
whileHover={{ scale: 1.05 }}
drag
whileDrag={{ scale: 1.1 }}
dragMomentum={false}
onDrag={(event, info) => sendDrag(event, info)}
/>
)
}
}
export function setRedPosition(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
const [pos, setPos] = useState({ x: 0, y: 0 })
useEffect(() => {
console.log(store.objects.red)
setPos(store.objects.red)
}, [store.objects.red])
return (
<Component
{...props}
whileHover={{ scale: 1.05 }}
animate={{ x: pos.x, y: pos.y }}
/>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment