Skip to content

Instantly share code, notes, and snippets.

@netgfx
Created April 12, 2023 10:11
Show Gist options
  • Save netgfx/14515b438ad6646a6211880d45a6df0c to your computer and use it in GitHub Desktop.
Save netgfx/14515b438ad6646a6211880d45a6df0c to your computer and use it in GitHub Desktop.
Framer + Supabase realtime (sender)
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: "YOUR SUPABASE URL HERE",
dbAPIKey:
"YOUR ANON KEY HERE",
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 sendMessage(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 },
},
}
)
// subscribe registers your client with the server
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(event, info, info.point.x, info.point.y)
if (store.channelRef.current) {
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,
},
})
}
}
useEffect(() => {
if (store.supabaseObj !== null) {
subscribeToRoom()
}
}, [store.supabaseObj])
return (
<Component
{...props}
ref={ref}
whileHover={{ scale: 1.05 }}
drag
whileDrag={{ scale: 1.1 }}
dragMomentum={false}
onDrag={(event, info) => sendDrag(event, info)}
/>
)
}
}
export function setYellowPosition(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
const [pos, setPos] = useState({ x: 0, y: 0 })
useEffect(() => {
setPos(store.objects.yellow)
}, [store.objects.yellow])
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