Adjusted types, environment vars, load env vars from Cloudflare (?), sync iframe updates [not working]
This commit is contained in:
parent
198109a919
commit
6cf1c2511b
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseBoxShapeUtil, TLBaseShape } from "tldraw"
|
||||
import { useCallback, useState } from "react"
|
||||
import { useCallback, useState, useEffect } from "react"
|
||||
//import Embed from "react-embed"
|
||||
|
||||
export type IEmbedShape = TLBaseShape<
|
||||
|
|
@ -9,7 +9,7 @@ export type IEmbedShape = TLBaseShape<
|
|||
h: number
|
||||
url: string | null
|
||||
interactionState?: {
|
||||
scrollPosition?: { x: number; y: number }
|
||||
scrollPosition: { x: number; y: number }
|
||||
currentTime?: number // for videos
|
||||
// other state you want to sync
|
||||
}
|
||||
|
|
@ -133,12 +133,26 @@ export class EmbedShape extends BaseBoxShapeUtil<IEmbedShape> {
|
|||
</g>
|
||||
)
|
||||
}
|
||||
|
||||
component(shape: IEmbedShape) {
|
||||
const [inputUrl, setInputUrl] = useState(shape.props.url || "")
|
||||
const [error, setError] = useState("")
|
||||
const [copyStatus, setCopyStatus] = useState(false)
|
||||
|
||||
// Add an effect to handle incoming sync updates
|
||||
useEffect((): void => {
|
||||
if (shape.props.interactionState?.scrollPosition) {
|
||||
const iframe = document.querySelector("iframe")
|
||||
if (iframe?.contentWindow) {
|
||||
// Dispatch custom event to iframe
|
||||
iframe.contentWindow.dispatchEvent(
|
||||
new CustomEvent("syncScroll", {
|
||||
detail: shape.props.interactionState.scrollPosition,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [shape.props.interactionState?.scrollPosition])
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
|
@ -327,11 +341,36 @@ export class EmbedShape extends BaseBoxShapeUtil<IEmbedShape> {
|
|||
loading="lazy"
|
||||
referrerPolicy="no-referrer"
|
||||
onLoad={(e) => {
|
||||
// Add message listener for iframe communication
|
||||
window.addEventListener("message", (event) => {
|
||||
const iframe = e.currentTarget as HTMLIFrameElement
|
||||
|
||||
// Inject scroll monitoring script
|
||||
const script = `
|
||||
window.addEventListener('scroll', () => {
|
||||
window.parent.postMessage({
|
||||
type: 'scroll',
|
||||
scrollPosition: {
|
||||
x: window.scrollX,
|
||||
y: window.scrollY
|
||||
}
|
||||
}, '*');
|
||||
});
|
||||
|
||||
// Listen for scroll updates from other users
|
||||
window.addEventListener('syncScroll', (e) => {
|
||||
window.scrollTo(e.detail.x, e.detail.y);
|
||||
});
|
||||
`
|
||||
|
||||
// @ts-ignore
|
||||
iframe.contentWindow?.eval(script as string)
|
||||
|
||||
// Listen for messages from iframe
|
||||
window.addEventListener("message", (event) => {
|
||||
if (event.source === iframe.contentWindow) {
|
||||
handleIframeInteraction(event.data)
|
||||
handleIframeInteraction({
|
||||
...shape.props.interactionState,
|
||||
scrollPosition: event.data.scrollPosition,
|
||||
})
|
||||
}
|
||||
})
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -36,15 +36,10 @@ export class VideoChatShape extends BaseBoxShapeUtil<IVideoChatShape> {
|
|||
}
|
||||
|
||||
try {
|
||||
const apiKey = import.meta.env["VITE_DAILY_API_KEY"]
|
||||
console.log("API Key available:", !!apiKey)
|
||||
if (!apiKey) throw new Error("Daily API key is missing")
|
||||
|
||||
const response = await fetch("https://api.daily.co/v1/rooms", {
|
||||
const response = await fetch("/api/create-room", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${apiKey.trim()}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
properties: {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
export interface Environment {
|
||||
TLDRAW_BUCKET: R2Bucket
|
||||
TLDRAW_DURABLE_OBJECT: DurableObjectNamespace
|
||||
DAILY_API_KEY: string;
|
||||
DAILY_DOMAIN: string;
|
||||
DAILY_API_KEY: string
|
||||
VITE_DAILY_API_KEY: string
|
||||
VITE_DAILY_DOMAIN: string
|
||||
VITE_GOOGLE_CLIENT_ID: string
|
||||
VITE_GOOGLE_MAPS_API_KEY: string
|
||||
}
|
||||
|
|
@ -62,6 +62,7 @@ const { preflight, corsify } = cors({
|
|||
maxAge: 86400,
|
||||
credentials: true,
|
||||
})
|
||||
|
||||
const router = AutoRouter<IRequest, [env: Environment, ctx: ExecutionContext]>({
|
||||
before: [preflight],
|
||||
finally: [
|
||||
|
|
@ -124,61 +125,43 @@ const router = AutoRouter<IRequest, [env: Environment, ctx: ExecutionContext]>({
|
|||
})
|
||||
})
|
||||
|
||||
.post("/daily/rooms", async (request, env) => {
|
||||
.post("/api/create-room", async (request) => {
|
||||
try {
|
||||
const { name, properties } = (await request.json()) as {
|
||||
name: string
|
||||
properties: Record<string, unknown>
|
||||
}
|
||||
// Replace with your actual video chat service API call
|
||||
const room = await createVideoRoom()
|
||||
|
||||
// Create a room using Daily.co API
|
||||
const dailyResponse = await fetch("https://api.daily.co/v1/rooms", {
|
||||
method: "POST",
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
url: room.url,
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${env.DAILY_API_KEY}`,
|
||||
"Access-Control-Allow-Origin": "*", // Configure appropriately for production
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name,
|
||||
properties,
|
||||
}),
|
||||
})
|
||||
|
||||
const dailyData = await dailyResponse.json()
|
||||
|
||||
if (!dailyResponse.ok) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
message:
|
||||
(dailyData as any).info || "Failed to create Daily.co room",
|
||||
}),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
url: `https://${env.DAILY_DOMAIN}/${(dailyData as any).name}`,
|
||||
}),
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
)
|
||||
} catch (error) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
message: error instanceof Error ? error.message : "Unknown error",
|
||||
}),
|
||||
{
|
||||
return new Response(JSON.stringify({ error: "Failed to create room" }), {
|
||||
status: 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Handle OPTIONS for CORS
|
||||
.options("/api/create-room", () => {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST",
|
||||
"Access-Control-Allow-Headers": "Content-Type",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// export our router for cloudflare
|
||||
export default router
|
||||
|
|
|
|||
Loading…
Reference in New Issue