readme: capturas y dibujos nuevos, sin Karvan
- capturas de un nodo de prueba con contenido de acampada: lanzador, tribus, votacion de semaforo, modulos, ajustes, barra, salas y el tema del dev - portada y esquema de la interfaz al dia; dos esquemas nuevos: como va la rama encima de Oasis y como funcionan las llamadas - el README cuenta las novedades de esta version y explica la rama Arreglos que salieron al hacer las capturas: - el boton de No molestar del Telefono ocupaba una fila entera arriba de cada pagina; ahora va en la barra de arriba, junto al avatar - Ajustes marcaba English aunque el idioma fuera otro (settings_view se queda con el idioma del arranque): el selector lo lee al pintar - barras de la votacion juntas y con las etiquetas en el mismo tipo - Personalizar la barra: una fila por atajo, sin sangria
152
README.md
|
|
@ -18,33 +18,38 @@ está qué se puede tocar y qué no. En corto: el backend, el middleware, los mo
|
|||
las traducciones son de epsylon y no se tocan; lo nuestro va en hojas, vistas y rutas
|
||||
propias.
|
||||
|
||||
Versión base: **Oasis 1.3.3** · Rama: `PRUEBAS` ·
|
||||
Versión base: Oasis 1.3.3 · Rama: `PRUEBAS` ·
|
||||
[Documentación completa](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki) ·
|
||||
[Versión de escritorio](https://gitea.laenre.net/hacklab/OASIS_LINUX)
|
||||
|
||||

|
||||
|
||||
**[⬇ Descargar la APK](https://gitea.laenre.net/hacklab/OASIS_MOBILE/releases)** ·
|
||||
[⬇ Descargar la APK](https://gitea.laenre.net/hacklab/OASIS_MOBILE/releases) ·
|
||||
Android 7 o superior, 64 bits · se instala junto al Oasis oficial sin pisarlo
|
||||
|
||||
### Novedades de esta versión
|
||||
|
||||
- **Al día con Oasis 1.3.3**: karma en el perfil, salas con directo, fotos selladas en
|
||||
- Al día con Oasis 1.3.3: karma en el perfil, salas con directo, fotos selladas en
|
||||
chats privados y tribus, visibilidad de menciones y las traducciones nuevas.
|
||||
- **Tema Acampada por defecto**: blanco, negro y cian, títulos en Anton y botones que
|
||||
se hunden al pulsar, con los colores de acampada26s.net. Los otros temas siguen en
|
||||
*Ajustes → Tema*.
|
||||
- **Arranca en modo acampada**: chats, teléfono, salas, pads, foro, wiki, tribus,
|
||||
parlamento, votaciones y eventos. El resto se activa en *Ajustes → Workflows*.
|
||||
- **Llamadas y salas del dev**: fuera Karvan, nuestras salas propias. Ahora se usan el
|
||||
Teléfono y las Salas de Oasis, con el audio y la cámara de Android enchufados por la
|
||||
rama.
|
||||
- **Filtros en fichas**: en chats, feed, foros o pads los filtros ya no son botones
|
||||
gigantes que tapan el contenido, sino fichas pequeñas en fila.
|
||||
- **Tarjetas más limpias**: borrar, fijar, enlazar y abrir van en una fila de iconos.
|
||||
- **Fotos más seguras**: si una foto no se puede limpiar de metadatos (ubicación,
|
||||
cámara…), no se sube y se avisa. Antes se subía tal cual.
|
||||
- **DNS**: primero el resolutor del sistema, que respeta la VPN y el DNS privado de
|
||||
- Arranca en modo acampada: chats, teléfono, salas, pads, foro, wiki, tribus,
|
||||
parlamento, votaciones y eventos. El resto se enciende en *Módulos* o en
|
||||
*Ajustes → Workflows*.
|
||||
- Las llamadas son las de Oasis. Fuera Karvan, el módulo propio de salas: ahora se usan
|
||||
el Teléfono y las Salas del dev, con el micrófono y la cámara del móvil enchufados.
|
||||
- Votaciones como en asamblea: al crear una se elige Sí/No, semáforo (verde, amarillo,
|
||||
rojo) o termómetro (del 1 al 5). Los resultados salen en barras.
|
||||
- Borrar pide confirmación. Antes la X de una tribu la borraba de un toque.
|
||||
- Iconos que se entienden en el lanzador y en la barra, en vez de letras del alfabeto
|
||||
vai. La barra marca dónde estás y se esconde al escribir.
|
||||
- Tribus en filas: doce comisiones caben en tres pantallas, no en diez. Dentro de una
|
||||
tribu, las secciones van en una tira de fichas.
|
||||
- Módulos con interruptores, agrupados como en el lanzador. Si entras en una sección
|
||||
apagada, te lo dice y la enciendes de un toque.
|
||||
- Pantallas más aprovechadas: un margen de 14 px en vez de los 74 que se sumaban, una
|
||||
sola letra para botones, buscador en una línea y el buzón en pocas líneas por mensaje.
|
||||
- Fotos más seguras: si una foto no se puede limpiar de metadatos (ubicación,
|
||||
cámara…), no se sube y se avisa.
|
||||
- DNS: primero el resolutor del sistema, que respeta la VPN y el DNS privado de
|
||||
Android; los públicos quedan de respaldo.
|
||||
|
||||
---
|
||||
|
|
@ -53,54 +58,57 @@ Android 7 o superior, 64 bits · se instala junto al Oasis oficial sin pisarlo
|
|||
|
||||
| | Oasis oficial | Esta rama |
|
||||
|---|---|---|
|
||||
| **Llamadas y salas** | Teléfono y Salas, sin micrófono ni cámara en Android | Los mismos, con el audio y la cámara del móvil |
|
||||
| **Interfaz de móvil** | El menú de escritorio en una pantalla pequeña | Tema Acampada, lanzador de módulos, filtros en fichas y barra de cuatro atajos |
|
||||
| **Primer arranque** | Casi sesenta módulos encendidos | Modo acampada: lo justo para organizarse |
|
||||
| **Varias identidades** | Una por instalación | Varias en el mismo móvil, con aviso si dos comparten clave |
|
||||
| **Respuesta citada** | — | Responder a un mensaje concreto dentro de un chat |
|
||||
| **Envoltorio Android** | APK sin permisos de cámara ni micrófono | Proyecto Gradle propio: permisos, subida de ficheros, servicio que sobrevive |
|
||||
| **Metadatos de las fotos** | Se quitan solo si está `sharp`; en Android **nunca** | Se quitan siempre: GPS, marca, modelo, número de serie |
|
||||
| Llamadas y salas | Teléfono y Salas, pero sin micrófono ni cámara en Android | Los mismos, con el micrófono y la cámara del móvil |
|
||||
| Interfaz de móvil | El menú de escritorio en una pantalla pequeña | Tema Acampada, lanzador con iconos, fichas, barra de cuatro atajos |
|
||||
| Primer arranque | Casi sesenta módulos encendidos | Modo acampada: lo justo para organizarse |
|
||||
| Votaciones | Seis opciones fijas en una tabla | Sí/No, semáforo o termómetro, con barras |
|
||||
| Varias identidades | Una por instalación | Varias en el mismo móvil, con aviso si dos comparten clave |
|
||||
| Envoltorio Android | APK sin permisos de cámara ni micrófono | Proyecto Gradle propio: permisos, subida de ficheros, servicio que sobrevive |
|
||||
| Metadatos de las fotos | Se quitan solo si está `sharp`; en Android nunca | Se quitan siempre: GPS, marca, modelo, número de serie |
|
||||
|
||||
Los nombres de las categorías, los módulos y el resto de la aplicación son los de
|
||||
epsylon, sin tocar.
|
||||
epsylon, sin tocar. Con el tema OasisMobile se ve el del propio dev.
|
||||
|
||||
---
|
||||
|
||||
## Qué es Oasis, en cuatro dibujos
|
||||
|
||||
Una red social **sin servidor**: publicas en tu propio equipo y los demás se traen una
|
||||
Una red social sin servidor: publicas en tu propio equipo y los demás se traen una
|
||||
copia. No hay cuenta, no hay contraseña y nadie puede borrarte.
|
||||
|
||||

|
||||
|
||||
Los mensajes viajan **de vecino en vecino**, así que llegan a gente con la que nunca te
|
||||
Los mensajes viajan de vecino en vecino, así que llegan a gente con la que nunca te
|
||||
has conectado. Por eso funciona incluso sin internet, entre dos móviles en la misma wifi.
|
||||
|
||||

|
||||
|
||||
Un **pub** es solo un nodo que no se apaga nunca. No es un servidor con tus datos: no
|
||||
Un pub es solo un nodo que no se apaga nunca. No es un servidor con tus datos: no
|
||||
guarda tu identidad, no decide qué ves y no puede borrarte.
|
||||
|
||||

|
||||
|
||||
Todo lo que publicas se encadena y va **firmado con tu clave**. Nadie puede colar un
|
||||
Todo lo que publicas se encadena y va firmado con tu clave. Nadie puede colar un
|
||||
mensaje en tu nombre ni cambiar lo que dijiste.
|
||||
|
||||

|
||||
|
||||
> La explicación completa —los saltos, las tribus, el LARP, los módulos— está en
|
||||
> **[Entender Oasis en diez minutos](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Entender)**.
|
||||
> [Entender Oasis en diez minutos](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Entender).
|
||||
|
||||
---
|
||||
|
||||
## Llamadas y salas
|
||||
|
||||

|
||||
|
||||
El Teléfono (llamadas de uno a uno, con buzón de voz) y las Salas (hasta cincuenta
|
||||
personas, con vídeo, grabación y emisión) son de Oasis. La APK oficial no pide
|
||||
permisos de micrófono ni de cámara, así que en Android no se pueden usar. Esta rama
|
||||
trae su propio envoltorio, que sí los pide, y enchufa el audio, la cámara y la emisión
|
||||
del móvil en los puntos que el propio Oasis deja para eso (`setAudioFactory` y
|
||||
compañía). La rama no tiene llamadas propias.
|
||||
permisos de micrófono ni de cámara, así que en Android no suenan. Esta rama trae su
|
||||
propio envoltorio, que sí los pide, y enchufa el audio y la cámara del móvil en los
|
||||
puntos que el propio Oasis deja para eso. La rama no tiene llamadas propias.
|
||||
|
||||
En la barra de arriba, junto al avatar, está el botón de *No molestar* del Teléfono.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -109,20 +117,42 @@ compañía). La rama no tiene llamadas propias.
|
|||

|
||||
|
||||
<p align="center">
|
||||
<img src="docs/capturas/01-portada.png" width="240">
|
||||
<img src="docs/capturas/04-foros.png" width="240">
|
||||
<img src="docs/capturas/06-barra.png" width="240">
|
||||
<img src="docs/capturas/01-portada.png" width="200">
|
||||
<img src="docs/capturas/02-tribus.png" width="200">
|
||||
<img src="docs/capturas/03-votacion.png" width="200">
|
||||
<img src="docs/capturas/04-modulos.png" width="200">
|
||||
</p>
|
||||
<p align="center">
|
||||
<img src="docs/capturas/05-ajustes.png" width="200">
|
||||
<img src="docs/capturas/06-barra.png" width="200">
|
||||
<img src="docs/capturas/08-salas.png" width="200">
|
||||
<img src="docs/capturas/07-oasismobile.png" width="200">
|
||||
</p>
|
||||
|
||||
Casi sesenta módulos no caben en la pantalla de un teléfono: la portada los ordena por
|
||||
secciones en una rejilla de iconos, como el cajón de apps del móvil. Abajo
|
||||
queda una barra de cuatro atajos que eliges tú. Dentro de cada módulo los filtros van en fichas pequeñas,
|
||||
para que el contenido se vea sin tener que bajar.
|
||||
Lanzador, tribus, una votación de semáforo, módulos, ajustes, la barra de atajos, las
|
||||
salas del dev y el mismo lanzador con el tema OasisMobile del dev.
|
||||
|
||||
Solo aparecen los módulos activos. En **Ajustes → Workflows** se eligen de golpe: el de
|
||||
**acampada** deja lo justo para organizarse (chats, teléfono, salas, pads, foro, wiki,
|
||||
tribus, parlamento, votaciones y eventos). En el móvil un workflow cambia los módulos,
|
||||
no el aspecto.
|
||||
Casi sesenta módulos no caben en la pantalla de un teléfono: la portada los ordena por
|
||||
secciones en una rejilla de iconos, como el cajón de apps del móvil. Abajo queda una
|
||||
barra de cuatro atajos que eliges tú. Dentro de cada módulo los filtros van en fichas
|
||||
pequeñas, para que el contenido se vea sin tener que bajar.
|
||||
|
||||
Solo aparecen los módulos activos. En *Ajustes → Workflows* se eligen de golpe: el de
|
||||
acampada deja lo justo para organizarse. En el móvil un workflow cambia los módulos,
|
||||
no el aspecto: el aspecto se elige en *Ajustes → Tema* (Acampada u OasisMobile).
|
||||
|
||||
---
|
||||
|
||||
## Cómo está hecha la rama
|
||||
|
||||

|
||||
|
||||
Oasis lo desarrolla epsylon y saca versión casi cada día. Para no tener que rehacer la
|
||||
rama en cada una, lo nuestro va en ficheros propios: hojas de estilo, unas pocas
|
||||
vistas, un router que va delante del suyo y el envoltorio de Android. El backend, el
|
||||
middleware, los modelos y las traducciones son suyos y no se tocan. Las normas están
|
||||
en la [guía de desarrollo](GUIA_DE_DESARROLLO.md) y las cifras en
|
||||
[docs/FRONTERA_UPSTREAM.md](docs/FRONTERA_UPSTREAM.md).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -132,28 +162,28 @@ no el aspecto.
|
|||
|
||||
| | |
|
||||
|---|---|
|
||||
| **[oasis-project.pub](https://oasis-project.pub)** | Directorio de pubs, con invitaciones y estado de cada uno |
|
||||
| **[0asis.net](https://0asis.net)** | El proyecto explicado desde el principio |
|
||||
| **[wiki.solarnethub.com](https://wiki.solarnethub.com/socialnet/overview)** | La documentación oficial, módulo por módulo |
|
||||
| [oasis-project.pub](https://oasis-project.pub) | Directorio de pubs, con invitaciones y estado de cada uno |
|
||||
| [0asis.net](https://0asis.net) | El proyecto explicado desde el principio |
|
||||
| [wiki.solarnethub.com](https://wiki.solarnethub.com/socialnet/overview) | La documentación oficial, módulo por módulo |
|
||||
|
||||
---
|
||||
|
||||
## Instalar
|
||||
|
||||
La APK **no está en ninguna tienda**: se descarga de las *releases* de este repositorio
|
||||
y se instala a mano, con orígenes desconocidos activado. Se instala **junto al Oasis
|
||||
oficial** sin pisarlo —el identificador es `net.laenre.oasis`—, así que puedes tener
|
||||
La APK no está en ninguna tienda: se descarga de las *releases* de este repositorio
|
||||
y se instala a mano, con orígenes desconocidos activado. Se instala junto al Oasis
|
||||
oficial sin pisarlo —el identificador es `net.laenre.oasis`—, así que puedes tener
|
||||
los dos y comparar.
|
||||
|
||||
Necesita unos **350 MB libres**. El primer arranque tarda entre 15 y 60 segundos porque
|
||||
Necesita unos 350 MB libres. El primer arranque tarda entre 15 y 60 segundos porque
|
||||
descomprime el servidor.
|
||||
|
||||
> **Verifica la huella de la firma** antes de instalar una APK bajada de un servidor
|
||||
> Verifica la huella de la firma antes de instalar una APK bajada de un servidor
|
||||
> propio: `apksigner verify --print-certs`
|
||||
|
||||
### Compilar
|
||||
|
||||
**Con Android Studio**, lo más fácil:
|
||||
Con Android Studio, lo más fácil:
|
||||
|
||||
```sh
|
||||
./android/scripts/android-studio.sh # trae el Oasis oficial y su APK, y empaqueta el backend
|
||||
|
|
@ -163,7 +193,7 @@ Después, en Android Studio: *File → Open →* la carpeta `android/`, esperar
|
|||
Sync, y *Build → Build App Bundle(s) / APK(s) → Build APK(s)*. Si cambias algo en
|
||||
`src/` o en `main.js`, vuelve a lanzar el script antes de compilar.
|
||||
|
||||
**Desde la terminal**, paso a paso:
|
||||
Desde la terminal, paso a paso:
|
||||
|
||||
```sh
|
||||
cd android
|
||||
|
|
@ -187,13 +217,13 @@ Para desarrollar, en el propio repositorio:
|
|||
| [docs/USABILIDAD_PAD.txt](docs/USABILIDAD_PAD.txt) | Pruebas de usabilidad en el móvil |
|
||||
|
||||
Todo lo de arriba, en detalle, está en la
|
||||
**[wiki](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki)**:
|
||||
[wiki](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki):
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| [Entender Oasis](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Entender) | La red, el gossip, los saltos, los pubs, las tribus y el LARP |
|
||||
| [Empezar desde cero](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Empezar) | Invitación, seguir gente, abrir tu blog o tu tienda |
|
||||
| [Llamadas](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Llamadas) | Cómo se llama y cómo montar un TURN |
|
||||
| [Llamadas](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Llamadas) | Teléfono y Salas en el móvil |
|
||||
| [La interfaz](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Interfaz) | Botón por botón |
|
||||
| [Identidades](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Identidades) | Varias cuentas en el mismo móvil |
|
||||
| [Compilar la APK](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki/Compilar) | Y cómo se publica una versión |
|
||||
|
|
@ -205,12 +235,12 @@ Todo lo de arriba, en detalle, está en la
|
|||
|
||||
## El proyecto original
|
||||
|
||||
Esta rama existe **gracias a** y **por encima de** el trabajo de epsylon. El código, la
|
||||
Esta rama existe gracias a y por encima de el trabajo de epsylon. El código, la
|
||||
arquitectura, los módulos y la red son suyos.
|
||||
|
||||
- **Código:** https://github.com/epsylon/oasis
|
||||
- **Proyecto:** https://solarnethub.com
|
||||
- **Wiki:** https://wiki.solarnethub.com/socialnet/overview
|
||||
- Código: https://github.com/epsylon/oasis
|
||||
- Proyecto: https://solarnethub.com
|
||||
- Wiki: https://wiki.solarnethub.com/socialnet/overview
|
||||
|
||||
## Licencia
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 133 KiB |
BIN
docs/capturas/02-tribus.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 110 KiB |
BIN
docs/capturas/03-votacion.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 115 KiB |
BIN
docs/capturas/04-modulos.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
docs/capturas/05-ajustes.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 116 KiB |
BIN
docs/capturas/07-oasismobile.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
docs/capturas/08-salas.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 64 KiB |
BIN
docs/capturas/esquema-llamadas.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
docs/capturas/esquema-rama.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
|
|
@ -1,8 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Portada y esquema de la interfaz del README, con la paleta del tema Acampada.
|
||||
"""Portada y esquemas del README, con la paleta del tema Acampada.
|
||||
|
||||
Las capturas de movil (01..07) se hacen aparte, con la app arrancada; este script
|
||||
solo compone 00-portada.png a partir de ellas y dibuja esquema-interfaz.png.
|
||||
Las capturas de movil (01..08) se hacen aparte, con la app arrancada en un nodo de
|
||||
pruebas a 412x915 y escala 2; este script compone 00-portada.png a partir de ellas y
|
||||
dibuja esquema-interfaz.png, esquema-rama.png y esquema-llamadas.png.
|
||||
El texto vive aqui: se cambia y se relanza, nunca se retocan los PNG a mano.
|
||||
|
||||
python3 docs/capturas/generar_portada.py
|
||||
|
|
@ -47,8 +48,8 @@ def portada():
|
|||
d.rectangle((80, bottom + 12, 420, bottom + 20), fill=FG)
|
||||
d.text((80, 196), "Rama PRUEBAS del hacklab · base Oasis 1.3.3 · tema Acampada, pensado para el pulgar",
|
||||
font=font(SANS, 27), fill=MUTED)
|
||||
shots = [("01-portada.png", "Lanzador de módulos"), ("03-karvan.png", "Karvan: salas efímeras"),
|
||||
("04-foros.png", "Filtros en fichas"), ("06-barra.png", "Tu barra de 4 atajos")]
|
||||
shots = [("01-portada.png", "Lanzador de módulos"), ("02-tribus.png", "Tribus en filas"),
|
||||
("03-votacion.png", "Votar en semáforo"), ("07-oasismobile.png", "O el tema del dev")]
|
||||
pw, gap, top = 320, 50, 270
|
||||
x = (W - (4 * (pw + 20) + 3 * gap)) // 2
|
||||
cap = font(ANTON, 34)
|
||||
|
|
@ -87,8 +88,8 @@ def esquema():
|
|||
d.rounded_rectangle((px0, py0, px1, py1), 30, outline=FG, width=5)
|
||||
d.rounded_rectangle((px0 + 16, py0 + 20, px1 - 16, py0 + 84), 14, fill=BG, outline=FG, width=3)
|
||||
s = font(SANS, 15)
|
||||
d.text((px0 + 46, py0 + 42), "logo · (Personal | Social) · avatar", font=s, fill=FG)
|
||||
secciones = [("COMUNIDAD", 8), ("BIBLIOTECA", 2), ("HERRAMIENTAS", 5)]
|
||||
d.text((px0 + 46, py0 + 42), "logo · no molestar · avatar", font=s, fill=FG)
|
||||
secciones = [("COMUNIDAD", 8), ("BIBLIOTECA", 2), ("GOBERNANZA", 2)]
|
||||
y = py0 + 110
|
||||
for nombre, n in secciones:
|
||||
d.text((px0 + 40, y), nombre, font=font(ANTON, 17), fill=FG)
|
||||
|
|
@ -108,12 +109,12 @@ def esquema():
|
|||
cajas = [
|
||||
((bx0, 190, bx1, 340), "ARRIBA — LA BARRA SUPERIOR",
|
||||
["El logo vuelve al inicio y el avatar abre tu perfil.",
|
||||
"Con muchos módulos activos salen los filtros Personal y Social;",
|
||||
"en modo activistas todo cabe en una pantalla y no hacen falta."], BG),
|
||||
"En medio, el botón de No molestar del Teléfono.",
|
||||
"Con muchos módulos activos salen también los filtros Personal y Social."], BG),
|
||||
((bx0, 375, bx1, 565), "EN MEDIO — EL LANZADOR",
|
||||
["Los módulos activos en una rejilla de iconos, por secciones,",
|
||||
"como el cajón de apps del móvil. Los nombres son los del Oasis",
|
||||
"oficial: Comunidad, Biblioteca, Herramientas…",
|
||||
"oficial: Comunidad, Biblioteca, Gobernanza…",
|
||||
"Solo en la pantalla de inicio; dentro de cada módulo, filtros en fichas."], BG),
|
||||
((bx0, 600, bx1, 750), "ABAJO — LOS ATAJOS",
|
||||
["Cuatro módulos a tu elección: ni uno más, que es para el pulgar.",
|
||||
|
|
@ -132,6 +133,79 @@ def esquema():
|
|||
out.save(HERE / "esquema-interfaz.png", optimize=True)
|
||||
|
||||
|
||||
def flecha(d, a, b, ancho=4):
|
||||
ang = math.atan2(b[1] - a[1], b[0] - a[0])
|
||||
tip = lambda da, r: (b[0] - r * math.cos(ang + da), b[1] - r * math.sin(ang + da))
|
||||
d.line((a, tip(0, 12)), fill=FG, width=ancho)
|
||||
d.polygon([b, tip(0.45, 20), tip(-0.45, 20)], fill=FG)
|
||||
|
||||
|
||||
def titulo(d, texto, sub):
|
||||
d.text((46, 26), texto, font=font(ANTON, 46), fill=FG)
|
||||
bottom = d.textbbox((46, 26), texto, font=font(ANTON, 46))[3]
|
||||
d.rectangle((46, bottom + 10, 260, bottom + 16), fill=FG)
|
||||
d.text((46, bottom + 30), sub, font=font(SANS, 18), fill=MUTED)
|
||||
|
||||
|
||||
def esquema_rama():
|
||||
"""Como va la rama encima de Oasis: lo del dev abajo, lo nuestro encima."""
|
||||
W, H = 1400, 760
|
||||
out = Image.new("RGB", (W, H), BG)
|
||||
d = ImageDraw.Draw(out)
|
||||
titulo(d, "CÓMO VA LA RAMA ENCIMA DE OASIS",
|
||||
"Oasis lo cambia el dev, casi una versión al día. La rama solo cambia cómo se ve y se usa en el móvil.")
|
||||
capa = [
|
||||
((60, 210, 380, 400), "ASPECTO",
|
||||
["mobile_base.css: la maqueta", "mobile_ux.css: márgenes, letra,", "botones y piezas nuevas",
|
||||
"Acampada.css: el skin"], NEON),
|
||||
((400, 210, 720, 400), "PANTALLAS",
|
||||
["mobile_ui.js y las vistas", "mobile_*.js. En una vista", "del dev, como mucho una", "línea que las llama"], NEON),
|
||||
((740, 210, 1060, 400), "RUTAS",
|
||||
["fork_routes.js y", "mobile_layer.js, delante", "del router del dev: lo que", "no atienden pasa al suyo"], NEON),
|
||||
((1080, 210, 1340, 400), "ANDROID",
|
||||
["envoltorio propio:", "permisos de micro y", "cámara, y el puente", "de audio del Teléfono"], NEON),
|
||||
]
|
||||
for box, t, l, r in capa:
|
||||
caja(d, box, t, l, r)
|
||||
d.text((60, 166), "LO DE LA RAMA", font=font(ANTON, 26), fill=FG)
|
||||
for x in (220, 560, 900, 1210):
|
||||
flecha(d, (x, 418), (x, 478))
|
||||
caja(d, (60, 500, 1340, 690), "OASIS DEL DEV: NO SE TOCA",
|
||||
["backend.js y su middleware · los modelos (lo que se publica y cómo se cuenta) · SSB y su arranque",
|
||||
"las traducciones · style.css y mobile.css · los temas, también OasisMobile.css",
|
||||
"De 6.400 líneas cambiadas en 43 ficheros suyos (octubre) a 1.045 en 40. Ver GUIA_DE_DESARROLLO.md"], BG)
|
||||
out.save(HERE / "esquema-rama.png", optimize=True)
|
||||
|
||||
|
||||
def esquema_llamadas():
|
||||
"""Las llamadas son las del dev; la rama solo enchufa el movil."""
|
||||
W, H = 1400, 700
|
||||
out = Image.new("RGB", (W, H), BG)
|
||||
d = ImageDraw.Draw(out)
|
||||
titulo(d, "LLAMADAS: LAS DEL DEV, CON EL MÓVIL ENCHUFADO",
|
||||
"Teléfono y Salas son de Oasis. La rama no tiene llamadas propias: solo hace que suenen en Android.")
|
||||
cajas = [
|
||||
((50, 200, 360, 430), "TELÉFONO Y SALAS",
|
||||
["De Oasis, tal cual.", "Llamadas de uno a uno", "con buzón de voz; salas", "de hasta 50, con vídeo,", "grabación y emisión."], BG),
|
||||
((400, 200, 700, 430), "LOS ENCHUFES",
|
||||
["setAudioFactory", "setVideoFactory", "setStreamFactory", "", "Los deja el propio dev."], BG),
|
||||
((740, 200, 1040, 430), "EL PUENTE",
|
||||
["main.js enchufa ahí", "phone_*_android.js:", "el audio y la cámara", "pasan por la app de", "Android."], NEON),
|
||||
((1080, 200, 1350, 430), "EL MÓVIL",
|
||||
["Micrófono, cámara", "y altavoz. Los permisos", "se piden la primera vez", "que llamas o entras", "en una sala."], NEON),
|
||||
]
|
||||
for box, t, l, r in cajas:
|
||||
caja(d, box, t, l, r)
|
||||
for a, b in (((362, 315), (398, 315)), ((702, 315), (738, 315)), ((1042, 315), (1078, 315))):
|
||||
flecha(d, a, b)
|
||||
caja(d, (50, 480, 1350, 630), "¿Y CON LA APK OFICIAL?",
|
||||
["No declara micrófono ni cámara y su navegador interno deniega esas peticiones:",
|
||||
"en Android las llamadas no pueden sonar. Por eso esta rama trae su propio envoltorio."], BG)
|
||||
out.save(HERE / "esquema-llamadas.png", optimize=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
portada()
|
||||
esquema()
|
||||
esquema_rama()
|
||||
esquema_llamadas()
|
||||
|
|
|
|||
|
|
@ -469,3 +469,40 @@ body .main-content { min-height: calc(100dvh - 300px); }
|
|||
.main-column .search-filters-row > table.search-filters-table { flex: 0 0 auto !important; }
|
||||
.main-column .pm-card div.pm-actions.pm-actions { width: auto !important; max-width: max-content; display: inline-flex !important; vertical-align: top; }
|
||||
.main-column .pm-card .pm-info-table tr:nth-child(1) td, .main-column .pm-card .pm-info-table tr:nth-child(1) a { white-space: nowrap !important; overflow: hidden; text-overflow: ellipsis; min-width: 0; max-width: 100%; text-align: left !important; }
|
||||
|
||||
/* ---------- el interruptor Abierto / No molestar del Telefono del dev ---------- */
|
||||
/* salia centrado en una fila propia arriba de cada pagina (unos 60px); va en la
|
||||
barra de arriba, junto al avatar */
|
||||
form.oasis-phone-state {
|
||||
position: fixed !important; top: calc(env(safe-area-inset-top, 0px) + 14px); right: 62px; z-index: 1001;
|
||||
margin: 0 !important; padding: 0 !important; width: auto !important;
|
||||
}
|
||||
form.oasis-phone-state .oasis-phone-state-btn {
|
||||
width: 40px !important; height: 40px !important; min-height: 40px !important; padding: 0 !important; margin: 0 !important;
|
||||
display: inline-flex !important; align-items: center; justify-content: center;
|
||||
border-radius: 50% !important; box-shadow: none !important; font-size: 20px !important;
|
||||
}
|
||||
.oasis-mobile-topbar .omt-menus { padding-right: 46px; }
|
||||
|
||||
/* barras de la votacion: juntas, y las etiquetas del dev (CONFUNDIDO, SEGUIR
|
||||
MAYORIA) en el mismo tipo que las nuestras (Si, No) */
|
||||
.main-column div.vote-bar { margin: 0 !important; padding: 0 !important; min-height: 0 !important; gap: 4px 10px !important; }
|
||||
.main-column .vote-bar > * { margin: 0 !important; }
|
||||
.main-column .vote-bar-meter { height: 12px !important; min-height: 0 !important; }
|
||||
.main-column .vote-bar-label { text-transform: lowercase; }
|
||||
.main-column .vote-bar-label::first-letter { text-transform: uppercase; }
|
||||
|
||||
/* personalizar la barra de abajo: una fila por atajo, como el resto de listas */
|
||||
.main-column .bb-manage-list, .main-column .bb-pick-grid { display: flex !important; flex-direction: column !important; gap: 8px !important; align-items: stretch !important; }
|
||||
.main-column .bb-manage-list form, .main-column .bb-pick-grid form { margin: 0 !important; width: 100% !important; }
|
||||
.main-column button.bb-manage-btn, .main-column button.bb-pick-btn {
|
||||
width: 100% !important; min-height: 52px !important; margin: 0 !important; padding: 8px 14px !important;
|
||||
display: flex !important; align-items: center; gap: 12px; justify-content: flex-start !important;
|
||||
font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 16px !important;
|
||||
text-transform: none !important; letter-spacing: 0 !important; box-shadow: none !important;
|
||||
}
|
||||
.main-column .bb-manage-btn .bb-manage-lbl, .main-column .bb-pick-btn .bb-pick-lbl { flex: 1 1 auto; text-align: left; }
|
||||
.main-column .bb-manage-btn .bb-manage-x { color: var(--ux-danger) !important; font-size: 18px; }
|
||||
.main-column .bb-manage h3, .main-column .bb-manage-add h3 { font-size: 20px !important; margin: 18px 0 10px !important; }
|
||||
.main-column a.bb-manage-done { display: block !important; width: 100% !important; margin-top: 18px !important; text-align: center; }
|
||||
.main-column div.bb-manage, .main-column div.bb-manage-add, .main-column div.bb-manage-list, .main-column div.bb-pick-grid { padding: 0 !important; margin: 0 !important; border: 0 !important; }
|
||||
|
|
|
|||
|
|
@ -119,9 +119,14 @@ const settingsOrder = (parts) => {
|
|||
// cada idioma un boton que se aplica al tocarlo (antes desplegable y otro boton)
|
||||
const LANGS = [['Español', 'es'], ['Català', 'ca'], ['Euskara', 'eu'], ['Galego', 'gl'], ['English', 'en'], ['Français', 'fr'],
|
||||
['Português', 'pt'], ['Italiano', 'it'], ['Deutsch', 'de'], ['Русский', 'ru'], ['العربية', 'ar'], ['हिन्दी', 'hi'], ['中文', 'zh']];
|
||||
const languagePick = (selected) => form({ action: '/language', method: 'post', class: 'lang-pick' },
|
||||
// el idioma se lee al pintar: settings_view desestructura selectedLanguage al cargar y
|
||||
// se queda con el valor de entonces (siempre "en")
|
||||
const languagePick = () => {
|
||||
const selected = require('./main_views').getLanguage();
|
||||
return form({ action: '/language', method: 'post', class: 'lang-pick' },
|
||||
...LANGS.map(([name, code]) => button({ type: 'submit', name: 'language', value: code, class: code === selected ? 'lang-chip is-current' : 'lang-chip', lang: code }, name))
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
// ---------- acciones de tarjeta ----------
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ const settingsView = (params) => {
|
|||
div({ class: "tags-header" },
|
||||
h2(i18n.language),
|
||||
p(i18n.languageDescription),
|
||||
isMobile ? mobileUi.languagePick(selectedLanguage) : form(
|
||||
isMobile ? mobileUi.languagePick() : form(
|
||||
{ action: "/language", method: "post" },
|
||||
select({ name: "language" }, [
|
||||
languageOption("English", "en"),
|
||||
|
|
|
|||