{{-- Navegadores bloqueiam som sem uma primeira interação — como esse
painel fica ligado sozinho numa TV, precisa de UM clique pra
destravar o áudio. Depois disso, os beeps tocam sozinhos. --}}
{{-- Tema "Plenário Feira Grande" — bifurcação SÓ de apresentação: a raiz
acima (wire:poll, x-data, ouvintes de eventos, botão de som) é comum
a todos os temas; tudo entre o else e o endif abaixo é o painel de
sempre, sem nenhuma alteração. --}}
@if(\App\Models\Configuracao::atual()->visual_quorum_painel_publico === 'plenario_feiragrande')
@include('livewire.publico.temas.plenario-feiragrande')
@else
{{-- ============ cabeçalho fixo, comum a todas as telas base ============ --}}
@php($config = \App\Models\Configuracao::atual())
@if($config->painel_mostrar_ao_vivo)
@if($sessao)
AO VIVO
@else
AGUARDANDO
@endif
@endif
@if($config->painel_mostrar_relogio_data)
@endif
{{-- ============ MENSAGEM NO TELÃO ============
Camada de apresentação pura (ver Sessao::isMensagemTelaoAtiva())
— nunca depende de votação/matéria/fala/cronômetro; some
sozinha quando o operador oculta (ResultadoAoVivo::estadoBase()
volta a calcular o estado real no próximo wire:poll.2s). --}}
@if($this->estadoBase === 'mensagem')
AVISO
{{ $sessao->mensagem_telao_texto }}
@endif
{{-- ============ SEM SESSÃO ATIVA — MODO INSTITUCIONAL ============
estadoBase() só chega a 'sem_sessao' quando $sessao é null (ver
primeiro `if` do método) — ou seja, este bloco é estruturalmente
inatingível durante uma sessão ativa, sem precisar de nenhuma
condição extra aqui. No próximo wire:poll.2s em que uma sessão
virar 'ativa', estadoBase() já deixa de retornar 'sem_sessao'
sozinho — o institucional desaparece e o painel legislativo
assume, sem nenhum código novo pra isso. --}}
@if($this->estadoBase === 'sem_sessao')
@include('livewire.publico.partials.modo-institucional', ['dados' => $this->dadosInstitucionais])
@endif
{{-- ============ PROJETOR (imagem ou vídeo ativado pelo operador) ============
estadoBase() já tinha prioridade máxima pra 'projecao' (ver
ResultadoAoVivo::estadoBase()) e projecaoEmbedUrl() já convertia
YouTube/Vimeo corretamente — mas nunca existia HTML aqui pra
mostrar isso: o telão ficava só no fundo escuro. Reaproveita o
mesmo wire:poll.2s do componente (raiz do arquivo) — nenhum
polling novo. Ao desligar, projecao_ativa vira false e
estadoBase() recalcula sozinho pro estado real da sessão (fala/
votação/quórum), sem precisar "lembrar" de nada. --}}
@if($this->estadoBase === 'projecao')
@endif
{{-- ============ SESSÃO SUSPENSA ============
Apresentação institucional — preserva cabeçalho/logo/relógio/
AO VIVO (ficam em .telao-topo, fora daqui) e nunca deixa a
tela vazia. Some sozinho ao retomar (Sessao.suspensa vira
false, estadoBase() recalcula pro estado real na próxima
wire:poll.2s), sem F5. --}}
@if($this->estadoBase === 'suspensa')
SESSÃO TEMPORARIAMENTE SUSPENSA
@if($sessao->suspensa_motivo)
{{ $sessao->suspensa_motivo }}
@endif
Os trabalhos serão retomados em instantes.
@endif
{{-- ============ QUÓRUM (tela padrão) ============
Etapa Sessão×Quórum, itens 17-20 do pedido — três estados
(ver ResultadoAoVivo::estadoQuorumTv()): 'aguardando' (sessão
ativa, nenhuma chamada existiu ainda — sem grid, sem número),
'aberto' (chamada manual em andamento) e 'encerrado' (última
chamada fechada continua exibida — nunca "zera" a TV). Rótulo
do card muda; o grid abaixo (e o rodapé do tema Plenário
Clássico) só aparecem fora de 'aguardando', porque
$this->vereadoresComPresenca()/$this->presentes já vêm vazios/
zerados nesse estado (ver ResultadoAoVivo::presencaPorVereador()). --}}
@if($this->estadoBase === 'quorum')
@if($this->estadoQuorumTv !== 'aguardando')
{{-- ============ MESA DIRETORA (só no tema Plenário Clássico) ============
Aditivo: só existe dentro deste @if, nunca visível nem
processado nos outros temas. Fonte: ResultadoAoVivo::
mesaDiretora() (Mandato tipo='mesa_diretora'), computed
preguiçoso — sem custo pros demais temas. --}}
@if($config->visual_quorum_painel_publico === 'plenario_classico' && $this->mesaDiretora->isNotEmpty())
MESA DIRETORA
@foreach($this->mesaDiretora as $m)
@if($m->user?->foto)
@else
{{ mb_substr($m->user->name ?? '?', 0, 1) }}
@endif
{{ $m->user->name ?? '—' }}
{{ $m->cargo }}
@endforeach
VEREADORES
@endif
{{-- Microcorreção "Preservar parâmetro de cores do quórum e
acrescentar modo de cards brancos" — a fonte do ESTADO
continua sendo sempre a mesma (Quorum::estadoVisual(),
nunca alterada), mas a APRESENTAÇÃO depende do tema
escolhido em Configuracao::visual_quorum_painel_publico
(item 5/6 do pedido: nunca misturar as duas coisas).
'padrao'/'cores_vivas' reproduzem EXATAMENTE a fórmula
histórica (nunca distinguiram "aguardando" de "ausente" —
os dois sempre foram card inteiro colorido); só
'cards_brancos' é o modo novo (branco + status colorido). --}}
@php($temaQuorum = $config->visual_quorum_painel_publico)
A sessão está em andamento. Assim que a chamada de quórum for iniciada, a presença aparecerá aqui.
@endif
@endif
{{-- ============ LEITURA DA MATÉRIA ============ --}}
@if($this->estadoBase === 'leitura' && $this->materiaEmLeitura)
{{-- CORREÇÃO 500 (view: unexpected token) — ATENÇÃO: nunca
escrever a sequência arroba-php seguida de arroba-endphp
(mesmo em prosa, mesmo dentro de um comentário Blade como
este) — o extrator de blocos de PHP do compilador roda
ANTES da remoção de comentários e usa uma busca não-gulosa
pelo PRÓXIMO arroba-endphp do arquivo inteiro (é o mesmo
tipo de armadilha já documentada mais acima pra comentário
CSS, só que agora vale também pra comentário Blade). Este
bloco usava a forma de BLOCO (abre com arroba-php sozinho,
fecha com arroba-endphp) — era o único arroba-endphp de todo
o arquivo, enquanto o resto do arquivo inteiro usa a forma
INLINE (arroba-php seguido de parênteses, sem fechamento)
dezenas de vezes antes deste ponto (ex.: perto do topo,
montando a variável de configuração). Como o compilador não
distingue as duas formas, ele casou o primeiro uso inline
do arquivo com o fechamento de bloco aqui embaixo, tratando
tudo no meio (centenas de linhas de HTML/diretivas reais)
como um único trecho de PHP puro — daí o 500 em QUALQUER
página que carregasse esta view, não só no estado leitura.
Reescrito abaixo só na FORMA (uma atribuição por linha, sem
nenhum fechamento de bloco) — mesmos cálculos, mesmos
valores, mesma lógica de antes, zero mudança de
comportamento. Faixa de tamanho do conteúdo (título +
descrição) decide a classe tl-curto/tl-medio/tl-longo/
tl-muito-longo (ver CSS acima de .telao-leitura). Conta
também quebras de linha da descrição. tl-muito-longo é o
limite técnico pra conteúdo "absurdamente grande" — a rede
de segurança pra esse extremo é o overflow:hidden da RAIZ do
componente (mesmo mecanismo do estado 'votacao'), nunca um
overflow:hidden no título/descrição em si. Identificação
(tipo + nº/ano quando existir) usa o mesmo formato já usado
nas telas administrativas. --}}
@php($tlMateria = $this->materiaEmLeitura->materia)
@php($tlTexto = trim(($tlMateria->titulo ?? '') . ' ' . ($tlMateria->descricao ?? '')))
@php($tlTamanho = mb_strlen($tlTexto))
@php($tlQuebras = substr_count($tlMateria->descricao ?? '', "\n"))
@php($tlNivel = match (true) { $tlTamanho > 1200 || $tlQuebras > 20 => 'muito-longo', $tlTamanho > 500 || $tlQuebras > 8 => 'longo', $tlTamanho > 180 || $tlQuebras > 3 => 'medio', default => 'curto' })
@php($tlIdentificacao = $tlMateria->tipo . ($tlMateria->numero ? ' nº ' . $tlMateria->numero . '/' . $tlMateria->ano : ''))
{{ $v->name }}
@if($v->eh_presidente)
@if($temaVotacao === 'plenario_dark')
Presidente
@else
— Presidente
@endif
@endif
@endif
@if($v->partido && $config->painel_mostrar_partido){{ $v->partido }}@endif
@if($v->eh_presidente && $situacaoPresidente === 'nao_vota')
NÃO VOTA
@elseif($v->eh_presidente && $situacaoPresidente === 'desempate')
DESEMPATE
@elseif($v->eh_presidente && $situacaoPresidente === 'liberado' && ! $voto)
VOTO LIBERADO
@endif
{{-- Indicador textual do voto — só existe no tema
'verde_institucional' (pedido explícito: não
aparece no quórum nem em nenhum outro tema).
Elemento semântico de verdade (não
pseudo-elemento/content:), condicionado ao
mesmo $classeVoto que já colore o card, então
nunca aparece sem voto ou com
painel_mostrar_votos_individuais desligado. --}}
@if($temaVotacao === 'verde_institucional' && $classeVoto)
@if($classeVoto === 'voto-favor')
Favor
@elseif($classeVoto === 'voto-contra')
Contra
@else
Abstenção
@endif
@endif
@endforeach
@endif
{{-- ============ VOTAÇÃO INCIDENTAL (Requerimento) ============
Microcorreção "VOTAÇÃO INCIDENTAL NO PAINEL TV" — TIPO 2 de
votação (Requerimento/VotoRequerimento), nunca misturado com
a votação de matéria acima. Sobrepõe o fluxo normal enquanto
estiver aberta (ver estadoBase()) sem nunca finalizar/excluir
a matéria internamente — ela só volta a aparecer sozinha
quando o requerimento termina. Nome do TipoRequerimento
sempre em destaque (nunca "Votação" genérico) pra ninguém
pensar que é a matéria em si sendo votada. Contagem vem só
de $this->contagemRequerimento (Requerimento::contarVotos()),
nunca calculada aqui. --}}
@if($this->estadoBase === 'votacao_incidental' && $this->requerimentoEmVotacao)
@php($req = $this->requerimentoEmVotacao)
@endif
{{-- ============ INSCRIÇÕES ABERTAS ============ --}}
{{-- ============ USO DA PALAVRA (inscrição formal) ============
Diagnóstico "Inscritos para Uso da Palavra" — este bloco
SUBSTITUI o antigo aviso incondicional de "inscrições abertas"
(que aparecia sozinho assim que um momento era aberto pro
vereador se inscrever, sem nenhuma ação do operador). Agora só
aparece quando Sessao::uso_da_palavra_visivel_telao é true —
ver estadoBase() acima: a existência de inscritos/momento
aberto nunca decide isso sozinha. Pedido de fala comum
(estado 'fila', acima) nunca depende deste estado e nunca é
afetado por ele.
Melhoria "Transparência dos Inscritos e do Sorteio" —
uso_da_palavra_modo_telao ('inscritos'|'sorteio') só decide o
CABEÇALHO exibido abaixo; a LISTA é sempre a mesma
$this->inscritosUsoDaPalavraPendentes (pedidos_fala.ordem ao
vivo) nos dois modos — inclusive no modo sorteio, de propósito:
assim, se alguém for cancelado depois do sorteio, a tela nunca
mostra nome inválido, sempre reflete quem realmente ainda está
na fila. Nenhum sorteio é disparado aqui — troca de modo é só
apresentação (CentralSessaoService::mostrarInscritosNaTv()/
mostrarSorteioNaTv()/tirarUsoDaPalavraDaTv()). Quando o
operador chama alguém, o pedido sai de 'pendente' e o telão
migra sozinho pro estado 'fala' (acima, prioridade mais alta) —
tela "Com a palavra" já existente, sem nenhuma tela nova.
============ --}}
@if($this->estadoBase === 'uso_da_palavra')
@php($modoUsoDaPalavra = $sessao->uso_da_palavra_modo_telao)
@if($this->inscritosUsoDaPalavraPendentes->isEmpty())
{{ $modoUsoDaPalavra === 'sorteio' ? '🎲 Sorteio — Uso da Palavra' : '🎙 Uso da Palavra' }}
@if($modoUsoDaPalavra === 'sorteio')
ORDEM SORTEADA — USO DA PALAVRA
Nenhum inscrito pendente no momento.
@else
AGUARDANDO INSCRIÇÕES
A etapa de Uso da Palavra está aberta. Assim que houver inscritos, a ordem de chamada
aparecerá aqui.
@endif
@else
@if($modoUsoDaPalavra === 'sorteio')
🎲Ordem sorteada — Uso da Palavra
@else
🎙Inscritos para Uso da Palavra
@endif
{{ $this->inscritosUsoDaPalavraPendentes->count() }}
@foreach($this->inscritosUsoDaPalavraPendentes as $i => $pedido)
@endif
@endif
{{-- ============ ENCAMINHAMENTO (Etapa K) ============
Fase própria do fluxo PRINCIPAL da matéria (nunca um
Requerimento/Incidente, nunca gera votação própria — item
15/16 do pedido). Reaproveita as classes .telao-fala-card/
.telao-fala-cronometro (mesmo desenho da fala normal), só com
rótulo/cor próprios pra nunca ser confundido com discussão. --}}
@if($this->estadoBase === 'encaminhamento' && $this->materiaEmEncaminhamento)
@php($materiaEnc = $this->materiaEmEncaminhamento)
ENCAMINHAMENTO
{{ $materiaEnc->materia->titulo }}
@if($this->falaEncaminhamentoAtiva)
@php($falaEnc = $this->falaEncaminhamentoAtiva)
@php($inicioEncEm = $falaEnc->tempo_inicio->toIso8601String())
@php($fimEncEm = $falaEnc->tempo_inicio->copy()->addMinutes($falaEnc->tempo_solicitado)->toIso8601String())
@php($duracaoEncSegundos = $falaEnc->tempo_solicitado * 60)
{{-- wire:key inclui $fimEncEm (não só o id do pedido) — item 3 da
melhoria de cronômetro: sem isso, um acréscimo de tempo
(que muda tempo_solicitado/tempo_inicio no MESMO pedido)
não fazia o Livewire trocar este elemento, e o x-init
(que só roda uma vez) nunca recalculava o novo fim —
o acréscimo simplesmente não aparecia no painel público. --}}
@if($falaEnc->fotoExibicao())
@else
{{ mb_substr($falaEnc->nomeExibicao(), 0, 1) }}
@endif
Com a palavra
{{ $falaEnc->nomeExibicao() }}
@if($falaEnc->partidoExibicao())
{{ $falaEnc->partidoExibicao() }}
@endif
@if($config->painel_mostrar_cronometro)
@endif
@else
ENCAMINHAMENTO EM ANDAMENTO
Aguardando próximo orador.
@endif
@endif
{{-- ============ FALA ATIVA (mostra pra qualquer fala autorizada, normal ou aparte) ============ --}}
@if($this->estadoBase === 'fala' && $this->falaEmAndamento)
@php($falaAtual = $this->falaEmAndamento)
@php($inicioEm = $falaAtual->tempo_inicio->toIso8601String())
@php($fimEm = $falaAtual->tempo_inicio->copy()->addMinutes($falaAtual->tempo_solicitado)->toIso8601String())
@php($duracaoSegundos = $falaAtual->tempo_solicitado * 60)
{{-- wire:key inclui $fimEm (não só o id do pedido) — item 3 da
melhoria de cronômetro: sem isso, um acréscimo de tempo
(que muda tempo_solicitado/tempo_inicio no MESMO pedido)
não fazia o Livewire trocar este elemento, e o x-init
(que só roda uma vez) nunca recalculava o novo fim — o
acréscimo simplesmente não aparecia no painel público. --}}
@if($falaAtual->fotoExibicao())
@else
{{ mb_substr($falaAtual->nomeExibicao(), 0, 1) }}
@endif
@if($falaAtual->isAparte())
Aparte autorizado
@elseif($falaAtual->isAvulso())
Convidado
@else
Fala autorizada
@endif
{{ $falaAtual->nomeExibicao() }}
@if($falaAtual->partidoExibicao())
{{ $falaAtual->partidoExibicao() }}
@endif
@if($config->painel_mostrar_cronometro)
{{-- Cronômetro — item "7": sempre grande, nunca quebra linha, nunca
fica atrás de outro elemento. Lógica de tempo 100% inalterada,
só a classe .telao-fala-cronometro mudou (era style inline). --}}
@endif
{{-- Região inferior — nunca sobrepõe o card principal (é um
irmão dele, não um overlay). Só pedidos com status
pendente aparecem aqui; quem está com a palavra tem
status 'autorizada' e nunca aparece duplicado nesta
lista. Atualiza sozinho a cada wire:poll.2s (raiz do
componente) — nenhum polling novo. --}}
@if($config->painel_mostrar_fila_espera && $this->pedidosPendentes->isNotEmpty())
Aguardando a palavra
@foreach($this->pedidosPendentes->take(8) as $pedido)
{{ $pedido->isAparte() ? 'Pedido de aparte registrado' : 'Pedido de fala registrado' }}
{{ $i + 1 }}
{{ $pedido->tempo_solicitado }} min
@endforeach
@endif
{{-- ============================================================
OVERLAYS — aparecem por cima da tela base e somem sozinhos
============================================================ --}}
{{-- tela preta de transição (contando os votos) --}}
APURANDO OS VOTOS...
{{-- resultado oficial da votação --}}
@if($config->painel_mostrar_totalizadores)
FAVORÁVEIS
CONTRÁRIOS
ABSTENÇÕES
@endif
{{ strtoupper(\App\Models\Configuracao::atual()->nome_camara) }} · RESULTADO OFICIAL
{{-- pedido de vistas --}}
Pedido de vistas
solicitou vistas da matéria em leitura
@endif {{-- fim da bifurcação do tema "Plenário Feira Grande" --}}