diff --git a/Estructura.md b/Estructura.md new file mode 100644 index 0000000..bb482c5 --- /dev/null +++ b/Estructura.md @@ -0,0 +1,131 @@ +# Cómo está organizado el código + +> ⚠ Rama experimental, no oficial. El Oasis oficial es +> https://github.com/epsylon/oasis · [Volver a la portada](Home) + +Esta rama tiene que hacer dos cosas a la vez: añadir funciones y **seguir el ritmo de +epsylon**, que publica una versión cada pocos días. Lo segundo solo sale bien si el +código propio se distingue del suyo y no le estorba. + +Esta página explica dónde vive cada cosa y por qué ahí. + +--- + +## La regla + +**Upstream no usa ni un solo subdirectorio** en `src/views`, `src/backend`, +`src/models`, `src/client/assets/styles` ni `src/client/assets/translations`: 66 vistas +y 67 modelos, todos planos. La rama sigue esa misma forma. Nada de carpetas propias. + +Y los nombres, los suyos: `*_model.js` para modelos, `*_view.js` para vistas, +`*_views.js` cuando son varias. + +## Los diez ficheros propios + +| Fichero | Qué es | A qué se parece en upstream | +|---|---|---| +| `src/models/karvan_model.js` | Las salas efímeras y su ciclo de vida | `polls_model.js` | +| `src/views/karvan_view.js` | La lista de salas y la sala | `chats_view.js` | +| `src/backend/karvan_routes.js` | Las rutas del módulo | — (ver abajo) | +| `src/client/public/js/karvan.js` | El cliente WebRTC del navegador | `pdf-viewer.js` | +| `src/client/assets/styles/karvan.css` | Los estilos del módulo | `highlight.css` | +| `src/views/hive_views.js` | El panal, la topbar y la barra inferior | `main_views.js` | +| `src/views/identities_view.js` | El selector de identidades | cualquier `*_view.js` | +| `src/backend/accounts.js` | Encontrar y elegir identidades | `nameCache.js` | +| `src/backend/turnCredentials.js` | Credenciales efímeras para TURN | `wallet_addresses.js` | +| `src/client/assets/translations/i18n_fork.js` | Los textos de la rama | junto a `i18n.js` | + +## Y lo que se toca de lo suyo + +**+247 líneas repartidas en 21 ficheros** — una media de once líneas por fichero. Casi +todo son enganches de una línea: + +```js +// main_views.js: la interfaz de móvil se llama, no se escribe aquí +const forkNav = require('./hive_views')({ i18n }); +``` + +La excepción es `OasisMobile.css`, con unas mil líneas: es el tema de la rama, y un +tema es un fichero entero por definición. + +## Las tres decisiones que no son obvias + +### Por qué las rutas van aparte + +Upstream mete **625 rutas** en `backend.js`, en una sola cadena. Ese fichero se +reescribe en cada versión: `+833/-286` líneas en la 0.9.2, `+266/-31` en la 0.9.1. + +Una ruta añadida en medio de esa cadena entra en conflicto **cada vez**. Por eso las +del módulo viven en `karvan_routes.js`, montadas en un router propio que se inserta +antes del de upstream: lo que no casa cae a `next()` y sigue su curso. + +Es la única pieza que no imita una existente, y por un motivo medible. + +### Por qué la interfaz de móvil está en un fichero suelto + +`hive_views.js` no se limita a agrupar: **existe para que `main_views.js` no crezca**. +Ese fichero cambia mucho entre versiones, y tener el panal dentro obligaría a rehacerlo +en cada integración. + +Sus tres funciones empiezan igual: + +```js +if (process.env.OASIS_MOBILE !== '1') return ""; +``` + +Así el mismo `main_views.js` sirve para las dos ramas: en escritorio no dibujan nada. +Por eso [OASIS_LINUX](https://gitea.laenre.net/hacklab/OASIS_LINUX) puede llevarlo +idéntico sin heredar la interfaz de móvil. + +### Por qué las traducciones son un overlay + +Upstream tiene once ficheros `oasis_XX.js` y **los reescribe enteros** en cada versión. +Añadir claves dentro significaría perderlas cada vez. + +`i18n_fork.js` las lleva aparte y `i18n.js` las mezcla con un enganche de tres líneas: + +```js +try { + const overlay = require('./i18n_fork.js'); + languages.forEach(l => Object.assign(i18n[l] = i18n[l] || {}, overlay[l] || overlay.en || {})); +} catch (e) {} +``` + +Dentro va **solo lo de la rama**. Los nombres de las categorías, por ejemplo, no están: +son los de epsylon y se leen de los suyos. + +--- + +## Lo que se ha quitado por sobrar + +Revisando esto salieron cosas que no deberían haber estado: + +| Qué | Por qué sobraba | +|---|---| +| `views/fork/` y `translations/fork/` | Subdirectorios propios; upstream no tiene ninguno | +| Una segunda ruta `/legacy/export` | Copia exacta de la del dev, en otro fichero | +| `media-favorites.js` y su JSON | De una versión anterior; nadie lo requería | +| El campo `subtopic` en el foro | Resto de unos subtemas propios que se descartaron | + +Los subtemas de verdad son los de upstream, con sus rutas y sus vistas. + +--- + +## Cómo comprobarlo + +Contra un clon de upstream de la misma versión: + +```sh +# ficheros propios de la rama +for d in src/backend src/models src/views; do + diff <(ls ../oasis/$d) <(ls $d) | grep '^>' +done + +# subdirectorios que upstream no tiene (no debería salir ninguno) +find src/views src/backend src/models -maxdepth 1 -type d | tail -n +2 + +# líneas añadidas sobre cada fichero suyo +for f in $(git ls-files 'src/**/*.js'); do + [ -f ../oasis/$f ] && n=$(diff ../oasis/$f $f | grep -c '^>') && [ $n -gt 0 ] && echo "$n $f" +done | sort -rn +``` diff --git a/Home.md b/Home.md index e986315..98c436b 100644 --- a/Home.md +++ b/Home.md @@ -34,6 +34,8 @@ Pixel 9 (Android 16). No hay ningún montaje: es lo que se ve al usarla. | **[Módulos](Modulos)** | Encender y apagar partes de la aplicación | | **[Identidades](Identidades)** | Varias cuentas en el mismo móvil, y el aviso que evita perder una | | **[Compilar la APK](Compilar)** | Cómo se construye, de dónde sale cada pieza | +| **[Estructura del código](Estructura)** | Dónde vive cada fichero y por qué ahí | +| **[Si algo va mal](Problemas)** | Los fallos que han pasado de verdad, y su arreglo | | **[Estado y hoja de ruta](Roadmap)** | Qué funciona, qué no, y qué está bloqueado | | **[Qué NO tiene](Limitaciones)** | Lo que falta respecto al oficial, sin adornos | diff --git a/Interfaz.md b/Interfaz.md index e4c3b63..e3f29a2 100644 --- a/Interfaz.md +++ b/Interfaz.md @@ -165,7 +165,20 @@ tres piezas no se dibujan. --- -## 8. Los nombres son los de epsylon +## 8. En horizontal + +![La misma pantalla girada](img/27-horizontal.png) + +El panal se reparte a lo ancho y la barra de abajo se estira. Girar el móvil **no +recarga la página** ni pierde lo que estuvieras escribiendo: la aplicación se queda +donde estaba. + +Eso hubo que arreglarlo —antes girar dejaba un error de conexión en pantalla—, y está +contado en [Si algo va mal](Problemas). + +--- + +## 9. Los nombres son los de epsylon @@ -188,24 +201,17 @@ cae al inglés. ## Cómo está hecho -Todo lo de esta página vive en **un solo fichero nuevo**, `src/views/fork/hive_nav.js`, -que exporta las tres funciones de dibujo y la lista de módulos que se pueden anclar. +Todo lo de esta página vive en **un solo fichero**, `src/views/hive_views.js`, que +exporta las tres funciones de dibujo y la lista de módulos que se pueden anclar. `main_views.js` lo llama en tres sitios. -Se hizo así a propósito: cuando epsylon publica una versión nueva, `main_views.js` -cambia mucho, y tener la interfaz de la rama en un fichero aparte evita rehacerla en -cada actualización. - -Las tres funciones empiezan igual: +Las tres empiezan igual: ```js if (process.env.OASIS_MOBILE !== '1') return ""; ``` -Así el mismo código sirve para las dos ramas: en escritorio no dibujan nada. Por eso -[OASIS_LINUX](https://gitea.laenre.net/hacklab/OASIS_LINUX) puede llevar el mismo -`main_views.js` sin heredar la interfaz de móvil. +Así el mismo código sirve para las dos ramas: en escritorio no dibujan nada. -Los textos propios de la rama están en `src/client/assets/translations/fork/i18n_fork.js`, -que se mezcla con el `i18n.js` de upstream mediante un enganche de tres líneas. Igual -que antes: si epsylon reescribe sus traducciones, las de la rama no se pierden. +Está desarrollado, con el resto de decisiones, en +**[Estructura del código](Estructura)**. diff --git a/Problemas.md b/Problemas.md new file mode 100644 index 0000000..0d119e4 --- /dev/null +++ b/Problemas.md @@ -0,0 +1,133 @@ +# Si algo va mal + +> ⚠ Rama experimental, no oficial. El Oasis oficial es +> https://github.com/epsylon/oasis · [Volver a la portada](Home) + +Todo lo de esta página ha pasado de verdad durante el desarrollo. No es una lista de +casos imaginarios. + +--- + +## Al abrir, se queda en una pantalla con un contador + + + +**No está colgada, está arrancando.** El primer arranque descomprime el servidor —unos +230 MB— y levanta SSB. En el emulador tarda 15 segundos; en un móvil lento, más. + +La pantalla enseña los segundos que lleva para que se note que sigue viva. Cuando el +servidor responde, carga la interfaz sola. + +Si pasa de un par de minutos, mira el registro: + +```sh +adb logcat -s OASIS-NODE:V +``` + +Tiene que llegar a `[Oasis] Backend started on port 3000`. + +
+ +## Se ve un error de conexión y no se recupera + +No debería pasar ya. Si la página no carga, la aplicación **vuelve a esperar al +servidor y recarga sola** la última pantalla que sí cargó. + +Antes sí ocurría, y por dos motivos que están arreglados: + +- **Al girar el móvil.** Faltaba una entrada en la lista de cambios de configuración + del manifiesto (`smallestScreenSize`), así que Android recreaba la pantalla y el + navegador interno recargaba antes de tiempo. +- **Cuando Android mataba el servidor** por falta de memoria: se quedaba muerta. Ahora + vuelve sola en unos veinte segundos. + +## No se puede instalar: falta espacio + +``` +INSTALL_FAILED_INSUFFICIENT_STORAGE +``` + +La APK son unos 80 MB y el servidor se descomprime dentro de los datos de la +aplicación: cuenta con **unos 350 MB libres**. + +Ojo con una trampa: Android rechaza instalar cuando el disco baja de cierto umbral, +**aunque el hueco dé de sobra para la APK**. En un emulador se ve así, con 500 MB +libres y una APK de 80. Si te pasa en un emulador de pruebas: + +```sh +adb shell settings put global sys_storage_threshold_percentage 2 +``` + +En un móvil de verdad, libera espacio y ya está. + +## Instalé una APK nueva pero se comporta como la vieja + +Pasa si el paquete del servidor no se rehizo. La APK lleva el backend dentro como un +zip, y si se compila sin volver a empaquetarlo, la aplicación arranca **con el código +anterior**. + +Usa siempre el script, que lo rehace y lo comprueba: + +```sh +cd android +./scripts/release.sh +``` + +Verifica que la APK lleva el servidor, el motor de Node y los dos permisos de cámara y +micrófono. Ver [Compilar la APK](Compilar). + +## No deja instalar: dice que es una versión anterior + +``` +INSTALL_FAILED_VERSION_DOWNGRADE +``` + +El número de versión sale del número de commits. Si compilas a mano con `./gradlew` +sin las variables de entorno, sale **1**, que es menor que la instalada. Compila con +`./scripts/release.sh`, que lo calcula. + +## Al pulsar Llamar no pasa nada + +Comprueba, por este orden: + +1. **Que concediste los permisos.** Ajustes → Aplicaciones → Oasis → Permisos. Si + dijiste *Don't allow*, no se vuelve a preguntar. +2. **Que la APK los declara.** La oficial no lo hace, y entonces ni siquiera aparecen + como opción: + ```sh + aapt dump permissions oasis.apk | grep -E "CAMERA|RECORD_AUDIO" + ``` +3. **Que hay otro participante.** Una llamada con uno solo enciende tu cámara y poco + más. Ver [Llamadas](Llamadas). + +## Los iconos se ven como cuadros vacíos (□) + +En el móvil no debería pasar. En **escritorio** sí, y no es un fallo de Oasis: usa +caracteres Unicode poco comunes y al sistema le falta una fuente que los cubra. + +```sh +sudo apt install fonts-noto-core # Debian, Ubuntu y derivadas +``` + +## Subí una foto y llevaba mi ubicación + +Es un problema conocido y **sin resolver**: las imágenes suben con sus metadatos EXIF, +incluida la posición GPS. + +Mientras tanto: quita la ubicación de las fotos antes de subirlas, o desactiva el +guardado de ubicación en la cámara. Ver [Qué NO tiene](Limitaciones). + +## Se cierra al salir de la aplicación + +No debería: el servidor corre como servicio en primer plano justamente para seguir +replicando en segundo plano. Comprobado a los veinte minutos. + +Si se corta, mira si la notificación de Oasis sigue en la barra. Si la denegaste, el +sistema puede matar el servicio antes con la memoria justa. Se vuelve a conceder en +Ajustes → Aplicaciones → Oasis → Notificaciones. + +## Cambié de identidad y sigo viendo la anterior + +El cambio **se aplica al reiniciar**, no al momento. En el móvil hay un botón +**Reiniciar ahora** en la misma pantalla; sin él, cerrar la aplicación no basta porque +el servidor sigue vivo en segundo plano. Ver [Identidades](Identidades). diff --git a/_Sidebar.md b/_Sidebar.md index e2273c8..787e38c 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -13,6 +13,11 @@ - [Módulos](Modulos) - [Identidades](Identidades) - [Compilar la APK](Compilar) +- [Estructura del código](Estructura) + +--- + +- [Si algo va mal](Problemas) --- diff --git a/img/26-espera.png b/img/26-espera.png new file mode 100644 index 0000000..36cfbe4 Binary files /dev/null and b/img/26-espera.png differ diff --git a/img/27-horizontal.png b/img/27-horizontal.png new file mode 100644 index 0000000..5a1dc8c Binary files /dev/null and b/img/27-horizontal.png differ