From 887e1725260446b4225ddeaaa0550344391093c5 Mon Sep 17 00:00:00 2001 From: admtracksteel Date: Mon, 25 May 2026 00:47:27 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Auto-deploy:=20melhoria=20no=20s?= =?UTF-8?q?nap=20e=20medi=C3=A7=C3=A3o=20AR=20em=2025/05/2026=2000:47:27?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MeetingRoom.tsx | 98 ++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/src/pages/MeetingRoom.tsx b/src/pages/MeetingRoom.tsx index 547e07b..76e5dda 100644 --- a/src/pages/MeetingRoom.tsx +++ b/src/pages/MeetingRoom.tsx @@ -1,5 +1,36 @@ -import { useEffect, useRef, useState, useMemo, Suspense } from 'react'; +import React, { useEffect, useRef, useState, useMemo, Suspense } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; + +interface ErrorBoundaryProps { + children: React.ReactNode; + fallback: React.ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; +} + +class ModelErrorBoundary extends React.Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError() { + return { hasError: true }; + } + + componentDidCatch(error: any, errorInfo: any) { + console.error("🚨 [ModelErrorBoundary] Falha de renderização/rede no modelo:", error, errorInfo); + } + + render() { + if (this.state.hasError) { + return this.props.fallback; + } + return this.props.children; + } +} import { Canvas, useFrame } from '@react-three/fiber'; import { OrbitControls, Text, useGLTF } from '@react-three/drei'; import * as THREE from 'three'; @@ -526,28 +557,42 @@ function ThreeMeetingRoomScene({ currentActiveModel, presentationState }: { curr {/* Modelo 3D da Maquete Holográfica */} - - - - + + + + + + + + + + }> - {currentActiveModel ? ( - - ) : ( - // Holograma Padrão Geométrico se não houver maquete carregada - - - - - - - - - - - )} - + + + + + }> + {currentActiveModel ? ( + + ) : ( + // Holograma Padrão Geométrico se não houver maquete carregada + + + + + + + + + + + )} + + @@ -721,7 +766,7 @@ export default function MeetingRoom() { }; // Inicializa o Supabase Presence & Broadcast para conexões oficiais - const connectToRoom = (targetRoomId: string) => { + const connectToRoom = async (targetRoomId: string) => { if (!name.trim()) { toast.error('Digite seu nome primeiro'); return; @@ -742,6 +787,13 @@ export default function MeetingRoom() { const finalRoomId = targetRoomId.trim().toUpperCase() || Math.random().toString(36).substring(3, 8).toUpperCase(); setRoomCode(finalRoomId); + + // Evita o erro "cannot add presence callbacks ... after subscribe()" removendo canais antigos com o mesmo tópico + const oldChannels = supabase.getChannels().filter(c => c.topic === `realtime:meeting_room_${finalRoomId}`); + for (const old of oldChannels) { + console.log(`🔌 [MeetingRoom] Removendo canal antigo ativo para evitar conflitos: ${old.topic}`); + await supabase.removeChannel(old); + } console.log(`🔌 [MeetingRoom] Conectando à sala: ${finalRoomId} como ${isPresenter ? 'Apresentador' : 'Convidado'}`);