Commit graph

11 commits

Author SHA1 Message Date
PontualTech / Karlão
0c0b2d2825 feat(ble): breadcrumb persistente sobrevive crash WebView v1.10.18
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Karlão reportou: APK fecha 'em seguida' ao mandar parear. v1.10.17
removeu wake-up do path Capacitor mas crash ainda persiste — agora
é em ble.requestDevice ou ble.connect/getServices.

Sem alert popup = crash nativo lado Java do plugin BLE. Try/catch JS
não captura. Solução: breadcrumb em localStorage ANTES de cada
chamada nativa.

bleCrumb(step) grava 'shivao_ble_last_step' no disco antes de:
- ensureBleNativeReady
- requestDevice
- selected:<name>
- ble.connect
- ble.getServices

Se app crashar, próxima abertura lê o breadcrumb e mostra alert
'⚠ Crash detectado · Última ação: ble.connect @ 2026...' — daí
descobrimos exatamente onde o plugin Java explode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 16:01:23 -03:00
PontualTech / Karlão
70b123735e fix(ble): remove wake-up do path Capacitor (crashava plugin) v1.10.17
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Karlão reportou que toda vez que tenta parear no APK, o app fecha
sem alert popup = crash nativo do plugin BLE Java.

Hipótese: as chamadas extras que adicionei (ble.read no notify char +
ble.write/writeWithoutResponse com 0x5A x4 wake bytes) crashavam o
plugin v6 em algum estado inválido.

Fix: remover wake-up sequence do path Capacitor. Mínimo viável:
1. ble.connect
2. ble.getServices
3. ble.startNotifications
4. delay 800ms
5. write JBD-0x03 com wnr forçado

A descoberta no PC (Web Bluetooth) confirmou que JBD-0x03 direto
(sem wake) já é suficiente — BMS responde com 41 bytes em 3 chunks.

startNotifications agora também envolto em try/catch que retorna
false se falhar (em vez de propagar exception nativa).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:44:16 -03:00
PontualTech / Karlão
ca66a6995f fix(boot): try/catch defensivo + migration btDevices + alert crash v1.10.16
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Karlão reportou: APK v1.10.15 crasha no boot mesmo após desinstalar
e reinstalar. Significa bug no código, não state corrompido.

Fix preventivo:
- Boot IIFE wrapped em try/catch master
- Cada init (loadState, tracking, anchor, battery, sw, sensors, rt,
  gcal) agora em try individual — falha de um não derruba o resto
- Migration defensiva de state.btDevices: filtra entries inválidas
  (null, sem id, etc)
- Se loadState crashar (state corrupto), reseta localStorage
- Crash master no try-catch chama alert() nativo + localStorage.clear()
  pra recovery automático na próxima abertura

Quando Karlão atualizar pra v1.10.16, vai aparecer mensagem específica
do erro (se ainda houver) — daí descubro causa exata em vez de
adivinhar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 10:39:02 -03:00
PontualTech / Karlão
56ddca53a4 fix(ble): dispatcher rotea chunks JBD de continuação v1.10.15
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
🎉 BMS RESPONDEU! Log v1.10.14 mostrou 3 chunks chegando do BMS
do Karlão:
- Chunk 1 (20b): dd 03 00 22 05 2b 02 8a... (header JBD + dados)
- Chunk 2 (20b): 00 00 d0 15 03 04 01 0b b7... (continuação)
- Chunk 3 (1b): 77 (end-of-frame)

Decoded: 13.23V (4S LiFePO4), +6.50A carregando, 21% SoC, 175 ciclos,
4 células, 27°C. PROTOCOLO JBD CORRETO.

Bug do parser: dispatcher só chamava bmsHandleChunk se primeiro byte
do chunk atual era 0xDD. Chunks 2 e 3 começam com 0x00 e 0x77 — não
roteados → reassembly nunca completou → dev.bms.voltage ficou null →
bmsTryProtocols viu '✗ JBD-0x03 sem RX'.

Fix em ambos os paths (Web Bluetooth + Capacitor):
- Se _bmsBuffers.has(deviceId), é continuação → roteia direto pra
  bmsHandleChunk
- Buffer vazio: primeiro byte determina protocolo

Próxima rodada deve mostrar 'BMS lido · 13.23V · 6.50A · 21%...' +
dashboard cheio.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:02:10 -03:00
PontualTech / Karlão
4cf670ae76 fix(ble): força write em ff02 mesmo sem property declarada v1.10.14
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
BMS chinês declara ff02 com property [read] apenas, MAS aceita writes
em background. Plugin Capacitor força através (Android stack permite).
Web Bluetooth do Chrome respeita spec — recusa writeValue se char
não tem write/wnr declarado.

Workaround: se nenhuma char tem write declarada, força usar primeira
não-notify (geralmente ff02). Tenta writeValue mesmo assim.
Browser pode lançar SecurityError, mas se BMS aceitar = funciona.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:56:52 -03:00
PontualTech / Karlão
0999da3b51 fix(ble): typo writeWithoutResponses→writeWithoutResponse v1.10.13
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Web Bluetooth log mostrou ff02 com property [read] sozinha, mas no
APK v1.10.7 o plugin reportava [wnr,read]. Discrepância revelou typo:
eu usei p.writeWithoutResponses (com S no final) mas o nome correto
da property em BluetoothCharacteristicProperties é singular —
p.writeWithoutResponse. Sempre undefined → ff02 não detectado como
writeChar → probe abortava com 'Sem chars notify+write'.

Fix: 4 ocorrências em bmsProbeWebBluetooth corrigidas. Plugin
Capacitor por sorte usa o nome diferente (writeWithoutResponse no
nested object) então não foi afetado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:42:19 -03:00
PontualTech / Karlão
a5bb6f5528 fix(sw): bump cache version pra forçar atualização v1.10.12
Karlão estava com v1.10.7 cacheado mesmo com servidor em v1.10.12.
Service Worker estava em v1.7.0 (não bumpado desde então).
Bump força activate event a deletar caches antigos.
2026-04-29 08:39:41 -03:00
PontualTech / Karlão
c7994167be feat(ui): redesign Marine Pro Dark — bottom nav + dark navy + Inter v1.7.0
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Reskin completo baseado em pesquisa de Navionics/Windy/PredictWind/Garmin
ActiveCaptain. Mata o feel "magazine editorial vintage" e adota padrões
mobile-app modernos.

Mudanças visuais (CSS overlay v3 sem alterar HTML/JS de business):
- Paleta dark navy (#0d2538) + cyan accent (#06b6d4) + reservado red pra alarme
- Inter (sans-serif) substitui Fraunces (italic editorial)
- Tabular nums em todas as métricas (lat/lon/depth/speed)
- Cards modernos: border-radius 14px + shadows sutis + bg dark
- Header 50% mais compacto (sem compass mark, avatar maior + accent cyan)
- FAB reposicionado acima da bottom nav, gradient cyan
- Modais: bottom sheet no mobile com top corners rounded
- Form fields dark com focus glow cyan
- Buttons com border-radius modernos, primary = cyan filled

Novos componentes:
- Bottom navigation: 5 tabs com line icons (Início/Travessias/Pendências/
  Zonas/Mais), backdrop-filter blur, badge vermelho em pendências overdue
- Safety status bar (sticky abaixo do header): GPS dot + Anchor watch +
  Bateria. Pulsa amarelo se warn, vermelho se danger
- switchPanel() unifica top tabs (legacy) + bottom nav

Service worker bumped pra invalidar cache antigo automaticamente.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 09:00:29 -03:00
PontualTech / Karlão
b48afaa84f feat(welcome): tela de boas-vindas com login Google/Email + URL hardcoded v1.6.0
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
UX simplificada drasticamente — usuário não precisa mais saber URL/token:
- Tela de boas-vindas full-screen quando não logado
- 3 botões grandes: Google, Email, Servidor próprio (avançado)
- URL hardcoded https://shivao.pontualtech.work como padrão
- Auto-conecta WebSocket + Google Calendar status após login
- Pull inicial automático pra puxar dados existentes da conta

Backend (server/src/index.js):
- Endpoint POST /api/auth/google: recebe credential (Google ID token),
  valida via tokeninfo do Google, confere aud == GOOGLE_CLIENT_ID,
  cria user automático com email do Google se não existe,
  retorna JWT access+refresh tokens
- Reusa GOOGLE_CLIENT_ID/SECRET já configurados no Coolify

Frontend (app/diario-bordo.html):
- Modal welcome com Google Sign-In via @google/gsi/client (script async)
- Tabs Login/Signup pro fluxo email
- Form avançado pra power users self-hosters
- Skip pra modo offline
- Once dismissed, fica oculto (localStorage flag)

Service Worker bumped pra v1.6.0 (invalida cache antigo).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:00:54 -03:00
PontualTech / Karlão
c76b50b45b fix(sw): bump cache version pra invalidar HTML antigo (v1.5.0)
Service Worker estava servindo HTML cacheado sem o código WebSocket/auto-sync.
Bump da VERSION força activate event a deletar caches antigos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:53:15 -03:00
PontualTech / Karlão
d1a2401048 feat(offline+sensors): Service Worker, bússola, barômetro, pré-cache de mapa
Implementa requisitos pra uso em áreas remotas:

OFFLINE REAL (Service Worker em server/public/sw.js)
- Pré-cache de shell (HTML, manifest, icon, Leaflet, fontes Google)
- Cache-first pra map tiles OSM (offline em alto-mar com tiles já visitados)
- Network-first pra Windy/Open-Meteo (com fallback ao cache)
- /api/* passa direto (não interferir em sync, heartbeat, auth)
- Skip-waiting + claim pra ativar imediatamente após install

SENSORES (sensor widget flutuante canto superior direito)
- Bússola via DeviceOrientationEvent (suporta iOS webkitCompassHeading + Android alpha)
- iOS: pede permission via gesture do usuário (botão 'Ativar bússola')
- Barômetro via Generic Sensor API (Android com sensor real, fallback gracioso)
- Tendência de pressão (subindo/caindo/estável) baseada em janela móvel
- Indicador de online/offline sempre visível

PRÉ-CACHE DE MAPA
- Botão 'Pré-cachear mapa' baixa tiles ~50km de raio (zooms 8-13, ~200 tiles)
- Comunicação page→SW via MessageChannel
- Limit 6 conexões paralelas (respeitando OSM tile policy)

DOCUMENTAÇÃO TERMÔMETRO: API web não tem termômetro de ambiente.
Solução: usar dado da Windy (já implementado) + cache offline via SW.

Sincronizado em app/ e server/public/ — single-file HTML preservado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:55:39 -03:00