Add canvas sync bridge for rspace.online integration
PostMessage listener in CanvasEmbed receives shape updates from the embedded rspace canvas iframe. Canvas-sync utility provides type guards and API helpers for pushing shapes to rspace. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8c13f6ad71
commit
cc88cdd0d8
|
|
@ -1,14 +1,31 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { isCanvasMessage, CanvasShapeMessage } from '@/lib/canvas-sync';
|
||||
|
||||
interface CanvasEmbedProps {
|
||||
canvasSlug: string;
|
||||
className?: string;
|
||||
onShapeUpdate?: (message: CanvasShapeMessage) => void;
|
||||
}
|
||||
|
||||
export function CanvasEmbed({ canvasSlug, className = '' }: CanvasEmbedProps) {
|
||||
const rspaceUrl = process.env.NEXT_PUBLIC_RSPACE_URL || 'https://rspace.online';
|
||||
export function CanvasEmbed({ canvasSlug, className = '', onShapeUpdate }: CanvasEmbedProps) {
|
||||
const canvasUrl = `https://${canvasSlug}.rspace.online`;
|
||||
|
||||
const handleMessage = useCallback(
|
||||
(event: MessageEvent) => {
|
||||
if (!isCanvasMessage(event)) return;
|
||||
if (event.data.communitySlug !== canvasSlug) return;
|
||||
onShapeUpdate?.(event.data);
|
||||
},
|
||||
[canvasSlug, onShapeUpdate]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('message', handleMessage);
|
||||
return () => window.removeEventListener('message', handleMessage);
|
||||
}, [handleMessage]);
|
||||
|
||||
return (
|
||||
<div className={`relative bg-slate-900 rounded-xl overflow-hidden border border-slate-700/50 ${className}`}>
|
||||
{/* Toolbar */}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Canvas sync utilities for rtrips.online <-> rspace.online integration
|
||||
*
|
||||
* Listens for postMessage events from the embedded rspace canvas iframe
|
||||
* and provides methods to push structured data to the canvas.
|
||||
*/
|
||||
|
||||
export interface CanvasShapeMessage {
|
||||
source: 'rspace-canvas';
|
||||
type: 'shape-updated' | 'shape-deleted';
|
||||
communitySlug: string;
|
||||
shapeId: string;
|
||||
data: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export function isCanvasMessage(event: MessageEvent): event is MessageEvent<CanvasShapeMessage> {
|
||||
return event.data?.source === 'rspace-canvas';
|
||||
}
|
||||
|
||||
/**
|
||||
* Push shapes to an rspace canvas community via the shapes API
|
||||
*/
|
||||
export async function pushShapesToCanvas(
|
||||
canvasSlug: string,
|
||||
shapes: Record<string, unknown>[],
|
||||
rspaceUrl?: string
|
||||
): Promise<void> {
|
||||
const baseUrl = rspaceUrl || process.env.RSPACE_INTERNAL_URL || 'http://rspace-online:3000';
|
||||
|
||||
const response = await fetch(`${baseUrl}/api/communities/${canvasSlug}/shapes`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ shapes }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`Failed to push shapes: ${response.status} ${text}`);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue