docs: fuente del PDF de la guia para el dev

This commit is contained in:
hacklab 2026-10-19 15:06:58 +02:00
parent d3e799e592
commit 05027031ef
2 changed files with 347 additions and 0 deletions

7
docs/guia_pdf/README.md Normal file
View file

@ -0,0 +1,7 @@
# PDF de la guia para el dev
Fuente de Oasis_Mobile_Guia_de_desarrollo.pdf (5 paginas A4). Para sacarlo:
chromium --headless=new --no-pdf-header-footer --print-to-pdf=guia.pdf guia.html
Comprobar con `pdfinfo guia.pdf` que siguen siendo 5 paginas.

340
docs/guia_pdf/guia.html Normal file
View file

@ -0,0 +1,340 @@
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Oasis Mobile · Guía de desarrollo</title>
<style>
@font-face { font-family: "Anton"; src: url("file:///home/sito/COFRE/CODERS/OASIS_MOBILE/src/client/assets/fonts/Anton-Regular.ttf"); }
@page { size: A4; margin: 0; }
:root { --fg: #0b0b0b; --muted: #5a5a5a; --line: #0b0b0b; --cyan: #00d7f0; --soft: #f1f4f5; --red: #c4003b; --amber: #c98a00; --green: #0a8f3c; }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: #fff; color: var(--fg); font-family: "Inter", "DejaVu Sans", sans-serif; font-size: 10.5pt; line-height: 1.45; }
.page { width: 210mm; height: 297mm; padding: 16mm 17mm 14mm; position: relative; page-break-after: always; overflow: hidden; }
.page:last-child { page-break-after: auto; }
h1, h2, h3 { font-family: "Anton", Impact, sans-serif; font-weight: 400; text-transform: uppercase; margin: 0; letter-spacing: .01em; line-height: 1; }
h1 { font-size: 54pt; }
h2 { font-size: 30pt; margin-bottom: 4mm; }
h2 + .rule { width: 34mm; height: 2.2mm; background: var(--fg); margin: 0 0 6mm; }
h3 { font-size: 14pt; margin: 0 0 2.5mm; }
p { margin: 0 0 3mm; }
.lead { font-size: 12pt; color: var(--muted); margin-bottom: 6mm; }
ul { margin: 0 0 3mm; padding-left: 5mm; }
li { margin: 0 0 1.6mm; }
li::marker { color: var(--fg); }
code { font-family: "DejaVu Sans Mono", monospace; font-size: 8.8pt; background: var(--soft); padding: .2mm 1.2mm; border-radius: 1mm; }
.foot { position: absolute; left: 17mm; right: 17mm; bottom: 8mm; display: flex; justify-content: space-between; font-size: 8pt; color: var(--muted); border-top: .4mm solid #ddd; padding-top: 2mm; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 7mm; }
.cols3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 5mm; }
.card { border: .6mm solid var(--fg); border-radius: 3mm; padding: 4.5mm 5mm; }
.card.cyan { background: #e2fbff; }
.tag { display: inline-block; font-family: "Anton"; text-transform: uppercase; font-size: 11pt; padding: .6mm 3mm; border-radius: 1.5mm; color: #fff; margin-bottom: 3mm; }
.tag.red { background: var(--red); } .tag.amber { background: var(--amber); } .tag.green { background: var(--green); }
.num { font-family: "Anton"; font-size: 34pt; line-height: 1; }
.kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4mm; margin: 6mm 0; }
.kpi div { border-top: 1.2mm solid var(--fg); padding-top: 2mm; }
.kpi span { display: block; font-size: 8.5pt; color: var(--muted); }
figure { margin: 0 0 5mm; }
figcaption { font-size: 8.5pt; color: var(--muted); margin-top: 1.5mm; }
svg text { font-family: "Inter", sans-serif; }
.cover { background: #fff; }
.cover .band { position: absolute; left: 0; right: 0; top: 0; height: 9mm; background: var(--cyan); }
.cover h1 { margin-top: 30mm; font-size: 64pt; }
.cover .sub { font-family: "Anton"; text-transform: uppercase; font-size: 24pt; margin-top: 4mm; }
.cover .meta { margin-top: 8mm; font-size: 11pt; color: var(--muted); }
.ask { border-left: 2.2mm solid var(--cyan); background: var(--soft); padding: 4mm 5mm; border-radius: 0 3mm 3mm 0; }
table { width: 100%; border-collapse: collapse; font-size: 9.5pt; }
th { text-align: left; font-family: "Anton"; font-weight: 400; text-transform: uppercase; font-size: 10pt; border-bottom: .6mm solid var(--fg); padding: 1.5mm 2mm; }
td { border-bottom: .3mm solid #ddd; padding: 1.6mm 2mm; vertical-align: top; }
table.tight td { padding: 1.1mm 2mm; }
</style>
</head>
<body>
<!-- 1. PORTADA -->
<section class="page cover">
<div class="band"></div>
<h1>Oasis Mobile</h1>
<div class="sub">Guía de desarrollo de la rama del hacklab</div>
<div class="meta">Propuesta para epsylon · base Oasis 1.3.3 · rama PRUEBAS · 19 de octubre de 2026</div>
<div class="kpi">
<div><div class="num">39</div><span>versiones de Oasis entre la 1.0.1 y la 1.3.3</span></div>
<div><div class="num">17</div><span>ficheros tuyos que la rama cambia, frente a tu APK oficial</span></div>
<div><div class="num">2</div><span>líneas nuestras en <code>backend.js</code></span></div>
<div><div class="num">0</div><span>cambios en modelos, middleware o traducciones</span></div>
</div>
<h3>Qué es esta rama</h3>
<ul>
<li>Una forma de usar Oasis en el móvil pensada para una acampada: tribus como comisiones, votaciones de asamblea, salas de voz.</li>
<li>No es otro Oasis. Es tu APK oficial con una capa encima: skins, unas pocas vistas, un router propio y textos.</li>
<li>Se instala junto a la oficial con otro paquete (<code>net.laenre.oasis</code>) y habla con la misma red.</li>
</ul>
<h3>Qué te pedimos</h3>
<ul>
<li>Que revises si la frontera que proponemos (página 3) te parece bien: qué es tuyo y no tocamos, y qué es nuestro.</li>
<li>Que nos digas si alguno de los puntos de la página 5 te interesa para Oasis, para dejar de llevarlo nosotros.</li>
</ul>
<figure style="margin-top:6mm">
<svg viewBox="0 0 700 150" width="100%">
<defs><marker id="ar0" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#0b0b0b"/></marker></defs>
<rect x="2" y="20" width="200" height="110" rx="10" fill="#fff" stroke="#0b0b0b" stroke-width="2.5"/>
<text x="102" y="58" text-anchor="middle" font-size="17" font-weight="700">Tu APK oficial</text>
<text x="102" y="82" text-anchor="middle" font-size="12" fill="#5a5a5a">app Android, puente de</text>
<text x="102" y="98" text-anchor="middle" font-size="12" fill="#5a5a5a">audio, node_modules</text>
<rect x="250" y="20" width="200" height="110" rx="10" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2.5"/>
<text x="350" y="58" text-anchor="middle" font-size="17" font-weight="700">+ capa de la rama</text>
<text x="350" y="82" text-anchor="middle" font-size="12" fill="#5a5a5a">skins, vistas mobile_*,</text>
<text x="350" y="98" text-anchor="middle" font-size="12" fill="#5a5a5a">router propio, textos</text>
<rect x="498" y="20" width="200" height="110" rx="10" fill="#0b0b0b" stroke="#0b0b0b" stroke-width="2.5"/>
<text x="598" y="58" text-anchor="middle" font-size="17" font-weight="700" fill="#fff">Oasis hacklab</text>
<text x="598" y="82" text-anchor="middle" font-size="12" fill="#ddd">otro paquete, misma red,</text>
<text x="598" y="98" text-anchor="middle" font-size="12" fill="#ddd">convive con la oficial</text>
<line x1="204" y1="75" x2="244" y2="75" stroke="#0b0b0b" stroke-width="2.5" marker-end="url(#ar0)"/>
<line x1="452" y1="75" x2="492" y2="75" stroke="#0b0b0b" stroke-width="2.5" marker-end="url(#ar0)"/>
</svg>
</figure>
<div class="foot"><span>Oasis Mobile · Guía de desarrollo</span><span>1 / 5</span></div>
</section>
<!-- 2. LA REGLA -->
<section class="page">
<h2>La regla</h2><div class="rule"></div>
<p class="lead">Oasis lo cambias tú. Nosotros cambiamos cómo se ve y se usa en el móvil, y lo hacemos en ficheros nuestros.</p>
<figure>
<svg viewBox="0 0 700 330" width="100%">
<defs><marker id="ar1" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#0b0b0b"/></marker></defs>
<text x="0" y="16" font-size="13" font-weight="700" letter-spacing="1">LA CAPA DE LA RAMA</text>
<g font-size="12">
<rect x="0" y="28" width="166" height="96" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/>
<text x="83" y="54" text-anchor="middle" font-size="15" font-weight="700">Aspecto</text>
<text x="83" y="76" text-anchor="middle">mobile_base.css</text><text x="83" y="92" text-anchor="middle">mobile_ux.css</text><text x="83" y="108" text-anchor="middle">Acampada.css</text>
<rect x="178" y="28" width="166" height="96" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/>
<text x="261" y="54" text-anchor="middle" font-size="15" font-weight="700">Pantallas</text>
<text x="261" y="76" text-anchor="middle">mobile_ui.js</text><text x="261" y="92" text-anchor="middle">mobile_*_view.js</text><text x="261" y="108" text-anchor="middle">hive_views.js</text>
<rect x="356" y="28" width="166" height="96" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/>
<text x="439" y="54" text-anchor="middle" font-size="15" font-weight="700">Rutas</text>
<text x="439" y="76" text-anchor="middle">fork_routes.js</text><text x="439" y="92" text-anchor="middle">mobile_layer.js</text><text x="439" y="108" text-anchor="middle">fork_workflows.js</text>
<rect x="534" y="28" width="166" height="96" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/>
<text x="617" y="54" text-anchor="middle" font-size="15" font-weight="700">Textos y APK</text>
<text x="617" y="76" text-anchor="middle">i18n_fork.js</text><text x="617" y="92" text-anchor="middle">(11 idiomas)</text><text x="617" y="108" text-anchor="middle">sobre_oficial.sh</text>
</g>
<g stroke="#0b0b0b" stroke-width="2" marker-end="url(#ar1)">
<line x1="83" y1="130" x2="83" y2="176"/><line x1="261" y1="130" x2="261" y2="176"/><line x1="439" y1="130" x2="439" y2="176"/><line x1="617" y1="130" x2="617" y2="176"/>
</g>
<text x="270" y="158" font-size="11" fill="#5a5a5a">una línea de enganche, solo con OASIS_MOBILE=1</text>
<rect x="0" y="184" width="700" height="140" rx="10" fill="#fff" stroke="#0b0b0b" stroke-width="3"/>
<text x="350" y="216" text-anchor="middle" font-size="18" font-weight="700">OASIS: TU CÓDIGO, TAL CUAL</text>
<g font-size="12" text-anchor="middle">
<rect x="18" y="234" width="152" height="70" rx="7" fill="#f1f4f5"/><text x="94" y="262" font-weight="700">backend.js</text><text x="94" y="280" fill="#5a5a5a">y su middleware</text>
<rect x="188" y="234" width="152" height="70" rx="7" fill="#f1f4f5"/><text x="264" y="262" font-weight="700">modelos</text><text x="264" y="280" fill="#5a5a5a">qué se publica y se cuenta</text>
<rect x="358" y="234" width="152" height="70" rx="7" fill="#f1f4f5"/><text x="434" y="262" font-weight="700">SSB y servidor</text><text x="434" y="280" fill="#5a5a5a">phone_module, puente</text>
<rect x="528" y="234" width="154" height="70" rx="7" fill="#f1f4f5"/><text x="605" y="262" font-weight="700">traducciones y temas</text><text x="605" y="280" fill="#5a5a5a">oasis_*.js, style.css…</text>
</g>
</svg>
<figcaption>La rama son cuatro piezas propias encima de tu código. Lo único que entra en tus ficheros son líneas de enganche.</figcaption>
</figure>
<div class="cols">
<div>
<h3>Por qué así</h3>
<ul>
<li>Sacas versión casi cada día y cada una llega en un solo commit: no se pueden coger cambios sueltos.</li>
<li><code>backend.js</code> cambió en 34 de 39 versiones, <code>main_views.js</code> en 31, las traducciones en 31.</li>
<li>Cada línea nuestra en esos ficheros sería un conflicto en la siguiente integración.</li>
<li>Si tocáramos un modelo, nuestro móvil contaría distinto que tu escritorio (votos, tribus, gobierno).</li>
</ul>
</div>
<div>
<h3>Cómo se mide</h3>
<ul>
<li>La referencia para el móvil es el <code>nodejs-project</code> de tu APK oficial, no tu git: ahí van tus cambios de móvil.</li>
<li>Hoy la rama cambia 17 ficheros tuyos y 561 líneas; en <code>backend.js</code>, 2.</li>
<li>En cada versión tuya se repite la comparación y se revisa si ha desaparecido alguna clase CSS de la que tiramos.</li>
</ul>
</div>
</div>
<div class="foot"><span>Oasis Mobile · Guía de desarrollo</span><span>2 / 5</span></div>
</section>
<!-- 3. LA FRONTERA -->
<section class="page">
<h2>Qué se toca y qué no</h2><div class="rule"></div>
<p class="lead">Tres zonas. La de en medio es la única que entra en tus ficheros, y solo con una línea.</p>
<div class="cols3">
<div class="card">
<span class="tag red">No se toca</span>
<ul>
<li><code>backend.js</code>, rutas y cadena de middleware</li>
<li>Modelos de <code>src/models</code>: lo que se publica en el log y cómo se cuenta</li>
<li><code>src/server</code>: arranque de SSB, dependencias, <code>phone_module</code></li>
<li><code>request_guards.js</code> y la CSP: nada en línea</li>
<li>Traducciones <code>oasis_*.js</code></li>
<li><code>style.css</code>, <code>mobile.css</code> y los temas, también <code>OasisMobile.css</code></li>
</ul>
</div>
<div class="card">
<span class="tag amber">Una línea</span>
<ul>
<li>Tus vistas: <code>main_views.js</code>, <code>tribes_view.js</code>, <code>vote_view.js</code>, <code>settings_view.js</code>, <code>welcome_view.js</code></li>
<li>La lógica va en <code>mobile_ui.js</code>; en tu vista, una llamada</li>
<li>Siempre detrás de <code>OASIS_MOBILE === '1'</code>: en escritorio todo queda como lo dejas</li>
<li>Si reescribes la vista, se vuelve a poner la línea</li>
</ul>
</div>
<div class="card cyan">
<span class="tag green">Nuestro</span>
<ul>
<li>Hojas: <code>mobile_base.css</code>, <code>mobile_ux.css</code>, <code>Acampada.css</code></li>
<li>Vistas: <code>mobile_ui.js</code>, <code>mobile_modules_view.js</code>, <code>hive_views.js</code>, <code>mobile_icons.js</code></li>
<li>Router: <code>fork_routes.js</code> y <code>mobile_layer.js</code></li>
<li>Workflows: <code>fork_workflows.js</code></li>
<li>Textos: <code>i18n_fork.js</code></li>
<li>APK: <code>sobre_oficial.sh</code></li>
</ul>
</div>
</div>
<h3 style="margin-top:4mm">Ejemplos concretos</h3>
<table class="tight">
<tr><th>Lo que hacía falta</th><th>Cómo se ha hecho</th><th>Zona</th></tr>
<tr><td>Votar en semáforo o termómetro, como en asamblea</td><td>Tu servidor ya acepta <code>options</code>; solo se añade el selector en el formulario</td><td>Una línea</td></tr>
<tr><td>Quien crea una votación no puede votar</td><td>Es una regla de tu modelo: no se cambia, se explica en pantalla</td><td>Nuestro</td></tr>
<tr><td>Avisar de que una sección está apagada y encenderla</td><td>Nuestro router mira tu redirección a <code>/modules</code>, sin tocar <code>checkMod</code></td><td>Nuestro</td></tr>
<tr><td>Workflow para acampadas</td><td>Se registra <code>acampada</code> en tus arrays; <code>activists</code> queda como el tuyo</td><td>Nuestro</td></tr>
<tr><td>Llamadas y salas</td><td>Las tuyas, con tu puente de audio: la APK se monta sobre la oficial</td><td>No se toca</td></tr>
<tr><td>Borrar con confirmación</td><td>Función en <code>mobile_ui.js</code>, enganchada en <code>renderContentActions</code></td><td>Una línea</td></tr>
</table>
<div class="foot"><span>Oasis Mobile · Guía de desarrollo</span><span>3 / 5</span></div>
</section>
<!-- 4. CÓMO FUNCIONA -->
<section class="page">
<h2>Cómo funciona por dentro</h2><div class="rule"></div>
<h3>Una petición en el móvil</h3>
<figure>
<svg viewBox="0 0 700 175" width="100%">
<defs><marker id="ar2" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#0b0b0b"/></marker></defs>
<g font-size="12" text-anchor="middle">
<rect x="0" y="40" width="110" height="80" rx="9" fill="#fff" stroke="#0b0b0b" stroke-width="2"/><text x="55" y="76" font-weight="700">WebView</text><text x="55" y="94" fill="#5a5a5a">de tu app</text>
<rect x="140" y="40" width="130" height="80" rx="9" fill="#f1f4f5" stroke="#0b0b0b" stroke-width="2"/><text x="205" y="70" font-weight="700">Tu middleware</text><text x="205" y="88" fill="#5a5a5a">contexto, idioma,</text><text x="205" y="102" fill="#5a5a5a">CSP</text>
<rect x="300" y="40" width="130" height="80" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/><text x="365" y="70" font-weight="700">fork_routes</text><text x="365" y="88" fill="#5a5a5a">rutas propias o</text><text x="365" y="102" fill="#5a5a5a">next() al tuyo</text>
<rect x="460" y="40" width="110" height="80" rx="9" fill="#f1f4f5" stroke="#0b0b0b" stroke-width="2"/><text x="515" y="76" font-weight="700">Tus rutas</text><text x="515" y="94" fill="#5a5a5a">y vistas</text>
<rect x="600" y="40" width="100" height="80" rx="9" fill="#e2fbff" stroke="#0b0b0b" stroke-width="2"/><text x="650" y="70" font-weight="700">mobile_ui</text><text x="650" y="88" fill="#5a5a5a">si la vista</text><text x="650" y="102" fill="#5a5a5a">lo llama</text>
</g>
<g stroke="#0b0b0b" stroke-width="2" marker-end="url(#ar2)">
<line x1="112" y1="80" x2="134" y2="80"/><line x1="272" y1="80" x2="294" y2="80"/><line x1="432" y1="80" x2="454" y2="80"/><line x1="572" y1="80" x2="594" y2="80"/>
</g>
<path d="M365 124 C365 160, 515 160, 515 124" fill="none" stroke="#0b0b0b" stroke-width="1.6" stroke-dasharray="5 4"/>
<text x="440" y="168" text-anchor="middle" font-size="11" fill="#5a5a5a">wrapUpstream mira tu respuesta (redirecciones) sin cambiarla</text>
<text x="0" y="22" font-size="11" fill="#5a5a5a">Nuestro router va justo delante del tuyo: una sola línea en backend.js lo monta.</text>
</svg>
</figure>
<div class="cols">
<div>
<h3>Hojas de estilo, en este orden</h3>
<figure>
<svg viewBox="0 0 330 200" width="100%">
<g font-size="12">
<rect x="0" y="0" width="330" height="34" rx="6" fill="#f1f4f5" stroke="#0b0b0b"/><text x="12" y="22">1 · style.css y mobile.css (tuyas)</text>
<rect x="0" y="40" width="330" height="34" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="62">2 · mobile_base.css: maqueta de la rama</text>
<rect x="0" y="80" width="330" height="34" rx="6" fill="#fff" stroke="#0b0b0b"/><text x="12" y="102">3 · skin: Acampada.css o tu OasisMobile.css</text>
<rect x="0" y="120" width="330" height="34" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="142">4 · hive_acampada.css (solo con Acampada)</text>
<rect x="0" y="160" width="330" height="34" rx="6" fill="#0b0b0b"/><text x="12" y="182" fill="#fff">5 · mobile_ux.css: piezas comunes, la última</text>
</g>
</svg>
</figure>
<ul>
<li>Con tu skin OasisMobile se ve tu tema tal cual, encima de nuestra maqueta.</li>
<li>Colores por variables <code>--ux-*</code>: valen para los dos skins.</li>
</ul>
</div>
<div>
<h3>La APK, montada sobre la tuya</h3>
<figure>
<svg viewBox="0 0 330 200" width="100%">
<defs><marker id="ar3" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#0b0b0b"/></marker></defs>
<g font-size="12">
<rect x="0" y="0" width="330" height="30" rx="6" fill="#fff" stroke="#0b0b0b"/><text x="12" y="20">tu APK oficial de la misma versión</text>
<rect x="0" y="42" width="330" height="30" rx="6" fill="#f1f4f5" stroke="#0b0b0b"/><text x="12" y="62">se desmonta (apktool, versión fija)</text>
<rect x="0" y="84" width="330" height="30" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="104">backend de la rama + tu node_modules</text>
<rect x="0" y="126" width="330" height="30" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="146">paquete net.laenre.oasis</text>
<rect x="0" y="168" width="330" height="30" rx="6" fill="#0b0b0b"/><text x="12" y="188" fill="#fff">se monta, se alinea y se firma</text>
</g>
<g stroke="#0b0b0b" stroke-width="1.6" marker-end="url(#ar3)"><line x1="300" y1="31" x2="300" y2="40"/><line x1="300" y1="73" x2="300" y2="82"/><line x1="300" y1="115" x2="300" y2="124"/><line x1="300" y1="157" x2="300" y2="166"/></g>
</svg>
</figure>
<ul>
<li>Tu app tal cual: puente de audio, notificaciones, permisos.</li>
<li>Se cambian también los authorities, el permiso propio y las acciones de llamada, para no cruzarse con la tuya.</li>
</ul>
</div>
</div>
<div class="foot"><span>Oasis Mobile · Guía de desarrollo</span><span>4 / 5</span></div>
</section>
<!-- 5. TRABAJAR JUNTOS -->
<section class="page">
<h2>Cómo seguimos</h2><div class="rule"></div>
<div class="cols">
<div>
<h3>Antes de cada commit</h3>
<ul>
<li>Nada de la zona roja en el diff; en tus vistas, solo líneas de enganche.</li>
<li><code>node --check</code> y el servidor local responde en las pantallas principales.</li>
<li>Visto a 360 y 412 px, en tableta, con la letra al 130 % y en un WebView viejo.</li>
<li>Textos nuevos en los 11 idiomas, en <code>i18n_fork.js</code>.</li>
<li>Nada en línea: la CSP lo bloquea.</li>
</ul>
<h3>Cuando sacas versión</h3>
<ul>
<li>Se coge la tuya tal cual; para el móvil, la de tu APK.</li>
<li>Se vuelven a poner los enganches en tus vistas.</li>
<li>Se repite la medición y se revisan las clases CSS.</li>
<li>Se monta la APK sobre tu oficial de esa versión.</li>
</ul>
</div>
<div>
<h3>Navegación en el móvil</h3>
<ul>
<li>Al abrir se ve la actividad, no un menú.</li>
<li>Abajo, cuatro atajos que elige cada cual y una pestaña Menú que abre todos los módulos desde abajo.</li>
<li>Probado en el emulador: dos toques a cualquier módulo desde cualquier pantalla.</li>
</ul>
<h3>Probado</h3>
<ul>
<li>Android 16 (APK real): 412 y 360 dp, tableta de 800 dp, letra al 130 %, gestos y tres botones.</li>
<li>Motores viejos: WebView 69 (Android 9) y 83 (Android 11), con alternativas donde falta <code>:has</code>, <code>gap</code> o <code>inset</code>.</li>
<li>Llamadas: en una sala el micrófono graba y se corta al salir.</li>
</ul>
</div>
</div>
<h3 style="margin-top:2mm">Lo que podría pasar a Oasis</h3>
<p>Cosas que hoy llevamos en tus ficheros y que nos gustaría que fueran tuyas, para dejar de mantenerlas aparte:</p>
<table>
<tr><th>Qué</th><th>Dónde está ahora</th><th>Por qué te puede interesar</th></tr>
<tr><td>Limpiar metadatos de las fotos también en Android</td><td><code>blobHandler.js</code> (190 líneas)</td><td>Sin <code>sharp</code> en el móvil, hoy las fotos suben con el GPS dentro</td></tr>
<tr><td>Varias identidades en el mismo móvil</td><td><code>ssb_config.js</code> (30 líneas)</td><td>Una persona, varias cuentas, con aviso si dos comparten clave</td></tr>
<tr><td>DNS del sistema primero</td><td><code>main.js</code> (45 líneas)</td><td>Respeta la VPN y el DNS privado de Android</td></tr>
<tr><td>Selector de idioma con el idioma actual</td><td>nuestro, en <code>mobile_ui.js</code></td><td><code>settings_view</code> lee <code>selectedLanguage</code> al cargar y siempre marca English</td></tr>
</table>
<div class="ask" style="margin-top:3mm">
<h3>Para aprobar</h3>
<ul style="margin:0">
<li>¿Te parece bien la frontera de la página 3?</li>
<li>¿Te parece bien que la APK de la rama se monte sobre tu oficial, con otro paquete?</li>
<li>¿Quieres alguno de los cuatro puntos de arriba en Oasis?</li>
</ul>
</div>
<div class="foot"><span>Oasis Mobile · Guía de desarrollo · hacklab · gitea.laenre.net/hacklab/OASIS_MOBILE</span><span>5 / 5</span></div>
</section>
</body>
</html>