feat: detectar instalação do LouvorJA Classo (Delphi) e reutilizar/migrar conteúdo — FASE 1 - #143
Open
rafaumeu wants to merge 41 commits into
Open
feat: detectar instalação do LouvorJA Classo (Delphi) e reutilizar/migrar conteúdo — FASE 1#143rafaumeu wants to merge 41 commits into
rafaumeu wants to merge 41 commits into
Conversation
…) e status; pause chega à TV e para o PC
…o dinâmica via appinfo)
…1.5s no control-bar, >1.0s no receiver)
…g (tela preta nunca)
…Q/título visíveis)
…no receiver 0.1.48
…sincronizam com áudio da TV
… por comprimento)
…invisíveis no sorteio
…la, volta fundo padrão)
…m vs vídeo liturgia) — IPC externalAlive
…a externa ativa (hardening culto) 0.1.49
…não tem o handler
…eat 25s no lock de mídia (0.1.50)
…k morto, hardening, heartbeat, paridade webos
…+ hint de atalhos + ESC no operador encerra Monitor único (Windows principalmente): projeção fullscreen screen-saver cobria o app do operador permanentemente — só saía fechando o aplicativo. - Ctrl+Alt+P global enquanto houver projeção viva; toggle hide/show com foco; unregister em todos os caminhos de fechamento (incl. will-quit) - Hint discreto (6s) nas janelas de projeção: ESC encerra · Ctrl+Alt+P alterna - ESC no operador com projeção ativa confirma encerramento (AppConfirm) - 9 testes novos (decisão pura do toggle + controller); suite 45/45 verde
… web-projection) e ESC fecha popup O commit anterior só enganchava o fluxo video/pdf/site (web-projection.mjs). A projeção de hinos/slides usa window.open → did-create-window no main.mjs e não passava por lá — hotkey e hint nunca eram registrados no fluxo principal. - projection-hotkey vira SINGLETON com windowProviders: cada fluxo registra suas janelas; registro do globalShortcut é único (2º register falharia) - main.mjs: init no attach, provider das janelas popup, ensure no window-open e ready-to-show, release no closed, hint injetado no popup - ESC na popup de hinos/slides FECHA a janela (relato Caique: 'sinto falta do ESC fechar as telas') — estado do player permanece no operador - web-projection: provider próprio + hint reutilizado do módulo - 14 testes (reset de singleton p/ ESM cache entre testes); suite 49/49
…ha direto) Decisão Rafael 30/08: qualquer projeção antes de ser fechada deve exibir um confirm só do lado do operador — a decisão de encerrar é sempre dele. - ESC na janela de projeção → main envia 'projection:close-requested' à janela do operador (não fecha mais direto) - Operador: useOperatorEscapeToCloseProjection centraliza os dois gatilhos (ESC local + evento IPC) e exibe AppConfirm 'Encerrar projeção?' - projection:external-alive agora cobre popups (bíblia/hinos) + web-projection — confirm aparece para TODAS as projeções - instrumentação de debug /tmp/hotkey-debug.log na hotkey (temporária)
…rca em memória na criação
Sintoma real (usuário): 1º Ctrl+Alt+P escondia a projeção, mas ela não
voltava — o Alt+Tab fazia o papel. Causa: o provider identificava a popup
por webContents.getURL().includes('#/popup'), que deixa de valer depois
da navegação interna — collectAliveProjectionWindows() retornava vazio
no caminho de volta (toggle → none com projeção aberta).
- main.mjs: popup marcada em projectionPopups.add(childWindow) no
did-create-window (fonte de verdade, independe de URL em runtime)
- toggle show-projection: win.moveTop() — alguns WMs restauram sem
reaplicar o alwaysOnTop e a projeção voltava afundada
- 49/49 testes verdes
… inclusas) e limpa estado da UI Bug reportado pelo Rafael: ESC → confirm 'Encerrar projeção?' aparecia, mas ao confirmar a popup de bíblia/hinos CONTINUAVA projetando — o botão Projetar ficava travado ativo. projection:close-url só fechava o fluxo web-projection (vídeo/pdf/site), nunca as popups do window.open. - closeAllProjectionWindows() em web-projection.mjs: fecha os DOIS fluxos - registerCloseProjectionPopups: inversão de dependência (main registra o fechamento das popups; ipc chama sem import circular) - Renderer: closeLocalProjectionState() chama closeProjectionModule() após o confirm — isProjecting/botão/watch voltam ao estado desligado - 49/49 testes, build e type-check ok
…ADDRINUSE) Bug real do José (Windows, print 30/08): 'listen EACCES 0.0.0.0:7071' — o Windows (Hyper-V/WSL) reserva faixas de porta e o new WebSocketServer lançava exceção NÃO TRATADA no main → 'A JavaScript error occurred in the main process' e o app nem abria. Mesmo sintoma com EADDRINUSE quando há duas instâncias (print local). - attachRemoteServer: tenta PORT..PORT+4; EACCES/EADDRINUSE = próxima porta com warn; nenhuma livre = controle remoto desligado, app SEGUE - uncaughtException handler no main: exceção não tratada loga + diálogo amigável, nunca mais crash silencioso sem explicação
…ona de verdade O fix 400475e tentava capturar EACCES/EADDRINUSE com try/catch em volta do construtor, mas o listen() do 'ws' e assincrono: o construtor retorna antes do bind e o erro chega como evento 'error' re-throwado como uncaughtException. Resultado: app continuava caindo com a porta 7071 ocupada/reservada (bug do Jose, reproduzido localmente 30/08 a noite). - tryListen(port) retorna Promise: resolve em 'listening', rejeita em 'error' — o catch do loop agora pega o erro real - log de 'servidor WS na porta' e QR/pairing-info passam a anunciar a porta REAL em uso (wss.address().port), nao a constante 7071 Evidencia: com 7071 ocupada, app sobe e usa 7072 sem uncaughtException.
…1 da issue #142 - electron/classo-detect.mjs: funções puras testáveis (classoCandidatePaths, looksLikeClassoInstall, scanClassoMedia, findClassoDataFiles, detectClassoInstallation) + probeClassoRegistry (reg query Windows, injetável/mockável nos testes) - IPC classo:detect + preload window.api.classo.detect() - 14 testes novos (63 no total na suite electron) - Nunca escaneia disco inteiro: registry + paths padrão, confirma via configPT.ja; scan de mídia limitado a 2 níveis de profundidade
…142 - ClassoDetectCard.vue: botão detectar, exibe root/álbuns/MB/liturgia/XML - ClassoApi no desktop-bridge (opcional — web não quebra) - locales pt-BR/en/es - MediaView agora renderiza o card (antes era placeholder) - 5 testes novos (368 total)
No Linux, setFullScreen(true) é EWMH: o window manager decide o monitor e vários WMs (Cinnamon/GNOME/XFCE) jogam o fullscreen no primário, ignorando o monitor alvo passado via window.open (monitor=<id>). Usuário relatou que a projeção nunca abria no monitor 2 em nenhuma versão Linux (1.8.9, 1.22.1, 1.28) — só arrastando a janela. - Linux agora usa a estratégia do win32: borderless + setBounds(bounds do monitor alvo) + alwaysOnTop (fullscreen fake, imune ao WM) - Modo janela com monitor explícito passa a posicionar 800x600 centrado no workArea do monitor alvo (antes ignorava o monitor completamente) - Lógica de display extraída p/ electron/projection-display.mjs (pura, testável): resolveProjectionDisplay + buildProjectionWindowBounds - 8 testes novos (43/43 verdes); npm run build ok
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #142
O que esta PR entrega (FASE 1 — detecção)
classoCandidatePaths()(paths padrão Windows, win32.join determinístico)looksLikeClassoInstall()(confirma via configPT.ja)scanClassoMedia()(agrupa MP3 por pasta-álbum, máx. 2 níveis)findClassoDataFiles()(liturgia.ja, itensAgendados*.xml, configPT.ja)detectClassoInstallation()(registry → paths padrão)probeClassoRegistry()(reg query HKCU/HKLM, nunca lança)classo:detect+window.louvorja.classo.detect()no preloadClassoApi/ClassoDetectionResultno desktop-bridge (opcional — web não quebra).O que fica pra FASE 2 (mesma issue)
Evidências