mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-22 13:19:05 +00:00
feat: implement frontend video platform configuration and abstraction
- Add NEXT_PUBLIC_VIDEO_PLATFORM environment variable support - Create video platform abstraction layer with factory pattern - Implement Whereby and Jitsi platform providers - Update room meeting page to use platform-agnostic component - Add platform display in room management (cards and table views) - Support single platform per deployment configuration - Maintain backward compatibility with existing Whereby integration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
94
www/app/lib/videoPlatforms/whereby/WherebyProvider.tsx
Normal file
94
www/app/lib/videoPlatforms/whereby/WherebyProvider.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
forwardRef,
|
||||
useImperativeHandle,
|
||||
} from "react";
|
||||
import { VideoPlatformComponentProps } from "../types";
|
||||
|
||||
// Whereby embed element type declaration
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
"whereby-embed": React.DetailedHTMLProps<
|
||||
React.HTMLAttributes<HTMLElement> & {
|
||||
room?: string;
|
||||
style?: React.CSSProperties;
|
||||
},
|
||||
HTMLElement
|
||||
>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const WherebyProvider = forwardRef<HTMLElement, VideoPlatformComponentProps>(
|
||||
({ meeting, roomRef, onReady, onConsentGiven, onConsentDeclined }, ref) => {
|
||||
const [wherebyLoaded, setWherebyLoaded] = useState(false);
|
||||
const internalRef = useRef<HTMLElement>(null);
|
||||
const elementRef = roomRef || internalRef;
|
||||
|
||||
// Expose the element ref through the forwarded ref
|
||||
useImperativeHandle(ref, () => elementRef.current!, [elementRef]);
|
||||
|
||||
// Load Whereby SDK
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
import("@whereby.com/browser-sdk/embed")
|
||||
.then(() => {
|
||||
setWherebyLoaded(true);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Handle leave event
|
||||
const handleLeave = useCallback(() => {
|
||||
// This will be handled by the parent component
|
||||
// through router navigation or other means
|
||||
}, []);
|
||||
|
||||
// Handle ready event
|
||||
const handleReady = useCallback(() => {
|
||||
if (onReady) {
|
||||
onReady();
|
||||
}
|
||||
}, [onReady]);
|
||||
|
||||
// Set up event listeners
|
||||
useEffect(() => {
|
||||
if (!wherebyLoaded || !elementRef.current) return;
|
||||
|
||||
const element = elementRef.current;
|
||||
|
||||
element.addEventListener("leave", handleLeave);
|
||||
element.addEventListener("ready", handleReady);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener("leave", handleLeave);
|
||||
element.removeEventListener("ready", handleReady);
|
||||
};
|
||||
}, [wherebyLoaded, handleLeave, handleReady, elementRef]);
|
||||
|
||||
if (!wherebyLoaded || !meeting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const roomUrl = meeting.host_room_url || meeting.room_url;
|
||||
|
||||
return (
|
||||
<whereby-embed
|
||||
ref={elementRef}
|
||||
room={roomUrl}
|
||||
style={{ width: "100vw", height: "100vh" }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
WherebyProvider.displayName = "WherebyProvider";
|
||||
|
||||
export default WherebyProvider;
|
||||
Reference in New Issue
Block a user